From 158f597264cb25751b9070c094364199b2f9790c Mon Sep 17 00:00:00 2001 From: Boonapart Date: Tue, 15 Jul 2025 17:36:09 +0300 Subject: [PATCH 01/11] Add SocialAccount and EmailAccount to core --- .../models/EmailAccountColors.kt | 7 ++ .../models/EmailAccountDimens.kt | 8 ++ .../models/SocialAccountDimens.kt | 13 +++ .../ui/accountbinding/ui/AccountContainer.kt | 14 +++ .../ui/CurrentAccountOrDeleteContainer.kt | 30 ++++++ .../ui/accountbinding/ui/EmailAccount.kt | 95 +++++++++++++++++++ .../ui/accountbinding/ui/SocialAccount.kt | 71 ++++++++++++++ 7 files changed, 238 insertions(+) create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt new file mode 100644 index 00000000..93604292 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt @@ -0,0 +1,7 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.ui.graphics.Color + +data class EmailAccountColors( + val driverColor: Color = Color.Black +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt new file mode 100644 index 00000000..8d2a35ee --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt @@ -0,0 +1,8 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +data class EmailAccountDimens( + val dividerHeight: Dp = 1.dp +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt new file mode 100644 index 00000000..7510ab9e --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt @@ -0,0 +1,13 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.urlaunched.android.design.resources.dimens.Dimens + +data class SocialAccountDimens( + val paddingEnd: Dp = Dimens.spacingNormal, + val paddingStart: Dp = 14.dp, + val paddingTop: Dp = 14.dp, + val paddingBottom: Dp = 14.dp, + val paddingHorizontal: Dp = Dimens.spacingSmall, +) diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt new file mode 100644 index 00000000..b9437663 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt @@ -0,0 +1,14 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +internal fun AccountContainer(modifier: Modifier = Modifier, content: @Composable () -> Unit) { + Box( + modifier = modifier + ) { + content() + } +} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt new file mode 100644 index 00000000..3c8abe69 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt @@ -0,0 +1,30 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +internal fun CurrentAccountOrDeleteContainer( + modifier: Modifier = Modifier, + hasAccount: Boolean, + isCurrentAccount: Boolean, + currentAccountContainer: @Composable () -> Unit, + deleteAccountContainer: @Composable () -> Unit +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.End, + verticalArrangement = Arrangement.Center + ) { + if (hasAccount) { + if (isCurrentAccount) { + currentAccountContainer() + } else { + deleteAccountContainer() + } + } + } +} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt new file mode 100644 index 00000000..97ba42ca --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt @@ -0,0 +1,95 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.urlaunched.android.design.resources.dimens.Dimens +import com.urlaunched.android.design.ui.accountbinding.models.EmailAccountColors +import com.urlaunched.android.design.ui.accountbinding.models.EmailAccountDimens + +@Composable +fun EmailAccount( + modifier: Modifier = Modifier, + hasAccount: Boolean, + isCurrentAccount: Boolean, + hasEmail: Boolean, + emailAccountColors: EmailAccountColors, + emailAccountDimens: EmailAccountDimens = EmailAccountDimens(), + onEditEmailClick: () -> Unit, + onAddAccountClick: () -> Unit, + onEditPasswordClick: () -> Unit, + emailProviderText: @Composable () -> Unit, + accountEmailText: @Composable () -> Unit, + passwordText: @Composable () -> Unit, + trailingIcon: @Composable () -> Unit, + addAccountText: @Composable () -> Unit, + currentAccountContainer: @Composable () -> Unit, + deleteAccountContainer: @Composable () -> Unit +) { + AccountContainer( + modifier = modifier, + content = { + Column(modifier = Modifier.fillMaxWidth()) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(Dimens.spacingSmall), + modifier = Modifier + .clickable { + if (hasAccount) { + onEditEmailClick() + } else { + onAddAccountClick() + } + } + .padding(Dimens.spacingNormal) + ) { + emailProviderText() + + if (hasEmail) { + accountEmailText() + + trailingIcon() + } else { + addAccountText() + } + } + + if (hasAccount) { + HorizontalDivider( + modifier = Modifier.fillMaxWidth(), + color = emailAccountColors.driverColor, + thickness = emailAccountDimens.dividerHeight + ) + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = onEditPasswordClick) + .padding(Dimens.spacingNormal) + ) { + passwordText() + + trailingIcon() + } + } + } + } + ) + + CurrentAccountOrDeleteContainer( + modifier = Modifier.fillMaxWidth(), + hasAccount = hasAccount, + isCurrentAccount = isCurrentAccount, + currentAccountContainer = currentAccountContainer, + deleteAccountContainer = deleteAccountContainer + ) +} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt new file mode 100644 index 00000000..1940658f --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt @@ -0,0 +1,71 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.urlaunched.android.design.ui.accountbinding.models.SocialAccountDimens + +@Composable +fun SocialAccount( + modifier: Modifier = Modifier, + hasAccount: Boolean, + isCurrentAccount: Boolean, + hasEmail: Boolean, + socialAccountDimens: SocialAccountDimens = SocialAccountDimens(), + onAddAccountClick: () -> Unit, + leadingIcon: @Composable () -> Unit, + providerText: @Composable () -> Unit, + accountEmailText: @Composable () -> Unit, + addAccountText: @Composable () -> Unit, + currentAccountContainer: @Composable () -> Unit, + deleteAccountContainer: @Composable () -> Unit +) { + AccountContainer( + modifier = modifier, + content = { + Column( + modifier = Modifier + .fillMaxWidth() + .clickable( + enabled = true, + onClick = onAddAccountClick + ) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(socialAccountDimens.paddingHorizontal), + modifier = Modifier.padding( + end = socialAccountDimens.paddingEnd, + start = socialAccountDimens.paddingStart, + top = socialAccountDimens.paddingTop, + bottom = socialAccountDimens.paddingBottom + ) + ) { + leadingIcon() + + providerText() + + if (hasEmail) { + accountEmailText() + } else { + addAccountText() + } + } + } + } + ) + + CurrentAccountOrDeleteContainer( + modifier = Modifier.fillMaxWidth(), + hasAccount = hasAccount, + isCurrentAccount = isCurrentAccount, + currentAccountContainer = currentAccountContainer, + deleteAccountContainer = deleteAccountContainer + ) +} \ No newline at end of file From 3f9d2838bc8290d9c3d0eda284529a88ee8a687a Mon Sep 17 00:00:00 2001 From: Boonapart Date: Tue, 15 Jul 2025 17:47:17 +0300 Subject: [PATCH 02/11] Add design api --- design/api/current.api | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/design/api/current.api b/design/api/current.api index 0e9da44d..caea352d 100644 --- a/design/api/current.api +++ b/design/api/current.api @@ -67,6 +67,58 @@ package com.urlaunched.android.design.resources.dimens { } +package com.urlaunched.android.design.ui.accountbinding.models { + + public final class EmailAccountColors { + ctor public EmailAccountColors(optional long driverColor); + method public long component1-0d7_KjU(); + method public com.urlaunched.android.design.ui.accountbinding.models.EmailAccountColors copy-8_81llA(long driverColor); + method public long getDriverColor(); + property public final long driverColor; + } + + public final class EmailAccountDimens { + ctor public EmailAccountDimens(optional float dividerHeight); + method public float component1-D9Ej5fM(); + method public com.urlaunched.android.design.ui.accountbinding.models.EmailAccountDimens copy-0680j_4(float dividerHeight); + method public float getDividerHeight(); + property public final float dividerHeight; + } + + public final class SocialAccountDimens { + ctor public SocialAccountDimens(optional float paddingEnd, optional float paddingStart, optional float paddingTop, optional float paddingBottom, optional float paddingHorizontal); + method public float component1-D9Ej5fM(); + method public float component2-D9Ej5fM(); + method public float component3-D9Ej5fM(); + method public float component4-D9Ej5fM(); + method public float component5-D9Ej5fM(); + method public com.urlaunched.android.design.ui.accountbinding.models.SocialAccountDimens copy-RyVG9vg(float paddingEnd, float paddingStart, float paddingTop, float paddingBottom, float paddingHorizontal); + method public float getPaddingBottom(); + method public float getPaddingEnd(); + method public float getPaddingHorizontal(); + method public float getPaddingStart(); + method public float getPaddingTop(); + property public final float paddingBottom; + property public final float paddingEnd; + property public final float paddingHorizontal; + property public final float paddingStart; + property public final float paddingTop; + } + +} + +package com.urlaunched.android.design.ui.accountbinding.ui { + + public final class EmailAccountKt { + method @androidx.compose.runtime.Composable public static void EmailAccount(optional androidx.compose.ui.Modifier modifier, boolean hasAccount, boolean isCurrentAccount, boolean hasEmail, com.urlaunched.android.design.ui.accountbinding.models.EmailAccountColors emailAccountColors, optional com.urlaunched.android.design.ui.accountbinding.models.EmailAccountDimens emailAccountDimens, kotlin.jvm.functions.Function0 onEditEmailClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, kotlin.jvm.functions.Function0 emailProviderText, kotlin.jvm.functions.Function0 accountEmailText, kotlin.jvm.functions.Function0 passwordText, kotlin.jvm.functions.Function0 trailingIcon, kotlin.jvm.functions.Function0 addAccountText, kotlin.jvm.functions.Function0 currentAccountContainer, kotlin.jvm.functions.Function0 deleteAccountContainer); + } + + public final class SocialAccountKt { + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean hasAccount, boolean isCurrentAccount, boolean hasEmail, optional com.urlaunched.android.design.ui.accountbinding.models.SocialAccountDimens socialAccountDimens, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 leadingIcon, kotlin.jvm.functions.Function0 providerText, kotlin.jvm.functions.Function0 accountEmailText, kotlin.jvm.functions.Function0 addAccountText, kotlin.jvm.functions.Function0 currentAccountContainer, kotlin.jvm.functions.Function0 deleteAccountContainer); + } + +} + package com.urlaunched.android.design.ui.backhandler { public final class DisableBackButtonKt { From 0c3a9b0d67a2be9eb81779c10a880a1c4a5a3ee0 Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Thu, 2 Oct 2025 18:44:39 +0300 Subject: [PATCH 03/11] Create shadow style with overload --- .../urlaunched/android/design/ui/shadow/Shadow.kt | 9 +++++++++ .../android/design/ui/shadow/models/ShadowStyle.kt | 14 ++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/shadow/models/ShadowStyle.kt diff --git a/design/src/main/java/com/urlaunched/android/design/ui/shadow/Shadow.kt b/design/src/main/java/com/urlaunched/android/design/ui/shadow/Shadow.kt index 1a82bf7b..afb142e9 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/shadow/Shadow.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/shadow/Shadow.kt @@ -9,6 +9,15 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp +import com.urlaunched.android.design.ui.shadow.models.ShadowStyle + +fun Modifier.shadow(style: ShadowStyle) = this.shadow( + color = style.color, + alpha = style.alpha, + cornersRadius = style.cornersRadius, + shadowBlurRadius = style.blurRadius, + offset = style.offset +) fun Modifier.shadow( color: Color = Color.Black, diff --git a/design/src/main/java/com/urlaunched/android/design/ui/shadow/models/ShadowStyle.kt b/design/src/main/java/com/urlaunched/android/design/ui/shadow/models/ShadowStyle.kt new file mode 100644 index 00000000..ed8979bb --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/shadow/models/ShadowStyle.kt @@ -0,0 +1,14 @@ +package com.urlaunched.android.design.ui.shadow.models + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.dp + +data class ShadowStyle( + val color: Color = Color.Black, + val alpha: Float = 1f, + val cornersRadius: Dp = 0.dp, + val blurRadius: Dp = 0.dp, + val offset: DpOffset = DpOffset.Zero +) \ No newline at end of file From 795f0a6a6c818e9530f0b7a1a8461ac344dbd439 Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Tue, 7 Oct 2025 13:27:22 +0300 Subject: [PATCH 04/11] Refactor email and social accounts binding cards --- .../constants/SocialAccountDimens.kt | 16 ++ .../models/EmailAccountColors.kt | 7 - .../models/EmailAccountDimens.kt | 8 - .../models/SocialAccountDimens.kt | 13 - .../ui/accountbinding/ui/AccountContainer.kt | 14 - .../ui/CurrentAccountOrDeleteContainer.kt | 30 --- .../ui/accountbinding/ui/EmailAccount.kt | 242 +++++++++++++----- .../ui/accountbinding/ui/SocialAccount.kt | 182 ++++++++++--- 8 files changed, 342 insertions(+), 170 deletions(-) create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt delete mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt delete mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt delete mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt delete mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt delete mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt new file mode 100644 index 00000000..e83a43e1 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt @@ -0,0 +1,16 @@ +package com.urlaunched.android.design.ui.accountbinding.constants + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.ui.unit.dp +import com.urlaunched.android.design.resources.dimens.Dimens + +internal object SocialAccountDimens { + private val defaultSocialAccountCardPadding = 14.dp + + val defaultContentPadding = PaddingValues( + end = Dimens.spacingNormal, + start = defaultSocialAccountCardPadding, + top = defaultSocialAccountCardPadding, + bottom = defaultSocialAccountCardPadding + ) +} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt deleted file mode 100644 index 93604292..00000000 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountColors.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.urlaunched.android.design.ui.accountbinding.models - -import androidx.compose.ui.graphics.Color - -data class EmailAccountColors( - val driverColor: Color = Color.Black -) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt deleted file mode 100644 index 8d2a35ee..00000000 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/EmailAccountDimens.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.urlaunched.android.design.ui.accountbinding.models - -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -data class EmailAccountDimens( - val dividerHeight: Dp = 1.dp -) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt deleted file mode 100644 index 7510ab9e..00000000 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/SocialAccountDimens.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.urlaunched.android.design.ui.accountbinding.models - -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.urlaunched.android.design.resources.dimens.Dimens - -data class SocialAccountDimens( - val paddingEnd: Dp = Dimens.spacingNormal, - val paddingStart: Dp = 14.dp, - val paddingTop: Dp = 14.dp, - val paddingBottom: Dp = 14.dp, - val paddingHorizontal: Dp = Dimens.spacingSmall, -) diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt deleted file mode 100644 index b9437663..00000000 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountContainer.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.urlaunched.android.design.ui.accountbinding.ui - -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@Composable -internal fun AccountContainer(modifier: Modifier = Modifier, content: @Composable () -> Unit) { - Box( - modifier = modifier - ) { - content() - } -} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt deleted file mode 100644 index 3c8abe69..00000000 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/CurrentAccountOrDeleteContainer.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.urlaunched.android.design.ui.accountbinding.ui - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier - -@Composable -internal fun CurrentAccountOrDeleteContainer( - modifier: Modifier = Modifier, - hasAccount: Boolean, - isCurrentAccount: Boolean, - currentAccountContainer: @Composable () -> Unit, - deleteAccountContainer: @Composable () -> Unit -) { - Column( - modifier = modifier, - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.Center - ) { - if (hasAccount) { - if (isCurrentAccount) { - currentAccountContainer() - } else { - deleteAccountContainer() - } - } - } -} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt index 97ba42ca..b9b9a5e8 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt @@ -1,95 +1,221 @@ package com.urlaunched.android.design.ui.accountbinding.ui -import androidx.compose.foundation.clickable +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.KeyboardArrowRight import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import com.urlaunched.android.design.resources.dimens.Dimens -import com.urlaunched.android.design.ui.accountbinding.models.EmailAccountColors -import com.urlaunched.android.design.ui.accountbinding.models.EmailAccountDimens +import com.urlaunched.android.design.ui.clickable.debouncedClickable +import com.urlaunched.android.design.ui.modifiers.ifNotNull +import com.urlaunched.android.design.ui.shadow.models.ShadowStyle +import com.urlaunched.android.design.ui.shadow.shadow @Composable fun EmailAccount( modifier: Modifier = Modifier, - hasAccount: Boolean, isCurrentAccount: Boolean, + hasAccount: Boolean, hasEmail: Boolean, - emailAccountColors: EmailAccountColors, - emailAccountDimens: EmailAccountDimens = EmailAccountDimens(), + containerColor: Color = Color.White, + shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), + shadow: ShadowStyle? = null, onEditEmailClick: () -> Unit, onAddAccountClick: () -> Unit, onEditPasswordClick: () -> Unit, - emailProviderText: @Composable () -> Unit, - accountEmailText: @Composable () -> Unit, - passwordText: @Composable () -> Unit, - trailingIcon: @Composable () -> Unit, - addAccountText: @Composable () -> Unit, - currentAccountContainer: @Composable () -> Unit, - deleteAccountContainer: @Composable () -> Unit + contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), + supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), + divider: @Composable () -> Unit = { + HorizontalDivider() + }, + emailProviderContent: @Composable RowScope.() -> Unit, + accountEmail: @Composable RowScope.() -> Unit, + passwordContent: @Composable RowScope.() -> Unit, + trailingIcon: @Composable RowScope.() -> Unit, + noAccountContent: @Composable RowScope.() -> Unit, + deleteAccount: @Composable ColumnScope.() -> Unit, + currentAccount: @Composable ColumnScope.() -> Unit ) { - AccountContainer( + EmailAccount( + cardModifier = Modifier + .ifNotNull(shadow) { Modifier.shadow(it) } + .clip(shape) + .background(containerColor), modifier = modifier, - content = { - Column(modifier = Modifier.fillMaxWidth()) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(Dimens.spacingSmall), + hasAccount = hasAccount, + hasEmail = hasEmail, + onEditEmailClick = onEditEmailClick, + onAddAccountClick = onAddAccountClick, + onEditPasswordClick = onEditPasswordClick, + contentPadding = contentPadding, + divider = divider, + emailProviderContent = emailProviderContent, + accountEmail = accountEmail, + passwordContent = passwordContent, + trailingIcon = trailingIcon, + noAccountContent = noAccountContent, + supportingContent = { + if (hasAccount) { + Column( + horizontalAlignment = Alignment.End, modifier = Modifier - .clickable { - if (hasAccount) { - onEditEmailClick() - } else { - onAddAccountClick() - } - } - .padding(Dimens.spacingNormal) + .fillMaxWidth() + .padding(supportingContentPadding) ) { - emailProviderText() - - if (hasEmail) { - accountEmailText() - - trailingIcon() + if (isCurrentAccount) { + currentAccount() } else { - addAccountText() + deleteAccount() } } + } + } + ) +} - if (hasAccount) { - HorizontalDivider( - modifier = Modifier.fillMaxWidth(), - color = emailAccountColors.driverColor, - thickness = emailAccountDimens.dividerHeight - ) +@Composable +fun EmailAccount( + modifier: Modifier = Modifier, + cardModifier: Modifier = Modifier, + hasAccount: Boolean, + hasEmail: Boolean, + onEditEmailClick: () -> Unit, + onAddAccountClick: () -> Unit, + onEditPasswordClick: () -> Unit, + contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), + divider: @Composable () -> Unit = { + HorizontalDivider() + }, + emailProviderContent: @Composable RowScope.() -> Unit, + accountEmail: @Composable RowScope.() -> Unit, + passwordContent: @Composable RowScope.() -> Unit, + trailingIcon: @Composable RowScope.() -> Unit, + noAccountContent: @Composable RowScope.() -> Unit, + supportingContent: @Composable ColumnScope.() -> Unit = {} +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.End + ) { + Column(modifier = cardModifier) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .debouncedClickable { + if (hasAccount) { + onEditEmailClick() + } else { + onAddAccountClick() + } + } + .padding(contentPadding) + ) { + emailProviderContent() - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = onEditPasswordClick) - .padding(Dimens.spacingNormal) - ) { - passwordText() + Spacer(Modifier.weight(1f)) - trailingIcon() - } + if (hasEmail) { + accountEmail() + + trailingIcon() + } else { + noAccountContent() + } + } + + if (hasAccount) { + divider() + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .debouncedClickable(onClick = onEditPasswordClick) + .padding(contentPadding) + ) { + passwordContent() + + trailingIcon() } } } - ) - CurrentAccountOrDeleteContainer( - modifier = Modifier.fillMaxWidth(), - hasAccount = hasAccount, - isCurrentAccount = isCurrentAccount, - currentAccountContainer = currentAccountContainer, - deleteAccountContainer = deleteAccountContainer + supportingContent() + } +} + +@Preview +@Composable +private fun EmailAccountPreview() { + EmailAccount( + isCurrentAccount = true, + hasAccount = true, + hasEmail = true, + modifier = Modifier + .background(Color.LightGray) + .padding(Dimens.spacingNormal), + onEditEmailClick = { }, + onAddAccountClick = { }, + onEditPasswordClick = { }, + emailProviderContent = { + Text( + text = "Gmail", + fontWeight = FontWeight.Bold + ) + }, + accountEmail = { + Text( + text = "someone@gmail.com", + textAlign = TextAlign.End, + modifier = Modifier.padding(end = Dimens.spacingSmall) + ) + }, + passwordContent = { + Text("Password") + }, + trailingIcon = { + Icon( + imageVector = Icons.Rounded.KeyboardArrowRight, + contentDescription = null + ) + }, + noAccountContent = { + Text( + text = "Add account" + ) + }, + currentAccount = { + Text( + text = "Current account" + ) + }, + deleteAccount = { + Text( + text = "Delete", + color = Color.Red + ) + } ) } \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt index 1940658f..59249d0b 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt @@ -1,71 +1,173 @@ package com.urlaunched.android.design.ui.accountbinding.ui -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Email +import androidx.compose.material3.Icon +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import com.urlaunched.android.design.ui.accountbinding.models.SocialAccountDimens +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import com.urlaunched.android.design.resources.dimens.Dimens +import com.urlaunched.android.design.ui.accountbinding.constants.SocialAccountDimens +import com.urlaunched.android.design.ui.clickable.debouncedClickable +import com.urlaunched.android.design.ui.modifiers.ifNotNull +import com.urlaunched.android.design.ui.shadow.models.ShadowStyle +import com.urlaunched.android.design.ui.shadow.shadow @Composable fun SocialAccount( modifier: Modifier = Modifier, - hasAccount: Boolean, isCurrentAccount: Boolean, + hasAccount: Boolean, hasEmail: Boolean, - socialAccountDimens: SocialAccountDimens = SocialAccountDimens(), + containerColor: Color = Color.White, + shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), + shadow: ShadowStyle? = null, onAddAccountClick: () -> Unit, - leadingIcon: @Composable () -> Unit, - providerText: @Composable () -> Unit, - accountEmailText: @Composable () -> Unit, - addAccountText: @Composable () -> Unit, - currentAccountContainer: @Composable () -> Unit, - deleteAccountContainer: @Composable () -> Unit + contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, + supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), + providerContent: @Composable RowScope.() -> Unit, + accountEmail: @Composable RowScope.() -> Unit, + addAccount: @Composable RowScope.() -> Unit, + deleteAccount: @Composable ColumnScope.() -> Unit, + currentAccount: @Composable ColumnScope.() -> Unit ) { - AccountContainer( + SocialAccount( + cardModifier = Modifier + .ifNotNull(shadow) { Modifier.shadow(it) } + .clip(shape) + .background(containerColor), modifier = modifier, - content = { - Column( + enabled = hasAccount, + hasEmail = hasEmail, + onAddAccountClick = onAddAccountClick, + contentPadding = contentPadding, + accountEmail = accountEmail, + addAccount = addAccount, + providerContent = providerContent, + supportingContent = { + if (hasAccount) { + Column( + horizontalAlignment = Alignment.End, + modifier = Modifier + .fillMaxWidth() + .padding(supportingContentPadding) + ) { + if (isCurrentAccount) { + currentAccount() + } else { + deleteAccount() + } + } + } + } + ) +} + +@Composable +fun SocialAccount( + modifier: Modifier = Modifier, + cardModifier: Modifier = Modifier, + hasEmail: Boolean, + enabled: Boolean = true, + onAddAccountClick: () -> Unit, + contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, + providerContent: @Composable RowScope.() -> Unit, + accountEmail: @Composable RowScope.() -> Unit, + addAccount: @Composable RowScope.() -> Unit, + supportingContent: @Composable ColumnScope.() -> Unit = {} +) { + Column( + modifier = modifier + ) { + Column(modifier = cardModifier) { + Row( + verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .clickable( - enabled = true, + .debouncedClickable( + enabled = enabled, onClick = onAddAccountClick ) + .padding(contentPadding) ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(socialAccountDimens.paddingHorizontal), - modifier = Modifier.padding( - end = socialAccountDimens.paddingEnd, - start = socialAccountDimens.paddingStart, - top = socialAccountDimens.paddingTop, - bottom = socialAccountDimens.paddingBottom - ) - ) { - leadingIcon() + providerContent() - providerText() + Spacer(Modifier.weight(1f)) - if (hasEmail) { - accountEmailText() - } else { - addAccountText() - } + if (hasEmail) { + accountEmail() + } else { + addAccount() } } } - ) - CurrentAccountOrDeleteContainer( - modifier = Modifier.fillMaxWidth(), - hasAccount = hasAccount, - isCurrentAccount = isCurrentAccount, - currentAccountContainer = currentAccountContainer, - deleteAccountContainer = deleteAccountContainer + supportingContent() + } +} + +@Preview +@Composable +private fun SocialAccountPreview() { + SocialAccount( + hasEmail = true, + hasAccount = true, + isCurrentAccount = true, + modifier = Modifier + .background(Color.LightGray) + .padding(Dimens.spacingNormal), + onAddAccountClick = {}, + providerContent = { + Icon( + imageVector = Icons.Default.Email, + contentDescription = null + ) + + Spacer(Modifier.width(Dimens.spacingSmall)) + + Text( + text = "Gmail", + fontWeight = FontWeight.Bold + ) + }, + accountEmail = { + Text( + text = "someone@gmail.com" + ) + }, + addAccount = { + Text( + text = "Add account", + modifier = Modifier.padding(end = Dimens.spacingSmall) + ) + }, + currentAccount = { + Text( + text = "Current account" + ) + }, + deleteAccount = { + Text( + text = "Delete", + color = Color.Red + ) + } ) } \ No newline at end of file From cb6f861d47e8b693cbfd606db2ae8bf16bfb299b Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Tue, 7 Oct 2025 13:31:14 +0300 Subject: [PATCH 05/11] Update api --- design/api/current.api | 71 +++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/design/api/current.api b/design/api/current.api index caea352d..56412b53 100644 --- a/design/api/current.api +++ b/design/api/current.api @@ -67,54 +67,16 @@ package com.urlaunched.android.design.resources.dimens { } -package com.urlaunched.android.design.ui.accountbinding.models { - - public final class EmailAccountColors { - ctor public EmailAccountColors(optional long driverColor); - method public long component1-0d7_KjU(); - method public com.urlaunched.android.design.ui.accountbinding.models.EmailAccountColors copy-8_81llA(long driverColor); - method public long getDriverColor(); - property public final long driverColor; - } - - public final class EmailAccountDimens { - ctor public EmailAccountDimens(optional float dividerHeight); - method public float component1-D9Ej5fM(); - method public com.urlaunched.android.design.ui.accountbinding.models.EmailAccountDimens copy-0680j_4(float dividerHeight); - method public float getDividerHeight(); - property public final float dividerHeight; - } - - public final class SocialAccountDimens { - ctor public SocialAccountDimens(optional float paddingEnd, optional float paddingStart, optional float paddingTop, optional float paddingBottom, optional float paddingHorizontal); - method public float component1-D9Ej5fM(); - method public float component2-D9Ej5fM(); - method public float component3-D9Ej5fM(); - method public float component4-D9Ej5fM(); - method public float component5-D9Ej5fM(); - method public com.urlaunched.android.design.ui.accountbinding.models.SocialAccountDimens copy-RyVG9vg(float paddingEnd, float paddingStart, float paddingTop, float paddingBottom, float paddingHorizontal); - method public float getPaddingBottom(); - method public float getPaddingEnd(); - method public float getPaddingHorizontal(); - method public float getPaddingStart(); - method public float getPaddingTop(); - property public final float paddingBottom; - property public final float paddingEnd; - property public final float paddingHorizontal; - property public final float paddingStart; - property public final float paddingTop; - } - -} - package com.urlaunched.android.design.ui.accountbinding.ui { public final class EmailAccountKt { - method @androidx.compose.runtime.Composable public static void EmailAccount(optional androidx.compose.ui.Modifier modifier, boolean hasAccount, boolean isCurrentAccount, boolean hasEmail, com.urlaunched.android.design.ui.accountbinding.models.EmailAccountColors emailAccountColors, optional com.urlaunched.android.design.ui.accountbinding.models.EmailAccountDimens emailAccountDimens, kotlin.jvm.functions.Function0 onEditEmailClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, kotlin.jvm.functions.Function0 emailProviderText, kotlin.jvm.functions.Function0 accountEmailText, kotlin.jvm.functions.Function0 passwordText, kotlin.jvm.functions.Function0 trailingIcon, kotlin.jvm.functions.Function0 addAccountText, kotlin.jvm.functions.Function0 currentAccountContainer, kotlin.jvm.functions.Function0 deleteAccountContainer); + method @androidx.compose.runtime.Composable public static void EmailAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasAccount, boolean hasEmail, kotlin.jvm.functions.Function0 onEditEmailClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 emailProviderContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, optional kotlin.jvm.functions.Function1 supportingContent); + method @androidx.compose.runtime.Composable public static void EmailAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasEmail, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onEditEmailClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 emailProviderContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); } public final class SocialAccountKt { - method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean hasAccount, boolean isCurrentAccount, boolean hasEmail, optional com.urlaunched.android.design.ui.accountbinding.models.SocialAccountDimens socialAccountDimens, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 leadingIcon, kotlin.jvm.functions.Function0 providerText, kotlin.jvm.functions.Function0 accountEmailText, kotlin.jvm.functions.Function0 addAccountText, kotlin.jvm.functions.Function0 currentAccountContainer, kotlin.jvm.functions.Function0 deleteAccountContainer); + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasEmail, optional boolean enabled, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 addAccount, optional kotlin.jvm.functions.Function1 supportingContent); + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasEmail, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 addAccount, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); } } @@ -480,11 +442,36 @@ package com.urlaunched.android.design.ui.scrollbar.controller { package com.urlaunched.android.design.ui.shadow { public final class ShadowKt { + method public static androidx.compose.ui.Modifier shadow(androidx.compose.ui.Modifier, com.urlaunched.android.design.ui.shadow.models.ShadowStyle style); method public static androidx.compose.ui.Modifier shadow(androidx.compose.ui.Modifier, optional long color, optional float alpha, optional float cornersRadius, optional float shadowBlurRadius, optional long offset); } } +package com.urlaunched.android.design.ui.shadow.models { + + public final class ShadowStyle { + ctor public ShadowStyle(optional long color, optional float alpha, optional float cornersRadius, optional float blurRadius, optional long offset); + method public long component1-0d7_KjU(); + method public float component2(); + method public float component3-D9Ej5fM(); + method public float component4-D9Ej5fM(); + method public long component5-RKDOV3M(); + method public com.urlaunched.android.design.ui.shadow.models.ShadowStyle copy-w1ByDHw(long color, float alpha, float cornersRadius, float blurRadius, long offset); + method public float getAlpha(); + method public float getBlurRadius(); + method public long getColor(); + method public float getCornersRadius(); + method public long getOffset(); + property public final float alpha; + property public final float blurRadius; + property public final long color; + property public final float cornersRadius; + property public final long offset; + } + +} + package com.urlaunched.android.design.ui.shimmer { public final class ShimmerKt { From 7607845f03e96abfe387a2086c4a6134c6289224 Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Tue, 14 Oct 2025 12:26:35 +0300 Subject: [PATCH 06/11] Add account binding container --- design/build.gradle | 1 + .../constants/SocialAccountDimens.kt | 3 + .../ui/accountbinding/models/Account.kt | 11 + .../models/AccountBindingDimens.kt | 9 + .../models/AccountBindingTextStyles.kt | 13 + .../models/AccountBindingTitles.kt | 8 + .../accountbinding/models/AccountCardStyle.kt | 22 ++ .../accountbinding/models/AccountProvider.kt | 33 ++ .../accountbinding/models/AccountsSection.kt | 10 + .../ui/AccountBindingContainer.kt | 355 ++++++++++++++++++ .../ui/accountbinding/ui/SocialAccount.kt | 2 +- .../src/main/res/drawable/ic_apple_icon.xml | 9 + .../main/res/drawable/ic_facebook_icon.xml | 9 + .../src/main/res/drawable/ic_google_icon.xml | 22 ++ design/src/main/res/values/strings.xml | 7 + gradle/libs.versions.toml | 1 + 16 files changed, 514 insertions(+), 1 deletion(-) create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingDimens.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTitles.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt create mode 100644 design/src/main/res/drawable/ic_apple_icon.xml create mode 100644 design/src/main/res/drawable/ic_facebook_icon.xml create mode 100644 design/src/main/res/drawable/ic_google_icon.xml create mode 100644 design/src/main/res/values/strings.xml diff --git a/design/build.gradle b/design/build.gradle index 38319e3a..f1594e52 100644 --- a/design/build.gradle +++ b/design/build.gradle @@ -69,6 +69,7 @@ dependencies { implementation libs.composeDependencies.composePreview implementation libs.composeDependencies.composeMaterial3 implementation libs.composeDependencies.composeMaterial2 + implementation libs.composeDependencies.composeMaterialIconsCore implementation libs.composeDependencies.composeNavigation implementation libs.composeDependencies.composeConstraintLayout implementation libs.composeDependencies.lifecycleRuntime diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt index e83a43e1..354fd3db 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt @@ -5,6 +5,9 @@ import androidx.compose.ui.unit.dp import com.urlaunched.android.design.resources.dimens.Dimens internal object SocialAccountDimens { + + val providerIconSize = 24.dp + private val defaultSocialAccountCardPadding = 14.dp val defaultContentPadding = PaddingValues( diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt new file mode 100644 index 00000000..ff7b3b09 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt @@ -0,0 +1,11 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +interface Account { + val credential: String? + val isCurrent: Boolean +} + +data class DefaultAccount( + override val credential: String?, + override val isCurrent: Boolean +) : Account \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingDimens.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingDimens.kt new file mode 100644 index 00000000..9aa36dbf --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingDimens.kt @@ -0,0 +1,9 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.ui.unit.Dp +import com.urlaunched.android.design.resources.dimens.Dimens + +data class AccountBindingDimens( + val sectionsSpacing: Dp = Dimens.spacingBig, + val accountsSpacing: Dp = Dimens.spacingNormalSpecial +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt new file mode 100644 index 00000000..8adc84f4 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt @@ -0,0 +1,13 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.ui.text.TextStyle + +data class AccountBindingTextStyles( + val sectionTitleStyle: TextStyle = TextStyle(), + val providerStyle: TextStyle = TextStyle(), + val accountEmailStyle: TextStyle = TextStyle(), + val passwordStyle: TextStyle = TextStyle(), + val addAccountStyle: TextStyle = TextStyle(), + val currentAccountStyle: TextStyle = TextStyle(), + val deleteAccountStyle: TextStyle = TextStyle() +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTitles.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTitles.kt new file mode 100644 index 00000000..d35b07f1 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTitles.kt @@ -0,0 +1,8 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +data class AccountBindingTitles( + val passwordTitle: String, + val addAccountTitle: String, + val currentAccountTitle: String, + val deleteAccountTitle: String +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt new file mode 100644 index 00000000..9cc4b3cc --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt @@ -0,0 +1,22 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp +import com.urlaunched.android.design.resources.dimens.Dimens +import com.urlaunched.android.design.ui.accountbinding.constants.SocialAccountDimens +import com.urlaunched.android.design.ui.shadow.models.ShadowStyle + +data class AccountCardStyle( + val containerColor: Color = Color.White, + val shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), + val shadow: ShadowStyle? = null, + val contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, + val passwordBasedContentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), + val supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), + val providerIconSize: Dp = SocialAccountDimens.providerIconSize, + val providerIconPadding: PaddingValues = PaddingValues(end = Dimens.spacingSmall), + val trailingIconSpacing: Dp = Dimens.spacingSmall +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt new file mode 100644 index 00000000..a9c63f56 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt @@ -0,0 +1,33 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import com.urlaunched.android.design.R + +interface AccountProvider { + @get:StringRes + val nameResId: Int + + @get:DrawableRes + val iconResId: Int? + get() = null +} + +interface PasswordBasedAccountProvider : AccountProvider + +class EmailAccountProvider(override val nameResId: Int = R.string.email_provider) : PasswordBasedAccountProvider + +object AppleAccountProvider : AccountProvider { + override val nameResId = R.string.apple_provider + override val iconResId = R.drawable.ic_apple_icon +} + +object GoogleAccountProvider : AccountProvider { + override val nameResId = R.string.google_provider + override val iconResId = R.drawable.ic_google_icon +} + +object FacebookAccountProvider : AccountProvider { + override val nameResId = R.string.facebook_provider + override val iconResId = R.drawable.ic_facebook_icon +} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt new file mode 100644 index 00000000..8ce14d79 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt @@ -0,0 +1,10 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +import androidx.compose.foundation.layout.RowScope +import androidx.compose.runtime.Composable + +data class AccountsSection( + val title: String, + val accountProviders: List, + val trailingContent: (@Composable RowScope.() -> Unit)? = null +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt new file mode 100644 index 00000000..42ecdde1 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt @@ -0,0 +1,355 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.rounded.KeyboardArrowRight +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.urlaunched.android.design.resources.dimens.Dimens +import com.urlaunched.android.design.ui.accountbinding.models.Account +import com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens +import com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles +import com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles +import com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle +import com.urlaunched.android.design.ui.accountbinding.models.AccountProvider +import com.urlaunched.android.design.ui.accountbinding.models.AccountsSection +import com.urlaunched.android.design.ui.accountbinding.models.AppleAccountProvider +import com.urlaunched.android.design.ui.accountbinding.models.DefaultAccount +import com.urlaunched.android.design.ui.accountbinding.models.EmailAccountProvider +import com.urlaunched.android.design.ui.accountbinding.models.FacebookAccountProvider +import com.urlaunched.android.design.ui.accountbinding.models.GoogleAccountProvider +import com.urlaunched.android.design.ui.accountbinding.models.PasswordBasedAccountProvider +import com.urlaunched.android.design.ui.clickable.debouncedClickable + +@Composable +fun AccountBindingContainer( + modifier: Modifier = Modifier, + sections: List, + account: (provider: AccountProvider) -> Account?, + onUnbindAccountClick: (provider: AccountProvider) -> Unit, + onEditPasswordClick: (provider: AccountProvider) -> Unit, + onEditEmailClick: (provider: AccountProvider) -> Unit, + onAddAccountClick: (provider: AccountProvider) -> Unit, + titles: AccountBindingTitles, + cardStyle: AccountCardStyle = AccountCardStyle(), + dimens: AccountBindingDimens = AccountBindingDimens(), + textStyles: AccountBindingTextStyles = AccountBindingTextStyles(), + divider: @Composable () -> Unit = { HorizontalDivider() }, + trailingIcon: @Composable RowScope.() -> Unit, + footerSection: @Composable ColumnScope.() -> Unit = {} +) { + AccountBindingContainer( + modifier = modifier, + sections = sections, + isCurrentAccount = { provider -> + account(provider)?.isCurrent == true + }, + hasAccount = { provider -> + account(provider) != null + }, + accountEmail = { provider -> + account(provider)?.credential + }, + footerSection = footerSection, + onUnbindAccountClick = onUnbindAccountClick, + onEditPasswordClick = onEditPasswordClick, + onEditEmailClick = onEditEmailClick, + onAddAccountClick = onAddAccountClick, + titles = titles, + cardStyle = cardStyle, + dimens = dimens, + textStyles = textStyles, + divider = divider, + trailingIcon = trailingIcon + ) +} + +@Composable +fun AccountBindingContainer( + modifier: Modifier = Modifier, + sections: List, + isCurrentAccount: (provider: AccountProvider) -> Boolean, + hasAccount: (provider: AccountProvider) -> Boolean, + accountEmail: (provider: AccountProvider) -> String?, + onUnbindAccountClick: (provider: AccountProvider) -> Unit, + onEditPasswordClick: (provider: AccountProvider) -> Unit, + onEditEmailClick: (provider: AccountProvider) -> Unit, + onAddAccountClick: (provider: AccountProvider) -> Unit, + titles: AccountBindingTitles, + cardStyle: AccountCardStyle = AccountCardStyle(), + dimens: AccountBindingDimens = AccountBindingDimens(), + textStyles: AccountBindingTextStyles = AccountBindingTextStyles(), + divider: @Composable () -> Unit = { HorizontalDivider() }, + trailingIcon: @Composable RowScope.() -> Unit, + footerSection: @Composable ColumnScope.() -> Unit = {} +) { + val providerContent: @Composable RowScope.(AccountProvider) -> Unit = { provider: AccountProvider -> + provider.iconResId?.let { resId -> + Icon( + painter = painterResource(id = resId), + contentDescription = null, + tint = Color.Unspecified, + modifier = Modifier + .padding(cardStyle.providerIconPadding) + .size(cardStyle.providerIconSize) + ) + } + + Text( + text = stringResource(id = provider.nameResId), + style = textStyles.providerStyle + ) + } + + val deleteAccount = @Composable { provider: AccountProvider -> + Text( + text = titles.deleteAccountTitle, + style = textStyles.deleteAccountStyle, + modifier = Modifier + .debouncedClickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + role = Role.Button, + onClick = { + onUnbindAccountClick(provider) + } + ) + ) + } + + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(dimens.sectionsSpacing) + ) { + sections.forEach { section -> + Column( + verticalArrangement = Arrangement.spacedBy(dimens.accountsSpacing) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = section.title, + style = textStyles.sectionTitleStyle + ) + + section.trailingContent?.invoke(this@Row) + } + + section.accountProviders.forEach { provider -> + val accountEmail = accountEmail(provider) + + when (provider) { + is PasswordBasedAccountProvider -> { + EmailAccount( + isCurrentAccount = isCurrentAccount(provider), + hasAccount = hasAccount(provider), + hasEmail = accountEmail != null, + onAddAccountClick = { + onAddAccountClick(provider) + }, + onEditPasswordClick = { + onEditPasswordClick(provider) + }, + onEditEmailClick = { + onEditEmailClick(provider) + }, + divider = divider, + trailingIcon = { + Spacer(Modifier.width(cardStyle.trailingIconSpacing)) + + trailingIcon() + }, + emailProviderContent = { + providerContent(provider) + }, + accountEmail = { + Text( + text = accountEmail.orEmpty(), + style = textStyles.accountEmailStyle, + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + }, + passwordContent = { + Text( + text = titles.passwordTitle, + style = textStyles.passwordStyle + ) + }, + noAccountContent = { + Text( + text = titles.addAccountTitle, + style = textStyles.addAccountStyle, + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + }, + currentAccount = { + Text( + text = titles.currentAccountTitle, + style = textStyles.currentAccountStyle + ) + }, + deleteAccount = { + deleteAccount(provider) + }, + containerColor = cardStyle.containerColor, + shape = cardStyle.shape, + shadow = cardStyle.shadow, + contentPadding = cardStyle.passwordBasedContentPadding, + supportingContentPadding = cardStyle.supportingContentPadding + ) + } + + else -> { + SocialAccount( + hasAccount = hasAccount(provider), + isCurrentAccount = isCurrentAccount(provider), + hasEmail = accountEmail != null, + containerColor = cardStyle.containerColor, + shape = cardStyle.shape, + shadow = cardStyle.shadow, + onAddAccountClick = { + onAddAccountClick(provider) + }, + contentPadding = cardStyle.contentPadding, + supportingContentPadding = cardStyle.supportingContentPadding, + providerContent = { + providerContent(provider) + }, + accountEmail = { + Text( + text = accountEmail.orEmpty(), + style = textStyles.accountEmailStyle, + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + }, + addAccount = { + Text( + text = titles.addAccountTitle, + style = textStyles.addAccountStyle, + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + }, + deleteAccount = { + deleteAccount(provider) + }, + currentAccount = { + Text( + text = titles.currentAccountTitle, + style = textStyles.currentAccountStyle + ) + } + ) + } + } + } + } + } + + footerSection() + } +} + +@Preview(showBackground = true, backgroundColor = 0xFFEFEFEF) +@Composable +private fun AccountBindingContainerPreview() { + val titleInfoBadge: @Composable RowScope.() -> Unit = { + Box( + modifier = Modifier + .clip(CircleShape) + .clickable {} + .padding(Dimens.spacingTiny) + ) { + Icon( + imageVector = Icons.Default.Info, + contentDescription = null, + tint = MaterialTheme.colorScheme.error, + modifier = Modifier.size(20.dp) + ) + } + } + + AccountBindingContainer( + modifier = Modifier + .fillMaxSize() + .padding(Dimens.spacingNormal), + sections = listOf( + AccountsSection( + title = "Account with mail:", + accountProviders = listOf(EmailAccountProvider()), + trailingContent = titleInfoBadge + ), + AccountsSection( + title = "Social accounts:", + accountProviders = listOf(GoogleAccountProvider, AppleAccountProvider, FacebookAccountProvider) + ) + ), + textStyles = AccountBindingTextStyles( + sectionTitleStyle = MaterialTheme.typography.titleMedium, + providerStyle = MaterialTheme.typography.bodyLarge, + accountEmailStyle = MaterialTheme.typography.bodyMedium, + passwordStyle = MaterialTheme.typography.bodyLarge, + addAccountStyle = MaterialTheme.typography.labelLarge.copy(color = MaterialTheme.colorScheme.primary), + currentAccountStyle = MaterialTheme.typography.labelMedium, + deleteAccountStyle = MaterialTheme.typography.labelMedium.copy(color = MaterialTheme.colorScheme.error) + ), + trailingIcon = { + Icon( + imageVector = Icons.Rounded.KeyboardArrowRight, + contentDescription = null + ) + }, + titles = AccountBindingTitles( + passwordTitle = "Password", + addAccountTitle = "Add account", + currentAccountTitle = "Your current account", + deleteAccountTitle = "Delete" + ), + account = { provider -> + when (provider) { + is EmailAccountProvider -> DefaultAccount("someone@gmail.com", true) + is GoogleAccountProvider -> DefaultAccount("someone@gmail.com", false) + else -> null + } + }, + onUnbindAccountClick = {}, + onEditPasswordClick = {}, + onEditEmailClick = {}, + onAddAccountClick = {} + ) +} \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt index 59249d0b..61fc8214 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt @@ -54,7 +54,7 @@ fun SocialAccount( .clip(shape) .background(containerColor), modifier = modifier, - enabled = hasAccount, + enabled = !hasAccount, hasEmail = hasEmail, onAddAccountClick = onAddAccountClick, contentPadding = contentPadding, diff --git a/design/src/main/res/drawable/ic_apple_icon.xml b/design/src/main/res/drawable/ic_apple_icon.xml new file mode 100644 index 00000000..2e6d40a5 --- /dev/null +++ b/design/src/main/res/drawable/ic_apple_icon.xml @@ -0,0 +1,9 @@ + + + diff --git a/design/src/main/res/drawable/ic_facebook_icon.xml b/design/src/main/res/drawable/ic_facebook_icon.xml new file mode 100644 index 00000000..a339cb97 --- /dev/null +++ b/design/src/main/res/drawable/ic_facebook_icon.xml @@ -0,0 +1,9 @@ + + + diff --git a/design/src/main/res/drawable/ic_google_icon.xml b/design/src/main/res/drawable/ic_google_icon.xml new file mode 100644 index 00000000..8915fc8e --- /dev/null +++ b/design/src/main/res/drawable/ic_google_icon.xml @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/design/src/main/res/values/strings.xml b/design/src/main/res/values/strings.xml new file mode 100644 index 00000000..5ae7ee85 --- /dev/null +++ b/design/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Google + Apple + Facebook + Email + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f5bcf8ab..99be8bba 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -121,6 +121,7 @@ composeDependencies-composeUi = { module = "androidx.compose.ui:ui", version.ref composeDependencies-composePreview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composeVersion" } composeDependencies-composeMaterial3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial3Version" } composeDependencies-composeMaterial2 = { module = "androidx.compose.material:material", version.ref = "composeMaterial2Version" } +composeDependencies-composeMaterialIconsCore = { module = "androidx.compose.material:material-icons-core", version.ref = "composeVersion" } composeDependencies-composeNavigation = { module = "androidx.navigation:navigation-compose", version.ref = "composeNavigationVersion" } composeDependencies-composeConstraintLayout = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "composeConstraintLayout" } composeDependencies-composeUiTooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "composeVersion" } From 6534393353905faeea431b16d526fbe1b6cb3ce1 Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Tue, 14 Oct 2025 12:40:00 +0300 Subject: [PATCH 07/11] Rename email to general credential --- .../models/AccountBindingTextStyles.kt | 2 +- .../accountbinding/models/AccountCardStyle.kt | 2 +- .../ui/AccountBindingContainer.kt | 42 ++++++++-------- ...mailAccount.kt => PasswordBasedAccount.kt} | 50 +++++++++---------- .../ui/accountbinding/ui/SocialAccount.kt | 20 ++++---- 5 files changed, 58 insertions(+), 58 deletions(-) rename design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/{EmailAccount.kt => PasswordBasedAccount.kt} (86%) diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt index 8adc84f4..58ba618e 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.text.TextStyle data class AccountBindingTextStyles( val sectionTitleStyle: TextStyle = TextStyle(), val providerStyle: TextStyle = TextStyle(), - val accountEmailStyle: TextStyle = TextStyle(), + val accountCredentialStyle: TextStyle = TextStyle(), val passwordStyle: TextStyle = TextStyle(), val addAccountStyle: TextStyle = TextStyle(), val currentAccountStyle: TextStyle = TextStyle(), diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt index 9cc4b3cc..dbf9f791 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountCardStyle.kt @@ -13,7 +13,7 @@ data class AccountCardStyle( val containerColor: Color = Color.White, val shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), val shadow: ShadowStyle? = null, - val contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, + val socialContentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, val passwordBasedContentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), val supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), val providerIconSize: Dp = SocialAccountDimens.providerIconSize, diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt index 42ecdde1..ad549622 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt @@ -57,7 +57,7 @@ fun AccountBindingContainer( account: (provider: AccountProvider) -> Account?, onUnbindAccountClick: (provider: AccountProvider) -> Unit, onEditPasswordClick: (provider: AccountProvider) -> Unit, - onEditEmailClick: (provider: AccountProvider) -> Unit, + onEditCredentialClick: (provider: AccountProvider) -> Unit, onAddAccountClick: (provider: AccountProvider) -> Unit, titles: AccountBindingTitles, cardStyle: AccountCardStyle = AccountCardStyle(), @@ -76,13 +76,13 @@ fun AccountBindingContainer( hasAccount = { provider -> account(provider) != null }, - accountEmail = { provider -> + accountCredential = { provider -> account(provider)?.credential }, footerSection = footerSection, onUnbindAccountClick = onUnbindAccountClick, onEditPasswordClick = onEditPasswordClick, - onEditEmailClick = onEditEmailClick, + onEditCredentialClick = onEditCredentialClick, onAddAccountClick = onAddAccountClick, titles = titles, cardStyle = cardStyle, @@ -99,10 +99,10 @@ fun AccountBindingContainer( sections: List, isCurrentAccount: (provider: AccountProvider) -> Boolean, hasAccount: (provider: AccountProvider) -> Boolean, - accountEmail: (provider: AccountProvider) -> String?, + accountCredential: (provider: AccountProvider) -> String?, onUnbindAccountClick: (provider: AccountProvider) -> Unit, onEditPasswordClick: (provider: AccountProvider) -> Unit, - onEditEmailClick: (provider: AccountProvider) -> Unit, + onEditCredentialClick: (provider: AccountProvider) -> Unit, onAddAccountClick: (provider: AccountProvider) -> Unit, titles: AccountBindingTitles, cardStyle: AccountCardStyle = AccountCardStyle(), @@ -168,22 +168,22 @@ fun AccountBindingContainer( } section.accountProviders.forEach { provider -> - val accountEmail = accountEmail(provider) + val accountCredential = accountCredential(provider) when (provider) { is PasswordBasedAccountProvider -> { - EmailAccount( + PasswordBasedAccount( isCurrentAccount = isCurrentAccount(provider), hasAccount = hasAccount(provider), - hasEmail = accountEmail != null, + hasCredential = accountCredential != null, onAddAccountClick = { onAddAccountClick(provider) }, onEditPasswordClick = { onEditPasswordClick(provider) }, - onEditEmailClick = { - onEditEmailClick(provider) + onEditCredentialClick = { + onEditCredentialClick(provider) }, divider = divider, trailingIcon = { @@ -191,13 +191,13 @@ fun AccountBindingContainer( trailingIcon() }, - emailProviderContent = { + providerContent = { providerContent(provider) }, - accountEmail = { + accountCredential = { Text( - text = accountEmail.orEmpty(), - style = textStyles.accountEmailStyle, + text = accountCredential.orEmpty(), + style = textStyles.accountCredentialStyle, overflow = TextOverflow.Ellipsis, maxLines = 1 ) @@ -237,22 +237,22 @@ fun AccountBindingContainer( SocialAccount( hasAccount = hasAccount(provider), isCurrentAccount = isCurrentAccount(provider), - hasEmail = accountEmail != null, + hasCredential = accountCredential != null, containerColor = cardStyle.containerColor, shape = cardStyle.shape, shadow = cardStyle.shadow, onAddAccountClick = { onAddAccountClick(provider) }, - contentPadding = cardStyle.contentPadding, + contentPadding = cardStyle.socialContentPadding, supportingContentPadding = cardStyle.supportingContentPadding, providerContent = { providerContent(provider) }, - accountEmail = { + accountCredential = { Text( - text = accountEmail.orEmpty(), - style = textStyles.accountEmailStyle, + text = accountCredential.orEmpty(), + style = textStyles.accountCredentialStyle, overflow = TextOverflow.Ellipsis, maxLines = 1 ) @@ -322,7 +322,7 @@ private fun AccountBindingContainerPreview() { textStyles = AccountBindingTextStyles( sectionTitleStyle = MaterialTheme.typography.titleMedium, providerStyle = MaterialTheme.typography.bodyLarge, - accountEmailStyle = MaterialTheme.typography.bodyMedium, + accountCredentialStyle = MaterialTheme.typography.bodyMedium, passwordStyle = MaterialTheme.typography.bodyLarge, addAccountStyle = MaterialTheme.typography.labelLarge.copy(color = MaterialTheme.colorScheme.primary), currentAccountStyle = MaterialTheme.typography.labelMedium, @@ -349,7 +349,7 @@ private fun AccountBindingContainerPreview() { }, onUnbindAccountClick = {}, onEditPasswordClick = {}, - onEditEmailClick = {}, + onEditCredentialClick = {}, onAddAccountClick = {} ) } \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt similarity index 86% rename from design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt rename to design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt index b9b9a5e8..de2ffb50 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/EmailAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt @@ -32,15 +32,15 @@ import com.urlaunched.android.design.ui.shadow.models.ShadowStyle import com.urlaunched.android.design.ui.shadow.shadow @Composable -fun EmailAccount( +fun PasswordBasedAccount( modifier: Modifier = Modifier, isCurrentAccount: Boolean, hasAccount: Boolean, - hasEmail: Boolean, + hasCredential: Boolean, containerColor: Color = Color.White, shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), shadow: ShadowStyle? = null, - onEditEmailClick: () -> Unit, + onEditCredentialClick: () -> Unit, onAddAccountClick: () -> Unit, onEditPasswordClick: () -> Unit, contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), @@ -48,29 +48,29 @@ fun EmailAccount( divider: @Composable () -> Unit = { HorizontalDivider() }, - emailProviderContent: @Composable RowScope.() -> Unit, - accountEmail: @Composable RowScope.() -> Unit, + providerContent: @Composable RowScope.() -> Unit, + accountCredential: @Composable RowScope.() -> Unit, passwordContent: @Composable RowScope.() -> Unit, trailingIcon: @Composable RowScope.() -> Unit, noAccountContent: @Composable RowScope.() -> Unit, deleteAccount: @Composable ColumnScope.() -> Unit, currentAccount: @Composable ColumnScope.() -> Unit ) { - EmailAccount( + PasswordBasedAccount( cardModifier = Modifier .ifNotNull(shadow) { Modifier.shadow(it) } .clip(shape) .background(containerColor), modifier = modifier, hasAccount = hasAccount, - hasEmail = hasEmail, - onEditEmailClick = onEditEmailClick, + hasCredential = hasCredential, + onEditCredentialClick = onEditCredentialClick, onAddAccountClick = onAddAccountClick, onEditPasswordClick = onEditPasswordClick, contentPadding = contentPadding, divider = divider, - emailProviderContent = emailProviderContent, - accountEmail = accountEmail, + providerContent = providerContent, + accountCredential = accountCredential, passwordContent = passwordContent, trailingIcon = trailingIcon, noAccountContent = noAccountContent, @@ -94,20 +94,20 @@ fun EmailAccount( } @Composable -fun EmailAccount( +fun PasswordBasedAccount( modifier: Modifier = Modifier, cardModifier: Modifier = Modifier, hasAccount: Boolean, - hasEmail: Boolean, - onEditEmailClick: () -> Unit, + hasCredential: Boolean, + onEditCredentialClick: () -> Unit, onAddAccountClick: () -> Unit, onEditPasswordClick: () -> Unit, contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), divider: @Composable () -> Unit = { HorizontalDivider() }, - emailProviderContent: @Composable RowScope.() -> Unit, - accountEmail: @Composable RowScope.() -> Unit, + providerContent: @Composable RowScope.() -> Unit, + accountCredential: @Composable RowScope.() -> Unit, passwordContent: @Composable RowScope.() -> Unit, trailingIcon: @Composable RowScope.() -> Unit, noAccountContent: @Composable RowScope.() -> Unit, @@ -124,19 +124,19 @@ fun EmailAccount( .fillMaxWidth() .debouncedClickable { if (hasAccount) { - onEditEmailClick() + onEditCredentialClick() } else { onAddAccountClick() } } .padding(contentPadding) ) { - emailProviderContent() + providerContent() Spacer(Modifier.weight(1f)) - if (hasEmail) { - accountEmail() + if (hasCredential) { + accountCredential() trailingIcon() } else { @@ -168,24 +168,24 @@ fun EmailAccount( @Preview @Composable -private fun EmailAccountPreview() { - EmailAccount( +private fun PasswordBasedAccountPreview() { + PasswordBasedAccount( isCurrentAccount = true, hasAccount = true, - hasEmail = true, + hasCredential = true, modifier = Modifier .background(Color.LightGray) .padding(Dimens.spacingNormal), - onEditEmailClick = { }, + onEditCredentialClick = { }, onAddAccountClick = { }, onEditPasswordClick = { }, - emailProviderContent = { + providerContent = { Text( text = "Gmail", fontWeight = FontWeight.Bold ) }, - accountEmail = { + accountCredential = { Text( text = "someone@gmail.com", textAlign = TextAlign.End, diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt index 61fc8214..c9c193aa 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt @@ -35,7 +35,7 @@ fun SocialAccount( modifier: Modifier = Modifier, isCurrentAccount: Boolean, hasAccount: Boolean, - hasEmail: Boolean, + hasCredential: Boolean, containerColor: Color = Color.White, shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), shadow: ShadowStyle? = null, @@ -43,7 +43,7 @@ fun SocialAccount( contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), providerContent: @Composable RowScope.() -> Unit, - accountEmail: @Composable RowScope.() -> Unit, + accountCredential: @Composable RowScope.() -> Unit, addAccount: @Composable RowScope.() -> Unit, deleteAccount: @Composable ColumnScope.() -> Unit, currentAccount: @Composable ColumnScope.() -> Unit @@ -55,10 +55,10 @@ fun SocialAccount( .background(containerColor), modifier = modifier, enabled = !hasAccount, - hasEmail = hasEmail, + hasCredential = hasCredential, onAddAccountClick = onAddAccountClick, contentPadding = contentPadding, - accountEmail = accountEmail, + accountCredential = accountCredential, addAccount = addAccount, providerContent = providerContent, supportingContent = { @@ -84,12 +84,12 @@ fun SocialAccount( fun SocialAccount( modifier: Modifier = Modifier, cardModifier: Modifier = Modifier, - hasEmail: Boolean, + hasCredential: Boolean, enabled: Boolean = true, onAddAccountClick: () -> Unit, contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, providerContent: @Composable RowScope.() -> Unit, - accountEmail: @Composable RowScope.() -> Unit, + accountCredential: @Composable RowScope.() -> Unit, addAccount: @Composable RowScope.() -> Unit, supportingContent: @Composable ColumnScope.() -> Unit = {} ) { @@ -111,8 +111,8 @@ fun SocialAccount( Spacer(Modifier.weight(1f)) - if (hasEmail) { - accountEmail() + if (hasCredential) { + accountCredential() } else { addAccount() } @@ -127,7 +127,7 @@ fun SocialAccount( @Composable private fun SocialAccountPreview() { SocialAccount( - hasEmail = true, + hasCredential = true, hasAccount = true, isCurrentAccount = true, modifier = Modifier @@ -147,7 +147,7 @@ private fun SocialAccountPreview() { fontWeight = FontWeight.Bold ) }, - accountEmail = { + accountCredential = { Text( text = "someone@gmail.com" ) From 7b1fc80398d47f0040c4d02b57057984ee315c5b Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Tue, 14 Oct 2025 12:56:18 +0300 Subject: [PATCH 08/11] Update api --- design/api/current.api | 174 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 169 insertions(+), 5 deletions(-) diff --git a/design/api/current.api b/design/api/current.api index 56412b53..30dd9e8f 100644 --- a/design/api/current.api +++ b/design/api/current.api @@ -67,16 +67,180 @@ package com.urlaunched.android.design.resources.dimens { } +package com.urlaunched.android.design.ui.accountbinding.models { + + public interface Account { + method public String? getCredential(); + method public boolean isCurrent(); + property public abstract String? credential; + property public abstract boolean isCurrent; + } + + public final class AccountBindingDimens { + ctor public AccountBindingDimens(optional float sectionsSpacing, optional float accountsSpacing); + method public float component1-D9Ej5fM(); + method public float component2-D9Ej5fM(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens copy-YgX7TsA(float sectionsSpacing, float accountsSpacing); + method public float getAccountsSpacing(); + method public float getSectionsSpacing(); + property public final float accountsSpacing; + property public final float sectionsSpacing; + } + + public final class AccountBindingTextStyles { + ctor public AccountBindingTextStyles(optional androidx.compose.ui.text.TextStyle sectionTitleStyle, optional androidx.compose.ui.text.TextStyle providerStyle, optional androidx.compose.ui.text.TextStyle accountCredentialStyle, optional androidx.compose.ui.text.TextStyle passwordStyle, optional androidx.compose.ui.text.TextStyle addAccountStyle, optional androidx.compose.ui.text.TextStyle currentAccountStyle, optional androidx.compose.ui.text.TextStyle deleteAccountStyle); + method public androidx.compose.ui.text.TextStyle component1(); + method public androidx.compose.ui.text.TextStyle component2(); + method public androidx.compose.ui.text.TextStyle component3(); + method public androidx.compose.ui.text.TextStyle component4(); + method public androidx.compose.ui.text.TextStyle component5(); + method public androidx.compose.ui.text.TextStyle component6(); + method public androidx.compose.ui.text.TextStyle component7(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles copy(androidx.compose.ui.text.TextStyle sectionTitleStyle, androidx.compose.ui.text.TextStyle providerStyle, androidx.compose.ui.text.TextStyle accountCredentialStyle, androidx.compose.ui.text.TextStyle passwordStyle, androidx.compose.ui.text.TextStyle addAccountStyle, androidx.compose.ui.text.TextStyle currentAccountStyle, androidx.compose.ui.text.TextStyle deleteAccountStyle); + method public androidx.compose.ui.text.TextStyle getAccountCredentialStyle(); + method public androidx.compose.ui.text.TextStyle getAddAccountStyle(); + method public androidx.compose.ui.text.TextStyle getCurrentAccountStyle(); + method public androidx.compose.ui.text.TextStyle getDeleteAccountStyle(); + method public androidx.compose.ui.text.TextStyle getPasswordStyle(); + method public androidx.compose.ui.text.TextStyle getProviderStyle(); + method public androidx.compose.ui.text.TextStyle getSectionTitleStyle(); + property public final androidx.compose.ui.text.TextStyle accountCredentialStyle; + property public final androidx.compose.ui.text.TextStyle addAccountStyle; + property public final androidx.compose.ui.text.TextStyle currentAccountStyle; + property public final androidx.compose.ui.text.TextStyle deleteAccountStyle; + property public final androidx.compose.ui.text.TextStyle passwordStyle; + property public final androidx.compose.ui.text.TextStyle providerStyle; + property public final androidx.compose.ui.text.TextStyle sectionTitleStyle; + } + + public final class AccountBindingTitles { + ctor public AccountBindingTitles(String passwordTitle, String addAccountTitle, String currentAccountTitle, String deleteAccountTitle); + method public String component1(); + method public String component2(); + method public String component3(); + method public String component4(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles copy(String passwordTitle, String addAccountTitle, String currentAccountTitle, String deleteAccountTitle); + method public String getAddAccountTitle(); + method public String getCurrentAccountTitle(); + method public String getDeleteAccountTitle(); + method public String getPasswordTitle(); + property public final String addAccountTitle; + property public final String currentAccountTitle; + property public final String deleteAccountTitle; + property public final String passwordTitle; + } + + public final class AccountCardStyle { + ctor public AccountCardStyle(optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, optional androidx.compose.foundation.layout.PaddingValues socialContentPadding, optional androidx.compose.foundation.layout.PaddingValues passwordBasedContentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, optional float providerIconSize, optional androidx.compose.foundation.layout.PaddingValues providerIconPadding, optional float trailingIconSpacing); + method public long component1-0d7_KjU(); + method public androidx.compose.ui.graphics.Shape component2(); + method public com.urlaunched.android.design.ui.shadow.models.ShadowStyle? component3(); + method public androidx.compose.foundation.layout.PaddingValues component4(); + method public androidx.compose.foundation.layout.PaddingValues component5(); + method public androidx.compose.foundation.layout.PaddingValues component6(); + method public float component7-D9Ej5fM(); + method public androidx.compose.foundation.layout.PaddingValues component8(); + method public float component9-D9Ej5fM(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle copy-CvDtS1k(long containerColor, androidx.compose.ui.graphics.Shape shape, com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, androidx.compose.foundation.layout.PaddingValues socialContentPadding, androidx.compose.foundation.layout.PaddingValues passwordBasedContentPadding, androidx.compose.foundation.layout.PaddingValues supportingContentPadding, float providerIconSize, androidx.compose.foundation.layout.PaddingValues providerIconPadding, float trailingIconSpacing); + method public long getContainerColor(); + method public androidx.compose.foundation.layout.PaddingValues getPasswordBasedContentPadding(); + method public androidx.compose.foundation.layout.PaddingValues getProviderIconPadding(); + method public float getProviderIconSize(); + method public com.urlaunched.android.design.ui.shadow.models.ShadowStyle? getShadow(); + method public androidx.compose.ui.graphics.Shape getShape(); + method public androidx.compose.foundation.layout.PaddingValues getSocialContentPadding(); + method public androidx.compose.foundation.layout.PaddingValues getSupportingContentPadding(); + method public float getTrailingIconSpacing(); + property public final long containerColor; + property public final androidx.compose.foundation.layout.PaddingValues passwordBasedContentPadding; + property public final androidx.compose.foundation.layout.PaddingValues providerIconPadding; + property public final float providerIconSize; + property public final com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow; + property public final androidx.compose.ui.graphics.Shape shape; + property public final androidx.compose.foundation.layout.PaddingValues socialContentPadding; + property public final androidx.compose.foundation.layout.PaddingValues supportingContentPadding; + property public final float trailingIconSpacing; + } + + public interface AccountProvider { + method @DrawableRes public default Integer? getIconResId(); + method @StringRes public int getNameResId(); + property @DrawableRes public default Integer? iconResId; + property @StringRes public abstract int nameResId; + } + + public final class AccountsSection { + ctor public AccountsSection(String title, java.util.List accountProviders, optional kotlin.jvm.functions.Function1? trailingContent); + method public String component1(); + method public java.util.List component2(); + method public kotlin.jvm.functions.Function1? component3(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountsSection copy(String title, java.util.List accountProviders, kotlin.jvm.functions.Function1? trailingContent); + method public java.util.List getAccountProviders(); + method public String getTitle(); + method public kotlin.jvm.functions.Function1? getTrailingContent(); + property public final java.util.List accountProviders; + property public final String title; + property public final kotlin.jvm.functions.Function1? trailingContent; + } + + public final class AppleAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + method public int getNameResId(); + property public Integer iconResId; + property public int nameResId; + field public static final com.urlaunched.android.design.ui.accountbinding.models.AppleAccountProvider INSTANCE; + } + + public final class DefaultAccount implements com.urlaunched.android.design.ui.accountbinding.models.Account { + ctor public DefaultAccount(String? credential, boolean isCurrent); + method public String? component1(); + method public boolean component2(); + method public com.urlaunched.android.design.ui.accountbinding.models.DefaultAccount copy(String? credential, boolean isCurrent); + method public String? getCredential(); + method public boolean isCurrent(); + property public String? credential; + property public boolean isCurrent; + } + + public final class EmailAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.PasswordBasedAccountProvider { + ctor public EmailAccountProvider(optional int nameResId); + method public int getNameResId(); + property public int nameResId; + } + + public final class FacebookAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + method public int getNameResId(); + property public Integer iconResId; + property public int nameResId; + field public static final com.urlaunched.android.design.ui.accountbinding.models.FacebookAccountProvider INSTANCE; + } + + public final class GoogleAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + method public int getNameResId(); + property public Integer iconResId; + property public int nameResId; + field public static final com.urlaunched.android.design.ui.accountbinding.models.GoogleAccountProvider INSTANCE; + } + + public interface PasswordBasedAccountProvider extends com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + } + +} + package com.urlaunched.android.design.ui.accountbinding.ui { - public final class EmailAccountKt { - method @androidx.compose.runtime.Composable public static void EmailAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasAccount, boolean hasEmail, kotlin.jvm.functions.Function0 onEditEmailClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 emailProviderContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, optional kotlin.jvm.functions.Function1 supportingContent); - method @androidx.compose.runtime.Composable public static void EmailAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasEmail, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onEditEmailClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 emailProviderContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); + public final class AccountBindingContainerKt { + method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 account, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditCredentialClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); + method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 isCurrentAccount, kotlin.jvm.functions.Function1 hasAccount, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditCredentialClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); + } + + public final class PasswordBasedAccountKt { + method @androidx.compose.runtime.Composable public static void PasswordBasedAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasAccount, boolean hasCredential, kotlin.jvm.functions.Function0 onEditCredentialClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, optional kotlin.jvm.functions.Function1 supportingContent); + method @androidx.compose.runtime.Composable public static void PasswordBasedAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasCredential, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onEditCredentialClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); } public final class SocialAccountKt { - method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasEmail, optional boolean enabled, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 addAccount, optional kotlin.jvm.functions.Function1 supportingContent); - method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasEmail, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountEmail, kotlin.jvm.functions.Function1 addAccount, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasCredential, optional boolean enabled, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 addAccount, optional kotlin.jvm.functions.Function1 supportingContent); + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasCredential, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 addAccount, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); } } From 479f6a4c56d2bacf4e1be7823fa743d96d5e5cd6 Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Wed, 8 Oct 2025 17:38:45 +0300 Subject: [PATCH 09/11] Update agp to 8.6.0 --- gradle/libs.versions.toml | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 99be8bba..04147eda 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -87,8 +87,8 @@ bottomSheetVersion = "1.33.0" # plugins # dependencies -androidApplicationPluginVersion = "8.4.2" -androidLibraryPluginVersion = "8.4.2" +androidApplicationPluginVersion = "8.6.0" +androidLibraryPluginVersion = "8.6.0" kotlinAndroidPluginVersion = "2.1.20" kotlinJvmPluginVersion = "2.1.20" kotlinSerializationPluginVersion = "2.1.20" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a..a4413138 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From f2bd28710866d8419912c2c62265e0d926e27bce Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Tue, 14 Oct 2025 17:21:03 +0300 Subject: [PATCH 10/11] Implement AccountData model instead of Account interface --- design/api/current.api | 65 ++++++------- .../ui/accountbinding/models/Account.kt | 11 --- .../ui/accountbinding/models/AccountData.kt | 6 ++ .../accountbinding/models/AccountProvider.kt | 28 +++--- .../accountbinding/models/AccountsSection.kt | 2 +- .../ui/AccountBindingContainer.kt | 94 +++++-------------- 6 files changed, 78 insertions(+), 128 deletions(-) delete mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt create mode 100644 design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt diff --git a/design/api/current.api b/design/api/current.api index 30dd9e8f..83fadeec 100644 --- a/design/api/current.api +++ b/design/api/current.api @@ -69,13 +69,6 @@ package com.urlaunched.android.design.resources.dimens { package com.urlaunched.android.design.ui.accountbinding.models { - public interface Account { - method public String? getCredential(); - method public boolean isCurrent(); - property public abstract String? credential; - property public abstract boolean isCurrent; - } - public final class AccountBindingDimens { ctor public AccountBindingDimens(optional float sectionsSpacing, optional float accountsSpacing); method public float component1-D9Ej5fM(); @@ -162,6 +155,17 @@ package com.urlaunched.android.design.ui.accountbinding.models { property public final float trailingIconSpacing; } + public final class AccountData { + ctor public AccountData(String? credential, boolean isCurrent); + method public String? component1(); + method public boolean component2(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountData copy(String? credential, boolean isCurrent); + method public String? getCredential(); + method public boolean isCurrent(); + property public final String? credential; + property public final boolean isCurrent; + } + public interface AccountProvider { method @DrawableRes public default Integer? getIconResId(); method @StringRes public int getNameResId(); @@ -170,58 +174,50 @@ package com.urlaunched.android.design.ui.accountbinding.models { } public final class AccountsSection { - ctor public AccountsSection(String title, java.util.List accountProviders, optional kotlin.jvm.functions.Function1? trailingContent); + ctor public AccountsSection(String title, java.util.Map accounts, optional kotlin.jvm.functions.Function1? trailingContent); method public String component1(); - method public java.util.List component2(); + method public java.util.Map component2(); method public kotlin.jvm.functions.Function1? component3(); - method public com.urlaunched.android.design.ui.accountbinding.models.AccountsSection copy(String title, java.util.List accountProviders, kotlin.jvm.functions.Function1? trailingContent); - method public java.util.List getAccountProviders(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountsSection copy(String title, java.util.Map accounts, kotlin.jvm.functions.Function1? trailingContent); + method public java.util.Map getAccounts(); method public String getTitle(); method public kotlin.jvm.functions.Function1? getTrailingContent(); - property public final java.util.List accountProviders; + property public final java.util.Map accounts; property public final String title; property public final kotlin.jvm.functions.Function1? trailingContent; } - public final class AppleAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + public final class EmailAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.PasswordBasedAccountProvider { + ctor public EmailAccountProvider(optional int nameResId); method public int getNameResId(); - property public Integer iconResId; property public int nameResId; - field public static final com.urlaunched.android.design.ui.accountbinding.models.AppleAccountProvider INSTANCE; } - public final class DefaultAccount implements com.urlaunched.android.design.ui.accountbinding.models.Account { - ctor public DefaultAccount(String? credential, boolean isCurrent); - method public String? component1(); - method public boolean component2(); - method public com.urlaunched.android.design.ui.accountbinding.models.DefaultAccount copy(String? credential, boolean isCurrent); - method public String? getCredential(); - method public boolean isCurrent(); - property public String? credential; - property public boolean isCurrent; + public interface PasswordBasedAccountProvider extends com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { } - public final class EmailAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.PasswordBasedAccountProvider { - ctor public EmailAccountProvider(optional int nameResId); - method public int getNameResId(); - property public int nameResId; + public abstract sealed class SocialAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { } - public final class FacebookAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + public static final class SocialAccountProvider.Apple extends com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider { method public int getNameResId(); property public Integer iconResId; property public int nameResId; - field public static final com.urlaunched.android.design.ui.accountbinding.models.FacebookAccountProvider INSTANCE; + field public static final com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider.Apple INSTANCE; } - public final class GoogleAccountProvider implements com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + public static final class SocialAccountProvider.Facebook extends com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider { method public int getNameResId(); property public Integer iconResId; property public int nameResId; - field public static final com.urlaunched.android.design.ui.accountbinding.models.GoogleAccountProvider INSTANCE; + field public static final com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider.Facebook INSTANCE; } - public interface PasswordBasedAccountProvider extends com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + public static final class SocialAccountProvider.Google extends com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider { + method public int getNameResId(); + property public Integer iconResId; + property public int nameResId; + field public static final com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider.Google INSTANCE; } } @@ -229,8 +225,7 @@ package com.urlaunched.android.design.ui.accountbinding.models { package com.urlaunched.android.design.ui.accountbinding.ui { public final class AccountBindingContainerKt { - method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 account, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditCredentialClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); - method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 isCurrentAccount, kotlin.jvm.functions.Function1 hasAccount, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditCredentialClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); + method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditCredentialClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); } public final class PasswordBasedAccountKt { diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt deleted file mode 100644 index ff7b3b09..00000000 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/Account.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.urlaunched.android.design.ui.accountbinding.models - -interface Account { - val credential: String? - val isCurrent: Boolean -} - -data class DefaultAccount( - override val credential: String?, - override val isCurrent: Boolean -) : Account \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt new file mode 100644 index 00000000..14e02025 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt @@ -0,0 +1,6 @@ +package com.urlaunched.android.design.ui.accountbinding.models + +data class AccountData( + val credential: String?, + val isCurrent: Boolean +) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt index a9c63f56..9f227168 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt @@ -17,17 +17,19 @@ interface PasswordBasedAccountProvider : AccountProvider class EmailAccountProvider(override val nameResId: Int = R.string.email_provider) : PasswordBasedAccountProvider -object AppleAccountProvider : AccountProvider { - override val nameResId = R.string.apple_provider - override val iconResId = R.drawable.ic_apple_icon -} - -object GoogleAccountProvider : AccountProvider { - override val nameResId = R.string.google_provider - override val iconResId = R.drawable.ic_google_icon -} - -object FacebookAccountProvider : AccountProvider { - override val nameResId = R.string.facebook_provider - override val iconResId = R.drawable.ic_facebook_icon +sealed class SocialAccountProvider : AccountProvider { + object Apple : SocialAccountProvider() { + override val nameResId = R.string.apple_provider + override val iconResId = R.drawable.ic_apple_icon + } + + object Google : SocialAccountProvider() { + override val nameResId = R.string.google_provider + override val iconResId = R.drawable.ic_google_icon + } + + object Facebook : SocialAccountProvider() { + override val nameResId = R.string.facebook_provider + override val iconResId = R.drawable.ic_facebook_icon + } } \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt index 8ce14d79..11720a3d 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountsSection.kt @@ -5,6 +5,6 @@ import androidx.compose.runtime.Composable data class AccountsSection( val title: String, - val accountProviders: List, + val accounts: Map, val trailingContent: (@Composable RowScope.() -> Unit)? = null ) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt index ad549622..b137192f 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt @@ -35,71 +35,22 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.urlaunched.android.design.resources.dimens.Dimens -import com.urlaunched.android.design.ui.accountbinding.models.Account import com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens import com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles import com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles import com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle +import com.urlaunched.android.design.ui.accountbinding.models.AccountData import com.urlaunched.android.design.ui.accountbinding.models.AccountProvider import com.urlaunched.android.design.ui.accountbinding.models.AccountsSection -import com.urlaunched.android.design.ui.accountbinding.models.AppleAccountProvider -import com.urlaunched.android.design.ui.accountbinding.models.DefaultAccount import com.urlaunched.android.design.ui.accountbinding.models.EmailAccountProvider -import com.urlaunched.android.design.ui.accountbinding.models.FacebookAccountProvider -import com.urlaunched.android.design.ui.accountbinding.models.GoogleAccountProvider import com.urlaunched.android.design.ui.accountbinding.models.PasswordBasedAccountProvider +import com.urlaunched.android.design.ui.accountbinding.models.SocialAccountProvider import com.urlaunched.android.design.ui.clickable.debouncedClickable @Composable fun AccountBindingContainer( modifier: Modifier = Modifier, sections: List, - account: (provider: AccountProvider) -> Account?, - onUnbindAccountClick: (provider: AccountProvider) -> Unit, - onEditPasswordClick: (provider: AccountProvider) -> Unit, - onEditCredentialClick: (provider: AccountProvider) -> Unit, - onAddAccountClick: (provider: AccountProvider) -> Unit, - titles: AccountBindingTitles, - cardStyle: AccountCardStyle = AccountCardStyle(), - dimens: AccountBindingDimens = AccountBindingDimens(), - textStyles: AccountBindingTextStyles = AccountBindingTextStyles(), - divider: @Composable () -> Unit = { HorizontalDivider() }, - trailingIcon: @Composable RowScope.() -> Unit, - footerSection: @Composable ColumnScope.() -> Unit = {} -) { - AccountBindingContainer( - modifier = modifier, - sections = sections, - isCurrentAccount = { provider -> - account(provider)?.isCurrent == true - }, - hasAccount = { provider -> - account(provider) != null - }, - accountCredential = { provider -> - account(provider)?.credential - }, - footerSection = footerSection, - onUnbindAccountClick = onUnbindAccountClick, - onEditPasswordClick = onEditPasswordClick, - onEditCredentialClick = onEditCredentialClick, - onAddAccountClick = onAddAccountClick, - titles = titles, - cardStyle = cardStyle, - dimens = dimens, - textStyles = textStyles, - divider = divider, - trailingIcon = trailingIcon - ) -} - -@Composable -fun AccountBindingContainer( - modifier: Modifier = Modifier, - sections: List, - isCurrentAccount: (provider: AccountProvider) -> Boolean, - hasAccount: (provider: AccountProvider) -> Boolean, - accountCredential: (provider: AccountProvider) -> String?, onUnbindAccountClick: (provider: AccountProvider) -> Unit, onEditPasswordClick: (provider: AccountProvider) -> Unit, onEditCredentialClick: (provider: AccountProvider) -> Unit, @@ -167,15 +118,18 @@ fun AccountBindingContainer( section.trailingContent?.invoke(this@Row) } - section.accountProviders.forEach { provider -> - val accountCredential = accountCredential(provider) + section.accounts.forEach { (provider, data) -> + val accountCredential = data?.credential + val hasCredential = accountCredential != null + val isCurrent = data?.isCurrent == true + val hasAccount = data != null when (provider) { is PasswordBasedAccountProvider -> { PasswordBasedAccount( - isCurrentAccount = isCurrentAccount(provider), - hasAccount = hasAccount(provider), - hasCredential = accountCredential != null, + isCurrentAccount = isCurrent, + hasAccount = hasAccount, + hasCredential = hasCredential, onAddAccountClick = { onAddAccountClick(provider) }, @@ -235,9 +189,9 @@ fun AccountBindingContainer( else -> { SocialAccount( - hasAccount = hasAccount(provider), - isCurrentAccount = isCurrentAccount(provider), - hasCredential = accountCredential != null, + hasAccount = hasAccount, + isCurrentAccount = isCurrent, + hasCredential = hasAccount, containerColor = cardStyle.containerColor, shape = cardStyle.shape, shadow = cardStyle.shadow, @@ -288,6 +242,11 @@ fun AccountBindingContainer( @Preview(showBackground = true, backgroundColor = 0xFFEFEFEF) @Composable private fun AccountBindingContainerPreview() { + val emailAccount = remember { AccountData(credential = "someone@gmail.com", isCurrent = true) } + val googleAccount = remember { AccountData(credential = "someone@gmail.com", isCurrent = false) } + val appleAccount = remember { null } + val facebookAccount = remember { null } + val titleInfoBadge: @Composable RowScope.() -> Unit = { Box( modifier = Modifier @@ -311,12 +270,18 @@ private fun AccountBindingContainerPreview() { sections = listOf( AccountsSection( title = "Account with mail:", - accountProviders = listOf(EmailAccountProvider()), + accounts = mapOf( + EmailAccountProvider() to emailAccount + ), trailingContent = titleInfoBadge ), AccountsSection( title = "Social accounts:", - accountProviders = listOf(GoogleAccountProvider, AppleAccountProvider, FacebookAccountProvider) + accounts = mapOf( + SocialAccountProvider.Google to googleAccount, + SocialAccountProvider.Apple to appleAccount, + SocialAccountProvider.Facebook to facebookAccount + ) ) ), textStyles = AccountBindingTextStyles( @@ -340,13 +305,6 @@ private fun AccountBindingContainerPreview() { currentAccountTitle = "Your current account", deleteAccountTitle = "Delete" ), - account = { provider -> - when (provider) { - is EmailAccountProvider -> DefaultAccount("someone@gmail.com", true) - is GoogleAccountProvider -> DefaultAccount("someone@gmail.com", false) - else -> null - } - }, onUnbindAccountClick = {}, onEditPasswordClick = {}, onEditCredentialClick = {}, From 494864064b67a2a6738e6a1483638f9a877fd9f3 Mon Sep 17 00:00:00 2001 From: Khotych Mykola Date: Wed, 15 Oct 2025 13:17:14 +0300 Subject: [PATCH 11/11] Rename credential to identifier --- design/api/current.api | 26 +++++++------- .../models/AccountBindingTextStyles.kt | 2 +- .../ui/accountbinding/models/AccountData.kt | 2 +- .../ui/AccountBindingContainer.kt | 34 +++++++++---------- .../accountbinding/ui/PasswordBasedAccount.kt | 30 ++++++++-------- .../ui/accountbinding/ui/SocialAccount.kt | 20 +++++------ 6 files changed, 57 insertions(+), 57 deletions(-) diff --git a/design/api/current.api b/design/api/current.api index 83fadeec..269a0318 100644 --- a/design/api/current.api +++ b/design/api/current.api @@ -81,7 +81,7 @@ package com.urlaunched.android.design.ui.accountbinding.models { } public final class AccountBindingTextStyles { - ctor public AccountBindingTextStyles(optional androidx.compose.ui.text.TextStyle sectionTitleStyle, optional androidx.compose.ui.text.TextStyle providerStyle, optional androidx.compose.ui.text.TextStyle accountCredentialStyle, optional androidx.compose.ui.text.TextStyle passwordStyle, optional androidx.compose.ui.text.TextStyle addAccountStyle, optional androidx.compose.ui.text.TextStyle currentAccountStyle, optional androidx.compose.ui.text.TextStyle deleteAccountStyle); + ctor public AccountBindingTextStyles(optional androidx.compose.ui.text.TextStyle sectionTitleStyle, optional androidx.compose.ui.text.TextStyle providerStyle, optional androidx.compose.ui.text.TextStyle accountIdentifierStyle, optional androidx.compose.ui.text.TextStyle passwordStyle, optional androidx.compose.ui.text.TextStyle addAccountStyle, optional androidx.compose.ui.text.TextStyle currentAccountStyle, optional androidx.compose.ui.text.TextStyle deleteAccountStyle); method public androidx.compose.ui.text.TextStyle component1(); method public androidx.compose.ui.text.TextStyle component2(); method public androidx.compose.ui.text.TextStyle component3(); @@ -89,15 +89,15 @@ package com.urlaunched.android.design.ui.accountbinding.models { method public androidx.compose.ui.text.TextStyle component5(); method public androidx.compose.ui.text.TextStyle component6(); method public androidx.compose.ui.text.TextStyle component7(); - method public com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles copy(androidx.compose.ui.text.TextStyle sectionTitleStyle, androidx.compose.ui.text.TextStyle providerStyle, androidx.compose.ui.text.TextStyle accountCredentialStyle, androidx.compose.ui.text.TextStyle passwordStyle, androidx.compose.ui.text.TextStyle addAccountStyle, androidx.compose.ui.text.TextStyle currentAccountStyle, androidx.compose.ui.text.TextStyle deleteAccountStyle); - method public androidx.compose.ui.text.TextStyle getAccountCredentialStyle(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles copy(androidx.compose.ui.text.TextStyle sectionTitleStyle, androidx.compose.ui.text.TextStyle providerStyle, androidx.compose.ui.text.TextStyle accountIdentifierStyle, androidx.compose.ui.text.TextStyle passwordStyle, androidx.compose.ui.text.TextStyle addAccountStyle, androidx.compose.ui.text.TextStyle currentAccountStyle, androidx.compose.ui.text.TextStyle deleteAccountStyle); + method public androidx.compose.ui.text.TextStyle getAccountIdentifierStyle(); method public androidx.compose.ui.text.TextStyle getAddAccountStyle(); method public androidx.compose.ui.text.TextStyle getCurrentAccountStyle(); method public androidx.compose.ui.text.TextStyle getDeleteAccountStyle(); method public androidx.compose.ui.text.TextStyle getPasswordStyle(); method public androidx.compose.ui.text.TextStyle getProviderStyle(); method public androidx.compose.ui.text.TextStyle getSectionTitleStyle(); - property public final androidx.compose.ui.text.TextStyle accountCredentialStyle; + property public final androidx.compose.ui.text.TextStyle accountIdentifierStyle; property public final androidx.compose.ui.text.TextStyle addAccountStyle; property public final androidx.compose.ui.text.TextStyle currentAccountStyle; property public final androidx.compose.ui.text.TextStyle deleteAccountStyle; @@ -156,13 +156,13 @@ package com.urlaunched.android.design.ui.accountbinding.models { } public final class AccountData { - ctor public AccountData(String? credential, boolean isCurrent); + ctor public AccountData(String? identifier, boolean isCurrent); method public String? component1(); method public boolean component2(); - method public com.urlaunched.android.design.ui.accountbinding.models.AccountData copy(String? credential, boolean isCurrent); - method public String? getCredential(); + method public com.urlaunched.android.design.ui.accountbinding.models.AccountData copy(String? identifier, boolean isCurrent); + method public String? getIdentifier(); method public boolean isCurrent(); - property public final String? credential; + property public final String? identifier; property public final boolean isCurrent; } @@ -225,17 +225,17 @@ package com.urlaunched.android.design.ui.accountbinding.models { package com.urlaunched.android.design.ui.accountbinding.ui { public final class AccountBindingContainerKt { - method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditCredentialClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); + method @androidx.compose.runtime.Composable public static void AccountBindingContainer(optional androidx.compose.ui.Modifier modifier, java.util.List sections, kotlin.jvm.functions.Function1 onUnbindAccountClick, kotlin.jvm.functions.Function1 onEditPasswordClick, kotlin.jvm.functions.Function1 onEditIdentifierClick, kotlin.jvm.functions.Function1 onAddAccountClick, com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTitles titles, optional com.urlaunched.android.design.ui.accountbinding.models.AccountCardStyle cardStyle, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingDimens dimens, optional com.urlaunched.android.design.ui.accountbinding.models.AccountBindingTextStyles textStyles, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 trailingIcon, optional kotlin.jvm.functions.Function1 footerSection); } public final class PasswordBasedAccountKt { - method @androidx.compose.runtime.Composable public static void PasswordBasedAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasAccount, boolean hasCredential, kotlin.jvm.functions.Function0 onEditCredentialClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, optional kotlin.jvm.functions.Function1 supportingContent); - method @androidx.compose.runtime.Composable public static void PasswordBasedAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasCredential, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onEditCredentialClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); + method @androidx.compose.runtime.Composable public static void PasswordBasedAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasAccount, boolean hasIdentifier, kotlin.jvm.functions.Function0 onEditIdentifierClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountIdentifier, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, optional kotlin.jvm.functions.Function1 supportingContent); + method @androidx.compose.runtime.Composable public static void PasswordBasedAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasIdentifier, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onEditIdentifierClick, kotlin.jvm.functions.Function0 onAddAccountClick, kotlin.jvm.functions.Function0 onEditPasswordClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, optional kotlin.jvm.functions.Function0 divider, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountIdentifier, kotlin.jvm.functions.Function1 passwordContent, kotlin.jvm.functions.Function1 trailingIcon, kotlin.jvm.functions.Function1 noAccountContent, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); } public final class SocialAccountKt { - method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasCredential, optional boolean enabled, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 addAccount, optional kotlin.jvm.functions.Function1 supportingContent); - method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasCredential, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountCredential, kotlin.jvm.functions.Function1 addAccount, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Modifier cardModifier, boolean hasIdentifier, optional boolean enabled, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountIdentifier, kotlin.jvm.functions.Function1 addAccount, optional kotlin.jvm.functions.Function1 supportingContent); + method @androidx.compose.runtime.Composable public static void SocialAccount(optional androidx.compose.ui.Modifier modifier, boolean isCurrentAccount, boolean hasAccount, boolean hasIdentifier, optional long containerColor, optional androidx.compose.ui.graphics.Shape shape, optional com.urlaunched.android.design.ui.shadow.models.ShadowStyle? shadow, kotlin.jvm.functions.Function0 onAddAccountClick, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.layout.PaddingValues supportingContentPadding, kotlin.jvm.functions.Function1 providerContent, kotlin.jvm.functions.Function1 accountIdentifier, kotlin.jvm.functions.Function1 addAccount, kotlin.jvm.functions.Function1 deleteAccount, kotlin.jvm.functions.Function1 currentAccount); } } diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt index 58ba618e..6dd12285 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountBindingTextStyles.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.text.TextStyle data class AccountBindingTextStyles( val sectionTitleStyle: TextStyle = TextStyle(), val providerStyle: TextStyle = TextStyle(), - val accountCredentialStyle: TextStyle = TextStyle(), + val accountIdentifierStyle: TextStyle = TextStyle(), val passwordStyle: TextStyle = TextStyle(), val addAccountStyle: TextStyle = TextStyle(), val currentAccountStyle: TextStyle = TextStyle(), diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt index 14e02025..de214aca 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt @@ -1,6 +1,6 @@ package com.urlaunched.android.design.ui.accountbinding.models data class AccountData( - val credential: String?, + val identifier: String?, val isCurrent: Boolean ) \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt index b137192f..0214513a 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt @@ -53,7 +53,7 @@ fun AccountBindingContainer( sections: List, onUnbindAccountClick: (provider: AccountProvider) -> Unit, onEditPasswordClick: (provider: AccountProvider) -> Unit, - onEditCredentialClick: (provider: AccountProvider) -> Unit, + onEditIdentifierClick: (provider: AccountProvider) -> Unit, onAddAccountClick: (provider: AccountProvider) -> Unit, titles: AccountBindingTitles, cardStyle: AccountCardStyle = AccountCardStyle(), @@ -119,8 +119,8 @@ fun AccountBindingContainer( } section.accounts.forEach { (provider, data) -> - val accountCredential = data?.credential - val hasCredential = accountCredential != null + val accountIdentifier = data?.identifier + val hasIdentifier = accountIdentifier != null val isCurrent = data?.isCurrent == true val hasAccount = data != null @@ -129,15 +129,15 @@ fun AccountBindingContainer( PasswordBasedAccount( isCurrentAccount = isCurrent, hasAccount = hasAccount, - hasCredential = hasCredential, + hasIdentifier = hasIdentifier, onAddAccountClick = { onAddAccountClick(provider) }, onEditPasswordClick = { onEditPasswordClick(provider) }, - onEditCredentialClick = { - onEditCredentialClick(provider) + onEditIdentifierClick = { + onEditIdentifierClick(provider) }, divider = divider, trailingIcon = { @@ -148,10 +148,10 @@ fun AccountBindingContainer( providerContent = { providerContent(provider) }, - accountCredential = { + accountIdentifier = { Text( - text = accountCredential.orEmpty(), - style = textStyles.accountCredentialStyle, + text = accountIdentifier.orEmpty(), + style = textStyles.accountIdentifierStyle, overflow = TextOverflow.Ellipsis, maxLines = 1 ) @@ -191,7 +191,7 @@ fun AccountBindingContainer( SocialAccount( hasAccount = hasAccount, isCurrentAccount = isCurrent, - hasCredential = hasAccount, + hasIdentifier = hasAccount, containerColor = cardStyle.containerColor, shape = cardStyle.shape, shadow = cardStyle.shadow, @@ -203,10 +203,10 @@ fun AccountBindingContainer( providerContent = { providerContent(provider) }, - accountCredential = { + accountIdentifier = { Text( - text = accountCredential.orEmpty(), - style = textStyles.accountCredentialStyle, + text = accountIdentifier.orEmpty(), + style = textStyles.accountIdentifierStyle, overflow = TextOverflow.Ellipsis, maxLines = 1 ) @@ -242,8 +242,8 @@ fun AccountBindingContainer( @Preview(showBackground = true, backgroundColor = 0xFFEFEFEF) @Composable private fun AccountBindingContainerPreview() { - val emailAccount = remember { AccountData(credential = "someone@gmail.com", isCurrent = true) } - val googleAccount = remember { AccountData(credential = "someone@gmail.com", isCurrent = false) } + val emailAccount = remember { AccountData(identifier = "someone@gmail.com", isCurrent = true) } + val googleAccount = remember { AccountData(identifier = "someone@gmail.com", isCurrent = false) } val appleAccount = remember { null } val facebookAccount = remember { null } @@ -287,7 +287,7 @@ private fun AccountBindingContainerPreview() { textStyles = AccountBindingTextStyles( sectionTitleStyle = MaterialTheme.typography.titleMedium, providerStyle = MaterialTheme.typography.bodyLarge, - accountCredentialStyle = MaterialTheme.typography.bodyMedium, + accountIdentifierStyle = MaterialTheme.typography.bodyMedium, passwordStyle = MaterialTheme.typography.bodyLarge, addAccountStyle = MaterialTheme.typography.labelLarge.copy(color = MaterialTheme.colorScheme.primary), currentAccountStyle = MaterialTheme.typography.labelMedium, @@ -307,7 +307,7 @@ private fun AccountBindingContainerPreview() { ), onUnbindAccountClick = {}, onEditPasswordClick = {}, - onEditCredentialClick = {}, + onEditIdentifierClick = {}, onAddAccountClick = {} ) } \ No newline at end of file diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt index de2ffb50..a6bf6685 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt @@ -36,11 +36,11 @@ fun PasswordBasedAccount( modifier: Modifier = Modifier, isCurrentAccount: Boolean, hasAccount: Boolean, - hasCredential: Boolean, + hasIdentifier: Boolean, containerColor: Color = Color.White, shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), shadow: ShadowStyle? = null, - onEditCredentialClick: () -> Unit, + onEditIdentifierClick: () -> Unit, onAddAccountClick: () -> Unit, onEditPasswordClick: () -> Unit, contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), @@ -49,7 +49,7 @@ fun PasswordBasedAccount( HorizontalDivider() }, providerContent: @Composable RowScope.() -> Unit, - accountCredential: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, passwordContent: @Composable RowScope.() -> Unit, trailingIcon: @Composable RowScope.() -> Unit, noAccountContent: @Composable RowScope.() -> Unit, @@ -63,14 +63,14 @@ fun PasswordBasedAccount( .background(containerColor), modifier = modifier, hasAccount = hasAccount, - hasCredential = hasCredential, - onEditCredentialClick = onEditCredentialClick, + hasIdentifier = hasIdentifier, + onEditIdentifierClick = onEditIdentifierClick, onAddAccountClick = onAddAccountClick, onEditPasswordClick = onEditPasswordClick, contentPadding = contentPadding, divider = divider, providerContent = providerContent, - accountCredential = accountCredential, + accountIdentifier = accountIdentifier, passwordContent = passwordContent, trailingIcon = trailingIcon, noAccountContent = noAccountContent, @@ -98,8 +98,8 @@ fun PasswordBasedAccount( modifier: Modifier = Modifier, cardModifier: Modifier = Modifier, hasAccount: Boolean, - hasCredential: Boolean, - onEditCredentialClick: () -> Unit, + hasIdentifier: Boolean, + onEditIdentifierClick: () -> Unit, onAddAccountClick: () -> Unit, onEditPasswordClick: () -> Unit, contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), @@ -107,7 +107,7 @@ fun PasswordBasedAccount( HorizontalDivider() }, providerContent: @Composable RowScope.() -> Unit, - accountCredential: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, passwordContent: @Composable RowScope.() -> Unit, trailingIcon: @Composable RowScope.() -> Unit, noAccountContent: @Composable RowScope.() -> Unit, @@ -124,7 +124,7 @@ fun PasswordBasedAccount( .fillMaxWidth() .debouncedClickable { if (hasAccount) { - onEditCredentialClick() + onEditIdentifierClick() } else { onAddAccountClick() } @@ -135,8 +135,8 @@ fun PasswordBasedAccount( Spacer(Modifier.weight(1f)) - if (hasCredential) { - accountCredential() + if (hasIdentifier) { + accountIdentifier() trailingIcon() } else { @@ -172,11 +172,11 @@ private fun PasswordBasedAccountPreview() { PasswordBasedAccount( isCurrentAccount = true, hasAccount = true, - hasCredential = true, + hasIdentifier = true, modifier = Modifier .background(Color.LightGray) .padding(Dimens.spacingNormal), - onEditCredentialClick = { }, + onEditIdentifierClick = { }, onAddAccountClick = { }, onEditPasswordClick = { }, providerContent = { @@ -185,7 +185,7 @@ private fun PasswordBasedAccountPreview() { fontWeight = FontWeight.Bold ) }, - accountCredential = { + accountIdentifier = { Text( text = "someone@gmail.com", textAlign = TextAlign.End, diff --git a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt index c9c193aa..bb3c565f 100644 --- a/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt @@ -35,7 +35,7 @@ fun SocialAccount( modifier: Modifier = Modifier, isCurrentAccount: Boolean, hasAccount: Boolean, - hasCredential: Boolean, + hasIdentifier: Boolean, containerColor: Color = Color.White, shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), shadow: ShadowStyle? = null, @@ -43,7 +43,7 @@ fun SocialAccount( contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), providerContent: @Composable RowScope.() -> Unit, - accountCredential: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, addAccount: @Composable RowScope.() -> Unit, deleteAccount: @Composable ColumnScope.() -> Unit, currentAccount: @Composable ColumnScope.() -> Unit @@ -55,10 +55,10 @@ fun SocialAccount( .background(containerColor), modifier = modifier, enabled = !hasAccount, - hasCredential = hasCredential, + hasIdentifier = hasIdentifier, onAddAccountClick = onAddAccountClick, contentPadding = contentPadding, - accountCredential = accountCredential, + accountIdentifier = accountIdentifier, addAccount = addAccount, providerContent = providerContent, supportingContent = { @@ -84,12 +84,12 @@ fun SocialAccount( fun SocialAccount( modifier: Modifier = Modifier, cardModifier: Modifier = Modifier, - hasCredential: Boolean, + hasIdentifier: Boolean, enabled: Boolean = true, onAddAccountClick: () -> Unit, contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, providerContent: @Composable RowScope.() -> Unit, - accountCredential: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, addAccount: @Composable RowScope.() -> Unit, supportingContent: @Composable ColumnScope.() -> Unit = {} ) { @@ -111,8 +111,8 @@ fun SocialAccount( Spacer(Modifier.weight(1f)) - if (hasCredential) { - accountCredential() + if (hasIdentifier) { + accountIdentifier() } else { addAccount() } @@ -127,7 +127,7 @@ fun SocialAccount( @Composable private fun SocialAccountPreview() { SocialAccount( - hasCredential = true, + hasIdentifier = true, hasAccount = true, isCurrentAccount = true, modifier = Modifier @@ -147,7 +147,7 @@ private fun SocialAccountPreview() { fontWeight = FontWeight.Bold ) }, - accountCredential = { + accountIdentifier = { Text( text = "someone@gmail.com" )