mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Added meeting/group call conversation history in call log
This commit is contained in:
parent
f74976f563
commit
4afb10d82a
13 changed files with 168 additions and 15 deletions
|
|
@ -34,8 +34,8 @@ class ConversationFragment : ConversationFragment() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
Log.i("$TAG Creating an in-call ConversationFragment")
|
||||
sendMessageViewModel.isInCallConversation.value = true
|
||||
viewModel.isInCallConversation.value = true
|
||||
sendMessageViewModel.isCallConversation.value = true
|
||||
viewModel.isCallConversation.value = true
|
||||
|
||||
binding.setBackClickListener {
|
||||
findNavController().popBackStack()
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
|
|||
|
||||
val showBackButton = MutableLiveData<Boolean>()
|
||||
|
||||
val isInCallConversation = MutableLiveData<Boolean>()
|
||||
val isCallConversation = MutableLiveData<Boolean>()
|
||||
|
||||
val avatarModel = MutableLiveData<ContactAvatarModel>()
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class SendMessageInConversationViewModel @UiThread constructor() : GenericViewMo
|
|||
|
||||
val isKeyboardOpen = MutableLiveData<Boolean>()
|
||||
|
||||
val isInCallConversation = MutableLiveData<Boolean>()
|
||||
val isCallConversation = MutableLiveData<Boolean>()
|
||||
|
||||
val isVoiceRecording = MutableLiveData<Boolean>()
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ class SendMessageInConversationViewModel @UiThread constructor() : GenericViewMo
|
|||
|
||||
isEmojiPickerOpen.value = false
|
||||
isPlayingVoiceRecord.value = false
|
||||
isInCallConversation.value = false
|
||||
isCallConversation.value = false
|
||||
maxNumberOfAttachmentsReached.value = false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.ui.main.history.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.chat.fragment.ConversationFragment
|
||||
|
||||
class ConferenceConversationFragment : ConversationFragment() {
|
||||
companion object {
|
||||
private const val TAG = "[Conference Conversation Fragment]"
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
Log.i("$TAG Creating a conference history ConversationFragment")
|
||||
sendMessageViewModel.isCallConversation.value = true
|
||||
viewModel.isCallConversation.value = true
|
||||
|
||||
binding.setBackClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,6 +160,22 @@ class HistoryFragment : SlidingPaneChildFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
viewModel.goToMeetingConversationEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { pair ->
|
||||
val localAddress = pair.first
|
||||
val remoteAddress = pair.second
|
||||
if (findNavController().currentDestination?.id == R.id.historyFragment) {
|
||||
Log.i("$TAG Going to meeting conversation [$localAddress][$remoteAddress]")
|
||||
val action =
|
||||
HistoryFragmentDirections.actionHistoryFragmentToConferenceConversationFragment(
|
||||
localAddress,
|
||||
remoteAddress
|
||||
)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.conferenceToJoinEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { conferenceUri ->
|
||||
Log.i("$TAG Requesting to go to waiting room for conference URI [$conferenceUri]")
|
||||
|
|
|
|||
|
|
@ -56,12 +56,18 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
val isConferenceCallLog = MutableLiveData<Boolean>()
|
||||
|
||||
val isChatRoomAvailable = MutableLiveData<Boolean>()
|
||||
|
||||
val callLogFoundEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
val chatRoomCreationErrorEvent: MutableLiveData<Event<Int>> by lazy {
|
||||
MutableLiveData<Event<Int>>()
|
||||
}
|
||||
|
||||
val goToMeetingConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
|
||||
MutableLiveData<Event<Pair<String, String>>>()
|
||||
}
|
||||
|
||||
val goToConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
|
||||
MutableLiveData<Event<Pair<String, String>>>()
|
||||
}
|
||||
|
|
@ -76,6 +82,8 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
private lateinit var address: Address
|
||||
|
||||
private var meetingChatRoom: ChatRoom? = null
|
||||
|
||||
private val chatRoomListener = object : ChatRoomListenerStub() {
|
||||
@WorkerThread
|
||||
override fun onStateChanged(chatRoom: ChatRoom, newState: ChatRoom.State?) {
|
||||
|
|
@ -124,7 +132,15 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
|
|||
address = model.address
|
||||
callLogModel.postValue(model)
|
||||
|
||||
isConferenceCallLog.postValue(callLog.wasConference())
|
||||
val conference = callLog.wasConference()
|
||||
isConferenceCallLog.postValue(conference)
|
||||
meetingChatRoom = callLog.chatRoom
|
||||
isChatRoomAvailable.postValue(meetingChatRoom != null)
|
||||
if (conference) {
|
||||
Log.i(
|
||||
"$TAG Conference call log, chat room is ${ if (meetingChatRoom != null) "available" else "not available"}"
|
||||
)
|
||||
}
|
||||
|
||||
val peerAddress = callLog.remoteAddress
|
||||
val history = arrayListOf<CallLogHistoryModel>()
|
||||
|
|
@ -172,6 +188,25 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun goToMeetingConversation() {
|
||||
coreContext.postOnCoreThread {
|
||||
val chatRoom = meetingChatRoom
|
||||
if (chatRoom != null) {
|
||||
goToMeetingConversationEvent.postValue(
|
||||
Event(
|
||||
Pair(
|
||||
chatRoom.localAddress.asStringUriOnly(),
|
||||
chatRoom.peerAddress.asStringUriOnly()
|
||||
)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Log.e("$TAG Failed to find chat room for current call log!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun goToConversation() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
|
|
|
|||
|
|
@ -89,7 +89,9 @@ class ScheduleMeetingFragment : GenericMainFragment() {
|
|||
observeToastEvents(viewModel)
|
||||
|
||||
val subject = args.subject
|
||||
viewModel.subject.value = subject
|
||||
if (subject.isNotEmpty()) {
|
||||
viewModel.subject.value = subject
|
||||
}
|
||||
|
||||
val participants = args.participants
|
||||
if (!participants.isNullOrEmpty()) {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
android:padding="15dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:onClick="@{backClickListener}"
|
||||
android:visibility="@{viewModel.isInCallConversation || viewModel.showBackButton && !viewModel.searchBarVisible ? View.VISIBLE : View.GONE}"
|
||||
android:visibility="@{viewModel.isCallConversation || viewModel.showBackButton && !viewModel.searchBarVisible ? View.VISIBLE : View.GONE}"
|
||||
android:src="@drawable/caret_left"
|
||||
android:contentDescription="@string/content_description_go_back_icon"
|
||||
app:tint="?attr/color_main1_500"
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginStart="@{viewModel.isInCallConversation || viewModel.showBackButton ? @dimen/chat_conversation_header_avatar_start_margin_if_back_button : @dimen/chat_conversation_header_avatar_start_margin_if_no_back_button, default=@dimen/chat_conversation_header_avatar_start_margin_if_back_button}"
|
||||
android:layout_marginStart="@{viewModel.isCallConversation || viewModel.showBackButton ? @dimen/chat_conversation_header_avatar_start_margin_if_back_button : @dimen/chat_conversation_header_avatar_start_margin_if_no_back_button, default=@dimen/chat_conversation_header_avatar_start_margin_if_back_button}"
|
||||
layout="@layout/contact_avatar"
|
||||
bind:model="@{viewModel.avatarModel}"
|
||||
app:layout_constraintStart_toEndOf="@id/back"
|
||||
|
|
@ -171,7 +171,7 @@
|
|||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/dots_three_vertical"
|
||||
android:contentDescription="@string/content_description_show_popup_menu"
|
||||
android:visibility="@{viewModel.isInCallConversation ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{viewModel.isCallConversation ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:tint="?attr/color_main2_500"/>
|
||||
|
|
@ -184,7 +184,7 @@
|
|||
android:padding="15dp"
|
||||
android:src="@drawable/phone"
|
||||
android:contentDescription="@string/content_description_call_start"
|
||||
android:visibility="@{viewModel.isInCallConversation || viewModel.isReadOnly || viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{viewModel.isCallConversation || viewModel.isReadOnly || viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/show_menu"
|
||||
app:tint="?attr/color_main2_500" />
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
android:id="@+id/extra_actions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{viewModel.isVoiceRecording ? View.INVISIBLE : (viewModel.isKeyboardOpen || viewModel.isInCallConversation || !viewModel.isFileTransferServerAvailable) ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{viewModel.isVoiceRecording ? View.INVISIBLE : (viewModel.isKeyboardOpen || viewModel.isCallConversation || !viewModel.isFileTransferServerAvailable) ? View.GONE : View.VISIBLE}"
|
||||
app:constraint_referenced_ids="emoji_picker_toggle, capture_image" />
|
||||
|
||||
<include
|
||||
|
|
@ -173,7 +173,7 @@
|
|||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:enabled="@{viewModel.textToSend.length() > 0 || viewModel.attachments.size() > 0}"
|
||||
android:visibility="@{viewModel.isInCallConversation || viewModel.textToSend.length() > 0 || viewModel.attachments.size() > 0 ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:visibility="@{viewModel.isCallConversation || viewModel.textToSend.length() > 0 || viewModel.attachments.size() > 0 ? View.VISIBLE : View.GONE, default=gone}"
|
||||
android:onClick="@{() -> viewModel.sendMessage()}"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/paper_plane_right"
|
||||
|
|
@ -188,7 +188,7 @@
|
|||
android:layout_width="40dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:visibility="@{viewModel.isInCallConversation || viewModel.textToSend.length() > 0 || viewModel.attachments.size() > 0 || viewModel.isVoiceRecording || !viewModel.isFileTransferServerAvailable ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{viewModel.isCallConversation || viewModel.textToSend.length() > 0 || viewModel.attachments.size() > 0 || viewModel.isVoiceRecording || !viewModel.isFileTransferServerAvailable ? View.GONE : View.VISIBLE}"
|
||||
android:onClick="@{() -> viewModel.startVoiceMessageRecording()}"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/microphone"
|
||||
|
|
|
|||
|
|
@ -249,8 +249,8 @@
|
|||
android:contentDescription="@string/content_description_join_conference"
|
||||
android:visibility="@{viewModel.isConferenceCallLog ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:tint="?attr/color_main2_500"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/meeting_chat"
|
||||
app:layout_constraintTop_toBottomOf="@id/status" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
|
|
@ -267,6 +267,36 @@
|
|||
app:layout_constraintStart_toStartOf="@id/meeting"
|
||||
app:layout_constraintEnd_toEndOf="@id/meeting"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/meeting_chat"
|
||||
android:onClick="@{() -> viewModel.goToMeetingConversation()}"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/circle_light_blue_button_background"
|
||||
android:padding="16dp"
|
||||
android:src="@drawable/chat_teardrop_text"
|
||||
android:contentDescription="@string/content_description_go_to_conversation"
|
||||
android:visibility="@{viewModel.isConferenceCallLog && viewModel.isChatRoomAvailable ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:tint="?attr/color_main2_500"
|
||||
app:layout_constraintStart_toEndOf="@id/meeting"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/status" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
style="@style/default_text_style"
|
||||
android:id="@+id/meeting_chat_label"
|
||||
android:onClick="@{() -> viewModel.goToMeetingConversation()}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/history_group_call_go_to_conversation"
|
||||
android:textSize="14sp"
|
||||
android:visibility="@{viewModel.isConferenceCallLog && viewModel.isChatRoomAvailable ? View.VISIBLE : View.GONE, default=gone}"
|
||||
app:layout_constraintTop_toBottomOf="@id/meeting_chat"
|
||||
app:layout_constraintStart_toStartOf="@id/meeting_chat"
|
||||
app:layout_constraintEnd_toEndOf="@id/meeting_chat"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/call_history"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
|||
|
|
@ -25,11 +25,34 @@
|
|||
app:destination="@id/emptyFragment"
|
||||
app:popUpTo="@id/historyFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/action_historyFragment_to_conferenceConversationFragment"
|
||||
app:destination="@id/conferenceConversationFragment"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
app:launchSingleTop="true" />
|
||||
</fragment>
|
||||
|
||||
<action
|
||||
android:id="@+id/action_global_historyFragment"
|
||||
app:destination="@id/historyFragment"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popExitAnim="@anim/slide_out_right"
|
||||
app:launchSingleTop="true" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/conferenceConversationFragment"
|
||||
android:name="org.linphone.ui.main.history.fragment.ConferenceConversationFragment"
|
||||
android:label="ConferenceConversationFragment"
|
||||
tools:layout="@layout/chat_conversation_fragment">
|
||||
<argument
|
||||
android:name="localSipUri"
|
||||
app:argType="string" />
|
||||
<argument
|
||||
android:name="remoteSipUri"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
|
||||
</navigation>
|
||||
|
|
@ -324,6 +324,7 @@
|
|||
<string name="history_group_call_start_dialog_set_subject">Nommer l\'appel de groupe</string>
|
||||
<string name="history_group_call_start_dialog_subject_hint">Nom de l\'appel de groupe</string>
|
||||
<string name="history_list_empty_history">Aucun appel dans votre historique…</string>
|
||||
<string name="history_group_call_go_to_conversation">Conversation</string>
|
||||
|
||||
<string name="history_dialog_delete_all_call_logs_title">Voulez-vous tout supprimer ?</string>
|
||||
<string name="history_dialog_delete_all_call_logs_message">Tout votre historique d\'appels sera supprimé.</string>
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@
|
|||
<string name="history_group_call_start_dialog_set_subject">Set group call subject</string>
|
||||
<string name="history_group_call_start_dialog_subject_hint">Group call subject</string>
|
||||
<string name="history_list_empty_history">No call for the moment…</string>
|
||||
<string name="history_group_call_go_to_conversation">Conversation</string>
|
||||
|
||||
<string name="history_dialog_delete_all_call_logs_title">Do you really want to delete all calls history?</string>
|
||||
<string name="history_dialog_delete_all_call_logs_message">All calls will be removed from the history</string>
|
||||
|
|
@ -871,6 +872,7 @@
|
|||
<string name="content_description_ldap_delete">Delete this LDAP configuration</string>
|
||||
<string name="content_description_ldap_save">Save LDAP configuration</string>
|
||||
<string name="content_description_play_call_recording">Plays the call recording</string>
|
||||
<string name="content_description_go_to_conversation">Go to conversation</string>
|
||||
|
||||
<!-- Copy of private hosts_allowlist_sample in androidx.car.app:app:1.7.0-beta01, as they recommend it -->
|
||||
<string-array name="hosts_allowlist_sample_copy" translatable="false">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue