Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
MFlisarWork committed Sep 18, 2024
1 parent 50fa22e commit 34cb1e4
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 225 deletions.
6 changes: 6 additions & 0 deletions demo/android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ dependencies {

implementation(libs.androidx.activity.compose)

// simple demo activity helper classes and functions I use in my demo activities
// + my theming library dependency
implementation("io.github.mflisar.composedemobaseactivity:library:0.8-alpha02")
implementation("com.github.MFlisar.ComposeThemer:core:0.2.1")
implementation("com.github.MFlisar.ComposeThemer:themes:0.2.1")

// ------------------------
// Libraries
// ------------------------
Expand Down
4 changes: 2 additions & 2 deletions demo/android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:name=".DemoApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,50 @@
package com.michaelflisar.kotpreferences.demo

import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.michaelflisar.kotpreferences.compose.collectAsState
import com.michaelflisar.composedemobaseactivity.classes.DemoTheme
import com.michaelflisar.composedemobaseactivity.classes.listSaverKeepEntryStateList
import com.michaelflisar.composedemobaseactivity.composables.DemoAppThemeRegion
import com.michaelflisar.composedemobaseactivity.composables.DemoCollapsibleRegion
import com.michaelflisar.composedemobaseactivity.composables.rememberExpandedRegions
import com.michaelflisar.composethemer.ComposeTheme
import com.michaelflisar.composethemer.defaultScrim
import com.michaelflisar.kotpreferences.compose.collectAsStateNotNull
import com.michaelflisar.kotpreferences.demo.classes.DemoTheme
import com.michaelflisar.kotpreferences.demo.classes.DemoUtil
import com.michaelflisar.kotpreferences.demo.composables.MyInfoLine
import com.michaelflisar.kotpreferences.demo.composables.MyLogInfo
import com.michaelflisar.kotpreferences.demo.composables.MyRegionTitle
import com.michaelflisar.kotpreferences.demo.settings.DemoSettingsModel
import com.michaelflisar.kotpreferences.demo.settings.TestEnum
import com.michaelflisar.kotpreferences.demo.ui.theme.AppTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class DemoActivity : ComponentActivity() {
Expand All @@ -40,29 +55,9 @@ class DemoActivity : ComponentActivity() {

setContent {

val stateTheme = DemoSettingsModel.appTheme.collectAsState()
val stateDynamicTheme = DemoSettingsModel.dynamicTheme.collectAsState()

// alternatively we could do following (this would use the settings cache [if enabled]
// or the initial value of the preference or the provided not null initial value) which would give us a not nullable state
// for all not nullable preferences
// val stateTheme = DemoSettingsModel.appTheme.collectAsStateNotNull()
// val stateDynamicTheme = DemoSettingsModel.dynamicTheme.collectAsStateNotNull()

// we at least wait for those 2 settings to load before rendering anything
// otherwise we must provide an initial state or handle null
val theme = stateTheme.value
val dynamicTheme = stateDynamicTheme.value
if (theme == null || dynamicTheme == null)
return@setContent

val initialTestsDone = rememberSaveable {
mutableStateOf(false)
}

val logs = rememberSaveable(saver = DemoUtil.LIST_SAVER) {
mutableStateListOf()
}
val initialTestsDone = rememberSaveable { mutableStateOf(false) }
val logs =
rememberSaveable(saver = listSaverKeepEntryStateList()) { mutableStateListOf<String>() }

LaunchedEffect(initialTestsDone.value) {
if (!initialTestsDone.value) {
Expand All @@ -71,36 +66,33 @@ class DemoActivity : ComponentActivity() {
}
}

AppTheme(
darkTheme = theme.isDark(),
dynamicColor = dynamicTheme
val baseTheme = DemoSettingsModel.baseTheme.collectAsStateNotNull()
val theme = DemoSettingsModel.theme.collectAsStateNotNull()
val dynamicTheme = DemoSettingsModel.dynamicTheme.collectAsStateNotNull()
val themeState = ComposeTheme.State(
base = baseTheme,
dynamic = dynamicTheme,
theme = theme
)

ComposeTheme(
state = themeState
) {
Surface(
modifier = Modifier
.fillMaxSize()
.imePadding(),
color = MaterialTheme.colorScheme.background
) {
Column {
// Update Edge-To-Edge state based on the current theme
//UpdateEdgeToEdgeDefault(this, themeState)

Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.app_name)) },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.onPrimary
)
)

Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Content(logs, theme, dynamicTheme)
}
}
) { paddingValues ->
Content(paddingValues, logs, themeState)
}
}
}
Expand All @@ -111,91 +103,75 @@ class DemoActivity : ComponentActivity() {
// ----------------

@Composable
fun ColumnScope.Content(
fun Content(
paddingValues: PaddingValues,
logs: MutableList<String>,
theme: DemoTheme,
dynamicTheme: Boolean
themeState: ComposeTheme.State
) {

val scope = rememberCoroutineScope()
val regions = rememberExpandedRegions(listOf(1))

Column(
modifier = Modifier
.weight(1f)
.verticalScroll(rememberScrollState())
.padding(paddingValues)
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {

// --------------------
// Infos about current state
// --------------------

MyRegionTitle("Infos")
MyInfoLine("Current Theme", theme.name)
MyInfoLine("Dynamic Theme", if (dynamicTheme) "YES" else "NO")

DemoAppThemeRegion(
regionId = 0,
theme = DemoTheme(
themeState.base.value,
themeState.theme.value,
themeState.dynamic.value,
ComposeTheme.getRegisteredThemes().map { it.key }
),
onThemeChanged = {
DemoSettingsModel.baseTheme.update(it.baseTheme)
DemoSettingsModel.theme.update(it.colorScheme)
DemoSettingsModel.dynamicTheme.update(it.dynamic)
},
expandedRegionsState = regions
)

// --------------------
// Actions
// Logs
// --------------------

MyRegionTitle("Actions")
Button(onClick = {
scope.launch(Dispatchers.IO) {
val value = DemoSettingsModel.appTheme.read()
val next = DemoTheme.values()[(value.ordinal + 1) % DemoTheme.values().size]
DemoSettingsModel.appTheme.update(next)
logs.add("DemoTheme changed from $value to $next")
}
}) {
Text("Next Theme")
}
Button(onClick = {
scope.launch(Dispatchers.IO) {
val value = DemoSettingsModel.dynamicTheme.read()
val next = !value
DemoSettingsModel.dynamicTheme.update(next)
logs.add("DynamicTheme changed from $value to $next")
}
}) {
Text("Toggle dynamic theme")
}
Button(onClick = {
scope.launch { runTests(logs) }
}) {
Text("Rerun tests")
}
}

// --------------------
// Logs
// --------------------
val listState = rememberLazyListState()
val lastScroll = rememberSaveable { mutableIntStateOf(logs.size) }

val listState = rememberLazyListState()

val lastScroll = rememberSaveable {
mutableStateOf(logs.size)
}

// always scroll to last item (but don't repeat this on screen rotation/recreation)
LaunchedEffect(logs.size) {
if (logs.size > 0 && lastScroll.value != logs.size - 1) {
listState.scrollToItem(logs.size - 1)
println("logs.size = scrolling...")
lastScroll.value = logs.size - 1
// always scroll to last item (but don't repeat this on screen rotation/recreation)
LaunchedEffect(logs.size) {
if (logs.size > 0 && lastScroll.value != logs.size - 1) {
listState.scrollToItem(logs.size - 1)
println("logs.size = scrolling...")
lastScroll.value = logs.size - 1
}
}
}

Column(modifier = Modifier.weight(1f)) {
MyRegionTitle("Logs")
LazyColumn(
state = listState
DemoCollapsibleRegion(
//modifier = Modifier.weight(1f),
title = "Logs",
regionId = 1,
expandedRegionsState = regions
) {
logs.forEachIndexed { index, log ->
item {
if (log.isEmpty()) {
HorizontalDivider()
} else {
MyLogInfo("Log $index", log)
MyRegionTitle("Logs")
LazyColumn(
state = listState
) {
logs.forEachIndexed { index, log ->
item {
if (log.isEmpty()) {
HorizontalDivider()
} else {
MyLogInfo("Log $index", log)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.michaelflisar.kotpreferences.demo

import android.app.Application
import com.michaelflisar.composethemer.ComposeTheme
import com.michaelflisar.composethemer.themes.ComposeThemes

class DemoApp : Application() {

override fun onCreate() {
super.onCreate()
ComposeTheme.register(*ComposeThemes.ALL.toTypedArray())
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.michaelflisar.kotpreferences.demo.classes

import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.toMutableStateList
import kotlin.random.Random

object DemoUtil {
Expand All @@ -11,11 +9,4 @@ object DemoUtil {
fun randomString(length: Int) = (1..length)
.map { Random.nextInt(0, CHARS.size).let { CHARS[it] } }
.joinToString("")

val LIST_SAVER = listSaver<MutableList<String>, String>(
save = {
it.toList()
},
restore = { it.toMutableStateList() }
)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.michaelflisar.kotpreferences.demo.settings

import com.michaelflisar.composedemobaseactivity.classes.DemoTheme
import com.michaelflisar.composethemer.ComposeTheme
import com.michaelflisar.composethemer.themes.themes.ThemeGreens
import com.michaelflisar.kotpreferences.core.SettingsModel
import com.michaelflisar.kotpreferences.core.enumPref
import com.michaelflisar.kotpreferences.core.initialisation.SettingSetup
import com.michaelflisar.kotpreferences.storage.datastore.DataStoreStorage
import com.michaelflisar.kotpreferences.storage.datastore.create
import com.michaelflisar.kotpreferences.demo.classes.DemoTheme

object DemoSettingsModel : SettingsModel(
DataStoreStorage.create(
Expand All @@ -16,7 +18,8 @@ object DemoSettingsModel : SettingsModel(
) {

// app settings
val appTheme by enumPref(DemoTheme.System)
val baseTheme by enumPref(ComposeTheme.BaseTheme.System)
val theme by stringPref(ThemeGreens.KEY)
val dynamicTheme by boolPref(false)

// simple types
Expand Down
Loading

0 comments on commit 34cb1e4

Please sign in to comment.