Skip to content

Commit 76e8a0c

Browse files
sentinelwebsentinelweb
authored andcommitted
#487 chnage snackbar to material3 use scaffold
1 parent 4465214 commit 76e8a0c

File tree

9 files changed

+87
-69
lines changed

9 files changed

+87
-69
lines changed

app/src/main/java/uk/co/sentinelweb/cuer/app/ui/filebrowser/FileBrowserFragment.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ class FileBrowserFragment : Fragment(), AndroidScopeComponent {
8888
super.onViewCreated(view, savedInstanceState)
8989
binding.composeView.setContent {
9090
FilesComposeables.FileBrowserAppUi(
91-
modelObservable = viewModel.modelObservable,
9291
viewModel = viewModel
9392
)
9493
}
@@ -102,9 +101,7 @@ class FileBrowserFragment : Fragment(), AndroidScopeComponent {
102101
Label.Up -> {
103102
navRouter.navigate(NavigationModel(NAV_BACK, mapOf(BACK_PARAMS to R.id.navigation_remotes)))
104103
}
105-
is Label.ErrorMessage -> {
106-
107-
}
104+
else -> Unit
108105
}
109106
}
110107

hub/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ dependencies {
2727
implementation(project(":remote"))
2828
implementation(project(":net"))
2929
implementation(compose.desktop.currentOs)
30-
implementation(compose.desktop.common)
30+
implementation(compose.desktop.common) // needed for viewModel
3131
implementation(libs.kotlinx.coroutines.swing)
32-
// implementation(libs.androidx.lifecycle.viewmodel.compose.desktop)
3332
implementation(libs.androidx.lifecycle.viewmodel.compose.desktop)
33+
implementation(compose.material3)
3434

3535
implementation(libs.koinCore)
3636
implementation(libs.kotlinxCoroutinesCore)

hub/src/main/kotlin/uk/co/sentinelweb/cuer/hub/ui/filebrowser/FilesUiCoordinator.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
11
package uk.co.sentinelweb.cuer.hub.ui.filebrowser
22

33
import androidx.compose.runtime.Composable
4-
import androidx.lifecycle.viewModelScope
54
import kotlinx.coroutines.*
65
import kotlinx.coroutines.flow.MutableStateFlow
76
import kotlinx.coroutines.flow.collectLatest
8-
import kotlinx.coroutines.flow.launchIn
9-
import kotlinx.coroutines.flow.onEach
107
import org.koin.core.component.KoinComponent
118
import org.koin.core.qualifier.named
129
import org.koin.core.scope.Scope
1310
import org.koin.dsl.module
1411
import uk.co.sentinelweb.cuer.app.ui.cast.CastController
1512
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesComposeables.FileBrowserDesktopUi
1613
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract
17-
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Label
14+
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Label.ErrorMessage
1815
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Model.Companion.Initial
1916
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.State
2017
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesViewModel
2118
import uk.co.sentinelweb.cuer.app.ui.remotes.selector.RemotesDialogContract
2219
import uk.co.sentinelweb.cuer.core.wrapper.LogWrapper
2320
import uk.co.sentinelweb.cuer.domain.NodeDomain
24-
import uk.co.sentinelweb.cuer.domain.ext.name
2521
import uk.co.sentinelweb.cuer.hub.ui.home.HomeUiCoordinator
2622
import uk.co.sentinelweb.cuer.hub.ui.remotes.selector.RemotesDialogLauncher
2723
import uk.co.sentinelweb.cuer.hub.ui.remotes.selector.RemotesDialogLauncherComposeables.ShowRemotesDialogIfNecessary
@@ -34,17 +30,18 @@ class FilesUiCoordinator(
3430
private val log: LogWrapper
3531
) : UiCoordinator<FilesContract.Model>,
3632
DesktopScopeComponent,
37-
KoinComponent {
33+
KoinComponent {// fixme check KoinComponent
3834

3935
init {
4036
log.tag(this)
4137
}
4238

43-
private val job = SupervisorJob()
44-
private val coordinatorScope = CoroutineScope(Dispatchers.Main + job)
39+
private val supervisorJob = SupervisorJob()
40+
private val coordinatorScope = CoroutineScope(Dispatchers.Main + supervisorJob)
4541

4642
override val scope: Scope = desktopScopeWithSource(this)
4743
override val modelObservable = MutableStateFlow(Initial)
44+
4845
private val viewModel: FilesViewModel by scope.inject()
4946
private val remotesDialogLauncher: RemotesDialogContract.Launcher by scope.inject()
5047

@@ -57,7 +54,7 @@ class FilesUiCoordinator(
5754
coordinatorScope.launch {
5855
viewModel.labels.collectLatest {
5956
when (it) {
60-
is Label.ErrorMessage -> parent.showError(it.message)
57+
is ErrorMessage -> parent.showError(it.message)
6158
else -> Unit
6259
}
6360
}
@@ -114,7 +111,6 @@ class FilesUiCoordinator(
114111
)
115112
}
116113
}
117-
118114
}
119115
}
120116
}

hub/src/main/kotlin/uk/co/sentinelweb/cuer/hub/ui/home/HomeComposeables.kt

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package uk.co.sentinelweb.cuer.hub.ui.home
33
import androidx.compose.desktop.ui.tooling.preview.Preview
44
import androidx.compose.foundation.background
55
import androidx.compose.foundation.layout.*
6-
import androidx.compose.material.*
6+
import androidx.compose.material3.Scaffold
7+
import androidx.compose.material3.SnackbarHost
8+
import androidx.compose.material3.SnackbarHostState
79
import androidx.compose.runtime.Composable
810
import androidx.compose.runtime.LaunchedEffect
911
import androidx.compose.runtime.collectAsState
1012
import androidx.compose.runtime.remember
1113
import androidx.compose.ui.Alignment
1214
import androidx.compose.ui.Modifier
13-
import androidx.compose.ui.draw.shadow
1415
import androidx.compose.ui.graphics.Color
1516
import androidx.compose.ui.unit.DpSize
1617
import androidx.compose.ui.unit.dp
@@ -81,14 +82,13 @@ fun Home(coordinator: HomeUiCoordinator) {
8182
),
8283
)
8384
},
84-
scaffoldState = rememberScaffoldState(snackbarHostState = snackbarHostState),
85-
snackbarHost = { state ->
86-
SnackbarHost(state, modifier = Modifier.padding(8.dp)) { data ->
85+
snackbarHost = {
86+
SnackbarHost(snackbarHostState, modifier = Modifier.padding(8.dp)) { data ->
8787
CustomSnackbar(snackbarData = data)
8888
}
89-
}
90-
) {
91-
Row {
89+
},
90+
) { padding ->
91+
Row(modifier = Modifier.padding(padding)) {
9292
Box(modifier = Modifier.width(400.dp)) {
9393
coordinator.remotesCoordinator.RemotesDesktopUi()
9494
}
@@ -109,27 +109,3 @@ fun Home(coordinator: HomeUiCoordinator) {
109109
}
110110
}
111111
}
112-
113-
@Composable
114-
fun CustomSnackbar(snackbarData: SnackbarData) {
115-
Snackbar(
116-
modifier = Modifier.background(MaterialTheme.colors.error),
117-
action = {
118-
TextButton(
119-
onClick = { snackbarData.dismiss() },
120-
elevation = ButtonDefaults.elevation(4.dp, 2.dp, 0.dp),
121-
colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colors.onError),
122-
shape = MaterialTheme.shapes.medium,
123-
modifier = Modifier,
124-
) {
125-
Text(
126-
text = snackbarData.actionLabel ?: "DISMISS",
127-
color = MaterialTheme.colors.error
128-
)
129-
}
130-
},
131-
backgroundColor = MaterialTheme.colors.error,
132-
) {
133-
Text(text = snackbarData.message, color = MaterialTheme.colors.onError)
134-
}
135-
}

