From ee3ba75a12ccc3f481507194dd43c486cb233945 Mon Sep 17 00:00:00 2001 From: michaelbel Date: Thu, 21 Nov 2024 22:34:12 +0300 Subject: [PATCH] Update project --- composeApp/build.gradle.kts | 5 +- .../org/michaelbel/template/MainActivity.kt | 7 +- .../michaelbel/template/Template.android.kt | 4 + .../kotlin/org/michaelbel/template/App.kt | 221 +++++++++++++++++- .../org/michaelbel/template/Template.kt | 3 + .../org/michaelbel/template/Template.ios.kt | 4 + .../org/michaelbel/template/Template.js.kt | 4 + .../org/michaelbel/template/Template.jvm.kt | 4 + .../org/michaelbel/template/Template.wasm.kt | 4 + gradle/libs.versions.toml | 17 +- 10 files changed, 249 insertions(+), 24 deletions(-) create mode 100644 composeApp/src/androidMain/kotlin/org/michaelbel/template/Template.android.kt create mode 100644 composeApp/src/commonMain/kotlin/org/michaelbel/template/Template.kt create mode 100644 composeApp/src/iosMain/kotlin/org/michaelbel/template/Template.ios.kt create mode 100644 composeApp/src/jsMain/kotlin/org/michaelbel/template/Template.js.kt create mode 100644 composeApp/src/jvmMain/kotlin/org/michaelbel/template/Template.jvm.kt create mode 100644 composeApp/src/wasmJsMain/kotlin/org/michaelbel/template/Template.wasm.kt diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 83c7549..d092629 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -4,12 +4,12 @@ import org.apache.commons.io.output.ByteArrayOutputStream import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig import java.nio.charset.Charset plugins { alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.kotlin.serialization) alias(libs.plugins.kotlin.compose) alias(libs.plugins.android.application) alias(libs.plugins.compose) @@ -74,12 +74,15 @@ kotlin { implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) + implementation(compose.material3) implementation(compose.ui) implementation(compose.components.resources) implementation(compose.components.uiToolingPreview) implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.serialization.json) implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.runtime.compose) + implementation(libs.jetbrains.androidx.navigation.compose) } androidMain.dependencies { implementation(compose.preview) diff --git a/composeApp/src/androidMain/kotlin/org/michaelbel/template/MainActivity.kt b/composeApp/src/androidMain/kotlin/org/michaelbel/template/MainActivity.kt index defc79c..93aaa56 100644 --- a/composeApp/src/androidMain/kotlin/org/michaelbel/template/MainActivity.kt +++ b/composeApp/src/androidMain/kotlin/org/michaelbel/template/MainActivity.kt @@ -4,16 +4,15 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -class MainActivity: ComponentActivity() { +class MainActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) enableEdgeToEdge() - setContent { - App() - } + setContent { App() } } } \ No newline at end of file diff --git a/composeApp/src/androidMain/kotlin/org/michaelbel/template/Template.android.kt b/composeApp/src/androidMain/kotlin/org/michaelbel/template/Template.android.kt new file mode 100644 index 0000000..43ed474 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/org/michaelbel/template/Template.android.kt @@ -0,0 +1,4 @@ +package org.michaelbel.template + +actual val TemplateName: String + get() = "Android Template" \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/org/michaelbel/template/App.kt b/composeApp/src/commonMain/kotlin/org/michaelbel/template/App.kt index 058fcba..de79d48 100644 --- a/composeApp/src/commonMain/kotlin/org/michaelbel/template/App.kt +++ b/composeApp/src/commonMain/kotlin/org/michaelbel/template/App.kt @@ -1,26 +1,225 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + package org.michaelbel.template +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material.Button -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.BadgedBox +import androidx.compose.material3.BottomAppBar +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Email +import androidx.compose.material.icons.outlined.Home +import androidx.compose.material.icons.outlined.Phone +import androidx.compose.material.icons.outlined.Settings +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import kotlinx.coroutines.launch +import kotlinx.serialization.Serializable @Composable fun App() { - MaterialTheme { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Button( - onClick = {} + val navHostController = rememberNavController() + var selectedRoute by remember { mutableStateOf(Navigation.Home) } + val snackbarHostState = remember { SnackbarHostState() } + val coroutineScope = rememberCoroutineScope() + + MaterialTheme( + colorScheme = if (isSystemInDarkTheme()) darkColorScheme() else lightColorScheme() + ) { + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = TemplateName + ) + } + ) + }, + bottomBar = { + BottomAppBar { + NavigationBarItem( + selected = selectedRoute == Navigation.Home, + onClick = { selectedRoute = Navigation.Home }, + icon = { + Icon( + imageVector = Icons.Outlined.Home, + contentDescription = null + ) + }, + label = { + Text( + text = "Home" + ) + } + ) + + NavigationBarItem( + selected = selectedRoute == Navigation.Chat, + onClick = { selectedRoute = Navigation.Chat }, + icon = { + BadgedBox( + badge = { + this@BottomAppBar.AnimatedVisibility( + visible = selectedRoute != Navigation.Chat, + enter = fadeIn(), + exit = fadeOut() + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .size(24.dp) + .background(color = Color.Red, shape = CircleShape) + ) { + Text( + text = "12", + color = Color.White, + fontSize = 12.sp, + fontWeight = FontWeight.Medium + ) + } + } + } + ) { + Icon( + imageVector = Icons.Outlined.Email, + contentDescription = null + ) + } + }, + label = { + Text( + text = "Chat" + ) + } + ) + + NavigationBarItem( + selected = selectedRoute == Navigation.Settings, + onClick = { selectedRoute = Navigation.Settings }, + icon = { + Icon( + imageVector = Icons.Outlined.Settings, + contentDescription = null + ) + }, + label = { + Text( + text = "Settings" + ) + } + ) + } + }, + snackbarHost = { + SnackbarHost( + hostState = snackbarHostState + ) + }, + floatingActionButton = { + Button( + onClick = { + coroutineScope.launch { + snackbarHostState.showSnackbar( + message = "Single-line snackbar with action", + actionLabel = "Action" + ) + } + } + ) { + Icon( + imageVector = Icons.Outlined.Phone, + contentDescription = null + ) + } + } + ) { innerPadding -> + NavHost( + navController = navHostController, + startDestination = selectedRoute, + modifier = Modifier.padding(innerPadding) ) { - Text("Print Log") + composable { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text( + text = "Home" + ) + } + } + composable { + Row( + modifier = Modifier.fillMaxSize(), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "Chat" + ) + } + } + composable { + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "Settings" + ) + } + } } } } +} + +sealed interface Navigation { + + @Serializable + data object Home: Navigation + + @Serializable + data object Chat: Navigation + + @Serializable + data object Settings: Navigation } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/org/michaelbel/template/Template.kt b/composeApp/src/commonMain/kotlin/org/michaelbel/template/Template.kt new file mode 100644 index 0000000..3355502 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/org/michaelbel/template/Template.kt @@ -0,0 +1,3 @@ +package org.michaelbel.template + +expect val TemplateName: String \ No newline at end of file diff --git a/composeApp/src/iosMain/kotlin/org/michaelbel/template/Template.ios.kt b/composeApp/src/iosMain/kotlin/org/michaelbel/template/Template.ios.kt new file mode 100644 index 0000000..edaf32b --- /dev/null +++ b/composeApp/src/iosMain/kotlin/org/michaelbel/template/Template.ios.kt @@ -0,0 +1,4 @@ +package org.michaelbel.template + +actual val TemplateName: String + get() = "iOS Template" \ No newline at end of file diff --git a/composeApp/src/jsMain/kotlin/org/michaelbel/template/Template.js.kt b/composeApp/src/jsMain/kotlin/org/michaelbel/template/Template.js.kt new file mode 100644 index 0000000..6d2dbbc --- /dev/null +++ b/composeApp/src/jsMain/kotlin/org/michaelbel/template/Template.js.kt @@ -0,0 +1,4 @@ +package org.michaelbel.template + +actual val TemplateName: String + get() = "JS Template" \ No newline at end of file diff --git a/composeApp/src/jvmMain/kotlin/org/michaelbel/template/Template.jvm.kt b/composeApp/src/jvmMain/kotlin/org/michaelbel/template/Template.jvm.kt new file mode 100644 index 0000000..1bebf86 --- /dev/null +++ b/composeApp/src/jvmMain/kotlin/org/michaelbel/template/Template.jvm.kt @@ -0,0 +1,4 @@ +package org.michaelbel.template + +actual val TemplateName: String + get() = "JVM Template" \ No newline at end of file diff --git a/composeApp/src/wasmJsMain/kotlin/org/michaelbel/template/Template.wasm.kt b/composeApp/src/wasmJsMain/kotlin/org/michaelbel/template/Template.wasm.kt new file mode 100644 index 0000000..525e817 --- /dev/null +++ b/composeApp/src/wasmJsMain/kotlin/org/michaelbel/template/Template.wasm.kt @@ -0,0 +1,4 @@ +package org.michaelbel.template + +actual val TemplateName: String + get() = "WASM Template" \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eea3cd1..388a8ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,13 +5,13 @@ target-sdk = "35" agp = "8.7.2" androidx-activity = "1.9.3" androidx-core-splashscreen = "1.0.1" -androidx-lifecycle = "2.8.3" +androidx-lifecycle = "2.8.4" google-material = "1.12.0" -jetbrains-compose = "1.7.0" -jetbrains-androidx-navigation-compose = "2.8.0-alpha08" -jetbrains-androidx-lifecycle-viewmodel-compose = "2.8.1" +jetbrains-compose = "1.7.1" +jetbrains-androidx-navigation-compose = "2.8.0-alpha10" +jetbrains-androidx-lifecycle-viewmodel-compose = "2.8.4" jetbrains-androidx-core-bundle = "1.0.1" kotlin = "2.0.21" @@ -19,10 +19,10 @@ kotlinx-coroutines = "1.9.0" kotlinx-datetime = "0.6.1" kotlinx-serialization = "1.7.3" -coil3 = "3.0.0-alpha08" -ktor = "3.0.0" -koin = "3.6.0-wasm-alpha2" -koin-compose = "1.2.0-Beta4" +coil3 = "3.0.3" +ktor = "3.0.1" +koin = "4.0.0" +koin-compose = "4.0.0" okio = "3.9.1" buildkonfig = "0.15.2" napier = "2.7.1" @@ -65,6 +65,7 @@ napier = { module = "io.github.aakira:napier", version.ref = "napier" } [plugins] kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } android-application = { id = "com.android.application", version.ref = "agp" } compose = { id = "org.jetbrains.compose", version.ref = "jetbrains-compose" }