Added menu to go to shared media/documents from conversation details, only startPostponedEnterTransition() in doOnPreDraw for RecyclerView fragments

This commit is contained in:
Sylvain Berfini 2024-12-10 13:56:32 +01:00
parent 4304552bc8
commit e0c58c0ac5
15 changed files with 141 additions and 70 deletions

View file

@ -136,7 +136,7 @@ class ConferenceParticipantDeviceModel
screenSharing: Boolean
) {
Log.i(
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] is ${if (screenSharing) "sharing it's screen" else "no longer sharing it's screen"}"
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] is ${if (screenSharing) "sharing its screen" else "no longer sharing its screen"}"
)
isScreenSharing.postValue(screenSharing)
}
@ -193,7 +193,7 @@ class ConferenceParticipantDeviceModel
val screenSharing = device.isScreenSharingEnabled
isScreenSharing.postValue(screenSharing)
if (screenSharing) {
Log.i("$TAG Participant [${device.address.asStringUriOnly()}] is sharing it's screen")
Log.i("$TAG Participant [${device.address.asStringUriOnly()}] is sharing its screen")
}
isVideoAvailable.postValue(device.getStreamAvailability(StreamType.Video))

View file

@ -316,7 +316,7 @@ class ConferenceViewModel
conferenceLayout.postValue(currentLayout)
if (currentLayout == GRID_LAYOUT && screenSharing) {
Log.w(
"$TAG Conference has a participant sharing it's screen, changing layout from mosaic to active speaker"
"$TAG Conference has a participant sharing its screen, changing layout from mosaic to active speaker"
)
setNewLayout(ACTIVE_SPEAKER_LAYOUT)
}

View file

@ -27,7 +27,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -117,9 +116,7 @@ class ConversationDocumentsListFragment : SlidingPaneChildFragment() {
viewModel.chatRoomFoundEvent.observe(viewLifecycleOwner) {
it.consume {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
startPostponedEnterTransition()
}
}

View file

@ -29,7 +29,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
@ -119,19 +118,15 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
Log.i(
"$TAG Found matching conversation for local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
startPostponedEnterTransition()
} else {
(view.parent as? ViewGroup)?.doOnPreDraw {
Log.e("$TAG Failed to find conversation, going back")
goBack()
val message = getString(R.string.conversation_to_display_no_found_toast)
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
Log.e("$TAG Failed to find conversation, going back")
goBack()
val message = getString(R.string.conversation_to_display_no_found_toast)
(requireActivity() as GenericActivity).showRedToast(
message,
R.drawable.warning_circle
)
}
}
}
@ -333,6 +328,24 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
binding.setCopyPeerSipUriClickListener {
copyAddressToClipboard(viewModel.peerSipUri.value.orEmpty())
}
binding.setGoToSharedMediaClickListener {
if (findNavController().currentDestination?.id == R.id.conversationInfoFragment) {
Log.i("$TAG Going to shared media fragment")
val action =
ConversationInfoFragmentDirections.actionConversationInfoFragmentToConversationMediaListFragment(localSipUri, remoteSipUri)
findNavController().navigate(action)
}
}
binding.setGoToSharedDocumentsClickListener {
if (findNavController().currentDestination?.id == R.id.conversationInfoFragment) {
Log.i("$TAG Going to shared documents fragment")
val action =
ConversationInfoFragmentDirections.actionConversationInfoFragmentToConversationDocumentsListFragment(localSipUri, remoteSipUri)
findNavController().navigate(action)
}
}
}
private fun showParticipantAdminPopupMenu(view: View, participantModel: ParticipantModel) {

View file

@ -27,7 +27,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -146,9 +145,7 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() {
viewModel.chatRoomFoundEvent.observe(viewLifecycleOwner) {
it.consume {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
startPostponedEnterTransition()
}
}

View file

@ -32,7 +32,6 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.UiThread
import androidx.core.content.FileProvider
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -125,10 +124,8 @@ class ContactFragment : SlidingPaneChildFragment() {
viewModel.contactFoundEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Contact has been found, start postponed enter transition")
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.openSlidingPaneEvent.value = Event(true)
}
startPostponedEnterTransition()
sharedViewModel.openSlidingPaneEvent.value = Event(true)
}
}

