mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Added send reaction, copy text & delete options to chat message long press menu
This commit is contained in:
parent
8269228b8a
commit
faf3e887b9
5 changed files with 113 additions and 5 deletions
|
|
@ -20,6 +20,9 @@
|
|||
package org.linphone.ui.main.chat.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RenderEffect
|
||||
import android.graphics.Shader
|
||||
|
|
@ -185,16 +188,33 @@ class ConversationFragment : GenericFragment() {
|
|||
null,
|
||||
false
|
||||
)
|
||||
|
||||
layout.root.setOnClickListener {
|
||||
dialog.dismiss()
|
||||
binding.root.setRenderEffect(null)
|
||||
}
|
||||
|
||||
layout.setDeleteClickListener {
|
||||
viewModel.deleteChatMessage(chatMessageModel)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
layout.setCopyClickListener {
|
||||
val text = chatMessageModel.text
|
||||
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val label = "Message"
|
||||
clipboard.setPrimaryClip(ClipData.newPlainText(label, text))
|
||||
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
layout.model = chatMessageModel
|
||||
chatMessageModel.dismissLongPressMenuEvent.observe(viewLifecycleOwner) {
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
val screenY = yPosition - AppUtils.getDimension(
|
||||
R.dimen.chat_bubble_long_press_menu_bubble_offset
|
||||
)
|
||||
|
||||
val rect = Rect()
|
||||
binding.root.getGlobalVisibleRect(rect)
|
||||
val height = rect.height()
|
||||
|
|
@ -209,6 +229,9 @@ class ConversationFragment : GenericFragment() {
|
|||
set.applyTo(constraintLayout)
|
||||
|
||||
dialog.setContentView(layout.root)
|
||||
dialog.setOnDismissListener {
|
||||
binding.root.setRenderEffect(null)
|
||||
}
|
||||
|
||||
dialog.window
|
||||
?.setLayout(
|
||||
|
|
|
|||
|
|
@ -22,15 +22,25 @@ package org.linphone.ui.main.chat.model
|
|||
import androidx.annotation.UiThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatMessage
|
||||
import org.linphone.core.ChatMessageListenerStub
|
||||
import org.linphone.core.ChatMessageReaction
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.contacts.model.ContactAvatarModel
|
||||
import org.linphone.utils.Event
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
import org.linphone.utils.TimestampUtils
|
||||
|
||||
class ChatMessageModel @WorkerThread constructor(
|
||||
chatMessage: ChatMessage,
|
||||
val chatMessage: ChatMessage,
|
||||
val avatarModel: ContactAvatarModel
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "[Chat Message Model]"
|
||||
}
|
||||
|
||||
val id = chatMessage.messageId
|
||||
|
||||
val isOutgoing = chatMessage.isOutgoing
|
||||
|
|
@ -45,13 +55,47 @@ class ChatMessageModel @WorkerThread constructor(
|
|||
|
||||
val time = TimestampUtils.toString(timestamp)
|
||||
|
||||
val dismissLongPressMenuEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
private val chatMessageListener = object : ChatMessageListenerStub() {
|
||||
@WorkerThread
|
||||
override fun onMsgStateChanged(message: ChatMessage, messageState: ChatMessage.State?) {
|
||||
state.postValue(chatMessage.state)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onNewMessageReaction(message: ChatMessage, reaction: ChatMessageReaction) {
|
||||
Log.i(
|
||||
"$TAG New reaction [${reaction.body}] from [${reaction.fromAddress.asStringUriOnly()}] for chat message with ID [$id]"
|
||||
)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onReactionRemoved(message: ChatMessage, address: Address) {
|
||||
Log.i("$TAG A reaction was removed for chat message with ID [$id]")
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
chatMessage.addListener(chatMessageListener)
|
||||
state.postValue(chatMessage.state)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun destroy() {
|
||||
chatMessage.removeListener(chatMessageListener)
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun onLongClick(): Boolean {
|
||||
return true
|
||||
fun sendReaction(emoji: String) {
|
||||
coreContext.postOnCoreThread {
|
||||
Log.i("$TAG Sending reaction [$emoji] to chat message with ID [$id]")
|
||||
val reaction = chatMessage.createReaction(emoji)
|
||||
reaction.send()
|
||||
dismissLongPressMenuEvent.postValue(Event(true))
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
|
|
|||
|
|
@ -35,4 +35,11 @@ class EventLogModel @WorkerThread constructor(eventLog: EventLog, avatarModel: C
|
|||
}
|
||||
|
||||
val notifyId = eventLog.notifyId
|
||||
|
||||
@WorkerThread
|
||||
fun destroy() {
|
||||
if (model is ChatMessageModel) {
|
||||
model.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.linphone.core.EventLog
|
|||
import org.linphone.core.Factory
|
||||
import org.linphone.core.Friend
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.chat.model.ChatMessageModel
|
||||
import org.linphone.ui.main.chat.model.EventLogModel
|
||||
import org.linphone.ui.main.contacts.model.ContactAvatarModel
|
||||
import org.linphone.ui.main.contacts.model.GroupAvatarModel
|
||||
|
|
@ -129,6 +130,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
|
|||
|
||||
coreContext.postOnCoreThread {
|
||||
chatRoom.removeListener(chatRoomListener)
|
||||
events.value.orEmpty().forEach(EventLogModel::destroy)
|
||||
avatarsMap.values.forEach(ContactAvatarModel::destroy)
|
||||
}
|
||||
}
|
||||
|
|
@ -186,6 +188,25 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun deleteChatMessage(chatMessageModel: ChatMessageModel) {
|
||||
coreContext.postOnCoreThread {
|
||||
val eventsLogs = events.value.orEmpty()
|
||||
val found = eventsLogs.find {
|
||||
it.model == chatMessageModel
|
||||
}
|
||||
if (found != null) {
|
||||
val list = arrayListOf<EventLogModel>()
|
||||
list.addAll(eventsLogs)
|
||||
list.remove(found)
|
||||
events.postValue(list)
|
||||
}
|
||||
|
||||
Log.i("$TAG Deleting message id [${chatMessageModel.id}]")
|
||||
chatRoom.deleteMessage(chatMessageModel.chatMessage)
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun configureChatRoom() {
|
||||
computeComposingLabel()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<variable
|
||||
name="copyClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="deleteClickListener"
|
||||
type="View.OnClickListener" />
|
||||
<variable
|
||||
name="model"
|
||||
type="org.linphone.ui.main.chat.model.ChatMessageModel" />
|
||||
|
|
@ -35,6 +41,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/thumbs_up"
|
||||
android:onClick="@{() -> model.sendReaction(@string/emoji_thumbs_up)}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
|
|
@ -48,6 +55,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/love"
|
||||
android:onClick="@{() -> model.sendReaction(@string/emoji_love)}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
|
|
@ -60,6 +68,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/laughing"
|
||||
android:onClick="@{() -> model.sendReaction(@string/emoji_laughing)}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
|
|
@ -72,6 +81,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/surprised"
|
||||
android:onClick="@{() -> model.sendReaction(@string/emoji_surprised)}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
|
|
@ -84,6 +94,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tear"
|
||||
android:onClick="@{() -> model.sendReaction(@string/emoji_tear)}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
|
|
@ -149,6 +160,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/copy"
|
||||
android:onClick="@{copyClickListener}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/menu_copy_chat_message"
|
||||
|
|
@ -175,6 +187,7 @@
|
|||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/delete"
|
||||
android:onClick="@{deleteClickListener}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/menu_delete_selected_item"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue