Skip to content

Commit 61fa1d3

Browse files
author
sentinelweb
committed
#489 hub player transport show
1 parent d50e85e commit 61fa1d3

File tree

5 files changed

+62
-16
lines changed

5 files changed

+62
-16
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import androidx.compose.ui.window.Window
2020
import androidx.compose.ui.window.WindowPosition
2121
import androidx.compose.ui.window.application
2222
import androidx.compose.ui.window.rememberWindowState
23+
import kotlinx.coroutines.ExperimentalCoroutinesApi
2324
import uk.co.sentinelweb.cuer.app.ui.common.compose.*
2425
import uk.co.sentinelweb.cuer.app.ui.local.LocalComposables
2526
import uk.co.sentinelweb.cuer.hub.ui.home.HomeContract.HomeModel.DisplayRoute.*
@@ -46,6 +47,7 @@ fun home(coordinator: HomeUiCoordinator) = application {
4647
}
4748
}
4849

50+
@ExperimentalCoroutinesApi
4951
@Composable
5052
@Preview
5153
fun Home(coordinator: HomeUiCoordinator) {
@@ -93,13 +95,16 @@ fun Home(coordinator: HomeUiCoordinator) {
9395
Box(modifier = Modifier.width(400.dp)) {
9496
coordinator.remotesCoordinator.RemotesDesktopUi()
9597
}
96-
Box(
98+
Column(
9799
modifier = Modifier
98100
.fillMaxSize()
99101
.background(Color.White)
102+
// .padding(bottom=if (state.value.showPlayer) 100.dp else 0.dp)
100103
) {
101-
val route = state.value.route
102-
when (route) {
104+
if (state.value.showPlayer) {
105+
coordinator.playerUiCoordinator?.PlayerDesktopUi()
106+
}
107+
when (state.value.route) {
103108
Settings -> PreferencesUi(coordinator.preferencesUiCoordinator)
104109
is Folders -> coordinator.filesUiCoordinator.FileBrowserDesktopUi()
105110
ThemeTest -> SharedThemeView.View()

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import uk.co.sentinelweb.cuer.domain.NodeDomain
55
class HomeContract {
66

77
data class HomeModel(
8-
val route: DisplayRoute = DisplayRoute.Settings
8+
val route: DisplayRoute = DisplayRoute.Settings,
9+
val showPlayer: Boolean = false,
910
) {
1011

1112
sealed class DisplayRoute {

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ class HomeUiCoordinator(
5252
private val log: LogWrapper by inject()
5353
private val playerConfigProvider: PlayerConfigProvider by inject()
5454

55-
private var playerUiCoordinator: VlcPlayerUiCoordinator? = null
55+
private var _playerUiCoordinator: VlcPlayerUiCoordinator? = null
56+
val playerUiCoordinator: VlcPlayerUiCoordinator?
57+
get() = _playerUiCoordinator
5658

5759
override var modelObservable = MutableStateFlow(HomeContract.HomeModel.Initial)
5860
private set
@@ -73,7 +75,7 @@ class HomeUiCoordinator(
7375
remotesCoordinator.destroy()
7476
preferencesUiCoordinator.destroy()
7577
filesUiCoordinator.destroy()
76-
playerUiCoordinator?.destroy()
78+
_playerUiCoordinator?.destroy()
7779
localCoordinator.destroy()
7880
scope.close()
7981
}
@@ -88,22 +90,24 @@ class HomeUiCoordinator(
8890

8991
fun showPlayer(item: PlaylistItemDomain, playlist: PlaylistDomain) {
9092
killPlayer()
91-
playerUiCoordinator = getKoin().get(parameters = { parametersOf(this@HomeUiCoordinator) })
93+
_playerUiCoordinator = getKoin().get(parameters = { parametersOf(this@HomeUiCoordinator) })
9294
val selectedScreen = playerConfigProvider.invoke()
9395
.screens
9496
.let { if (it.size > PREFERRED_SCREEN_DEFAULT) it.get(PREFERRED_SCREEN_DEFAULT) else it.get(0) }
95-
playerUiCoordinator?.setupPlaylistAndItem(item, playlist, selectedScreen)
97+
_playerUiCoordinator?.setupPlaylistAndItem(item, playlist, selectedScreen)
98+
modelObservable.value = modelObservable.value.copy(showPlayer = true)
9699
}
97100

98101
fun killPlayer() {
99-
playerUiCoordinator?.destroy()
100-
playerUiCoordinator = null
102+
modelObservable.value = modelObservable.value.copy(showPlayer = false)
103+
_playerUiCoordinator?.destroy()
104+
_playerUiCoordinator = null
101105
}
102106

103107
// called from the webserver
104108
override fun launchVideo(item: PlaylistItemDomain, screenIndex: Int?) {
105109
killPlayer()
106-
playerUiCoordinator = getKoin().get(parameters = { parametersOf(this@HomeUiCoordinator) })
110+
_playerUiCoordinator = getKoin().get(parameters = { parametersOf(this@HomeUiCoordinator) })
107111
val queuePlaylist = PlaylistDomain(
108112
id = Identifier(QueueTemp.id, MEMORY),
109113
title = "Queue",
@@ -113,7 +117,8 @@ class HomeUiCoordinator(
113117
val selectedScreen = playerConfigProvider.invoke()
114118
.screens
115119
.let { if (it.size > index) it.get(index) else it.get(0) }
116-
playerUiCoordinator?.setupPlaylistAndItem(item, queuePlaylist, selectedScreen)
120+
_playerUiCoordinator?.setupPlaylistAndItem(item, queuePlaylist, selectedScreen)
121+
modelObservable.value = modelObservable.value.copy(showPlayer = true)
117122
}
118123

119124
fun showError(message: String) {

hub/src/main/kotlin/uk/co/sentinelweb/cuer/hub/ui/player/vlc/VlcPlayerUiCoordinator.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package uk.co.sentinelweb.cuer.hub.ui.player.vlc
22

33
import SleepPreventer
4+
import androidx.compose.foundation.layout.height
5+
import androidx.compose.material3.MaterialTheme
6+
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.collectAsState
8+
import androidx.compose.ui.Modifier
9+
import androidx.compose.ui.unit.dp
410
import com.arkivanov.essenty.lifecycle.Lifecycle
511
import com.arkivanov.essenty.lifecycle.LifecycleRegistry
612
import com.arkivanov.mvikotlin.core.utils.diff
@@ -23,6 +29,7 @@ import uk.co.sentinelweb.cuer.app.queue.QueueMediatorContract
2329
import uk.co.sentinelweb.cuer.app.ui.common.skip.EmptySkipView
2430
import uk.co.sentinelweb.cuer.app.ui.common.skip.SkipContract
2531
import uk.co.sentinelweb.cuer.app.ui.common.skip.SkipPresenter
32+
import uk.co.sentinelweb.cuer.app.ui.player.PlayerComposeables
2633
import uk.co.sentinelweb.cuer.app.ui.player.PlayerContract
2734
import uk.co.sentinelweb.cuer.app.ui.player.PlayerContract.MviStore.Label.*
2835
import uk.co.sentinelweb.cuer.app.ui.player.PlayerContract.View.Event
@@ -66,6 +73,18 @@ class VlcPlayerUiCoordinator(
6673
private var playlistId: OrchestratorContract.Identifier<GUID>? = null
6774
private lateinit var screen: PlayerNodeDomain.Screen
6875

76+
@Composable
77+
fun PlayerDesktopUi() {
78+
val state = modelObservable.collectAsState()
79+
PlayerComposeables.PlayerTransport(
80+
state.value,
81+
this@VlcPlayerUiCoordinator,
82+
contentColor = MaterialTheme.colorScheme.onSurface,
83+
backgroundColor = MaterialTheme.colorScheme.surface,
84+
modifier = Modifier.height(100.dp)
85+
)
86+
}
87+
6988
override fun create() {
7089
log.tag(this)
7190
lifecycle.onCreate()
@@ -106,7 +125,7 @@ class VlcPlayerUiCoordinator(
106125
}
107126
}
108127

109-
override val renderer: ViewRenderer<Model> = diff {
128+
val modelDiffer: ViewRenderer<Model> = diff {
110129
diff(get = Model::playState, set = {
111130
playerWindow.updateUiPlayState(it)
112131
})
@@ -124,6 +143,13 @@ class VlcPlayerUiCoordinator(
124143
})
125144
}
126145

146+
override val renderer: ViewRenderer<Model> = object : ViewRenderer<Model> {
147+
override fun render(model: Model) {
148+
modelObservable.value = model
149+
modelDiffer.render(model)
150+
}
151+
}
152+
127153
fun focusPlayerWindow() {
128154
playerWindow.doFocus()
129155
}

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/ui/player/PlayerComposeables.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import androidx.compose.ui.unit.dp
1111
import com.arkivanov.mvikotlin.core.view.BaseMviView
1212
import org.jetbrains.compose.resources.painterResource
1313
import org.jetbrains.compose.resources.stringResource
14+
import org.jetbrains.compose.ui.tooling.preview.Preview
1415
import org.koin.core.component.KoinComponent
1516
import org.koin.core.component.inject
1617
import uk.co.sentinelweb.cuer.app.ui.common.compose.colorTransparentBlack
18+
import uk.co.sentinelweb.cuer.app.ui.player.PlayerComposeables.VolumeDisplay
1719
import uk.co.sentinelweb.cuer.app.ui.player.PlayerContract.View.Event
1820
import uk.co.sentinelweb.cuer.app.ui.player.PlayerContract.View.Event.*
1921
import uk.co.sentinelweb.cuer.app.ui.player.PlayerContract.View.Model
@@ -25,14 +27,16 @@ private val buttonSize = 48.dp
2527
private val buttonPadding = 8.dp
2628

2729
object PlayerComposeables : KoinComponent {
30+
2831
private val log: LogWrapper by inject<LogWrapper>()
2932

3033
@Composable
3134
fun PlayerTransport(
3235
model: Model,
3336
view: BaseMviView<Model, Event>,
3437
contentColor: Color = Color.White,
35-
modifier: Modifier,
38+
backgroundColor: Color = colorTransparentBlack,
39+
modifier: Modifier = Modifier,
3640
) {
3741
log.tag("PlayerComposeables")
3842
Column(
@@ -41,7 +45,7 @@ object PlayerComposeables : KoinComponent {
4145
modifier = modifier
4246
.fillMaxWidth()
4347
.wrapContentHeight()
44-
.background(colorTransparentBlack)
48+
.background(backgroundColor)
4549
) {
4650

4751
Row(
@@ -159,7 +163,6 @@ object PlayerComposeables : KoinComponent {
159163
)
160164
}
161165

162-
163166
Slider(
164167
value = sliderPosition,
165168
onValueChange = { fraction -> sliderPosition = fraction },
@@ -188,3 +191,9 @@ object PlayerComposeables : KoinComponent {
188191
}
189192
}
190193
}
194+
195+
@Preview
196+
@Composable
197+
fun VolumeDisplayPreview() {
198+
VolumeDisplay(0.5f, Modifier.fillMaxWidth())
199+
}

0 commit comments

Comments
 (0)