mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Sticker management v2 – Improve list animations and state transitions.
- Uninstall selected packs in a single database transaction to avoid UI flickering. - Add section header keys to prevent them from animating wildly while scrolling.
This commit is contained in:
@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecret
|
||||
import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream
|
||||
import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream
|
||||
import org.thoughtcrime.securesms.database.model.IncomingSticker
|
||||
import org.thoughtcrime.securesms.database.model.StickerPackId
|
||||
import org.thoughtcrime.securesms.database.model.StickerPackRecord
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri
|
||||
@@ -296,9 +297,15 @@ class StickerTable(
|
||||
}
|
||||
|
||||
fun uninstallPack(packId: String) {
|
||||
uninstallPacks(setOf(StickerPackId(packId)))
|
||||
}
|
||||
|
||||
fun uninstallPacks(packIds: Set<StickerPackId>) {
|
||||
writableDatabase.withinTransaction { db ->
|
||||
updatePackInstalled(db = db, packId = packId, installed = false, notify = false)
|
||||
deleteStickersInPackExceptCover(db, packId)
|
||||
packIds.forEach { packId ->
|
||||
updatePackInstalled(db = db, packId = packId.value, installed = false, notify = false)
|
||||
deleteStickersInPackExceptCover(db, packId.value)
|
||||
}
|
||||
}
|
||||
|
||||
notifyStickerPackListeners()
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId.DirectReply
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId.GroupReply
|
||||
import org.thoughtcrime.securesms.database.model.StickerPackId
|
||||
import org.thoughtcrime.securesms.database.model.StoryType
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge
|
||||
@@ -1075,7 +1076,7 @@ object SyncMessageProcessor {
|
||||
|
||||
when (operation.type!!) {
|
||||
StickerPackOperation.Type.INSTALL -> jobManager.add(StickerPackDownloadJob.forInstall(packId, packKey, false))
|
||||
StickerPackOperation.Type.REMOVE -> SignalDatabase.stickers.uninstallPack(packId)
|
||||
StickerPackOperation.Type.REMOVE -> SignalDatabase.stickers.uninstallPacks(setOf(StickerPackId(packId)))
|
||||
}
|
||||
} else {
|
||||
warn("Received incomplete sticker pack operation sync.")
|
||||
|
||||
@@ -412,7 +412,13 @@ private fun AvailableStickersContent(
|
||||
modifier = modifier.fillMaxHeight()
|
||||
) {
|
||||
if (blessedPacks.isNotEmpty()) {
|
||||
item { StickerPackSectionHeader(text = stringResource(R.string.StickerManagement_signal_artist_series_header)) }
|
||||
item(key = "blessed_section_header") {
|
||||
StickerPackSectionHeader(
|
||||
text = stringResource(R.string.StickerManagement_signal_artist_series_header),
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
}
|
||||
|
||||
items(
|
||||
items = blessedPacks,
|
||||
key = { it.id.value }
|
||||
@@ -442,7 +448,12 @@ private fun AvailableStickersContent(
|
||||
}
|
||||
|
||||
if (notBlessedPacks.isNotEmpty()) {
|
||||
item { StickerPackSectionHeader(text = stringResource(R.string.StickerManagement_stickers_you_received_header)) }
|
||||
item(key = "not_blessed_section_header") {
|
||||
StickerPackSectionHeader(
|
||||
text = stringResource(R.string.StickerManagement_stickers_you_received_header),
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
}
|
||||
items(
|
||||
items = notBlessedPacks,
|
||||
key = { it.id.value }
|
||||
@@ -508,9 +519,12 @@ private fun InstalledStickersContent(
|
||||
rightDpOffset = if (isRtl) 56.dp else screenWidth
|
||||
)
|
||||
) {
|
||||
item {
|
||||
item(key = "installed_section_header") {
|
||||
DraggableItem(dragDropState, 0) {
|
||||
StickerPackSectionHeader(text = stringResource(R.string.StickerManagement_installed_stickers_header))
|
||||
StickerPackSectionHeader(
|
||||
text = stringResource(R.string.StickerManagement_installed_stickers_header),
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,15 +118,17 @@ object StickerManagementRepository {
|
||||
@Discouraged("For Java use only. In Kotlin, use uninstallStickerPack() instead.")
|
||||
fun uninstallStickerPackAsync(packId: String, packKey: String) {
|
||||
coroutineScope.launch {
|
||||
uninstallStickerPack(StickerPackId(packId), StickerPackKey(packKey))
|
||||
uninstallStickerPacks(mapOf(StickerPackId(packId) to StickerPackKey(packKey)))
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun uninstallStickerPack(packId: StickerPackId, packKey: StickerPackKey) = withContext(Dispatchers.IO) {
|
||||
stickersDbTable.uninstallPack(packId.value)
|
||||
suspend fun uninstallStickerPacks(packKeysById: Map<StickerPackId, StickerPackKey>) = withContext(Dispatchers.IO) {
|
||||
stickersDbTable.uninstallPacks(packIds = packKeysById.keys)
|
||||
|
||||
if (SignalStore.account.hasLinkedDevices) {
|
||||
AppDependencies.jobManager.add(MultiDeviceStickerPackOperationJob(packId.value, packKey.value, MultiDeviceStickerPackOperationJob.Type.REMOVE))
|
||||
packKeysById.forEach { (packId, packKey) ->
|
||||
AppDependencies.jobManager.add(MultiDeviceStickerPackOperationJob(packId.value, packKey.value, MultiDeviceStickerPackOperationJob.Type.REMOVE))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,12 +133,7 @@ class StickerManagementViewModel : ViewModel() {
|
||||
private fun uninstallStickerPacks(packIds: Set<StickerPackId>) {
|
||||
val packsToUninstall = _uiState.value.installedPacks.filter { packIds.contains(it.id) }
|
||||
viewModelScope.launch {
|
||||
packsToUninstall.forEach { pack ->
|
||||
StickerManagementRepository.uninstallStickerPack(packId = pack.id, packKey = pack.key)
|
||||
_uiState.update { previousState ->
|
||||
previousState.copy(selectedPackIds = previousState.selectedPackIds.minus(pack.id))
|
||||
}
|
||||
}
|
||||
StickerManagementRepository.uninstallStickerPacks(packsToUninstall.associate { it.id to it.key })
|
||||
|
||||
_uiState.update { previousState ->
|
||||
previousState.copy(
|
||||
@@ -146,7 +141,8 @@ class StickerManagementViewModel : ViewModel() {
|
||||
StickerManagementConfirmation.UninstalledPack(packsToUninstall.single().record.title)
|
||||
} else {
|
||||
StickerManagementConfirmation.UninstalledPacks(packsToUninstall.size)
|
||||
}
|
||||
},
|
||||
selectedPackIds = previousState.selectedPackIds.minus(packIds)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user