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
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
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 ) {
var groups by this . groups
groups = groups . map {
if ( it . id == groupId ) it . copy ( currentScene = currentScene )
else it
private val subscribers : MutableList < ( List <Group> ) -> Unit > = mutableListOf ()
fun subscribe ( subscriber : ( List <Group> ) -> Unit ) = subscribers . add (subscriber)
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
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
@ -8,15 +10,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable fun SceneSwitcher (
scenes : Collection <Scene> ,
currentScene : Scene ? ,
onSwitch : (Scene) -> Unit ,
) {
CenteredColumn {
for ( scene in scenes ) {
@Composable fun SceneSwitcher ( group : Group , onSwitch : (Scene) -> Unit ) {
CenteringColumn {
Text ( group . name )
Spacer ( Modifier . height ( compactSpacing ) )
for ( scene in group . scenes ) {
val colors =
if ( scene . id == currentScene ?. id ) ButtonDefaults . buttonColors ()
if ( scene . id == group . currentScene ?. id ) ButtonDefaults . buttonColors ()
else ButtonDefaults . filledTonalButtonColors ()
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.compose.setContent
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.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@ -27,15 +26,17 @@ class MainActivity : ComponentActivity () {
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate (savedInstanceState)
var groups by AppState . groups
groups = Config . groups
Config . groups . forEach { AppState . addGroup (it) }
var groups by mutableStateOf ( AppState . groups )
AppState . subscribe { groups = it }
lifecycleScope . launch (IO) {
val prefs = applicationContext . dataStore . data . firstOrNull ()
if ( prefs != null ) {
val savedSceneName = prefs [ stringPreferencesKey ("scene") ]
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 ) {
AppState . setCurrentScene ( 0 , savedScene )
}
@ -47,14 +48,14 @@ class MainActivity : ComponentActivity () {
setContent {
ZanburTheme {
Scaffold { scaffoldPadding ->
CenteredColumn ( Modifier . padding (scaffoldPadding) . fillMaxSize () ) {
CenteringColumn ( Modifier . padding (scaffoldPadding) . fillMaxSize () ) {
CenteredColumn ( Modifier . width ( 300 . dp ) ) {
Text (groups [0] . name)
Spacer ( Modifier . height ( compactSpacing ) )
SceneSwitcher ( groups [0] . scenes , groups [0] . currentScene ) {
AppState . setCurrentScene ( 0 , it )
publishSceneChange ( groups [0] , it )
Column ( Modifier . width ( 300 . dp ) ) {
groups . forEach { group ->
SceneSwitcher (group) {
AppState . setCurrentScene ( group . id , it )
publishSceneChange ( group , it )
}
}
}
}
@ -68,9 +69,7 @@ class MainActivity : ComponentActivity () {
override fun onStop () {
super . onStop ()
val groups by AppState . groups
val currentScene = groups [0] . currentScene
val currentScene = AppState . groups [0] . currentScene
if ( currentScene != null ) lifecycleScope . launch (IO) {
applicationContext . dataStore . edit {
it [ stringPreferencesKey ("scene") ] = currentScene . name

View file

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

View file

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