@@ -19,6 +19,9 @@ package com.wire.android.feature.cells.ui.tags
1919
2020import androidx.compose.foundation.text.input.TextFieldState
2121import androidx.compose.foundation.text.input.clearText
22+ import androidx.compose.runtime.getValue
23+ import androidx.compose.runtime.mutableStateOf
24+ import androidx.compose.runtime.setValue
2225import androidx.compose.runtime.snapshotFlow
2326import androidx.lifecycle.SavedStateHandle
2427import androidx.lifecycle.viewModelScope
@@ -27,16 +30,13 @@ import com.wire.android.ui.common.ActionsViewModel
2730import com.wire.kalium.cells.domain.usecase.GetAllTagsUseCase
2831import com.wire.kalium.cells.domain.usecase.RemoveNodeTagsUseCase
2932import com.wire.kalium.cells.domain.usecase.UpdateNodeTagsUseCase
33+ import com.wire.kalium.common.functional.getOrElse
3034import com.wire.kalium.common.functional.onFailure
3135import com.wire.kalium.common.functional.onSuccess
3236import dagger.hilt.android.lifecycle.HiltViewModel
3337import kotlinx.coroutines.flow.MutableStateFlow
34- import kotlinx.coroutines.flow.SharingStarted
35- import kotlinx.coroutines.flow.asStateFlow
3638import kotlinx.coroutines.flow.collectLatest
37- import kotlinx.coroutines.flow.combine
3839import kotlinx.coroutines.flow.debounce
39- import kotlinx.coroutines.flow.stateIn
4040import kotlinx.coroutines.flow.update
4141import kotlinx.coroutines.launch
4242import javax.inject.Inject
@@ -55,70 +55,77 @@ class AddRemoveTagsViewModel @Inject constructor(
5555
5656 val tagsTextState = TextFieldState ()
5757
58- private val allTags: MutableStateFlow <Set <String >> = MutableStateFlow (emptySet())
59-
6058 val initialTags: Set <String > = navArgs.tags.toSet()
61- private val _addedTags : MutableStateFlow <Set <String >> = MutableStateFlow (navArgs.tags.toSet())
62- internal val addedTags = _addedTags .asStateFlow()
6359
6460 val disallowedChars = listOf (" ," , " ;" , " /" , " \\ " , " \" " , " \' " , " <" , " >" )
6561
66- private val _suggestedTags = MutableStateFlow <Set <String >>(emptySet())
67- internal val suggestedTags =
68- allTags.combine(addedTags) { all, added ->
69- all.filter { it !in added }.toSet().sorted()
70- }.stateIn(viewModelScope, SharingStarted .WhileSubscribed (), emptySet())
62+ var allTags: Set <String > = emptySet()
63+ private set
64+
65+ val addedTags: MutableStateFlow <Set <String >> = MutableStateFlow (navArgs.tags.toSet())
66+
67+ var suggestedTags by mutableStateOf<Set <String >>(emptySet())
68+ private set
7169
7270 init {
7371 viewModelScope.launch {
74- getAllTagsUseCase().onSuccess { tags ->
75- allTags.update { tags }
76- }
77- launch {
78- snapshotFlow { tagsTextState.text.toString() }
79- .debounce(TYPING_DEBOUNCE_TIME )
80- .collectLatest { query ->
81- val filtered = if (query.isBlank()) {
82- allTags.value
83- } else {
84- allTags.value.filter { it.contains(query, ignoreCase = true ) }.toSet()
85- }
86- _suggestedTags .value = filtered
87- }
88- }
72+ allTags = getAllTagsUseCase().getOrElse { emptySet() }
73+ updateSuggestions(" " ) // initial state
74+ }
75+
76+ viewModelScope.launch {
77+ snapshotFlow { tagsTextState.text.toString() }
78+ .debounce(TYPING_DEBOUNCE_TIME )
79+ .collectLatest {
80+ onQueryChanged(it)
81+ }
8982 }
9083 }
9184
85+ fun onQueryChanged (query : String ) {
86+ updateSuggestions(query)
87+ }
88+
89+ private fun updateSuggestions (query : String ) {
90+ suggestedTags = allTags
91+ .asSequence()
92+ .filter { query.isBlank() || it.contains(query, ignoreCase = true ) }
93+ .filter { it !in addedTags.value }
94+ .toSet()
95+ }
96+
9297 fun isValidTag (): Boolean = disallowedChars.none {
9398 it in tagsTextState.text
9499 } && tagsTextState.text.length in ALLOWED_LENGTH
95100
96101 fun addTag (tag : String ) {
97102 tag.trim().let { newTag ->
98- if (newTag.isNotBlank() && newTag !in _addedTags .value) {
99- _addedTags .update { it + newTag }
103+ if (newTag.isNotBlank() && newTag !in addedTags.value) {
104+ addedTags.update { it + newTag }
105+ updateSuggestions(" " )
100106 tagsTextState.clearText()
101107 }
102108 }
103109 }
104110
105111 fun removeTag (tag : String ) {
106- _addedTags .update { it - tag }
112+ addedTags.update { it - tag }
113+ updateSuggestions(" " )
107114 }
108115
109116 fun removeLastTag () {
110- _addedTags .value.lastOrNull()?.let { lastTag ->
117+ addedTags .value.lastOrNull()?.let { lastTag ->
111118 removeTag(lastTag)
112119 }
113120 }
114121
115122 fun updateTags () {
116123 viewModelScope.launch {
117124 isLoading.value = true
118- val result = if (_addedTags .value.isEmpty()) {
125+ val result = if (addedTags .value.isEmpty()) {
119126 removeNodeTagsUseCase(navArgs.uuid)
120127 } else {
121- updateNodeTagsUseCase(navArgs.uuid, _addedTags .value)
128+ updateNodeTagsUseCase(navArgs.uuid, addedTags .value)
122129 }
123130
124131 result
0 commit comments