From a66031cfce3bc38b2d03c1dfca35521892aecb81 Mon Sep 17 00:00:00 2001 From: lisa-signal Date: Wed, 4 Jun 2025 15:16:14 -0400 Subject: [PATCH] Fix chat folder to not show mute option if there isn't any chat. --- .../chats/folders/ChatFolderContextMenu.kt | 7 ++++-- .../chats/folders/ChatFoldersRepository.kt | 4 ++-- .../conversationlist/ChatFolderAdapter.kt | 1 + .../ChatFolderMappingModel.kt | 2 ++ .../ConversationListViewModel.kt | 7 +++--- .../securesms/database/ChatFolderTables.kt | 7 +++--- .../securesms/database/ThreadTable.kt | 22 +++++++++++++++++++ 7 files changed, 40 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFolderContextMenu.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFolderContextMenu.kt index 9a2c816800..27d87701d3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFolderContextMenu.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFolderContextMenu.kt @@ -19,6 +19,7 @@ object ChatFolderContextMenu { rootView: ViewGroup = anchorView.rootView as ViewGroup, folderType: ChatFolderRecord.FolderType, unreadCount: Int, + isEmpty: Boolean, isMuted: Boolean, onEdit: () -> Unit = {}, onMuteAll: () -> Unit = {}, @@ -32,6 +33,7 @@ object ChatFolderContextMenu { rootView = rootView, folderType = folderType, unreadCount = unreadCount, + isEmpty = isEmpty, isMuted = isMuted, callbacks = object : Callbacks { override fun onEdit() = onEdit() @@ -48,6 +50,7 @@ object ChatFolderContextMenu { anchorView: View, rootView: ViewGroup, unreadCount: Int, + isEmpty: Boolean, isMuted: Boolean, folderType: ChatFolderRecord.FolderType, callbacks: Callbacks @@ -61,13 +64,13 @@ object ChatFolderContextMenu { ) } - if (isMuted) { + if (isMuted && !isEmpty) { add( ActionItem(R.drawable.symbol_bell_24, context.getString(R.string.ChatFoldersFragment__unmute_all)) { callbacks.onUnmuteAll() } ) - } else { + } else if (!isEmpty) { add( ActionItem(R.drawable.symbol_bell_slash_24, context.getString(R.string.ChatFoldersFragment__mute_all)) { callbacks.onMuteAll() diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersRepository.kt index 89baee08f3..107efa4877 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersRepository.kt @@ -13,8 +13,8 @@ object ChatFoldersRepository { return SignalDatabase.chatFolders.getCurrentChatFolders() } - fun getUnreadCountAndMutedStatusForFolders(folders: List): HashMap> { - return SignalDatabase.chatFolders.getUnreadCountAndMutedStatusForFolders(folders) + fun getUnreadCountAndEmptyAndMutedStatusForFolders(folders: List): HashMap> { + return SignalDatabase.chatFolders.getUnreadCountAndEmptyAndMutedStatusForFolders(folders) } fun createFolder(folder: ChatFolderRecord, includedRecipients: Set, excludedRecipients: Set) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderAdapter.kt index d8e74dc19a..9a92a07385 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderAdapter.kt @@ -43,6 +43,7 @@ class ChatFolderAdapter(val callbacks: Callbacks) : MappingAdapter() { anchorView = view, folderType = model.chatFolder.folderType, unreadCount = model.unreadCount, + isEmpty = model.isEmpty, isMuted = model.isMuted, onEdit = { callbacks.onEdit(model.chatFolder) }, onMuteAll = { callbacks.onMuteAll(model.chatFolder) }, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderMappingModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderMappingModel.kt index e1867c730d..2d27bd075d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderMappingModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ChatFolderMappingModel.kt @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.util.adapter.mapping.MappingModel data class ChatFolderMappingModel( val chatFolder: ChatFolderRecord, val unreadCount: Int, + val isEmpty: Boolean, val isMuted: Boolean, val isSelected: Boolean ) : MappingModel, Parcelable { @@ -22,6 +23,7 @@ data class ChatFolderMappingModel( override fun areContentsTheSame(newItem: ChatFolderMappingModel): Boolean { return chatFolder == newItem.chatFolder && unreadCount == newItem.unreadCount && + isEmpty == newItem.isEmpty && isMuted == newItem.isMuted && isSelected == newItem.isSelected } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.kt index 4db91ee9b2..a9ecb66d54 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListViewModel.kt @@ -217,7 +217,7 @@ sealed class ConversationListViewModel( private fun loadCurrentFolders() { viewModelScope.launch(Dispatchers.IO) { val folders = ChatFoldersRepository.getCurrentFolders() - val unreadCountAndMutedStatus = ChatFoldersRepository.getUnreadCountAndMutedStatusForFolders(folders) + val unreadCountAndEmptyAndMutedStatus = ChatFoldersRepository.getUnreadCountAndEmptyAndMutedStatusForFolders(folders) val selectedFolderId = if (currentFolder.id == -1L) { folders.firstOrNull()?.id @@ -227,8 +227,9 @@ sealed class ConversationListViewModel( val chatFolders = folders.map { folder -> ChatFolderMappingModel( chatFolder = folder, - unreadCount = unreadCountAndMutedStatus[folder.id]?.first ?: 0, - isMuted = unreadCountAndMutedStatus[folder.id]?.second ?: false, + unreadCount = unreadCountAndEmptyAndMutedStatus[folder.id]?.first ?: 0, + isEmpty = unreadCountAndEmptyAndMutedStatus[folder.id]?.second ?: false, + isMuted = unreadCountAndEmptyAndMutedStatus[folder.id]?.third ?: false, isSelected = selectedFolderId == folder.id ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ChatFolderTables.kt b/app/src/main/java/org/thoughtcrime/securesms/database/ChatFolderTables.kt index a8fd2e1092..a2d00d63d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ChatFolderTables.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ChatFolderTables.kt @@ -236,12 +236,13 @@ class ChatFolderTables(context: Context?, databaseHelper: SignalDatabase?) : Dat /** * Given a list of folders, maps a folder id to the folder's unread count and whether all the chats in the folder are muted */ - fun getUnreadCountAndMutedStatusForFolders(folders: List): HashMap> { - val map: HashMap> = hashMapOf() + fun getUnreadCountAndEmptyAndMutedStatusForFolders(folders: List): HashMap> { + val map: HashMap> = hashMapOf() folders.map { folder -> val unreadCount = SignalDatabase.threads.getUnreadCountByChatFolder(folder) + val isEmpty = !SignalDatabase.threads.hasChatInFolder(folder) val isMuted = !SignalDatabase.threads.hasUnmutedChatsInFolder(folder) - map[folder.id] = Pair(unreadCount, isMuted) + map[folder.id] = Triple(unreadCount, isEmpty, isMuted) } return map } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt index 79ff6f5248..548478d871 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadTable.kt @@ -650,6 +650,28 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa return allCount + forcedUnreadCount } + /** + * Returns whether or not there are chats in a chat folder + */ + fun hasChatInFolder(folder: ChatFolderRecord): Boolean { + val chatFolderQuery = folder.toQuery() + + val hasChats = + """ + SELECT EXISTS( + SELECT 1 + FROM $TABLE_NAME + LEFT OUTER JOIN ${RecipientTable.TABLE_NAME} ON $TABLE_NAME.$RECIPIENT_ID = ${RecipientTable.TABLE_NAME}.${RecipientTable.ID} + WHERE + $ARCHIVED = 0 + $chatFolderQuery + LIMIT 1 + ) + """ + + return readableDatabase.rawQuery(hasChats, null).readToSingleBoolean() + } + /** * Returns whether or not there are any unmuted chats in a chat folder */