From a1e8b6c8d2d6fa979bf4f9823dd5cb44235cbb0b Mon Sep 17 00:00:00 2001 From: Ashfame Date: Wed, 1 Mar 2023 20:38:31 +0400 Subject: [PATCH 1/7] show unknown room when room is loaded in a single user mode, and creates a guest session if necessary --- frontend/iframe/platform/Navigation.ts | 1 + frontend/iframe/viewmodels/RootViewModel.ts | 75 +++++++++++++++++++++ frontend/iframe/views/RootView.ts | 3 + package.json | 2 +- yarn.lock | 4 +- 5 files changed, 82 insertions(+), 3 deletions(-) diff --git a/frontend/iframe/platform/Navigation.ts b/frontend/iframe/platform/Navigation.ts index bb70bc0a..80ba12e5 100644 --- a/frontend/iframe/platform/Navigation.ts +++ b/frontend/iframe/platform/Navigation.ts @@ -9,6 +9,7 @@ export enum Section { SessionLoading = "loading", Session = "session", Error = "error", + UnknownRoom = "unknown-room", Redirecting = "redirecting", } diff --git a/frontend/iframe/viewmodels/RootViewModel.ts b/frontend/iframe/viewmodels/RootViewModel.ts index 4e61ae3f..fa17d251 100644 --- a/frontend/iframe/viewmodels/RootViewModel.ts +++ b/frontend/iframe/viewmodels/RootViewModel.ts @@ -4,6 +4,7 @@ import { LogoutViewModel } from "hydrogen-web/src/domain/LogoutViewModel"; import { SegmentType } from "hydrogen-web/src/domain/navigation"; import { SessionLoadViewModel } from "hydrogen-web/src/domain/SessionLoadViewModel"; import { SessionPickerViewModel } from "hydrogen-web/src/domain/SessionPickerViewModel"; +import { UnknownRoomViewModel } from "hydrogen-web/src/domain/session/room/UnknownRoomViewModel"; import { Options as BaseOptions, ViewModel } from "hydrogen-web/src/domain/ViewModel"; import { Client } from "hydrogen-web/src/matrix/Client.js"; import { HomeServerApi } from "hydrogen-web/src/matrix/net/HomeServerApi"; @@ -22,6 +23,7 @@ export class RootViewModel extends ViewModel { private _sessionPickerViewModel: SessionPickerViewModel | undefined; private _sessionLoadViewModel: SessionLoadViewModel | undefined; private _sessionViewModel: SessionViewModel | undefined; + private _unknownRoomViewModel: UnknownRoomViewModel | undefined; private _pendingClient: Client; private readonly _singleRoomIdOrAlias: string | undefined; private _resolvedSingleRoomId: string | undefined; @@ -46,6 +48,8 @@ export class RootViewModel extends ViewModel { return Section.SessionLoading; } else if (this._sessionViewModel) { return Section.Session; + } else if (this._unknownRoomViewModel) { + return Section.UnknownRoom; } else { return Section.Redirecting; } @@ -71,6 +75,10 @@ export class RootViewModel extends ViewModel { return this._sessionLoadViewModel; } + public get unknownRoomViewModel(): UnknownRoomViewModel | undefined { + return this._unknownRoomViewModel; + } + public get sessionViewModel(): SessionViewModel | undefined { return this._sessionViewModel; } @@ -157,6 +165,22 @@ export class RootViewModel extends ViewModel { this._showLogin(loginToken); } } else { + if (this._singleRoomIdOrAlias) { + // No active session but we're in single-room mode. + if (!this._resolvedSingleRoomId) { + try { + this._resolvedSingleRoomId = await this.resolveRoomAlias(this._singleRoomIdOrAlias); + } catch (error) { + console.warn(error); + } + } + + if (this._resolvedSingleRoomId) { + await this._showUnknownRoom(this._resolvedSingleRoomId); + return; + } + } + try { if (!(shouldRestoreLastUrl && this.urlRouter.tryRestoreLastUrl())) { const sessionInfos = await this.platform.sessionInfoStorage.getAll(); @@ -204,6 +228,29 @@ export class RootViewModel extends ViewModel { return response.room_id; } + private async isWorldReadableRoom(roomId: string, sessionId: string): Promise { + const sessionInfo = await this.platform.sessionInfoStorage.get(sessionId); + if (!sessionInfo) { + console.error(`Could not find session for id ${sessionId}`); + return false; + } + + const homeserver = await lookupHomeserver(roomId.split(':')[1], this.platform.request); + const homeserverApi = new HomeServerApi({ + homeserver: homeserver, + request: this.platform.request, + accessToken: sessionInfo.accessToken, + reconnector: this.platform.reconnector, + }); + + return homeserverApi.state(roomId, 'm.room.history_visibility', '').response().then( + response => response.history_visibility === 'world_readable' + ).catch(err => { + console.error(err); + return false; + }); + } + private _showLogin(loginToken: string | undefined) { this._setSection(() => { const options = this.childOptions({ @@ -271,6 +318,34 @@ export class RootViewModel extends ViewModel { }); } + private async _showUnknownRoom(roomId: string) { + const client = new Client(this.platform); + let chosenSession; + + let sessionInfos = await this.platform.sessionInfoStorage.getAll(); + if (sessionInfos.length === 0) { + const homeserver = await lookupHomeserver(roomId.split(':')[1], this.platform.request); + await client.doGuestLogin(homeserver); + sessionInfos = await this.platform.sessionInfoStorage.getAll(); + chosenSession = sessionInfos[0]; + } else { + chosenSession = sessionInfos[0]; + await client.startWithExistingSession(chosenSession.id); + } + console.info('chosenSession',chosenSession); + // @TODO need to stop/prevent sync for guest account (when creating a new one or reusing an existing one) + + this._setSection(() => { + this._unknownRoomViewModel = new UnknownRoomViewModel(this.childOptions({ + roomIdOrAlias: roomId, + session: chosenSession, + isWorldReadablePromise: this.isWorldReadableRoom(roomId, chosenSession.id), + })); + }); + + this.navigation.push("session", chosenSession.id); + } + private _setSection(setter: Function) { // Clear all members the activeSection depends on. this._error = undefined; diff --git a/frontend/iframe/views/RootView.ts b/frontend/iframe/views/RootView.ts index 053c5398..571cb613 100644 --- a/frontend/iframe/views/RootView.ts +++ b/frontend/iframe/views/RootView.ts @@ -4,6 +4,7 @@ import { TemplateView } from "hydrogen-web/src/platform/web/ui/general/TemplateV import { LoginView } from "hydrogen-web/src/platform/web/ui/login/LoginView"; import { SessionLoadView } from "hydrogen-web/src/platform/web/ui/login/SessionLoadView"; import { SessionPickerView } from "hydrogen-web/src/platform/web/ui/login/SessionPickerView"; +import { UnknownRoomView } from "hydrogen-web/src/platform/web/ui/session/room/UnknownRoomView"; import { LogoutView } from "hydrogen-web/src/platform/web/ui/LogoutView"; import { Section } from "../platform/Navigation"; import { RootViewModel } from "../viewmodels/RootViewModel"; @@ -36,6 +37,8 @@ export class RootView extends TemplateView { return new StaticView(t => t.p("Redirecting...")); case Section.SessionLoading: return new SessionLoadView(vm.sessionLoadViewModel); + case Section.UnknownRoom: + return new UnknownRoomView(vm.unknownRoomViewModel); case Section.Error: return new StaticView(t => { return t.div({ className: "StatusView" }, [ diff --git a/package.json b/package.json index ee30e748..7d400a5d 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dependencies": { "@wordpress/compose": "^5.17.0", "bs58": "^5.0.0", - "hydrogen-web": "Automattic/hydrogen-web#peeking_unknown_rooms", + "hydrogen-web": "Automattic/hydrogen-web#peeking_with_guest_login", "node-html-parser": "^4.0.0" }, "resolutions": { diff --git a/yarn.lock b/yarn.lock index 8b492ad9..5c492a59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5715,9 +5715,9 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -hydrogen-web@Automattic/hydrogen-web#peeking_unknown_rooms: +hydrogen-web@Automattic/hydrogen-web#peeking_with_guest_login: version "0.3.8" - resolved "https://codeload.github.com/Automattic/hydrogen-web/tar.gz/07cce3857a163c17ee68aa86b304bd4430de9bfd" + resolved "https://codeload.github.com/Automattic/hydrogen-web/tar.gz/8b71ac900e683da110077d9ae87e6902dfb73399" dependencies: "@matrix-org/olm" "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz" another-json "^0.2.0" From e7cba314d2846e8eb8960b84a0fed77e9ea066a7 Mon Sep 17 00:00:00 2001 From: Ashfame Date: Mon, 6 Mar 2023 22:56:58 +0400 Subject: [PATCH 2/7] don't even try to restore last url when in single room mode --- frontend/iframe/viewmodels/RootViewModel.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/iframe/viewmodels/RootViewModel.ts b/frontend/iframe/viewmodels/RootViewModel.ts index a48a1210..624446cb 100644 --- a/frontend/iframe/viewmodels/RootViewModel.ts +++ b/frontend/iframe/viewmodels/RootViewModel.ts @@ -79,7 +79,7 @@ export class RootViewModel extends ViewModel { } public get singleRoomMode(): boolean { - return !!this._resolvedSingleRoomId; + return !!this._singleRoomIdOrAlias; } public async start() { @@ -157,7 +157,8 @@ export class RootViewModel extends ViewModel { } } else { try { - if (!(shouldRestoreLastUrl && this.urlRouter.tryRestoreLastUrl())) { + // don't even try to restore last url when in single room mode + if (this.singleRoomMode || !(shouldRestoreLastUrl && this.urlRouter.tryRestoreLastUrl())) { const sessionInfos = await this.platform.sessionInfoStorage.getAll(); if (sessionInfos.length === 0) { this.navigation.push(Section.Login); From dc1362b5375b405f53f49655a34ccc480a8e395e Mon Sep 17 00:00:00 2001 From: Ashfame Date: Tue, 7 Mar 2023 13:23:58 +0400 Subject: [PATCH 3/7] dont override sending to the correct url and move our code to run only when no session exists --- frontend/iframe/viewmodels/RootViewModel.ts | 33 ++++++++++----------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/frontend/iframe/viewmodels/RootViewModel.ts b/frontend/iframe/viewmodels/RootViewModel.ts index fa17d251..9827eeff 100644 --- a/frontend/iframe/viewmodels/RootViewModel.ts +++ b/frontend/iframe/viewmodels/RootViewModel.ts @@ -165,27 +165,26 @@ export class RootViewModel extends ViewModel { this._showLogin(loginToken); } } else { - if (this._singleRoomIdOrAlias) { - // No active session but we're in single-room mode. - if (!this._resolvedSingleRoomId) { - try { - this._resolvedSingleRoomId = await this.resolveRoomAlias(this._singleRoomIdOrAlias); - } catch (error) { - console.warn(error); - } - } - - if (this._resolvedSingleRoomId) { - await this._showUnknownRoom(this._resolvedSingleRoomId); - return; - } - } - try { if (!(shouldRestoreLastUrl && this.urlRouter.tryRestoreLastUrl())) { const sessionInfos = await this.platform.sessionInfoStorage.getAll(); if (sessionInfos.length === 0) { - this.navigation.push(Section.Login); + if (this._singleRoomIdOrAlias) { + // No active session but we're in single-room mode. + if (!this._resolvedSingleRoomId) { + try { + this._resolvedSingleRoomId = await this.resolveRoomAlias(this._singleRoomIdOrAlias); + } catch (error) { + console.warn(error); + } + } + + if (this._resolvedSingleRoomId) { + await this._showUnknownRoom(this._resolvedSingleRoomId); + } + } else { + this.navigation.push(Section.Login); + } } else if (sessionInfos.length === 1) { this.navigation.push(Section.Session, sessionInfos[0].id); } else { From ff40c097e79447bca124534f4216cc836151c9cc Mon Sep 17 00:00:00 2001 From: Ashfame Date: Tue, 7 Mar 2023 15:36:48 +0400 Subject: [PATCH 4/7] resolve room alias early on when figuring out navigation path --- frontend/iframe/viewmodels/RootViewModel.ts | 46 +++++++-------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/frontend/iframe/viewmodels/RootViewModel.ts b/frontend/iframe/viewmodels/RootViewModel.ts index 9827eeff..c4b630d4 100644 --- a/frontend/iframe/viewmodels/RootViewModel.ts +++ b/frontend/iframe/viewmodels/RootViewModel.ts @@ -109,6 +109,17 @@ export class RootViewModel extends ViewModel { const sessionId = this.navigation.path.get("session")?.value; const loginToken = this.navigation.path.get("sso")?.value; + if (this._singleRoomIdOrAlias && !this._resolvedSingleRoomId) { + try { + this._resolvedSingleRoomId = await this.resolveRoomAlias(this._singleRoomIdOrAlias); + } catch (error) { + // Something went wrong when navigating to the room. + // We swallow the error and fallback to non-single-room mode. + console.warn(error); + this._resolvedSingleRoomId = undefined; + } + } + if (isLogin) { if (this.activeSection !== Section.Login) { this._showLogin(undefined); @@ -126,21 +137,7 @@ export class RootViewModel extends ViewModel { void this._showPicker(); } } else if (sessionId) { - if (this._singleRoomIdOrAlias && !this._resolvedSingleRoomId) { - // We're in single-room mode but haven't resolved the room alias yet. - try { - this._resolvedSingleRoomId = await this.resolveRoomAlias(this._singleRoomIdOrAlias, sessionId); - } catch (error) { - // Something went wrong when navigating to the room. - // We swallow the error and fallback to non-single-room mode. - console.warn(error); - this._resolvedSingleRoomId = undefined; - this.emitChange("singleRoomMode"); - } - } - if (this._resolvedSingleRoomId) { - this.emitChange("singleRoomMode"); this.navigation.push("room", this._resolvedSingleRoomId); } @@ -169,22 +166,11 @@ export class RootViewModel extends ViewModel { if (!(shouldRestoreLastUrl && this.urlRouter.tryRestoreLastUrl())) { const sessionInfos = await this.platform.sessionInfoStorage.getAll(); if (sessionInfos.length === 0) { - if (this._singleRoomIdOrAlias) { - // No active session but we're in single-room mode. - if (!this._resolvedSingleRoomId) { - try { - this._resolvedSingleRoomId = await this.resolveRoomAlias(this._singleRoomIdOrAlias); - } catch (error) { - console.warn(error); - } - } - - if (this._resolvedSingleRoomId) { - await this._showUnknownRoom(this._resolvedSingleRoomId); - } - } else { - this.navigation.push(Section.Login); + if (this._resolvedSingleRoomId) { + await this._showUnknownRoom(this._resolvedSingleRoomId); + return; } + this.navigation.push(Section.Login); } else if (sessionInfos.length === 1) { this.navigation.push(Section.Session, sessionInfos[0].id); } else { @@ -331,8 +317,6 @@ export class RootViewModel extends ViewModel { chosenSession = sessionInfos[0]; await client.startWithExistingSession(chosenSession.id); } - console.info('chosenSession',chosenSession); - // @TODO need to stop/prevent sync for guest account (when creating a new one or reusing an existing one) this._setSection(() => { this._unknownRoomViewModel = new UnknownRoomViewModel(this.childOptions({ From 53ec06b0c998474f8a49f70be36bc2ab5c82fc3b Mon Sep 17 00:00:00 2001 From: Ashfame Date: Tue, 7 Mar 2023 15:59:31 +0400 Subject: [PATCH 5/7] update dependencies - mainly hydrogen's branch --- yarn.lock | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5c492a59..1a9ea138 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3801,11 +3801,16 @@ core-js-pure@^3.25.1, core-js-pure@^3.8.1: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.3.tgz#66ac5bfa5754b47fdfd14f3841c5ed21c46db608" integrity sha512-T/7qvgv70MEvRkZ8p6BasLZmOVYKzOaWNBEHAU8FmveCJkl4nko2quqPQOmy6AJIp5MBanhz9no3A94NoRb0XA== -core-js@^3.19.1, core-js@^3.6.5: +core-js@^3.19.1: version "3.25.3" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.3.tgz#cbc2be50b5ddfa7981837bd8c41639f27b166593" integrity sha512-y1hvKXmPHvm5B7w4ln1S4uc9eV/O5+iFExSRUimnvIph11uaizFR8LFMdONN8hG3P2pipUfX4Y/fR8rAEtcHcQ== +core-js@^3.6.5: + version "3.29.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.29.0.tgz#0273e142b67761058bcde5615c503c7406b572d6" + integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -4243,9 +4248,9 @@ domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: domelementtype "^2.3.0" dompurify@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.0.tgz#c9c88390f024c2823332615c9e20a453cf3825dd" - integrity sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA== + version "2.4.5" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.5.tgz#0e89a27601f0bad978f9a924e7a05d5d2cccdd87" + integrity sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA== domutils@^2.8.0: version "2.8.0" @@ -5717,7 +5722,7 @@ human-signals@^2.1.0: hydrogen-web@Automattic/hydrogen-web#peeking_with_guest_login: version "0.3.8" - resolved "https://codeload.github.com/Automattic/hydrogen-web/tar.gz/8b71ac900e683da110077d9ae87e6902dfb73399" + resolved "https://codeload.github.com/Automattic/hydrogen-web/tar.gz/f95684bfd31bee3487a8ba75938d69e60abd6b07" dependencies: "@matrix-org/olm" "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz" another-json "^0.2.0" From f53aee9296ccfb3489ea889125f4cd7dc3938db9 Mon Sep 17 00:00:00 2001 From: Ashfame Date: Thu, 9 Mar 2023 18:43:59 +0400 Subject: [PATCH 6/7] log error in console when error happens while applying navigation --- frontend/iframe/viewmodels/RootViewModel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/iframe/viewmodels/RootViewModel.ts b/frontend/iframe/viewmodels/RootViewModel.ts index 9b9e07b8..8bd500ea 100644 --- a/frontend/iframe/viewmodels/RootViewModel.ts +++ b/frontend/iframe/viewmodels/RootViewModel.ts @@ -179,6 +179,7 @@ export class RootViewModel extends ViewModel { } } } catch (err) { + console.error(err); this._setSection(() => this._error = err); } } From a6d9f9a0b7d0f393ca9fe0953718c539a37f5812 Mon Sep 17 00:00:00 2001 From: Ashfame Date: Thu, 9 Mar 2023 18:45:04 +0400 Subject: [PATCH 7/7] pass the right session object of Session class instead of SessionInfoStorage --- frontend/iframe/viewmodels/RootViewModel.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/frontend/iframe/viewmodels/RootViewModel.ts b/frontend/iframe/viewmodels/RootViewModel.ts index 8bd500ea..52488ff1 100644 --- a/frontend/iframe/viewmodels/RootViewModel.ts +++ b/frontend/iframe/viewmodels/RootViewModel.ts @@ -313,22 +313,19 @@ export class RootViewModel extends ViewModel { if (sessionInfos.length === 0) { const homeserver = await lookupHomeserver(roomId.split(':')[1], this.platform.request); await client.doGuestLogin(homeserver); - sessionInfos = await this.platform.sessionInfoStorage.getAll(); - chosenSession = sessionInfos[0]; } else { - chosenSession = sessionInfos[0]; await client.startWithExistingSession(chosenSession.id); } this._setSection(() => { this._unknownRoomViewModel = new UnknownRoomViewModel(this.childOptions({ roomIdOrAlias: roomId, - session: chosenSession, - isWorldReadablePromise: this.isWorldReadableRoom(roomId, chosenSession.id), + session: client.session, + isWorldReadablePromise: this.isWorldReadableRoom(roomId, client.sessionId), })); }); - this.navigation.push("session", chosenSession.id); + this.navigation.push("session", client.sessionId); } private _setSection(setter: Function) {