diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/CustomGoogleButton.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/CustomGoogleButton.kt index 56c1627..988005e 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/CustomGoogleButton.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/CustomGoogleButton.kt @@ -45,7 +45,7 @@ fun CustomGoogleButton( Text( style = MaterialTheme.typography.h5, color = MaterialTheme.colors.surface, - text = stringResource(R.string.txt_connect_with_google) + text = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_connect_with_google) ) Icon( tint = Color.Transparent, diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/TopActionBar.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/TopActionBar.kt index 7da2ede..34394db 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/TopActionBar.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/custom/TopActionBar.kt @@ -31,7 +31,7 @@ fun TopActionBar(modifier: Modifier = Modifier) { Image( modifier = Modifier.height(23.dp), painter = painterResource(id = R.drawable.ic_lottiefiles_logo), - contentDescription = stringResource(id = R.string.txt_lottie_logo) + contentDescription = stringResource(id = org.zxconnect.android.beserve.i18n.R.string.txt_lottie_logo) ) } ) diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt index 3f12713..369e624 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt @@ -9,7 +9,7 @@ import com.ericampire.android.androidstudycase.domain.usecase.FindPopularLottieF import com.ericampire.android.androidstudycase.domain.usecase.FindRecentLottieFileUseCase import com.ericampire.android.androidstudycase.util.Result import com.ericampire.android.androidstudycase.util.data -import com.ericampire.android.androidstudycase.util.mvi.BaseViewModel +import com.ericampire.android.androidstudycase.util.mvi.BViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -23,7 +23,7 @@ class ExploreViewModel @AssistedInject constructor( private val findPopularLottieFileUseCase: FindPopularLottieFileUseCase, private val findRecentLottieFileUseCase: FindRecentLottieFileUseCase, private val findFeaturedLottieFileUseCase: FindFeaturedLottieFileUseCase -) : BaseViewModel(initialState) { +) : BViewModel(initialState) { init { viewModelScope.launch { diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt index 2e9a47f..9da3219 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt @@ -54,7 +54,7 @@ fun ExploreScreen( val state by viewModel.collectAsState(ExploreViewState::files) val context = LocalContext.current - val tabItems = stringArrayResource(id = R.array.explore_item) + val tabItems = stringArrayResource(id = org.zxconnect.android.beserve.i18n.R.array.explore_item) val pagerState = rememberPagerState() diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/business/HomeViewModel.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/business/HomeViewModel.kt index 8ba8b53..28e0ea7 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/business/HomeViewModel.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/business/HomeViewModel.kt @@ -6,7 +6,7 @@ import com.ericampire.android.androidstudycase.app.hilt.hiltMavericksViewModelFa import com.ericampire.android.androidstudycase.domain.usecase.* import com.ericampire.android.androidstudycase.util.PreviewData import com.ericampire.android.androidstudycase.util.data -import com.ericampire.android.androidstudycase.util.mvi.BaseViewModel +import com.ericampire.android.androidstudycase.util.mvi.BViewModel import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -23,7 +23,7 @@ class HomeViewModel @AssistedInject constructor( private val findUsersUseCase: FindUsersUseCase, private val findFeaturedLottieFileUseCase: FindFeaturedLottieFileUseCase, private val saveUserUseCase: SaveUserUseCase -) : BaseViewModel(initialState) { +) : BViewModel(initialState) { init { diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/BrowseAllItemView.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/BrowseAllItemView.kt index b67258a..b3d98d3 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/BrowseAllItemView.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/BrowseAllItemView.kt @@ -47,14 +47,14 @@ fun BrowseAllItemView(modifier: Modifier = Modifier) { modifier = Modifier.padding(end = 12.dp) ) { Text( - text = stringResource(R.string.txt_browse_all), + text = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_browse_all), style = MaterialTheme.typography.h4.copy( color = MaterialTheme.colors.onSurface ), ) Text( - text = stringResource(R.string.txt_browse_all_desc), + text = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_browse_all_desc), style = MaterialTheme.typography.body1.copy( color = MaterialTheme.colors.onSurface ), @@ -63,7 +63,7 @@ fun BrowseAllItemView(modifier: Modifier = Modifier) { TextButton(onClick = { /*TODO*/ }) { Text( - text = stringResource(R.string.txt_go_to_explore), + text = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_go_to_explore), ) } } diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/HomeScreen.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/HomeScreen.kt index 916213f..5182d8f 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/HomeScreen.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/HomeScreen.kt @@ -191,7 +191,7 @@ fun HomeContent( Text( modifier = Modifier.padding(horizontal = 16.dp), maxLines = 1, - text = stringResource(id = R.string.txt_featured_animator), + text = stringResource(id = org.zxconnect.android.beserve.i18n.R.string.txt_featured_animator), style = MaterialTheme.typography.h4.copy( color = MaterialTheme.colors.onSurface ), @@ -219,7 +219,7 @@ fun HomeContent( Text( modifier = Modifier.padding(horizontal = 16.dp), maxLines = 1, - text = stringResource(id = R.string.txt_latest_story), + text = stringResource(id = org.zxconnect.android.beserve.i18n.R.string.txt_latest_story), style = MaterialTheme.typography.h4.copy( color = MaterialTheme.colors.onSurface ), diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/LoginBottomSheet.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/LoginBottomSheet.kt index dcb84f4..03263b1 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/LoginBottomSheet.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/LoginBottomSheet.kt @@ -81,7 +81,7 @@ fun LoginBottomSheet( ) Text( textAlign = TextAlign.Center, - text = stringResource(id = R.string.txt_get_started), + text = stringResource(id = org.zxconnect.android.beserve.i18n.R.string.txt_get_started), style = MaterialTheme.typography.body1.copy( color = MaterialTheme.colors.onSurface ), diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/UnLoggedUserHeaderView.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/UnLoggedUserHeaderView.kt index 5186cb6..37ec133 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/UnLoggedUserHeaderView.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/home/ui/UnLoggedUserHeaderView.kt @@ -37,7 +37,7 @@ fun UnLoggedUserHeaderView( .size(57.dp) .clip(CircleShape), painter = painterResource(id = R.drawable.lottiefiles_circle_logo), - contentDescription = stringResource(id = R.string.txt_lottie_logo) + contentDescription = stringResource(id = org.zxconnect.android.beserve.i18n.R.string.txt_lottie_logo) ) Column( verticalArrangement = Arrangement.spacedBy(8.dp), @@ -51,7 +51,7 @@ fun UnLoggedUserHeaderView( ) Text( maxLines = 1, - text = stringResource(R.string.txt_hello_stranger), + text = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_hello_stranger), style = MaterialTheme.typography.h3.copy( color = AppColor.PaleBlue ), @@ -59,7 +59,7 @@ fun UnLoggedUserHeaderView( Text( modifier = Modifier.clickable(onClick = onLoginClick), maxLines = 1, - text = stringResource(R.string.txt_login), + text = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_login), style = MaterialTheme.typography.body1.copy( color = AppColor.Teal ), diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/preview/ui/PreviewScreen.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/preview/ui/PreviewScreen.kt index 36b77da..74c0224 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/preview/ui/PreviewScreen.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/preview/ui/PreviewScreen.kt @@ -66,7 +66,7 @@ fun PreviewScreen(navController: NavController) { permissionState = cameraPermissionState, permissionNotGrantedContent = { PermissionNotAvailableContent( - descriptionMessage = stringResource(R.string.txt_camera_permssion_required), + descriptionMessage = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_camera_permssion_required), onPermissionRequest = { cameraPermissionState.launchPermissionRequest() } @@ -74,7 +74,7 @@ fun PreviewScreen(navController: NavController) { }, permissionNotAvailableContent = { PermissionNotAvailableContent( - descriptionMessage = stringResource(R.string.txt_permission_denied), + descriptionMessage = stringResource(org.zxconnect.android.beserve.i18n.R.string.txt_permission_denied), onPermissionRequest = { cameraPermissionState.launchPermissionRequest() } diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/util/Destination.kt b/app/src/main/java/com/ericampire/android/androidstudycase/util/Destination.kt index 32c95e0..c669797 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/util/Destination.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/util/Destination.kt @@ -4,8 +4,8 @@ import androidx.annotation.StringRes import com.ericampire.android.androidstudycase.R sealed class Destination(val route: String, @StringRes val resourceId: Int) { - object Home : Destination("home", R.string.txt_home) - object Explore : Destination("explore", R.string.txt_explore) - object Preview : Destination("preview", R.string.txt_preview) - object Login : Destination("login", R.string.txt_login) + object Home : Destination("home", org.zxconnect.android.beserve.i18n.R.string.txt_home) + object Explore : Destination("explore", org.zxconnect.android.beserve.i18n.R.string.txt_explore) + object Preview : Destination("preview", org.zxconnect.android.beserve.i18n.R.string.txt_preview) + object Login : Destination("login", org.zxconnect.android.beserve.i18n.R.string.txt_login) } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Libs.kt b/buildSrc/src/main/kotlin/Libs.kt index 2e48219..1b3dc2f 100644 --- a/buildSrc/src/main/kotlin/Libs.kt +++ b/buildSrc/src/main/kotlin/Libs.kt @@ -163,4 +163,9 @@ object Libs { const val junit5_android_test_core = "de.mannodermaus.junit5:android-test-core:_" const val junit5_android_test_runner = "de.mannodermaus.junit5:android-test-runner:_" + + const val mvi_kotlin_core = "com.arkivanov.mvikotlin:mvikotlin:_" + const val mvi_kotlin_main = "com.arkivanov.mvikotlin:mvikotlin-main:_" + const val mvi_kotlin_logging = "com.arkivanov.mvikotlin:mvikotlin-logging:_" + const val mvi_kotlin_extension_coroutine = "com.arkivanov.mvikotlin:mvikotlin-extensions-coroutines:_" } diff --git a/gradle.properties b/gradle.properties index 98bed16..b8c9089 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,11 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +org.gradle.unsafe.configuration-cache=true +org.gradle.unsafe.configuration-cache-problems=warn +android.nonTransitiveRClass=true +kotlin.code.style=official +org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -Dfile.encoding\=UTF-8 -XX:+UseParallelGC +android.useAndroidX=true +android.enableJetifier=true +kapt.incremental.apt=true \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index fff4fed..78d5c99 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,5 @@ plugins { - id("de.fayard.refreshVersions") version "0.20.0" -//// # available:"0.21.0" -//// # available:"0.22.0" -//// # available:"0.23.0" + id("de.fayard.refreshVersions") version "0.23.0" } refreshVersions { @@ -17,7 +14,7 @@ dependencyResolutionManagement { jcenter() // Todo: Warning this repository is going to shut down soon } } -rootProject.name = "lottiefiles" +rootProject.name = "lottiefiles-app" include(":app") include(":util") include(":i18n") diff --git a/util/build.gradle.kts b/util/build.gradle.kts index d4d319e..28e1a8f 100644 --- a/util/build.gradle.kts +++ b/util/build.gradle.kts @@ -31,6 +31,8 @@ android { dependencies { api(project(":i18n")) + api("org.reduxkotlin:redux-kotlin-threadsafe:0.5.5") + implementation(Libs.core_ktx) api(Libs.androidx_lifecycle_viewmodel_ktx) diff --git a/util/src/main/java/com/ericampire/android/androidstudycase/util/extension/Context.kt b/util/src/main/java/com/ericampire/android/androidstudycase/util/extension/Context.kt index c472081..e06aedb 100644 --- a/util/src/main/java/com/ericampire/android/androidstudycase/util/extension/Context.kt +++ b/util/src/main/java/com/ericampire/android/androidstudycase/util/extension/Context.kt @@ -54,7 +54,7 @@ private fun Context.shareFile(filePath: String) { ) val shareIntent = ShareCompat.IntentBuilder(this) - .setChooserTitle(getString(R.string.txt_share_lottie_file)) + .setChooserTitle(getString(org.zxconnect.android.beserve.i18n.R.string.txt_share_lottie_file)) .setStream(fileUri) .setType("application/pdf") .createChooserIntent() diff --git a/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/BaseViewModel.kt b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/BViewModel.kt similarity index 73% rename from util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/BaseViewModel.kt rename to util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/BViewModel.kt index 71b8a77..8853c55 100644 --- a/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/BaseViewModel.kt +++ b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/BViewModel.kt @@ -4,8 +4,11 @@ import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch +import org.reduxkotlin.Reducer +import org.reduxkotlin.Store +import org.reduxkotlin.createThreadSafeStore -abstract class BaseViewModel( +abstract class BViewModel( initialState: S ) : MavericksViewModel(initialState) { protected val pendingAction = MutableSharedFlow() diff --git a/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Action.kt b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Action.kt new file mode 100644 index 0000000..65fdd7e --- /dev/null +++ b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Action.kt @@ -0,0 +1,6 @@ +package com.ericampire.android.androidstudycase.util.mvi.core + +/** + * + */ +interface Action \ No newline at end of file diff --git a/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Reducer.kt b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Reducer.kt new file mode 100644 index 0000000..ab30b70 --- /dev/null +++ b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Reducer.kt @@ -0,0 +1,14 @@ +package com.ericampire.android.androidstudycase.util.mvi.core + + + +interface Reducer { + + /** + * Given a [currentState] and some [action] that user took, produce a new [State]. + * + * This will give us and predictable state management, that ensures each state is associated + * with some specific user intent or action + */ + fun reduce(currentState: S, action: A): S +} \ No newline at end of file diff --git a/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/State.kt b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/State.kt new file mode 100644 index 0000000..faddd2e --- /dev/null +++ b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/State.kt @@ -0,0 +1,6 @@ +package com.ericampire.android.androidstudycase.util.mvi.core + +/** + * + */ +interface State \ No newline at end of file diff --git a/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Store.kt b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Store.kt new file mode 100644 index 0000000..0becbba --- /dev/null +++ b/util/src/main/java/com/ericampire/android/androidstudycase/util/mvi/core/Store.kt @@ -0,0 +1,25 @@ +package com.ericampire.android.androidstudycase.util.mvi.core + +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + + +/** + * A [Store] is our state container for a given screen + * + * @param[initialState] this is the initial state of the screen when it is first creates + * @param[reducer] A system for taking in the current state, and a new action, and outputting the + * updated state + */ +abstract class Store( + initialState: S, + private val reducer: Reducer +) { + private val _state = MutableStateFlow(initialState) + val state: StateFlow = _state + + fun dispatch(action: A) { + val currentState = _state.value + _state.value = reducer.reduce(currentState, action) + } +} \ No newline at end of file diff --git a/versions.properties b/versions.properties index c09e891..e2760ae 100644 --- a/versions.properties +++ b/versions.properties @@ -34,25 +34,25 @@ version.androidx.preference=1.1.1 version.androidx.appcompat=1.3.0 ## unused -version.androidx.compose.compiler=1.0.4 +version.androidx.compose.compiler=1.1.0-beta01 ## unused -version.androidx.compose.material-icons-extended=1.0.4 +version.androidx.compose.material-icons-extended=1.1.0-beta01 ## unused -version.androidx.compose.material=1.0.4 +version.androidx.compose.material=1.1.0-beta01 ## unused -version.androidx.compose.runtime=1.0.4 +version.androidx.compose.runtime=1.1.0-beta01 ## unused version.google.accompanist=0.20.0 ## unused -version.androidx.compose.ui=1.0.4 +version.androidx.compose.ui=1.1.0-beta01 ## unused -version.androidx.compose.ui-viewbinding=1.0.4 +version.androidx.compose.ui-viewbinding=1.1.0-beta01 ## unused version.androidx.core=1.5.0 @@ -195,3 +195,15 @@ version.de.mannodermaus.junit5..android-test-runner=1.2.2 ## unused version.de.mannodermaus.junit5..android-test-core=1.2.2 + +## unused +version.com.arkivanov.mvikotlin..mvikotlin=2.0.4 + +## unused +version.com.arkivanov.mvikotlin..mvikotlin-main=2.0.4 + +## unused +version.com.arkivanov.mvikotlin..mvikotlin-logging=2.0.4 + +## unused +version.com.arkivanov.mvikotlin..mvikotlin-extensions-coroutines=2.0.4