diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 7a75037b..5bedb857 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -99,8 +99,6 @@ dependencies { implementation("androidx.compose.material:material") implementation("androidx.compose.foundation:foundation") implementation("androidx.compose.material:material") - // Accompanist - implementation(libs.google.accompanist.systemuicontroller) // FireBase implementation(platform(libs.google.firebase.bom)) implementation("com.google.firebase:firebase-auth-ktx") diff --git a/androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/MainActivity.kt b/androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/MainActivity.kt index afdc32c0..4630191e 100644 --- a/androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/MainActivity.kt +++ b/androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/MainActivity.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.runtime.getValue import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.core.view.WindowCompat @@ -38,8 +39,8 @@ class MainActivity : ComponentActivity() { val componentContext = defaultComponentContext() val rootComponent = DefaultRootComponent(componentContext, rootModule, servicesModule) val rootBottomSheetComponent = rootComponent.rootBottomSheetComponent + setContent { - TransparentBars() val bottomSheetState = rememberSlotModalBottomSheetState( rootBottomSheetComponent.childSlot, onDismiss = rootBottomSheetComponent::dismissSlotChild @@ -50,7 +51,7 @@ class MainActivity : ComponentActivity() { } } } - ComposeApplication { + ComposeApplication(rootModule.themeSwitcher.value) { ModalBottomSheetLayout( sheetState = bottomSheetState.sheetState, sheetContent = bottomSheetState.sheetContent.value, diff --git a/gradle.properties b/gradle.properties index 89e33267..d5741d15 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,14 +41,15 @@ makeevrserg.java.source=11 makeevrserg.java.target=11 makeevrserg.java.ktarget=11 # Android -makeevrserg.android.sdk.compile=33 +makeevrserg.android.sdk.compile=34 makeevrserg.android.sdk.min=21 -makeevrserg.android.sdk.target=33 +makeevrserg.android.sdk.target=34 # Project makeevrserg.project.name=EmpireProjektMobile makeevrserg.project.group=com.makeevrserg.empireprojekt.mobile -makeevrserg.project.version.string=0.0.2 -makeevrserg.project.version.code=4 +makeevrserg.project.version.string=0.0.3 +makeevrserg.project.version.code=5 makeevrserg.project.description=EmpireProjekt mobile application makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com makeevrserg.project.url=https://empireprojekt.ru +org.jetbrains.compose.ios.resources.sync=false \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c5822aab..3fbb84ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,40 +2,40 @@ # Kotlin kotlin-version = "1.8.20" kotlin-dokka = "1.8.10" -kotlin-coroutines = "1.6.4" +kotlin-coroutines = "1.7.2" kotlin-compilerExtensionVersion = "1.4.5" kotlin-android-application = "8.0.1" -kotlin-serialization-json = "1.5.0" +kotlin-serialization-json = "1.5.1" # Androidx -androidx-lifecycle = "2.6.0" +androidx-lifecycle = "2.6.1" androidx-lifecycle-ext = "2.2.0" androidx-compose-bom = "2023.06.00" -androidx-fragment = "1.5.5" -androidx-core = "1.9.0" +androidx-fragment = "1.6.1" +androidx-core = "1.10.1" androidx-appcompat = "1.6.1" -androidx-room = "2.5.1" +androidx-room = "2.5.2" androidx-test-extJunit = "1.1.5" -androidx-navigation-compose = "2.5.3" -androidx-activity-compose = "1.6.1" -androidx-activity-ktx = "1.8.0-alpha02" -androidx-lifecycle-viewModelCompose = "2.6.0" +androidx-navigation-compose = "2.7.0" +androidx-activity-compose = "1.7.2" +androidx-activity-ktx = "1.8.0-alpha06" +androidx-lifecycle-viewModelCompose = "2.6.1" androidx-constraintlayout-compose = "1.0.1" androidx-constraintlayout-android = "2.1.4" -androidx-viewbinding = "7.4.2" -androidx-recyclerview = "1.3.0" +androidx-viewbinding = "8.1.0" +androidx-recyclerview = "1.3.1" androidx-cicerone = "7.1" leakcanary = "2.9.1" # Google -google-coroutinesPlayServices = "1.6.4" -google-android-material = "1.8.0" -google-auth = "20.4.1" -google-ads = "21.5.0" -google-crashlytics = "2.9.0" +google-coroutinesPlayServices = "1.7.2" +google-android-material = "1.9.0" +google-auth = "20.6.0" +google-ads = "22.2.0" +google-crashlytics = "2.9.8" google-services = "4.3.15" google-accompanist = "0.31.0-alpha" -google-firebase-bom = "31.2.3" +google-firebase-bom = "32.2.2" # Yandex yandex-ads = "5.7.0" @@ -43,7 +43,7 @@ yandex-ads = "5.7.0" # Testw test-junit = "4.13.2" tests-assertk = "0.25" -tests-turbine = "0.7.0" +tests-turbine = "1.0.0" # Other ktor = "2.3.2-eap-692" @@ -58,16 +58,16 @@ klibs-kdi = "1.1.0" kotlin-compose = "1.4.0" # Moko -moko-mvvm = "0.15.0" -moko-resources = "0.22.3" -moko-network = "0.20.1" +moko-mvvm = "0.16.1" +moko-resources = "0.23.0" +moko-network = "0.21.0" # Decompose -decompose = "2.0.0-beta-01" +decompose = "2.0.1" essenty = "1.1.0" # MVIKotlin -mvikotlin = "3.1.0" +mvikotlin = "3.2.1" # lwjgl lwjgl = "3.3.1" diff --git a/modules/features/root/build.gradle.kts b/modules/features/root/build.gradle.kts index 68c06bf8..0994d47e 100644 --- a/modules/features/root/build.gradle.kts +++ b/modules/features/root/build.gradle.kts @@ -17,7 +17,11 @@ plugins { buildConfig { className("BuildKonfig") // forces the class name. Defaults to 'BuildConfig' packageName("${projectInfo.group}.shared") // forces the package. Defaults to '${project.group}' - buildConfigField("String", "VERSION_CODE", "\"${gradleProperty("project.version.code").integer}\"") + buildConfigField( + "String", + "VERSION_CODE", + "\"${gradleProperty("project.version.code").integer}\"" + ) buildConfigField("String", "VERSION_NAME", "\"${projectInfo.versionString}\"") } @@ -89,11 +93,20 @@ kotlin { implementation(libs.ktor.client.darwin) } } + val iosX64Main by getting { + resources.srcDirs("build/generated/moko/iosX64Main/src") + } + val iosArm64Main by getting { + resources.srcDirs("build/generated/moko/iosArm64Main/src") + } } } android { apply(plugin = "kotlin-parcelize") namespace = "${projectInfo.group}.shared" + sourceSets { + getByName("main").java.srcDirs("build/generated/moko/androidMain/src") + } } dependencies { // FireBase @@ -102,6 +115,7 @@ dependencies { implementation("com.google.firebase:firebase-common-ktx") implementation("com.google.firebase:firebase-firestore-ktx") implementation("com.google.firebase:firebase-messaging-ktx") + implementation(libs.klibs.kstorage) implementation(libs.google.auth) implementation(libs.kotlin.coroutines.playServices) } diff --git a/modules/features/root/root.podspec b/modules/features/root/root.podspec index 94f48d33..995e0097 100644 --- a/modules/features/root/root.podspec +++ b/modules/features/root/root.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = 'root' - spec.version = '0.0.2' + spec.version = '0.0.3' spec.homepage = 'https://empireprojekt.ru' spec.source = { :http=> ''} spec.authors = '' diff --git a/modules/features/root/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/factories/SettingsFactory.kt b/modules/features/root/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/factories/SettingsFactory.kt index a4ec0579..8cfbb9dd 100644 --- a/modules/features/root/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/factories/SettingsFactory.kt +++ b/modules/features/root/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/factories/SettingsFactory.kt @@ -1,6 +1,7 @@ package com.makeevrserg.empireprojekt.mobile.features.root.di.factories import com.russhwolf.settings.Settings +import com.russhwolf.settings.SharedPreferencesSettings import ru.astrainteractive.klibs.kdi.Factory import ru.astrainteractive.klibs.mikro.platform.PlatformConfiguration @@ -9,6 +10,6 @@ actual class SettingsFactory actual constructor( private val configuration: PlatformConfiguration ) : Factory { override fun create(): Settings { - TODO() + return SharedPreferencesSettings.Factory(configuration.applicationContext).create("SETTINGS") } } diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/DefaultRootComponent.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/DefaultRootComponent.kt index 54eec4b4..a8fabc5f 100644 --- a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/DefaultRootComponent.kt +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/DefaultRootComponent.kt @@ -20,6 +20,7 @@ import com.makeevrserg.empireprojekt.mobile.features.root.di.impl.status.StatusM import com.makeevrserg.empireprojekt.mobile.features.status.DefaultMinecraftStatusComponent import com.makeevrserg.empireprojekt.mobile.features.status.StatusComponent import com.makeevrserg.empireprojekt.mobile.features.status.UrlStatusComponent +import com.makeevrserg.empireprojekt.mobile.features.theme.ThemeSwitcher import com.makeevrserg.empireprojekt.mobile.services.core.CoroutineFeature class DefaultRootComponent( @@ -27,10 +28,11 @@ class DefaultRootComponent( rootModule: RootModule, servicesModule: ServicesModule ) : RootComponent, ComponentContext by componentContext { - override val rootBottomSheetComponent: RootBottomSheetComponent = DefaultRootBottomSheetComponent( - componentContext = childContext("RootBottomSheetComponent"), - servicesModule = servicesModule, - ) + override val rootBottomSheetComponent: RootBottomSheetComponent = + DefaultRootBottomSheetComponent( + componentContext = childContext("RootBottomSheetComponent"), + servicesModule = servicesModule, + ) private val navigation = StackNavigation() override val childStack: Value> = childStack( @@ -98,6 +100,7 @@ class DefaultRootComponent( } ) Configuration.Status( + themeSwitcher = rootModule.themeSwitcher.value, statusComponents = listOf( esmpStatusComponent, ainteractiveStatusComponent, @@ -133,6 +136,9 @@ class DefaultRootComponent( val splashComponent: SplashComponent ) : Configuration - class Status(val statusComponents: List) : Configuration + class Status( + val statusComponents: List, + val themeSwitcher: ThemeSwitcher + ) : Configuration } } diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/RootModule.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/RootModule.kt index 63cf3649..b7abd4f6 100644 --- a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/RootModule.kt +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/RootModule.kt @@ -1,20 +1,20 @@ package com.makeevrserg.empireprojekt.mobile.features.root.di import com.makeevrserg.empireprojekt.mobile.features.root.di.impl.root.RootModuleImpl +import com.makeevrserg.empireprojekt.mobile.features.theme.ThemeSwitcher import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope -import ru.astrainteractive.klibs.kdi.ExperimentalKDIApi +import ru.astrainteractive.klibs.kdi.Module import ru.astrainteractive.klibs.kdi.Single -import ru.astrainteractive.klibs.kdi.WiredModule import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers -@OptIn(ExperimentalKDIApi::class) -interface RootModule : WiredModule { +interface RootModule : Module { val servicesModule: ServicesModule val settings: Single val dispatchers: Single val mainScope: Single + val themeSwitcher: Single companion object : RootModule by RootModuleImpl } diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/ServicesModule.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/ServicesModule.kt index af427091..d76a6248 100644 --- a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/ServicesModule.kt +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/ServicesModule.kt @@ -3,14 +3,12 @@ package com.makeevrserg.empireprojekt.mobile.features.root.di import com.makeevrserg.empireprojekt.mobile.services.core.LinkBrowser import io.ktor.client.HttpClient import kotlinx.serialization.json.Json -import ru.astrainteractive.klibs.kdi.ExperimentalKDIApi import ru.astrainteractive.klibs.kdi.Lateinit +import ru.astrainteractive.klibs.kdi.Module import ru.astrainteractive.klibs.kdi.Single -import ru.astrainteractive.klibs.kdi.WiredModule import ru.astrainteractive.klibs.mikro.platform.PlatformConfiguration -@OptIn(ExperimentalKDIApi::class) -interface ServicesModule : WiredModule { +interface ServicesModule : Module { val platformConfiguration: Lateinit val jsonConfiguration: Single val httpClient: Single diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/RootModuleImpl.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/RootModuleImpl.kt index 6348ff7f..8ed66afe 100644 --- a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/RootModuleImpl.kt +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/RootModuleImpl.kt @@ -2,16 +2,15 @@ package com.makeevrserg.empireprojekt.mobile.features.root.di.impl.root import com.makeevrserg.empireprojekt.mobile.features.root.di.RootModule import com.makeevrserg.empireprojekt.mobile.features.root.di.factories.SettingsFactory +import com.makeevrserg.empireprojekt.mobile.features.theme.ThemeSwitcher +import com.makeevrserg.empireprojekt.mobile.features.theme.ThemeSwitcherComponent import kotlinx.coroutines.MainScope -import ru.astrainteractive.klibs.kdi.ExperimentalKDIApi import ru.astrainteractive.klibs.kdi.Single -import ru.astrainteractive.klibs.kdi.WiredModule import ru.astrainteractive.klibs.kdi.getValue import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers -@OptIn(ExperimentalKDIApi::class) -internal object RootModuleImpl : RootModule, WiredModule by WiredModule.Default() { +internal object RootModuleImpl : RootModule { override val servicesModule by Single { ServicesModuleImpl() } @@ -19,13 +18,16 @@ internal object RootModuleImpl : RootModule, WiredModule by WiredModule.Default( override val settings = Single { val configuration by servicesModule.platformConfiguration SettingsFactory(configuration).create() - }.remember() + } override val dispatchers = Single { DefaultKotlinDispatchers - }.remember() + } override val mainScope = Single { MainScope() - }.remember() + } + override val themeSwitcher: Single = Single { + ThemeSwitcherComponent(settings.value) + } } diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/ServicesModuleImpl.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/ServicesModuleImpl.kt index 12531a7b..91961cd9 100644 --- a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/ServicesModuleImpl.kt +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/root/di/impl/root/ServicesModuleImpl.kt @@ -7,15 +7,12 @@ import io.ktor.client.HttpClient import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json -import ru.astrainteractive.klibs.kdi.ExperimentalKDIApi import ru.astrainteractive.klibs.kdi.Lateinit import ru.astrainteractive.klibs.kdi.Single -import ru.astrainteractive.klibs.kdi.WiredModule import ru.astrainteractive.klibs.kdi.getValue import ru.astrainteractive.klibs.mikro.platform.PlatformConfiguration -@OptIn(ExperimentalKDIApi::class) -internal class ServicesModuleImpl : ServicesModule, WiredModule by WiredModule.Default() { +internal class ServicesModuleImpl : ServicesModule { override val platformConfiguration = Lateinit() override val jsonConfiguration = Single { diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/theme/ThemeSwitcher.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/theme/ThemeSwitcher.kt new file mode 100644 index 00000000..fdb4f1ea --- /dev/null +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/theme/ThemeSwitcher.kt @@ -0,0 +1,15 @@ +package com.makeevrserg.empireprojekt.mobile.features.theme + +import kotlinx.coroutines.flow.StateFlow + +interface ThemeSwitcher { + val theme: StateFlow + + enum class Theme { + DARK, LIGHT + } + + fun selectDarkTheme() + fun selectLightTheme() + fun selectTheme(theme: Theme) +} diff --git a/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/theme/ThemeSwitcherComponent.kt b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/theme/ThemeSwitcherComponent.kt new file mode 100644 index 00000000..6bb3ca92 --- /dev/null +++ b/modules/features/root/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/theme/ThemeSwitcherComponent.kt @@ -0,0 +1,37 @@ +package com.makeevrserg.empireprojekt.mobile.features.theme + +import com.russhwolf.settings.Settings +import kotlinx.coroutines.flow.StateFlow +import ru.astrainteractive.klibs.kstorage.StateFlowMutableStorageValue + +class ThemeSwitcherComponent(private val settings: Settings) : ThemeSwitcher { + private val key = "THEME" + private val default = ThemeSwitcher.Theme.DARK + private val themeFlowStorageValue = StateFlowMutableStorageValue( + default = default, + loadSettingsValue = { + val ordinal = settings.getInt(key, ThemeSwitcher.Theme.LIGHT.ordinal) + ThemeSwitcher.Theme.values().getOrNull(ordinal) ?: default + }, + saveSettingsValue = { + settings.putInt(key, it.ordinal) + } + ) + override val theme: StateFlow = themeFlowStorageValue.stateFlow + + override fun selectDarkTheme() { + themeFlowStorageValue.save(ThemeSwitcher.Theme.DARK) + } + + override fun selectLightTheme() { + themeFlowStorageValue.save(ThemeSwitcher.Theme.LIGHT) + } + + override fun selectTheme(theme: ThemeSwitcher.Theme) { + themeFlowStorageValue.save(theme) + } + + init { + themeFlowStorageValue.load() + } +} diff --git a/modules/features/ui/build.gradle.kts b/modules/features/ui/build.gradle.kts index 37e9d35a..f9cabed8 100644 --- a/modules/features/ui/build.gradle.kts +++ b/modules/features/ui/build.gradle.kts @@ -38,6 +38,12 @@ kotlin { implementation(projects.modules.features.root) } } + val androidMain by getting { + dependencies { + // Accompanist + implementation(libs.google.accompanist.systemuicontroller) + } + } } } android { diff --git a/androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/TransparentBars.kt b/modules/features/ui/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/TransparentBars.kt similarity index 62% rename from androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/TransparentBars.kt rename to modules/features/ui/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/TransparentBars.kt index 9ef9fe3c..251fe6d2 100644 --- a/androidApp/src/main/java/com/makeevrserg/empireprojekt/mobile/TransparentBars.kt +++ b/modules/features/ui/src/androidMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/TransparentBars.kt @@ -1,4 +1,4 @@ -package com.makeevrserg.empireprojekt.mobile +package com.makeevrserg.empireprojekt.mobile.features.ui.root import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -6,13 +6,14 @@ import androidx.compose.ui.graphics.Color import com.google.accompanist.systemuicontroller.rememberSystemUiController @Composable -fun TransparentBars() { +actual fun TransparentBars(isDarkTheme: Boolean) { val systemUiController = rememberSystemUiController() - DisposableEffect(systemUiController) { + DisposableEffect(systemUiController, isDarkTheme) { systemUiController.setSystemBarsColor( color = Color.Transparent, - darkIcons = false + darkIcons = !isDarkTheme ) - onDispose {} + onDispose { + } } } diff --git a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ApplicationContent.kt b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ApplicationContent.kt index a0bc46af..9464841e 100644 --- a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ApplicationContent.kt +++ b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ApplicationContent.kt @@ -35,6 +35,7 @@ fun ApplicationContent( is DefaultRootComponent.Configuration.Status -> StatusScreen( rootComponent = rootComponent, rootBottomSheetComponent = rootBottomSheetComponent, + themeSwitcher = screen.themeSwitcher, statusComponents = screen.statusComponents ) } diff --git a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ComposeApplication.kt b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ComposeApplication.kt index 9f4ca978..bb963f6e 100644 --- a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ComposeApplication.kt +++ b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/ComposeApplication.kt @@ -1,24 +1,45 @@ package com.makeevrserg.empireprojekt.mobile.features.ui.root +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.with import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import com.makeevrserg.empireprojekt.mobile.core.ui.theme.AppTheme import com.makeevrserg.empireprojekt.mobile.core.ui.theme.LocalAppTheme +import com.makeevrserg.empireprojekt.mobile.features.theme.ThemeSwitcher +private fun ThemeSwitcher.Theme.toComposeTheme() = when (this) { + ThemeSwitcher.Theme.DARK -> AppTheme.DefaultDarkTheme + ThemeSwitcher.Theme.LIGHT -> AppTheme.DefaultLightTheme +} + +@OptIn(ExperimentalAnimationApi::class) @Composable -fun ComposeApplication(content: @Composable () -> Unit) { - val appTheme = AppTheme.DefaultDarkTheme +fun ComposeApplication(themeSwitcher: ThemeSwitcher, content: @Composable () -> Unit) { + val theme by themeSwitcher.theme.collectAsState() + val appTheme = theme.toComposeTheme() + TransparentBars(appTheme.isDark) - CompositionLocalProvider( - LocalAppTheme provides appTheme, - content = { - MaterialTheme( - colors = LocalAppTheme.current.materialColor, - typography = LocalAppTheme.current.typography, - shapes = LocalAppTheme.current.shapes, - content = content - ) - } - ) + AnimatedContent( + targetState = appTheme, + transitionSpec = { fadeIn() with fadeOut() } + ) { appTheme -> + CompositionLocalProvider( + LocalAppTheme provides appTheme, + content = { + MaterialTheme( + colors = LocalAppTheme.current.materialColor, + typography = LocalAppTheme.current.typography, + shapes = LocalAppTheme.current.shapes, + content = content + ) + } + ) + } } diff --git a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/TransparentBars.kt b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/TransparentBars.kt new file mode 100644 index 00000000..d72e50f0 --- /dev/null +++ b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/root/TransparentBars.kt @@ -0,0 +1,6 @@ +package com.makeevrserg.empireprojekt.mobile.features.ui.root + +import androidx.compose.runtime.Composable + +@Composable +expect fun TransparentBars(isDarkTheme: Boolean) diff --git a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/status/StatusScreen.kt b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/status/StatusScreen.kt index e342f90c..bc2bd5c7 100644 --- a/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/status/StatusScreen.kt +++ b/modules/features/ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/features/ui/status/StatusScreen.kt @@ -1,29 +1,36 @@ package com.makeevrserg.empireprojekt.mobile.features.ui.status +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.FloatingActionButton import androidx.compose.material.Icon import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.WbSunny import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import com.makeevrserg.empireprojekt.mobile.core.ui.asComposableString import com.makeevrserg.empireprojekt.mobile.core.ui.components.navBarsPadding import com.makeevrserg.empireprojekt.mobile.core.ui.theme.AppTheme import com.makeevrserg.empireprojekt.mobile.features.root.DefaultRootComponent import com.makeevrserg.empireprojekt.mobile.features.root.RootBottomSheetComponent import com.makeevrserg.empireprojekt.mobile.features.status.StatusComponent +import com.makeevrserg.empireprojekt.mobile.features.theme.ThemeSwitcher import com.makeevrserg.empireprojekt.mobile.features.ui.status.widget.StatusWidget import com.makeevrserg.empireprojekt.mobile.resources.MR +import ru.astrainteractive.klibs.mikro.core.util.next @Composable fun StatusScreen( rootComponent: DefaultRootComponent, rootBottomSheetComponent: RootBottomSheetComponent, + themeSwitcher: ThemeSwitcher, statusComponents: List, ) { Scaffold( @@ -39,7 +46,7 @@ fun StatusScreen( Icon( imageVector = Icons.Filled.Info, contentDescription = null, - tint = AppTheme.materialColor.onPrimary + tint = AppTheme.alColors.onSecondaryVariant ) } }, @@ -50,6 +57,20 @@ fun StatusScreen( .navBarsPadding() .padding(AppTheme.dimens.S) ) { + item { + Icon( + imageVector = Icons.Filled.WbSunny, + contentDescription = null, + tint = AppTheme.materialColor.onPrimary, + modifier = Modifier + .clip(CircleShape) + .clickable { + val nextTheme = + themeSwitcher.theme.value.next(ThemeSwitcher.Theme.values()) + themeSwitcher.selectTheme(nextTheme) + } + ) + } item { Text( text = MR.strings.status_title.asComposableString(), diff --git a/modules/services/core-ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/core/ui/theme/AppTheme.kt b/modules/services/core-ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/core/ui/theme/AppTheme.kt index a182a274..6fac94f1 100644 --- a/modules/services/core-ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/core/ui/theme/AppTheme.kt +++ b/modules/services/core-ui/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/core/ui/theme/AppTheme.kt @@ -23,7 +23,8 @@ sealed class AppTheme( val shapes: Shapes = Shapes(), val dimens: Dimens = Dimens(), val textSizes: TextSizes = TextSizes(), - val alColors: ALColors = ALColors() + val alColors: ALColors = ALColors(), + val isDark: Boolean ) { companion object { val materialColor: Colors @@ -91,6 +92,7 @@ sealed class AppTheme( surface = Color(0xFFFFFFFF), onSurface = Color(0xFF000000), ), + isDark = true ) object DefaultLightTheme : AppTheme( @@ -104,6 +106,7 @@ sealed class AppTheme( secondaryVariant = Color(0xFF106BBB), onSurface = Color(0xFF000000), ), + isDark = false ) } diff --git a/modules/services/core/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/services/core/FakeComponentContextFactory.kt b/modules/services/core/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/services/core/FakeComponentContextFactory.kt new file mode 100644 index 00000000..758cb4ba --- /dev/null +++ b/modules/services/core/src/commonMain/kotlin/com/makeevrserg/empireprojekt/mobile/services/core/FakeComponentContextFactory.kt @@ -0,0 +1,10 @@ +package com.makeevrserg.empireprojekt.mobile.services.core + +import com.arkivanov.decompose.ComponentContext +import com.arkivanov.decompose.DefaultComponentContext +import com.arkivanov.essenty.lifecycle.LifecycleRegistry +import ru.astrainteractive.klibs.kdi.Factory + +object FakeComponentContextFactory : Factory { + override fun create(): ComponentContext = DefaultComponentContext(LifecycleRegistry()) +} diff --git a/modules/services/resources/build.gradle.kts b/modules/services/resources/build.gradle.kts index fc47b99e..432fc6cd 100644 --- a/modules/services/resources/build.gradle.kts +++ b/modules/services/resources/build.gradle.kts @@ -16,6 +16,12 @@ kotlin { implementation(libs.moko.resources.core) } } + val iosX64Main by getting { + resources.srcDirs("build/generated/moko/iosX64Main/src") + } + val iosArm64Main by getting { + resources.srcDirs("build/generated/moko/iosArm64Main/src") + } } } multiplatformResources {