Skip to content

Commit 2d3c0c9

Browse files
author
TEYSSANDIER Raphael
committed
feature: Rework again
1 parent 6322df3 commit 2d3c0c9

File tree

12 files changed

+387
-32
lines changed

12 files changed

+387
-32
lines changed

FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/AppWindow.kt

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ package io.github.openflocon.flocondesktop
55
import androidx.compose.foundation.ComposeFoundationFlags
66
import androidx.compose.foundation.ExperimentalFoundationApi
77
import androidx.compose.foundation.background
8-
import androidx.compose.foundation.layout.Box
98
import androidx.compose.foundation.layout.fillMaxSize
109
import androidx.compose.runtime.Composable
1110
import androidx.compose.runtime.getValue
11+
import androidx.compose.runtime.produceState
1212
import androidx.compose.ui.Modifier
1313
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1414
import androidx.navigation3.scene.DialogSceneStrategy
@@ -20,17 +20,21 @@ import io.github.openflocon.domain.adb.repository.AdbRepository
2020
import io.github.openflocon.domain.domainModule
2121
import io.github.openflocon.domain.settings.usecase.ObserveFontSizeMultiplierUseCase
2222
import io.github.openflocon.flocondesktop.adb.AdbRepositoryImpl
23+
import io.github.openflocon.flocondesktop.app.AppAction
24+
import io.github.openflocon.flocondesktop.app.AppUiState
2325
import io.github.openflocon.flocondesktop.app.AppViewModel
2426
import io.github.openflocon.flocondesktop.app.di.appModule
2527
import io.github.openflocon.flocondesktop.common.di.commonModule
26-
import io.github.openflocon.flocondesktop.common.ui.feedback.FeedbackDisplayerView
2728
import io.github.openflocon.flocondesktop.core.di.coreModule
2829
import io.github.openflocon.flocondesktop.features.analytics.analyticsRoutes
2930
import io.github.openflocon.flocondesktop.features.featuresModule
31+
import io.github.openflocon.flocondesktop.features.network.NetworkRoutes
3032
import io.github.openflocon.flocondesktop.features.network.networkRoutes
31-
import io.github.openflocon.flocondesktop.menu.MainRoutes
33+
import io.github.openflocon.flocondesktop.menu.MenuSceneStrategy
3234
import io.github.openflocon.flocondesktop.menu.di.mainModule
33-
import io.github.openflocon.flocondesktop.menu.menuRoutes
35+
import io.github.openflocon.flocondesktop.menu.ui.buildLeftPanelState
36+
import io.github.openflocon.flocondesktop.menu.ui.model.SubScreen
37+
import io.github.openflocon.flocondesktop.menu.ui.view.leftpannel.LeftPanelView
3438
import io.github.openflocon.library.designsystem.FloconTheme
3539
import io.github.openflocon.navigation.FloconNavigation
3640
import io.github.openflocon.navigation.MainFloconNavigationState
@@ -64,7 +68,7 @@ fun App() {
6468
// scope<MainRoutes.Sub> {
6569
// scoped { MainFloconNavigationState(MainRoutes.Main) }
6670
// }
67-
single { MainFloconNavigationState(MainRoutes.Main) }
71+
single { MainFloconNavigationState(NetworkRoutes.Main) }
6872
singleOf(::AdbRepositoryImpl) bind AdbRepository::class
6973
},
7074
)
@@ -80,9 +84,12 @@ fun App() {
8084
fontSizeMultiplier = fontSizeMultiplier
8185
) {
8286
val viewModel: AppViewModel = koinViewModel()
87+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
8388

8489
Content(
90+
uiState = uiState,
8591
navigationState = viewModel.navigationState,
92+
onAction = viewModel::onAction
8693
)
8794
}
8895
// }
@@ -91,26 +98,36 @@ fun App() {
9198

9299
@Composable
93100
private fun Content(
94-
navigationState: MainFloconNavigationState
101+
uiState: AppUiState,
102+
navigationState: MainFloconNavigationState,
103+
onAction: (AppAction) -> Unit
95104
) {
96-
Box(
105+
// TODO Redo
106+
val menuState by produceState(
107+
buildLeftPanelState(SubScreen.Network),
108+
uiState.contentState.current
109+
) {
110+
value = buildLeftPanelState(uiState.contentState.current)
111+
}
112+
113+
FloconNavigation(
114+
navigationState = navigationState,
115+
sceneStrategy = PanelSceneStrategy()
116+
.then(WindowSceneStrategy())
117+
.then(DialogSceneStrategy())
118+
.then(MenuSceneStrategy {
119+
LeftPanelView(
120+
state = menuState,
121+
expanded = it,
122+
onClickItem = { menu -> onAction(AppAction.SelectMenu(menu.screen)) }
123+
)
124+
})
125+
.then(SinglePaneSceneStrategy()),
97126
modifier = Modifier
98127
.fillMaxSize()
128+
.background(FloconTheme.colorPalette.surface)
99129
) {
100-
FloconNavigation(
101-
navigationState = navigationState,
102-
sceneStrategy = PanelSceneStrategy()
103-
.then(WindowSceneStrategy())
104-
.then(DialogSceneStrategy())
105-
.then(SinglePaneSceneStrategy()),
106-
modifier = Modifier
107-
.matchParentSize()
108-
.background(FloconTheme.colorPalette.surface)
109-
) {
110-
menuRoutes()
111-
networkRoutes()
112-
analyticsRoutes()
113-
}
114-
FeedbackDisplayerView()
130+
networkRoutes()
131+
analyticsRoutes()
115132
}
116133
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
package io.github.openflocon.flocondesktop.app
22

3-
internal sealed interface AppAction
3+
import io.github.openflocon.flocondesktop.menu.ui.model.SubScreen
4+
5+
internal sealed interface AppAction {
6+
7+
data class SelectMenu(val menu: SubScreen) : AppAction
8+
9+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.github.openflocon.flocondesktop.app
2+
3+
import androidx.compose.runtime.Immutable
4+
import io.github.openflocon.flocondesktop.menu.ui.model.AppsStateUiModel
5+
import io.github.openflocon.flocondesktop.menu.ui.model.DevicesStateUiModel
6+
import io.github.openflocon.flocondesktop.menu.ui.model.RecordVideoStateUiModel
7+
import io.github.openflocon.flocondesktop.menu.ui.model.previewAppsStateUiModel
8+
import io.github.openflocon.flocondesktop.menu.ui.model.previewDevicesStateUiModel
9+
10+
@Immutable
11+
data class AppUiState(
12+
val contentState: ContentUiState,
13+
val deviceState: DevicesStateUiModel,
14+
val appState: AppsStateUiModel,
15+
val recordState: RecordVideoStateUiModel
16+
)
17+
18+
fun previewAppUiState() = AppUiState(
19+
contentState = previewContentUiState(),
20+
deviceState = previewDevicesStateUiModel(),
21+
appState = previewAppsStateUiModel(),
22+
recordState = RecordVideoStateUiModel.Recording
23+
)

FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/app/AppViewModel.kt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,23 @@ package io.github.openflocon.flocondesktop.app
33
import androidx.lifecycle.ViewModel
44
import androidx.lifecycle.viewModelScope
55
import io.github.openflocon.domain.common.DispatcherProvider
6+
import io.github.openflocon.domain.device.usecase.RestartAppUseCase
7+
import io.github.openflocon.domain.device.usecase.TakeScreenshotUseCase
8+
import io.github.openflocon.domain.feedback.FeedbackDisplayer
69
import io.github.openflocon.domain.settings.usecase.InitAdbPathUseCase
710
import io.github.openflocon.domain.settings.usecase.StartAdbForwardUseCase
11+
import io.github.openflocon.flocondesktop.common.utils.stateInWhileSubscribed
12+
import io.github.openflocon.flocondesktop.features.analytics.AnalyticsRoutes
13+
import io.github.openflocon.flocondesktop.features.network.NetworkRoutes
14+
import io.github.openflocon.flocondesktop.menu.ui.delegates.DevicesDelegate
15+
import io.github.openflocon.flocondesktop.menu.ui.delegates.RecordVideoDelegate
16+
import io.github.openflocon.flocondesktop.menu.ui.model.SubScreen
817
import io.github.openflocon.flocondesktop.messages.ui.MessagesServerDelegate
918
import io.github.openflocon.navigation.MainFloconNavigationState
1019
import kotlinx.coroutines.delay
20+
import kotlinx.coroutines.flow.MutableStateFlow
21+
import kotlinx.coroutines.flow.combine
22+
import kotlinx.coroutines.flow.update
1123
import kotlinx.coroutines.isActive
1224
import kotlinx.coroutines.launch
1325

@@ -18,8 +30,41 @@ internal class AppViewModel(
1830
val navigationState: MainFloconNavigationState,
1931
private val initialSetupStateHolder: InitialSetupStateHolder,
2032
dispatcherProvider: DispatcherProvider,
33+
private val devicesDelegate: DevicesDelegate,
34+
private val takeScreenshotUseCase: TakeScreenshotUseCase,
35+
private val restartAppUseCase: RestartAppUseCase,
36+
private val recordVideoDelegate: RecordVideoDelegate,
37+
private val feedbackDisplayer: FeedbackDisplayer
2138
) : ViewModel(messagesServerDelegate) {
2239

40+
private val contentState = MutableStateFlow(
41+
ContentUiState(
42+
current = SubScreen.Network
43+
)
44+
)
45+
46+
val uiState = combine(
47+
contentState,
48+
devicesDelegate.devicesState,
49+
devicesDelegate.appsState,
50+
recordVideoDelegate.state
51+
) { content, devices, apps, record ->
52+
AppUiState(
53+
contentState = content,
54+
deviceState = devices,
55+
appState = apps,
56+
recordState = record
57+
)
58+
}
59+
.stateInWhileSubscribed(
60+
AppUiState(
61+
contentState = contentState.value,
62+
deviceState = devicesDelegate.devicesState.value,
63+
appState = devicesDelegate.appsState.value,
64+
recordState = recordVideoDelegate.state.value
65+
)
66+
)
67+
2368
init {
2469
viewModelScope.launch(dispatcherProvider.viewModel) {
2570
initAdbPathUseCase().alsoFailure {
@@ -38,5 +83,28 @@ internal class AppViewModel(
3883
}
3984
}
4085

86+
fun onAction(action: AppAction) {
87+
when (action) {
88+
is AppAction.SelectMenu -> onSelectMenu(action)
89+
}
90+
}
91+
92+
private fun onSelectMenu(action: AppAction.SelectMenu) {
93+
contentState.update { it.copy(current = action.menu) }
94+
navigationState.menu(
95+
when (action.menu) {
96+
SubScreen.Analytics -> AnalyticsRoutes.Main
97+
SubScreen.Dashboard -> TODO()
98+
SubScreen.Database -> TODO()
99+
SubScreen.Deeplinks -> TODO()
100+
SubScreen.Files -> TODO()
101+
SubScreen.Images -> TODO()
102+
SubScreen.Network -> NetworkRoutes.Main
103+
SubScreen.Settings -> TODO()
104+
SubScreen.SharedPreferences -> TODO()
105+
SubScreen.Tables -> TODO()
106+
}
107+
)
108+
}
41109

42110
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.github.openflocon.flocondesktop.app
2+
3+
import androidx.compose.runtime.Immutable
4+
import io.github.openflocon.flocondesktop.menu.ui.model.SubScreen
5+
6+
@Immutable
7+
data class ContentUiState(
8+
val current: SubScreen
9+
)
10+
11+
fun previewContentUiState() = ContentUiState(
12+
current = SubScreen.Network
13+
)
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
package io.github.openflocon.flocondesktop.features.analytics
22

33
import androidx.navigation3.runtime.EntryProviderScope
4+
import io.github.openflocon.flocondesktop.features.analytics.view.AnalyticsScreen
5+
import io.github.openflocon.flocondesktop.menu.MenuSceneStrategy
6+
import io.github.openflocon.flocondesktop.menu.ui.model.SubScreen
47
import io.github.openflocon.navigation.FloconRoute
8+
import kotlinx.serialization.Serializable
9+
10+
sealed interface AnalyticsRoutes : FloconRoute {
11+
12+
@Serializable
13+
data object Main : AnalyticsRoutes
14+
15+
}
516

617
fun EntryProviderScope<FloconRoute>.analyticsRoutes() {
7-
// TODO
18+
entry<AnalyticsRoutes.Main>(
19+
metadata = MenuSceneStrategy.menu(SubScreen.Analytics)
20+
) {
21+
AnalyticsScreen()
22+
}
823
}

FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/Navigation.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,32 @@ package io.github.openflocon.flocondesktop.features.network
33
import androidx.navigation3.runtime.EntryProviderScope
44
import io.github.openflocon.domain.settings.repository.SettingsRepository
55
import io.github.openflocon.flocondesktop.features.network.detail.view.NetworkDetailScreen
6+
import io.github.openflocon.flocondesktop.features.network.list.view.NetworkScreen
7+
import io.github.openflocon.flocondesktop.menu.MenuScene
8+
import io.github.openflocon.flocondesktop.menu.MenuSceneStrategy
9+
import io.github.openflocon.flocondesktop.menu.ui.model.SubScreen
610
import io.github.openflocon.navigation.FloconRoute
11+
import io.github.openflocon.navigation.PanelRoute
712
import io.github.openflocon.navigation.scene.PanelSceneStrategy
813
import kotlinx.serialization.Serializable
914
import org.koin.mp.KoinPlatform
1015

11-
internal sealed interface NetworkRoutes : FloconRoute {
16+
internal sealed interface NetworkRoutes {
1217

1318
@Serializable
14-
data class Panel(val requestId: String) : FloconRoute
19+
data object Main : PanelRoute
20+
21+
@Serializable
22+
data class Panel(val requestId: String) : PanelRoute
1523

1624
}
1725

1826
fun EntryProviderScope<FloconRoute>.networkRoutes() {
27+
entry<NetworkRoutes.Main>(
28+
metadata = MenuSceneStrategy.menu(SubScreen.Network)
29+
) {
30+
NetworkScreen()
31+
}
1932
entry<NetworkRoutes.Panel>(
2033
metadata = PanelSceneStrategy.panel(
2134
pinnable = true,

0 commit comments

Comments
 (0)