diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt index 1678d5fc89..2b79608ae1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsFragment.kt @@ -63,12 +63,22 @@ class ChatsSettingsFragment : DSLSettingsFragment(R.string.preferences_chats__ch if (RemoteConfig.showChatFolders) { sectionHeaderPref(R.string.ChatsSettingsFragment__chat_folders) - clickPref( - title = DSLSettingsText.from(R.string.ChatsSettingsFragment__add_chat_folder), - onClick = { - Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment) - } - ) + if (state.folderCount == 0) { + clickPref( + title = DSLSettingsText.from(R.string.ChatsSettingsFragment__add_chat_folder), + onClick = { + Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment) + } + ) + } else { + clickPref( + title = DSLSettingsText.from(R.string.ChatsSettingsFragment__add_edit_chat_folder), + summary = DSLSettingsText.from(resources.getQuantityString(R.plurals.ChatsSettingsFragment__d_folder, state.folderCount, state.folderCount)), + onClick = { + Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment) + } + ) + } dividerPref() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsState.kt index ed174592c2..d5d7250a58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsState.kt @@ -6,5 +6,6 @@ data class ChatsSettingsState( val keepMutedChatsArchived: Boolean, val useSystemEmoji: Boolean, val enterKeySends: Boolean, - val localBackupsEnabled: Boolean + val localBackupsEnabled: Boolean, + val folderCount: Int ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt index f726738063..3d2281bd6e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/ChatsSettingsViewModel.kt @@ -2,6 +2,10 @@ package org.thoughtcrime.securesms.components.settings.app.chats import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import org.thoughtcrime.securesms.components.settings.app.chats.folders.ChatFoldersRepository import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.util.BackupUtil @@ -22,7 +26,8 @@ class ChatsSettingsViewModel @JvmOverloads constructor( keepMutedChatsArchived = SignalStore.settings.shouldKeepMutedChatsArchived(), useSystemEmoji = SignalStore.settings.isPreferSystemEmoji, enterKeySends = SignalStore.settings.isEnterKeySends, - localBackupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(AppDependencies.application) + localBackupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(AppDependencies.application), + folderCount = 0 ) ) @@ -58,11 +63,24 @@ class ChatsSettingsViewModel @JvmOverloads constructor( } fun refresh() { - val backupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(AppDependencies.application) + viewModelScope.launch(Dispatchers.IO) { + val count = ChatFoldersRepository.getFolderCount() + val backupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(AppDependencies.application) - if (store.state.localBackupsEnabled != backupsEnabled - ) { - store.update { it.copy(localBackupsEnabled = backupsEnabled) } + if (store.state.localBackupsEnabled != backupsEnabled) { + store.update { + it.copy( + folderCount = count, + localBackupsEnabled = backupsEnabled + ) + } + } else { + store.update { + it.copy( + folderCount = count + ) + } + } } } } 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 ed4164bc98..3f0751ca95 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 @@ -44,4 +44,8 @@ object ChatFoldersRepository { fun getFolder(id: Long): ChatFolderRecord { return SignalDatabase.chatFolders.getChatFolder(id) } + + fun getFolderCount(): Int { + return SignalDatabase.chatFolders.getFolderCount() + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/CreateFoldersFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/CreateFoldersFragment.kt index 0955119d59..a0a68c94f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/CreateFoldersFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/CreateFoldersFragment.kt @@ -33,6 +33,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -58,6 +59,8 @@ import org.thoughtcrime.securesms.compose.ComposeFragment import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.navigation.safeNavigate +private const val MAX_CHAT_COUNT = 5 + /** * Fragment that allows user to create, edit, or delete an individual folder */ @@ -175,6 +178,9 @@ fun CreateFolderScreen( onCreateConfirmed: (Boolean) -> Unit = {}, onCreateDismissed: (Boolean) -> Unit = {} ) { + var expandIncluded by remember { mutableStateOf(false) } + var expandExcluded by remember { mutableStateOf(false) } + if (state.showDeleteDialog) { Dialogs.SimpleAlertDialog( title = "", @@ -250,11 +256,27 @@ fun CreateFolderScreen( } } - items(state.currentFolder.includedRecipients.toList()) { recipient -> - ChatRow( - recipient = recipient, - onClick = onAddChat - ) + if (!expandIncluded && state.currentFolder.includedRecipients.size > MAX_CHAT_COUNT) { + items(state.currentFolder.includedRecipients.toList().subList(0, MAX_CHAT_COUNT)) { recipient -> + ChatRow( + recipient = recipient, + onClick = onAddChat + ) + } + item { + FolderRow( + icon = R.drawable.symbol_chevron_down_24, + title = stringResource(R.string.CreateFoldersFragment__see_all), + onClick = { expandIncluded = true } + ) + } + } else { + items(state.currentFolder.includedRecipients.toList()) { recipient -> + ChatRow( + recipient = recipient, + onClick = onAddChat + ) + } } item { @@ -279,11 +301,27 @@ fun CreateFolderScreen( ) } - items(state.currentFolder.excludedRecipients.toList()) { recipient -> - ChatRow( - recipient = recipient, - onClick = onRemoveChat - ) + if (!expandExcluded && state.currentFolder.excludedRecipients.size > MAX_CHAT_COUNT) { + items(state.currentFolder.excludedRecipients.toList().subList(0, MAX_CHAT_COUNT)) { recipient -> + ChatRow( + recipient = recipient, + onClick = onAddChat + ) + } + item { + FolderRow( + icon = R.drawable.symbol_chevron_down_24, + title = stringResource(R.string.CreateFoldersFragment__see_all), + onClick = { expandExcluded = true } + ) + } + } else { + items(state.currentFolder.excludedRecipients.toList()) { recipient -> + ChatRow( + recipient = recipient, + onClick = onRemoveChat + ) + } } item { 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 4750b81ce6..60134b0a51 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ChatFolderTables.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ChatFolderTables.kt @@ -4,6 +4,7 @@ import android.content.ContentValues import android.content.Context import androidx.core.content.contentValuesOf import org.signal.core.util.SqlUtil +import org.signal.core.util.count import org.signal.core.util.delete import org.signal.core.util.groupBy import org.signal.core.util.insertInto @@ -232,6 +233,18 @@ class ChatFolderTables(context: Context?, databaseHelper: SignalDatabase?) : Dat } } + /** + * Returns the number of user-made folders + */ + fun getFolderCount(): Int { + return readableDatabase + .count() + .from(ChatFolderTable.TABLE_NAME) + .where("${ChatFolderTable.FOLDER_TYPE} != ${ChatFolderRecord.FolderType.ALL.value}") + .run() + .readToSingleInt() + } + /** * Adds a chat folder and its corresponding included/excluded chats */ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8a6655dd42..3ddbc7b61c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5069,8 +5069,15 @@ Send with enter Chat folders - + Add a chat folder + + Add or edit folders + + + %1$d folder + %1$d folders + @@ -5172,6 +5179,8 @@ Delete folder Delete this chat folder? + + See all