Skip to content

Commit 7534fca

Browse files
committed
hide tags without conversations
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
1 parent a43b9d2 commit 7534fca

2 files changed

Lines changed: 67 additions & 24 deletions

File tree

app/src/main/java/com/nextcloud/talk/conversationlist/ui/ConversationsListScreen.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ fun ConversationsListScreen(
140140
// ViewModel state
141141
val entries by viewModel.conversationListEntriesFlow.collectAsStateWithLifecycle()
142142
val rooms by viewModel.getRoomsStateFlow.collectAsStateWithLifecycle()
143+
val visibleRooms by viewModel.visibleRoomsFlow.collectAsStateWithLifecycle()
143144
val isShimmerVisible by viewModel.isShimmerVisible.collectAsStateWithLifecycle()
144145
val isSearchActive by viewModel.isSearchActiveFlow.collectAsStateWithLifecycle()
145146
val searchQuery by viewModel.currentSearchQueryFlow.collectAsStateWithLifecycle()
@@ -184,8 +185,17 @@ fun ConversationsListScreen(
184185
val hasConversationTagsCapability = state.currentUser?.capabilities?.spreedCapability?.let {
185186
CapabilitiesUtil.hasSpreedFeatureCapability(it, SpreedFeatures.CONVERSATION_TAGS)
186187
} == true
188+
val nonEmptyConversationTags = remember(conversationTags, visibleRooms) {
189+
conversationTags.filter { tag ->
190+
if (tag.type == ConversationTag.TYPE_FAVORITES) {
191+
visibleRooms.any { it.favorite }
192+
} else {
193+
visibleRooms.any { it.tagIds.contains(tag.id) }
194+
}
195+
}
196+
}
187197
val showConversationTagsRow = hasConversationTagsCapability &&
188-
conversationTags.isNotEmpty() &&
198+
nonEmptyConversationTags.isNotEmpty() &&
189199
!isSearchActive &&
190200
!showShareTo &&
191201
!isForward
@@ -336,7 +346,7 @@ fun ConversationsListScreen(
336346
tagsRowContent = if (showConversationTagsRow) {
337347
{
338348
ConversationTagsRow(
339-
tags = conversationTags,
349+
tags = nonEmptyConversationTags,
340350
selectedTagId = selectedTagFilter,
341351
onTagSelected = { tagId ->
342352
val isFavorites = conversationTags.any {

app/src/main/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -255,26 +255,44 @@ class ConversationsListViewModel @Inject constructor(
255255
selectedTagIsFavoritesFlow.value = tagId != null && isFavorites
256256
}
257257

258+
private val searchDisplayModeFlow = combine(_isSearchActiveFlow, _currentSearchQueryFlow) { active, query ->
259+
when {
260+
!active -> SearchDisplayMode.OFF
261+
query.isEmpty() -> SearchDisplayMode.ALL_CONVERSATIONS
262+
else -> SearchDisplayMode.RESULTS
263+
}
264+
}
265+
258266
/**
259267
* Single source of truth for the [ConversationList] LazyColumn.
260268
* Auto-reacts to rooms, filter, tag filter, search-active and search-result changes.
261269
*/
262270
val conversationListEntriesFlow: StateFlow<List<ConversationListEntry>> = combine(
263271
getRoomsStateFlow,
264272
_filterStateFlow,
265-
combine(_isSearchActiveFlow, _currentSearchQueryFlow) { active, query ->
266-
when {
267-
!active -> SearchDisplayMode.OFF
268-
query.isEmpty() -> SearchDisplayMode.ALL_CONVERSATIONS
269-
else -> SearchDisplayMode.RESULTS
270-
}
271-
},
273+
searchDisplayModeFlow,
272274
combine(_selectedTagFilterFlow, selectedTagIsFavoritesFlow, ::TagFilterSelection),
273275
combine(searchResultEntries, hideRoomToken, ::Pair)
274276
) { rooms, filterState, searchMode, tagFilter, (searchResults, hideToken) ->
275277
buildConversationListEntries(rooms, filterState, searchMode, tagFilter, searchResults, hideToken)
276278
}.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
277279

280+
/**
281+
* Rooms that would actually be shown in the list under the current filter chips
282+
* (mention/unread/archive) and hidden-room/lobby rules, but *before* narrowing to a
283+
* specific tag. Used to decide which tag filter chips currently have a matching,
284+
* visible conversation - e.g. a tag whose only conversation is archived should not
285+
* show up as a chip unless the "Archived" filter is active.
286+
*/
287+
val visibleRoomsFlow: StateFlow<List<ConversationModel>> = combine(
288+
getRoomsStateFlow,
289+
_filterStateFlow,
290+
searchDisplayModeFlow,
291+
hideRoomToken
292+
) { rooms, filterState, searchMode, hideToken ->
293+
baseFilterRooms(rooms, filterState, searchMode, hideToken)
294+
}.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
295+
278296
/** Clears the tag filter when the filtered-by tag no longer exists (e.g. it was deleted). */
279297
fun clearTagFilterIfMatches(tagId: String) {
280298
if (_selectedTagFilterFlow.value == tagId) {
@@ -640,6 +658,34 @@ class ConversationsListViewModel @Inject constructor(
640658
): List<ConversationListEntry> {
641659
if (searchMode == SearchDisplayMode.RESULTS) return searchResults
642660

661+
var filtered = baseFilterRooms(rooms, filterState, searchMode, hideToken)
662+
663+
if (searchMode != SearchDisplayMode.ALL_CONVERSATIONS) {
664+
filtered = when {
665+
tagFilter.isFavorites -> filtered.filter { it.favorite }
666+
tagFilter.tagId != null -> filtered.filter { it.tagIds.contains(tagFilter.tagId) }
667+
else -> filtered
668+
}
669+
}
670+
671+
val sorted = filtered.sortedWith(
672+
compareByDescending<ConversationModel> { it.favorite }
673+
.thenByDescending { it.lastActivity }
674+
)
675+
return sorted.map { ConversationListEntry.ConversationEntry(it) }
676+
}
677+
678+
/**
679+
* Applies the hidden-room/lobby rules and the current filter chips (mention/unread/archive),
680+
* but not the tag filter. Shared by [buildConversationListEntries] and [visibleRoomsFlow] so
681+
* that both the list content and the tag-chip visibility agree on what "visible" means.
682+
*/
683+
private fun baseFilterRooms(
684+
rooms: List<ConversationModel>,
685+
filterState: Map<String, Boolean>,
686+
searchMode: SearchDisplayMode,
687+
hideToken: String?
688+
): List<ConversationModel> {
643689
val hasFilterEnabled = filterState[MENTION] == true ||
644690
filterState[UNREAD] == true ||
645691
filterState[ARCHIVE] == true
@@ -655,25 +701,12 @@ class ConversationsListViewModel @Inject constructor(
655701

656702
filtered = when {
657703
// While search is open with an empty query, all conversations are listed,
658-
// ignoring active filters, the tag filter and the default hiding of archived/future-event rooms
704+
// ignoring active filters and the default hiding of archived/future-event rooms
659705
searchMode == SearchDisplayMode.ALL_CONVERSATIONS -> filtered
660706
hasFilterEnabled -> filtered.filter { filterConversationModel(it, filterState) }
661707
else -> filtered.filter { !isFutureEvent(it) && !it.hasArchived }
662708
}
663-
664-
if (searchMode != SearchDisplayMode.ALL_CONVERSATIONS) {
665-
filtered = when {
666-
tagFilter.isFavorites -> filtered.filter { it.favorite }
667-
tagFilter.tagId != null -> filtered.filter { it.tagIds.contains(tagFilter.tagId) }
668-
else -> filtered
669-
}
670-
}
671-
672-
val sorted = filtered.sortedWith(
673-
compareByDescending<ConversationModel> { it.favorite }
674-
.thenByDescending { it.lastActivity }
675-
)
676-
return sorted.map { ConversationListEntry.ConversationEntry(it) }
709+
return filtered
677710
}
678711

679712
@Suppress("CyclomaticComplexMethod", "NestedBlockDepth")

0 commit comments

Comments
 (0)