Skip to content

Commit c5ae4f1

Browse files
committed
feat(account-setting): wire avatar to indicator selection
1 parent 8f59c9b commit c5ae4f1

File tree

12 files changed

+193
-46
lines changed

12 files changed

+193
-46
lines changed

core/ui/setting/api/src/commonMain/kotlin/net/thunderbird/core/ui/setting/SettingValue.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,24 @@ sealed interface SettingValue<T> : Setting {
6969
* @param value The currently selected option.
7070
* @param options The list of available options to choose from.
7171
*/
72-
data class CompactSelectSingleOption(
72+
data class CompactSelectSingleOption<T>(
7373
override val id: String,
7474
val title: () -> String,
7575
val description: () -> String? = { null },
76-
override val value: CompactOption,
77-
val options: ImmutableList<CompactOption>,
78-
) : SettingValue<CompactOption> {
76+
override val value: CompactOption<T>,
77+
val options: ImmutableList<CompactOption<T>>,
78+
) : SettingValue<CompactOption<T>> {
7979
override val requiresEditView: Boolean = false
8080

8181
init {
8282
require(options.size >= 2) { "There must be at least two options." }
8383
require(options.size <= 4) { "There can be at most four options." }
8484
}
8585

86-
data class CompactOption(
86+
data class CompactOption<T>(
8787
val id: String,
8888
val title: () -> String,
89+
val value: T,
8990
)
9091
}
9192

core/ui/setting/impl-dialog/src/debug/kotlin/net/thunderbird/core/ui/setting/dialog/ui/fake/FakeSettingData.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ internal object FakeSettingData {
3030
)
3131

3232
private val compactOptions = persistentListOf(
33-
CompactOption("1") { "Choice 1" },
34-
CompactOption("2") { "Choice 2" },
35-
CompactOption("3") { "Choice 3" },
33+
CompactOption(id = "1", title = { "Option 1" }, value = "1"),
34+
CompactOption(id = "2", title = { "Option 2" }, value = "2"),
35+
CompactOption(id = "3", title = { "Option 3" }, value = "3"),
3636
)
3737

3838
val compactSelectSingleOption = SettingValue.CompactSelectSingleOption(
@@ -44,12 +44,12 @@ internal object FakeSettingData {
4444
)
4545

4646
private val options = persistentListOf(
47-
Option("1") { "Compact Choice 1" },
48-
Option("2") { "Compact Choice 2" },
49-
Option("3") { "Compact Choice 3" },
50-
Option("1") { "Compact Choice 4" },
51-
Option("2") { "Compact Choice 5" },
52-
Option("3") { "Compact Choice 6" },
47+
Option("1") { "Option 1" },
48+
Option("2") { "Option 2" },
49+
Option("3") { "Option 3" },
50+
Option("4") { "Option 4" },
51+
Option("5") { "Option 5" },
52+
Option("6") { "Option 6" },
5353
)
5454

5555
val selectSingleOption = SettingValue.SelectSingleOption(

core/ui/setting/impl-dialog/src/main/kotlin/net/thunderbird/core/ui/setting/dialog/ui/components/dialog/SettingDialog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ internal fun SettingDialog(
5252
}
5353

5454
// No dialog needed
55-
is SettingValue.CompactSelectSingleOption, is SettingValue.Switch -> Unit
55+
is SettingValue.CompactSelectSingleOption<*>, is SettingValue.Switch -> Unit
5656
}
5757
}

core/ui/setting/impl-dialog/src/main/kotlin/net/thunderbird/core/ui/setting/dialog/ui/components/list/SettingItem.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private fun RenderSettingValue(
6363
)
6464
}
6565

66-
is SettingValue.CompactSelectSingleOption -> {
66+
is SettingValue.CompactSelectSingleOption<*> -> {
6767
CompactSelectSingleOptionItem(
6868
setting = setting,
6969
onSettingValueChange = onSettingValueChange,

core/ui/setting/impl-dialog/src/main/kotlin/net/thunderbird/core/ui/setting/dialog/ui/components/list/value/CompactSelectSingleOptionItem.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import app.k9mail.core.ui.compose.theme2.MainTheme
1212
import net.thunderbird.core.ui.setting.SettingValue
1313

1414
@Composable
15-
internal fun CompactSelectSingleOptionItem(
16-
setting: SettingValue.CompactSelectSingleOption,
15+
internal fun <T> CompactSelectSingleOptionItem(
16+
setting: SettingValue.CompactSelectSingleOption<T>,
1717
onSettingValueChange: (SettingValue<*>) -> Unit,
1818
modifier: Modifier = Modifier,
1919
) {

feature/account/settings/impl/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ android {
1414
}
1515

1616
dependencies {
17+
api(projects.feature.account.api)
1718
api(projects.feature.account.settings.api)
1819
implementation(projects.feature.account.core)
20+
implementation(projects.feature.account.avatar.api)
1921
implementation(projects.feature.account.avatar.impl)
2022

2123
implementation(projects.core.outcome)

feature/account/settings/impl/src/main/kotlin/net/thunderbird/feature/account/settings/AccountSettingsModule.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ val featureAccountSettingsModule = module {
3232
GetGeneralSettings(
3333
repository = get(),
3434
resourceProvider = get(),
35+
monogramCreator = get(),
3536
)
3637
}
3738

feature/account/settings/impl/src/main/kotlin/net/thunderbird/feature/account/settings/impl/domain/usecase/GetGeneralSettings.kt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import net.thunderbird.core.ui.setting.SettingValue
1010
import net.thunderbird.core.ui.setting.SettingValue.CompactSelectSingleOption.CompactOption
1111
import net.thunderbird.core.ui.setting.Settings
1212
import net.thunderbird.feature.account.AccountId
13+
import net.thunderbird.feature.account.avatar.AvatarMonogramCreator
1314
import net.thunderbird.feature.account.profile.AccountAvatar
1415
import net.thunderbird.feature.account.profile.AccountProfile
1516
import net.thunderbird.feature.account.profile.AccountProfileRepository
@@ -23,6 +24,7 @@ import net.thunderbird.feature.account.settings.impl.domain.entity.generateId
2324
internal class GetGeneralSettings(
2425
private val repository: AccountProfileRepository,
2526
private val resourceProvider: ResourceProvider.GeneralResourceProvider,
27+
private val monogramCreator: AvatarMonogramCreator,
2628
) : UseCase.GetGeneralSettings {
2729
override fun invoke(accountId: AccountId): Flow<AccountSettingsOutcome> {
2830
return repository.getById(accountId).map { profile ->
@@ -39,7 +41,7 @@ internal class GetGeneralSettings(
3941
}
4042

4143
private fun generateSettings(accountId: AccountId, profile: AccountProfile): Settings {
42-
val profileIndicatorOptions = generateProfileIndicatorOptions(profile.id)
44+
val profileIndicatorOptions = generateProfileIndicatorOptions(profile.id, profile.avatar, profile.name)
4345

4446
return persistentListOf(
4547
SettingDecoration.Custom(
@@ -73,33 +75,51 @@ internal class GetGeneralSettings(
7375
)
7476
}
7577

76-
private fun selectProfileIndicatorOption(profile: AccountProfile, options: List<CompactOption>): CompactOption {
78+
private fun selectProfileIndicatorOption(
79+
profile: AccountProfile,
80+
options: List<CompactOption<AccountAvatar>>,
81+
): CompactOption<AccountAvatar> {
7782
return when (profile.avatar) {
7883
is AccountAvatar.Monogram -> options.first {
7984
it.id == generateMonogramId(profile.id.asRaw())
8085
}
86+
8187
is AccountAvatar.Image -> options.first {
8288
it.id == generateImageId(profile.id.asRaw())
8389
}
90+
8491
is AccountAvatar.Icon -> options.first {
8592
it.id == generateIconId(profile.id.asRaw())
8693
}
8794
}
8895
}
8996

90-
private fun generateProfileIndicatorOptions(accountId: AccountId): ImmutableList<CompactOption> {
97+
private fun generateProfileIndicatorOptions(
98+
accountId: AccountId,
99+
avatar: AccountAvatar,
100+
name: String,
101+
): ImmutableList<CompactOption<AccountAvatar>> {
91102
return persistentListOf(
92103
CompactOption(
93104
id = generateMonogramId(accountId.asRaw()),
94105
title = resourceProvider.profileIndicatorMonogram,
106+
value = avatar as? AccountAvatar.Monogram ?: AccountAvatar.Monogram(
107+
value = monogramCreator.create(name, null),
108+
),
95109
),
96110
CompactOption(
97111
id = generateImageId(accountId.asRaw()),
98112
title = resourceProvider.profileIndicatorImage,
113+
value = avatar as? AccountAvatar.Image ?: AccountAvatar.Image(
114+
uri = "avatar_placeholder_uri",
115+
),
99116
),
100117
CompactOption(
101118
id = generateIconId(accountId.asRaw()),
102119
title = resourceProvider.profileIndicatorIcon,
120+
value = avatar as? AccountAvatar.Icon ?: AccountAvatar.Icon(
121+
name = "user",
122+
),
103123
),
104124
)
105125
}

feature/account/settings/impl/src/main/kotlin/net/thunderbird/feature/account/settings/impl/domain/usecase/UpdateGeneralSettings.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package net.thunderbird.feature.account.settings.impl.domain.usecase
33
import kotlinx.coroutines.flow.firstOrNull
44
import net.thunderbird.core.outcome.Outcome
55
import net.thunderbird.core.ui.setting.SettingValue
6+
import net.thunderbird.core.ui.setting.SettingValue.CompactSelectSingleOption.CompactOption
67
import net.thunderbird.feature.account.AccountId
78
import net.thunderbird.feature.account.profile.AccountAvatar
89
import net.thunderbird.feature.account.profile.AccountProfile
@@ -21,7 +22,16 @@ internal class UpdateGeneralSettings(
2122
): Outcome<Unit, SettingsError> {
2223
return when (setting.id) {
2324
GeneralPreference.PROFILE_INDICATOR.generateId(accountId) -> {
24-
val avatar = setting.value as AccountAvatar
25+
val option = setting.value as CompactOption<*>
26+
val avatar = option.value as? AccountAvatar
27+
28+
if (avatar == null) {
29+
return Outcome.failure(
30+
SettingsError.NotFound(
31+
message = "Invalid avatar option selected for accountId: $accountId",
32+
),
33+
)
34+
}
2535
updateAccountProfile(accountId) {
2636
copy(avatar = avatar)
2737
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.thunderbird.feature.account.settings.impl.domain.usecase
2+
3+
import net.thunderbird.feature.account.avatar.AvatarMonogramCreator
4+
5+
internal class FakeMonogramCreator : AvatarMonogramCreator {
6+
override fun create(name: String?, email: String?): String {
7+
return name?.take(2)?.uppercase() ?: "XX"
8+
}
9+
}

0 commit comments

Comments
 (0)