move "open thread" to context menu + add threads system message

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2025-07-04 14:34:39 +02:00
parent ae2d3d2a76
commit fd10937d68
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
9 changed files with 75 additions and 37 deletions

View File

@ -167,8 +167,7 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
// parent message handling // parent message handling
val chatActivity = commonMessageInterface as ChatActivity val chatActivity = commonMessageInterface as ChatActivity
binding.messageQuote.quotedChatMessageView.visibility = binding.messageQuote.quotedChatMessageView.visibility =
// TODO replace message.parentMessageId with topmostParentId if (chatActivity.threadId == message.threadId) {
if (chatActivity.threadId == message.parentMessageId) {
View.GONE View.GONE
} else if (!message.isDeleted && message.parentMessageId != null) { } else if (!message.isDeleted && message.parentMessageId != null) {
processParentMessage(message) processParentMessage(message)
@ -372,14 +371,6 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
viewThemeUtils viewThemeUtils
) )
// TODO replace message.parentMessageId!! with topmostParentId (=threadId)
binding.messageQuote.threadIcon.setOnClickListener {
chatActivity.openThread(
chatActivity.roomToken,
message.parentMessageId!!
)
}
viewThemeUtils.talk.themeParentMessage( viewThemeUtils.talk.themeParentMessage(
parentChatMessage, parentChatMessage,
message, message,

View File

@ -178,13 +178,18 @@ class OutcomingTextMessageViewHolder(itemView: View) :
} }
viewThemeUtils.platform.colorTextView(binding.messageTime, ColorRole.ON_SURFACE_VARIANT) viewThemeUtils.platform.colorTextView(binding.messageTime, ColorRole.ON_SURFACE_VARIANT)
setBubbleOnChatMessage(message) setBubbleOnChatMessage(message)
// parent message handling // parent message handling
if (!message.isDeleted && message.parentMessageId != null) { val chatActivity = commonMessageInterface as ChatActivity
processParentMessage(message) binding.messageQuote.quotedChatMessageView.visibility =
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE if (chatActivity.threadId == message.threadId) {
} else { View.GONE
binding.messageQuote.quotedChatMessageView.visibility = View.GONE } else if (!message.isDeleted && message.parentMessageId != null) {
} processParentMessage(message)
View.VISIBLE
} else {
View.GONE
}
binding.checkMark.visibility = View.INVISIBLE binding.checkMark.visibility = View.INVISIBLE
binding.sendingProgress.visibility = View.GONE binding.sendingProgress.visibility = View.GONE
@ -199,8 +204,6 @@ class OutcomingTextMessageViewHolder(itemView: View) :
updateStatus(R.drawable.ic_check, context.resources?.getString(R.string.nc_message_sent)) updateStatus(R.drawable.ic_check, context.resources?.getString(R.string.nc_message_sent))
} }
val chatActivity = commonMessageInterface as ChatActivity
chatActivity.lifecycleScope.launch { chatActivity.lifecycleScope.launch {
if (message.isTemporary && !networkMonitor.isOnline.value) { if (message.isTemporary && !networkMonitor.isOnline.value) {
updateStatus( updateStatus(

View File

@ -4130,13 +4130,15 @@ class ChatActivity :
private fun isChatThread(): Boolean = threadId != null && threadId!! > 0 private fun isChatThread(): Boolean = threadId != null && threadId!! > 0
fun openThread(roomToken: String, threadId: Long) { fun openThread(chatMessage: ChatMessage) {
val bundle = Bundle() chatMessage.threadId?.let {
bundle.putString(KEY_ROOM_TOKEN, roomToken) val bundle = Bundle()
bundle.putLong(KEY_THREAD_ID, threadId) bundle.putString(KEY_ROOM_TOKEN, roomToken)
val chatIntent = Intent(context, ChatActivity::class.java) bundle.putLong(KEY_THREAD_ID, it)
chatIntent.putExtras(bundle) val chatIntent = Intent(context, ChatActivity::class.java)
startActivity(chatIntent) chatIntent.putExtras(bundle)
startActivity(chatIntent)
}
} }
override fun joinAudioCall() { override fun joinAudioCall() {

View File

@ -429,7 +429,8 @@ data class ChatMessage(
AVATAR_SET, AVATAR_SET,
AVATAR_REMOVED, AVATAR_REMOVED,
FEDERATED_USER_ADDED, FEDERATED_USER_ADDED,
FEDERATED_USER_REMOVED FEDERATED_USER_REMOVED,
THREAD_CREATED
} }
companion object { companion object {

View File

@ -71,6 +71,7 @@ import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.RECORDIN
import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.RECORDING_STOPPED import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.RECORDING_STOPPED
import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.USER_ADDED import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.USER_ADDED
import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.USER_REMOVED import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.USER_REMOVED
import com.nextcloud.talk.chat.data.model.ChatMessage.SystemMessageType.THREAD_CREATED
/* /*
* see https://nextcloud-talk.readthedocs.io/en/latest/chat/#system-messages * see https://nextcloud-talk.readthedocs.io/en/latest/chat/#system-messages
@ -141,6 +142,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
"avatar_removed" -> AVATAR_REMOVED "avatar_removed" -> AVATAR_REMOVED
"federated_user_added" -> FEDERATED_USER_ADDED "federated_user_added" -> FEDERATED_USER_ADDED
"federated_user_removed" -> FEDERATED_USER_REMOVED "federated_user_removed" -> FEDERATED_USER_REMOVED
"thread_created" -> THREAD_CREATED
else -> DUMMY else -> DUMMY
} }
} }
@ -210,6 +212,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
AVATAR_REMOVED -> "avatar_removed" AVATAR_REMOVED -> "avatar_removed"
FEDERATED_USER_ADDED -> "federated_user_added" FEDERATED_USER_ADDED -> "federated_user_added"
FEDERATED_USER_REMOVED -> "federated_user_removed" FEDERATED_USER_REMOVED -> "federated_user_removed"
THREAD_CREATED -> "thread_created"
else -> "" else -> ""
} }
} }

View File

@ -144,6 +144,7 @@ class MessageActionsDialog(
currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
isOnline isOnline
) )
initMenuOpenThread(message.isThread && chatActivity.threadId == null)
initMenuEditMessage(isMessageEditable) initMenuEditMessage(isMessageEditable)
initMenuDeleteMessage(showMessageDeletionButton && isOnline) initMenuDeleteMessage(showMessageDeletionButton && isOnline)
initMenuForwardMessage( initMenuForwardMessage(
@ -411,6 +412,17 @@ class MessageActionsDialog(
dialogMessageActionsBinding.menuReplyPrivately.visibility = getVisibility(visible) dialogMessageActionsBinding.menuReplyPrivately.visibility = getVisibility(visible)
} }
private fun initMenuOpenThread(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuOpenThread.setOnClickListener {
chatActivity.openThread(message)
dismiss()
}
}
dialogMessageActionsBinding.menuOpenThread.visibility = getVisibility(visible)
}
private fun initMenuReplyToMessage(visible: Boolean) { private fun initMenuReplyToMessage(visible: Boolean) {
if (visible) { if (visible) {
dialogMessageActionsBinding.menuReplyToMessage.setOnClickListener { dialogMessageActionsBinding.menuReplyToMessage.setOnClickListener {

View File

@ -282,6 +282,39 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/menu_open_thread"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_open_thread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:paddingStart="@dimen/standard_padding"
android:paddingEnd="@dimen/zero"
android:src="@drawable/outline_thread_unread_24"
app:tint="@color/high_emphasis_menu_icon" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_open_thread"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/standard_padding"
android:text="@string/open_thread"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/menu_notify_message" android:id="@+id/menu_notify_message"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -84,17 +84,6 @@
</com.google.android.flexbox.FlexboxLayout> </com.google.android.flexbox.FlexboxLayout>
<ImageButton
android:id="@+id/threadIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@color/transparent"
android:src="@drawable/outline_thread_unread_24" />
<ImageButton <ImageButton
android:id="@+id/cancelReplyButton" android:id="@+id/cancelReplyButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -545,6 +545,10 @@ How to translate with transifex:
<string name="typing_1_other">and 1 other is typing …</string> <string name="typing_1_other">and 1 other is typing …</string>
<string name="typing_x_others">and %1$s others are typing …</string> <string name="typing_x_others">and %1$s others are typing …</string>
<string name="deck_card_description">%1$s in %2$s</string> <string name="deck_card_description">%1$s in %2$s</string>
<string name="open_thread">See thread</string>
<string name="reply_in_thread">Reply in thread</string>
<!-- Upload --> <!-- Upload -->
<string name="nc_add_file">Add to conversation</string> <string name="nc_add_file">Add to conversation</string>
<string name="nc_upload_picture_from_cam">Take photo</string> <string name="nc_upload_picture_from_cam">Take photo</string>