shared/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ kotlin {
7272

7373
implementation(compose.runtime)
7474
implementation(compose.foundation)
75-
implementation(compose.material)
75+
implementation(compose.material)// fixme try to remove this
7676
implementation(compose.material3)
7777
implementation(compose.materialIconsExtended)
7878
implementation(compose.ui)

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/ui/common/compose/CuerSharedAppBarComposables.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package uk.co.sentinelweb.cuer.app.ui.common.compose
22

3+
import androidx.compose.foundation.background
34
import androidx.compose.foundation.clickable
45
import androidx.compose.foundation.layout.*
56
import androidx.compose.material.icons.Icons
@@ -174,3 +175,36 @@ fun TopAppBarOverflowMenu(
174175
}
175176
}
176177
}
178+
179+
@Composable
180+
fun CustomSnackbar(snackbarData: SnackbarData) {
181+
Snackbar(
182+
modifier = Modifier.background(MaterialTheme.colorScheme.error),
183+
containerColor = MaterialTheme.colorScheme.error,
184+
contentColor = MaterialTheme.colorScheme.onError,
185+
shape = MaterialTheme.shapes.medium,
186+
action = {
187+
TextButton(
188+
onClick = { snackbarData.dismiss() },
189+
elevation = ButtonDefaults.elevatedButtonElevation(4.dp, 2.dp, 0.dp),
190+
colors = ButtonDefaults.buttonColors(
191+
contentColor = MaterialTheme.colorScheme.error,
192+
containerColor = MaterialTheme.colorScheme.onError,
193+
),
194+
shape = MaterialTheme.shapes.small,
195+
modifier = Modifier,
196+
) {
197+
Text(
198+
text = snackbarData.visuals.actionLabel ?: "DISMISS",
199+
color = MaterialTheme.colorScheme.error,
200+
style = MaterialTheme.typography.bodyMedium,
201+
)
202+
}
203+
},
204+
) {
205+
Text(
206+
text = snackbarData.visuals.message,
207+
color = MaterialTheme.colorScheme.onError
208+
)
209+
}
210+
}

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/ui/filebrowser/FilesComposeables.kt

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,28 @@ package uk.co.sentinelweb.cuer.app.ui.filebrowser
22

