BIT-711: Adding UI for AddyIo service (#456)

This commit is contained in:
joshua-livefront
2024-06-20 17:08:07 +01:00
committed by Álison Fernandes
parent 5ec810d4d6
commit 78461394f3
4 changed files with 367 additions and 19 deletions
@@ -817,6 +817,7 @@ private fun UsernameOptionsItem(
//region ForwardedEmailAliasType Composables
@Suppress("LongMethod")
@Composable
private fun ColumnScope.ForwardedEmailAliasTypeContent(
usernameTypeState: GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias,
@@ -833,8 +834,26 @@ private fun ColumnScope.ForwardedEmailAliasTypeContent(
when (usernameTypeState.selectedServiceType) {
is ServiceType.AnonAddy -> {
// TODO: AnonAddy Service Implementation (BIT-711)
is ServiceType.AddyIo -> {
BitwardenPasswordField(
label = stringResource(id = R.string.api_access_token),
value = usernameTypeState.selectedServiceType.apiAccessToken,
onValueChange = forwardedEmailAliasHandlers.onAddyIoAccessTokenTextChange,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
)
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
label = stringResource(id = R.string.domain_name_required_parenthesis),
value = usernameTypeState.selectedServiceType.domainName,
onValueChange = forwardedEmailAliasHandlers.onAddyIoDomainNameTextChange,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
)
}
is ServiceType.DuckDuckGo -> {
@@ -1185,10 +1204,13 @@ private class PassphraseHandlers(
*/
private class ForwardedEmailAliasHandlers(
val onServiceChange: (ServiceTypeOption) -> Unit,
val onAddyIoAccessTokenTextChange: (String) -> Unit,
val onAddyIoDomainNameTextChange: (String) -> Unit,
val onDuckDuckGoApiKeyTextChange: (String) -> Unit,
val onFirefoxRelayAccessTokenTextChange: (String) -> Unit,
) {
companion object {
@Suppress("LongMethod")
fun create(viewModel: GeneratorViewModel): ForwardedEmailAliasHandlers {
return ForwardedEmailAliasHandlers(
onServiceChange = { newServiceTypeOption ->
@@ -1203,6 +1225,32 @@ private class ForwardedEmailAliasHandlers(
),
)
},
onAddyIoAccessTokenTextChange = { newAccessToken ->
viewModel.trySendAction(
GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.AddyIo
.AccessTokenTextChange(
accessToken = newAccessToken,
),
)
},
onAddyIoDomainNameTextChange = { newDomainName ->
viewModel.trySendAction(
GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.AddyIo
.DomainTextChange(
domain = newDomainName,
),
)
},
onDuckDuckGoApiKeyTextChange = { newApiKey ->
viewModel.trySendAction(
GeneratorAction
@@ -1227,7 +1275,6 @@ private class ForwardedEmailAliasHandlers(
.AccessTokenTextChange(
accessToken = newAccessToken,
),
)
},
)
@@ -22,8 +22,11 @@ import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Pa
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.CatchAllEmail
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.AddyIo
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.DuckDuckGo
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.FastMail
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.FirefoxRelay
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.SimpleLogin
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.PlusAddressedEmail
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.RandomWord
@@ -115,6 +118,10 @@ class GeneratorViewModel @Inject constructor(
handleServiceTypeOptionSelect(action)
}
is GeneratorAction.MainType.Username.UsernameType.ForwardedEmailAlias.AddyIo -> {
handleAddyIoSpecificAction(action)
}
is GeneratorAction.MainType.Username.UsernameType.ForwardedEmailAlias.DuckDuckGo.ApiKeyTextChange -> {
handleDuckDuckGoTextInputChange(action)
}
@@ -554,15 +561,15 @@ class GeneratorViewModel @Inject constructor(
)
Username.UsernameTypeOption.CATCH_ALL_EMAIL -> loadUsernameOptions(
selectedType = Username(selectedType = Username.UsernameType.CatchAllEmail()),
selectedType = Username(selectedType = CatchAllEmail()),
)
Username.UsernameTypeOption.FORWARDED_EMAIL_ALIAS -> loadUsernameOptions(
selectedType = Username(selectedType = Username.UsernameType.ForwardedEmailAlias()),
selectedType = Username(selectedType = ForwardedEmailAlias()),
)
Username.UsernameTypeOption.RANDOM_WORD -> loadUsernameOptions(
selectedType = Username(selectedType = Username.UsernameType.RandomWord()),
selectedType = Username(selectedType = RandomWord()),
)
}
}
@@ -580,30 +587,92 @@ class GeneratorViewModel @Inject constructor(
.ServiceTypeOptionSelect,
) {
when (action.serviceTypeOption) {
ForwardedEmailAlias.ServiceTypeOption.ANON_ADDY -> updateForwardedEmailAliasType {
ForwardedEmailAlias(selectedServiceType = ServiceType.AnonAddy())
ForwardedEmailAlias.ServiceTypeOption.ADDY_IO -> updateForwardedEmailAliasType {
ForwardedEmailAlias(selectedServiceType = AddyIo())
}
ForwardedEmailAlias.ServiceTypeOption.DUCK_DUCK_GO -> updateForwardedEmailAliasType {
ForwardedEmailAlias(selectedServiceType = ServiceType.DuckDuckGo())
ForwardedEmailAlias(selectedServiceType = DuckDuckGo())
}
ForwardedEmailAlias.ServiceTypeOption.FAST_MAIL -> updateForwardedEmailAliasType {
ForwardedEmailAlias(selectedServiceType = ServiceType.FastMail())
ForwardedEmailAlias(selectedServiceType = FastMail())
}
ForwardedEmailAlias.ServiceTypeOption.FIREFOX_RELAY -> updateForwardedEmailAliasType {
ForwardedEmailAlias(selectedServiceType = ServiceType.FirefoxRelay())
ForwardedEmailAlias(selectedServiceType = FirefoxRelay())
}
ForwardedEmailAlias.ServiceTypeOption.SIMPLE_LOGIN -> updateForwardedEmailAliasType {
ForwardedEmailAlias(selectedServiceType = ServiceType.SimpleLogin())
ForwardedEmailAlias(selectedServiceType = SimpleLogin())
}
}
}
//endregion Forwarded Email Alias Specific Handlers
//region Addy.Io Service Specific Handlers
private fun handleAddyIoSpecificAction(
action: GeneratorAction.MainType.Username.UsernameType.ForwardedEmailAlias.AddyIo,
) {
when (action) {
is GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.AddyIo
.AccessTokenTextChange,
-> {
handleAddyIoAccessTokenTextChange(action)
}
is GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.AddyIo
.DomainTextChange,
-> {
handleAddyIoDomainNameTextChange(action)
}
}
}
private fun handleAddyIoAccessTokenTextChange(
action: GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.AddyIo
.AccessTokenTextChange,
) {
updateAddyIoServiceType { addyIoServiceType ->
val newAccessToken = action.accessToken
addyIoServiceType.copy(apiAccessToken = newAccessToken)
}
}
private fun handleAddyIoDomainNameTextChange(
action: GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.AddyIo
.DomainTextChange,
) {
updateAddyIoServiceType { addyIoServiceType ->
val newDomain = action.domain
addyIoServiceType.copy(domainName = newDomain)
}
}
//endregion Addy.Io Service Specific Handlers
//region DuckDuckGo Service Specific Handlers
private fun handleDuckDuckGoTextInputChange(
@@ -800,6 +869,30 @@ class GeneratorViewModel @Inject constructor(
}
}
private inline fun updateAddyIoServiceType(
crossinline block: (AddyIo) -> AddyIo,
) {
updateGeneratorMainTypeUsername { currentUsernameType ->
if (currentUsernameType.selectedType !is ForwardedEmailAlias) {
return@updateGeneratorMainTypeUsername currentUsernameType
}
val currentServiceType = (currentUsernameType.selectedType).selectedServiceType
if (currentServiceType !is AddyIo) {
return@updateGeneratorMainTypeUsername currentUsernameType
}
val updatedServiceType = block(currentServiceType)
currentUsernameType.copy(
selectedType = ForwardedEmailAlias(
selectedServiceType = updatedServiceType,
obfuscatedText = currentUsernameType.selectedType.obfuscatedText,
),
)
}
}
private inline fun updateDuckDuckGoServiceType(
crossinline block: (DuckDuckGo) -> DuckDuckGo,
) {
@@ -1173,7 +1266,7 @@ data class GeneratorState(
* the label for each type.
*/
enum class ServiceTypeOption(val labelRes: Int) {
ANON_ADDY(R.string.addy_io),
ADDY_IO(R.string.addy_io),
DUCK_DUCK_GO(R.string.duck_duck_go),
FAST_MAIL(R.string.fastmail),
FIREFOX_RELAY(R.string.firefox_relay),
@@ -1195,19 +1288,19 @@ data class GeneratorState(
abstract val displayStringResId: Int?
/**
* Represents the Anon Addy service type, with a configurable option for
* Represents the Addy Io service type, with a configurable option for
* service and api key.
*
* @property apiAccessToken The token used for generation.
* @property domainName The domain name used for generation.
*/
@Parcelize
data class AnonAddy(
data class AddyIo(
val apiAccessToken: String = "",
val domainName: String = "",
) : ServiceType(), Parcelable {
override val displayStringResId: Int
get() = ServiceTypeOption.ANON_ADDY.labelRes
get() = ServiceTypeOption.ADDY_IO.labelRes
}
/**
@@ -1498,6 +1591,26 @@ sealed class GeneratorAction {
.ServiceTypeOption,
) : ForwardedEmailAlias()
/**
* Represents actions specifically related to the AddyIo service.
*/
sealed class AddyIo : ForwardedEmailAlias() {
/**
* Fired when the access token input text is changed.
*
* @property accessToken The new access token text.
*/
data class AccessTokenTextChange(val accessToken: String) : AddyIo()
/**
* Fired when the domain text input is changed.
*
* @property domain The new domain text.
*/
data class DomainTextChange(val domain: String) : AddyIo()
}
/**
* Represents actions specifically related to the DuckDuckGo service.
*/