Several dashboard fixes (#508)

This commit is contained in:
Sebastian Neubauer 2026-03-09 09:10:22 +01:00 committed by GitHub
parent 7a0c65fab0
commit b3cd442ae2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 104 additions and 37 deletions

View file

@ -33,16 +33,16 @@ class DashboardSelectorDelegate(
if (dashboards.isEmpty()) {
DashboardsStateUiModel.Empty
} else {
val sortedDashboards = dashboards.sortedBy { it }
DashboardsStateUiModel.WithContent(
dashboards = dashboards.map { toUi(it) },
selected =
toUi(
selected ?: run {
dashboards.first().also {
selectCurrentDeviceDashboardUseCase(it)
}
},
),
dashboards = sortedDashboards.map { it.toUi() },
selected = selected?.toUi() ?: run {
sortedDashboards.first().let {
selectCurrentDeviceDashboardUseCase(it)
it.toUi()
}
},
)
}
}.flowOn(dispatcherProvider.viewModel)
@ -52,8 +52,8 @@ class DashboardSelectorDelegate(
DashboardsStateUiModel.Loading,
)
fun toUi(dashboardId: DashboardId) = DeviceDashboardUiModel(
id = dashboardId,
fun DashboardId.toUi() = DeviceDashboardUiModel(
id = this,
)
fun onDashboardSelected(dashboardId: DashboardId) {

View file

@ -7,11 +7,13 @@ import kotlinx.coroutines.flow.Flow
interface DeviceDashboardsDataSource {
fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardId?>
fun observeSelectedDeviceDashboard(
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardId?>
fun selectDeviceDashboard(
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel,
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel,
)
fun deleteDashboard(
@ -19,9 +21,13 @@ interface DeviceDashboardsDataSource {
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
)
fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardArrangementDomainModel>
fun observeDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardArrangementDomainModel>
fun selectDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel,
arrangement: DashboardArrangementDomainModel,
)

View file

@ -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<DashboardId?> = deviceDashboardsDataSource.observeSelectedDeviceDashboard(
override fun observeSelectedDeviceDashboard(
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardId?> = deviceDashboardsDataSource.observeSelectedDeviceDashboard(
deviceIdAndPackageName = deviceIdAndPackageName,
).flowOn(dispatcherProvider.data)
@ -133,16 +135,22 @@ class DashboardRepositoryImpl(
deviceIdAndPackageName = deviceIdAndPackageName,
).flowOn(dispatcherProvider.data)
override fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardArrangementDomainModel> = deviceDashboardsDataSource.observeDashboardArrangement(
override fun observeDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardArrangementDomainModel> = 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,
)

View file

@ -11,37 +11,71 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
class DeviceDashboardsDataSourceInMemory : DeviceDashboardsDataSource {
private val selectedDeviceDashboards = MutableStateFlow<Map<DeviceIdAndPackageNameDomainModel, DashboardId?>>(emptyMap())
private val selectedDashboardArrangements = MutableStateFlow<Map<DeviceIdAndPackageNameDomainModel, DashboardArrangementDomainModel>>(emptyMap())
private val selectedDeviceDashboards = MutableStateFlow<Map<String, DashboardId?>>(emptyMap())
private val selectedDashboardArrangements = MutableStateFlow<Map<String, DashboardArrangementDomainModel>>(emptyMap())
override fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardId?> = selectedDeviceDashboards
.map { it[deviceIdAndPackageName] }
override fun observeSelectedDeviceDashboard(
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardId?> = 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(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardArrangementDomainModel> = selectedDashboardArrangements
.map { it[deviceIdAndPackageName] ?: DashboardArrangementDomainModel.Adaptive }
override fun observeDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardArrangementDomainModel> = selectedDashboardArrangements
.map {
val dashboardArrangementKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName)
it[dashboardArrangementKey] ?: DashboardArrangementDomainModel.Adaptive
}
.distinctUntilChanged()
override fun selectDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel,
arrangement: DashboardArrangementDomainModel
) {
val dashboardArrangementKey = getDashboardArrangementKey(dashboardId, deviceIdAndPackageName)
selectedDashboardArrangements.update {
it + (deviceIdAndPackageName to arrangement)
it + (dashboardArrangementKey to arrangement)
}
}
private fun getSelectedDashboardKey(
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): String {
return deviceIdAndPackageName.packageName
}
private fun getDashboardArrangementKey(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): String {
return "${deviceIdAndPackageName.packageName}_$dashboardId"
}
}

View file

@ -9,12 +9,20 @@ import kotlinx.coroutines.flow.Flow
interface DashboardRepository {
fun observeDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId): Flow<DashboardDomainModel?>
suspend fun selectDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, dashboardId: DashboardId)
suspend fun selectDeviceDashboard(dashboardId: DashboardId, deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel)
fun observeSelectedDeviceDashboard(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardId?>
fun observeDeviceDashboards(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<List<DashboardId>>
fun observeDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel): Flow<DashboardArrangementDomainModel>
suspend fun selectDashboardArrangement(deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel, arrangement: DashboardArrangementDomainModel)
fun observeDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel
): Flow<DashboardArrangementDomainModel>
suspend fun selectDashboardArrangement(
dashboardId: DashboardId,
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel,
arrangement: DashboardArrangementDomainModel
)
suspend fun sendClickEvent(
deviceIdAndPackageName: DeviceIdAndPackageNameDomainModel,

View file

@ -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,
)
}
}
}
}
}

View file

@ -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,
)