From f2357c61518687ba0b9732722f1709737676e655 Mon Sep 17 00:00:00 2001 From: "Andres Gomez, Thomas (ITDV CC) - AF (ext)" Date: Sat, 15 Jul 2023 22:00:36 +0200 Subject: [PATCH] Add google signin & navigation. --- app/build.gradle.kts | 44 ++++- app/src/main/AndroidManifest.xml | 2 + .../com/pixelized/lexique/MainActivity.kt | 32 --- .../detail/CharacterDetailViewModel.kt | 9 - .../com/pixelized/rplexicon/MainActivity.kt | 48 +++++ .../{lexique => rplexicon}/MainApplication.kt | 2 +- .../{lexique => rplexicon}/model/Lexicon.kt | 2 +- .../module/NetworkModule.kt | 4 +- .../network/IGoogleSpreadSheet.kt | 2 +- .../repository/LexiconRepository.kt | 6 +- .../ui/navigation/ComposableAuthentication.kt | 25 +++ .../navigation/ComposableCharacterDetail.kt | 49 +++++ .../ui/navigation/ComposableLexicon.kt | 25 +++ .../rplexicon/ui/navigation/ScreenNavHost.kt | 45 +++++ .../ui/navigation/animatedComposable.kt | 107 ++++++++++ .../authentication/AuthenticationScreen.kt | 182 ++++++++++++++++++ .../authentication/AuthenticationViewModel.kt | 95 +++++++++ .../screens/detail/CharacterDetailScreen.kt | 84 ++++---- .../detail/CharacterDetailViewModel.kt | 35 ++++ .../ui/screens/lexicon/LexiconItem.kt | 4 +- .../ui/screens/lexicon/LexiconScreen.kt | 12 +- .../ui/screens/lexicon/LexiconViewModel.kt | 6 +- .../{lexique => rplexicon}/ui/theme/Color.kt | 2 +- .../{lexique => rplexicon}/ui/theme/Theme.kt | 26 +-- .../{lexique => rplexicon}/ui/theme/Type.kt | 2 +- .../ui/theme/colors/GoogleColorPalette.kt | 12 ++ .../utilitary/extentions/StringEt.kt | 3 + app/src/main/res/values-fr/strings.xml | 5 + app/src/main/res/values/google.xml | 4 + app/src/main/res/values/strings.xml | 2 + build.gradle.kts | 2 +- 31 files changed, 764 insertions(+), 114 deletions(-) delete mode 100644 app/src/main/java/com/pixelized/lexique/MainActivity.kt delete mode 100644 app/src/main/java/com/pixelized/lexique/ui/screens/detail/CharacterDetailViewModel.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/MainActivity.kt rename app/src/main/java/com/pixelized/{lexique => rplexicon}/MainApplication.kt (80%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/model/Lexicon.kt (89%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/module/NetworkModule.kt (84%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/network/IGoogleSpreadSheet.kt (91%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/repository/LexiconRepository.kt (95%) create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableAuthentication.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableCharacterDetail.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableLexicon.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/navigation/ScreenNavHost.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/navigation/animatedComposable.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/screens/detail/CharacterDetailScreen.kt (71%) create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailViewModel.kt rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/screens/lexicon/LexiconItem.kt (96%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/screens/lexicon/LexiconScreen.kt (86%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/screens/lexicon/LexiconViewModel.kt (89%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/theme/Color.kt (85%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/theme/Theme.kt (72%) rename app/src/main/java/com/pixelized/{lexique => rplexicon}/ui/theme/Type.kt (95%) create mode 100644 app/src/main/java/com/pixelized/rplexicon/ui/theme/colors/GoogleColorPalette.kt create mode 100644 app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/StringEt.kt create mode 100644 app/src/main/res/values-fr/strings.xml create mode 100644 app/src/main/res/values/google.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3dcea9c..26e777c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import com.android.build.gradle.internal.dsl.SigningConfig + plugins { id("com.android.application") id("org.jetbrains.kotlin.android") @@ -6,15 +8,24 @@ plugins { } android { - namespace = "com.pixelized.lexique" + namespace = "com.pixelized.rplexicon" compileSdk = 33 + signingConfigs { + create("pixelized") { + storeFile = file(project.properties["PIXELIZED_RELEASE_STORE_FILE"] as String) + storePassword = project.properties["PIXELIZED_RELEASE_STORE_PASSWORD"] as String + keyAlias = project.properties["PIXELIZED_RELEASE_KEY_ALIAS"] as String + keyPassword = project.properties["PIXELIZED_RELEASE_KEY_PASSWORD"] as String + } + } + defaultConfig { - applicationId = "com.pixelized.lexique" + applicationId = "com.pixelized.rplexicon" minSdk = 26 targetSdk = 33 versionCode = 1 - versionName = "1.0" + versionName = "0.1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -24,10 +35,20 @@ android { buildTypes { release { - isMinifyEnabled = false + isDebuggable = false + isMinifyEnabled = true + signingConfig = signingConfigs.pixelized proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" + getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" + ) + } + debug { + applicationIdSuffix = ".dev" + isDebuggable = true + isMinifyEnabled = false + signingConfig = signingConfigs.pixelized + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } @@ -67,15 +88,24 @@ dependencies { implementation("androidx.compose.material3:material3:1.1.1") debugImplementation("androidx.compose.ui:ui-tooling:1.4.3") + // Accompanist + implementation("com.google.accompanist:accompanist-navigation-animation:0.30.1") + implementation("com.google.accompanist:accompanist-placeholder:0.30.1") + // Hilt: Dependency injection implementation("androidx.hilt:hilt-navigation-compose:1.0.0") implementation("com.google.dagger:hilt-android:2.45") kapt("com.google.dagger:hilt-compiler:2.45") + // Google service + implementation("com.google.android.gms:play-services-auth:20.6.0") + // Image implementation("com.github.skydoves:landscapist-glide:2.1.11") kapt("com.github.bumptech.glide:compiler:4.14.2") // this have to be align with landscapist-glide // Retrofit : Network implementation("com.squareup.retrofit2:retrofit:2.9.0") -} \ No newline at end of file +} + +private val NamedDomainObjectContainer.pixelized get() = this.getByName("pixelized") \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5c1cd19..16743da 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,8 @@ xmlns:tools="http://schemas.android.com/tools"> + + { error("Activity not available") } + +@AndroidEntryPoint +class MainActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContent { + LexiconTheme { + CompositionLocalProvider( + LocalActivity provides this + ) { + Scaffold( + content = { padding -> + Surface( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues = padding), + color = MaterialTheme.colorScheme.background + ) { + ScreenNavHost() + } + } + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/lexique/MainApplication.kt b/app/src/main/java/com/pixelized/rplexicon/MainApplication.kt similarity index 80% rename from app/src/main/java/com/pixelized/lexique/MainApplication.kt rename to app/src/main/java/com/pixelized/rplexicon/MainApplication.kt index 2d0e14d..d62a343 100644 --- a/app/src/main/java/com/pixelized/lexique/MainApplication.kt +++ b/app/src/main/java/com/pixelized/rplexicon/MainApplication.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique +package com.pixelized.rplexicon import android.app.Application import dagger.hilt.android.HiltAndroidApp diff --git a/app/src/main/java/com/pixelized/lexique/model/Lexicon.kt b/app/src/main/java/com/pixelized/rplexicon/model/Lexicon.kt similarity index 89% rename from app/src/main/java/com/pixelized/lexique/model/Lexicon.kt rename to app/src/main/java/com/pixelized/rplexicon/model/Lexicon.kt index db6e6e1..dafe0a0 100644 --- a/app/src/main/java/com/pixelized/lexique/model/Lexicon.kt +++ b/app/src/main/java/com/pixelized/rplexicon/model/Lexicon.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.model +package com.pixelized.rplexicon.model import android.net.Uri diff --git a/app/src/main/java/com/pixelized/lexique/module/NetworkModule.kt b/app/src/main/java/com/pixelized/rplexicon/module/NetworkModule.kt similarity index 84% rename from app/src/main/java/com/pixelized/lexique/module/NetworkModule.kt rename to app/src/main/java/com/pixelized/rplexicon/module/NetworkModule.kt index c201a3e..843aceb 100644 --- a/app/src/main/java/com/pixelized/lexique/module/NetworkModule.kt +++ b/app/src/main/java/com/pixelized/rplexicon/module/NetworkModule.kt @@ -1,6 +1,6 @@ -package com.pixelized.lexique.module +package com.pixelized.rplexicon.module -import com.pixelized.lexique.network.IGoogleSpreadSheet +import com.pixelized.rplexicon.network.IGoogleSpreadSheet import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/app/src/main/java/com/pixelized/lexique/network/IGoogleSpreadSheet.kt b/app/src/main/java/com/pixelized/rplexicon/network/IGoogleSpreadSheet.kt similarity index 91% rename from app/src/main/java/com/pixelized/lexique/network/IGoogleSpreadSheet.kt rename to app/src/main/java/com/pixelized/rplexicon/network/IGoogleSpreadSheet.kt index 7829b56..2e2c6c7 100644 --- a/app/src/main/java/com/pixelized/lexique/network/IGoogleSpreadSheet.kt +++ b/app/src/main/java/com/pixelized/rplexicon/network/IGoogleSpreadSheet.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.network +package com.pixelized.rplexicon.network import retrofit2.http.GET diff --git a/app/src/main/java/com/pixelized/lexique/repository/LexiconRepository.kt b/app/src/main/java/com/pixelized/rplexicon/repository/LexiconRepository.kt similarity index 95% rename from app/src/main/java/com/pixelized/lexique/repository/LexiconRepository.kt rename to app/src/main/java/com/pixelized/rplexicon/repository/LexiconRepository.kt index b30d847..fd18f96 100644 --- a/app/src/main/java/com/pixelized/lexique/repository/LexiconRepository.kt +++ b/app/src/main/java/com/pixelized/rplexicon/repository/LexiconRepository.kt @@ -1,8 +1,8 @@ -package com.pixelized.lexique.repository +package com.pixelized.rplexicon.repository import android.net.Uri -import com.pixelized.lexique.model.Lexicon -import com.pixelized.lexique.network.IGoogleSpreadSheet +import com.pixelized.rplexicon.model.Lexicon +import com.pixelized.rplexicon.network.IGoogleSpreadSheet import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableAuthentication.kt b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableAuthentication.kt new file mode 100644 index 0000000..12f8972 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableAuthentication.kt @@ -0,0 +1,25 @@ +package com.pixelized.rplexicon.ui.navigation + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.NavOptionsBuilder +import com.pixelized.rplexicon.ui.screens.authentication.AuthenticationScreen + +private const val ROUTE = "authentication" + +const val AUTHENTICATION_ROUTE = ROUTE + +fun NavGraphBuilder.composableAuthentication() { + animatedComposable( + route = AUTHENTICATION_ROUTE, + animation = NavigationAnimation.Fade, + ) { + AuthenticationScreen() + } +} + +fun NavHostController.navigateToAuthentication( + option: NavOptionsBuilder.() -> Unit = {}, +) { + navigate(route = ROUTE, builder = option) +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableCharacterDetail.kt b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableCharacterDetail.kt new file mode 100644 index 0000000..9ddd856 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableCharacterDetail.kt @@ -0,0 +1,49 @@ +package com.pixelized.rplexicon.ui.navigation + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.lifecycle.SavedStateHandle +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.NavOptionsBuilder +import androidx.navigation.NavType +import androidx.navigation.navArgument +import com.pixelized.rplexicon.ui.screens.detail.CharacterDetailScreen +import com.pixelized.rplexicon.utilitary.extentions.ARG + +private const val ROUTE = "CharacterDetail" +private const val ARG_ID = "id" +val CHARACTER_DETAIL_ROUTE = "$ROUTE?${ARG_ID.ARG}" + +@Stable +@Immutable +data class CharacterDetailArgument( + val id: String, +) + +val SavedStateHandle.characterDetailArgument: CharacterDetailArgument + get() = CharacterDetailArgument( + id = get(ARG_ID) ?: error("CharacterDetailArgument argument: id") + ) + +fun NavGraphBuilder.composableCharacterDetail() { + animatedComposable( + route = CHARACTER_DETAIL_ROUTE, + arguments = listOf( + navArgument(name = ARG_ID) { + type = NavType.StringType + } + ), + animation = NavigationAnimation.Push, + ) { + CharacterDetailScreen() + } +} + +fun NavHostController.navigateToCharacterDetail( + id: String, + option: NavOptionsBuilder.() -> Unit = {}, +) { + val route = "$ROUTE?$ARG_ID=$id" + navigate(route = route, builder = option) +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableLexicon.kt b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableLexicon.kt new file mode 100644 index 0000000..fcc10a2 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ComposableLexicon.kt @@ -0,0 +1,25 @@ +package com.pixelized.rplexicon.ui.navigation + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.NavOptionsBuilder +import com.pixelized.rplexicon.ui.screens.lexicon.LexiconScreen + +private const val ROUTE = "lexicon" + +const val LEXICON_ROUTE = ROUTE + +fun NavGraphBuilder.composableLexicon() { + animatedComposable( + route = LEXICON_ROUTE, + animation = NavigationAnimation.Fade, + ) { + LexiconScreen() + } +} + +fun NavHostController.navigateToLexicon( + option: NavOptionsBuilder.() -> Unit = {}, +) { + navigate(route = ROUTE, builder = option) +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ScreenNavHost.kt b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ScreenNavHost.kt new file mode 100644 index 0000000..ebfc9a8 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/ScreenNavHost.kt @@ -0,0 +1,45 @@ +package com.pixelized.rplexicon.ui.navigation + +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.navigation.NavHostController +import androidx.navigation.NavOptionsBuilder +import com.google.accompanist.navigation.animation.AnimatedNavHost +import com.google.accompanist.navigation.animation.rememberAnimatedNavController + +val LocalScreenNavHost = staticCompositionLocalOf { + error("LocalScreenNavHost not ready") +} + +@OptIn(ExperimentalAnimationApi::class) +@Composable +fun ScreenNavHost( + navHostController: NavHostController = rememberAnimatedNavController(), + startDestination: String = AUTHENTICATION_ROUTE, +) { + CompositionLocalProvider( + LocalScreenNavHost provides navHostController, + ) { + AnimatedNavHost( + navController = navHostController, + startDestination = startDestination, + ) { + composableAuthentication() + composableLexicon() + composableCharacterDetail() + } + } +} + +fun defaultOption(): NavOptionsBuilder.() -> Unit = { } + +fun rootOption(): NavOptionsBuilder.() -> Unit = { + launchSingleTop = true + restoreState = true + popUpTo(0) { + saveState = true + inclusive = true + } +} diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/navigation/animatedComposable.kt b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/animatedComposable.kt new file mode 100644 index 0000000..bfb3bfd --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/navigation/animatedComposable.kt @@ -0,0 +1,107 @@ +package com.pixelized.rplexicon.ui.navigation + +import androidx.compose.animation.* +import androidx.compose.animation.core.tween +import androidx.compose.runtime.Composable +import androidx.navigation.NamedNavArgument +import androidx.navigation.NavBackStackEntry +import androidx.navigation.NavGraphBuilder +import com.google.accompanist.navigation.animation.composable + +@OptIn(ExperimentalAnimationApi::class) +fun NavGraphBuilder.animatedComposable( + route: String, + arguments: List = emptyList(), + animation: NavigationAnimation = NavigationAnimation.NONE, + content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit, +) { + composable( + route = route, + arguments = arguments, + enterTransition = animation.enterTransition, + exitTransition = animation.exitTransition, + popEnterTransition = animation.popEnterTransition, + popExitTransition = animation.popExitTransition, + content = content, + ) +} + +@OptIn(ExperimentalAnimationApi::class) +sealed class NavigationAnimation constructor( + val enterTransition: (AnimatedContentScope.() -> EnterTransition?)?, + val exitTransition: (AnimatedContentScope.() -> ExitTransition?)?, + val popEnterTransition: (AnimatedContentScope.() -> EnterTransition?)?, + val popExitTransition: (AnimatedContentScope.() -> ExitTransition?)?, +) { + object Push : NavigationAnimation( + enterTransition = { + slideIntoContainer( + towards = AnimatedContentScope.SlideDirection.Left, + animationSpec = tween(DURATION), + ) + }, + exitTransition = { + null + }, + popEnterTransition = { + null + }, + popExitTransition = { + slideOutOfContainer( + towards = AnimatedContentScope.SlideDirection.Right, + animationSpec = tween(DURATION), + ) + }, + ) + + object Modal : NavigationAnimation( + enterTransition = { + slideIntoContainer( + towards = AnimatedContentScope.SlideDirection.Up, + animationSpec = tween(DURATION), + ) + }, + exitTransition = { + null + }, + popEnterTransition = { + null + }, + popExitTransition = { + slideOutOfContainer( + towards = AnimatedContentScope.SlideDirection.Down, + animationSpec = tween(DURATION), + ) + }, + ) + + object Fade : NavigationAnimation( + enterTransition = { + fadeIn( + animationSpec = tween(DURATION), + ) + }, + exitTransition = { + null + }, + popEnterTransition = { + null + }, + popExitTransition = { + fadeOut( + animationSpec = tween(DURATION), + ) + }, + ) + + object NONE : NavigationAnimation( + enterTransition = null, + exitTransition = null, + popEnterTransition = null, + popExitTransition = null, + ) + + companion object { + const val DURATION = 300 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt new file mode 100644 index 0000000..5ace864 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationScreen.kt @@ -0,0 +1,182 @@ +package com.pixelized.rplexicon.ui.screens.authentication + +import android.content.res.Configuration.UI_MODE_NIGHT_NO +import android.content.res.Configuration.UI_MODE_NIGHT_YES +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.State +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.pixelized.rplexicon.LocalActivity +import com.pixelized.rplexicon.R +import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost +import com.pixelized.rplexicon.ui.navigation.navigateToLexicon +import com.pixelized.rplexicon.ui.navigation.rootOption +import com.pixelized.rplexicon.ui.theme.LexiconTheme +import com.pixelized.rplexicon.ui.theme.colors.GoogleColorPalette +import kotlinx.coroutines.CoroutineScope + +@Composable +fun AuthenticationScreen( + viewModel: AuthenticationViewModel = hiltViewModel() +) { + val screen = LocalScreenNavHost.current + val activity = LocalActivity.current + val state = viewModel.rememberAuthenticationState(activity = activity) + + Surface { + AuthenticationScreenContent( + modifier = Modifier.fillMaxSize(), + onGoogleSignIn = { + viewModel.signIn(activity = activity) + }, + ) + + HandleAuthenticationState( + state = state, + onSignIn = { + screen.navigateToLexicon(option = rootOption()) + }, + ) + } +} + +@Composable +fun HandleAuthenticationState( + state: State, + onSignIn: suspend CoroutineScope.() -> Unit +) { + if (state.value == AuthenticationViewModel.Authentication.Success) { + LaunchedEffect(key1 = "Authentication.Success", block = onSignIn) + } +} + +@Composable +private fun AuthenticationScreenContent( + modifier: Modifier = Modifier, + onGoogleSignIn: () -> Unit, +) { + Box( + modifier = modifier, + contentAlignment = Alignment.BottomCenter, + ) { + Button( + modifier = Modifier + .padding(all = 16.dp) + .fillMaxWidth(), + colors = ButtonDefaults.outlinedButtonColors(), + onClick = onGoogleSignIn, + ) { + Text(text = rememeberGoogleStringResource()) + } + } +} + +@Composable +private fun rememberBackgroundGradient(): Brush { + val colorScheme = MaterialTheme.colorScheme + return remember { + Brush.verticalGradient( + colors = listOf( + colorScheme.surface.copy(alpha = 0.2f), + colorScheme.surface.copy(alpha = 0.5f), + colorScheme.surface.copy(alpha = 1.0f), + ) + ) + } +} + +@Composable +private fun rememeberGoogleStringResource(): AnnotatedString { + val default = LocalTextStyle.current.toSpanStyle() + val google = stringResource(id = R.string.action_google_sign_in) + return remember { + buildAnnotatedString { + withStyle( + style = default + ) { + append(google) + append(" ") + } + withStyle( + style = default.copy( + color = GoogleColorPalette.BLUE, + fontWeight = FontWeight.ExtraBold + ), + ) { + append("G") + } + withStyle( + style = default.copy( + color = GoogleColorPalette.RED, + fontWeight = FontWeight.ExtraBold + ), + ) { + append("o") + } + withStyle( + style = default.copy( + color = GoogleColorPalette.YELLOW, + fontWeight = FontWeight.ExtraBold + ), + ) { + append("o") + } + withStyle( + style = default.copy( + color = GoogleColorPalette.BLUE, + fontWeight = FontWeight.ExtraBold + ), + ) { + append("g") + } + withStyle( + style = default.copy( + color = GoogleColorPalette.GREEN, + fontWeight = FontWeight.ExtraBold + ), + ) { + append("l") + } + withStyle( + style = default.copy( + color = GoogleColorPalette.RED, + fontWeight = FontWeight.ExtraBold + ), + ) { + append("e") + } + } + } +} + +@Composable +@Preview(uiMode = UI_MODE_NIGHT_NO) +@Preview(uiMode = UI_MODE_NIGHT_YES) +private fun AuthenticationScreenContentPreview() { + LexiconTheme { + AuthenticationScreenContent( + onGoogleSignIn = { }, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt new file mode 100644 index 0000000..d198388 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/authentication/AuthenticationViewModel.kt @@ -0,0 +1,95 @@ +package com.pixelized.rplexicon.ui.screens.authentication + +import android.app.Activity +import android.app.Application +import android.content.Context +import android.content.IntentSender.SendIntentException +import androidx.activity.compose.ManagedActivityResultLauncher +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.ActivityResult +import androidx.activity.result.IntentSenderRequest +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.AndroidViewModel +import com.google.android.gms.auth.api.identity.GetSignInIntentRequest +import com.google.android.gms.auth.api.identity.Identity +import com.google.android.gms.auth.api.signin.GoogleSignIn +import com.google.android.gms.auth.api.signin.GoogleSignInAccount +import com.pixelized.rplexicon.R +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class AuthenticationViewModel @Inject constructor( + application: Application, +) : AndroidViewModel(application) { + + private val context: Context get() = getApplication() + private var launcher: ManagedActivityResultLauncher? = null + + private val account: GoogleSignInAccount? by lazy { + GoogleSignIn.getLastSignedInAccount(application) + } + + private val lastGoogleToken: String? by lazy { + GoogleSignIn.getLastSignedInAccount(application)?.idToken + } + + private val state = mutableStateOf( + when (account) { + null -> Authentication.Initial + else -> Authentication.Success + } + ) + + @Composable + fun rememberAuthenticationState(activity: Activity): State { + launcher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartIntentSenderForResult(), + onResult = { + if (it.resultCode == Activity.RESULT_OK) { + val credential = Identity + .getSignInClient(activity) + .getSignInCredentialFromIntent(it.data) + state.value = Authentication.Success + } else { + state.value = Authentication.Failure + } + }, + ) + + return state + } + + fun signIn(activity: Activity) { + state.value = Authentication.Initial + + val request: GetSignInIntentRequest = GetSignInIntentRequest.builder() + .setServerClientId(context.getString(R.string.google_sign_in_id)) + .build() + + Identity.getSignInClient(activity).getSignInIntent(request) + .addOnSuccessListener { result -> + try { + launcher?.launch( + IntentSenderRequest.Builder(result.intentSender).build() + ) + } catch (e: SendIntentException) { + state.value = Authentication.Failure + } + } + .addOnFailureListener { e -> + state.value = Authentication.Failure + } + } + + @Stable + sealed class Authentication { + object Initial : Authentication() + object Success : Authentication() + object Failure : Authentication() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/lexique/ui/screens/detail/CharacterDetailScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailScreen.kt similarity index 71% rename from app/src/main/java/com/pixelized/lexique/ui/screens/detail/CharacterDetailScreen.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailScreen.kt index 1cdfe6a..ccfd565 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/screens/detail/CharacterDetailScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailScreen.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.ui.screens.detail +package com.pixelized.rplexicon.ui.screens.detail import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_YES @@ -32,6 +32,8 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -50,8 +52,8 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel -import com.pixelized.lexique.R -import com.pixelized.lexique.ui.theme.LexiconTheme +import com.pixelized.rplexicon.R +import com.pixelized.rplexicon.ui.theme.LexiconTheme import com.skydoves.landscapist.ImageOptions import com.skydoves.landscapist.glide.GlideImage @@ -70,7 +72,14 @@ data class CharacterDetailUio( fun CharacterDetailScreen( viewModel: CharacterDetailViewModel = hiltViewModel(), ) { - + Surface { + CharacterDetailScreenContent( + modifier = Modifier.fillMaxSize(), + item = viewModel.character, + onBack = { }, + onItem = { }, + ) + } } @OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class) @@ -78,8 +87,9 @@ fun CharacterDetailScreen( private fun CharacterDetailScreenContent( modifier: Modifier = Modifier, state: ScrollState = rememberScrollState(), - item: CharacterDetailUio, + item: State, onBack: () -> Unit, + onItem: () -> Unit, ) { val colorScheme = MaterialTheme.colorScheme val typography = MaterialTheme.typography @@ -104,7 +114,7 @@ private fun CharacterDetailScreenContent( Box( modifier = Modifier.padding(paddingValues = paddingValues), ) { - item.portrait.firstOrNull()?.let { uri -> + item.value.portrait.firstOrNull()?.let { uri -> Box( modifier = Modifier .fillMaxWidth() @@ -142,14 +152,14 @@ private fun CharacterDetailScreenContent( modifier = Modifier.padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(4.dp) ) { - item.name?.let { + item.value.name?.let { Text( modifier = Modifier.alignByBaseline(), style = typography.headlineSmall, text = it, ) } - item.diminutive?.let { + item.value.diminutive?.let { Text( modifier = Modifier.alignByBaseline(), style = remember { typography.labelMedium.copy(fontStyle = FontStyle.Italic) }, @@ -161,20 +171,20 @@ private fun CharacterDetailScreenContent( modifier = Modifier.padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(4.dp) ) { - item.race?.let { + item.value.race?.let { Text( style = remember { typography.labelMedium.copy(fontStyle = FontStyle.Italic) }, text = it, ) } - item.gender?.let { + item.value.gender?.let { Text( style = remember { typography.labelMedium.copy(fontStyle = FontStyle.Italic) }, text = it, ) } } - item.description?.let { + item.value.description?.let { Text( modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp), style = typography.titleMedium, @@ -193,7 +203,7 @@ private fun CharacterDetailScreenContent( text = it, ) } - item.history?.let { + item.value.history?.let { Text( modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp), style = typography.titleMedium, @@ -205,7 +215,7 @@ private fun CharacterDetailScreenContent( text = it, ) } - if (item.portrait.isNotEmpty()) { + if (item.value.portrait.isNotEmpty()) { Text( modifier = Modifier.padding(start = 16.dp, top = 24.dp, end = 16.dp), style = typography.titleMedium, @@ -215,7 +225,7 @@ private fun CharacterDetailScreenContent( contentPadding = PaddingValues(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp) ) { - items(items = item.portrait) { + items(items = item.value.portrait) { GlideImage( modifier = Modifier.height(320.dp), imageModel = { it }, @@ -261,29 +271,35 @@ private fun Modifier.scrollOffset( private fun CharacterDetailScreenContentPreview() { LexiconTheme { Surface { + val character = remember { + mutableStateOf( + CharacterDetailUio( + name = "Brulkhai", + diminutive = "./ Bru", + gender = "female", + race = "Demi-Orc", + portrait = listOf( + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/889/large/bayard-wu-0716.jpg?1468642855"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/877/large/bayard-wu-0714.jpg?1468642665"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/887/large/bayard-wu-0715.jpg?1468642839"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/891/large/bayard-wu-0623-03.jpg?1468642872"), + Uri.parse("https://cdna.artstation.com/p/assets/images/images/002/869/868/large/bayard-wu-0622-03.jpg?1466664135"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/002/869/871/large/bayard-wu-0622-04.jpg?1466664153"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/347/181/large/bayard-wu-1217.jpg?1482770883"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/635/large/bayard-wu-1215.jpg?1482166826"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/631/large/bayard-wu-1209.jpg?1482166803"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/641/large/bayard-wu-1212.jpg?1482166838"), + ), + description = "Brulkhai, ou plus simplement Bru, est solidement bâti. Elle mesure 192 cm pour 110 kg de muscles lorsqu’elle est en bonne santé. Elle a les cheveux châtains, les yeux noisettes et la peau couleur gris-vert typique de son espèce. D’un tempérament taciturne, elle parle peu et de façon concise. Elle est parfois brutale, aussi bien physiquement que verbalement, Elle ne prend cependant aucun plaisir à malmener ceux qu’elle considère plus faibles qu’elle. D’une nature simple et honnête, elle ne mâche pas ses mots et ne dissimule généralement pas ses pensées. Son intelligence modeste est plus le reflet d’un manque d’éducation et d’une capacité limitée à gérer ses émotions qu’à une débilité congénitale. Elle voue à la force un culte car c’est par son expression qu’elle se sent vraiment vivante et éprouve de grandes difficultés vis à vis de ceux qu’elle nomme foshnu (bébé, chouineur en commun).", + history = null, + ) + ) + } CharacterDetailScreenContent( modifier = Modifier.fillMaxSize(), - item = CharacterDetailUio( - name = "Brulkhai", - diminutive = "./ Bru", - gender = "female", - race = "Demi-Orc", - portrait = listOf( - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/889/large/bayard-wu-0716.jpg?1468642855"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/877/large/bayard-wu-0714.jpg?1468642665"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/887/large/bayard-wu-0715.jpg?1468642839"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/891/large/bayard-wu-0623-03.jpg?1468642872"), - Uri.parse("https://cdna.artstation.com/p/assets/images/images/002/869/868/large/bayard-wu-0622-03.jpg?1466664135"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/002/869/871/large/bayard-wu-0622-04.jpg?1466664153"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/347/181/large/bayard-wu-1217.jpg?1482770883"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/635/large/bayard-wu-1215.jpg?1482166826"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/631/large/bayard-wu-1209.jpg?1482166803"), - Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/641/large/bayard-wu-1212.jpg?1482166838"), - ), - description = "Brulkhai, ou plus simplement Bru, est solidement bâti. Elle mesure 192 cm pour 110 kg de muscles lorsqu’elle est en bonne santé. Elle a les cheveux châtains, les yeux noisettes et la peau couleur gris-vert typique de son espèce. D’un tempérament taciturne, elle parle peu et de façon concise. Elle est parfois brutale, aussi bien physiquement que verbalement, Elle ne prend cependant aucun plaisir à malmener ceux qu’elle considère plus faibles qu’elle. D’une nature simple et honnête, elle ne mâche pas ses mots et ne dissimule généralement pas ses pensées. Son intelligence modeste est plus le reflet d’un manque d’éducation et d’une capacité limitée à gérer ses émotions qu’à une débilité congénitale. Elle voue à la force un culte car c’est par son expression qu’elle se sent vraiment vivante et éprouve de grandes difficultés vis à vis de ceux qu’elle nomme foshnu (bébé, chouineur en commun).", - history = null, - ), + item = character, onBack = { }, + onItem = { }, ) } } diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailViewModel.kt new file mode 100644 index 0000000..1e07059 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/detail/CharacterDetailViewModel.kt @@ -0,0 +1,35 @@ +package com.pixelized.rplexicon.ui.screens.detail + +import android.net.Uri +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class CharacterDetailViewModel @Inject constructor() : ViewModel() { + + val character: State = mutableStateOf( + CharacterDetailUio( + name = "Brulkhai", + diminutive = "./ Bru", + gender = "female", + race = "Demi-Orc", + portrait = listOf( + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/889/large/bayard-wu-0716.jpg?1468642855"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/877/large/bayard-wu-0714.jpg?1468642665"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/887/large/bayard-wu-0715.jpg?1468642839"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/003/024/891/large/bayard-wu-0623-03.jpg?1468642872"), + Uri.parse("https://cdna.artstation.com/p/assets/images/images/002/869/868/large/bayard-wu-0622-03.jpg?1466664135"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/002/869/871/large/bayard-wu-0622-04.jpg?1466664153"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/347/181/large/bayard-wu-1217.jpg?1482770883"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/635/large/bayard-wu-1215.jpg?1482166826"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/631/large/bayard-wu-1209.jpg?1482166803"), + Uri.parse("https://cdnb.artstation.com/p/assets/images/images/004/297/641/large/bayard-wu-1212.jpg?1482166838"), + ), + description = "Brulkhai, ou plus simplement Bru, est solidement bâti. Elle mesure 192 cm pour 110 kg de muscles lorsqu’elle est en bonne santé. Elle a les cheveux châtains, les yeux noisettes et la peau couleur gris-vert typique de son espèce. D’un tempérament taciturne, elle parle peu et de façon concise. Elle est parfois brutale, aussi bien physiquement que verbalement, Elle ne prend cependant aucun plaisir à malmener ceux qu’elle considère plus faibles qu’elle. D’une nature simple et honnête, elle ne mâche pas ses mots et ne dissimule généralement pas ses pensées. Son intelligence modeste est plus le reflet d’un manque d’éducation et d’une capacité limitée à gérer ses émotions qu’à une débilité congénitale. Elle voue à la force un culte car c’est par son expression qu’elle se sent vraiment vivante et éprouve de grandes difficultés vis à vis de ceux qu’elle nomme foshnu (bébé, chouineur en commun).", + history = null, + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconItem.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconItem.kt similarity index 96% rename from app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconItem.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconItem.kt index f2f5d46..d417882 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconItem.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconItem.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.ui.screens.lexicon +package com.pixelized.rplexicon.ui.screens.lexicon import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_YES @@ -17,7 +17,7 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.pixelized.lexique.ui.theme.LexiconTheme +import com.pixelized.rplexicon.ui.theme.LexiconTheme @Stable data class LexiconItemUio( diff --git a/app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconScreen.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconScreen.kt similarity index 86% rename from app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconScreen.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconScreen.kt index 57be3c0..2726989 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconScreen.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconScreen.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.ui.screens.lexicon +package com.pixelized.rplexicon.ui.screens.lexicon import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_YES @@ -18,16 +18,22 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel -import com.pixelized.lexique.ui.theme.LexiconTheme +import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost +import com.pixelized.rplexicon.ui.navigation.navigateToCharacterDetail +import com.pixelized.rplexicon.ui.theme.LexiconTheme @Composable fun LexiconScreen( viewModel: LexiconViewModel = hiltViewModel(), ) { + val screen = LocalScreenNavHost.current + Surface { LexiconScreenContent( items = viewModel.items, - onItem = { }, + onItem = { + screen.navigateToCharacterDetail(id = "") + }, ) } } diff --git a/app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconViewModel.kt b/app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconViewModel.kt similarity index 89% rename from app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconViewModel.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconViewModel.kt index c8eaca0..0b30f61 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/screens/lexicon/LexiconViewModel.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/screens/lexicon/LexiconViewModel.kt @@ -1,11 +1,11 @@ -package com.pixelized.lexique.ui.screens.lexicon +package com.pixelized.rplexicon.ui.screens.lexicon import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.pixelized.lexique.model.Lexicon -import com.pixelized.lexique.repository.LexiconRepository +import com.pixelized.rplexicon.model.Lexicon +import com.pixelized.rplexicon.repository.LexiconRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject diff --git a/app/src/main/java/com/pixelized/lexique/ui/theme/Color.kt b/app/src/main/java/com/pixelized/rplexicon/ui/theme/Color.kt similarity index 85% rename from app/src/main/java/com/pixelized/lexique/ui/theme/Color.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/theme/Color.kt index 8a04bb1..c058ebb 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/theme/Color.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/theme/Color.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.ui.theme +package com.pixelized.rplexicon.ui.theme import androidx.compose.ui.graphics.Color diff --git a/app/src/main/java/com/pixelized/lexique/ui/theme/Theme.kt b/app/src/main/java/com/pixelized/rplexicon/ui/theme/Theme.kt similarity index 72% rename from app/src/main/java/com/pixelized/lexique/ui/theme/Theme.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/theme/Theme.kt index 0471009..9700121 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/theme/Theme.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/theme/Theme.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.ui.theme +package com.pixelized.rplexicon.ui.theme import android.app.Activity import android.os.Build @@ -45,22 +45,22 @@ fun LexiconTheme( content: @Composable () -> Unit ) { val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } +// dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { +// val context = LocalContext.current +// if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) +// } darkTheme -> DarkColorScheme else -> LightColorScheme } - val view = LocalView.current - if (!view.isInEditMode) { - SideEffect { - val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() - WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme - } - } +// val view = LocalView.current +// if (!view.isInEditMode) { +// SideEffect { +// val window = (view.context as Activity).window +// window.statusBarColor = colorScheme.primary.toArgb() +// WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme +// } +// } MaterialTheme( colorScheme = colorScheme, diff --git a/app/src/main/java/com/pixelized/lexique/ui/theme/Type.kt b/app/src/main/java/com/pixelized/rplexicon/ui/theme/Type.kt similarity index 95% rename from app/src/main/java/com/pixelized/lexique/ui/theme/Type.kt rename to app/src/main/java/com/pixelized/rplexicon/ui/theme/Type.kt index f87c9be..6b7ad06 100644 --- a/app/src/main/java/com/pixelized/lexique/ui/theme/Type.kt +++ b/app/src/main/java/com/pixelized/rplexicon/ui/theme/Type.kt @@ -1,4 +1,4 @@ -package com.pixelized.lexique.ui.theme +package com.pixelized.rplexicon.ui.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle diff --git a/app/src/main/java/com/pixelized/rplexicon/ui/theme/colors/GoogleColorPalette.kt b/app/src/main/java/com/pixelized/rplexicon/ui/theme/colors/GoogleColorPalette.kt new file mode 100644 index 0000000..6ce33c5 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/ui/theme/colors/GoogleColorPalette.kt @@ -0,0 +1,12 @@ +package com.pixelized.rplexicon.ui.theme.colors + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color + +@Immutable +object GoogleColorPalette { + val BLUE = Color(0xFF4285F4) + val RED = Color(0xFFEA4335) + val YELLOW = Color(0xFFFBBC05) + val GREEN = Color(0xFF34A853) +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/StringEt.kt b/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/StringEt.kt new file mode 100644 index 0000000..7f05ee4 --- /dev/null +++ b/app/src/main/java/com/pixelized/rplexicon/utilitary/extentions/StringEt.kt @@ -0,0 +1,3 @@ +package com.pixelized.rplexicon.utilitary.extentions + +val String.ARG: String get() = "$this={$this}" \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml new file mode 100644 index 0000000..ab20bf3 --- /dev/null +++ b/app/src/main/res/values-fr/strings.xml @@ -0,0 +1,5 @@ + + Lexique + + Se connecter avec + \ No newline at end of file diff --git a/app/src/main/res/values/google.xml b/app/src/main/res/values/google.xml new file mode 100644 index 0000000..9a565ec --- /dev/null +++ b/app/src/main/res/values/google.xml @@ -0,0 +1,4 @@ + + + 62913404482-ergqkjiuvint49q8lm555j21vvb6af7s.apps.googleusercontent.com + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 652e555..e0179a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ Lexique + + Sign in with \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 2dc5d92..546f759 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { id("com.android.application") version "8.1.0-rc01" apply false + id("com.google.dagger.hilt.android") version "2.44" apply false id("org.jetbrains.kotlin.android") version "1.8.22" apply false id("org.jetbrains.kotlin.kapt") version "1.8.22" apply false - id("com.google.dagger.hilt.android") version "2.44" apply false } \ No newline at end of file