diff --git a/FloconDesktop/composeApp/schemas/io.github.openflocon.flocondesktop.common.db.AppDatabase/27.json b/FloconDesktop/composeApp/schemas/io.github.openflocon.flocondesktop.common.db.AppDatabase/27.json index a0535955..1abd1131 100644 --- a/FloconDesktop/composeApp/schemas/io.github.openflocon.flocondesktop.common.db.AppDatabase/27.json +++ b/FloconDesktop/composeApp/schemas/io.github.openflocon.flocondesktop.common.db.AppDatabase/27.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 27, - "identityHash": "6602c9e782a66f200b014ac2cfb4ef99", + "identityHash": "2064d08d969f8275c5f4dea45aa8505a", "entities": [ { "tableName": "FloconHttpRequestEntity", @@ -764,11 +764,48 @@ "createSql": "CREATE INDEX IF NOT EXISTS `index_AnalyticsItemEntity_deviceId_analyticsTableId` ON `${TABLE_NAME}` (`deviceId`, `analyticsTableId`)" } ] + }, + { + "tableName": "network_filter", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`deviceId` TEXT NOT NULL, `columnName` TEXT NOT NULL, `isEnabled` INTEGER NOT NULL, `itemsAsJson` TEXT NOT NULL, PRIMARY KEY(`deviceId`, `columnName`))", + "fields": [ + { + "fieldPath": "deviceId", + "columnName": "deviceId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "columnName", + "columnName": "columnName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isEnabled", + "columnName": "isEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "itemsAsJson", + "columnName": "itemsAsJson", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "deviceId", + "columnName" + ] + } } ], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6602c9e782a66f200b014ac2cfb4ef99')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2064d08d969f8275c5f4dea45aa8505a')" ] } } \ No newline at end of file diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt index c6112131..0858485b 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/AppDatabase.kt @@ -21,14 +21,16 @@ import io.github.openflocon.flocondesktop.features.files.data.datasources.model. import io.github.openflocon.flocondesktop.features.images.data.datasources.local.FloconImageDao import io.github.openflocon.flocondesktop.features.images.data.datasources.local.model.DeviceImageEntity import io.github.openflocon.flocondesktop.features.network.data.datasource.local.FloconHttpRequestDao +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.NetworkFilterDao import io.github.openflocon.flocondesktop.features.network.data.datasource.local.model.FloconHttpRequestEntity +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.model.NetworkFilterEntity import io.github.openflocon.flocondesktop.features.table.data.datasource.local.FloconTableDao import io.github.openflocon.flocondesktop.features.table.data.datasource.local.model.TableEntity import io.github.openflocon.flocondesktop.features.table.data.datasource.local.model.TableItemEntity import kotlinx.coroutines.Dispatchers @Database( - version = 27, + version = 28, entities = [ FloconHttpRequestEntity::class, FileEntity::class, @@ -41,6 +43,7 @@ import kotlinx.coroutines.Dispatchers SuccessQueryEntity::class, DeeplinkEntity::class, AnalyticsItemEntity::class, + NetworkFilterEntity::class, ], ) @TypeConverters( @@ -56,6 +59,7 @@ abstract class AppDatabase : RoomDatabase() { abstract val queryDao: QueryDao abstract val deeplinkDao: FloconDeeplinkDao abstract val analyticsDao: FloconAnalyticsDao + abstract val networkFilterDao: NetworkFilterDao } fun getRoomDatabase(): AppDatabase = getDatabaseBuilder() diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt index c1bf0bc9..e465b9e4 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/common/db/RoomModule.kt @@ -31,4 +31,7 @@ val roomModule = single { get().analyticsDao } + single { + get().networkFilterDao + } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkFilterRepositoryImpl.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkFilterRepositoryImpl.kt new file mode 100644 index 00000000..87f5ff57 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/NetworkFilterRepositoryImpl.kt @@ -0,0 +1,41 @@ +package io.github.openflocon.flocondesktop.features.network.data + +import io.github.openflocon.flocondesktop.DeviceId +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.NetworkFilterLocalDataSource +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkFilterRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged + +class NetworkFilterRepositoryImpl( + private val networkFilterLocalDataSource: NetworkFilterLocalDataSource, +) : NetworkFilterRepository { + override suspend fun get( + deviceId: DeviceId, + column: NetworkTextFilterColumns, + ): TextFilterStateDomainModel? { + return networkFilterLocalDataSource.get( + deviceId = deviceId, + column = column, + ) + } + + override fun observe(deviceId: DeviceId): Flow> { + return networkFilterLocalDataSource.observe( + deviceId = deviceId, + ).distinctUntilChanged() + } + + override suspend fun update( + deviceId: DeviceId, + column: NetworkTextFilterColumns, + newValue: TextFilterStateDomainModel + ) { + return networkFilterLocalDataSource.update( + deviceId = deviceId, + column = column, + newValue = newValue, + ) + } +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterDao.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterDao.kt new file mode 100644 index 00000000..30164c32 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterDao.kt @@ -0,0 +1,21 @@ +package io.github.openflocon.flocondesktop.features.network.data.datasource.local + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.model.NetworkFilterEntity +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import kotlinx.coroutines.flow.Flow + +@Dao +interface NetworkFilterDao { + @Query("SELECT * FROM network_filter WHERE deviceId = :deviceId AND columnName = :column") + suspend fun get(deviceId: String, column: NetworkTextFilterColumns): NetworkFilterEntity? + + @Query("SELECT * FROM network_filter WHERE deviceId = :deviceId") + fun observe(deviceId: String): Flow> + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrUpdate(entity: NetworkFilterEntity) +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterLocalDataSource.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterLocalDataSource.kt new file mode 100644 index 00000000..79ec811f --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterLocalDataSource.kt @@ -0,0 +1,20 @@ +package io.github.openflocon.flocondesktop.features.network.data.datasource.local + +import io.github.openflocon.flocondesktop.DeviceId +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import kotlinx.coroutines.flow.Flow + +interface NetworkFilterLocalDataSource { + suspend fun get( + deviceId: DeviceId, + column: NetworkTextFilterColumns + ): TextFilterStateDomainModel? + + fun observe(deviceId: DeviceId): Flow> + suspend fun update( + deviceId: DeviceId, + column: NetworkTextFilterColumns, + newValue: TextFilterStateDomainModel + ) +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterLocalDataSourceRoom.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterLocalDataSourceRoom.kt new file mode 100644 index 00000000..1b3f2fd1 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/NetworkFilterLocalDataSourceRoom.kt @@ -0,0 +1,54 @@ +package io.github.openflocon.flocondesktop.features.network.data.datasource.local + +import io.github.openflocon.flocondesktop.DeviceId +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.mapper.textFilterToDomain +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.mapper.textFilterToEntity +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.model.NetworkFilterEntity +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json + + +class NetworkFilterLocalDataSourceRoom( + private val networkFilterDao: NetworkFilterDao, +) : NetworkFilterLocalDataSource { + + override suspend fun get( + deviceId: DeviceId, + column: NetworkTextFilterColumns + ): TextFilterStateDomainModel? { + return networkFilterDao.get( + deviceId = deviceId, + column = column, + )?.let { + textFilterToDomain(it) + } + } + + override fun observe(deviceId: DeviceId): Flow> { + return networkFilterDao.observe( + deviceId = deviceId, + ).map { + it.associate { + it.columnName to textFilterToDomain(it) + } + } + } + + override suspend fun update( + deviceId: DeviceId, + column: NetworkTextFilterColumns, + newValue: TextFilterStateDomainModel + ) { + networkFilterDao.insertOrUpdate( + textFilterToEntity( + deviceId = deviceId, + column = column, + domain = newValue, + ) + ) + } +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/FilterMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/FilterMapper.kt new file mode 100644 index 00000000..fc563b1f --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/mapper/FilterMapper.kt @@ -0,0 +1,54 @@ +package io.github.openflocon.flocondesktop.features.network.data.datasource.local.mapper + +import io.github.openflocon.flocondesktop.DeviceId +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.model.FilterItemSavedEntity +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.model.NetworkFilterEntity +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import kotlinx.serialization.json.Json + + +fun textFilterItemToEntity(item: TextFilterStateDomainModel.FilterItem): FilterItemSavedEntity { + return FilterItemSavedEntity( + text = item.text, + isActive = item.isActive, + isExcluded = item.isExcluded, + ) +} + +fun textFilterItemToDomain(item: FilterItemSavedEntity): TextFilterStateDomainModel.FilterItem { + return TextFilterStateDomainModel.FilterItem( + text = item.text, + isActive = item.isActive, + isExcluded = item.isExcluded, + ) +} + +fun textFilterToEntity( + deviceId: DeviceId, + column: NetworkTextFilterColumns, + domain: TextFilterStateDomainModel +): NetworkFilterEntity { + val itemsEntity: List = domain.items.map { + textFilterItemToEntity(it) + } + return NetworkFilterEntity( + deviceId = deviceId, + columnName = column, + isEnabled = domain.isEnabled, + itemsAsJson = Json.encodeToString(itemsEntity) + ) +} + + +fun textFilterToDomain( + entity: NetworkFilterEntity +): TextFilterStateDomainModel { + val itemsEntity = Json.decodeFromString>(entity.itemsAsJson) + return TextFilterStateDomainModel( + isEnabled = entity.isEnabled, + items = itemsEntity.map { + textFilterItemToDomain(it) + } + ) +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FilterItemSavedEntity.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FilterItemSavedEntity.kt new file mode 100644 index 00000000..338bbbaa --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/FilterItemSavedEntity.kt @@ -0,0 +1,10 @@ +package io.github.openflocon.flocondesktop.features.network.data.datasource.local.model + +import kotlinx.serialization.Serializable + +@Serializable +data class FilterItemSavedEntity( + val text: String, + val isActive: Boolean, + val isExcluded: Boolean, +) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/NetworkFilterEntity.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/NetworkFilterEntity.kt new file mode 100644 index 00000000..9febef0a --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/datasource/local/model/NetworkFilterEntity.kt @@ -0,0 +1,17 @@ +package io.github.openflocon.flocondesktop.features.network.data.datasource.local.model + +import androidx.room.Entity +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns + +@Entity( + tableName = "network_filter", + primaryKeys = [ + "deviceId", "columnName" + ] +) +data class NetworkFilterEntity( + val deviceId: String, + val columnName: NetworkTextFilterColumns, + val isEnabled: Boolean, + val itemsAsJson: String, +) diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/di/NetworkDataModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/di/NetworkDataModule.kt index 531008bb..3932153d 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/di/NetworkDataModule.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/data/di/NetworkDataModule.kt @@ -1,8 +1,12 @@ package io.github.openflocon.flocondesktop.features.network.data.di +import io.github.openflocon.flocondesktop.features.network.data.NetworkFilterRepositoryImpl import io.github.openflocon.flocondesktop.features.network.data.NetworkRepositoryImpl +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.NetworkFilterLocalDataSource +import io.github.openflocon.flocondesktop.features.network.data.datasource.local.NetworkFilterLocalDataSourceRoom import io.github.openflocon.flocondesktop.features.network.data.datasource.local.NetworkLocalDataSource import io.github.openflocon.flocondesktop.features.network.data.datasource.local.NetworkLocalDataSourceRoom +import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkFilterRepository import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkRepository import io.github.openflocon.flocondesktop.messages.domain.repository.sub.MessagesReceiverRepository import org.koin.core.module.dsl.bind @@ -18,4 +22,10 @@ val networkDataModule = singleOf(::NetworkLocalDataSourceRoom) { bind() } + singleOf(::NetworkFilterRepositoryImpl) { + bind() + } + singleOf(::NetworkFilterLocalDataSourceRoom) { + bind() + } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/di/NetworkDomainModule.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/di/NetworkDomainModule.kt index d8eaa249..27be236b 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/di/NetworkDomainModule.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/di/NetworkDomainModule.kt @@ -6,6 +6,9 @@ import io.github.openflocon.flocondesktop.features.network.domain.ObserveHttpReq import io.github.openflocon.flocondesktop.features.network.domain.RemoveHttpRequestUseCase import io.github.openflocon.flocondesktop.features.network.domain.RemoveHttpRequestsBeforeUseCase import io.github.openflocon.flocondesktop.features.network.domain.ResetCurrentDeviceHttpRequestsUseCase +import io.github.openflocon.flocondesktop.features.network.domain.filter.GetNetworkFilterUseCase +import io.github.openflocon.flocondesktop.features.network.domain.filter.ObserveNetworkFilterUseCase +import io.github.openflocon.flocondesktop.features.network.domain.filter.UpdateNetworkFilterUseCase import org.koin.core.module.dsl.factoryOf import org.koin.dsl.module @@ -17,4 +20,7 @@ val networkDomainModule = factoryOf(::ResetCurrentDeviceHttpRequestsUseCase) factoryOf(::RemoveHttpRequestsBeforeUseCase) factoryOf(::RemoveHttpRequestUseCase) + factoryOf(::GetNetworkFilterUseCase) + factoryOf(::ObserveNetworkFilterUseCase) + factoryOf(::UpdateNetworkFilterUseCase) } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/GetNetworkFilterUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/GetNetworkFilterUseCase.kt new file mode 100644 index 00000000..48d7a6a0 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/GetNetworkFilterUseCase.kt @@ -0,0 +1,20 @@ +package io.github.openflocon.flocondesktop.features.network.domain.filter + +import io.github.openflocon.flocondesktop.core.domain.device.GetCurrentDeviceIdUseCase +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkFilterRepository + +class GetNetworkFilterUseCase( + private val getCurrentDeviceIdUseCase: GetCurrentDeviceIdUseCase, + private val networkFilterRepository: NetworkFilterRepository, +) { + suspend operator fun invoke(column: NetworkTextFilterColumns): TextFilterStateDomainModel { + return getCurrentDeviceIdUseCase()?.let { deviceId -> + networkFilterRepository.get(deviceId = deviceId, column = column) + } ?: TextFilterStateDomainModel( + items = listOf(), + isEnabled = true, + ) + } +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/ObserveNetworkFilterUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/ObserveNetworkFilterUseCase.kt new file mode 100644 index 00000000..c5ef9774 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/ObserveNetworkFilterUseCase.kt @@ -0,0 +1,22 @@ +package io.github.openflocon.flocondesktop.features.network.domain.filter + +import io.github.openflocon.flocondesktop.core.domain.device.ObserveCurrentDeviceIdUseCase +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkFilterRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf + +class ObserveNetworkFilterUseCase( + private val observeCurrentDeviceIdUseCase: ObserveCurrentDeviceIdUseCase, + private val networkFilterRepository: NetworkFilterRepository, +) { + operator fun invoke(): Flow> { + return observeCurrentDeviceIdUseCase().flatMapLatest { deviceId -> + if (deviceId == null) flowOf(emptyMap()) + else networkFilterRepository.observe(deviceId = deviceId) + }.distinctUntilChanged() + } +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/UpdateNetworkFilterUseCase.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/UpdateNetworkFilterUseCase.kt new file mode 100644 index 00000000..868e45e0 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/filter/UpdateNetworkFilterUseCase.kt @@ -0,0 +1,24 @@ +package io.github.openflocon.flocondesktop.features.network.domain.filter + +import io.github.openflocon.flocondesktop.core.domain.device.GetCurrentDeviceIdUseCase +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import io.github.openflocon.flocondesktop.features.network.domain.repository.NetworkFilterRepository + +class UpdateNetworkFilterUseCase( + private val getCurrentDeviceIdUseCase: GetCurrentDeviceIdUseCase, + private val networkFilterRepository: NetworkFilterRepository, +) { + suspend operator fun invoke( + column: NetworkTextFilterColumns, + newValue: TextFilterStateDomainModel + ) { + getCurrentDeviceIdUseCase()?.let { deviceId -> + networkFilterRepository.update( + deviceId = deviceId, + column = column, + newValue = newValue + ) + } + } +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/NetworkTextFilterColumns.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/NetworkTextFilterColumns.kt new file mode 100644 index 00000000..d38205b9 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/NetworkTextFilterColumns.kt @@ -0,0 +1,9 @@ +package io.github.openflocon.flocondesktop.features.network.domain.model + +enum class NetworkTextFilterColumns { + RequestTime, + Domain, + Query, + Status, + Time, +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/TextFilterStateDomainModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/TextFilterStateDomainModel.kt new file mode 100644 index 00000000..2c6964c1 --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/model/TextFilterStateDomainModel.kt @@ -0,0 +1,12 @@ +package io.github.openflocon.flocondesktop.features.network.domain.model + +data class TextFilterStateDomainModel( + val items: List, + val isEnabled: Boolean, +) { + data class FilterItem( + val text: String, + val isActive: Boolean, + val isExcluded: Boolean, + ) +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/repository/NetworkFilterRepository.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/repository/NetworkFilterRepository.kt new file mode 100644 index 00000000..ae9052bc --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/domain/repository/NetworkFilterRepository.kt @@ -0,0 +1,20 @@ +package io.github.openflocon.flocondesktop.features.network.domain.repository + +import io.github.openflocon.flocondesktop.DeviceId +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import kotlinx.coroutines.flow.Flow + +interface NetworkFilterRepository { + suspend fun get( + deviceId: DeviceId, + column: NetworkTextFilterColumns + ): TextFilterStateDomainModel? + + fun observe(deviceId: DeviceId): Flow> + suspend fun update( + deviceId: DeviceId, + column: NetworkTextFilterColumns, + newValue: TextFilterStateDomainModel + ) +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/SortAndFilterNetworkItemsProcessor.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/SortAndFilterNetworkItemsProcessor.kt index ad0dc2e8..62cfd918 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/SortAndFilterNetworkItemsProcessor.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/SortAndFilterNetworkItemsProcessor.kt @@ -1,13 +1,13 @@ package io.github.openflocon.flocondesktop.features.network.ui import io.github.openflocon.flocondesktop.features.network.domain.model.FloconHttpRequestDomainModel +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns import io.github.openflocon.flocondesktop.features.network.ui.delegate.HeaderDelegate import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkItemViewState import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkMethodUi import io.github.openflocon.flocondesktop.features.network.ui.model.SortedByUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.NetworkColumnsTypeUiModel -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterColumns -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel class SortAndFilterNetworkItemsProcessor { operator fun invoke( @@ -15,7 +15,7 @@ class SortAndFilterNetworkItemsProcessor { filterState: FilterUiState, sorted: HeaderDelegate.Sorted?, allowedMethods: List, - textFilters: Map, + textFilters: Map, ): List { return items.asSequence() .filter { item -> @@ -62,8 +62,8 @@ private fun sort( return sequence.sortedWith(sortedComparator) } -private fun TextFilterState.filter( - column: TextFilterColumns, +private fun TextFilterStateUiModel.filter( + column: NetworkTextFilterColumns, items: List> ): List> { return items.filter { item -> @@ -71,21 +71,21 @@ private fun TextFilterState.filter( } } -private fun TextFilterState.filter( - column: TextFilterColumns, +private fun TextFilterStateUiModel.filter( + column: NetworkTextFilterColumns, item: Pair ): Boolean { val text = when (column) { - TextFilterColumns.RequestTime -> item.second.dateFormatted - TextFilterColumns.Domain -> item.second.domain - TextFilterColumns.Query -> item.second.type.text - TextFilterColumns.Status -> item.second.status.text - TextFilterColumns.Time -> item.second.timeFormatted + NetworkTextFilterColumns.RequestTime -> item.second.dateFormatted + NetworkTextFilterColumns.Domain -> item.second.domain + NetworkTextFilterColumns.Query -> item.second.type.text + NetworkTextFilterColumns.Status -> item.second.status.text + NetworkTextFilterColumns.Time -> item.second.timeFormatted } return filterByText(text) } -private fun TextFilterState.filterByText(text: String): Boolean { +private fun TextFilterStateUiModel.filterByText(text: String): Boolean { for (filter in this.allFilters) { if (!filter.filterByText(text)) return false @@ -94,7 +94,7 @@ private fun TextFilterState.filterByText(text: String): Boolean { return true } -private fun TextFilterState.FilterItem.filterByText(text: String): Boolean { +private fun TextFilterStateUiModel.FilterItem.filterByText(text: String): Boolean { if (!this.isActive) return true diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/delegate/HeaderDelegate.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/delegate/HeaderDelegate.kt index 7a137fa0..e516efb4 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/delegate/HeaderDelegate.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/delegate/HeaderDelegate.kt @@ -3,6 +3,12 @@ package io.github.openflocon.flocondesktop.features.network.ui.delegate import io.github.openflocon.flocondesktop.common.coroutines.closeable.CloseableDelegate import io.github.openflocon.flocondesktop.common.coroutines.closeable.CloseableScoped import io.github.openflocon.flocondesktop.common.coroutines.dispatcherprovider.DispatcherProvider +import io.github.openflocon.flocondesktop.features.network.domain.filter.GetNetworkFilterUseCase +import io.github.openflocon.flocondesktop.features.network.domain.filter.ObserveNetworkFilterUseCase +import io.github.openflocon.flocondesktop.features.network.domain.filter.UpdateNetworkFilterUseCase +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns +import io.github.openflocon.flocondesktop.features.network.ui.mapper.toTextFilterDomain +import io.github.openflocon.flocondesktop.features.network.ui.mapper.toTextFilterUi import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkMethodUi import io.github.openflocon.flocondesktop.features.network.ui.model.SortedByUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.NetworkHeaderUiState @@ -13,20 +19,25 @@ import io.github.openflocon.flocondesktop.features.network.ui.model.header.colum import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.NetworkStatusColumnUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.NetworkTextColumnUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.MethodFilterState -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterColumns -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + class HeaderDelegate( private val closeableDelegate: CloseableDelegate, dispatcherProvider: DispatcherProvider, + private val observeNetworkFilterUseCase: ObserveNetworkFilterUseCase, + private val updateNetworkFilterUseCase: UpdateNetworkFilterUseCase, + private val getNetworkFilterUseCase: GetNetworkFilterUseCase, ) : CloseableScoped by closeableDelegate { data class Sorted( @@ -34,7 +45,9 @@ class HeaderDelegate( val sort: SortedByUiModel.Enabled, ) - val textFiltersState = MutableStateFlow>(emptyMap()) + val textFiltersState: StateFlow> = observeNetworkFilterUseCase() + .map { it.mapValues { (key, value) -> toTextFilterUi(value) } } + .stateIn(coroutineScope, started = SharingStarted.WhileSubscribed(5_000), emptyMap()) val sorted = MutableStateFlow(null) private val methodFilterState = MutableStateFlow( @@ -76,13 +89,14 @@ class HeaderDelegate( fun buildHeaderValue( sorted: Sorted?, methodFilterState: MethodFilterState, - textFiltersState: Map, + textFiltersState: Map, ): NetworkHeaderUiState { return NetworkHeaderUiState( requestTime = NetworkTextColumnUiModel( sortedBy = sorted?.takeIf { it.column == NetworkColumnsTypeUiModel.RequestTime }?.sort ?: SortedByUiModel.None, - filter = textFiltersState[TextFilterColumns.RequestTime] ?: TextFilterState.EMPTY, + filter = textFiltersState[NetworkTextFilterColumns.RequestTime] + ?: TextFilterStateUiModel.EMPTY, ), method = NetworkMethodColumnUiModel( sortedBy = sorted?.takeIf { it.column == NetworkColumnsTypeUiModel.Method }?.sort @@ -92,22 +106,22 @@ class HeaderDelegate( domain = NetworkTextColumnUiModel( sortedBy = sorted?.takeIf { it.column == NetworkColumnsTypeUiModel.Domain }?.sort ?: SortedByUiModel.None, - filter = textFiltersState[TextFilterColumns.Domain] ?: TextFilterState.EMPTY, + filter = textFiltersState[NetworkTextFilterColumns.Domain] ?: TextFilterStateUiModel.EMPTY, ), query = NetworkTextColumnUiModel( sortedBy = sorted?.takeIf { it.column == NetworkColumnsTypeUiModel.Query }?.sort ?: SortedByUiModel.None, - filter = textFiltersState[TextFilterColumns.Query] ?: TextFilterState.EMPTY, + filter = textFiltersState[NetworkTextFilterColumns.Query] ?: TextFilterStateUiModel.EMPTY, ), status = NetworkStatusColumnUiModel( sortedBy = sorted?.takeIf { it.column == NetworkColumnsTypeUiModel.Status }?.sort ?: SortedByUiModel.None, - filter = textFiltersState[TextFilterColumns.Status] ?: TextFilterState.EMPTY, + filter = textFiltersState[NetworkTextFilterColumns.Status] ?: TextFilterStateUiModel.EMPTY, ), time = NetworkTextColumnUiModel( sortedBy = sorted?.takeIf { it.column == NetworkColumnsTypeUiModel.Time }?.sort ?: SortedByUiModel.None, - filter = textFiltersState[TextFilterColumns.Time] ?: TextFilterState.EMPTY, + filter = textFiltersState[NetworkTextFilterColumns.Time] ?: TextFilterStateUiModel.EMPTY, ), ) } @@ -139,42 +153,44 @@ class HeaderDelegate( } fun onFilterAction(action: OnFilterAction) { - when (action) { - is OnFilterAction.ClickOnMethod -> { - val clicked = action.methodUi - methodFilterState.update { - it.copy(items = it.items.map { item -> - if (item.method == clicked) { - item.copy(isSelected = !item.isSelected) - } else item - }) + coroutineScope.launch { + when (action) { + is OnFilterAction.ClickOnMethod -> { + val clicked = action.methodUi + methodFilterState.update { + it.copy(items = it.items.map { item -> + if (item.method == clicked) { + item.copy(isSelected = !item.isSelected) + } else item + }) + } } - } - is OnFilterAction.TextFilter -> { - textFilterAction(column = action.column, action = action.action) + is OnFilterAction.TextFilter -> { + textFilterAction(column = action.column, action = action.action) + } } } } - private fun textFilterAction(column: TextFilterColumns, action: TextFilterAction) { - val filter = textFiltersState.value[column] ?: TextFilterState( - includedFilters = listOf(), - excludedFilters = listOf(), - isEnabled = true, - ) + private suspend fun textFilterAction( + column: NetworkTextFilterColumns, + action: TextFilterAction + ) { + val filter: TextFilterStateUiModel = getNetworkFilterUseCase(column).let { toTextFilterUi(it) } val updated = parformAction(filter, action) - textFiltersState.update { - it + Pair(column, updated) - } + updateNetworkFilterUseCase( + column = column, + newValue = toTextFilterDomain(updated) + ) } } private fun parformAction( - filter: TextFilterState, + filter: TextFilterStateUiModel, action: TextFilterAction -): TextFilterState { +): TextFilterStateUiModel { return when (action) { is TextFilterAction.Delete -> { filter.copy( @@ -185,7 +201,7 @@ private fun parformAction( is TextFilterAction.Exclude -> { filter.copy( - excludedFilters = (filter.excludedFilters + TextFilterState.FilterItem( + excludedFilters = (filter.excludedFilters + TextFilterStateUiModel.FilterItem( text = action.text, isActive = true, isExcluded = true @@ -195,7 +211,7 @@ private fun parformAction( is TextFilterAction.Include -> { filter.copy( - includedFilters = (filter.includedFilters + TextFilterState.FilterItem( + includedFilters = (filter.includedFilters + TextFilterStateUiModel.FilterItem( text = action.text, isActive = true, isExcluded = false diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/FilterMapper.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/FilterMapper.kt new file mode 100644 index 00000000..c3d4b6bd --- /dev/null +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/mapper/FilterMapper.kt @@ -0,0 +1,35 @@ +package io.github.openflocon.flocondesktop.features.network.ui.mapper + +import io.github.openflocon.flocondesktop.features.network.domain.model.TextFilterStateDomainModel +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel + +fun toTextFilterUi(textFilter: TextFilterStateDomainModel) : TextFilterStateUiModel { + return TextFilterStateUiModel( + includedFilters = textFilter.items.filter { it.isExcluded.not() }.map { itemToUI(it) }, + excludedFilters = textFilter.items.filter { it.isExcluded }.map { itemToUI(it) }, + isEnabled = textFilter.isEnabled + ) +} + +fun toTextFilterDomain(textFilter: TextFilterStateUiModel) : TextFilterStateDomainModel { + return TextFilterStateDomainModel( + items = textFilter.allFilters.map { itemToDomain(it) }, + isEnabled = textFilter.isEnabled, + ) +} + +fun itemToDomain(item: TextFilterStateUiModel.FilterItem): TextFilterStateDomainModel.FilterItem { + return TextFilterStateDomainModel.FilterItem( + text = item.text, + isActive = item.isActive, + isExcluded = item.isExcluded + ) +} + +fun itemToUI(item: TextFilterStateDomainModel.FilterItem): TextFilterStateUiModel.FilterItem { + return TextFilterStateUiModel.FilterItem( + text = item.text, + isActive = item.isActive, + isExcluded = item.isExcluded + ) +} diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/OnFilterAction.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/OnFilterAction.kt index dcb4da48..0e5416d2 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/OnFilterAction.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/OnFilterAction.kt @@ -1,9 +1,9 @@ package io.github.openflocon.flocondesktop.features.network.ui.model.header +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns import io.github.openflocon.flocondesktop.features.network.ui.model.NetworkMethodUi -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterColumns sealed interface OnFilterAction { data class ClickOnMethod(val methodUi: NetworkMethodUi) : OnFilterAction - data class TextFilter(val column: TextFilterColumns, val action: TextFilterAction) : OnFilterAction + data class TextFilter(val column: NetworkTextFilterColumns, val action: TextFilterAction) : OnFilterAction } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/TextFilterAction.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/TextFilterAction.kt index b56f1b88..e3788e7b 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/TextFilterAction.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/TextFilterAction.kt @@ -1,10 +1,10 @@ package io.github.openflocon.flocondesktop.features.network.ui.model.header -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel sealed interface TextFilterAction { data class Include(val text: String) : TextFilterAction data class Exclude(val text: String) : TextFilterAction - data class SetIsActive(val item: TextFilterState.FilterItem, val isActive: Boolean) : TextFilterAction - data class Delete(val item: TextFilterState.FilterItem) : TextFilterAction + data class SetIsActive(val item: TextFilterStateUiModel.FilterItem, val isActive: Boolean) : TextFilterAction + data class Delete(val item: TextFilterStateUiModel.FilterItem) : TextFilterAction } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkStatusColumnUiModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkStatusColumnUiModel.kt index 7bc05de8..4af2ea73 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkStatusColumnUiModel.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkStatusColumnUiModel.kt @@ -2,18 +2,18 @@ package io.github.openflocon.flocondesktop.features.network.ui.model.header.colu import androidx.compose.runtime.Immutable import io.github.openflocon.flocondesktop.features.network.ui.model.SortedByUiModel -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.previewTextFilterState @Immutable data class NetworkStatusColumnUiModel( override val sortedBy: SortedByUiModel, - override val filter: TextFilterState, // TODO maybe later a specific filter + override val filter: TextFilterStateUiModel, // TODO maybe later a specific filter ) : NetworkColumnUiModel { companion object { val EMPTY = NetworkStatusColumnUiModel( sortedBy = SortedByUiModel.None, - filter = TextFilterState.EMPTY, + filter = TextFilterStateUiModel.EMPTY, ) } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkTextColumnUiModel.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkTextColumnUiModel.kt index a2a2fdba..afdc2eae 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkTextColumnUiModel.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/NetworkTextColumnUiModel.kt @@ -2,18 +2,18 @@ package io.github.openflocon.flocondesktop.features.network.ui.model.header.colu import androidx.compose.runtime.Immutable import io.github.openflocon.flocondesktop.features.network.ui.model.SortedByUiModel -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.previewTextFilterState @Immutable data class NetworkTextColumnUiModel( override val sortedBy: SortedByUiModel, - override val filter: TextFilterState, + override val filter: TextFilterStateUiModel, ) : NetworkColumnUiModel { companion object { val EMPTY = NetworkTextColumnUiModel( sortedBy = SortedByUiModel.None, - filter = TextFilterState.EMPTY, + filter = TextFilterStateUiModel.EMPTY, ) } } diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/filter/TextFilterState.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/filter/TextFilterStateUiModel.kt similarity index 80% rename from FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/filter/TextFilterState.kt rename to FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/filter/TextFilterStateUiModel.kt index 310592ce..8ed5108b 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/filter/TextFilterState.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/model/header/columns/base/filter/TextFilterStateUiModel.kt @@ -1,19 +1,11 @@ package io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter import androidx.compose.runtime.Immutable -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState.FilterItem - -enum class TextFilterColumns { - RequestTime, - Domain, - Query, - Status, - Time, -} +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel.FilterItem @Immutable -data class TextFilterState( +data class TextFilterStateUiModel( val includedFilters: List, val excludedFilters: List, val isEnabled: Boolean, @@ -30,8 +22,8 @@ data class TextFilterState( override val isActive: Boolean = allFilters.isNotEmpty() && isEnabled && allFilters.any { it.isActive } - companion object { - val EMPTY = TextFilterState( + companion object Companion { + val EMPTY = TextFilterStateUiModel( includedFilters = emptyList(), excludedFilters = emptyList(), isEnabled = false, @@ -39,7 +31,7 @@ data class TextFilterState( } } -fun previewTextFilterState() = TextFilterState( +fun previewTextFilterState() = TextFilterStateUiModel( isEnabled = true, includedFilters = listOf( FilterItem(text = "toInclude", isExcluded = false, isActive = true), diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/filters/TextFilterDropdown.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/filters/TextFilterDropdown.kt index 64ca7d9e..ab2d453e 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/filters/TextFilterDropdown.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/filters/TextFilterDropdown.kt @@ -45,7 +45,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import io.github.openflocon.flocondesktop.common.ui.interactions.hover import io.github.openflocon.flocondesktop.features.network.ui.model.header.TextFilterAction -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterState +import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterStateUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.previewTextFilterState import io.github.openflocon.library.designsystem.FloconTheme import org.jetbrains.compose.ui.tooling.preview.Preview @@ -55,7 +55,7 @@ import org.jetbrains.compose.ui.tooling.preview.Preview fun TextFilterDropdown( expanded: Boolean, onDismissRequest: () -> Unit, - filterState: TextFilterState, + filterState: TextFilterStateUiModel, textFilterAction: (TextFilterAction) -> Unit, ) { DropdownMenu( @@ -74,7 +74,7 @@ fun TextFilterDropdown( @Composable private fun TextFilterDropdownContent( modifier: Modifier = Modifier, - filterState: TextFilterState, + filterState: TextFilterStateUiModel, textFilterAction: (TextFilterAction) -> Unit, ) { Column(modifier = modifier) { @@ -163,10 +163,10 @@ private fun TextFilterDropdownContent( @Composable private fun FilterItemView( - item: TextFilterState.FilterItem, + item: TextFilterStateUiModel.FilterItem, modifier: Modifier = Modifier, - changeIsActive: (item: TextFilterState.FilterItem, newValue: Boolean) -> Unit, - clickDelete: (item: TextFilterState.FilterItem) -> Unit, + changeIsActive: (item: TextFilterStateUiModel.FilterItem, newValue: Boolean) -> Unit, + clickDelete: (item: TextFilterStateUiModel.FilterItem) -> Unit, ) { var isHover by remember { mutableStateOf(false) } Row( diff --git a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/header/NetworkItemHeaderView.kt b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/header/NetworkItemHeaderView.kt index 74bd4316..872aa1cc 100644 --- a/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/header/NetworkItemHeaderView.kt +++ b/FloconDesktop/composeApp/src/commonMain/kotlin/io/github/openflocon/flocondesktop/features/network/ui/view/header/NetworkItemHeaderView.kt @@ -16,12 +16,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import io.github.openflocon.flocondesktop.features.network.ui.NetworkAction +import io.github.openflocon.flocondesktop.features.network.domain.model.NetworkTextFilterColumns import io.github.openflocon.flocondesktop.features.network.ui.model.SortedByUiModel import io.github.openflocon.flocondesktop.features.network.ui.model.header.NetworkHeaderUiState import io.github.openflocon.flocondesktop.features.network.ui.model.header.OnFilterAction import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.NetworkColumnsTypeUiModel -import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.filter.TextFilterColumns import io.github.openflocon.flocondesktop.features.network.ui.model.header.columns.base.isFiltered import io.github.openflocon.flocondesktop.features.network.ui.model.header.previewNetworkHeaderUiState import io.github.openflocon.flocondesktop.features.network.ui.view.NetworkItemColumnWidths @@ -72,7 +71,7 @@ fun NetworkItemHeaderView( }, filterState = state.requestTime.filter, textFilterAction = { - onFilterAction(OnFilterAction.TextFilter(TextFilterColumns.RequestTime, it)) + onFilterAction(OnFilterAction.TextFilter(NetworkTextFilterColumns.RequestTime, it)) } ) } @@ -128,7 +127,7 @@ fun NetworkItemHeaderView( isDropdownExpanded = false }, textFilterAction = { - onFilterAction(OnFilterAction.TextFilter(TextFilterColumns.Domain, it)) + onFilterAction(OnFilterAction.TextFilter(NetworkTextFilterColumns.Domain, it)) } ) } @@ -154,7 +153,7 @@ fun NetworkItemHeaderView( isDropdownExpanded = false }, textFilterAction = { - onFilterAction(OnFilterAction.TextFilter(TextFilterColumns.Query,it)) + onFilterAction(OnFilterAction.TextFilter(NetworkTextFilterColumns.Query,it)) } ) } @@ -181,7 +180,7 @@ fun NetworkItemHeaderView( isDropdownExpanded = false }, textFilterAction = { - onFilterAction(OnFilterAction.TextFilter(TextFilterColumns.Status,it)) + onFilterAction(OnFilterAction.TextFilter(NetworkTextFilterColumns.Status,it)) } ) } @@ -207,7 +206,7 @@ fun NetworkItemHeaderView( isDropdownExpanded = false }, textFilterAction = { - onFilterAction(OnFilterAction.TextFilter(TextFilterColumns.Time, it)) + onFilterAction(OnFilterAction.TextFilter(NetworkTextFilterColumns.Time, it)) } ) }