33
import androidx.compose.foundation.*
44
import androidx.compose.foundation.layout.*
5-
import androidx.compose.material3.CircularProgressIndicator
6-
import androidx.compose.material3.MaterialTheme
7-
import androidx.compose.material3.Surface
8-
import androidx.compose.material3.Text
5+
import androidx.compose.material3.*
96
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.LaunchedEffect
108
import androidx.compose.runtime.collectAsState
9+
import androidx.compose.runtime.remember
1110
import androidx.compose.ui.Alignment
1211
import androidx.compose.ui.Alignment.Companion.CenterVertically
1312
import androidx.compose.ui.Modifier
1413
import androidx.compose.ui.graphics.Color
1514
import androidx.compose.ui.graphics.ColorFilter
1615
import androidx.compose.ui.layout.ContentScale
1716
import androidx.compose.ui.unit.dp
18-
import kotlinx.coroutines.flow.Flow
1917
import org.jetbrains.compose.resources.painterResource
2018
import org.jetbrains.compose.resources.stringResource
2119
import uk.co.sentinelweb.cuer.app.ui.common.compose.Action
2220
import uk.co.sentinelweb.cuer.app.ui.common.compose.CuerMenuItem.*
2321
import uk.co.sentinelweb.cuer.app.ui.common.compose.CuerSharedAppBarComposables.CuerSharedAppBar
2422
import uk.co.sentinelweb.cuer.app.ui.common.compose.CuerSharedTheme
23+
import uk.co.sentinelweb.cuer.app.ui.common.compose.CustomSnackbar
2524
import uk.co.sentinelweb.cuer.app.ui.common.compose.colorTransparentYellow
25+
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Label
26+
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Label.None
2627
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.ListItemType.*
2728
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Model.Companion.Initial
2829
import uk.co.sentinelweb.cuer.app.ui.filebrowser.FilesContract.Sort.Alpha
@@ -36,15 +37,24 @@ object FilesComposeables {
3637

3738
// todo use scaffold - move up to app
3839
@Composable
39-
fun FileBrowserAppUi(modelObservable: Flow<FilesContract.Model>, viewModel: FilesContract.ViewModel) {
40-
val model = modelObservable.collectAsState(initial = Initial)
40+
fun FileBrowserAppUi(viewModel: FilesContract.ViewModel) {
41+
val model = viewModel.modelObservable.collectAsState(initial = Initial)
42+
val snackbarHostState = remember { SnackbarHostState() }
43+
val label = viewModel.labels.collectAsState(initial = None)
44+
45+
LaunchedEffect(label.value) {
46+
when (label.value) {
47+
is Label.ErrorMessage -> snackbarHostState.showSnackbar(
48+
message = (label.value as Label.ErrorMessage).message,
49+
actionLabel = "DISMISS",
50+
)
51+
52+
else -> Unit
53+
}
54+
}
4155
CuerSharedTheme {
42-
Surface {
43-
Column(
44-
modifier = Modifier
45-
.fillMaxHeight()
46-
.padding(bottom = 60.dp)
47-
) {
56+
Scaffold(
57+
topBar = {
4858
Box(
4959
contentAlignment = Alignment.TopStart,
5060
modifier = Modifier
@@ -71,14 +81,20 @@ object FilesComposeables {
7181
Action(item = Reload, action = { viewModel.onRefreshClick() }),
7282
),
7383
overflowActions = listOf(
74-
Action(Help, { }),
75-
Action(Settings, { }),
84+
Action(Help, { }),
85+
Action(Settings, { }),
7686
),
7787
modifier = Modifier.fillMaxSize().align(Alignment.CenterStart)
7888
)
7989
}
80-
FilesView(model = model.value, viewModel = viewModel)
90+
},
91+
snackbarHost = {
92+
SnackbarHost(snackbarHostState, modifier = Modifier.padding(8.dp)) { data ->
93+
CustomSnackbar(snackbarData = data)
94+
}
8195
}
96+
) {
97+
FilesView(model = model.value, viewModel = viewModel)
8298
}
8399
}
84100
}
@@ -95,15 +111,13 @@ object FilesComposeables {
95111
Box(
96112
contentAlignment = Alignment.TopStart,
97113
modifier = Modifier
98-
.height(60.dp)
99114
) {
100115
Image(
101116
painter = painterResource(Res.drawable.header_files_smoke),
102117
contentDescription = "",
103118
contentScale = ContentScale.Crop,
104119
modifier = Modifier
105-
.fillMaxSize()
106-
.wrapContentHeight(),
120+
.matchParentSize()
107121
)
108122
CuerSharedAppBar(
109123
title = stringResource(Res.string.files_title) + ": " + (model.value.nodeName ?: "No host"),

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/ui/filebrowser/FilesContract.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface FilesContract {
1010

1111
interface ViewModel {
1212
val modelObservable: Flow<Model>
13+
val labels: Flow<Label>
1314

1415
fun onClickFolder(folder: PlaylistDomain)
1516

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/ui/filebrowser/FilesViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class FilesViewModel(
4747
override val modelObservable: Flow<Model> = _modelObservable
4848

4949
private val _labels = MutableStateFlow<Label>(None)
50-
val labels: Flow<Label>
50+
override val labels: Flow<Label>
5151
get() = _labels
5252

5353
init {

0 commit comments

Comments
 (0)