@@ -20,6 +20,12 @@ import java.util.UUID
2020import kotlin.io.encoding.Base64
2121import kotlin.io.encoding.ExperimentalEncodingApi
2222
23+ // wrapper to have stable ID for each condition item to preserve focus
24+ data class FilterConditionVM (
25+ val id : String ,
26+ val condition : FilterConditionItem ,
27+ )
28+
2329class FilterEditViewModel (
2430 private val savedStateHandle : SavedStateHandle ,
2531 private val filterRepository : IFilterRepository
@@ -31,9 +37,8 @@ class FilterEditViewModel(
3137 val packageName = mutableStateOf(" " )
3238 val isFilterEnabled = mutableStateOf(true )
3339 val matchAllConditions = mutableStateOf(true ) // true for AND, false for OR
34- val conditions = mutableStateListOf<FilterConditionItem >()
35- val filterAction =
36- mutableStateOf(FilterAction .BLOCK ) // Add state for the action, default to BLOCK
40+ val conditions = mutableStateListOf<FilterConditionVM >()
41+ val filterAction = mutableStateOf(FilterAction .BLOCK ) // Add state for the action, default to BLOCK
3742
3843 val availableConditionTypes: List <ConditionType > = ConditionType .entries
3944 val availableFilterActions: List <FilterAction > = FilterAction .entries
@@ -64,12 +69,13 @@ class FilterEditViewModel(
6469 ?.urlDecode()
6570 ?.let { value ->
6671 if (value.isNotBlank()) {
67- conditions.add(
72+ conditions.add(FilterConditionVM (
73+ id = UUID .randomUUID().toString(),
6874 FilterConditionItem (
6975 type = conditionType,
7076 value = value
7177 )
72- )
78+ ))
7379 }
7480 }
7581 }
@@ -79,10 +85,12 @@ class FilterEditViewModel(
7985 savedStateHandle[AppRoute .FilterEditScreen .FILTER_EDIT_ARG_IS_ONGOING ]
8086 ? : false
8187 conditions.add(
88+ FilterConditionVM (
89+ id = UUID .randomUUID().toString(),
8290 FilterConditionItem (
8391 type = ConditionType .IS_ONGOING_EQUALS ,
8492 value = isOngoingFromNav.toString()
85- )
93+ ))
8694 )
8795 }
8896
@@ -106,39 +114,50 @@ class FilterEditViewModel(
106114 isFilterEnabled.value = loadedFilter.isEnabled
107115 matchAllConditions.value = loadedFilter.matchAllConditions
108116 conditions.clear()
109- conditions.addAll(loadedFilter.conditions)
117+ conditions.addAll(loadedFilter.conditions.mapIndexed {
118+ index, condition ->
119+ FilterConditionVM (
120+ id = UUID .randomUUID().toString(),
121+ condition = condition
122+ )
123+ })
110124 filterAction.value = loadedFilter.action // Load the action
111125 }
112126 }
113127
114128 fun addCondition () {
115- conditions.add(FilterConditionItem (type = ConditionType .TITLE_CONTAINS , value = " " ))
129+ conditions.add(
130+ FilterConditionVM (
131+ id = UUID .randomUUID().toString(),
132+ FilterConditionItem (type = ConditionType .TITLE_CONTAINS , value = " " )
133+ )
134+ )
116135 }
117136
118- fun removeCondition (item : FilterConditionItem ) {
137+ fun removeCondition (item : FilterConditionVM ) {
119138 conditions.remove(item)
120139 }
121140
122141 fun updateConditionType (index : Int , newType : ConditionType ) {
123142 if (index in conditions.indices) {
124- val currentItem = conditions[index]
143+ val item = conditions[index]
125144 when {
126145 // If changing from IS_ONGOING_EQUALS, reset value to empty string
127- currentItem .type == ConditionType .IS_ONGOING_EQUALS && newType != ConditionType .IS_ONGOING_EQUALS ->
128- conditions[index] = currentItem .copy(type = newType, value = " " )
146+ item.condition .type == ConditionType .IS_ONGOING_EQUALS && newType != ConditionType .IS_ONGOING_EQUALS ->
147+ conditions[index] = item .copy(condition = item.condition.copy( type = newType, value = " " ) )
129148 // If changing to IS_ONGOING_EQUALS, reset value to false
130- currentItem .type != ConditionType .IS_ONGOING_EQUALS && newType == ConditionType .IS_ONGOING_EQUALS -> {
131- conditions[index] = currentItem .copy(type = newType, value = " false" )
149+ item.condition .type != ConditionType .IS_ONGOING_EQUALS && newType == ConditionType .IS_ONGOING_EQUALS -> {
150+ conditions[index] = item .copy(condition = item.condition.copy( type = newType, value = " false" ) )
132151 }
133- else -> conditions[index] = currentItem .copy(type = newType)
152+ else -> conditions[index] = item .copy(condition = item.condition.copy( type = newType) )
134153 }
135154 }
136155 }
137156
138157 fun updateConditionValue (index : Int , newValue : String ) {
139158 if (index in conditions.indices) {
140159 val currentItem = conditions[index]
141- conditions[index] = currentItem.copy(value = newValue)
160+ conditions[index] = currentItem.copy(condition = currentItem.condition.copy( value = newValue) )
142161 }
143162 }
144163
@@ -151,7 +170,7 @@ class FilterEditViewModel(
151170 isEnabled = isFilterEnabled.value,
152171 matchAllConditions = matchAllConditions.value,
153172 // todo: filter empty conditions
154- conditions = ArrayList ( conditions) ,
173+ conditions = conditions.map { it.condition } ,
155174 action = filterAction.value
156175 )
157176
0 commit comments