View file

@ -28,7 +28,6 @@ import androidx.activity.OnBackPressedCallback
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.lifecycleScope
@ -164,10 +163,7 @@ class EditContactFragment : SlidingPaneChildFragment() {
for (items in viewModel.phoneNumbers) {
addCell(items)
}
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
startPostponedEnterTransition()
}
}
}

View file

@ -29,7 +29,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
@ -112,15 +111,11 @@ class HistoryFragment : SlidingPaneChildFragment() {
Log.i(
"$TAG Found matching call log for call ID [$callId]"
)
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.openSlidingPaneEvent.value = Event(true)
}
startPostponedEnterTransition()
sharedViewModel.openSlidingPaneEvent.value = Event(true)
} else {
(view.parent as? ViewGroup)?.doOnPreDraw {
Log.e("$TAG Failed to find call log, going back")
goBack()
}
Log.e("$TAG Failed to find call log, going back")
goBack()
}
}
}

View file

@ -32,7 +32,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
@ -165,14 +164,10 @@ class MeetingFragment : SlidingPaneChildFragment() {
viewModel.conferenceInfoFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
if (found) {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
startPostponedEnterTransition()
} else {
Log.e("$TAG Failed to find meeting with URI [$uri], going back")
(view.parent as? ViewGroup)?.doOnPreDraw {
goBack()
}
goBack()
}
}
}

View file

@ -28,7 +28,6 @@ import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.UiThread
import androidx.core.content.ContextCompat
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -116,14 +115,10 @@ class MeetingWaitingRoomFragment : GenericMainFragment() {
viewModel.conferenceInfoFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
if (found) {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
}
startPostponedEnterTransition()
} else {
Log.e("$TAG Failed to find meeting with URI [$uri], going back")
(view.parent as? ViewGroup)?.doOnPreDraw {
goBack()
}
goBack()
}
}
}

View file

