Add chat folder support to storage service.

This commit is contained in:
Michelle Tang
2025-04-04 11:36:17 -04:00
parent f6ecb572b1
commit eb1cf8d62f
26 changed files with 1131 additions and 84 deletions

View File

@@ -0,0 +1,31 @@
package org.thoughtcrime.securesms.components.settings.app.chats.folders
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.whispersystems.signalservice.api.util.UuidUtil
import java.util.UUID
/**
* UUID wrapper class for chat folders, used in storage service
*/
@Parcelize
data class ChatFolderId(val uuid: UUID) : Parcelable {
companion object {
fun from(id: String): ChatFolderId {
return ChatFolderId(UuidUtil.parseOrThrow(id))
}
fun from(uuid: UUID): ChatFolderId {
return ChatFolderId(uuid)
}
fun generate(): ChatFolderId {
return ChatFolderId(UUID.randomUUID())
}
}
override fun toString(): String {
return uuid.toString()
}
}

View File

@@ -1,7 +1,9 @@
package org.thoughtcrime.securesms.components.settings.app.chats.folders
import android.os.Parcelable
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.whispersystems.signalservice.api.storage.StorageId
/**
* Represents an entry in the [org.thoughtcrime.securesms.database.ChatFolderTables].
@@ -17,7 +19,12 @@ data class ChatFolderRecord(
val showMutedChats: Boolean = true,
val showIndividualChats: Boolean = false,
val showGroupChats: Boolean = false,
val folderType: FolderType = FolderType.CUSTOM
val folderType: FolderType = FolderType.CUSTOM,
val chatFolderId: ChatFolderId = ChatFolderId.generate(),
@IgnoredOnParcel
val storageServiceId: StorageId? = null,
val storageServiceProto: ByteArray? = null,
val deletedTimestampMs: Long = 0
) : Parcelable {
enum class FolderType(val value: Int) {
/** Folder containing all chats */

View File

@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.settings.app.chats.folders
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.storage.StorageSyncHelper
/**
* Repository for chat folders that handles creation, deletion, listing, etc.,
@@ -9,7 +10,7 @@ import org.thoughtcrime.securesms.recipients.Recipient
object ChatFoldersRepository {
fun getCurrentFolders(): List<ChatFolderRecord> {
return SignalDatabase.chatFolders.getChatFolders()
return SignalDatabase.chatFolders.getCurrentChatFolders()
}
fun getUnreadCountAndMutedStatusForFolders(folders: List<ChatFolderRecord>): HashMap<Long, Pair<Int, Boolean>> {
@@ -25,6 +26,7 @@ object ChatFoldersRepository {
)
SignalDatabase.chatFolders.createFolder(updatedFolder)
StorageSyncHelper.scheduleSyncForDataChange()
}
fun updateFolder(folder: ChatFolderRecord, includedRecipients: Set<Recipient>, excludedRecipients: Set<Recipient>) {
@@ -36,21 +38,29 @@ object ChatFoldersRepository {
)
SignalDatabase.chatFolders.updateFolder(updatedFolder)
scheduleSync(updatedFolder.id)
}
fun deleteFolder(folder: ChatFolderRecord) {
SignalDatabase.chatFolders.deleteChatFolder(folder)
scheduleSync(folder.id)
}
fun updatePositions(folders: List<ChatFolderRecord>) {
SignalDatabase.chatFolders.updatePositions(folders)
folders.forEach { scheduleSync(it.id) }
}
fun getFolder(id: Long): ChatFolderRecord {
return SignalDatabase.chatFolders.getChatFolder(id)
return SignalDatabase.chatFolders.getChatFolder(id)!!
}
fun getFolderCount(): Int {
return SignalDatabase.chatFolders.getFolderCount()
}
private fun scheduleSync(id: Long) {
SignalDatabase.chatFolders.markNeedsSync(id)
StorageSyncHelper.scheduleSyncForDataChange()
}
}

View File

@@ -97,7 +97,7 @@ class CreateFoldersFragment : ComposeFragment() {
val isNewFolder = state.originalFolder.folderRecord.id == -1L
LaunchedEffect(Unit) {
if (state.originalFolder == state.currentFolder) {
if (state.originalFolder.folderRecord.id == state.currentFolder.folderRecord.id) {
viewModel.setCurrentFolderId(arguments?.getLong(KEY_FOLDER_ID) ?: -1)
viewModel.addThreadsToFolder(arguments?.getLongArray(KEY_THREAD_IDS))
}