mirror of
https://github.com/openflocon/Flocon.git
synced 2026-05-17 05:43:16 +00:00
fix: [NETWORK] filters (#293)
Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
parent
03a5598b7f
commit
ad22c5366a
3 changed files with 46 additions and 27 deletions
|
|
@ -3,7 +3,7 @@ package io.github.openflocon.flocondesktop.features.network
|
|||
import io.github.openflocon.flocondesktop.features.network.badquality.BadQualityNetworkViewModel
|
||||
import io.github.openflocon.flocondesktop.features.network.list.NetworkViewModel
|
||||
import io.github.openflocon.flocondesktop.features.network.list.delegate.HeaderDelegate
|
||||
import io.github.openflocon.flocondesktop.features.network.list.processor.SortAndFilterNetworkItemsProcessor
|
||||
import io.github.openflocon.flocondesktop.features.network.list.processor.FilterNetworkItemsProcessor
|
||||
import io.github.openflocon.flocondesktop.features.network.mock.NetworkMocksViewModel
|
||||
import io.github.openflocon.flocondesktop.features.network.mock.processor.ExportMocksProcessor
|
||||
import io.github.openflocon.flocondesktop.features.network.mock.processor.ImportMocksProcessor
|
||||
|
|
@ -16,7 +16,7 @@ internal val networkModule = module {
|
|||
viewModelOf(::NetworkViewModel)
|
||||
factoryOf(::MessagesServerDelegate)
|
||||
factoryOf(::HeaderDelegate)
|
||||
factoryOf(::SortAndFilterNetworkItemsProcessor)
|
||||
factoryOf(::FilterNetworkItemsProcessor)
|
||||
|
||||
viewModelOf(::NetworkMocksViewModel)
|
||||
factoryOf(::ExportMocksProcessor)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import io.github.openflocon.flocondesktop.features.network.list.model.NetworkMet
|
|||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkUiState
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.TopBarUiState
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.header.columns.base.filter.TextFilterStateUiModel
|
||||
import io.github.openflocon.flocondesktop.features.network.list.processor.SortAndFilterNetworkItemsProcessor
|
||||
import io.github.openflocon.flocondesktop.features.network.list.processor.FilterNetworkItemsProcessor
|
||||
import io.github.openflocon.flocondesktop.features.network.model.NetworkBodyDetailUi
|
||||
import io.github.openflocon.library.designsystem.common.copyToClipboard
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -69,7 +69,7 @@ class NetworkViewModel(
|
|||
private val dispatcherProvider: DispatcherProvider,
|
||||
private val feedbackDisplayer: FeedbackDisplayer,
|
||||
private val headerDelegate: HeaderDelegate,
|
||||
private val sortAndFilterNetworkItemsProcessor: SortAndFilterNetworkItemsProcessor,
|
||||
private val filterNetworkItemsProcessor: FilterNetworkItemsProcessor,
|
||||
private val observeCurrentDeviceIdAndPackageNameUseCase: ObserveCurrentDeviceIdAndPackageNameUseCase,
|
||||
private val exportNetworkCallsToCsv: ExportNetworkCallsToCsvUseCase,
|
||||
private val decodeJwtTokenUseCase: DecodeJwtTokenUseCase,
|
||||
|
|
@ -174,7 +174,7 @@ class NetworkViewModel(
|
|||
contentState,
|
||||
filterConfig,
|
||||
) { items, content, config ->
|
||||
sortAndFilterNetworkItemsProcessor(
|
||||
filterNetworkItemsProcessor(
|
||||
items = items,
|
||||
filterState = config.filterState,
|
||||
allowedMethods = config.allowedMethods,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import io.github.openflocon.flocondesktop.features.network.list.model.NetworkIte
|
|||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkMethodUi
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.header.columns.base.filter.TextFilterStateUiModel
|
||||
|
||||
class SortAndFilterNetworkItemsProcessor {
|
||||
class FilterNetworkItemsProcessor {
|
||||
operator fun invoke(
|
||||
items: List<Pair<FloconNetworkCallDomainModel, NetworkItemViewState>>,
|
||||
filterState: TopBarUiState,
|
||||
|
|
@ -18,8 +18,12 @@ class SortAndFilterNetworkItemsProcessor {
|
|||
item.second.method in allowedMethods
|
||||
}
|
||||
.filter { item ->
|
||||
textFilters.filter { it.value.isActive }.all { (column, textFilter) ->
|
||||
textFilter.filter(column, item)
|
||||
val filters = textFilters.filter { it.value.isActive }
|
||||
if(filters.isEmpty()) true
|
||||
else {
|
||||
filters.any { (column, textFilter) ->
|
||||
textFilter.filter(column, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
.map { it.second }
|
||||
|
|
@ -41,33 +45,48 @@ private fun TextFilterStateUiModel.filter(
|
|||
}
|
||||
|
||||
private fun TextFilterStateUiModel.filterByText(text: String?): Boolean {
|
||||
if (text == null)
|
||||
return true // accepts if text is null
|
||||
|
||||
for (filter in this.allFilters) {
|
||||
if (!filter.filterByText(text))
|
||||
return false
|
||||
// 1. If text is null, it always passes the filter (default behavior).
|
||||
if (text == null) {
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
val activeFilters = this.allFilters.filter { it.isActive }
|
||||
|
||||
// 2. If there are no active filters, it always passes.
|
||||
if (activeFilters.isEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
val (excludedFilters, includedFilters) = activeFilters.partition { it.isExcluded }
|
||||
|
||||
// --- Step 1: Exclusion Check ---
|
||||
|
||||
// 4. Check if the text matches ANY exclusion filter.
|
||||
// If ANY active 'isExcluded' filter matches, the item MUST be rejected (return false).
|
||||
val isExcluded = excludedFilters.any { it.matches(text) }
|
||||
|
||||
if (isExcluded) {
|
||||
return false // Excluded, so it fails the filter immediately.
|
||||
}
|
||||
|
||||
// --- Step 2: Inclusion Check ---
|
||||
|
||||
// 5. If there are no inclusion filters, the item passes (as it wasn't excluded).
|
||||
if (includedFilters.isEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 6. If not excluded, check if the text matches AT LEAST ONE inclusion filter.
|
||||
// If ANY non-excluded filter matches, the item is kept (return true).
|
||||
return includedFilters.any { it.matches(text) }
|
||||
}
|
||||
|
||||
private fun TextFilterStateUiModel.FilterItem.filterByText(text: String): Boolean {
|
||||
if (!this.isActive)
|
||||
return true
|
||||
|
||||
// Crée une instance de Regex en fonction de 'isRegex'
|
||||
val filterResult = if (this.isRegex) {
|
||||
private fun TextFilterStateUiModel.FilterItem.matches(text: String): Boolean {
|
||||
return if (this.isRegex) {
|
||||
Regex(this.text, setOf(RegexOption.IGNORE_CASE)).containsMatchIn(text)
|
||||
} else {
|
||||
text.contains(this.text, ignoreCase = true)
|
||||
}
|
||||
|
||||
return if (this.isExcluded) {
|
||||
!filterResult
|
||||
} else {
|
||||
filterResult
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Loading…
Add table
Add a link
Reference in a new issue