feat(core): bulk clean conversations
This commit is contained in:
@@ -1,126 +0,0 @@
|
||||
package me.rhunk.snapenhance.messaging
|
||||
|
||||
import androidx.compose.runtime.MutableIntState
|
||||
import kotlinx.coroutines.delay
|
||||
import me.rhunk.snapenhance.bridge.snapclient.MessagingBridge
|
||||
import me.rhunk.snapenhance.bridge.snapclient.types.Message
|
||||
import me.rhunk.snapenhance.common.data.ContentType
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
enum class MessagingTaskType(
|
||||
val key: String
|
||||
) {
|
||||
SAVE("SAVE"),
|
||||
UNSAVE("UNSAVE"),
|
||||
DELETE("ERASE"),
|
||||
READ("READ"),
|
||||
}
|
||||
|
||||
typealias MessagingTaskConstraint = Message.() -> Boolean
|
||||
|
||||
object MessagingConstraints {
|
||||
val USER_ID: (String) -> MessagingTaskConstraint = { userId: String ->
|
||||
{
|
||||
this.senderId == userId
|
||||
}
|
||||
}
|
||||
val NO_USER_ID: (String) -> MessagingTaskConstraint = { userId: String ->
|
||||
{
|
||||
this.senderId != userId
|
||||
}
|
||||
}
|
||||
val MY_USER_ID: (messagingBridge: MessagingBridge) -> MessagingTaskConstraint = {
|
||||
val myUserId = it.myUserId
|
||||
{
|
||||
this.senderId == myUserId
|
||||
}
|
||||
}
|
||||
val CONTENT_TYPE: (Array<ContentType>) -> MessagingTaskConstraint = {
|
||||
val contentTypes = it.map { type -> type.id };
|
||||
{
|
||||
contentTypes.contains(this.contentType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MessagingTask(
|
||||
private val messagingBridge: MessagingBridge,
|
||||
private val conversationId: String,
|
||||
val taskType: MessagingTaskType,
|
||||
val constraints: List<MessagingTaskConstraint>,
|
||||
private val processedMessageCount: MutableIntState,
|
||||
val onSuccess: (message: Message) -> Unit = {},
|
||||
private val onFailure: (message: Message, reason: String) -> Unit = { _, _ -> },
|
||||
private val overrideClientMessageIds: List<Long>? = null,
|
||||
private val amountToProcess: Int? = null,
|
||||
) {
|
||||
private suspend fun processMessages(
|
||||
messages: List<Message>
|
||||
) {
|
||||
messages.forEach { message ->
|
||||
if (constraints.any { !it(message) }) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val error = messagingBridge.updateMessage(conversationId, message.clientMessageId, taskType.key)
|
||||
error?.takeIf { error != "DUPLICATE_REQUEST" }?.let {
|
||||
onFailure(message, error)
|
||||
}
|
||||
onSuccess(message)
|
||||
processedMessageCount.intValue++
|
||||
delay(Random.nextLong(20, 50))
|
||||
}
|
||||
}
|
||||
|
||||
fun hasFixedGoal() = overrideClientMessageIds?.takeIf { it.isNotEmpty() } != null || amountToProcess?.takeIf { it > 0 } != null
|
||||
|
||||
suspend fun run() {
|
||||
var processedOverrideMessages = 0
|
||||
var lastMessageId = Long.MAX_VALUE
|
||||
|
||||
do {
|
||||
val fetchedMessages = messagingBridge.fetchConversationWithMessagesPaginated(
|
||||
conversationId,
|
||||
100,
|
||||
lastMessageId
|
||||
) ?: return
|
||||
|
||||
if (fetchedMessages.isEmpty()) {
|
||||
break
|
||||
}
|
||||
|
||||
lastMessageId = fetchedMessages.first().clientMessageId
|
||||
|
||||
overrideClientMessageIds?.let { ids ->
|
||||
fetchedMessages.retainAll { message ->
|
||||
ids.contains(message.clientMessageId)
|
||||
}
|
||||
}
|
||||
|
||||
amountToProcess?.let { amount ->
|
||||
while (processedMessageCount.intValue + fetchedMessages.size > amount) {
|
||||
fetchedMessages.removeLastOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
processMessages(fetchedMessages.reversed())
|
||||
|
||||
overrideClientMessageIds?.let { ids ->
|
||||
processedOverrideMessages += fetchedMessages.count { message ->
|
||||
ids.contains(message.clientMessageId)
|
||||
}
|
||||
|
||||
if (processedOverrideMessages >= ids.size) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
amountToProcess?.let { amount ->
|
||||
if (processedMessageCount.intValue >= amount) {
|
||||
return
|
||||
}
|
||||
}
|
||||
} while (true)
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,12 @@ import me.rhunk.snapenhance.common.Constants
|
||||
import me.rhunk.snapenhance.common.ReceiversConfig
|
||||
import me.rhunk.snapenhance.common.data.ContentType
|
||||
import me.rhunk.snapenhance.common.data.SocialScope
|
||||
import me.rhunk.snapenhance.common.messaging.MessagingConstraints
|
||||
import me.rhunk.snapenhance.common.messaging.MessagingTask
|
||||
import me.rhunk.snapenhance.common.messaging.MessagingTaskConstraint
|
||||
import me.rhunk.snapenhance.common.messaging.MessagingTaskType
|
||||
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
|
||||
import me.rhunk.snapenhance.common.util.snap.SnapWidgetBroadcastReceiverHelper
|
||||
import me.rhunk.snapenhance.messaging.MessagingConstraints
|
||||
import me.rhunk.snapenhance.messaging.MessagingTask
|
||||
import me.rhunk.snapenhance.messaging.MessagingTaskConstraint
|
||||
import me.rhunk.snapenhance.messaging.MessagingTaskType
|
||||
import me.rhunk.snapenhance.ui.manager.Routes
|
||||
import me.rhunk.snapenhance.ui.util.Dialog
|
||||
|
||||
@@ -299,14 +299,17 @@ class MessagingPreview: Routes.Route() {
|
||||
else selectConstraintsDialog = true
|
||||
}
|
||||
ActionButton(text = translation[if (hasSelection) "mark_selection_as_seen_option" else "mark_all_as_seen_option"], icon = Icons.Rounded.RemoveRedEye) {
|
||||
launchMessagingTask(MessagingTaskType.READ, listOf(
|
||||
launchMessagingTask(
|
||||
MessagingTaskType.READ, listOf(
|
||||
MessagingConstraints.NO_USER_ID(messagingBridge.myUserId),
|
||||
MessagingConstraints.CONTENT_TYPE(arrayOf(ContentType.SNAP))
|
||||
))
|
||||
runCurrentTask()
|
||||
}
|
||||
ActionButton(text = translation[if (hasSelection) "delete_selection_option" else "delete_all_option"], icon = Icons.Rounded.DeleteForever) {
|
||||
launchMessagingTask(MessagingTaskType.DELETE, listOf(MessagingConstraints.USER_ID(messagingBridge.myUserId))) { message ->
|
||||
launchMessagingTask(MessagingTaskType.DELETE, listOf(MessagingConstraints.USER_ID(messagingBridge.myUserId), {
|
||||
contentType != ContentType.STATUS.id
|
||||
})) { message ->
|
||||
coroutineScope.launch {
|
||||
message.contentType = ContentType.STATUS.id
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user