Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
weblate committed Jun 9, 2024
2 parents a85fbda + bcbf54b commit 2ab925c
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class LoggerHistoryRoot : Routes.Route() {
})

val edits by rememberAsyncMutableState(defaultValue = emptyList()) {
loggerWrapper.getMessageEdits(selectedConversation!!, message.messageId)
loggerWrapper.getChatEdits(selectedConversation!!, message.messageId)
}
edits.forEach { messageEdit ->
val date = remember {
Expand All @@ -152,10 +152,10 @@ class LoggerHistoryRoot : Routes.Route() {
Text(
modifier = Modifier.pointerInput(Unit) {
detectTapGestures(onLongPress = {
context.androidContext.copyToClipboard(messageEdit.messageText)
context.androidContext.copyToClipboard(messageEdit.message)
})
}.fillMaxWidth().padding(start = 4.dp),
text = messageEdit.messageText + " (edited at $date)",
text = messageEdit.message + " (edited at $date)",
fontWeight = FontWeight.Light,
fontStyle = FontStyle.Italic,
fontSize = 12.sp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package me.rhunk.snapenhance.bridge.logger;

parcelable LoggedChatEdit {
long timestamp;
String message;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.rhunk.snapenhance.bridge.logger;

import me.rhunk.snapenhance.bridge.logger.BridgeLoggedMessage;
import me.rhunk.snapenhance.bridge.logger.LoggedChatEdit;

interface LoggerInterface {
/**
Expand Down Expand Up @@ -38,4 +39,6 @@ interface LoggerInterface {
String eventType,
String data
);

List<LoggedChatEdit> getChatEdits(String conversationId, long messageId);
}
1 change: 1 addition & 0 deletions common/src/main/assets/lang/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,7 @@
"preview_button": "Preview",
"download_button": "Download",
"delete_logged_message_button": "Delete Logged Message",
"show_chat_edit_history": "Show Chat Edit History",
"convert_message": "Convert Message",
"edit_message": "Edit Message"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import kotlinx.coroutines.*
import me.rhunk.snapenhance.bridge.logger.BridgeLoggedMessage
import me.rhunk.snapenhance.bridge.logger.LoggedChatEdit
import me.rhunk.snapenhance.bridge.logger.LoggerInterface
import me.rhunk.snapenhance.common.bridge.InternalFileHandleType
import me.rhunk.snapenhance.common.data.StoryData
Expand All @@ -20,11 +21,6 @@ import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
import java.io.File
import java.util.UUID

class LoggedMessageEdit(
val timestamp: Long,
val messageText: String
)

class LoggedMessage(
val messageId: Long,
val conversationId: String,
Expand Down Expand Up @@ -422,17 +418,17 @@ class LoggerWrapper(
return ConversationInfo(conversationId, participantSize, groupTitle, usernames)
}

fun getMessageEdits(conversationId: String, messageId: Long): List<LoggedMessageEdit> {
val edits = mutableListOf<LoggedMessageEdit>()
override fun getChatEdits(conversationId: String, messageId: Long): List<LoggedChatEdit> {
val edits = mutableListOf<LoggedChatEdit>()
database.rawQuery(
"SELECT added_timestamp, message_text FROM chat_edits WHERE conversation_id = ? AND message_id = ?",
"SELECT added_timestamp, message_text FROM chat_edits WHERE conversation_id = ? AND message_id = ? ORDER BY added_timestamp ASC",
arrayOf(conversationId, messageId.toString())
).use {
while (it.moveToNext()) {
edits.add(LoggedMessageEdit(
timestamp = it.getLongOrNull("added_timestamp") ?: continue,
messageText = it.getStringOrNull("message_text") ?: continue
))
).use { cursor ->
while (cursor.moveToNext()) {
edits.add(LoggedChatEdit().apply {
timestamp = cursor.getLongOrNull("added_timestamp") ?: return@apply
message = cursor.getStringOrNull("message_text")
}.takeIf { it.timestamp > 0L } ?: continue)
}
}
return edits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.os.DeadObjectException
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import me.rhunk.snapenhance.bridge.logger.BridgeLoggedMessage
import me.rhunk.snapenhance.bridge.logger.LoggedChatEdit
import me.rhunk.snapenhance.common.data.ContentType
import me.rhunk.snapenhance.common.data.MessageState
import me.rhunk.snapenhance.common.data.QuotedMessageContentStatus
Expand Down Expand Up @@ -76,6 +77,11 @@ class MessageLogger : Feature("MessageLogger",
}
}

fun getChatEdits(conversationId: String, clientMessageId: Long): List<LoggedChatEdit> {
val uniqueMessageId = makeUniqueIdentifier(conversationId, clientMessageId) ?: return emptyList()
return loggerInterface.getChatEdits(conversationId, uniqueMessageId)
}

private fun computeMessageIdentifier(conversationId: String, orderKey: Long) = (orderKey.toString() + conversationId).longHashCode()

private fun makeUniqueIdentifier(conversationId: String, clientMessageId: Long): Long? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.Button
import android.widget.LinearLayout
import me.rhunk.snapenhance.bridge.logger.LoggedChatEdit
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
Expand Down Expand Up @@ -131,6 +132,30 @@ class ChatActionMenu : AbstractMenu() {
}
}
})

injectButton(Button(viewGroup.context).apply {
var chatEdits = emptyList<LoggedChatEdit>()
text = this@ChatActionMenu.context.translation["chat_action_menu.show_chat_edit_history"]
setOnClickListener {
menuViewInjector.menu(NewChatActionMenu::class)?.showChatEditHistory(chatEdits)
}
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
visibility = View.GONE
chatEdits = this@ChatActionMenu.context.feature(MessageLogger::class).getChatEdits(
messaging.openedConversationUUID.toString(),
messaging.lastFocusedMessageId,
)
if (chatEdits.isEmpty()) return
visibility = View.VISIBLE
}

override fun onViewDetachedFromWindow(v: View) {
visibility = View.GONE
chatEdits = emptyList()
}
})
})
}

if (context.config.experimental.editMessage.get() && messaging.conversationManager?.isEditMessageSupported() == true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,32 @@ import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.icons.Icons
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
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material.icons.outlined.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import me.rhunk.snapenhance.bridge.logger.LoggedChatEdit
import me.rhunk.snapenhance.common.data.ContentType
import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
import me.rhunk.snapenhance.common.ui.createComposeView
import me.rhunk.snapenhance.common.ui.rememberAsyncMutableState
import me.rhunk.snapenhance.common.util.ktx.copyToClipboard
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
import me.rhunk.snapenhance.common.util.protobuf.ProtoWriter
Expand All @@ -48,9 +51,11 @@ import me.rhunk.snapenhance.core.ui.debugEditText
import me.rhunk.snapenhance.core.ui.iterateParent
import me.rhunk.snapenhance.core.ui.menu.AbstractMenu
import me.rhunk.snapenhance.core.ui.triggerCloseTouchEvent
import me.rhunk.snapenhance.core.util.ktx.getIdentifier
import me.rhunk.snapenhance.core.util.ktx.isDarkTheme
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.core.util.ktx.vibrateLongPress
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Date
import kotlin.io.encoding.Base64
Expand All @@ -70,6 +75,32 @@ class NewChatActionMenu : AbstractMenu() {
}
}

fun showChatEditHistory(
edits: List<LoggedChatEdit>,
) {
createComposeAlertDialog(context.mainActivity!!) {
LazyColumn(
modifier = Modifier.padding(16.dp),
) {
itemsIndexed(edits) { index, edit ->
Column(
modifier = Modifier.padding(8.dp).fillMaxWidth().pointerInput(Unit) {
detectTapGestures(
onLongPress = {
context.androidContext.copyToClipboard(edit.message)
}
)
},
horizontalAlignment = Alignment.Start,
) {
Text(edit.message)
Text(text = DateFormat.getDateTimeInstance().format(edit.timestamp) + " (${index + 1})", fontSize = 12.sp, fontWeight = FontWeight.Light)
}
}
}
}.show()
}

fun editCurrentMessage(
localContext: Context,
dismissActionMenu: () -> Unit,
Expand Down Expand Up @@ -267,6 +298,11 @@ class NewChatActionMenu : AbstractMenu() {

val composeView = createComposeView(event.view.context) {
val primaryColor = remember { if (event.view.context.isDarkTheme()) Color.White else Color.Black }
val avenirNextMediumFont = remember {
FontFamily(
Font(context.resources.getIdentifier("avenir_next_medium", "font"), FontWeight.Medium)
)
}

@Composable
fun ListButton(
Expand All @@ -288,7 +324,7 @@ class NewChatActionMenu : AbstractMenu() {
tint = primaryColor,
contentDescription = text
)
Text(text, color = primaryColor)
Text(text, color = primaryColor, fontFamily = avenirNextMediumFont, fontSize = 16.sp)
}
Spacer(modifier = Modifier
.height(1.dp)
Expand All @@ -300,11 +336,11 @@ class NewChatActionMenu : AbstractMenu() {
modifier = Modifier.fillMaxWidth(),
) {
if (context.config.downloader.downloadContextMenu.get()) {
ListButton(icon = Icons.Default.RemoveRedEye, text = context.translation["chat_action_menu.preview_button"], modifier = Modifier.clickable {
ListButton(icon = Icons.Outlined.RemoveRedEye, text = context.translation["chat_action_menu.preview_button"], modifier = Modifier.clickable {
closeActionMenu()
mediaDownloader.onMessageActionMenu(true)
})
ListButton(icon = Icons.Default.Download, text = context.translation["chat_action_menu.download_button"], modifier = Modifier.pointerInput(Unit) {
ListButton(icon = Icons.Outlined.Download, text = context.translation["chat_action_menu.download_button"], modifier = Modifier.pointerInput(Unit) {
detectTapGestures(
onTap = {
closeActionMenu()
Expand All @@ -319,7 +355,7 @@ 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 {
ListButton(icon = Icons.Outlined.Edit, text = context.translation["chat_action_menu.edit_message"], modifier = Modifier.clickable {
editCurrentMessage(event.view.context) {
context.runOnUiThread {
closeActionMenu()
Expand All @@ -329,7 +365,21 @@ class NewChatActionMenu : AbstractMenu() {
}

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 {
val chatEdits by rememberAsyncMutableState(defaultValue = null) {
context.feature(MessageLogger::class).getChatEdits(
messaging.openedConversationUUID.toString(),
messaging.lastFocusedMessageId
)
}

if (chatEdits != null && chatEdits?.isNotEmpty() == true) {
ListButton(icon = Icons.Outlined.History, text = context.translation["chat_action_menu.show_chat_edit_history"], modifier = Modifier.clickable {
closeActionMenu()
showChatEditHistory(chatEdits!!)
})
}

ListButton(icon = Icons.Outlined.BookmarkRemove, text = context.translation["chat_action_menu.delete_logged_message_button"], modifier = Modifier.clickable {
closeActionMenu()
context.executeAsync {
messageLogger.deleteMessage(messaging.openedConversationUUID.toString(), messaging.lastFocusedMessageId)
Expand Down

0 comments on commit 2ab925c

Please sign in to comment.