Skip to content

feat(new-registration): new registration personal account creation (WPB-17454) #4060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
Jun 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c61631f
new reg
yamilmedina Jun 3, 2025
c6eb8ac
Merge branch 'develop' into feat/new-regs-accountselector
yamilmedina Jun 3, 2025
d38bfd9
local FF for selector screen vs old flow
yamilmedina Jun 3, 2025
03bff85
flavor based FF for selector screen vs old flow
yamilmedina Jun 3, 2025
e4d4dad
wip
yamilmedina Jun 3, 2025
45778a8
selector components and actions
yamilmedina Jun 4, 2025
7802ad4
refactor component naming for reusage
yamilmedina Jun 4, 2025
edf322f
navigation to current native flows
yamilmedina Jun 4, 2025
fe1a8e3
selector components and actions
yamilmedina Jun 4, 2025
a50dfec
detekt
yamilmedina Jun 4, 2025
d786602
detekt
yamilmedina Jun 4, 2025
5a6846f
Merge branch 'develop' into feat/new-regs-accountselector
yamilmedina Jun 5, 2025
9544062
change path
yamilmedina Jun 5, 2025
6174622
wip for details, new navigation graph and pass email through
yamilmedina Jun 5, 2025
1e697e4
add deprecation notice for old routes
yamilmedina Jun 6, 2025
4daba9b
feat: changes for personal account, merging into one vm
yamilmedina Jun 6, 2025
6c8b56f
feat: changes for personal account, merging into one vm
yamilmedina Jun 6, 2025
05818ba
feat: changes for personal account, merging into one vm
yamilmedina Jun 6, 2025
23ff4a9
feat: changes for personal account, merging into one vm
yamilmedina Jun 6, 2025
2be20f3
feat: changes for personal account, merging into one vm
yamilmedina Jun 10, 2025
31b4cad
Merge branch 'develop' into feat/new-regs-accountselector
yamilmedina Jun 10, 2025
945d0c8
Merge branch 'feat/new-regs-accountselector' into feat/new-regs-perso…
yamilmedina Jun 10, 2025
d9c6876
feat: pr comments
yamilmedina Jun 10, 2025
ab63bb4
Merge branch 'feat/new-regs-accountselector' into feat/new-regs-perso…
yamilmedina Jun 10, 2025
27f16ff
wip, simplyfing and removing not needed code in new flow
yamilmedina Jun 10, 2025
4deb116
Merge branch 'develop' into feat/new-regs-personalacc
yamilmedina Jun 11, 2025
e2cc592
apply designs and navigation to verification code
yamilmedina Jun 11, 2025
8e00d5e
feat: integrate with usecase
yamilmedina Jun 11, 2025
1c19899
feat: implement new design to username
yamilmedina Jun 11, 2025
461b460
feat: implement new design to username
yamilmedina Jun 11, 2025
889c0b6
feat: implement new design to username
yamilmedina Jun 11, 2025
a282773
kalium ref
yamilmedina Jun 11, 2025
e37768d
Merge branch 'develop' into feat/new-regs-personalacc
yamilmedina Jun 11, 2025
a66429a
detekt
yamilmedina Jun 11, 2025
d5e5717
reduce duplication
yamilmedina Jun 11, 2025
5913725
detekt
yamilmedina Jun 11, 2025
ecd6fdb
detekt
yamilmedina Jun 11, 2025
07dd2eb
detekt
yamilmedina Jun 11, 2025
5be8855
add missing footer for personal acccount
yamilmedina Jun 12, 2025
6e4c3ef
detekt
yamilmedina Jun 12, 2025
fdeaafe
feat: pr comments
yamilmedina Jun 13, 2025
d64000a
Merge branch 'develop' into feat/new-regs-personalacc
yamilmedina Jun 13, 2025
3eb2df1
Merge branch 'develop' into feat/new-regs-personalacc
yamilmedina Jun 13, 2025
2e2815c
kalium ref
yamilmedina Jun 13, 2025
6df96db
Merge branch 'develop' into feat/new-regs-personalacc
yamilmedina Jun 16, 2025
4abedf5
feat(new-registration): team account creation from app to team settin…
yamilmedina Jun 16, 2025
f8a3036
Merge branch 'develop' into feat/new-regs-personalacc
yamilmedina Jun 16, 2025
b56fc53
kalium ref
yamilmedina Jun 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ import com.wire.android.navigation.BackStackMode
import com.wire.android.navigation.NavigationCommand
import com.wire.android.navigation.Navigator
import com.wire.android.navigation.annotation.app.WireDestination
import com.wire.android.ui.authentication.create.common.ServerTitle
import com.wire.android.ui.authentication.create.common.CreateAccountFlowType
import com.wire.android.ui.authentication.create.common.CreateAccountNavArgs
import com.wire.android.ui.authentication.create.common.CreatePersonalAccountNavGraph
import com.wire.android.ui.authentication.create.common.CreateTeamAccountNavGraph
import com.wire.android.ui.authentication.create.common.ServerTitle
import com.wire.android.ui.authentication.create.summary.CreateAccountSummaryNavArgs
import com.wire.android.ui.authentication.verificationcode.ResendCodeText
import com.wire.android.ui.common.WireDialog
Expand All @@ -64,6 +64,7 @@ import com.wire.android.ui.common.topappbar.NavigationIconType
import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar
import com.wire.android.ui.destinations.CreateAccountSummaryScreenDestination
import com.wire.android.ui.destinations.RemoveDeviceScreenDestination
import com.wire.android.ui.registration.code.CreateAccountCodeResult
import com.wire.android.ui.theme.wireColorScheme
import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography
Expand Down Expand Up @@ -96,7 +97,7 @@ fun CreateAccountCodeScreen(
serverConfig = serverConfig
)

