From a8fef6dfaf315afd2a6f04712cd4ca9ccb638cb3 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer <33195281+snappdevelopment@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:47:26 +0100 Subject: [PATCH] Add dashboard arrangement dropdown to choose items per row (#411) Co-authored-by: Sebastian Neubauer --- .../features/dashboard/DashboardViewModel.kt | 28 ++++++++- .../dashboard/mapper/DashboardUiMapper.kt | 8 +++ .../dashboard/model/DashboardArrangement.kt | 8 +++ .../view/DashboardArrangementView.kt | 61 +++++++++++++++++++ .../dashboard/view/DashboardScreen.kt | 12 ++++ .../features/dashboard/view/DashboardView.kt | 8 ++- .../datasource/DeviceDashboardsDataSource.kt | 8 +++ .../repository/DashboardRepositoryImpl.kt | 18 ++++++ .../DeviceDashboardsDataSourceInMemory.kt | 16 +++++ .../github/openflocon/domain/dashboard/DI.kt | 5 ++ .../models/DashboardArrangementDomainModel.kt | 6 ++ .../repository/DashboardRepository.kt | 4 ++ .../ObserveDashboardArrangementUseCase.kt | 23 +++++++ .../SelectDashboardArrangementUseCase.kt | 19 ++++++ 14 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/model/DashboardArrangement.kt create mode 100644 FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardArrangementView.kt create mode 100644 FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/models/DashboardArrangementDomainModel.kt create mode 100644 FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/ObserveDashboardArrangementUseCase.kt create mode 100644 FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/SelectDashboardArrangementUseCase.kt diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/DashboardViewModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/DashboardViewModel.kt index df62786e..a2fd67ce 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/DashboardViewModel.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/DashboardViewModel.kt @@ -3,17 +3,20 @@ package io.github.openflocon.flocondesktop.features.dashboard import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import io.github.openflocon.domain.common.DispatcherProvider -import io.github.openflocon.domain.dashboard.models.DashboardId +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel import io.github.openflocon.domain.dashboard.usecase.DeleteCurrentDeviceSelectedDashboardUseCase import io.github.openflocon.domain.dashboard.usecase.DeleteDashboardUseCase import io.github.openflocon.domain.dashboard.usecase.ObserveCurrentDeviceDashboardUseCase +import io.github.openflocon.domain.dashboard.usecase.ObserveDashboardArrangementUseCase import io.github.openflocon.domain.dashboard.usecase.SendCheckBoxUpdateDeviceDeviceUseCase import io.github.openflocon.domain.dashboard.usecase.SendClickEventToDeviceDeviceUseCase +import io.github.openflocon.domain.dashboard.usecase.SelectDashboardArrangementUseCase import io.github.openflocon.domain.dashboard.usecase.SubmitFormToDeviceDeviceUseCase import io.github.openflocon.domain.dashboard.usecase.SubmitTextFieldToDeviceDeviceUseCase import io.github.openflocon.domain.feedback.FeedbackDisplayer import io.github.openflocon.flocondesktop.features.dashboard.delegate.DashboardSelectorDelegate import io.github.openflocon.flocondesktop.features.dashboard.mapper.toUi +import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardArrangement import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardViewState import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardsStateUiModel import io.github.openflocon.flocondesktop.features.dashboard.model.DeviceDashboardUiModel @@ -35,10 +38,22 @@ class DashboardViewModel( private val feedbackDisplayer: FeedbackDisplayer, private val deleteCurrentDeviceSelectedDashboardUseCase: DeleteCurrentDeviceSelectedDashboardUseCase, private val deleteDashboardUseCase: DeleteDashboardUseCase, + private val observeDashboardArrangementUseCase: ObserveDashboardArrangementUseCase, + private val selectDashboardArrangementUseCase: SelectDashboardArrangementUseCase, ) : ViewModel(dashboardSelectorDelegate) { val deviceDashboards: StateFlow = dashboardSelectorDelegate.deviceDashboards + val arrangement: StateFlow = + observeDashboardArrangementUseCase() + .map { it.toUi() } + .flowOn(dispatcherProvider.viewModel) + .stateIn( + viewModelScope, + SharingStarted.WhileSubscribed(5_000), + DashboardArrangement.Adaptive, + ) + val state: StateFlow = observeCurrentDeviceDashboardUseCase() .map { it?.toUi() } @@ -98,4 +113,15 @@ class DashboardViewModel( feedbackDisplayer.displayMessage("Dashboard removed") } } + + fun onArrangementClicked(arrangement: DashboardArrangement) { + viewModelScope.launch(dispatcherProvider.viewModel) { + selectDashboardArrangementUseCase( + when (arrangement) { + is DashboardArrangement.Adaptive -> DashboardArrangementDomainModel.Adaptive + is DashboardArrangement.Fixed -> DashboardArrangementDomainModel.Fixed(itemsPerRow = arrangement.itemsPerRow) + } + ) + } + } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/mapper/DashboardUiMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/mapper/DashboardUiMapper.kt index 8143226e..cb8a1806 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/mapper/DashboardUiMapper.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/mapper/DashboardUiMapper.kt @@ -2,6 +2,7 @@ package io.github.openflocon.flocondesktop.features.dashboard.mapper import androidx.compose.ui.graphics.Color import io.github.openflocon.domain.dashboard.models.ContainerConfigDomainModel +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel import io.github.openflocon.domain.dashboard.models.DashboardDomainModel import io.github.openflocon.domain.dashboard.models.DashboardElementDomainModel import io.github.openflocon.domain.dashboard.models.FormContainerConfigDomainModel @@ -10,6 +11,7 @@ import io.github.openflocon.flocondesktop.common.ui.JsonPrettyPrinter import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardContainerViewState import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardContainerViewState.ContainerConfig import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardViewState +import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardArrangement internal fun DashboardDomainModel.toUi(): DashboardViewState = DashboardViewState( items = containers.map { container -> @@ -71,3 +73,9 @@ internal fun ContainerConfigDomainModel.toUI(): ContainerConfig = SectionContainerConfigDomainModel -> ContainerConfig.Section } + +internal fun DashboardArrangementDomainModel.toUi(): DashboardArrangement = + when (this) { + is DashboardArrangementDomainModel.Adaptive -> DashboardArrangement.Adaptive + is DashboardArrangementDomainModel.Fixed -> DashboardArrangement.Fixed(itemsPerRow = itemsPerRow) + } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/model/DashboardArrangement.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/model/DashboardArrangement.kt new file mode 100644 index 00000000..6ceac6a7 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/model/DashboardArrangement.kt @@ -0,0 +1,8 @@ +package io.github.openflocon.flocondesktop.features.dashboard.model + +sealed interface DashboardArrangement { + + data object Adaptive : DashboardArrangement + + data class Fixed(val itemsPerRow: Int) : DashboardArrangement +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardArrangementView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardArrangementView.kt new file mode 100644 index 00000000..f3678c1f --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardArrangementView.kt @@ -0,0 +1,61 @@ +package io.github.openflocon.flocondesktop.features.dashboard.view + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardArrangement +import io.github.openflocon.library.designsystem.FloconTheme +import io.github.openflocon.library.designsystem.components.FloconButton +import io.github.openflocon.library.designsystem.components.FloconDropdownMenu +import io.github.openflocon.library.designsystem.components.FloconDropdownMenuItem + +@Composable +internal fun DashboardArrangementView( + arrangement: DashboardArrangement, + onArrangementClicked: (DashboardArrangement) -> Unit, + modifier: Modifier = Modifier, +) { + var expanded by remember { mutableStateOf(false) } + + FloconDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + onExpandRequest = { expanded = true }, + anchorContent = { + FloconButton( + onClick = { expanded = true }, + containerColor = FloconTheme.colorPalette.secondary + ) { + Text( + text = when (arrangement) { + is DashboardArrangement.Adaptive -> "Items per row: Auto" + is DashboardArrangement.Fixed -> "Items per row: ${arrangement.itemsPerRow}" + }, + style = FloconTheme.typography.bodySmall + ) + } + }, + modifier = modifier + ) { + FloconDropdownMenuItem( + text = "Auto", + onClick = { + onArrangementClicked(DashboardArrangement.Adaptive) + expanded = false + }, + ) + repeat(5) { itemCount -> + FloconDropdownMenuItem( + text = "${itemCount + 1}", + onClick = { + onArrangementClicked(DashboardArrangement.Fixed(itemsPerRow = itemCount + 1)) + expanded = false + } + ) + } + } +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardScreen.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardScreen.kt index d398ea47..659eb770 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardScreen.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import io.github.openflocon.flocondesktop.features.dashboard.DashboardViewModel +import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardArrangement import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardViewState import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardsStateUiModel import io.github.openflocon.flocondesktop.features.dashboard.model.DeviceDashboardUiModel @@ -30,6 +31,7 @@ fun DashboardScreen(modifier: Modifier = Modifier) { val viewModel: DashboardViewModel = koinViewModel() val state by viewModel.state.collectAsStateWithLifecycle() val deviceDashboards by viewModel.deviceDashboards.collectAsStateWithLifecycle() + val arrangement by viewModel.arrangement.collectAsStateWithLifecycle() DisposableEffect(viewModel) { viewModel.onVisible() @@ -40,6 +42,7 @@ fun DashboardScreen(modifier: Modifier = Modifier) { DashboardScreen( state = state, deviceDashboards = deviceDashboards, + arrangement = arrangement, modifier = modifier, onDashboardSelected = viewModel::onDashboardSelected, onClickButton = viewModel::onButtonClicked, @@ -48,6 +51,7 @@ fun DashboardScreen(modifier: Modifier = Modifier) { onUpdateCheckBox = viewModel::onUpdateCheckBox, deleteCurrentDashboard = viewModel::deleteCurrentDashboard, onDeleteClicked = viewModel::onDeleteClicked, + onArrangementClicked = viewModel::onArrangementClicked ) } @@ -55,9 +59,11 @@ fun DashboardScreen(modifier: Modifier = Modifier) { fun DashboardScreen( state: DashboardViewState?, deviceDashboards: DashboardsStateUiModel, + arrangement: DashboardArrangement, onDashboardSelected: (DeviceDashboardUiModel) -> Unit, onDeleteClicked: (DeviceDashboardUiModel) -> Unit, deleteCurrentDashboard: () -> Unit, + onArrangementClicked: (DashboardArrangement) -> Unit, onClickButton: (buttonId: String) -> Unit, submitTextField: (textFieldId: String, value: String) -> Unit, submitForm: (formId: String, formValues: Map) -> Unit, @@ -81,6 +87,11 @@ fun DashboardScreen( Box(modifier = Modifier.weight(1f)) // to have actions on the right }, actions = { + DashboardArrangementView( + onArrangementClicked = onArrangementClicked, + arrangement = arrangement + ) + FloconOverflow { FloconDropdownMenuItem( text = "Delete Dashboards", @@ -103,6 +114,7 @@ fun DashboardScreen( submitTextField = submitTextField, submitForm = submitForm, onUpdateCheckBox = onUpdateCheckBox, + arrangement = arrangement ) } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardView.kt index a9ebf12e..f0b8ed38 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/view/DashboardView.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.lazy.staggeredgrid.items import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardArrangement import io.github.openflocon.flocondesktop.features.dashboard.model.DashboardViewState import io.github.openflocon.flocondesktop.features.dashboard.model.previewDashboardViewState import io.github.openflocon.library.designsystem.FloconTheme @@ -20,11 +21,15 @@ fun DashboardView( submitTextField: (textFieldId: String, value: String) -> Unit, submitForm: (formId: String, values: Map) -> Unit, onUpdateCheckBox: (checkBoxId: String, value: Boolean) -> Unit, + arrangement: DashboardArrangement, modifier: Modifier = Modifier, ) { LazyVerticalStaggeredGrid( modifier = modifier, - columns = StaggeredGridCells.Adaptive(minSize = 300.dp), + columns = when(arrangement) { + is DashboardArrangement.Adaptive -> StaggeredGridCells.Adaptive(minSize = 300.dp) + is DashboardArrangement.Fixed -> StaggeredGridCells.Fixed(arrangement.itemsPerRow) + }, horizontalArrangement = Arrangement.spacedBy(8.dp), verticalItemSpacing = 8.dp, ) { @@ -51,6 +56,7 @@ private fun DashboardViewPreview() { submitTextField = { _, _ -> }, submitForm = { _, _ -> }, onUpdateCheckBox = { _, _ -> }, + arrangement = DashboardArrangement.Adaptive ) } } diff --git a/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/datasource/DeviceDashboardsDataSource.kt b/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/datasource/DeviceDashboardsDataSource.kt index 08678fea..81d81154 100644 --- a/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/datasource/DeviceDashboardsDataSource.kt +++ b/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/datasource/DeviceDashboardsDataSource.kt @@ -1,5 +1,6 @@ package io.github.openflocon.data.core.dashboard.datasource +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel import io.github.openflocon.domain.dashboard.models.DashboardId import io.github.openflocon.domain.device.models.DeviceIdAndPackageNameDomainModel import kotlinx.coroutines.flow.Flow @@ -17,4 +18,11 @@ interface DeviceDashboardsDataSource { dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel ) + + fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow + + fun selectDashboardArrangement( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, + arrangement: DashboardArrangementDomainModel, + ) } diff --git a/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/repository/DashboardRepositoryImpl.kt b/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/repository/DashboardRepositoryImpl.kt index 2ac0ebce..55fa6979 100644 --- a/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/repository/DashboardRepositoryImpl.kt +++ b/FloconDesktop/data/core/src/commonMain/kotlin/io/github/openflocon/data/core/dashboard/repository/DashboardRepositoryImpl.kt @@ -5,6 +5,7 @@ import io.github.openflocon.data.core.dashboard.datasource.DeviceDashboardsDataS import io.github.openflocon.data.core.dashboard.datasource.ToDeviceDashboardDataSource import io.github.openflocon.domain.Protocol import io.github.openflocon.domain.common.DispatcherProvider +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel import io.github.openflocon.domain.dashboard.models.DashboardDomainModel import io.github.openflocon.domain.dashboard.models.DashboardId import io.github.openflocon.domain.dashboard.repository.DashboardRepository @@ -136,6 +137,23 @@ class DashboardRepositoryImpl( deviceIdAndPackageName = deviceIdAndPackageName, ).flowOn(dispatcherProvider.data) + override fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = + deviceDashboardsDataSource.observeDashboardArrangement( + deviceIdAndPackageName = deviceIdAndPackageName, + ).flowOn(dispatcherProvider.data) + + override suspend fun selectDashboardArrangement( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, + arrangement: DashboardArrangementDomainModel + ) { + withContext(dispatcherProvider.data) { + deviceDashboardsDataSource.selectDashboardArrangement( + deviceIdAndPackageName = deviceIdAndPackageName, + arrangement = arrangement, + ) + } + } + override suspend fun deleteDashboard( deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId diff --git a/FloconDesktop/data/local/src/commonMain/kotlin/io/github/openflocon/data/local/dashboard/datasource/DeviceDashboardsDataSourceInMemory.kt b/FloconDesktop/data/local/src/commonMain/kotlin/io/github/openflocon/data/local/dashboard/datasource/DeviceDashboardsDataSourceInMemory.kt index 06d89953..7b3e5c78 100644 --- a/FloconDesktop/data/local/src/commonMain/kotlin/io/github/openflocon/data/local/dashboard/datasource/DeviceDashboardsDataSourceInMemory.kt +++ b/FloconDesktop/data/local/src/commonMain/kotlin/io/github/openflocon/data/local/dashboard/datasource/DeviceDashboardsDataSourceInMemory.kt @@ -1,6 +1,7 @@ package io.github.openflocon.data.local.dashboard.datasource import io.github.openflocon.data.core.dashboard.datasource.DeviceDashboardsDataSource +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel import io.github.openflocon.domain.dashboard.models.DashboardId import io.github.openflocon.domain.device.models.DeviceIdAndPackageNameDomainModel import kotlinx.coroutines.flow.Flow @@ -11,6 +12,7 @@ import kotlinx.coroutines.flow.update class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource { private val selectedDeviceDashboards = MutableStateFlow>(emptyMap()) + private val selectedDashboardArrangements = MutableStateFlow>(emptyMap()) override fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = selectedDeviceDashboards @@ -31,4 +33,18 @@ class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource { } } + override fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = + selectedDashboardArrangements + .map { it[deviceIdAndPackageName] ?: DashboardArrangementDomainModel.Adaptive } + .distinctUntilChanged() + + override fun selectDashboardArrangement( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, + arrangement: DashboardArrangementDomainModel + ) { + selectedDashboardArrangements.update { + it + (deviceIdAndPackageName to arrangement) + } + } + } diff --git a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/DI.kt b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/DI.kt index eacc9d65..c70ec74f 100644 --- a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/DI.kt +++ b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/DI.kt @@ -5,10 +5,12 @@ import io.github.openflocon.domain.dashboard.usecase.DeleteDashboardUseCase import io.github.openflocon.domain.dashboard.usecase.GetCurrentDeviceSelectedDashboardUseCase import io.github.openflocon.domain.dashboard.usecase.ObserveCurrentDeviceDashboardUseCase import io.github.openflocon.domain.dashboard.usecase.ObserveCurrentDeviceSelectedDashboardUseCase +import io.github.openflocon.domain.dashboard.usecase.ObserveDashboardArrangementUseCase import io.github.openflocon.domain.dashboard.usecase.ObserveDeviceDashboardsUseCase import io.github.openflocon.domain.dashboard.usecase.SelectCurrentDeviceDashboardUseCase import io.github.openflocon.domain.dashboard.usecase.SendCheckBoxUpdateDeviceDeviceUseCase import io.github.openflocon.domain.dashboard.usecase.SendClickEventToDeviceDeviceUseCase +import io.github.openflocon.domain.dashboard.usecase.SelectDashboardArrangementUseCase import io.github.openflocon.domain.dashboard.usecase.SubmitFormToDeviceDeviceUseCase import io.github.openflocon.domain.dashboard.usecase.SubmitTextFieldToDeviceDeviceUseCase import org.koin.core.module.dsl.factoryOf @@ -26,6 +28,9 @@ internal val dashboardModule = module { factoryOf(::ObserveDeviceDashboardsUseCase) factoryOf(::SelectCurrentDeviceDashboardUseCase) + factoryOf(::ObserveDashboardArrangementUseCase) + factoryOf(::SelectDashboardArrangementUseCase) + factoryOf(::DeleteDashboardUseCase) factoryOf(::DeleteCurrentDeviceSelectedDashboardUseCase) } diff --git a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/models/DashboardArrangementDomainModel.kt b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/models/DashboardArrangementDomainModel.kt new file mode 100644 index 00000000..74b0e4b7 --- /dev/null +++ b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/models/DashboardArrangementDomainModel.kt @@ -0,0 +1,6 @@ +package io.github.openflocon.domain.dashboard.models + +sealed interface DashboardArrangementDomainModel { + data object Adaptive : DashboardArrangementDomainModel + data class Fixed(val itemsPerRow: Int) : DashboardArrangementDomainModel +} diff --git a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/repository/DashboardRepository.kt b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/repository/DashboardRepository.kt index 775c2236..87ef927b 100644 --- a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/repository/DashboardRepository.kt +++ b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/repository/DashboardRepository.kt @@ -1,5 +1,6 @@ package io.github.openflocon.domain.dashboard.repository +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel import io.github.openflocon.domain.dashboard.models.DashboardDomainModel import io.github.openflocon.domain.dashboard.models.DashboardId import io.github.openflocon.domain.device.models.DeviceIdAndPackageNameDomainModel @@ -12,6 +13,9 @@ interface DashboardRepository { fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow fun observeDeviceDashboards(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow> + fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow + suspend fun selectDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, arrangement: DashboardArrangementDomainModel) + suspend fun sendClickEvent( deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId, diff --git a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/ObserveDashboardArrangementUseCase.kt b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/ObserveDashboardArrangementUseCase.kt new file mode 100644 index 00000000..7cc85b10 --- /dev/null +++ b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/ObserveDashboardArrangementUseCase.kt @@ -0,0 +1,23 @@ +package io.github.openflocon.domain.dashboard.usecase + +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel +import io.github.openflocon.domain.dashboard.repository.DashboardRepository +import io.github.openflocon.domain.device.usecase.ObserveCurrentDeviceIdAndPackageNameUseCase +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf + +class ObserveDashboardArrangementUseCase( + private val dashboardRepository: DashboardRepository, + private val observeCurrentDeviceIdAndPackageNameUseCase: ObserveCurrentDeviceIdAndPackageNameUseCase +) { + operator fun invoke(): Flow = observeCurrentDeviceIdAndPackageNameUseCase().flatMapLatest { model -> + if (model == null) { + flowOf(DashboardArrangementDomainModel.Adaptive) + } else { + dashboardRepository.observeDashboardArrangement( + deviceIdAndPackageName = model, + ) + } + } +} diff --git a/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/SelectDashboardArrangementUseCase.kt b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/SelectDashboardArrangementUseCase.kt new file mode 100644 index 00000000..6205ccee --- /dev/null +++ b/FloconDesktop/domain/src/commonMain/kotlin/io/github/openflocon/domain/dashboard/usecase/SelectDashboardArrangementUseCase.kt @@ -0,0 +1,19 @@ +package io.github.openflocon.domain.dashboard.usecase + +import io.github.openflocon.domain.dashboard.models.DashboardArrangementDomainModel +import io.github.openflocon.domain.dashboard.repository.DashboardRepository +import io.github.openflocon.domain.device.usecase.GetCurrentDeviceIdAndPackageNameUseCase + +class SelectDashboardArrangementUseCase( + private val dashboardRepository: DashboardRepository, + private val getCurrentDeviceIdAndPackageNameUseCase: GetCurrentDeviceIdAndPackageNameUseCase, +) { + suspend operator fun invoke(arrangement: DashboardArrangementDomainModel) { + val current = getCurrentDeviceIdAndPackageNameUseCase() ?: return + + dashboardRepository.selectDashboardArrangement( + deviceIdAndPackageName = current, + arrangement = arrangement, + ) + } +}