Added menu

This commit is contained in:
Sylvain Berfini 2023-06-22 16:28:32 +02:00
parent c0169e7bcb
commit 09ca9b5351
7 changed files with 175 additions and 20 deletions

View file

@ -138,6 +138,11 @@ class ChatRoomData(val chatRoom: ChatRoom) {
chatRoomDataListener?.onClicked()
}
fun onLongClicked(): Boolean {
chatRoomDataListener?.onLongClicked()
return true
}
private fun computeLastMessageImdnIcon(message: ChatMessage) {
val state = message.state
showLastMessageImdnIcon.postValue(
@ -209,4 +214,6 @@ class ChatRoomData(val chatRoom: ChatRoom) {
abstract class ChatRoomDataListener {
abstract fun onClicked()
abstract fun onLongClicked()
}

View file

@ -19,6 +19,7 @@
*/
package org.linphone.ui.conversations
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -32,12 +33,22 @@ import org.linphone.utils.LinphoneUtils
class ConversationMenuDialogFragment(
private val chatRoom: ChatRoom,
private val mutedCallback: ((Boolean) -> Unit)? = null
private val onDismiss: (() -> Unit)? = null
) : BottomSheetDialogFragment() {
companion object {
const val TAG = "ConversationMenuDialogFragment"
}
override fun onCancel(dialog: DialogInterface) {
onDismiss?.invoke()
super.onCancel(dialog)
}
override fun onDismiss(dialog: DialogInterface) {
onDismiss?.invoke()
super.onDismiss(dialog)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -47,7 +58,7 @@ class ConversationMenuDialogFragment(
val id = LinphoneUtils.getChatRoomId(chatRoom)
view.isMuted = corePreferences.chatRoomMuted(id)
view.isRead = chatRoom.unreadMessagesCount == 0 // FIXME: danger?
view.isRead = chatRoom.unreadMessagesCount == 0
view.setMarkAsReadClickListener {
coreContext.postOnCoreThread { core ->
@ -56,15 +67,9 @@ class ConversationMenuDialogFragment(
dismiss()
}
view.setCallClickListener {
// TODO
dismiss()
}
view.setMuteClickListener {
coreContext.postOnCoreThread { core ->
corePreferences.muteChatRoom(id, true)
mutedCallback?.invoke(true)
}
dismiss()
}
@ -72,7 +77,6 @@ class ConversationMenuDialogFragment(
view.setUnMuteClickListener {
coreContext.postOnCoreThread { core ->
corePreferences.muteChatRoom(id, false)
mutedCallback?.invoke(false)
}
dismiss()
}

View file

@ -27,6 +27,7 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.navigation.navGraphViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.linphone.R
import org.linphone.databinding.ConversationsFragmentBinding
@ -37,6 +38,26 @@ class ConversationsFragment : Fragment() {
)
private lateinit var adapter: ConversationsListAdapter
private val observer = object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
scrollToTop()
}
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
if (positionStart == 0 && itemCount == 1) {
scrollToTop()
}
}
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
scrollToTop()
}
}
override fun onDestroyView() {
binding.conversationsList.adapter = null
adapter.unregisterAdapterDataObserver(observer)
super.onDestroyView()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -59,6 +80,7 @@ class ConversationsFragment : Fragment() {
binding.lifecycleOwner = viewLifecycleOwner
adapter = ConversationsListAdapter(viewLifecycleOwner)
adapter.registerAdapterDataObserver(observer)
binding.conversationsList.setHasFixedSize(true)
binding.conversationsList.adapter = adapter
@ -66,10 +88,10 @@ class ConversationsFragment : Fragment() {
it.consume { data ->
}
}
adapter.chatRoomMenuClickedEvent.observe(viewLifecycleOwner) {
adapter.chatRoomLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { data ->
val modalBottomSheet = ConversationMenuDialogFragment(data.chatRoom) { muted ->
data.isMuted.postValue(muted)
val modalBottomSheet = ConversationMenuDialogFragment(data.chatRoom) {
adapter.resetSelection()
}
modalBottomSheet.show(parentFragmentManager, ConversationMenuDialogFragment.TAG)
}
@ -90,4 +112,8 @@ class ConversationsFragment : Fragment() {
}
}
}
private fun scrollToTop() {
binding.conversationsList.scrollToPosition(0)
}
}

View file

@ -34,9 +34,15 @@ import org.linphone.utils.Event
class ConversationsListAdapter(
private val viewLifecycleOwner: LifecycleOwner
) : ListAdapter<ChatRoomData, RecyclerView.ViewHolder>(ConversationDiffCallback()) {
val chatRoomClickedEvent = MutableLiveData<Event<ChatRoomData>>()
val chatRoomClickedEvent: MutableLiveData<Event<ChatRoomData>> by lazy {
MutableLiveData<Event<ChatRoomData>>()
}
val chatRoomMenuClickedEvent = MutableLiveData<Event<ChatRoomData>>()
val chatRoomLongClickedEvent: MutableLiveData<Event<ChatRoomData>> by lazy {
MutableLiveData<Event<ChatRoomData>>()
}
var selectedAdapterPosition = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val binding: ChatRoomListCellBinding = DataBindingUtil.inflate(
@ -52,6 +58,11 @@ class ConversationsListAdapter(
(holder as ViewHolder).bind(getItem(position))
}
fun resetSelection() {
notifyItemChanged(selectedAdapterPosition)
selectedAdapterPosition = -1
}
inner class ViewHolder(
val binding: ChatRoomListCellBinding
) : RecyclerView.ViewHolder(binding.root) {
@ -62,10 +73,18 @@ class ConversationsListAdapter(
lifecycleOwner = viewLifecycleOwner
executePendingBindings()
binding.root.isSelected = bindingAdapterPosition == selectedAdapterPosition
chatRoomData.chatRoomDataListener = object : ChatRoomDataListener() {
override fun onClicked() {
chatRoomClickedEvent.value = Event(chatRoomData)
}
override fun onLongClicked() {
selectedAdapterPosition = bindingAdapterPosition
binding.root.isSelected = true
chatRoomLongClickedEvent.value = Event(chatRoomData)
}
}
}
}

View file

@ -15,6 +15,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> data.onClicked()}"
android:onLongClick="@{() -> data.onLongClicked()}"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/conversation_cell_background">

View file

@ -7,15 +7,15 @@
<variable
name="markAsReadClickListener"
type="View.OnClickListener" />
<variable
name="callClickListener"
type="View.OnClickListener" />
<variable
name="muteClickListener"
type="View.OnClickListener" />
<variable
name="unMuteClickListener"
type="View.OnClickListener" />
<variable
name="callClickListener"
type="View.OnClickListener" />
<variable
name="deleteClickListener"
type="View.OnClickListener" />
@ -27,13 +27,109 @@
type="Boolean" />
</data>
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:background="@color/separator">
<TextView
android:id="@+id/mark_as_read"
android:onClick="@{markAsReadClickListener}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Marquer comme lu"
android:padding="20dp"
android:visibility="@{isRead ? View.GONE : View.VISIBLE}"
android:textSize="17sp"
android:textColor="@color/gray_1"
android:gravity="center"
android:background="@color/gray_2"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toTopOf="@id/mute"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/mute"
android:onClick="@{muteClickListener}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Mettre en sourdine"
android:padding="20dp"
android:visibility="@{isMuted ? View.GONE : View.VISIBLE}"
android:textSize="17sp"
android:textColor="@color/gray_1"
android:gravity="center"
android:background="@color/gray_2"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toTopOf="@id/unmute"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</LinearLayout>
<TextView
android:id="@+id/unmute"
android:onClick="@{unMuteClickListener}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enlever la sourdine"
android:padding="20dp"
android:visibility="@{isMuted ? View.VISIBLE : View.GONE, default=gone}"
android:textSize="17sp"
android:textColor="@color/gray_1"
android:gravity="center"
android:background="@color/gray_2"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toTopOf="@id/call"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/call"
android:onClick="@{callClickListener}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Appeler"
android:padding="20dp"
android:textSize="17sp"
android:textColor="@color/gray_1"
android:gravity="center"
android:background="@color/gray_2"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toTopOf="@id/delete"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/delete"
android:onClick="@{deleteClickListener}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Supprimer la conversation"
android:padding="20dp"
android:textSize="17sp"
android:textColor="@color/red_danger"
android:gravity="center"
android:background="@color/gray_2"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toTopOf="@id/leave"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/leave"
android:onClick="@{deleteClickListener}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Quitter la conversation"
android:padding="20dp"
android:textSize="17sp"
android:textColor="@color/gray_1"
android:gravity="center"
android:background="@color/gray_2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -4,10 +4,12 @@
<color name="black">#000000</color>
<color name="white">#FFFFFF</color>
<color name="red_danger">#DD5F5F</color>
<color name="gray_1">#6C7A87</color>
<color name="gray_2">#F9F9F9</color>
<color name="gray_3">#EEF6F8</color>
<color name="gray_4">#949494</color>
<color name="gray_5">#4E4E4E</color>
<color name="separator">#E5E5EA</color>
</resources>