(codeState.result as? CreateAccountCodeViewState.Result.Error.DialogError)?.let {
(codeState.result as? CreateAccountCodeResult.Error.DialogError)?.let {
val (title, message) = it.getResources(type = codeState.type)
WireDialog(
title = title,
Expand All @@ -110,10 +111,10 @@ fun CreateAccountCodeScreen(
)
}
LaunchedEffect(codeState.result) {
if (codeState.result is CreateAccountCodeViewState.Result.Success) {
if (codeState.result is CreateAccountCodeResult.Success) {
navigateToSummaryScreen()
}
if (codeState.result is CreateAccountCodeViewState.Result.Error.TooManyDevicesError) {
if (codeState.result is CreateAccountCodeResult.Error.TooManyDevicesError) {
clearCodeError()
clearCodeField()
navigator.navigate(NavigationCommand(RemoveDeviceScreenDestination, BackStackMode.CLEAR_WHOLE))
Expand Down Expand Up @@ -171,7 +172,7 @@ private fun CodeContent(
codeLength = state.codeLength,
textState = textState,
state = when (state.result) {
is CreateAccountCodeViewState.Result.Error.TextFieldError.InvalidActivationCodeError ->
is CreateAccountCodeResult.Error.TextFieldError.InvalidActivationCodeError ->
WireTextFieldState.Error(stringResource(id = R.string.create_account_code_error))

else -> WireTextFieldState.Default
Expand Down Expand Up @@ -199,33 +200,33 @@ private fun CodeContent(
}

@Composable
private fun CreateAccountCodeViewState.Result.Error.DialogError.getResources(type: CreateAccountFlowType) = when (this) {
CreateAccountCodeViewState.Result.Error.DialogError.AccountAlreadyExistsError -> DialogErrorStrings(
private fun CreateAccountCodeResult.Error.DialogError.getResources(type: CreateAccountFlowType) = when (this) {
CreateAccountCodeResult.Error.DialogError.AccountAlreadyExistsError -> DialogErrorStrings(
stringResource(id = R.string.create_account_code_error_title),
stringResource(id = R.string.create_account_email_already_in_use_error)
)

CreateAccountCodeViewState.Result.Error.DialogError.BlackListedError -> DialogErrorStrings(
CreateAccountCodeResult.Error.DialogError.BlackListedError -> DialogErrorStrings(
stringResource(id = R.string.create_account_code_error_title),
stringResource(id = R.string.create_account_email_blacklisted_error)
)

CreateAccountCodeViewState.Result.Error.DialogError.EmailDomainBlockedError -> DialogErrorStrings(
CreateAccountCodeResult.Error.DialogError.EmailDomainBlockedError -> DialogErrorStrings(
stringResource(id = R.string.create_account_code_error_title),
stringResource(id = R.string.create_account_email_domain_blocked_error)
)

CreateAccountCodeViewState.Result.Error.DialogError.InvalidEmailError -> DialogErrorStrings(
CreateAccountCodeResult.Error.DialogError.InvalidEmailError -> DialogErrorStrings(
stringResource(id = R.string.create_account_code_error_title),
stringResource(id = R.string.create_account_email_invalid_error)
)

CreateAccountCodeViewState.Result.Error.DialogError.TeamMembersLimitError -> DialogErrorStrings(
CreateAccountCodeResult.Error.DialogError.TeamMembersLimitError -> DialogErrorStrings(
stringResource(id = R.string.create_account_code_error_title),
stringResource(id = R.string.create_account_code_error_team_members_limit_reached)
)

CreateAccountCodeViewState.Result.Error.DialogError.CreationRestrictedError -> DialogErrorStrings(
CreateAccountCodeResult.Error.DialogError.CreationRestrictedError -> DialogErrorStrings(
stringResource(id = R.string.create_account_code_error_title),
stringResource(
id = when (type) {
Expand All @@ -235,10 +236,10 @@ private fun CreateAccountCodeViewState.Result.Error.DialogError.getResources(typ
)
)
// TODO: sync with design about the error message
CreateAccountCodeViewState.Result.Error.DialogError.UserAlreadyExistsError ->
CreateAccountCodeResult.Error.DialogError.UserAlreadyExistsError ->
DialogErrorStrings("User Already LoggedIn", "UserAlreadyLoggedIn")

is CreateAccountCodeViewState.Result.Error.DialogError.GenericError ->
is CreateAccountCodeResult.Error.DialogError.GenericError ->
this.coreFailure.dialogErrorStrings(LocalContext.current.resources)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.wire.android.ui.authentication.create.common.CreateAccountNavArgs
import com.wire.android.ui.common.textfield.textAsFlow
import com.wire.android.ui.navArgs
import com.wire.android.ui.registration.code.CreateAccountCodeResult
import com.wire.android.util.WillNeverOccurError
import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.logic.configuration.server.ServerConfig
Expand Down Expand Up @@ -103,7 +104,7 @@
}

fun clearCodeError() {
codeState = codeState.copy(result = CreateAccountCodeViewState.Result.None)
codeState = codeState.copy(result = CreateAccountCodeResult.None)

Check warning on line 107 in app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt#L107

Added line #L107 was not covered by tests
}

fun clearCodeField() {
Expand Down Expand Up @@ -193,19 +194,19 @@
}

is RegisterClientResult.Success -> {
codeState = codeState.copy(result = CreateAccountCodeViewState.Result.Success)
codeState = codeState.copy(result = CreateAccountCodeResult.Success)

Check warning on line 197 in app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt#L197

Added line #L197 was not covered by tests
}

is RegisterClientResult.E2EICertificateRequired -> {
// TODO
codeState = codeState.copy(result = CreateAccountCodeViewState.Result.Success)
codeState = codeState.copy(result = CreateAccountCodeResult.Success)

Check warning on line 202 in app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt#L202

Added line #L202 was not covered by tests
}
}
}
}
}

private fun updateCodeErrorState(codeError: CreateAccountCodeViewState.Result.Error) {
private fun updateCodeErrorState(codeError: CreateAccountCodeResult.Error) {
codeState = codeState.copy(loading = false, result = codeError)
}

Expand All @@ -219,8 +220,8 @@
)

private fun RegisterClientResult.Failure.toCodeError() = when (this) {
is RegisterClientResult.Failure.TooManyClients -> CreateAccountCodeViewState.Result.Error.TooManyDevicesError
is RegisterClientResult.Failure.Generic -> CreateAccountCodeViewState.Result.Error.DialogError.GenericError(this.genericFailure)
is RegisterClientResult.Failure.TooManyClients -> CreateAccountCodeResult.Error.TooManyDevicesError
is RegisterClientResult.Failure.Generic -> CreateAccountCodeResult.Error.DialogError.GenericError(this.genericFailure)
is RegisterClientResult.Failure.InvalidCredentials ->
throw WillNeverOccurError("RegisterClient: wrong password when register client after creating a new account")

Expand All @@ -229,30 +230,30 @@
}

private fun RegisterResult.Failure.toCodeError() = when (this) {
RegisterResult.Failure.InvalidActivationCode -> CreateAccountCodeViewState.Result.Error.TextFieldError.InvalidActivationCodeError
RegisterResult.Failure.AccountAlreadyExists -> CreateAccountCodeViewState.Result.Error.DialogError.AccountAlreadyExistsError
RegisterResult.Failure.BlackListed -> CreateAccountCodeViewState.Result.Error.DialogError.BlackListedError
RegisterResult.Failure.EmailDomainBlocked -> CreateAccountCodeViewState.Result.Error.DialogError.EmailDomainBlockedError
RegisterResult.Failure.InvalidEmail -> CreateAccountCodeViewState.Result.Error.DialogError.InvalidEmailError
RegisterResult.Failure.TeamMembersLimitReached -> CreateAccountCodeViewState.Result.Error.DialogError.TeamMembersLimitError
RegisterResult.Failure.UserCreationRestricted -> CreateAccountCodeViewState.Result.Error.DialogError.CreationRestrictedError
is RegisterResult.Failure.Generic -> CreateAccountCodeViewState.Result.Error.DialogError.GenericError(this.failure)
RegisterResult.Failure.InvalidActivationCode -> CreateAccountCodeResult.Error.TextFieldError.InvalidActivationCodeError
RegisterResult.Failure.AccountAlreadyExists -> CreateAccountCodeResult.Error.DialogError.AccountAlreadyExistsError
RegisterResult.Failure.BlackListed -> CreateAccountCodeResult.Error.DialogError.BlackListedError
RegisterResult.Failure.EmailDomainBlocked -> CreateAccountCodeResult.Error.DialogError.EmailDomainBlockedError
RegisterResult.Failure.InvalidEmail -> CreateAccountCodeResult.Error.DialogError.InvalidEmailError
RegisterResult.Failure.TeamMembersLimitReached -> CreateAccountCodeResult.Error.DialogError.TeamMembersLimitError
RegisterResult.Failure.UserCreationRestricted -> CreateAccountCodeResult.Error.DialogError.CreationRestrictedError
is RegisterResult.Failure.Generic -> CreateAccountCodeResult.Error.DialogError.GenericError(this.failure)
}

private fun AddAuthenticatedUserUseCase.Result.Failure.toCodeError() = when (this) {
is AddAuthenticatedUserUseCase.Result.Failure.Generic ->
CreateAccountCodeViewState.Result.Error.DialogError.GenericError(this.genericFailure)
CreateAccountCodeResult.Error.DialogError.GenericError(this.genericFailure)

Check warning on line 245 in app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt#L245

Added line #L245 was not covered by tests

AddAuthenticatedUserUseCase.Result.Failure.UserAlreadyExists ->
CreateAccountCodeViewState.Result.Error.DialogError.UserAlreadyExistsError
CreateAccountCodeResult.Error.DialogError.UserAlreadyExistsError

Check warning on line 248 in app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewModel.kt#L248

Added line #L248 was not covered by tests
}

private fun RequestActivationCodeResult.toCodeError() = when (this) {
RequestActivationCodeResult.Failure.AlreadyInUse -> CreateAccountCodeViewState.Result.Error.DialogError.AccountAlreadyExistsError
RequestActivationCodeResult.Failure.BlacklistedEmail -> CreateAccountCodeViewState.Result.Error.DialogError.BlackListedError
RequestActivationCodeResult.Failure.DomainBlocked -> CreateAccountCodeViewState.Result.Error.DialogError.EmailDomainBlockedError
RequestActivationCodeResult.Failure.InvalidEmail -> CreateAccountCodeViewState.Result.Error.DialogError.InvalidEmailError
is RequestActivationCodeResult.Failure.Generic -> CreateAccountCodeViewState.Result.Error.DialogError.GenericError(this.failure)
RequestActivationCodeResult.Success -> CreateAccountCodeViewState.Result.None
RequestActivationCodeResult.Failure.AlreadyInUse -> CreateAccountCodeResult.Error.DialogError.AccountAlreadyExistsError
RequestActivationCodeResult.Failure.BlacklistedEmail -> CreateAccountCodeResult.Error.DialogError.BlackListedError
RequestActivationCodeResult.Failure.DomainBlocked -> CreateAccountCodeResult.Error.DialogError.EmailDomainBlockedError
RequestActivationCodeResult.Failure.InvalidEmail -> CreateAccountCodeResult.Error.DialogError.InvalidEmailError
is RequestActivationCodeResult.Failure.Generic -> CreateAccountCodeResult.Error.DialogError.GenericError(this.failure)
RequestActivationCodeResult.Success -> CreateAccountCodeResult.None
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,13 @@
package com.wire.android.ui.authentication.create.code

import com.wire.android.ui.authentication.create.common.CreateAccountFlowType
import com.wire.kalium.common.error.CoreFailure
import com.wire.android.ui.registration.code.CreateAccountCodeResult
import com.wire.android.ui.registration.code.CreateAccountVerificationCodeViewState.Companion.DEFAULT_VERIFICATION_CODE_LENGTH

data class CreateAccountCodeViewState(
val type: CreateAccountFlowType,
val codeLength: Int = DEFAULT_VERIFICATION_CODE_LENGTH,
val email: String = "",
val loading: Boolean = false,
val result: Result = Result.None,
) {
sealed interface Result {
data object None : Result
data object Success : Result
sealed class Error : Result {
sealed class TextFieldError : Error() {
data object InvalidActivationCodeError : TextFieldError()
}

sealed class DialogError : Error() {
data object InvalidEmailError : DialogError()
data object AccountAlreadyExistsError : DialogError()
data object BlackListedError : DialogError()
data object EmailDomainBlockedError : DialogError()
data object TeamMembersLimitError : DialogError()
data object CreationRestrictedError : DialogError()
data object UserAlreadyExistsError : DialogError()
data class GenericError(val coreFailure: CoreFailure) : DialogError()
}
data object TooManyDevicesError : Error()
}
}
companion object {
const val DEFAULT_VERIFICATION_CODE_LENGTH = 6
}
}
val result: CreateAccountCodeResult = CreateAccountCodeResult.None,

Check warning on line 30 in app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewState.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/authentication/create/code/CreateAccountCodeViewState.kt#L30

Added line #L30 was not covered by tests
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.wire.kalium.logic.configuration.server.ServerConfig
import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.TypeParceler

@Deprecated("This nav arg belongs to the old registration flow, please use the new one [CreateAccountDataNavArgs]")
@Parcelize
@TypeParceler<ServerConfig.Links?, ServerConfigLinksParceler>()
data class CreateAccountNavArgs(
Expand All @@ -32,9 +33,17 @@ data class CreateAccountNavArgs(
val customServerConfig: ServerConfig.Links? = null,
) : Parcelable

@Parcelize
@TypeParceler<ServerConfig.Links?, ServerConfigLinksParceler>()
data class CreateAccountDataNavArgs(
val userRegistrationInfo: UserRegistrationInfo = UserRegistrationInfo(),
val customServerConfig: ServerConfig.Links? = null,
) : Parcelable

@Parcelize
data class UserRegistrationInfo(
val email: String = String.EMPTY,
val name: String = String.EMPTY,
val firstName: String = String.EMPTY,
val lastName: String = String.EMPTY,
val password: String = String.EMPTY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,22 @@ package com.wire.android.ui.authentication.create.common
import com.ramcosta.composedestinations.annotation.NavGraph
import com.ramcosta.composedestinations.annotation.RootNavGraph

@Deprecated("These destinations belongs to the old registration flow, please use the new one [CreateAccountNavGraph]")
@RootNavGraph
@NavGraph
annotation class CreatePersonalAccountNavGraph(
val start: Boolean = false
)

@Deprecated("These destinations belongs to the old registration flow, please use the new one [CreateAccountNavGraph]")
@RootNavGraph
@NavGraph
annotation class CreateTeamAccountNavGraph(
val start: Boolean = false
)

@RootNavGraph
@NavGraph
annotation class CreateAccountNavGraph(
val start: Boolean = false
)
Loading
Loading