Support multiple groups, remove Compose's MutableState from AppState

This commit is contained in:
Reinout Meliesie 2024-08-01 16:19:21 +02:00
parent ac8fa6f0c0
commit ba05088342
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
5 changed files with 43 additions and 39 deletions

View file

@ -1,19 +1,24 @@
package com.kernelmaft.zanbur package com.kernelmaft.zanbur
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
object AppState { object AppState {
val groups : MutableState < List <Group> > = mutableStateOf ( emptyList () ) val groups : List <Group> get () = groupsAsMutable
private var groupsAsMutable : List <Group> = emptyList ()
fun setCurrentScene ( groupId : Int , currentScene : Scene ) { private val subscribers : MutableList < ( List <Group> ) -> Unit > = mutableListOf ()
var groups by this . groups
groups = groups . map { fun subscribe ( subscriber : ( List <Group> ) -> Unit ) = subscribers . add (subscriber)
if ( it . id == groupId ) it . copy ( currentScene = currentScene )
else it fun addGroup ( group : Group ) {
groupsAsMutable += group
subscribers . forEach { it (groups) }
}
fun setCurrentScene ( groupId : Int , scene : Scene ) {
groupsAsMutable = groupsAsMutable . mapIndexed { index , group ->
if ( index == groupId ) group . copy ( currentScene = scene )
else group
} }
subscribers . forEach { it (groups) }
} }
} }

View file

@ -1,6 +1,8 @@
package com.kernelmaft.zanbur package com.kernelmaft.zanbur
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -8,15 +10,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@Composable fun SceneSwitcher ( @Composable fun SceneSwitcher ( group : Group , onSwitch : (Scene) -> Unit ) {
scenes : Collection <Scene> , CenteringColumn {
currentScene : Scene ? , Text ( group . name )
onSwitch : (Scene) -> Unit , Spacer ( Modifier . height ( compactSpacing ) )
) {
CenteredColumn { for ( scene in group . scenes ) {
for ( scene in scenes ) {
val colors = val colors =
if ( scene . id == currentScene ?. id ) ButtonDefaults . buttonColors () if ( scene . id == group . currentScene ?. id ) ButtonDefaults . buttonColors ()
else ButtonDefaults . filledTonalButtonColors () else ButtonDefaults . filledTonalButtonColors ()
Button ( { onSwitch (scene) } , Modifier . fillMaxWidth () , true , ButtonDefaults . shape , colors ) { Button ( { onSwitch (scene) } , Modifier . fillMaxWidth () , true , ButtonDefaults . shape , colors ) {

View file

@ -7,14 +7,13 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -27,15 +26,17 @@ class MainActivity : ComponentActivity () {
override fun onCreate ( savedInstanceState : Bundle ? ) { override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate (savedInstanceState) super . onCreate (savedInstanceState)
var groups by AppState . groups Config . groups . forEach { AppState . addGroup (it) }
groups = Config . groups
var groups by mutableStateOf ( AppState . groups )
AppState . subscribe { groups = it }
lifecycleScope . launch (IO) { lifecycleScope . launch (IO) {
val prefs = applicationContext . dataStore . data . firstOrNull () val prefs = applicationContext . dataStore . data . firstOrNull ()
if ( prefs != null ) { if ( prefs != null ) {
val savedSceneName = prefs [ stringPreferencesKey ("scene") ] val savedSceneName = prefs [ stringPreferencesKey ("scene") ]
if ( savedSceneName != null ) { if ( savedSceneName != null ) {
val savedScene = groups [0] . scenes . find { it . name == savedSceneName } val savedScene = AppState . groups [0] . scenes . find { it . name == savedSceneName }
if ( savedScene != null ) { if ( savedScene != null ) {
AppState . setCurrentScene ( 0 , savedScene ) AppState . setCurrentScene ( 0 , savedScene )
} }
@ -47,14 +48,14 @@ class MainActivity : ComponentActivity () {
setContent { setContent {
ZanburTheme { ZanburTheme {
Scaffold { scaffoldPadding -> Scaffold { scaffoldPadding ->
CenteredColumn ( Modifier . padding (scaffoldPadding) . fillMaxSize () ) { CenteringColumn ( Modifier . padding (scaffoldPadding) . fillMaxSize () ) {
CenteredColumn ( Modifier . width ( 300 . dp ) ) { Column ( Modifier . width ( 300 . dp ) ) {
Text (groups [0] . name) groups . forEach { group ->
Spacer ( Modifier . height ( compactSpacing ) ) SceneSwitcher (group) {
SceneSwitcher ( groups [0] . scenes , groups [0] . currentScene ) { AppState . setCurrentScene ( group . id , it )
AppState . setCurrentScene ( 0 , it ) publishSceneChange ( group , it )
publishSceneChange ( groups [0] , it ) }
} }
} }
} }
@ -68,9 +69,7 @@ class MainActivity : ComponentActivity () {
override fun onStop () { override fun onStop () {
super . onStop () super . onStop ()
val groups by AppState . groups val currentScene = AppState . groups [0] . currentScene
val currentScene = groups [0] . currentScene
if ( currentScene != null ) lifecycleScope . launch (IO) { if ( currentScene != null ) lifecycleScope . launch (IO) {
applicationContext . dataStore . edit { applicationContext . dataStore . edit {
it [ stringPreferencesKey ("scene") ] = currentScene . name it [ stringPreferencesKey ("scene") ] = currentScene . name

View file

@ -4,7 +4,7 @@ package com.kernelmaft.zanbur
data class Group ( data class Group (
val id : Int , val id : Int ,
val name : String , val name : String ,
val scenes : Collection <Scene> , val scenes : List <Scene> ,
val currentScene : Scene ? = null , val currentScene : Scene ? = null ,
) )

View file

@ -30,8 +30,7 @@ val compactSpacing = 16 . dp
MaterialTheme ( colorScheme, shapes , typography , content ) MaterialTheme ( colorScheme, shapes , typography , content )
} }
@Composable fun CenteredColumn ( @Composable fun CenteringColumn (
modifier : Modifier = Modifier , modifier : Modifier = Modifier ,
content : @Composable ColumnScope . () -> Unit , content : @Composable ColumnScope . () -> Unit ,
) = ) = Column ( modifier , Center , CenterHorizontally , content )
Column ( modifier , Center , CenterHorizontally , content )