diff --git a/.github/workflows/check_pr.yml b/.github/workflows/check_pr.yml index 268149ec1..4f16a8f1f 100644 --- a/.github/workflows/check_pr.yml +++ b/.github/workflows/check_pr.yml @@ -47,7 +47,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v2.4.2 - name: Decode Keystore File id: decode_keystore_file diff --git a/.github/workflows/distribution_app.yml b/.github/workflows/distribution_app.yml index cd788020f..5588b19e3 100644 --- a/.github/workflows/distribution_app.yml +++ b/.github/workflows/distribution_app.yml @@ -27,11 +27,11 @@ jobs: with: fetch-depth: 0 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'zulu' - java-version: 11 + java-version: 17 - name: Make Gradlew Executable run: chmod +x ./gradlew diff --git a/app/src/main/kotlin/org/michaelbel/movies/MainActivity.kt b/app/src/main/kotlin/org/michaelbel/movies/MainActivity.kt index 1bc9c8a40..5c46e7bb9 100644 --- a/app/src/main/kotlin/org/michaelbel/movies/MainActivity.kt +++ b/app/src/main/kotlin/org/michaelbel/movies/MainActivity.kt @@ -5,7 +5,6 @@ import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.getValue -import androidx.compose.ui.unit.LayoutDirection import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -36,7 +35,6 @@ internal class MainActivity: AppCompatActivity() { setContent { val currentTheme: AppTheme by viewModel.currentTheme.collectAsStateWithLifecycle() val dynamicColors: Boolean by viewModel.dynamicColors.collectAsStateWithLifecycle() - val layoutDirection: LayoutDirection by viewModel.layoutDirection.collectAsStateWithLifecycle() val navHostController: NavHostController = rememberNavController().apply { addOnDestinationChangedListener(viewModel::analyticsTrackDestination) diff --git a/app/src/main/kotlin/org/michaelbel/movies/MainViewModel.kt b/app/src/main/kotlin/org/michaelbel/movies/MainViewModel.kt index 29e61d73c..58a3dc518 100644 --- a/app/src/main/kotlin/org/michaelbel/movies/MainViewModel.kt +++ b/app/src/main/kotlin/org/michaelbel/movies/MainViewModel.kt @@ -1,13 +1,11 @@ package org.michaelbel.movies import android.os.Bundle -import androidx.compose.ui.unit.LayoutDirection import androidx.navigation.NavDestination import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import androidx.work.workDataOf import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.stateIn @@ -18,6 +16,7 @@ import org.michaelbel.movies.common.viewmodel.BaseViewModel import org.michaelbel.movies.domain.interactor.settings.SettingsInteractor import org.michaelbel.movies.domain.workers.AccountUpdateWorker import org.michaelbel.movies.domain.workers.MoviesDatabaseWorker +import javax.inject.Inject @HiltViewModel internal class MainViewModel @Inject constructor( @@ -40,13 +39,6 @@ internal class MainViewModel @Inject constructor( initialValue = false ) - val layoutDirection: StateFlow = settingsInteractor.layoutDirection - .stateIn( - scope = this, - started = SharingStarted.Lazily, - initialValue = LayoutDirection.Ltr - ) - init { fetchRemoteConfig() prepopulateDatabase() diff --git a/core/analytics-impl/build.gradle.kts b/core/analytics-impl/build.gradle.kts index b229f7fa6..763635372 100644 --- a/core/analytics-impl/build.gradle.kts +++ b/core/analytics-impl/build.gradle.kts @@ -29,5 +29,5 @@ android { } dependencies { - implementation(libs.firebase.analytics) + implementation(libs.firebase.analytics.ktx) } \ No newline at end of file diff --git a/core/analytics/build.gradle.kts b/core/analytics/build.gradle.kts index 5f0b79d1f..d91b3ce84 100644 --- a/core/analytics/build.gradle.kts +++ b/core/analytics/build.gradle.kts @@ -36,5 +36,5 @@ android { } dependencies { - implementation(libs.firebase.analytics) + implementation(libs.firebase.analytics.ktx) } \ No newline at end of file diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 06b942c1d..481c624be 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -56,16 +56,16 @@ dependencies { implementation(project(":core:analytics")) api(project(":core:entities")) api(libs.bundles.kotlin.coroutines) - api(libs.firebase.config) - api(libs.play.services.base) - api(libs.play.core) - api(libs.androidx.core) + api(libs.firebase.config.ktx) + api(libs.gms.play.services.base) + api(libs.play.core.ktx) + api(libs.androidx.core.ktx) api(libs.androidx.activity.compose) api(libs.bundles.lifecycle) api(libs.timber) implementation(libs.bundles.appcompat) - implementation(libs.firebase.crashlytics) - implementation(libs.firebase.messaging) + implementation(libs.firebase.crashlytics.ktx) + implementation(libs.firebase.messaging.ktx) implementation(libs.androidx.startup.runtime) implementation(libs.androidx.browser) diff --git a/core/common/src/main/kotlin/org/michaelbel/movies/common/localization/model/AppLanguage.kt b/core/common/src/main/kotlin/org/michaelbel/movies/common/localization/model/AppLanguage.kt index 95cbd27df..a21525a99 100644 --- a/core/common/src/main/kotlin/org/michaelbel/movies/common/localization/model/AppLanguage.kt +++ b/core/common/src/main/kotlin/org/michaelbel/movies/common/localization/model/AppLanguage.kt @@ -5,13 +5,9 @@ import org.michaelbel.movies.common.localization.exceptions.InvalidLocaleExcepti sealed class AppLanguage( val code: String ) { - object English: AppLanguage("en") { - override fun toString(): String = "English" - } + data object English: AppLanguage("en") - object Russian: AppLanguage("ru") { - override fun toString(): String = "Russian" - } + data object Russian: AppLanguage("ru") companion object { fun transform(code: String): AppLanguage { diff --git a/core/common/src/main/kotlin/org/michaelbel/movies/common/theme/AppTheme.kt b/core/common/src/main/kotlin/org/michaelbel/movies/common/theme/AppTheme.kt index 4bafd448b..d09b2013b 100644 --- a/core/common/src/main/kotlin/org/michaelbel/movies/common/theme/AppTheme.kt +++ b/core/common/src/main/kotlin/org/michaelbel/movies/common/theme/AppTheme.kt @@ -6,17 +6,11 @@ import org.michaelbel.movies.common.theme.exceptions.InvalidThemeException sealed class AppTheme( val theme: Int ) { - object NightNo: AppTheme(AppCompatDelegate.MODE_NIGHT_NO) { - override fun toString(): String = "NightNo" - } + data object NightNo: AppTheme(AppCompatDelegate.MODE_NIGHT_NO) - object NightYes: AppTheme(AppCompatDelegate.MODE_NIGHT_YES) { - override fun toString(): String = "NightYes" - } + data object NightYes: AppTheme(AppCompatDelegate.MODE_NIGHT_YES) - object FollowSystem: AppTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) { - override fun toString(): String = "FollowSystem" - } + data object FollowSystem: AppTheme(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) companion object { fun transform(theme: Int): AppTheme { diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 4c6e4ede1..40f6fe264 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -47,7 +47,7 @@ android { } dependencies { - api(libs.kotlin.serialization) + api(libs.kotlin.serialization.json) implementation(libs.okhttp.logging.interceptor) implementation(libs.retrofit.converter.serialization) api(libs.retrofit) diff --git a/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountScreenContent.kt b/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountScreenContent.kt index b4d8df738..92bbfc2c7 100644 --- a/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountScreenContent.kt +++ b/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountScreenContent.kt @@ -169,8 +169,7 @@ internal fun AccountScreenContent( ) { if (loading) { CircularProgressIndicator( - modifier = Modifier - .size(24.dp), + modifier = Modifier.size(24.dp), strokeWidth = 2.dp ) } else { diff --git a/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountToolbar.kt b/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountToolbar.kt index 5662cb571..dd6f0719e 100644 --- a/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountToolbar.kt +++ b/feature/account-impl/src/main/kotlin/org/michaelbel/movies/account/ui/AccountToolbar.kt @@ -57,8 +57,7 @@ fun AccountToolbar( private fun AccountToolbarPreview() { MoviesTheme { AccountToolbar( - modifier = Modifier - .background(MaterialTheme.colorScheme.primaryContainer), + modifier = Modifier.background(MaterialTheme.colorScheme.primaryContainer), onNavigationIconClick = {} ) } diff --git a/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthLinksBox.kt b/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthLinksBox.kt index 066bd0613..ef6e40e00 100644 --- a/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthLinksBox.kt +++ b/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthLinksBox.kt @@ -87,8 +87,7 @@ private fun AuthLinksBoxPreview() { AuthLinksBox( onTermsOfUseClick = {}, onPrivacyPolicyClick = {}, - modifier = Modifier - .background(MaterialTheme.colorScheme.primaryContainer) + modifier = Modifier.background(MaterialTheme.colorScheme.primaryContainer) ) } } \ No newline at end of file diff --git a/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthToolbar.kt b/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthToolbar.kt index cb20736a5..f6219c4dc 100644 --- a/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthToolbar.kt +++ b/feature/auth-impl/src/main/kotlin/org/michaelbel/movies/auth/ui/AuthToolbar.kt @@ -57,8 +57,7 @@ fun AuthToolbar( private fun AuthToolbarPreview() { MoviesTheme { AuthToolbar( - modifier = Modifier - .background(MaterialTheme.colorScheme.primaryContainer), + modifier = Modifier.background(MaterialTheme.colorScheme.primaryContainer), onNavigationIconClick = {} ) } diff --git a/feature/details-impl/src/main/kotlin/org/michaelbel/movies/details/ui/DetailsToolbar.kt b/feature/details-impl/src/main/kotlin/org/michaelbel/movies/details/ui/DetailsToolbar.kt index aa798e787..9e52fe9f5 100644 --- a/feature/details-impl/src/main/kotlin/org/michaelbel/movies/details/ui/DetailsToolbar.kt +++ b/feature/details-impl/src/main/kotlin/org/michaelbel/movies/details/ui/DetailsToolbar.kt @@ -64,7 +64,7 @@ fun DetailsToolbar( ) } }, - colors = TopAppBarDefaults.smallTopAppBarColors( + colors = TopAppBarDefaults.topAppBarColors( containerColor = Color.Transparent ) ) diff --git a/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedContent.kt b/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedContent.kt index de4eff286..a91853485 100644 --- a/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedContent.kt +++ b/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedContent.kt @@ -14,7 +14,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import androidx.paging.compose.LazyPagingItems -import androidx.paging.compose.items +import androidx.paging.compose.itemContentType +import androidx.paging.compose.itemKey import org.michaelbel.movies.domain.data.entity.MovieDb import org.michaelbel.movies.entities.isTmdbApiKeyEmpty import org.michaelbel.movies.ui.ktx.isNotEmpty @@ -34,10 +35,15 @@ fun FeedContent( state = listState, contentPadding = contentPadding ) { - items(pagingItems) { movieItem -> - movieItem?.let { movie -> + items( + count = pagingItems.itemCount, + key = pagingItems.itemKey(), + contentType = pagingItems.itemContentType() + ) { index -> + val movieDb: MovieDb? = pagingItems[index] + if (movieDb != null) { FeedMovieBox( - movie = movie, + movie = movieDb, modifier = Modifier .fillMaxWidth() .padding( @@ -47,7 +53,7 @@ fun FeedContent( .clip(MaterialTheme.shapes.small) .background(MaterialTheme.colorScheme.inversePrimary) .clickable { - onMovieClick(movie.movieId) + onMovieClick(movieDb.movieId) } ) } diff --git a/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedToolbar.kt b/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedToolbar.kt index 99e344503..1ae04ddf5 100644 --- a/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedToolbar.kt +++ b/feature/feed-impl/src/main/kotlin/org/michaelbel/movies/feed/ui/FeedToolbar.kt @@ -77,7 +77,7 @@ fun FeedToolbar( } } }, - colors = TopAppBarDefaults.smallTopAppBarColors( + colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.inversePrimary ) ) diff --git a/feature/settings-impl/src/main/kotlin/org/michaelbel/movies/settings/ui/SettingsToolbar.kt b/feature/settings-impl/src/main/kotlin/org/michaelbel/movies/settings/ui/SettingsToolbar.kt index 2f58fad3c..8bd9ebd10 100644 --- a/feature/settings-impl/src/main/kotlin/org/michaelbel/movies/settings/ui/SettingsToolbar.kt +++ b/feature/settings-impl/src/main/kotlin/org/michaelbel/movies/settings/ui/SettingsToolbar.kt @@ -50,7 +50,7 @@ internal fun SettingsToolbar( ) } }, - colors = TopAppBarDefaults.smallTopAppBarColors( + colors = TopAppBarDefaults.topAppBarColors( containerColor = Color.Transparent ) ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d4fe88b65..ccca4bc33 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,28 +4,28 @@ min-sdk = "21" compile-sdk = "33" target-sdk = "33" -gradle = "8.0.1" -kotlin = "1.8.21" -kotlin-ksp = "1.8.21-1.0.11" -kotlin-coroutines = "1.7.1" -kotlin-serialization = "1.5.1" -compose-compiler = "1.4.7" -detekt = "1.22.0" -spotless = "6.18.0" +gradle = "8.0.2" +kotlin = "1.9.0" +kotlin-ksp = "1.9.0-1.0.12" +kotlin-coroutines = "1.7.2" +kotlin-serialization-json = "1.5.1" +compose-compiler = "1.5.0" +detekt = "1.23.0" +spotless = "6.20.0" google-services = "4.3.15" -play-services-ads = "22.1.0" -play-services-base = "18.2.0" -firebase-analytics = "21.2.2" +gms-play-services-ads = "22.1.0" +gms-play-services-base = "18.2.0" +firebase-analytics-ktx = "21.3.0" firebase-appdistribution = "3.2.0" -firebase-config = "21.4.0" +firebase-config-ktx = "21.4.0" firebase-crashlytics-plugin = "2.9.4" -firebase-crashlytics = "18.3.7" -firebase-messaging = "23.1.2" -play-core = "1.8.1" +firebase-crashlytics-ktx = "18.3.7" +firebase-messaging-ktx = "23.1.2" +play-core-ktx = "1.8.1" accompanist = "0.30.1" material = "1.9.0" material-compose-theme-adapter = "1.2.1" -hilt = "2.46.1" +hilt = "2.47" androidx-compose-foundation = "1.4.3" androidx-compose-runtime = "1.4.3" androidx-compose-ui = "1.4.3" @@ -33,16 +33,16 @@ androidx-compose-compiler = "1.4.7" androidx-compose-material = "1.4.3" androidx-compose-material3 = "1.1.0" androidx-appcompat = "1.7.0-alpha02" -androidx-activity = "1.7.1" +androidx-activity = "1.7.2" androidx-browser = "1.5.0" -androidx-core = "1.10.1" +androidx-core-ktx = "1.10.1" androidx-core-splashscreen = "1.0.1" androidx-constraintlayout = "1.0.1" androidx-lifecycle = "2.6.1" androidx-hilt-navigation-compose = "1.0.0" androidx-hilt-work = "1.0.0" androidx-navigation = "2.5.3" -androidx-paging = "1.0.0-alpha19" +androidx-paging = "1.0.0-alpha20" androidx-datastore = "1.0.0" androidx-startup = "1.1.1" androidx-room = "2.5.1" @@ -53,11 +53,11 @@ androidx-espresso-core = "3.5.1" androidx-benchmark = "1.1.1" androidx-profile-installer = "1.3.1" androidx-work = "2.8.1" -coil = "2.3.0" +coil = "2.4.0" okhttp = "4.11.0" retrofit = "2.9.0" retrofit-converter-serialization = "1.0.0" -chucker = "3.5.2" +chucker = "4.0.0" timber = "5.0.1" javapoet = "1.13.0" junit = "4.13.2" @@ -68,14 +68,14 @@ palantir-git = "3.0.0" kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" } kotlin-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlin-coroutines" } kotlin-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlin-coroutines" } -kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization" } -play-services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "play-services-ads" } -play-services-base = { module = "com.google.android.gms:play-services-base", version.ref = "play-services-base" } -firebase-analytics = { module = "com.google.firebase:firebase-analytics-ktx", version.ref = "firebase-analytics" } -firebase-config = { module = "com.google.firebase:firebase-config-ktx", version.ref = "firebase-config" } -firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx", version.ref = "firebase-crashlytics" } -firebase-messaging = { module = "com.google.firebase:firebase-messaging-ktx", version.ref = "firebase-messaging" } -play-core = { module = "com.google.android.play:core-ktx", version.ref = "play-core" } +kotlin-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization-json" } +gms-play-services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "gms-play-services-ads" } +gms-play-services-base = { module = "com.google.android.gms:play-services-base", version.ref = "gms-play-services-base" } +firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx", version.ref = "firebase-analytics-ktx" } +firebase-config-ktx = { module = "com.google.firebase:firebase-config-ktx", version.ref = "firebase-config-ktx" } +firebase-crashlytics-ktx = { module = "com.google.firebase:firebase-crashlytics-ktx", version.ref = "firebase-crashlytics-ktx" } +firebase-messaging-ktx = { module = "com.google.firebase:firebase-messaging-ktx", version.ref = "firebase-messaging-ktx" } +play-core-ktx = { module = "com.google.android.play:core-ktx", version.ref = "play-core-ktx" } accompanist-appcompat-theme = { module = "com.google.accompanist:accompanist-appcompat-theme", version.ref = "accompanist" } accompanist-drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist" } accompanist-insets = { module = "com.google.accompanist:accompanist-insets", version.ref = "accompanist" } @@ -103,7 +103,7 @@ androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "a androidx-appcompat-resources = { module = "androidx.appcompat:appcompat-resources", version.ref = "androidx-appcompat" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } androidx-browser = { module = "androidx.browser:browser", version.ref = "androidx-browser" } -androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-core-splashscreen" } androidx-constraintlayout-compose = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "androidx-constraintlayout" } androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } diff --git a/readme.md b/readme.md index 236123d70..eb88a18d6 100644 --- a/readme.md +++ b/readme.md @@ -2,6 +2,7 @@ Movies = [![check-pr-badge](https://github.com/michaelbel/movies/actions/workflows/check_pr.yml/badge.svg?branch=develop)](https://github.com/michaelbel/movies/actions/workflows/check_pr.yml) +[![google-play-downloads](https://PlayBadges.pavi2410.me/badge/downloads?id=org.michaelbel.moviemade)](https://play.google.com/store/apps/details?id=org.michaelbel.moviemade) [![paypal-badge](https://img.shields.io/badge/Donate-Paypal-FF5252.svg)](https://paypal.me/michaelbel) [![last-commit-badge](https://img.shields.io/github/last-commit/michaelbel/moviemade?color=FF5252)](https://github.com/michaelbel/moviemade/commits)