diff --git a/src/components/Join.vue b/src/components/Join.vue
index 34937d0..62c4055 100644
--- a/src/components/Join.vue
+++ b/src/components/Join.vue
@@ -90,17 +90,17 @@
- {{
roomId && roomId.startsWith("@") ? $t("join.enter_room_user") : $t("join.enter_room")
}}
- {{
roomId && roomId.startsWith("@") ? $t("join.join_user") : $t("join.join")
}}
{{ loadingMessage }}
- {{ $t("join.you_have_been_banned") }}
+ {{ $t("join.you_have_been_banned") }}
diff --git a/src/models/user.js b/src/models/user.js
deleted file mode 100644
index a9f1870..0000000
--- a/src/models/user.js
+++ /dev/null
@@ -1,23 +0,0 @@
-export default class User {
- constructor(user_id, password, is_guest) {
- this.user_id = user_id;
- this.password = password;
- this.is_guest = is_guest || false
- }
-
- static localPart(user_id) {
- if (user_id && user_id.startsWith('@') && user_id.includes(':')) {
- const parts = user_id.split(":");
- return parts[0].substring(1);
- }
- return user_id;
- }
-
- static domainPart(user_id) {
- if (user_id && user_id.startsWith('@') && user_id.includes(':')) {
- const parts = user_id.split(":");
- return parts[1];
- }
- return undefined;
- }
-}
\ No newline at end of file
diff --git a/src/models/user.ts b/src/models/user.ts
new file mode 100644
index 0000000..018fef6
--- /dev/null
+++ b/src/models/user.ts
@@ -0,0 +1,27 @@
+export default class User {
+ user_id: string;
+ password: string | null;
+ is_guest: boolean;
+
+ constructor(user_id: string, password: string | null, is_guest?: boolean) {
+ this.user_id = user_id;
+ this.password = password;
+ this.is_guest = is_guest || false;
+ }
+
+ static localPart(user_id: string | null) {
+ if (user_id && user_id.startsWith("@") && user_id.includes(":")) {
+ const parts = user_id.split(":");
+ return parts[0].substring(1);
+ }
+ return user_id;
+ }
+
+ static domainPart(user_id: string | null) {
+ if (user_id && user_id.startsWith("@") && user_id.includes(":")) {
+ const parts = user_id.split(":");
+ return parts[1];
+ }
+ return undefined;
+ }
+}
diff --git a/src/services/analytics.service.js b/src/services/analytics.service.ts
similarity index 82%
rename from src/services/analytics.service.js
rename to src/services/analytics.service.ts
index ea644d6..4da5018 100644
--- a/src/services/analytics.service.js
+++ b/src/services/analytics.service.ts
@@ -1,9 +1,23 @@
import cleaninsights from "./cleaninsights.service";
import matomo from "./matomo.service";
+export interface AnalyticsEngine {
+ event(category: string, action: string);
+}
+
+type AnalyticsEvent = {
+ category: string;
+ action: string;
+}
+
export default {
install(app) {
class AnalyticsServiceClass {
+
+ engines: AnalyticsEngine[];
+ cachedEvents: AnalyticsEvent[];
+ initialized: boolean;
+
constructor() {
this.engines = [];
this.cachedEvents = [];
@@ -37,7 +51,7 @@ export default {
this.initialized = true;
// Handle cached events
- this.cachedEvents.forEach(([category, action]) => {
+ this.cachedEvents.forEach(({category, action}) => {
this.event(category, action);
});
this.cachedEvents = [];
@@ -46,7 +60,7 @@ export default {
event(category, action) {
if (!this.initialized) {
- this.cachedEvents.push([category, action]);
+ this.cachedEvents.push({category, action});
return;
}
diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js
index be87dce..7870a8b 100644
--- a/src/services/matrix.service.js
+++ b/src/services/matrix.service.js
@@ -85,19 +85,19 @@ export default {
joinedRooms() {
return this.rooms.filter((room) => {
- return room.selfMembership === "join";
+ return room.getMyMembership() === "join";
});
},
invites() {
return this.rooms.filter((room) => {
- return room.selfMembership === "invite";
+ return room.getMyMembership() === "invite";
});
},
joinedAndInvitedRooms() {
return this.rooms.filter((room) => {
- return room.selfMembership === "join" || room.selfMembership === "invite";
+ return room.getMyMembership() === "join" || room.getMyMembership() === "invite";
});
},
},
@@ -313,6 +313,8 @@ export default {
store: matrixStore,
deviceId: user.device_id,
accessToken: user.access_token,
+ refreshToken: user.refresh_token,
+ tokenRefreshFunction: this.onSessionRefresh,
timelineSupport: true,
unstableClientRelationAggregation: true,
cryptoStore: cryptoStore
@@ -413,7 +415,7 @@ export default {
case "m.room.join_rules":
{
const room = this.matrixClient.getRoom(event.getRoomId());
- if (room && room.getJoinRule() == "private" && room.selfMembership == "invite") {
+ if (room && room.getJoinRule() == "private" && room.getMyMembership() == "invite") {
// We have an invite to a room that's now "private"? This is most probably a deleted DM room.
// Reject the invite, i.e. call "leave" on it.
this.matrixClient.leave(room.roomId);
@@ -451,7 +453,7 @@ export default {
},
onRoom(room) {
- if (room.selfMembership === "invite") {
+ if (room.getMyMembership() === "invite") {
this.matrixClient
.getRoomTags(room.roomId)
.then((reply) => {
@@ -468,7 +470,7 @@ export default {
},
onRoomMyMembership(room) {
- if (room.selfMembership === "invite") {
+ if (room.getMyMembership() === "invite") {
// Invitation. Need to call "recalculate" to pick
// up room name, not sure why exactly.
room.recalculate();
@@ -476,6 +478,28 @@ export default {
this.reloadRooms();
},
+ onSessionRefresh(refreshToken) {
+ const now = Date.now();
+ return this.matrixClient.refreshToken(refreshToken).then((result) => {
+ // Store new one!
+ var user = this.$store.state.auth.user;
+ user.access_token = result.access_token;
+ user.refresh_token = result.refresh_token;
+ user.expires_in_ms = result.expires_in_ms;
+ this.$store.commit("setUser", user);
+
+ // Return AccessTokens struct
+ let accesssTokens = {
+ accessToken: result.access_token,
+ refreshToken: result.refresh_token
+ };
+ if (result.expires_in_ms) {
+ accesssTokens.expiry = new Date(now + result.expires_in_ms);
+ };
+ return accesssTokens;
+ });
+ },
+
onSessionLoggedOut() {
console.log("Logged out!");
if (this.matrixClient) {
@@ -517,7 +541,7 @@ export default {
// each time!
var updatedRooms = this.matrixClient.getVisibleRooms();
updatedRooms = updatedRooms.filter((room) => {
- return room.selfMembership && (room.selfMembership == "invite" || room.selfMembership == "join") && room.currentState.getStateEvents(STATE_EVENT_ROOM_DELETED).length == 0;
+ return room.getMyMembership() && (room.getMyMembership() == "invite" || room.getMyMembership() == "join") && room.currentState.getStateEvents(STATE_EVENT_ROOM_DELETED).length == 0;
});
updatedRooms.forEach((room) => {
room["avatar"] = room.getAvatarUrl(this.matrixClient.getHomeserverUrl(), 80, 80, "scale", true, this.useAuthedMedia);
@@ -567,7 +591,7 @@ export default {
var ids = {};
const ret = [];
for (const room of this.rooms) {
- if (room.selfMembership == "join" && this.getRoomJoinRule(room) == "invite") {
+ if (room.getMyMembership() == "join" && this.getRoomJoinRule(room) == "invite") {
for (const member of room.getJoinedMembers()) {
if (member.userId != this.currentUserId && !ids[member.userId]) {
ids[member.userId] = member;
@@ -842,7 +866,7 @@ export default {
})
.then(() => {
//console.log("Purge: create timeline");
- return timelineWindow.load(null, 100);
+ return timelineWindow.load(undefined, 100);
})
.then(() => {
const getMoreIfAvailable = function _getMoreIfAvailable() {
@@ -1234,7 +1258,7 @@ export default {
since: response.next_batch,
})
.then((response) => {
- return _findOrGetMore(client, response);
+ return _findOrGetMore(client, useAuthedMedia, response);
})
.catch((err) => {
return Promise.reject("Failed to find room: " + err);
diff --git a/src/services/navigation.service.js b/src/services/navigation.service.js
deleted file mode 100644
index a03c19f..0000000
--- a/src/services/navigation.service.js
+++ /dev/null
@@ -1,82 +0,0 @@
-export default {
- install(app, router) {
- var routes = [];
- var nextRoutes = null;
- var zeroIndex = undefined;
-
- router.beforeResolve((to, ignoredfrom, next) => {
- if (!zeroIndex) {
- routes = [to];
- zeroIndex = window.history.length;
- }
- next();
- })
-
- router.beforeEach((to, from, next) => {
- if (nextRoutes) {
- console.log("Nav: next routes set, going:", routes, nextRoutes);
- routes = nextRoutes;
- nextRoutes = null;
- if (routes.length > 0) {
- console.log("Redirecting to", routes[routes.length - 1]);
- next(routes[routes.length - 1]);
- return;
- }
- }
- next();
- })
-
- const navigationService = {
- /***
- * @param mode Mode of operation. -1 = push as root, 0 = replace, 1 = normal push
- */
- push(route, mode) {
- if (mode === undefined) {
- mode = 1;
- }
- if (mode == -1) {
- nextRoutes = [route];
- } else if (mode == 0) {
- // Replace
- nextRoutes = [...routes];
- nextRoutes.pop();
- nextRoutes.push(route);
- } else {
- nextRoutes = [...routes];
- nextRoutes.push(route);
- }
-
- const index = nextRoutes.length - routes.length;
- const targetIndex = nextRoutes.length - 1;
- console.log("Nav - index " + index + " Target " + targetIndex);
- if (index < 0) {
- console.log("Nav - go " + index);
- router.go(index);
- } else if (index == 0) {
- console.log("Nav - replace");
- routes = nextRoutes;
- nextRoutes = null;
- router.replace(route).catch((ignoredErr) => {});
- } else {
- console.log("Nav - push");
- router.push(route).catch((ignoredErr) => {});
- }
- },
-
- canPop() {
- if (nextRoutes) {
- return nextRoutes.length > 1;
- }
- return routes.length > 1;
- },
-
- pop() {
- routes.pop();
- router.go(-1);
- }
- }
-
- app.$navigation = navigationService;
- app.config.globalProperties.$navigation = navigationService;
- }
-}
diff --git a/src/services/navigation.service.ts b/src/services/navigation.service.ts
new file mode 100644
index 0000000..ea601b3
--- /dev/null
+++ b/src/services/navigation.service.ts
@@ -0,0 +1,84 @@
+import { RouteLocationNormalizedGeneric, Router } from "vue-router";
+
+export default {
+ install(app, router: Router) {
+ var routes: RouteLocationNormalizedGeneric[] = [];
+ var nextRoutes: RouteLocationNormalizedGeneric[] | null = null;
+ var zeroIndex: number | undefined = undefined;
+
+ router.beforeResolve((to, ignoredfrom, next) => {
+ if (!zeroIndex) {
+ routes = [to];
+ zeroIndex = window.history.length;
+ }
+ next();
+ });
+
+ router.beforeEach((to, from, next) => {
+ if (nextRoutes) {
+ console.log("Nav: next routes set, going:", routes, nextRoutes);
+ routes = nextRoutes;
+ nextRoutes = null;
+ if (routes.length > 0) {
+ console.log("Redirecting to", routes[routes.length - 1]);
+ next(routes[routes.length - 1]);
+ return;
+ }
+ }
+ next();
+ });
+
+ const navigationService = {
+ /***
+ * @param mode Mode of operation. -1 = push as root, 0 = replace, 1 = normal push
+ */
+ push(route, mode) {
+ if (mode === undefined) {
+ mode = 1;
+ }
+ if (mode == -1) {
+ nextRoutes = [route];
+ } else if (mode == 0) {
+ // Replace
+ nextRoutes = [...routes];
+ nextRoutes.pop();
+ nextRoutes.push(route);
+ } else {
+ nextRoutes = [...routes];
+ nextRoutes.push(route);
+ }
+
+ const index = nextRoutes.length - routes.length;
+ const targetIndex = nextRoutes.length - 1;
+ console.log("Nav - index " + index + " Target " + targetIndex);
+ if (index < 0) {
+ console.log("Nav - go " + index);
+ router.go(index);
+ } else if (index == 0) {
+ console.log("Nav - replace");
+ routes = nextRoutes;
+ nextRoutes = null;
+ router.replace(route).catch((ignoredErr) => {});
+ } else {
+ console.log("Nav - push");
+ router.push(route).catch((ignoredErr) => {});
+ }
+ },
+
+ canPop() {
+ if (nextRoutes) {
+ return nextRoutes.length > 1;
+ }
+ return routes.length > 1;
+ },
+
+ pop() {
+ routes.pop();
+ router.go(-1);
+ },
+ };
+
+ app.$navigation = navigationService;
+ app.config.globalProperties.$navigation = navigationService;
+ },
+};
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..37f3149
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "compilerOptions": {
+ "strict": true
+ },
+}
\ No newline at end of file