commit 553664771d64cf519420687200677707e62947ad
parent 865a8953b8e07cc113b9c51b639dddef04817d21
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Tue,  2 Apr 2024 21:08:00 +0200

fix(core/experimental): edit message

Diffstat:
Mcommon/src/main/assets/lang/en_US.json | 3++-
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/AbstractMenu.kt | 1+
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/MenuViewInjector.kt | 16+++++++++++++---
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/ChatActionMenu.kt | 67++-----------------------------------------------------------------
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/NewChatActionMenu.kt | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 98 insertions(+), 69 deletions(-)

diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json @@ -1059,7 +1059,8 @@ "preview_button": "Preview", "download_button": "Download", "delete_logged_message_button": "Delete Logged Message", - "convert_message": "Convert Message" + "convert_message": "Convert Message", + "edit_message": "Edit Message" }, "opera_context_menu": { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/AbstractMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/AbstractMenu.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import me.rhunk.snapenhance.core.ModContext abstract class AbstractMenu { + lateinit var menuViewInjector: MenuViewInjector lateinit var context: ModContext open fun inject(parent: ViewGroup, view: View, viewConsumer: (View) -> Unit) {} diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/MenuViewInjector.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/MenuViewInjector.kt @@ -13,11 +13,12 @@ import me.rhunk.snapenhance.core.features.FeatureLoadParams import me.rhunk.snapenhance.core.features.impl.messaging.Messaging import me.rhunk.snapenhance.core.ui.menu.impl.* import me.rhunk.snapenhance.core.util.ktx.getIdentifier +import kotlin.reflect.KClass @SuppressLint("DiscouragedApi") class MenuViewInjector : Feature("MenuViewInjector", loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) { - override fun asyncOnActivityCreate() { - val menuMap = arrayOf( + private val menuMap by lazy { + arrayOf( NewChatActionMenu(), OperaContextActionMenu(), OperaDownloadIconMenu(), @@ -27,9 +28,18 @@ class MenuViewInjector : Feature("MenuViewInjector", loadParams = FeatureLoadPar SettingsMenu() ).associateBy { it.context = context - it.init() + it.menuViewInjector = this it::class } + } + + @Suppress("UNCHECKED_CAST") + fun <T: AbstractMenu> menu(menuClass: KClass<T>): T? { + return menuMap[menuClass] as? T + } + + override fun asyncOnActivityCreate() { + menuMap.forEach { it.value.init() } val messaging = context.feature(Messaging::class) diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/ChatActionMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/ChatActionMenu.kt @@ -4,17 +4,11 @@ import android.view.View import android.view.ViewGroup import android.view.ViewGroup.MarginLayoutParams import android.widget.Button -import android.widget.EditText import android.widget.LinearLayout -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import me.rhunk.snapenhance.common.util.protobuf.ProtoReader -import me.rhunk.snapenhance.common.util.protobuf.ProtoWriter import me.rhunk.snapenhance.core.features.impl.downloader.MediaDownloader import me.rhunk.snapenhance.core.features.impl.experiments.ConvertMessageLocally import me.rhunk.snapenhance.core.features.impl.messaging.Messaging import me.rhunk.snapenhance.core.features.impl.spying.MessageLogger -import me.rhunk.snapenhance.core.ui.ViewAppearanceHelper import me.rhunk.snapenhance.core.ui.ViewTagState import me.rhunk.snapenhance.core.ui.applyTheme import me.rhunk.snapenhance.core.ui.menu.AbstractMenu @@ -141,66 +135,9 @@ class ChatActionMenu : AbstractMenu() { if (context.config.experimental.editMessage.get() && messaging.conversationManager?.isEditMessageSupported() == true) { injectButton(Button(viewGroup.context).apply button@{ - text = "Edit Message" + text = this@ChatActionMenu.context.translation["chat_action_menu.edit_message"] setOnClickListener { - messaging.conversationManager?.fetchMessage( - messaging.openedConversationUUID.toString(), - messaging.lastFocusedMessageId, - onSuccess = onSuccess@{ message -> - closeActionMenu() - if (message.senderId.toString() != this@ChatActionMenu.context.database.myUserId) { - this@ChatActionMenu.context.shortToast("You can only edit your own messages") - return@onSuccess - } - - val editText = EditText(viewGroup.context).apply { - setText(ProtoReader(message.messageContent?.content ?: return@apply).getString(2, 1) ?: run { - this@ChatActionMenu.context.shortToast("You can only edit text messages") - return@onSuccess - }) - setTextColor(resources.getColor(android.R.color.white, context.theme)) - postDelayed({ - requestFocus() - setSelection(text.length) - context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE) - .let { it as android.view.inputmethod.InputMethodManager } - .showSoftInput(this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT) - }, 200) - } - - this@ChatActionMenu.context.runOnUiThread { - ViewAppearanceHelper.newAlertDialogBuilder(this@ChatActionMenu.context.mainActivity!!) - .setPositiveButton("Save") { _, _ -> - val newMessageContent = ProtoWriter().apply { - from(2) { addString(1, editText.text.toString()) } - }.toByteArray() - message.messageContent?.content = newMessageContent - messaging.conversationManager?.editMessage( - message.messageDescriptor?.conversationId.toString(), - message.messageDescriptor?.messageId ?: return@setPositiveButton, - newMessageContent, - onSuccess = { - this@ChatActionMenu.context.coroutineScope.launch(Dispatchers.Main) { - message.messageMetadata?.isEdited = true - messaging.localUpdateMessage( - message.messageDescriptor?.conversationId.toString(), - message, - forceUpdate = true - ) - } - }, - onError = { - this@ChatActionMenu.context.shortToast("Failed to edit message: $it") - } - ) - } - .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() } - .setView(editText) - .setTitle("Edit message content") - .show() - } - } - ) + menuViewInjector.menu(NewChatActionMenu::class)?.editCurrentMessage(context, closeActionMenu) } }) } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/NewChatActionMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/NewChatActionMenu.kt @@ -3,6 +3,7 @@ package me.rhunk.snapenhance.core.ui.menu.impl import android.content.Context import android.text.format.Formatter import android.view.ViewGroup +import android.widget.EditText import android.widget.LinearLayout import android.widget.ScrollView import androidx.compose.foundation.border @@ -14,6 +15,7 @@ import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.RemoveRedEye import androidx.compose.material.icons.outlined.Image import androidx.compose.material.icons.rounded.BookmarkRemove +import androidx.compose.material.icons.rounded.Edit import androidx.compose.material3.Button import androidx.compose.material3.Card import androidx.compose.material3.Icon @@ -27,10 +29,13 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.unit.dp +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import me.rhunk.snapenhance.common.data.ContentType import me.rhunk.snapenhance.common.ui.createComposeView import me.rhunk.snapenhance.common.util.ktx.copyToClipboard import me.rhunk.snapenhance.common.util.protobuf.ProtoReader +import me.rhunk.snapenhance.common.util.protobuf.ProtoWriter import me.rhunk.snapenhance.common.util.snap.RemoteMediaResolver import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent import me.rhunk.snapenhance.core.features.impl.downloader.MediaDownloader @@ -65,6 +70,71 @@ class NewChatActionMenu : AbstractMenu() { } } + fun editCurrentMessage( + localContext: Context, + dismissActionMenu: () -> Unit, + ) { + val messaging = context.feature(Messaging::class) + messaging.conversationManager?.fetchMessage( + messaging.openedConversationUUID.toString(), + messaging.lastFocusedMessageId, + onSuccess = onSuccess@{ message -> + dismissActionMenu() + if (message.senderId.toString() != context.database.myUserId) { + context.shortToast("You can only edit your own messages") + return@onSuccess + } + + val editText = EditText(localContext).apply { + setText(ProtoReader(message.messageContent?.content ?: return@apply).getString(2, 1) ?: run { + this@NewChatActionMenu.context.shortToast("You can only edit text messages") + return@onSuccess + }) + setTextColor(resources.getColor(android.R.color.white, context.theme)) + postDelayed({ + requestFocus() + setSelection(text.length) + context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE) + .let { it as android.view.inputmethod.InputMethodManager } + .showSoftInput(this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT) + }, 200) + } + + context.runOnUiThread { + ViewAppearanceHelper.newAlertDialogBuilder(context.mainActivity!!) + .setPositiveButton("Save") { _, _ -> + val newMessageContent = ProtoWriter().apply { + from(2) { addString(1, editText.text.toString()) } + }.toByteArray() + message.messageContent?.content = newMessageContent + messaging.conversationManager?.editMessage( + message.messageDescriptor?.conversationId.toString(), + message.messageDescriptor?.messageId ?: return@setPositiveButton, + newMessageContent, + onSuccess = { + context.coroutineScope.launch(Dispatchers.Main) { + message.messageMetadata?.isEdited = true + messaging.localUpdateMessage( + message.messageDescriptor?.conversationId.toString(), + message, + forceUpdate = true + ) + } + }, + onError = { + context.shortToast("Failed to edit message: $it") + } + ) + } + .setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() } + .setView(editText) + .setTitle("Edit message content") + .show() + } + } + ) + } + private val lastFocusedMessage get() = context.database.getConversationMessageFromId(context.feature(Messaging::class).lastFocusedMessageId) @@ -243,6 +313,16 @@ class NewChatActionMenu : AbstractMenu() { }) } + if (context.config.experimental.editMessage.get() && messaging.conversationManager?.isEditMessageSupported() == true) { + ListButton(icon = Icons.Rounded.Edit, text = context.translation["chat_action_menu.edit_message"], modifier = Modifier.clickable { + editCurrentMessage(event.view.context) { + context.runOnUiThread { + closeActionMenu() + } + } + }) + } + if (context.config.messaging.messageLogger.globalState == true) { ListButton(icon = Icons.Rounded.BookmarkRemove, text = context.translation["chat_action_menu.delete_logged_message_button"], modifier = Modifier.clickable { closeActionMenu()