Fixed chat room scroll freeze + system overlay on some launchers + reduce multi contents in chat bubble size
This commit is contained in:
parent
153932ba54
commit
0415629299
6 changed files with 78 additions and 62 deletions
|
@ -37,7 +37,7 @@ import org.linphone.utils.Event
|
||||||
class ChatRoomsListAdapter(
|
class ChatRoomsListAdapter(
|
||||||
selectionVM: ListTopBarViewModel,
|
selectionVM: ListTopBarViewModel,
|
||||||
private val viewLifecycleOwner: LifecycleOwner
|
private val viewLifecycleOwner: LifecycleOwner
|
||||||
) : SelectionListAdapter<ChatRoom, RecyclerView.ViewHolder>(selectionVM, ChatRoomDiffCallback()) {
|
) : SelectionListAdapter<ChatRoomViewModel, RecyclerView.ViewHolder>(selectionVM, ChatRoomDiffCallback()) {
|
||||||
val selectedChatRoomEvent: MutableLiveData<Event<ChatRoom>> by lazy {
|
val selectedChatRoomEvent: MutableLiveData<Event<ChatRoom>> by lazy {
|
||||||
MutableLiveData<Event<ChatRoom>>()
|
MutableLiveData<Event<ChatRoom>>()
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,8 @@ class ChatRoomsListAdapter(
|
||||||
inner class ViewHolder(
|
inner class ViewHolder(
|
||||||
private val binding: ChatRoomListCellBinding
|
private val binding: ChatRoomListCellBinding
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
fun bind(chatRoom: ChatRoom) {
|
fun bind(chatRoomViewModel: ChatRoomViewModel) {
|
||||||
with(binding) {
|
with(binding) {
|
||||||
val chatRoomViewModel = ChatRoomViewModel(chatRoom)
|
|
||||||
viewModel = chatRoomViewModel
|
viewModel = chatRoomViewModel
|
||||||
|
|
||||||
lifecycleOwner = viewLifecycleOwner
|
lifecycleOwner = viewLifecycleOwner
|
||||||
|
@ -83,8 +82,8 @@ class ChatRoomsListAdapter(
|
||||||
if (selectionViewModel.isEditionEnabled.value == true) {
|
if (selectionViewModel.isEditionEnabled.value == true) {
|
||||||
selectionViewModel.onToggleSelect(adapterPosition)
|
selectionViewModel.onToggleSelect(adapterPosition)
|
||||||
} else {
|
} else {
|
||||||
selectedChatRoomEvent.value = Event(chatRoom)
|
selectedChatRoomEvent.value = Event(chatRoomViewModel.chatRoom)
|
||||||
chatRoom.markAsRead()
|
chatRoomViewModel.chatRoom.markAsRead()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,19 +102,18 @@ class ChatRoomsListAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ChatRoomDiffCallback : DiffUtil.ItemCallback<ChatRoom>() {
|
private class ChatRoomDiffCallback : DiffUtil.ItemCallback<ChatRoomViewModel>() {
|
||||||
override fun areItemsTheSame(
|
override fun areItemsTheSame(
|
||||||
oldItem: ChatRoom,
|
oldItem: ChatRoomViewModel,
|
||||||
newItem: ChatRoom
|
newItem: ChatRoomViewModel
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return oldItem.localAddress.weakEqual(newItem.localAddress) &&
|
return oldItem.chatRoom == newItem.chatRoom
|
||||||
oldItem.peerAddress.weakEqual(newItem.peerAddress)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun areContentsTheSame(
|
override fun areContentsTheSame(
|
||||||
oldItem: ChatRoom,
|
oldItem: ChatRoomViewModel,
|
||||||
newItem: ChatRoom
|
newItem: ChatRoomViewModel
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return newItem.unreadMessagesCount == 0
|
return newItem.unreadMessagesCount.value == 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,10 +110,10 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
)
|
)
|
||||||
val swipeListener = object : RecyclerViewSwipeListener {
|
val swipeListener = object : RecyclerViewSwipeListener {
|
||||||
override fun onLeftToRightSwipe(viewHolder: RecyclerView.ViewHolder) {
|
override fun onLeftToRightSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||||
|
val chatRoomViewModel = adapter.currentList[viewHolder.adapterPosition]
|
||||||
|
chatRoomViewModel.chatRoom.markAsRead()
|
||||||
|
coreContext.notificationsManager.dismissChatNotification(chatRoomViewModel.chatRoom)
|
||||||
adapter.notifyItemChanged(viewHolder.adapterPosition)
|
adapter.notifyItemChanged(viewHolder.adapterPosition)
|
||||||
val chatRoom = adapter.currentList[viewHolder.adapterPosition]
|
|
||||||
chatRoom.markAsRead()
|
|
||||||
coreContext.notificationsManager.dismissChatNotification(chatRoom)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
|
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||||
|
@ -126,7 +126,7 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.showDeleteButton({
|
viewModel.showDeleteButton({
|
||||||
listViewModel.deleteChatRoom(adapter.currentList[viewHolder.adapterPosition])
|
listViewModel.deleteChatRoom(adapter.currentList[viewHolder.adapterPosition].chatRoom)
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}, getString(R.string.dialog_delete))
|
}, getString(R.string.dialog_delete))
|
||||||
|
|
||||||
|
@ -145,10 +145,6 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
adapter.submitList(chatRooms)
|
adapter.submitList(chatRooms)
|
||||||
})
|
})
|
||||||
|
|
||||||
listViewModel.latestUpdatedChatRoomId.observe(viewLifecycleOwner, { position ->
|
|
||||||
adapter.notifyItemChanged(position)
|
|
||||||
})
|
|
||||||
|
|
||||||
listViewModel.contactsUpdatedEvent.observe(viewLifecycleOwner, {
|
listViewModel.contactsUpdatedEvent.observe(viewLifecycleOwner, {
|
||||||
it.consume {
|
it.consume {
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
|
@ -268,8 +264,8 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
||||||
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
|
override fun deleteItems(indexesOfItemToDelete: ArrayList<Int>) {
|
||||||
val list = ArrayList<ChatRoom>()
|
val list = ArrayList<ChatRoom>()
|
||||||
for (index in indexesOfItemToDelete) {
|
for (index in indexesOfItemToDelete) {
|
||||||
val chatRoom = adapter.currentList[index]
|
val chatRoomViewModel = adapter.currentList[index]
|
||||||
list.add(chatRoom)
|
list.add(chatRoomViewModel.chatRoom)
|
||||||
}
|
}
|
||||||
listViewModel.deleteChatRooms(list)
|
listViewModel.deleteChatRooms(list)
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,12 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf
|
||||||
) {
|
) {
|
||||||
callInProgress.value = core.callsNb > 0
|
callInProgress.value = core.callsNb > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onChatRoomRead(core: Core, room: ChatRoom) {
|
||||||
|
if (room == chatRoom) {
|
||||||
|
unreadMessagesCount.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() {
|
private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() {
|
||||||
|
@ -216,11 +222,14 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
|
destroy()
|
||||||
|
super.onCleared()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun destroy() {
|
||||||
coreContext.contactsManager.removeListener(contactsUpdatedListener)
|
coreContext.contactsManager.removeListener(contactsUpdatedListener)
|
||||||
chatRoom.removeListener(chatRoomListener)
|
chatRoom.removeListener(chatRoomListener)
|
||||||
chatRoom.core.removeListener(coreListener)
|
chatRoom.core.removeListener(coreListener)
|
||||||
|
|
||||||
super.onCleared()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun contactLookup() {
|
fun contactLookup() {
|
||||||
|
|
|
@ -31,9 +31,7 @@ import org.linphone.utils.Event
|
||||||
import org.linphone.utils.LinphoneUtils
|
import org.linphone.utils.LinphoneUtils
|
||||||
|
|
||||||
class ChatRoomsListViewModel : ErrorReportingViewModel() {
|
class ChatRoomsListViewModel : ErrorReportingViewModel() {
|
||||||
val chatRooms = MutableLiveData<ArrayList<ChatRoom>>()
|
val chatRooms = MutableLiveData<ArrayList<ChatRoomViewModel>>()
|
||||||
|
|
||||||
val latestUpdatedChatRoomId = MutableLiveData<Int>()
|
|
||||||
|
|
||||||
val contactsUpdatedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
val contactsUpdatedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||||
MutableLiveData<Event<Boolean>>()
|
MutableLiveData<Event<Boolean>>()
|
||||||
|
@ -57,46 +55,33 @@ class ChatRoomsListViewModel : ErrorReportingViewModel() {
|
||||||
private val listener: CoreListenerStub = object : CoreListenerStub() {
|
private val listener: CoreListenerStub = object : CoreListenerStub() {
|
||||||
override fun onChatRoomStateChanged(core: Core, chatRoom: ChatRoom, state: ChatRoom.State) {
|
override fun onChatRoomStateChanged(core: Core, chatRoom: ChatRoom, state: ChatRoom.State) {
|
||||||
if (state == ChatRoom.State.Created) {
|
if (state == ChatRoom.State.Created) {
|
||||||
updateChatRooms()
|
addChatRoom(chatRoom)
|
||||||
} else if (state == ChatRoom.State.TerminationFailed) {
|
} else if (state == ChatRoom.State.TerminationFailed) {
|
||||||
Log.e("[Chat Rooms] Group chat room removal for address ${chatRoom.peerAddress.asStringUriOnly()} has failed !")
|
Log.e("[Chat Rooms] Group chat room removal for address ${chatRoom.peerAddress.asStringUriOnly()} has failed !")
|
||||||
onErrorEvent.value = Event(R.string.chat_room_removal_failed_snack)
|
onErrorEvent.value = Event(R.string.chat_room_removal_failed_snack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChatRoomSubjectChanged(core: Core, chatRoom: ChatRoom) {
|
|
||||||
updateChatRoom(chatRoom)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
|
|
||||||
updateChatRoom(chatRoom)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
||||||
if (chatRooms.value?.indexOf(chatRoom) == 0) updateChatRoom(chatRoom)
|
if (findChatRoomIndex(chatRoom) != 0) reorderChatRooms()
|
||||||
else updateChatRooms()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
||||||
if (chatRooms.value?.indexOf(chatRoom) == 0) updateChatRoom(chatRoom)
|
if (findChatRoomIndex(chatRoom) != 0) reorderChatRooms()
|
||||||
else updateChatRooms()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMessageReceivedUnableDecrypt(
|
|
||||||
core: Core,
|
|
||||||
chatRoom: ChatRoom,
|
|
||||||
message: ChatMessage
|
|
||||||
) {
|
|
||||||
updateChatRooms()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val chatRoomListener = object : ChatRoomListenerStub() {
|
private val chatRoomListener = object : ChatRoomListenerStub() {
|
||||||
override fun onStateChanged(chatRoom: ChatRoom, newState: ChatRoom.State) {
|
override fun onStateChanged(chatRoom: ChatRoom, newState: ChatRoom.State) {
|
||||||
if (newState == ChatRoom.State.Deleted) {
|
if (newState == ChatRoom.State.Deleted) {
|
||||||
val list = arrayListOf<ChatRoom>()
|
val list = arrayListOf<ChatRoomViewModel>()
|
||||||
list.addAll(chatRooms.value.orEmpty())
|
for (chatRoomViewModel in chatRooms.value.orEmpty()) {
|
||||||
list.remove(chatRoom)
|
if (chatRoomViewModel.chatRoom != chatRoom) {
|
||||||
|
list.add(chatRoomViewModel)
|
||||||
|
} else {
|
||||||
|
chatRoomViewModel.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
chatRooms.value = list
|
chatRooms.value = list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,15 +130,42 @@ class ChatRoomsListViewModel : ErrorReportingViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateChatRoom(chatRoom: ChatRoom) {
|
private fun updateChatRooms() {
|
||||||
latestUpdatedChatRoomId.value = chatRooms.value?.indexOf(chatRoom)
|
for (chatRoomViewModel in chatRooms.value.orEmpty()) {
|
||||||
|
chatRoomViewModel.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateChatRooms() {
|
val list = arrayListOf<ChatRoomViewModel>()
|
||||||
val list = arrayListOf<ChatRoom>()
|
for (chatRoom in coreContext.core.chatRooms) {
|
||||||
|
val viewModel = ChatRoomViewModel(chatRoom)
|
||||||
list.addAll(coreContext.core.chatRooms)
|
list.add(viewModel)
|
||||||
|
}
|
||||||
chatRooms.value = list
|
chatRooms.value = list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addChatRoom(chatRoom: ChatRoom) {
|
||||||
|
val list = arrayListOf<ChatRoomViewModel>()
|
||||||
|
val viewModel = ChatRoomViewModel(chatRoom)
|
||||||
|
list.add(viewModel)
|
||||||
|
list.addAll(chatRooms.value.orEmpty())
|
||||||
|
chatRooms.value = list
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reorderChatRooms() {
|
||||||
|
val list = arrayListOf<ChatRoomViewModel>()
|
||||||
|
list.addAll(chatRooms.value.orEmpty())
|
||||||
|
list.sortByDescending { chatRoomViewModel -> chatRoomViewModel.chatRoom.lastUpdateTime }
|
||||||
|
chatRooms.value = list
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findChatRoomIndex(chatRoom: ChatRoom): Int {
|
||||||
|
var index = 0
|
||||||
|
for (chatRoomViewModel in chatRooms.value.orEmpty()) {
|
||||||
|
if (chatRoomViewModel.chatRoom == chatRoom) {
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -552,9 +552,10 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
|
|
||||||
if (overlayY == 0f) overlayY = AppUtils.pixelsToDp(40f)
|
if (overlayY == 0f) overlayY = AppUtils.pixelsToDp(40f)
|
||||||
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||||
|
// WRAP_CONTENT doesn't work well on some launchers...
|
||||||
val params: WindowManager.LayoutParams = WindowManager.LayoutParams(
|
val params: WindowManager.LayoutParams = WindowManager.LayoutParams(
|
||||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
AppUtils.getDimension(R.dimen.call_overlay_size).toInt(),
|
||||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
AppUtils.getDimension(R.dimen.call_overlay_size).toInt(),
|
||||||
Compatibility.getOverlayType(),
|
Compatibility.getOverlayType(),
|
||||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||||
PixelFormat.TRANSLUCENT
|
PixelFormat.TRANSLUCENT
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<dimen name="outgoing_chat_message_bubble_right_margin">3dp</dimen>
|
<dimen name="outgoing_chat_message_bubble_right_margin">3dp</dimen>
|
||||||
<dimen name="chat_message_bubble_image_height_big">200dp</dimen>
|
<dimen name="chat_message_bubble_image_height_big">200dp</dimen>
|
||||||
<dimen name="chat_message_bubble_image_height_small">100dp</dimen>
|
<dimen name="chat_message_bubble_image_height_small">100dp</dimen>
|
||||||
<dimen name="chat_message_bubble_file_size">150dp</dimen>
|
<dimen name="chat_message_bubble_file_size">120dp</dimen>
|
||||||
<dimen name="chat_message_bubble_file_icon_size">30dp</dimen>
|
<dimen name="chat_message_bubble_file_icon_size">30dp</dimen>
|
||||||
<dimen name="chat_message_bubble_desired_height">600dp</dimen>
|
<dimen name="chat_message_bubble_desired_height">600dp</dimen>
|
||||||
<dimen name="video_preview_max_size">200dp</dimen>
|
<dimen name="video_preview_max_size">200dp</dimen>
|
||||||
|
|
Loading…
Reference in a new issue