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

View File

@ -178,13 +178,18 @@ class OutcomingTextMessageViewHolder(itemView: View) :
}
viewThemeUtils.platform.colorTextView(binding.messageTime, ColorRole.ON_SURFACE_VARIANT)
setBubbleOnChatMessage(message)
// parent message handling
if (!message.isDeleted && message.parentMessageId != null) {
processParentMessage(message)
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} else {
binding.messageQuote.quotedChatMessageView.visibility = View.GONE
}
val chatActivity = commonMessageInterface as ChatActivity
binding.messageQuote.quotedChatMessageView.visibility =
if (chatActivity.threadId == message.threadId) {
View.GONE
} else if (!message.isDeleted && message.parentMessageId != null) {
processParentMessage(message)
View.VISIBLE
} else {
View.GONE
}
binding.checkMark.visibility = View.INVISIBLE
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))
}
val chatActivity = commonMessageInterface as ChatActivity
chatActivity.lifecycleScope.launch {
if (message.isTemporary && !networkMonitor.isOnline.value) {
updateStatus(

View File

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

View File

@ -429,7 +429,8 @@ data class ChatMessage(
AVATAR_SET,
AVATAR_REMOVED,
FEDERATED_USER_ADDED,
FEDERATED_USER_REMOVED
FEDERATED_USER_REMOVED,
THREAD_CREATED
}
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.USER_ADDED
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
@ -141,6 +142,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
"avatar_removed" -> AVATAR_REMOVED
"federated_user_added" -> FEDERATED_USER_ADDED
"federated_user_removed" -> FEDERATED_USER_REMOVED
"thread_created" -> THREAD_CREATED
else -> DUMMY
}
}
@ -210,6 +212,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
AVATAR_REMOVED -> "avatar_removed"
FEDERATED_USER_ADDED -> "federated_user_added"
FEDERATED_USER_REMOVED -> "federated_user_removed"
THREAD_CREATED -> "thread_created"
else -> ""
}
}

View File

@ -144,6 +144,7 @@ class MessageActionsDialog(
currentConversation?.type != ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
isOnline
)
initMenuOpenThread(message.isThread && chatActivity.threadId == null)
initMenuEditMessage(isMessageEditable)
initMenuDeleteMessage(showMessageDeletionButton && isOnline)
initMenuForwardMessage(
@ -411,6 +412,17 @@ class MessageActionsDialog(
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) {
if (visible) {
dialogMessageActionsBinding.menuReplyToMessage.setOnClickListener {

View File

@ -282,6 +282,39 @@
</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
android:id="@+id/menu_notify_message"
android:layout_width="match_parent"

View File

@ -84,17 +84,6 @@
</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
android:id="@+id/cancelReplyButton"
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_x_others">and %1$s others are typing …</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 -->
<string name="nc_add_file">Add to conversation</string>
<string name="nc_upload_picture_from_cam">Take photo</string>