From 61e70a9cae04f78eeca0440d2073000898d31a36 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Sat, 7 Mar 2026 09:31:19 +0000 Subject: [PATCH 1/4] Fix dashboard arrangement key --- .../datasource/DeviceDashboardsDataSource.kt | 6 +++++- .../repository/DashboardRepositoryImpl.kt | 8 +++++++- .../DeviceDashboardsDataSourceInMemory.kt | 20 +++++++++++++++---- .../repository/DashboardRepository.kt | 12 +++++++++-- .../ObserveDashboardArrangementUseCase.kt | 14 ++++++++++--- .../SelectDashboardArrangementUseCase.kt | 3 +++ 6 files changed, 52 insertions(+), 11 deletions(-) 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 81d811547..1bde4cb6e 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 @@ -19,9 +19,13 @@ interface DeviceDashboardsDataSource { deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel ) - fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow + fun observeDashboardArrangement( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow fun selectDashboardArrangement( + dashboardId: DashboardId, 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 7ea059348..bb7148a77 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 @@ -133,16 +133,22 @@ class DashboardRepositoryImpl( deviceIdAndPackageName = deviceIdAndPackageName, ).flowOn(dispatcherProvider.data) - override fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = deviceDashboardsDataSource.observeDashboardArrangement( + override fun observeDashboardArrangement( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow = deviceDashboardsDataSource.observeDashboardArrangement( + dashboardId = dashboardId, deviceIdAndPackageName = deviceIdAndPackageName, ).flowOn(dispatcherProvider.data) override suspend fun selectDashboardArrangement( + dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, arrangement: DashboardArrangementDomainModel ) { withContext(dispatcherProvider.data) { deviceDashboardsDataSource.selectDashboardArrangement( + dashboardId = dashboardId, deviceIdAndPackageName = deviceIdAndPackageName, arrangement = arrangement, ) 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 000be6eaf..f47e1c0b2 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 @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.update class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource { private val selectedDeviceDashboards = MutableStateFlow>(emptyMap()) - private val selectedDashboardArrangements = MutableStateFlow>(emptyMap()) + private val selectedDashboardArrangements = MutableStateFlow>(emptyMap()) override fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = selectedDeviceDashboards .map { it[deviceIdAndPackageName] } @@ -32,16 +32,28 @@ class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource { } } - override fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = selectedDashboardArrangements - .map { it[deviceIdAndPackageName] ?: DashboardArrangementDomainModel.Adaptive } + override fun observeDashboardArrangement(dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = selectedDashboardArrangements + .map { + val dashboardKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName) + it[dashboardKey] ?: DashboardArrangementDomainModel.Adaptive + } .distinctUntilChanged() override fun selectDashboardArrangement( + dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, arrangement: DashboardArrangementDomainModel ) { + val dashboardKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName) selectedDashboardArrangements.update { - it + (deviceIdAndPackageName to arrangement) + it + (dashboardKey to arrangement) } } + + private fun getDashboardArrangementKey( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): String { + return "${deviceIdAndPackageName.packageName}_$dashboardId" + } } 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 87ef927b2..c3bb785be 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 @@ -13,8 +13,16 @@ interface DashboardRepository { fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow fun observeDeviceDashboards(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow> - fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow - suspend fun selectDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, arrangement: DashboardArrangementDomainModel) + fun observeDashboardArrangement( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow + + suspend fun selectDashboardArrangement( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, + arrangement: DashboardArrangementDomainModel + ) suspend fun sendClickEvent( deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, 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 index 7cc85b10f..6612586bb 100644 --- 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 @@ -15,9 +15,17 @@ class ObserveDashboardArrangementUseCase( if (model == null) { flowOf(DashboardArrangementDomainModel.Adaptive) } else { - dashboardRepository.observeDashboardArrangement( - deviceIdAndPackageName = model, - ) + dashboardRepository.observeSelectedDeviceDashboard(deviceIdAndPackageName = model) + .flatMapLatest { dashboardId -> + if (dashboardId == null) { + flowOf(DashboardArrangementDomainModel.Adaptive) + } else { + dashboardRepository.observeDashboardArrangement( + dashboardId = dashboardId, + 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 index 6205ccee5..d9ca25ec6 100644 --- 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 @@ -7,11 +7,14 @@ import io.github.openflocon.domain.device.usecase.GetCurrentDeviceIdAndPackageNa class SelectDashboardArrangementUseCase( private val dashboardRepository: DashboardRepository, private val getCurrentDeviceIdAndPackageNameUseCase: GetCurrentDeviceIdAndPackageNameUseCase, + private val getCurrentDeviceSelectedDashboardUseCase: GetCurrentDeviceSelectedDashboardUseCase, ) { suspend operator fun invoke(arrangement: DashboardArrangementDomainModel) { val current = getCurrentDeviceIdAndPackageNameUseCase() ?: return + val currentSelectedDashboard = getCurrentDeviceSelectedDashboardUseCase() ?: return dashboardRepository.selectDashboardArrangement( + dashboardId = currentSelectedDashboard, deviceIdAndPackageName = current, arrangement = arrangement, ) From e0aea704b2e45c95b4444dc09bcde45e5f923c52 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Sat, 7 Mar 2026 09:52:58 +0000 Subject: [PATCH 2/4] Fix dashboard selection key --- .../datasource/DeviceDashboardsDataSource.kt | 6 ++- .../repository/DashboardRepositoryImpl.kt | 10 ++-- .../DeviceDashboardsDataSourceInMemory.kt | 48 ++++++++++++++----- .../repository/DashboardRepository.kt | 2 +- 4 files changed, 46 insertions(+), 20 deletions(-) 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 1bde4cb6e..623e72e91 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 @@ -7,11 +7,13 @@ import kotlinx.coroutines.flow.Flow interface DeviceDashboardsDataSource { - fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow + fun observeSelectedDeviceDashboard( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow fun selectDeviceDashboard( - deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, ) fun deleteDashboard( 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 bb7148a77..d65c3a5ca 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 @@ -114,18 +114,20 @@ class DashboardRepositoryImpl( } override suspend fun selectDeviceDashboard( - deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, - dashboardId: DashboardId + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel ) { withContext(dispatcherProvider.data) { deviceDashboardsDataSource.selectDeviceDashboard( - deviceIdAndPackageName = deviceIdAndPackageName, dashboardId = dashboardId, + deviceIdAndPackageName = deviceIdAndPackageName, ) } } - override fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = deviceDashboardsDataSource.observeSelectedDeviceDashboard( + override fun observeSelectedDeviceDashboard( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow = deviceDashboardsDataSource.observeSelectedDeviceDashboard( deviceIdAndPackageName = deviceIdAndPackageName, ).flowOn(dispatcherProvider.data) 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 f47e1c0b2..d15a62924 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 @@ -11,31 +11,47 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource { - private val selectedDeviceDashboards = MutableStateFlow>(emptyMap()) + private val selectedDeviceDashboards = MutableStateFlow>(emptyMap()) private val selectedDashboardArrangements = MutableStateFlow>(emptyMap()) - override fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = selectedDeviceDashboards - .map { it[deviceIdAndPackageName] } + override fun observeSelectedDeviceDashboard( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow = selectedDeviceDashboards + .map { + val dashboardKey = getSelectedDashboardKey(deviceIdAndPackageName) + it[dashboardKey] + } .distinctUntilChanged() - override fun selectDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId) { + override fun selectDeviceDashboard( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ) { + val dashboardKey = getSelectedDashboardKey(deviceIdAndPackageName) selectedDeviceDashboards.update { - it + (deviceIdAndPackageName to dashboardId) + it + (dashboardKey to dashboardId) } } - override fun deleteDashboard(dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel) { + override fun deleteDashboard( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ) { + val dashboardKey = getSelectedDashboardKey(deviceIdAndPackageName) selectedDeviceDashboards.update { - if (it[deviceIdAndPackageName] == dashboardId) { - it - deviceIdAndPackageName + if (it[dashboardKey] == dashboardId) { + it - dashboardKey } else it } } - override fun observeDashboardArrangement(dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow = selectedDashboardArrangements + override fun observeDashboardArrangement( + dashboardId: DashboardId, + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): Flow = selectedDashboardArrangements .map { - val dashboardKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName) - it[dashboardKey] ?: DashboardArrangementDomainModel.Adaptive + val dashboardArrangementKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName) + it[dashboardArrangementKey] ?: DashboardArrangementDomainModel.Adaptive } .distinctUntilChanged() @@ -44,12 +60,18 @@ class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource { deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, arrangement: DashboardArrangementDomainModel ) { - val dashboardKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName) + val dashboardArrangementKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName) selectedDashboardArrangements.update { - it + (dashboardKey to arrangement) + it + (dashboardArrangementKey to arrangement) } } + private fun getSelectedDashboardKey( + deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel + ): String { + return deviceIdAndPackageName.packageName + } + private fun getDashboardArrangementKey( dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel 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 c3bb785be..a24a650af 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 @@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.Flow interface DashboardRepository { fun observeDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId): Flow - suspend fun selectDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId) + suspend fun selectDeviceDashboard(dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel) fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow fun observeDeviceDashboards(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow> From 9e7e36840157ce917f1232cd19b31f9187c3c4d9 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Sat, 7 Mar 2026 10:18:00 +0000 Subject: [PATCH 3/4] Fix dashboard list jumping --- .../dashboard/delegate/DashboardSelectorDelegate.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt index 6e6cef9a4..57abbc436 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt @@ -33,12 +33,14 @@ class DashboardSelectorDelegate( if (dashboards.isEmpty()) { DashboardsStateUiModel.Empty } else { + val sortedDashboards = dashboards.sortedBy { it } + DashboardsStateUiModel.WithContent( - dashboards = dashboards.map { toUi(it) }, + dashboards = sortedDashboards.map { toUi(it) }, selected = toUi( selected ?: run { - dashboards.first().also { + sortedDashboards.first().also { selectCurrentDeviceDashboardUseCase(it) } }, From cd7f04709bacc8dd2dbf88d133a067946a8915d3 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Sat, 7 Mar 2026 11:03:32 +0000 Subject: [PATCH 4/4] Change toUi to extension function --- .../delegate/DashboardSelectorDelegate.kt | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt index 57abbc436..8d1db4cdb 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/dashboard/delegate/DashboardSelectorDelegate.kt @@ -36,15 +36,13 @@ class DashboardSelectorDelegate( val sortedDashboards = dashboards.sortedBy { it } DashboardsStateUiModel.WithContent( - dashboards = sortedDashboards.map { toUi(it) }, - selected = - toUi( - selected ?: run { - sortedDashboards.first().also { - selectCurrentDeviceDashboardUseCase(it) - } - }, - ), + dashboards = sortedDashboards.map { it.toUi() }, + selected = selected?.toUi() ?: run { + sortedDashboards.first().let { + selectCurrentDeviceDashboardUseCase(it) + it.toUi() + } + }, ) } }.flowOn(dispatcherProvider.viewModel) @@ -54,8 +52,8 @@ class DashboardSelectorDelegate( DashboardsStateUiModel.Loading, ) - fun toUi(dashboardId: DashboardId) = DeviceDashboardUiModel( - id = dashboardId, + fun DashboardId.toUi() = DeviceDashboardUiModel( + id = this, ) fun onDashboardSelected(dashboardId: DashboardId) {