@@ -4,10 +4,12 @@ import { LogoutViewModel } from "hydrogen-web/src/domain/LogoutViewModel";
44import { SegmentType } from "hydrogen-web/src/domain/navigation" ;
55import { SessionLoadViewModel } from "hydrogen-web/src/domain/SessionLoadViewModel" ;
66import { SessionPickerViewModel } from "hydrogen-web/src/domain/SessionPickerViewModel" ;
7+ import { UnknownRoomViewModel } from "hydrogen-web/src/domain/session/room/UnknownRoomViewModel" ;
78import { Options as BaseOptions , ViewModel } from "hydrogen-web/src/domain/ViewModel" ;
89import { Client } from "hydrogen-web/src/matrix/Client.js" ;
9- import { HomeserverApi } from "../platform/HomeserverApi " ;
10+ import { HomeServerApi } from "hydrogen-web/src/matrix/net/HomeServerApi " ;
1011import { allSections , Section } from "../platform/Navigation" ;
12+ import { lookupHomeserver } from "hydrogen-web/src/matrix/well-known" ;
1113import { Platform } from "../platform/Platform" ;
1214import { SessionViewModel } from "./SessionViewModel" ;
1315
@@ -21,6 +23,7 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
2123 private _sessionPickerViewModel : SessionPickerViewModel | undefined ;
2224 private _sessionLoadViewModel : SessionLoadViewModel | undefined ;
2325 private _sessionViewModel : SessionViewModel | undefined ;
26+ private _unknownRoomViewModel : UnknownRoomViewModel | undefined ;
2427 private _pendingClient : Client ;
2528 private readonly _singleRoomIdOrAlias : string | undefined ;
2629 private _resolvedSingleRoomId : string | undefined ;
@@ -45,6 +48,8 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
4548 return Section . SessionLoading ;
4649 } else if ( this . _sessionViewModel ) {
4750 return Section . Session ;
51+ } else if ( this . _unknownRoomViewModel ) {
52+ return Section . UnknownRoom ;
4853 } else {
4954 return Section . Redirecting ;
5055 }
@@ -70,6 +75,10 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
7075 return this . _sessionLoadViewModel ;
7176 }
7277
78+ public get unknownRoomViewModel ( ) : UnknownRoomViewModel | undefined {
79+ return this . _unknownRoomViewModel ;
80+ }
81+
7382 public get sessionViewModel ( ) : SessionViewModel | undefined {
7483 return this . _sessionViewModel ;
7584 }
@@ -100,6 +109,17 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
100109 const sessionId = this . navigation . path . get ( "session" ) ?. value ;
101110 const loginToken = this . navigation . path . get ( "sso" ) ?. value ;
102111
112+ if ( this . _singleRoomIdOrAlias && ! this . _resolvedSingleRoomId ) {
113+ try {
114+ this . _resolvedSingleRoomId = await this . resolveRoomAlias ( this . _singleRoomIdOrAlias ) ;
115+ } catch ( error ) {
116+ // Something went wrong when navigating to the room.
117+ // We swallow the error and fallback to non-single-room mode.
118+ console . warn ( error ) ;
119+ this . _resolvedSingleRoomId = undefined ;
120+ }
121+ }
122+
103123 if ( isLogin ) {
104124 if ( this . activeSection !== Section . Login ) {
105125 this . _showLogin ( undefined ) ;
@@ -117,21 +137,7 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
117137 void this . _showPicker ( ) ;
118138 }
119139 } else if ( sessionId ) {
120- if ( this . _singleRoomIdOrAlias && ! this . _resolvedSingleRoomId ) {
121- // We're in single-room mode but haven't resolved the room alias yet.
122- try {
123- this . _resolvedSingleRoomId = await this . resolveRoomAlias ( sessionId , this . _singleRoomIdOrAlias ) ;
124- } catch ( error ) {
125- // Something went wrong when navigating to the room.
126- // We swallow the error and fallback to non-single-room mode.
127- console . warn ( error ) ;
128- this . _resolvedSingleRoomId = undefined ;
129- this . emitChange ( "singleRoomMode" ) ;
130- }
131- }
132-
133140 if ( this . _resolvedSingleRoomId ) {
134- this . emitChange ( "singleRoomMode" ) ;
135141 this . navigation . push ( "room" , this . _resolvedSingleRoomId ) ;
136142 }
137143
@@ -161,6 +167,10 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
161167 if ( this . singleRoomMode || ! ( shouldRestoreLastUrl && this . urlRouter . tryRestoreLastUrl ( ) ) ) {
162168 const sessionInfos = await this . platform . sessionInfoStorage . getAll ( ) ;
163169 if ( sessionInfos . length === 0 ) {
170+ if ( this . _resolvedSingleRoomId ) {
171+ await this . _showUnknownRoom ( this . _resolvedSingleRoomId ) ;
172+ return ;
173+ }
164174 this . navigation . push ( Section . Login ) ;
165175 } else if ( sessionInfos . length === 1 ) {
166176 this . navigation . push ( Section . Session , sessionInfos [ 0 ] . id ) ;
@@ -169,23 +179,63 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
169179 }
170180 }
171181 } catch ( err ) {
182+ console . error ( err ) ;
172183 this . _setSection ( ( ) => this . _error = err ) ;
173184 }
174185 }
175186 }
176187
177- private async resolveRoomAlias ( sessionId : string , roomIdOrAlias : string ) : Promise < string > {
188+ private async resolveRoomAlias ( roomIdOrAlias : string , sessionId ?: string ) : Promise < string > {
189+ if ( roomIdOrAlias . startsWith ( '!' ) ) {
190+ return roomIdOrAlias ;
191+ }
192+
193+ let sessionInfo ;
194+ if ( sessionId ) {
195+ sessionInfo = await this . platform . sessionInfoStorage . get ( sessionId ) ;
196+ }
197+ let homeserver : string ;
198+ let accessToken : string ;
199+ if ( sessionInfo ) {
200+ homeserver = sessionInfo . homeserver ;
201+ accessToken = sessionInfo . accessToken ;
202+ } else {
203+ homeserver = await lookupHomeserver ( roomIdOrAlias . split ( ':' ) [ 1 ] , this . platform . request ) ;
204+ accessToken = '' ;
205+ }
206+
207+ const homeserverApi = new HomeServerApi ( {
208+ homeserver : homeserver ,
209+ request : this . platform . request ,
210+ accessToken : accessToken ,
211+ reconnector : this . platform . reconnector ,
212+ } ) ;
213+
214+ let response = await homeserverApi . resolveRoomAlias ( roomIdOrAlias ) . response ( ) ;
215+ return response . room_id ;
216+ }
217+
218+ private async isWorldReadableRoom ( roomId : string , sessionId : string ) : Promise < boolean > {
178219 const sessionInfo = await this . platform . sessionInfoStorage . get ( sessionId ) ;
179220 if ( ! sessionInfo ) {
180- throw new Error ( `Could not find session for id ${ sessionId } ` ) ;
221+ console . error ( `Could not find session for id ${ sessionId } ` ) ;
222+ return false ;
181223 }
182224
183- const homeserverApi = new HomeserverApi ( {
184- homeserver : sessionInfo . homeserver ,
185- request : this . platform . request
225+ const homeserver = await lookupHomeserver ( roomId . split ( ':' ) [ 1 ] , this . platform . request ) ;
226+ const homeserverApi = new HomeServerApi ( {
227+ homeserver : homeserver ,
228+ request : this . platform . request ,
229+ accessToken : sessionInfo . accessToken ,
230+ reconnector : this . platform . reconnector ,
186231 } ) ;
187232
188- return await homeserverApi . resolveRoomAlias ( roomIdOrAlias ) ;
233+ return homeserverApi . state ( roomId , 'm.room.history_visibility' , '' ) . response ( ) . then (
234+ response => response . history_visibility === 'world_readable'
235+ ) . catch ( err => {
236+ console . error ( err ) ;
237+ return false ;
238+ } ) ;
189239 }
190240
191241 private _showLogin ( loginToken : string | undefined ) {
@@ -255,6 +305,29 @@ export class RootViewModel extends ViewModel<SegmentType, Options> {
255305 } ) ;
256306 }
257307
308+ private async _showUnknownRoom ( roomId : string ) {
309+ const client = new Client ( this . platform ) ;
310+ let chosenSession ;
311+
312+ let sessionInfos = await this . platform . sessionInfoStorage . getAll ( ) ;
313+ if ( sessionInfos . length === 0 ) {
314+ const homeserver = await lookupHomeserver ( roomId . split ( ':' ) [ 1 ] , this . platform . request ) ;
315+ await client . doGuestLogin ( homeserver ) ;
316+ } else {
317+ await client . startWithExistingSession ( chosenSession . id ) ;
318+ }
319+
320+ this . _setSection ( ( ) => {
321+ this . _unknownRoomViewModel = new UnknownRoomViewModel ( this . childOptions ( {
322+ roomIdOrAlias : roomId ,
323+ session : client . session ,
324+ isWorldReadablePromise : this . isWorldReadableRoom ( roomId , client . sessionId ) ,
325+ } ) ) ;
326+ } ) ;
327+
328+ this . navigation . push ( "session" , client . sessionId ) ;
329+ }
330+
258331 private _setSection ( setter : Function ) {
259332 // Clear all members the activeSection depends on.
260333 this . _error = undefined ;
0 commit comments