@@ -40,6 +40,7 @@ import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
40
40
import io.element.android.features.rageshake.api.reporter.BugReporter
41
41
import io.element.android.features.signedout.api.SignedOutEntryPoint
42
42
import io.element.android.features.viewfolder.api.ViewFolderEntryPoint
43
+ import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint
43
44
import io.element.android.libraries.architecture.BackstackView
44
45
import io.element.android.libraries.architecture.BaseFlowNode
45
46
import io.element.android.libraries.architecture.createNode
@@ -58,6 +59,7 @@ import io.element.android.libraries.sessionstorage.api.SessionStore
58
59
import kotlinx.coroutines.flow.distinctUntilChanged
59
60
import kotlinx.coroutines.flow.launchIn
60
61
import kotlinx.coroutines.flow.onEach
62
+ import kotlinx.coroutines.launch
61
63
import kotlinx.parcelize.Parcelize
62
64
import timber.log.Timber
63
65
@@ -74,6 +76,7 @@ class RootFlowNode(
74
76
private val bugReportEntryPoint : BugReportEntryPoint ,
75
77
private val viewFolderEntryPoint : ViewFolderEntryPoint ,
76
78
private val signedOutEntryPoint : SignedOutEntryPoint ,
79
+ private val accountSelectEntryPoint : AccountSelectEntryPoint ,
77
80
private val intentResolver : IntentResolver ,
78
81
private val oidcActionFlow : OidcActionFlow ,
79
82
private val bugReporter : BugReporter ,
@@ -184,6 +187,12 @@ class RootFlowNode(
184
187
@Parcelize
185
188
data object SplashScreen : NavTarget
186
189
190
+ @Parcelize
191
+ data class AccountSelect (
192
+ val currentSessionId : SessionId ,
193
+ val intent : Intent ,
194
+ ) : NavTarget
195
+
187
196
@Parcelize
188
197
data class NotLoggedInFlow (
189
198
val params : LoginParams ?
@@ -278,6 +287,29 @@ class RootFlowNode(
278
287
.callback(callback)
279
288
.build()
280
289
}
290
+ is NavTarget .AccountSelect -> {
291
+ val callback: AccountSelectEntryPoint .Callback = object : AccountSelectEntryPoint .Callback {
292
+ override fun onAccountSelected (sessionId : SessionId ) {
293
+ lifecycleScope.launch {
294
+ if (sessionId == navTarget.currentSessionId) {
295
+ // Ensure that the account selection Node is removed from the backstack
296
+ // Do not pop when the account is changed to avoid a UI flicker.
297
+ backstack.pop()
298
+ }
299
+ attachSession(sessionId)
300
+ .attachIncomingShare(navTarget.intent)
301
+ }
302
+ }
303
+
304
+ override fun onCancel () {
305
+ backstack.pop()
306
+ }
307
+ }
308
+ accountSelectEntryPoint
309
+ .nodeBuilder(this , buildContext)
310
+ .callback(callback)
311
+ .build()
312
+ }
281
313
}
282
314
}
283
315
@@ -328,9 +360,20 @@ class RootFlowNode(
328
360
// No session, open login
329
361
switchToNotLoggedInFlow(null )
330
362
} else {
331
- // TODO Multi-account: show a screen to select an account
332
- attachSession(latestSessionId)
333
- .attachIncomingShare(intent)
363
+ // wait for the current session to be restored
364
+ val loggedInFlowNode = attachSession(latestSessionId)
365
+ if (sessionStore.getAllSessions().size > 1 ) {
366
+ // Several accounts, let the user choose which one to use
367
+ backstack.push(
368
+ NavTarget .AccountSelect (
369
+ currentSessionId = latestSessionId,
370
+ intent = intent,
371
+ )
372
+ )
373
+ } else {
374
+ // Only one account, directly attach the incoming share node.
375
+ loggedInFlowNode.attachIncomingShare(intent)
376
+ }
334
377
}
335
378
}
336
379
0 commit comments