@ -31,7 +31,6 @@ import android.widget.ArrayAdapter
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@ -194,10 +193,8 @@ class AccountProfileFragment : GenericMainFragment() {
viewModel.accountFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
if (found) {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
setupDialPlanPicker()
}
startPostponedEnterTransition()
setupDialPlanPicker()
} else {
Log.e(
"$TAG Failed to find an account matching this identity address [$identity]"

View file

@ -129,7 +129,7 @@ abstract class AddressSelectionViewModel
@UiThread
fun switchToMultipleSelectionMode() {
Log.i("$$TAG Multiple selection mode ON")
Log.i("$TAG Multiple selection mode ON")
multipleSelectionMode.value = true
selectionCount.postValue(

View file

@ -33,6 +33,12 @@
<variable
name="copyPeerSipUriClickListener"
type="View.OnClickListener" />
<variable
name="goToSharedMediaClickListener"
type="View.OnClickListener" />
<variable
name="goToSharedDocumentsClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.main.chat.viewmodel.ConversationInfoViewModel" />
@ -340,6 +346,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="10dp"
android:background="@drawable/tertiary_button_background"
android:drawableStart="@drawable/plus_circle"
android:drawablePadding="8dp"
@ -354,11 +361,79 @@
android:text="@string/conversation_info_add_participants_label"
android:visibility="@{!viewModel.expandParticipants || !viewModel.isMyselfAdmin || !viewModel.isGroup || viewModel.isReadOnly ? View.GONE : View.VISIBLE, default=gone}"
app:drawableTint="?attr/color_main1_500"
app:layout_constraintBottom_toTopOf="@id/actions"
app:layout_constraintBottom_toTopOf="@id/media_actions"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/participants" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/media_actions"
style="@style/section_header_style"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="26dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="26dp"
android:layout_marginBottom="8dp"
android:padding="5dp"
android:text="@string/contact_details_media_documents_title"
app:layout_constraintBottom_toTopOf="@id/media_actions_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/add_participants" />
<ImageView
android:id="@+id/media_actions_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:src="@drawable/shape_squircle_white_background"
android:contentDescription="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/media_actions"
app:layout_constraintBottom_toBottomOf="@id/action_documents"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/action_media"
style="@style/context_menu_action_label_style"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@drawable/action_background"
android:drawableStart="@drawable/image"
android:onClick="@{goToSharedMediaClickListener}"
android:text="@string/conversation_media_list_title"
app:layout_constraintEnd_toEndOf="@id/media_actions_background"
app:layout_constraintStart_toStartOf="@id/media_actions_background"
app:layout_constraintTop_toTopOf="@id/media_actions_background" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:background="?attr/color_main2_200"
app:layout_constraintEnd_toEndOf="@id/action_media"
app:layout_constraintStart_toStartOf="@id/action_media"
app:layout_constraintTop_toBottomOf="@id/action_media" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/action_documents"
style="@style/context_menu_action_label_style"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="@dimen/screen_bottom_margin"
android:background="@drawable/action_background"
android:drawableStart="@drawable/file_pdf"
android:onClick="@{goToSharedDocumentsClickListener}"
android:text="@string/conversation_document_list_title"
app:layout_constraintEnd_toEndOf="@id/media_actions_background"
app:layout_constraintStart_toStartOf="@id/media_actions_background"
app:layout_constraintTop_toBottomOf="@id/action_media" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actions"
style="@style/section_header_style"
@ -373,8 +448,7 @@
app:layout_constraintBottom_toTopOf="@id/actions_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/add_participants"
app:layout_constraintVertical_bias="0" />
app:layout_constraintTop_toBottomOf="@id/media_actions_background" />
<ImageView
android:id="@+id/actions_background"
@ -497,11 +571,9 @@
android:drawableStart="@drawable/trash_simple"
android:onClick="@{deleteHistoryClickListener}"
android:text="@string/conversation_info_delete_history_action"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/actions_background"
app:layout_constraintStart_toStartOf="@id/actions_background"
app:layout_constraintTop_toBottomOf="@id/action_leave_group"
app:layout_constraintVertical_bias="0" />
app:layout_constraintTop_toBottomOf="@id/action_leave_group" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -101,6 +101,22 @@
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
<action
android:id="@+id/action_conversationInfoFragment_to_conversationMediaListFragment"
app:destination="@id/conversationMediaListFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
<action
android:id="@+id/action_conversationInfoFragment_to_conversationDocumentsListFragment"
app:destination="@id/conversationDocumentsListFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
<fragment

View file

@ -403,6 +403,7 @@
<string name="contact_details_trust_title">Trust</string>
<string name="contact_details_no_device_found">No device found…</string>
<string name="contact_details_trusted_devices_count">Number of trusted devices:</string>
<string name="contact_details_media_documents_title">Media &amp; documents</string>
<string name="contact_details_actions_title">Other actions</string>
<string name="contact_details_edit">Edit</string>
<string name="contact_details_add_to_favourites">Add to favourites</string>
@ -726,7 +727,7 @@
<string name="conference_participant_was_kicked_out_toast">Participant was kicked out of conference</string>
<string name="conference_participant_joining_text">Joining…</string>
<string name="conference_participant_paused_text">Paused</string>
<string name="conference_active_speaker_is_screen_sharing">is sharing it\'s screen</string>
<string name="conference_active_speaker_is_screen_sharing">is sharing its screen</string>
<string name="conference_failed_to_add_participant_invalid_address_toast">Invalid SIP address, can\'t be added to conference</string>
<string name="conference_layout_grid">Mosaic</string>