mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-26 03:40:56 +01:00
Clean up chat folder records.
This commit is contained in:
committed by
Cody Henthorne
parent
247c5de140
commit
82bb18e218
@@ -0,0 +1,12 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.chats.folders
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
/**
|
||||
* Information needed when creating/updating a chat folder. Used in [ChatFoldersSettingsState]
|
||||
*/
|
||||
data class ChatFolder(
|
||||
val folderRecord: ChatFolderRecord = ChatFolderRecord(),
|
||||
val includedRecipients: Set<Recipient> = emptySet(),
|
||||
val excludedRecipients: Set<Recipient> = emptySet()
|
||||
)
|
||||
@@ -1,9 +1,7 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.chats.folders
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
/**
|
||||
* Represents an entry in the [org.thoughtcrime.securesms.database.ChatFolderTables].
|
||||
@@ -15,17 +13,11 @@ data class ChatFolderRecord(
|
||||
val position: Int = -1,
|
||||
val includedChats: List<Long> = emptyList(),
|
||||
val excludedChats: List<Long> = emptyList(),
|
||||
@IgnoredOnParcel
|
||||
val includedRecipients: Set<Recipient> = emptySet(),
|
||||
@IgnoredOnParcel
|
||||
val excludedRecipients: Set<Recipient> = emptySet(),
|
||||
val showUnread: Boolean = false,
|
||||
val showMutedChats: Boolean = true,
|
||||
val showIndividualChats: Boolean = false,
|
||||
val showGroupChats: Boolean = false,
|
||||
val isMuted: Boolean = false,
|
||||
val folderType: FolderType = FolderType.CUSTOM,
|
||||
val unreadCount: Int = 0
|
||||
val folderType: FolderType = FolderType.CUSTOM
|
||||
) : Parcelable {
|
||||
enum class FolderType(val value: Int) {
|
||||
/** Folder containing all chats */
|
||||
|
||||
@@ -404,7 +404,6 @@ private fun ChatFolderPreview() {
|
||||
showIndividualChats = true,
|
||||
showGroupChats = true,
|
||||
showMutedChats = true,
|
||||
isMuted = false,
|
||||
folderType = ChatFolderRecord.FolderType.CUSTOM
|
||||
),
|
||||
ChatFolderRecord(
|
||||
@@ -415,7 +414,6 @@ private fun ChatFolderPreview() {
|
||||
showIndividualChats = true,
|
||||
showGroupChats = false,
|
||||
showMutedChats = false,
|
||||
isMuted = false,
|
||||
folderType = ChatFolderRecord.FolderType.CUSTOM
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.chats.folders
|
||||
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
/**
|
||||
* Repository for chat folders that handles creation, deletion, listing, etc.,
|
||||
*/
|
||||
object ChatFoldersRepository {
|
||||
|
||||
fun getCurrentFolders(includeUnreadAndMutedCounts: Boolean = false): List<ChatFolderRecord> {
|
||||
return SignalDatabase.chatFolders.getChatFolders(includeUnreadAndMutedCounts)
|
||||
fun getCurrentFolders(): List<ChatFolderRecord> {
|
||||
return SignalDatabase.chatFolders.getChatFolders()
|
||||
}
|
||||
|
||||
fun createFolder(folder: ChatFolderRecord) {
|
||||
val includedChats = folder.includedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
val excludedChats = folder.excludedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
fun getUnreadCountAndMutedStatusForFolders(folders: List<ChatFolderRecord>): HashMap<Long, Pair<Int, Boolean>> {
|
||||
return SignalDatabase.chatFolders.getUnreadCountAndMutedStatusForFolders(folders)
|
||||
}
|
||||
|
||||
fun createFolder(folder: ChatFolderRecord, includedRecipients: Set<Recipient>, excludedRecipients: Set<Recipient>) {
|
||||
val includedChats = includedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
val excludedChats = excludedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
val updatedFolder = folder.copy(
|
||||
includedChats = includedChats,
|
||||
excludedChats = excludedChats
|
||||
@@ -22,9 +27,9 @@ object ChatFoldersRepository {
|
||||
SignalDatabase.chatFolders.createFolder(updatedFolder)
|
||||
}
|
||||
|
||||
fun updateFolder(folder: ChatFolderRecord) {
|
||||
val includedChats = folder.includedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
val excludedChats = folder.excludedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
fun updateFolder(folder: ChatFolderRecord, includedRecipients: Set<Recipient>, excludedRecipients: Set<Recipient>) {
|
||||
val includedChats = includedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
val excludedChats = excludedRecipients.map { recipient -> SignalDatabase.threads.getOrCreateThreadIdFor(recipient) }
|
||||
val updatedFolder = folder.copy(
|
||||
includedChats = includedChats,
|
||||
excludedChats = excludedChats
|
||||
|
||||
@@ -9,8 +9,8 @@ import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
data class ChatFoldersSettingsState(
|
||||
val folders: List<ChatFolderRecord> = emptyList(),
|
||||
val suggestedFolders: List<ChatFolderRecord> = emptyList(),
|
||||
val originalFolder: ChatFolderRecord = ChatFolderRecord(),
|
||||
val currentFolder: ChatFolderRecord = ChatFolderRecord(),
|
||||
val originalFolder: ChatFolder = ChatFolder(),
|
||||
val currentFolder: ChatFolder = ChatFolder(),
|
||||
val showDeleteDialog: Boolean = false,
|
||||
val showConfirmationDialog: Boolean = false,
|
||||
val pendingIncludedRecipients: Set<RecipientId> = emptySet(),
|
||||
|
||||
@@ -24,15 +24,15 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
|
||||
fun loadCurrentFolders(context: Context) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val folders = ChatFoldersRepository.getCurrentFolders(includeUnreadAndMutedCounts = false)
|
||||
val folders = ChatFoldersRepository.getCurrentFolders()
|
||||
val suggestedFolders = getSuggestedFolders(context, folders)
|
||||
|
||||
internalState.update {
|
||||
it.copy(
|
||||
folders = folders,
|
||||
suggestedFolders = suggestedFolders,
|
||||
currentFolder = ChatFolderRecord(),
|
||||
originalFolder = ChatFolderRecord()
|
||||
currentFolder = ChatFolder(),
|
||||
originalFolder = ChatFolder()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,8 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
SignalDatabase.threads.getRecipientForThreadId(threadId)
|
||||
}
|
||||
|
||||
val updatedFolder = folder.copy(
|
||||
val updatedFolder = ChatFolder(
|
||||
folderRecord = folder,
|
||||
includedRecipients = includedRecipients.toSet(),
|
||||
excludedRecipients = excludedRecipients.toSet()
|
||||
)
|
||||
@@ -112,32 +113,32 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun updateName(name: String) {
|
||||
val updatedFolder = internalState.value.currentFolder.copy(
|
||||
val updatedFolder = internalState.value.currentFolder.folderRecord.copy(
|
||||
name = name.substring(0, minOf(name.length, 32))
|
||||
)
|
||||
|
||||
internalState.update {
|
||||
it.copy(currentFolder = updatedFolder)
|
||||
it.copy(currentFolder = it.currentFolder.copy(folderRecord = updatedFolder))
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleShowUnread(showUnread: Boolean) {
|
||||
val updatedFolder = internalState.value.currentFolder.copy(
|
||||
val updatedFolder = internalState.value.currentFolder.folderRecord.copy(
|
||||
showUnread = showUnread
|
||||
)
|
||||
|
||||
internalState.update {
|
||||
it.copy(currentFolder = updatedFolder)
|
||||
it.copy(currentFolder = it.currentFolder.copy(folderRecord = updatedFolder))
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleShowMutedChats(showMuted: Boolean) {
|
||||
val updatedFolder = internalState.value.currentFolder.copy(
|
||||
val updatedFolder = internalState.value.currentFolder.folderRecord.copy(
|
||||
showMutedChats = showMuted
|
||||
)
|
||||
|
||||
internalState.update {
|
||||
it.copy(currentFolder = updatedFolder)
|
||||
it.copy(currentFolder = it.currentFolder.copy(folderRecord = updatedFolder))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
|
||||
fun deleteFolder(context: Context) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
ChatFoldersRepository.deleteFolder(internalState.value.originalFolder)
|
||||
ChatFoldersRepository.deleteFolder(internalState.value.originalFolder.folderRecord)
|
||||
|
||||
loadCurrentFolders(context)
|
||||
internalState.update {
|
||||
@@ -166,8 +167,8 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
|
||||
fun createFolder(context: Context, folder: ChatFolderRecord? = null) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val currentFolder = folder ?: internalState.value.currentFolder
|
||||
ChatFoldersRepository.createFolder(currentFolder)
|
||||
val currentFolder = if (folder != null) ChatFolder(folder) else internalState.value.currentFolder
|
||||
ChatFoldersRepository.createFolder(currentFolder.folderRecord, currentFolder.includedRecipients, currentFolder.excludedRecipients)
|
||||
loadCurrentFolders(context)
|
||||
|
||||
internalState.update {
|
||||
@@ -192,7 +193,8 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
|
||||
fun updateFolder(context: Context) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
ChatFoldersRepository.updateFolder(internalState.value.currentFolder)
|
||||
val currentFolder = internalState.value.currentFolder
|
||||
ChatFoldersRepository.updateFolder(currentFolder.folderRecord, currentFolder.includedRecipients, currentFolder.excludedRecipients)
|
||||
loadCurrentFolders(context)
|
||||
|
||||
internalState.update {
|
||||
@@ -208,10 +210,10 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
val excludedChats = currentFolder.excludedRecipients.map { recipient -> recipient.id }.toMutableSet()
|
||||
|
||||
val chatTypes: MutableSet<ChatType> = mutableSetOf()
|
||||
if (currentFolder.showIndividualChats) {
|
||||
if (currentFolder.folderRecord.showIndividualChats) {
|
||||
chatTypes.add(ChatType.INDIVIDUAL)
|
||||
}
|
||||
if (currentFolder.showGroupChats) {
|
||||
if (currentFolder.folderRecord.showGroupChats) {
|
||||
chatTypes.add(ChatType.GROUPS)
|
||||
}
|
||||
|
||||
@@ -309,10 +311,12 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
internalState.update {
|
||||
it.copy(
|
||||
currentFolder = updatedFolder.copy(
|
||||
folderRecord = updatedFolder.folderRecord.copy(
|
||||
showIndividualChats = showIndividualChats,
|
||||
showGroupChats = showGroupChats
|
||||
),
|
||||
includedRecipients = includedRecipients,
|
||||
excludedRecipients = excludedRecipients,
|
||||
showIndividualChats = showIndividualChats,
|
||||
showGroupChats = showGroupChats
|
||||
excludedRecipients = excludedRecipients
|
||||
),
|
||||
pendingIncludedRecipients = emptySet(),
|
||||
pendingExcludedRecipients = emptySet()
|
||||
@@ -331,8 +335,8 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
val currentFolder = state.value.currentFolder
|
||||
val originalFolder = state.value.originalFolder
|
||||
|
||||
return if (currentFolder.id == -1L) {
|
||||
currentFolder.includedRecipients.isNotEmpty() || currentFolder.showIndividualChats || currentFolder.showGroupChats
|
||||
return if (currentFolder.folderRecord.id == -1L) {
|
||||
currentFolder.includedRecipients.isNotEmpty() || currentFolder.folderRecord.showIndividualChats || currentFolder.folderRecord.showGroupChats
|
||||
} else {
|
||||
originalFolder != currentFolder ||
|
||||
originalFolder.includedRecipients != currentFolder.includedRecipients ||
|
||||
@@ -350,6 +354,6 @@ class ChatFoldersViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun hasEmptyName(): Boolean {
|
||||
return state.value.currentFolder.name.isEmpty()
|
||||
return state.value.currentFolder.folderRecord.name.isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class CreateFoldersFragment : ComposeFragment() {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
val navController: NavController by remember { mutableStateOf(findNavController()) }
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val isNewFolder = state.originalFolder.id == -1L
|
||||
val isNewFolder = state.originalFolder.folderRecord.id == -1L
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
if (state.originalFolder == state.currentFolder) {
|
||||
@@ -221,7 +221,7 @@ fun CreateFolderScreen(
|
||||
LazyColumn {
|
||||
item {
|
||||
TextField(
|
||||
value = state.currentFolder.name,
|
||||
value = state.currentFolder.folderRecord.name,
|
||||
label = { Text(text = stringResource(id = R.string.CreateFoldersFragment__folder_name)) },
|
||||
onValueChange = onNameChange,
|
||||
keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Sentences),
|
||||
@@ -245,7 +245,7 @@ fun CreateFolderScreen(
|
||||
onClick = onAddChat
|
||||
)
|
||||
|
||||
if (state.currentFolder.showIndividualChats) {
|
||||
if (state.currentFolder.folderRecord.showIndividualChats) {
|
||||
FolderRow(
|
||||
icon = R.drawable.symbol_person_light_24,
|
||||
title = stringResource(R.string.ChatFoldersFragment__one_on_one_chats),
|
||||
@@ -253,7 +253,7 @@ fun CreateFolderScreen(
|
||||
)
|
||||
}
|
||||
|
||||
if (state.currentFolder.showGroupChats) {
|
||||
if (state.currentFolder.folderRecord.showGroupChats) {
|
||||
FolderRow(
|
||||
icon = R.drawable.symbol_group_light_20,
|
||||
title = stringResource(R.string.ChatFoldersFragment__groups),
|
||||
@@ -366,12 +366,12 @@ fun CreateFolderScreen(
|
||||
|
||||
Buttons.MediumTonal(
|
||||
colors = ButtonDefaults.filledTonalButtonColors(
|
||||
contentColor = if (state.currentFolder.name.isEmpty()) {
|
||||
contentColor = if (state.currentFolder.folderRecord.name.isEmpty()) {
|
||||
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
containerColor = if (state.currentFolder.name.isEmpty()) {
|
||||
containerColor = if (state.currentFolder.folderRecord.name.isEmpty()) {
|
||||
MaterialTheme.colorScheme.surfaceVariant
|
||||
} else {
|
||||
MaterialTheme.colorScheme.primaryContainer
|
||||
@@ -380,7 +380,7 @@ fun CreateFolderScreen(
|
||||
),
|
||||
enabled = hasChanges,
|
||||
onClick = {
|
||||
if (state.currentFolder.name.isEmpty()) {
|
||||
if (state.currentFolder.folderRecord.name.isEmpty()) {
|
||||
onShowToast()
|
||||
} else {
|
||||
onCreateConfirmed()
|
||||
@@ -419,7 +419,7 @@ private fun ShowUnreadSection(state: ChatFoldersSettingsState, onToggleShowUnrea
|
||||
)
|
||||
}
|
||||
Switch(
|
||||
checked = state.currentFolder.showUnread,
|
||||
checked = state.currentFolder.folderRecord.showUnread,
|
||||
onCheckedChange = onToggleShowUnread
|
||||
)
|
||||
}
|
||||
@@ -440,7 +440,7 @@ private fun ShowMutedSection(state: ChatFoldersSettingsState, onToggleShowMuted:
|
||||
)
|
||||
}
|
||||
Switch(
|
||||
checked = state.currentFolder.showMutedChats,
|
||||
checked = state.currentFolder.folderRecord.showMutedChats,
|
||||
onCheckedChange = onToggleShowMuted
|
||||
)
|
||||
}
|
||||
@@ -449,7 +449,7 @@ private fun ShowMutedSection(state: ChatFoldersSettingsState, onToggleShowMuted:
|
||||
@SignalPreview
|
||||
@Composable
|
||||
private fun CreateFolderPreview() {
|
||||
val previewFolder = ChatFolderRecord(id = 1, name = "WIP")
|
||||
val previewFolder = ChatFolder(ChatFolderRecord(id = 1, name = "WIP"))
|
||||
|
||||
Previews.Preview {
|
||||
CreateFolderScreen(
|
||||
@@ -463,7 +463,7 @@ private fun CreateFolderPreview() {
|
||||
@SignalPreview
|
||||
@Composable
|
||||
private fun EditFolderPreview() {
|
||||
val previewFolder = ChatFolderRecord(id = 1, name = "Work")
|
||||
val previewFolder = ChatFolder(ChatFolderRecord(id = 1, name = "Work"))
|
||||
|
||||
Previews.Preview {
|
||||
CreateFolderScreen(
|
||||
|
||||
Reference in New Issue
Block a user