diff --git a/design/api/current.api b/design/api/current.api index 0e9da44d..269a0318 100644 --- a/design/api/current.api +++ b/design/api/current.api @@ -67,6 +67,179 @@ package com.urlaunched.android.design.resources.dimens { } +package com.urlaunched.android.design.ui.accountbinding.models { + + 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 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(); + 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 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 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; + 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 final class AccountData { + 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? identifier, boolean isCurrent); + method public String? getIdentifier(); + method public boolean isCurrent(); + property public final String? identifier; + property public final boolean isCurrent; + } + + 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.Map accounts, optional kotlin.jvm.functions.Function1? trailingContent); + method public String component1(); + 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.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.Map accounts; + property public final String title; + property public final kotlin.jvm.functions.Function1? trailingContent; + } + + 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 interface PasswordBasedAccountProvider extends com.urlaunched.android.design.ui.accountbinding.models.AccountProvider { + } + + public abstract sealed class SocialAccountProvider 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.SocialAccountProvider.Apple INSTANCE; + } + + 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.SocialAccountProvider.Facebook INSTANCE; + } + + 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; + } + +} + +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 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 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 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); + } + +} + package com.urlaunched.android.design.ui.backhandler { public final class DisableBackButtonKt { @@ -428,11 +601,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 { 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 new file mode 100644 index 00000000..354fd3db --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/constants/SocialAccountDimens.kt @@ -0,0 +1,19 @@ +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 { + + val providerIconSize = 24.dp + + 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/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..6dd12285 --- /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 accountIdentifierStyle: 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..dbf9f791 --- /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 socialContentPadding: 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/AccountData.kt b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountData.kt new file mode 100644 index 00000000..de214aca --- /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 identifier: 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 new file mode 100644 index 00000000..9f227168 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/models/AccountProvider.kt @@ -0,0 +1,35 @@ +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 + +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 new file mode 100644 index 00000000..11720a3d --- /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 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 new file mode 100644 index 00000000..0214513a --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/AccountBindingContainer.kt @@ -0,0 +1,313 @@ +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.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.EmailAccountProvider +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, + onUnbindAccountClick: (provider: AccountProvider) -> Unit, + onEditPasswordClick: (provider: AccountProvider) -> Unit, + onEditIdentifierClick: (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.accounts.forEach { (provider, data) -> + val accountIdentifier = data?.identifier + val hasIdentifier = accountIdentifier != null + val isCurrent = data?.isCurrent == true + val hasAccount = data != null + + when (provider) { + is PasswordBasedAccountProvider -> { + PasswordBasedAccount( + isCurrentAccount = isCurrent, + hasAccount = hasAccount, + hasIdentifier = hasIdentifier, + onAddAccountClick = { + onAddAccountClick(provider) + }, + onEditPasswordClick = { + onEditPasswordClick(provider) + }, + onEditIdentifierClick = { + onEditIdentifierClick(provider) + }, + divider = divider, + trailingIcon = { + Spacer(Modifier.width(cardStyle.trailingIconSpacing)) + + trailingIcon() + }, + providerContent = { + providerContent(provider) + }, + accountIdentifier = { + Text( + text = accountIdentifier.orEmpty(), + style = textStyles.accountIdentifierStyle, + 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, + isCurrentAccount = isCurrent, + hasIdentifier = hasAccount, + containerColor = cardStyle.containerColor, + shape = cardStyle.shape, + shadow = cardStyle.shadow, + onAddAccountClick = { + onAddAccountClick(provider) + }, + contentPadding = cardStyle.socialContentPadding, + supportingContentPadding = cardStyle.supportingContentPadding, + providerContent = { + providerContent(provider) + }, + accountIdentifier = { + Text( + text = accountIdentifier.orEmpty(), + style = textStyles.accountIdentifierStyle, + 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 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 } + + 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:", + accounts = mapOf( + EmailAccountProvider() to emailAccount + ), + trailingContent = titleInfoBadge + ), + AccountsSection( + title = "Social accounts:", + accounts = mapOf( + SocialAccountProvider.Google to googleAccount, + SocialAccountProvider.Apple to appleAccount, + SocialAccountProvider.Facebook to facebookAccount + ) + ) + ), + textStyles = AccountBindingTextStyles( + sectionTitleStyle = MaterialTheme.typography.titleMedium, + providerStyle = MaterialTheme.typography.bodyLarge, + accountIdentifierStyle = 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" + ), + onUnbindAccountClick = {}, + onEditPasswordClick = {}, + 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 new file mode 100644 index 00000000..a6bf6685 --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/PasswordBasedAccount.kt @@ -0,0 +1,221 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +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.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 PasswordBasedAccount( + modifier: Modifier = Modifier, + isCurrentAccount: Boolean, + hasAccount: Boolean, + hasIdentifier: Boolean, + containerColor: Color = Color.White, + shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), + shadow: ShadowStyle? = null, + onEditIdentifierClick: () -> Unit, + onAddAccountClick: () -> Unit, + onEditPasswordClick: () -> Unit, + contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), + supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), + divider: @Composable () -> Unit = { + HorizontalDivider() + }, + providerContent: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, + passwordContent: @Composable RowScope.() -> Unit, + trailingIcon: @Composable RowScope.() -> Unit, + noAccountContent: @Composable RowScope.() -> Unit, + deleteAccount: @Composable ColumnScope.() -> Unit, + currentAccount: @Composable ColumnScope.() -> Unit +) { + PasswordBasedAccount( + cardModifier = Modifier + .ifNotNull(shadow) { Modifier.shadow(it) } + .clip(shape) + .background(containerColor), + modifier = modifier, + hasAccount = hasAccount, + hasIdentifier = hasIdentifier, + onEditIdentifierClick = onEditIdentifierClick, + onAddAccountClick = onAddAccountClick, + onEditPasswordClick = onEditPasswordClick, + contentPadding = contentPadding, + divider = divider, + providerContent = providerContent, + accountIdentifier = accountIdentifier, + passwordContent = passwordContent, + trailingIcon = trailingIcon, + noAccountContent = noAccountContent, + supportingContent = { + if (hasAccount) { + Column( + horizontalAlignment = Alignment.End, + modifier = Modifier + .fillMaxWidth() + .padding(supportingContentPadding) + ) { + if (isCurrentAccount) { + currentAccount() + } else { + deleteAccount() + } + } + } + } + ) +} + +@Composable +fun PasswordBasedAccount( + modifier: Modifier = Modifier, + cardModifier: Modifier = Modifier, + hasAccount: Boolean, + hasIdentifier: Boolean, + onEditIdentifierClick: () -> Unit, + onAddAccountClick: () -> Unit, + onEditPasswordClick: () -> Unit, + contentPadding: PaddingValues = PaddingValues(Dimens.spacingNormal), + divider: @Composable () -> Unit = { + HorizontalDivider() + }, + providerContent: @Composable RowScope.() -> Unit, + accountIdentifier: @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) { + onEditIdentifierClick() + } else { + onAddAccountClick() + } + } + .padding(contentPadding) + ) { + providerContent() + + Spacer(Modifier.weight(1f)) + + if (hasIdentifier) { + accountIdentifier() + + trailingIcon() + } else { + noAccountContent() + } + } + + if (hasAccount) { + divider() + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .debouncedClickable(onClick = onEditPasswordClick) + .padding(contentPadding) + ) { + passwordContent() + + trailingIcon() + } + } + } + + supportingContent() + } +} + +@Preview +@Composable +private fun PasswordBasedAccountPreview() { + PasswordBasedAccount( + isCurrentAccount = true, + hasAccount = true, + hasIdentifier = true, + modifier = Modifier + .background(Color.LightGray) + .padding(Dimens.spacingNormal), + onEditIdentifierClick = { }, + onAddAccountClick = { }, + onEditPasswordClick = { }, + providerContent = { + Text( + text = "Gmail", + fontWeight = FontWeight.Bold + ) + }, + accountIdentifier = { + 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 new file mode 100644 index 00000000..bb3c565f --- /dev/null +++ b/design/src/main/java/com/urlaunched/android/design/ui/accountbinding/ui/SocialAccount.kt @@ -0,0 +1,173 @@ +package com.urlaunched.android.design.ui.accountbinding.ui + +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 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, + isCurrentAccount: Boolean, + hasAccount: Boolean, + hasIdentifier: Boolean, + containerColor: Color = Color.White, + shape: Shape = RoundedCornerShape(Dimens.cornerRadiusBig), + shadow: ShadowStyle? = null, + onAddAccountClick: () -> Unit, + contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, + supportingContentPadding: PaddingValues = PaddingValues(top = Dimens.spacingSmall), + providerContent: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, + addAccount: @Composable RowScope.() -> Unit, + deleteAccount: @Composable ColumnScope.() -> Unit, + currentAccount: @Composable ColumnScope.() -> Unit +) { + SocialAccount( + cardModifier = Modifier + .ifNotNull(shadow) { Modifier.shadow(it) } + .clip(shape) + .background(containerColor), + modifier = modifier, + enabled = !hasAccount, + hasIdentifier = hasIdentifier, + onAddAccountClick = onAddAccountClick, + contentPadding = contentPadding, + accountIdentifier = accountIdentifier, + 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, + hasIdentifier: Boolean, + enabled: Boolean = true, + onAddAccountClick: () -> Unit, + contentPadding: PaddingValues = SocialAccountDimens.defaultContentPadding, + providerContent: @Composable RowScope.() -> Unit, + accountIdentifier: @Composable RowScope.() -> Unit, + addAccount: @Composable RowScope.() -> Unit, + supportingContent: @Composable ColumnScope.() -> Unit = {} +) { + Column( + modifier = modifier + ) { + Column(modifier = cardModifier) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .debouncedClickable( + enabled = enabled, + onClick = onAddAccountClick + ) + .padding(contentPadding) + ) { + providerContent() + + Spacer(Modifier.weight(1f)) + + if (hasIdentifier) { + accountIdentifier() + } else { + addAccount() + } + } + } + + supportingContent() + } +} + +@Preview +@Composable +private fun SocialAccountPreview() { + SocialAccount( + hasIdentifier = 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 + ) + }, + accountIdentifier = { + 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 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 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..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" @@ -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" } 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