Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bump] Compose Multiplatform and Window Size Classes #6

Merged
merged 1 commit into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinxSerialization)
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.compose.compiler)
Expand Down Expand Up @@ -41,7 +42,6 @@ kotlin {
implementation(libs.androidx.activity.compose)
implementation(libs.common.koin.android)
implementation(libs.androidx.datastore)
implementation(libs.androidx.compose.windowsizeclass)
}

desktopMain.dependencies {
Expand Down Expand Up @@ -71,9 +71,15 @@ kotlin {
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)

// Material3
// implementation(libs.composematerial3.adaptive)
// implementation(libs.composematerial3.adaptive.layout)
// implementation(libs.composematerial3.adaptive.navigation)

// Common
implementation(libs.common.koin)
implementation(libs.util.constraintlayout)
implementation(libs.kotlin.serialization.json)
}

commonTest.dependencies {
Expand Down
10 changes: 6 additions & 4 deletions app/src/androidMain/kotlin/id/gdg/app/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:OptIn(ExperimentalMaterial3WindowSizeClassApi::class)

package id.gdg.app

import android.os.Bundle
Expand All @@ -7,21 +9,21 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import id.gdg.ui.DarkColorPalette
import id.gdg.ui.LightColorPalette
import id.gdg.ui.androidx.compose.material3.windowsizeclass.CommonWindowSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.LocalWindowSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import id.gdg.ui.LocalWindowSizeClass

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
val colors = if (isSystemInDarkTheme()) DarkColorPalette else LightColorPalette
val windowSizeClass: CommonWindowSizeClass = calculateWindowSizeClass(this)
val windowSizeClass = calculateWindowSizeClass(this)

CompositionLocalProvider(LocalWindowSizeClass provides windowSizeClass) {
MaterialTheme(
Expand Down
60 changes: 23 additions & 37 deletions app/src/commonMain/kotlin/id/gdg/app/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.navigation.toRoute
import id.gdg.app.di.ViewModelFactory
import id.gdg.app.ui.AppEvent
import id.gdg.app.ui.AppRouter
import id.gdg.app.ui.EventDetailRouter
import id.gdg.app.ui.HomeRouter
import id.gdg.app.ui.OnboardingRouter
import id.gdg.app.ui.ScreenScaffold
import id.gdg.app.ui.SplashScreenRouter
import id.gdg.app.ui.screen.EventDetailScreen
import id.gdg.app.ui.screen.MainScreen
import id.gdg.app.ui.screen.OnboardingScreen
Expand All @@ -28,36 +30,38 @@ fun AppContent(
Scaffold { innerPadding ->
NavHost(
navController = navController,
startDestination = AppRouter.Onboarding.toString(), //defaultRoute(state.activeChapterId),
startDestination = SplashScreenRouter,
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
composable(route = AppRouter.Splash.toString()) {
composable<SplashScreenRouter> {
SplashScreen {
navController.navigateTo(
from = AppRouter.Splash,
to = AppRouter.Onboarding
)
navController.navigate(OnboardingRouter) {
popUpTo(SplashScreenRouter) {
inclusive = true
}
}
}
}

composable(route = AppRouter.Onboarding.toString()) {
composable<OnboardingRouter> {
OnboardingScreen(
chapterList = viewModel.chapterList,
onChapterSelected = { chapterId ->
viewModel.sendEvent(AppEvent.ChangeChapterId(chapterId))
},
navigateToMainScreen = {
navController.navigateTo(
from = AppRouter.Onboarding,
to = AppRouter.Home
)
navController.navigate(HomeRouter) {
popUpTo(OnboardingRouter) {
inclusive = true
}
}
}
)
}

composable(route = AppRouter.Home.toString()) {
composable<HomeRouter> {
ScreenScaffold(
viewModel = viewModel,
mainScreen = { viewModel, onEventDetailClicked ->
Expand All @@ -81,37 +85,19 @@ fun AppContent(
)
},
navigateToDetailScreen = { eventId ->
navController.navigate(
AppRouter.EventDetail.route.param(eventId)
)
navController.navigate(EventDetailRouter(eventId))
}
)
}

composable(
route = AppRouter.EventDetail.toString(),
arguments = listOf(navArgument(AppRouter.ARG_EVENT_ID) { type = NavType.StringType })
) { backStackEntry ->
val eventId = backStackEntry.arguments?.getString(AppRouter.ARG_EVENT_ID).orEmpty()
composable<EventDetailRouter> {
val eventDetail = it.toRoute<EventDetailRouter>()

EventDetailScreen(
viewModel = viewModel,
eventId = eventId
eventId = eventDetail.eventId
)
}
}
}
}

private fun NavHostController.navigateTo(from: AppRouter? = null, to: AppRouter) {
navigate(to.route.toString()) {
if (from != null) {
// popUpTo(from.route) {
// inclusive = true
// }
}
}
}

private fun defaultRoute(chapterId: Int) =
if (chapterId > 0) AppRouter.Home.route else AppRouter.Splash.route
44 changes: 0 additions & 44 deletions app/src/commonMain/kotlin/id/gdg/app/ui/AppRouter.kt

This file was deleted.

17 changes: 17 additions & 0 deletions app/src/commonMain/kotlin/id/gdg/app/ui/Router.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package id.gdg.app.ui

import kotlinx.serialization.Serializable

sealed interface Router

@Serializable
data object SplashScreenRouter : Router

@Serializable
data object OnboardingRouter : Router

@Serializable
data object HomeRouter : Router

@Serializable
data class EventDetailRouter(val eventId: String) : Router
11 changes: 5 additions & 6 deletions app/src/commonMain/kotlin/id/gdg/app/ui/ScreenScaffold.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package id.gdg.app.ui

import androidx.compose.material3.Surface
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
Expand All @@ -9,11 +10,9 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.dp
import id.gdg.app.AppViewModel
import id.gdg.ui.LocalWindowSizeClass
import id.gdg.ui.TwoPanelScaffold
import id.gdg.ui.TwoPanelScaffoldAnimationSpec
import id.gdg.ui.androidx.compose.material3.windowsizeclass.CommonWindowSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.CommonWindowWidthSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.LocalWindowSizeClass

@Composable
fun ScreenScaffold(
Expand All @@ -24,13 +23,13 @@ fun ScreenScaffold(
) {
var selectedEventId by rememberSaveable { mutableStateOf("") }

val windowSizeClazz: CommonWindowSizeClass = LocalWindowSizeClass.current
val windowSizeClazz = LocalWindowSizeClass.current
var shouldPanelOpened: Boolean? by rememberSaveable { mutableStateOf(null) }
var panelVisibility by rememberSaveable { mutableStateOf(shouldPanelOpened != null) }

LaunchedEffect(windowSizeClazz) {
shouldPanelOpened = shouldPanelOpened.takeIf {
windowSizeClazz.widthSizeClass != CommonWindowWidthSizeClass.Compact
windowSizeClazz.widthSizeClass != WindowWidthSizeClass.Compact
}

panelVisibility = shouldPanelOpened != null
Expand All @@ -45,7 +44,7 @@ fun ScreenScaffold(
mainScreen(viewModel) {
// If the screen size is compact (or mobile device screen size), then
// navigate to detail page with router. Otherwise, render the [panel].
if (windowSizeClazz.widthSizeClass == CommonWindowWidthSizeClass.Compact) {
if (windowSizeClazz.widthSizeClass == WindowWidthSizeClass.Compact) {
navigateToDetailScreen(it)
return@mainScreen
}
Expand Down
9 changes: 6 additions & 3 deletions app/src/desktopMain/kotlin/id/gdg/app/main.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:OptIn(ExperimentalMaterial3WindowSizeClassApi::class)

package id.gdg.app

import androidx.compose.foundation.background
Expand All @@ -7,6 +9,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.window.WindowDraggableArea
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
Expand All @@ -23,8 +27,7 @@ import id.gdg.app.di.appModule
import id.gdg.chapter.data.dataStore
import id.gdg.ui.DarkColorPalette
import id.gdg.ui.LightColorPalette
import id.gdg.ui.androidx.compose.material3.windowsizeclass.CommonWindowSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.LocalWindowSizeClass
import id.gdg.ui.LocalWindowSizeClass
import org.koin.core.context.startKoin
import org.koin.dsl.module

Expand All @@ -42,7 +45,7 @@ fun main() = application {
val colors = if (isSystemInDarkTheme()) DarkColorPalette else LightColorPalette

CompositionLocalProvider(
LocalWindowSizeClass provides CommonWindowSizeClass.calculateFromSize(windowState.size)
LocalWindowSizeClass provides calculateWindowSizeClass()
) {
MaterialTheme(colorScheme = colors) {
AppContent()
Expand Down
10 changes: 5 additions & 5 deletions app/src/iosMain/kotlin/id/gdg/app/MainViewController.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@file:Suppress("FunctionName")
@file:OptIn(ExperimentalMaterial3WindowSizeClassApi::class)

package id.gdg.app

Expand All @@ -7,20 +8,19 @@ import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.window.ComposeUIViewController
import id.gdg.ui.DarkColorPalette
import id.gdg.ui.LightColorPalette
import id.gdg.ui.androidx.compose.material3.windowsizeclass.LocalWindowSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.CommonWindowSizeClass
import id.gdg.ui.androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import id.gdg.ui.LocalWindowSizeClass

fun MainViewController() = ComposeUIViewController {
BoxWithConstraints {
val colors = if (isSystemInDarkTheme()) DarkColorPalette else LightColorPalette
val windowSizeClass: CommonWindowSizeClass = calculateWindowSizeClass(DpSize(maxWidth, maxHeight))
val windowSizeClass = calculateWindowSizeClass()

CompositionLocalProvider(LocalWindowSizeClass provides windowSizeClass) {
MaterialTheme(colorScheme = colors) {
Expand Down
6 changes: 2 additions & 4 deletions gdg-ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ kotlin {
}

sourceSets {
androidMain.dependencies {
implementation(libs.androidx.compose.windowsizeclass)
}
commonMain.dependencies {
api(libs.composematerial3.window.size.clazz)

api(libs.util.qdsfdhvh.image.loader)
api(libs.util.shimmer)

Expand All @@ -43,7 +42,6 @@ kotlin {
android {
namespace = "id.gdg.ui"
compileSdk = libs.versions.android.compileSdk.get().toInt()
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")

defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInt()
Expand Down
2 changes: 0 additions & 2 deletions gdg-ui/src/androidMain/AndroidManifest.xml

This file was deleted.

Loading
Loading