mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-17 04:20:00 +03:00
dynamically switching the onboarding flow based on the capabilities of the homeserver
- when avatars can't be changed we complete the personlisation flow
This commit is contained in:
parent
46be481eda
commit
716928d9d2
6 changed files with 66 additions and 25 deletions
|
@ -75,6 +75,7 @@ sealed class OnboardingAction : VectorViewModelAction {
|
|||
|
||||
data class UserAcceptCertificate(val fingerprint: Fingerprint) : OnboardingAction()
|
||||
|
||||
object PersonalizeProfile : OnboardingAction()
|
||||
data class UpdateDisplayName(val displayName: String) : OnboardingAction()
|
||||
object UpdateDisplayNameSkipped : OnboardingAction()
|
||||
data class ProfilePictureSelected(val uri: Uri) : OnboardingAction()
|
||||
|
|
|
@ -51,9 +51,8 @@ sealed class OnboardingViewEvents : VectorViewEvents {
|
|||
object OnAccountCreated : OnboardingViewEvents()
|
||||
object OnAccountSignedIn : OnboardingViewEvents()
|
||||
object OnTakeMeHome : OnboardingViewEvents()
|
||||
object OnPersonalizeProfile : OnboardingViewEvents()
|
||||
object OnDisplayNameUpdated : OnboardingViewEvents()
|
||||
object OnDisplayNameSkipped : OnboardingViewEvents()
|
||||
object OnChooseDisplayName : OnboardingViewEvents()
|
||||
object OnChooseProfilePicture : OnboardingViewEvents()
|
||||
object OnPersonalizationComplete : OnboardingViewEvents()
|
||||
object OnBack : OnboardingViewEvents()
|
||||
}
|
||||
|
|
|
@ -81,7 +81,6 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||
private val stringProvider: StringProvider,
|
||||
private val homeServerHistoryService: HomeServerHistoryService,
|
||||
private val vectorFeatures: VectorFeatures,
|
||||
private val vectorOverrides: VectorOverrides,
|
||||
private val analyticsTracker: AnalyticsTracker,
|
||||
private val uriFilenameResolver: UriFilenameResolver,
|
||||
private val vectorOverrides: VectorOverrides
|
||||
|
@ -158,12 +157,13 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||
is OnboardingAction.ResetAction -> handleResetAction(action)
|
||||
is OnboardingAction.UserAcceptCertificate -> handleUserAcceptCertificate(action)
|
||||
OnboardingAction.ClearHomeServerHistory -> handleClearHomeServerHistory()
|
||||
is OnboardingAction.PostViewEvent -> _viewEvents.post(action.viewEvent)
|
||||
is OnboardingAction.UpdateDisplayName -> updateDisplayName(action.displayName)
|
||||
OnboardingAction.UpdateDisplayNameSkipped -> _viewEvents.post(OnboardingViewEvents.OnDisplayNameSkipped)
|
||||
OnboardingAction.UpdateDisplayNameSkipped -> handleDisplayNameStepComplete()
|
||||
OnboardingAction.UpdateProfilePictureSkipped -> _viewEvents.post(OnboardingViewEvents.OnPersonalizationComplete)
|
||||
OnboardingAction.PersonalizeProfile -> handlePersonalizeProfile()
|
||||
is OnboardingAction.ProfilePictureSelected -> handleProfilePictureSelected(action)
|
||||
OnboardingAction.SaveSelectedProfilePicture -> updateProfilePicture()
|
||||
is OnboardingAction.PostViewEvent -> _viewEvents.post(action.viewEvent)
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
|
@ -921,7 +921,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||
personalizationState = personalizationState.copy(displayName = displayName)
|
||||
)
|
||||
}
|
||||
_viewEvents.post(OnboardingViewEvents.OnDisplayNameUpdated)
|
||||
handleDisplayNameStepComplete()
|
||||
} catch (error: Throwable) {
|
||||
setState { copy(asyncDisplayName = Fail(error)) }
|
||||
_viewEvents.post(OnboardingViewEvents.Failure(error))
|
||||
|
@ -929,12 +929,35 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handlePersonalizeProfile() {
|
||||
withPersonalisationState {
|
||||
when {
|
||||
it.supportsChangingDisplayName -> _viewEvents.post(OnboardingViewEvents.OnChooseDisplayName)
|
||||
it.supportsChangingProfilePicture -> _viewEvents.post(OnboardingViewEvents.OnChooseDisplayName)
|
||||
else -> throw IllegalStateException("It should not be possible to personalize without supporting display name or avatar changing")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDisplayNameStepComplete() {
|
||||
withPersonalisationState {
|
||||
when {
|
||||
it.supportsChangingProfilePicture -> _viewEvents.post(OnboardingViewEvents.OnChooseProfilePicture)
|
||||
else -> _viewEvents.post(OnboardingViewEvents.OnPersonalizationComplete)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleProfilePictureSelected(action: OnboardingAction.ProfilePictureSelected) {
|
||||
setState {
|
||||
copy(personalizationState = personalizationState.copy(selectedPictureUri = action.uri))
|
||||
}
|
||||
}
|
||||
|
||||
private fun withPersonalisationState(block: (PersonalizationState) -> Unit) {
|
||||
withState { block(it.personalizationState) }
|
||||
}
|
||||
|
||||
private fun updateProfilePicture() {
|
||||
withState { state ->
|
||||
when (val pictureUri = state.personalizationState.selectedPictureUri) {
|
||||
|
|
|
@ -44,7 +44,7 @@ class FtueAuthAccountCreatedFragment @Inject constructor(
|
|||
|
||||
private fun setupViews() {
|
||||
views.accountCreatedSubtitle.text = getString(R.string.ftue_account_created_subtitle, activeSessionHolder.getActiveSession().myUserId)
|
||||
views.accountCreatedPersonalize.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnPersonalizeProfile)) }
|
||||
views.accountCreatedPersonalize.debouncedClicks { viewModel.handle(OnboardingAction.PersonalizeProfile) }
|
||||
views.accountCreatedTakeMeHome.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) }
|
||||
views.accountCreatedTakeMeHomeCta.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) }
|
||||
}
|
||||
|
|
|
@ -232,10 +232,9 @@ class FtueAuthVariant(
|
|||
}
|
||||
is OnboardingViewEvents.OnAccountCreated -> onAccountCreated()
|
||||
OnboardingViewEvents.OnAccountSignedIn -> onAccountSignedIn()
|
||||
OnboardingViewEvents.OnPersonalizeProfile -> onPersonalizeProfile()
|
||||
OnboardingViewEvents.OnChooseDisplayName -> onChooseDisplayName()
|
||||
OnboardingViewEvents.OnTakeMeHome -> navigateToHome(createdAccount = true)
|
||||
OnboardingViewEvents.OnDisplayNameUpdated -> onDisplayNameUpdated()
|
||||
OnboardingViewEvents.OnDisplayNameSkipped -> onDisplayNameUpdated()
|
||||
OnboardingViewEvents.OnChooseProfilePicture -> onChooseProfilePicture()
|
||||
OnboardingViewEvents.OnPersonalizationComplete -> navigateToHome(createdAccount = true)
|
||||
OnboardingViewEvents.OnBack -> activity.popBackstack()
|
||||
}.exhaustive
|
||||
|
@ -412,14 +411,14 @@ class FtueAuthVariant(
|
|||
activity.finish()
|
||||
}
|
||||
|
||||
private fun onPersonalizeProfile() {
|
||||
private fun onChooseDisplayName() {
|
||||
activity.addFragmentToBackstack(views.loginFragmentContainer,
|
||||
FtueAuthChooseDisplayNameFragment::class.java,
|
||||
option = commonOption
|
||||
)
|
||||
}
|
||||
|
||||
private fun onDisplayNameUpdated() {
|
||||
private fun onChooseProfilePicture() {
|
||||
activity.addFragmentToBackstack(views.loginFragmentContainer,
|
||||
FtueAuthChooseProfilePictureFragment::class.java,
|
||||
option = commonOption
|
||||
|
|
|
@ -36,7 +36,6 @@ import im.vector.app.test.fakes.FakeStringProvider
|
|||
import im.vector.app.test.fakes.FakeUri
|
||||
import im.vector.app.test.fakes.FakeUriFilenameResolver
|
||||
import im.vector.app.test.fakes.FakeVectorFeatures
|
||||
import im.vector.app.test.fakes.FakeVectorOverrides
|
||||
import im.vector.app.test.test
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import org.junit.Before
|
||||
|
@ -111,21 +110,31 @@ class OnboardingViewModelTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `when handling display name update then updates upstream user display name`() = runBlockingTest {
|
||||
fun `given changing profile picture is supported when updating display name then updates upstream user display name and moves to choose profile picture`() = runBlockingTest {
|
||||
val personalisedInitialState = initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = true))
|
||||
viewModel = createViewModel(personalisedInitialState)
|
||||
val test = viewModel.test(this)
|
||||
|
||||
viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME))
|
||||
|
||||
test
|
||||
.assertStates(
|
||||
initialState,
|
||||
initialState.copy(asyncDisplayName = Loading()),
|
||||
initialState.copy(
|
||||
asyncDisplayName = Success(Unit),
|
||||
personalizationState = initialState.personalizationState.copy(displayName = A_DISPLAY_NAME)
|
||||
)
|
||||
)
|
||||
.assertEvents(OnboardingViewEvents.OnDisplayNameUpdated)
|
||||
.assertStates(expectedSuccessfulDisplayNameUpdateStates(personalisedInitialState))
|
||||
.assertEvents(OnboardingViewEvents.OnChooseProfilePicture)
|
||||
.finish()
|
||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given changing profile picture is not supported when updating display name then updates upstream user display name and completes personalization`() = runBlockingTest {
|
||||
val personalisedInitialState = initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = false))
|
||||
viewModel = createViewModel(personalisedInitialState)
|
||||
val test = viewModel.test(this)
|
||||
|
||||
viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME))
|
||||
|
||||
test
|
||||
.assertStates(expectedSuccessfulDisplayNameUpdateStates(personalisedInitialState))
|
||||
.assertEvents(OnboardingViewEvents.OnPersonalizationComplete)
|
||||
.finish()
|
||||
fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME)
|
||||
}
|
||||
|
@ -227,7 +236,6 @@ class OnboardingViewModelTest {
|
|||
FakeStringProvider().instance,
|
||||
FakeHomeServerHistoryService(),
|
||||
FakeVectorFeatures(),
|
||||
FakeVectorOverrides(),
|
||||
FakeAnalyticsTracker(),
|
||||
fakeUriFilenameResolver.instance,
|
||||
DefaultVectorOverrides()
|
||||
|
@ -259,4 +267,15 @@ class OnboardingViewModelTest {
|
|||
fakeAuthenticationService.expectReset()
|
||||
fakeSession.expectStartsSyncing()
|
||||
}
|
||||
|
||||
private fun expectedSuccessfulDisplayNameUpdateStates(personalisedInitialState: OnboardingViewState): List<OnboardingViewState> {
|
||||
return listOf(
|
||||
personalisedInitialState,
|
||||
personalisedInitialState.copy(asyncDisplayName = Loading()),
|
||||
personalisedInitialState.copy(
|
||||
asyncDisplayName = Success(Unit),
|
||||
personalizationState = personalisedInitialState.personalizationState.copy(displayName = A_DISPLAY_NAME)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue