Refactored Media & File viewers

This commit is contained in:
Sylvain Berfini 2024-02-07 10:54:28 +01:00
parent c71af9f23a
commit 91ec675cbe
18 changed files with 174 additions and 457 deletions

View file

@ -402,6 +402,7 @@ class MainActivity : GenericActivity() {
val pair = Pair(localSipUri, remoteSipUri)
sharedViewModel.showConversationEvent.value = Event(pair)
}
args?.clear()
val action = ConversationsListFragmentDirections.actionGlobalConversationsListFragment()
findNavController().navigate(action)

View file

@ -39,8 +39,6 @@ import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.PopupWindow
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
@ -244,17 +242,6 @@ class ConversationFragment : SlidingPaneChildFragment() {
private var bottomSheetReactionsModel: MessageReactionsModel? = null
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (
findNavController().currentDestination?.id == R.id.fileViewerFragment ||
findNavController().currentDestination?.id == R.id.mediaListViewerFragment
) {
// Holds fragment in place while new fragment slides over it
return AnimationUtils.loadAnimation(activity, R.anim.hold)
}
return super.onCreateAnimation(transit, enter, nextAnim)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -750,43 +737,40 @@ class ConversationFragment : SlidingPaneChildFragment() {
}
private fun goToFileViewer(path: String) {
if (findNavController().currentDestination?.id == R.id.conversationFragment) {
Log.i("$TAG Navigating to file viewer fragment with path [$path]")
val extension = FileUtils.getExtensionFromFileName(path)
val mime = FileUtils.getMimeTypeFromExtension(extension)
when (FileUtils.getMimeType(mime)) {
FileUtils.MimeType.Image, FileUtils.MimeType.Video -> {
val action =
ConversationFragmentDirections.actionConversationFragmentToMediaListViewerFragment(
localSipUri = viewModel.localSipUri,
remoteSipUri = viewModel.remoteSipUri,
path = path
)
findNavController().navigate(action)
}
FileUtils.MimeType.Pdf, FileUtils.MimeType.PlainText -> {
val action =
ConversationFragmentDirections.actionConversationFragmentToFileViewerFragment(
path
)
findNavController().navigate(action)
}
else -> {
val intent = Intent(Intent.ACTION_VIEW)
val contentUri: Uri =
FileUtils.getPublicFilePath(requireContext(), path)
intent.setDataAndType(contentUri, "file/$mime")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
requireContext().startActivity(intent)
} catch (anfe: ActivityNotFoundException) {
Log.e("$TAG Can't open file [$path] in third party app: $anfe")
val message = getString(
R.string.toast_no_app_registered_to_handle_content_type_error
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showRedToast(message, icon)
}
Log.i("$TAG Navigating to file viewer fragment with path [$path]")
val extension = FileUtils.getExtensionFromFileName(path)
val mime = FileUtils.getMimeTypeFromExtension(extension)
val bundle = Bundle()
bundle.apply {
putString("localSipUri", viewModel.localSipUri)
putString("remoteSipUri", viewModel.remoteSipUri)
putString("path", path)
}
when (FileUtils.getMimeType(mime)) {
FileUtils.MimeType.Image, FileUtils.MimeType.Video -> {
bundle.putBoolean("isMedia", true)
sharedViewModel.displayFileEvent.value = Event(bundle)
}
FileUtils.MimeType.Pdf, FileUtils.MimeType.PlainText -> {
bundle.putBoolean("isMedia", false)
sharedViewModel.displayFileEvent.value = Event(bundle)
}
else -> {
val intent = Intent(Intent.ACTION_VIEW)
val contentUri: Uri =
FileUtils.getPublicFilePath(requireContext(), path)
intent.setDataAndType(contentUri, "file/$mime")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
requireContext().startActivity(intent)
} catch (anfe: ActivityNotFoundException) {
Log.e("$TAG Can't open file [$path] in third party app: $anfe")
val message = getString(
R.string.toast_no_app_registered_to_handle_content_type_error
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showRedToast(message, icon)
}
}
}

View file

@ -26,8 +26,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
@ -39,6 +37,7 @@ import org.linphone.databinding.ChatMediaFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.chat.viewmodel.ConversationMediaListViewModel
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
import org.linphone.utils.Event
import org.linphone.utils.FileUtils
@UiThread
@ -53,16 +52,6 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() {
private val args: ConversationMediaListFragmentArgs by navArgs()
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (
findNavController().currentDestination?.id == R.id.mediaListViewerFragment
) {
// Holds fragment in place while new fragment slides over it
return AnimationUtils.loadAnimation(activity, R.anim.hold)
}
return super.onCreateAnimation(transit, enter, nextAnim)
}
override fun goBack(): Boolean {
return findNavController().popBackStack()
}
@ -116,43 +105,40 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() {
}
private fun goToFileViewer(path: String) {
if (findNavController().currentDestination?.id == R.id.conversationMediaListFragment) {
Log.i("$TAG Navigating to file viewer fragment with path [$path]")
val extension = FileUtils.getExtensionFromFileName(path)
val mime = FileUtils.getMimeTypeFromExtension(extension)
when (FileUtils.getMimeType(mime)) {
FileUtils.MimeType.Image, FileUtils.MimeType.Video -> {
val action =
ConversationMediaListFragmentDirections.actionConversationMediaListFragmentToMediaListViewerFragment(
localSipUri = viewModel.localSipUri,
remoteSipUri = viewModel.remoteSipUri,
path = path
)
findNavController().navigate(action)
}
FileUtils.MimeType.Pdf, FileUtils.MimeType.PlainText -> {
val action =
ConversationMediaListFragmentDirections.actionConversationMediaListFragmentToFileViewerFragment(
path
)
findNavController().navigate(action)
}
else -> {
val intent = Intent(Intent.ACTION_VIEW)
val contentUri: Uri =
FileUtils.getPublicFilePath(requireContext(), path)
intent.setDataAndType(contentUri, "file/$mime")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
requireContext().startActivity(intent)
} catch (anfe: ActivityNotFoundException) {
Log.e("$TAG Can't open file [$path] in third party app: $anfe")
val message = getString(
R.string.toast_no_app_registered_to_handle_content_type_error
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showRedToast(message, icon)
}
Log.i("$TAG Navigating to file viewer fragment with path [$path]")
val extension = FileUtils.getExtensionFromFileName(path)
val mime = FileUtils.getMimeTypeFromExtension(extension)
val bundle = Bundle()
bundle.apply {
putString("localSipUri", viewModel.localSipUri)
putString("remoteSipUri", viewModel.remoteSipUri)
putString("path", path)
}
when (FileUtils.getMimeType(mime)) {
FileUtils.MimeType.Image, FileUtils.MimeType.Video -> {
bundle.putBoolean("isMedia", true)
sharedViewModel.displayFileEvent.value = Event(bundle)
}
FileUtils.MimeType.Pdf, FileUtils.MimeType.PlainText -> {
bundle.putBoolean("isMedia", false)
sharedViewModel.displayFileEvent.value = Event(bundle)
}
else -> {
val intent = Intent(Intent.ACTION_VIEW)
val contentUri: Uri =
FileUtils.getPublicFilePath(requireContext(), path)
intent.setDataAndType(contentUri, "file/$mime")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
requireContext().startActivity(intent)
} catch (anfe: ActivityNotFoundException) {
Log.e("$TAG Can't open file [$path] in third party app: $anfe")
val message = getString(
R.string.toast_no_app_registered_to_handle_content_type_error
)
val icon = R.drawable.file
(requireActivity() as MainActivity).showRedToast(message, icon)
}
}
}

View file

@ -218,6 +218,32 @@ class ConversationsListFragment : AbstractTopBarFragment() {
}
}
sharedViewModel.displayFileEvent.observe(viewLifecycleOwner) {
it.consume { bundle ->
if (findNavController().currentDestination?.id == R.id.conversationsListFragment) {
val path = bundle.getString("path", "")
val isMedia = bundle.getBoolean("isMedia", false)
Log.i(
"$TAG Navigating to ${if (isMedia) "media" else "file"} viewer fragment with path [$path]"
)
val action = if (isMedia) {
val localSipUri = bundle.getString("localSipUri", "")
val remoteSipUri = bundle.getString("remoteSipUri", "")
ConversationsListFragmentDirections.actionConversationsListFragmentToMediaListViewerFragment(
localSipUri = localSipUri,
remoteSipUri = remoteSipUri,
path = path
)
} else {
ConversationsListFragmentDirections.actionConversationsListFragmentToFileViewerFragment(
path
)
}
findNavController().navigate(action)
}
}
}
sharedViewModel.messageToForwardEvent.observe(viewLifecycleOwner) { event ->
if (!event.consumed()) {
// Do not consume it yet

View file

@ -17,14 +17,14 @@
* 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.chat.adapter
package org.linphone.ui.main.file_media_viewer.adapter
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import org.linphone.core.tools.Log
import org.linphone.ui.main.chat.fragment.MediaViewerFragment
import org.linphone.ui.main.chat.viewmodel.ConversationMediaListViewModel
import org.linphone.ui.main.file_media_viewer.fragment.MediaViewerFragment
class MediaListAdapter(fragment: Fragment, private val viewModel: ConversationMediaListViewModel) : FragmentStateAdapter(
fragment

View file

@ -17,7 +17,7 @@
* 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.viewer.adapter
package org.linphone.ui.main.file_media_viewer.adapter
import android.view.LayoutInflater
import android.view.View
@ -25,7 +25,7 @@ import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import org.linphone.R
import org.linphone.ui.main.viewer.viewmodel.FileViewModel
import org.linphone.ui.main.file_media_viewer.viewmodel.FileViewModel
class PdfPagesListAdapter(private val viewModel: FileViewModel) : RecyclerView.Adapter<PdfPagesListAdapter.PdfPageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder {

View file

@ -1,4 +1,4 @@
package org.linphone.ui.main.viewer.fragment
package org.linphone.ui.main.file_media_viewer.fragment
import android.app.Activity
import android.content.Intent
@ -20,14 +20,14 @@ import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.FileViewerFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
import org.linphone.ui.main.viewer.adapter.PdfPagesListAdapter
import org.linphone.ui.main.viewer.viewmodel.FileViewModel
import org.linphone.ui.main.file_media_viewer.adapter.PdfPagesListAdapter
import org.linphone.ui.main.file_media_viewer.viewmodel.FileViewModel
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.Event
import org.linphone.utils.FileUtils
@UiThread
class FileViewerFragment : SlidingPaneChildFragment() {
class FileViewerFragment : GenericFragment() {
companion object {
private const val TAG = "[File Viewer Fragment]"
@ -74,11 +74,7 @@ class FileViewerFragment : SlidingPaneChildFragment() {
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
val path = if (arguments?.containsKey("path") == true) {
requireArguments().getString("path", args.path)
} else {
args.path
}
val path = args.path
Log.i("$TAG Path argument is [$path]")
viewModel.loadFile(path)
@ -138,30 +134,6 @@ class FileViewerFragment : SlidingPaneChildFragment() {
}
}
viewModel.isVideo.observe(viewLifecycleOwner) { isVideo ->
if (isVideo) {
binding.videoPlayer.setVideoPath(path)
binding.videoPlayer.setOnCompletionListener {
Log.i("$TAG End of file reached")
viewModel.isVideoPlaying.value = false
}
(view.parent as? ViewGroup)?.doOnPreDraw {
binding.videoPlayer.start()
viewModel.isVideoPlaying.value = true
}
}
}
viewModel.toggleVideoPlayPauseEvent.observe(viewLifecycleOwner) {
it.consume { play ->
if (play) {
binding.videoPlayer.start()
} else {
binding.videoPlayer.pause()
}
}
}
viewModel.showGreenToastEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
val message = pair.first
@ -191,21 +163,9 @@ class FileViewerFragment : SlidingPaneChildFragment() {
override fun onPause() {
binding.pdfViewPager.unregisterOnPageChangeCallback(pageChangedListener)
if (binding.videoPlayer.isPlaying) {
binding.videoPlayer.pause()
viewModel.isVideoPlaying.value = false
}
super.onPause()
}
override fun onDestroyView() {
binding.videoPlayer.stopPlayback()
super.onDestroyView()
}
override fun onDestroy() {
// Reset default navigation bar color
requireActivity().window.navigationBarColor = navBarDefaultColor

View file

@ -17,7 +17,7 @@
* 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.chat.fragment
package org.linphone.ui.main.file_media_viewer.fragment
import android.net.Uri
import android.os.Bundle
@ -27,7 +27,6 @@ import android.view.ViewGroup
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.viewpager2.widget.ViewPager2
import kotlinx.coroutines.Dispatchers
@ -35,21 +34,21 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatMediaViewerFragmentBinding
import org.linphone.databinding.FileMediaViewerFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.chat.adapter.MediaListAdapter
import org.linphone.ui.main.chat.viewmodel.ConversationMediaListViewModel
import org.linphone.ui.main.fragment.SlidingPaneChildFragment
import org.linphone.ui.main.file_media_viewer.adapter.MediaListAdapter
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.FileUtils
class MediaListViewerFragment : SlidingPaneChildFragment() {
class MediaListViewerFragment : GenericFragment() {
companion object {
private const val TAG = "[Media List Viewer]"
}
private lateinit var binding: ChatMediaViewerFragmentBinding
private lateinit var binding: FileMediaViewerFragmentBinding
private lateinit var adapter: MediaListAdapter
@ -76,14 +75,10 @@ class MediaListViewerFragment : SlidingPaneChildFragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = ChatMediaViewerFragmentBinding.inflate(layoutInflater)
binding = FileMediaViewerFragmentBinding.inflate(layoutInflater)
return binding.root
}
override fun goBack(): Boolean {
return findNavController().popBackStack()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
super.onViewCreated(view, savedInstanceState)
@ -218,7 +213,9 @@ class MediaListViewerFragment : SlidingPaneChildFragment() {
// Reset default navigation bar color
requireActivity().window.navigationBarColor = navBarDefaultColor
viewPager.unregisterOnPageChangeCallback(pageListener)
if (::viewPager.isInitialized) {
viewPager.unregisterOnPageChangeCallback(pageListener)
}
super.onDestroy()
}

View file

@ -1,26 +1,24 @@
package org.linphone.ui.main.chat.fragment
package org.linphone.ui.main.file_media_viewer.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.UiThread
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatMediaViewerChildFragmentBinding
import org.linphone.ui.main.chat.viewmodel.MediaViewModel
import org.linphone.databinding.FileMediaViewerChildFragmentBinding
import org.linphone.ui.main.file_media_viewer.viewmodel.MediaViewModel
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.ui.main.viewmodel.SharedMainViewModel
@UiThread
class MediaViewerFragment : Fragment() {
class MediaViewerFragment : GenericFragment() {
companion object {
private const val TAG = "[Media Viewer Fragment]"
}
private lateinit var binding: ChatMediaViewerChildFragmentBinding
private lateinit var sharedViewModel: SharedMainViewModel
private lateinit var binding: FileMediaViewerChildFragmentBinding
private lateinit var viewModel: MediaViewModel
@ -29,7 +27,7 @@ class MediaViewerFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = ChatMediaViewerChildFragmentBinding.inflate(layoutInflater)
binding = FileMediaViewerChildFragmentBinding.inflate(layoutInflater)
return binding.root
}

View file

@ -1,4 +1,4 @@
package org.linphone.ui.main.viewer.viewmodel
package org.linphone.ui.main.file_media_viewer.viewmodel
import android.graphics.Bitmap
import android.graphics.pdf.PdfRenderer
@ -28,8 +28,6 @@ class FileViewModel @UiThread constructor() : ViewModel() {
private const val TAG = "[File ViewModel]"
}
val path = MutableLiveData<String>()
val fileName = MutableLiveData<String>()
val fullScreenMode = MutableLiveData<Boolean>()
@ -40,14 +38,8 @@ class FileViewModel @UiThread constructor() : ViewModel() {
val pdfPages = MutableLiveData<String>()
val isImage = MutableLiveData<Boolean>()
val isAudio = MutableLiveData<Boolean>()
val isVideo = MutableLiveData<Boolean>()
val isVideoPlaying = MutableLiveData<Boolean>()
val isText = MutableLiveData<Boolean>()
val text = MutableLiveData<String>()
@ -62,10 +54,6 @@ class FileViewModel @UiThread constructor() : ViewModel() {
MutableLiveData<Event<String>>()
}
val toggleVideoPlayPauseEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val showGreenToastEvent: MutableLiveData<Event<Pair<String, Int>>> by lazy {
MutableLiveData<Event<Pair<String, Int>>>()
}
@ -110,18 +98,6 @@ class FileViewModel @UiThread constructor() : ViewModel() {
Log.i("$TAG File [$file] seems to be a PDF")
loadPdf()
}
FileUtils.MimeType.Image -> {
Log.i("$TAG File [$file] seems to be an image")
isImage.value = true
path.value = file
fileReadyEvent.value = Event(true)
}
FileUtils.MimeType.Video -> {
Log.i("$TAG File [$file] seems to be a video")
isVideo.value = true
isVideoPlaying.value = false
fileReadyEvent.value = Event(true)
}
FileUtils.MimeType.Audio -> {
Log.i("$TAG File [$file] seems to be an audio")
// TODO: handle audio files
@ -189,13 +165,6 @@ class FileViewModel @UiThread constructor() : ViewModel() {
}
}
@UiThread
fun playPauseVideo() {
val playVideo = isVideoPlaying.value == false
isVideoPlaying.value = playVideo
toggleVideoPlayPauseEvent.value = Event(playVideo)
}
@UiThread
fun exportToMediaStore() {
if (::filePath.isInitialized) {

View file

@ -1,4 +1,4 @@
package org.linphone.ui.main.chat.viewmodel
package org.linphone.ui.main.file_media_viewer.viewmodel
import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData

View file

@ -20,6 +20,7 @@
package org.linphone.ui.main.viewmodel
import android.net.Uri
import android.os.Bundle
import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
@ -108,6 +109,10 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() {
val mediaViewerFullScreenMode = MutableLiveData<Boolean>()
val displayFileEvent: MutableLiveData<Event<Bundle>> by lazy {
MutableLiveData<Event<Bundle>>()
}
val forceRefreshConversationInfo: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}

View file

@ -1,165 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="backClickListener"
type="View.OnClickListener" />
<variable
name="shareClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.main.viewer.viewmodel.FileViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<VideoView
android:id="@+id/video_player"
android:onClick="@{() -> viewModel.toggleFullScreen()}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:visibility="@{viewModel.isVideo ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/play_pause_video_playback"
android:onClick="@{() -> viewModel.playPauseVideo()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:padding="8dp"
android:src="@{viewModel.isVideoPlaying ? @drawable/pause_fill : @drawable/play_fill, default=@drawable/play_fill}"
android:visibility="@{viewModel.isVideo &amp;&amp; !viewModel.fullScreenMode ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintBottom_toTopOf="@id/file_name"
app:layout_constraintStart_toStartOf="@id/pdf_view_pager"
app:layout_constraintEnd_toEndOf="@id/pdf_view_pager"
app:tint="?attr/color_main1_500"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pdf_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="@{viewModel.isPdf ? View.VISIBLE : View.GONE, default=gone}" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/pages_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:visibility="@{viewModel.isPdf ? View.VISIBLE : View.GONE, default=gone}"
android:text="@{viewModel.pdfCurrentPage + ` / ` + viewModel.pdfPages, default=`1 / 30`}"
android:textColor="@color/white"
android:background="#80000000"
app:layout_constraintBottom_toTopOf="@id/file_name"
app:layout_constraintStart_toStartOf="@id/pdf_view_pager"
app:layout_constraintEnd_toEndOf="@id/pdf_view_pager" />
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/image"
android:onClick="@{() -> viewModel.toggleFullScreen()}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/illu"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
coilFile="@{viewModel.path}"
android:visibility="@{viewModel.isImage ? View.VISIBLE : View.GONE, default=gone}" />
<ImageView
android:id="@+id/back"
android:onClick="@{backClickListener}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="?attr/color_main2_000"
android:adjustViewBounds="true"
android:padding="15dp"
android:src="@drawable/caret_left"
android:contentDescription="@string/content_description_go_back_icon"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:tint="?attr/color_main1_500"
app:layout_constraintBottom_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/main_page_title_style"
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:background="?attr/color_main2_000"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text=""
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:layout_constraintEnd_toStartOf="@id/share"
app:layout_constraintStart_toEndOf="@id/back"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/share"
android:onClick="@{shareClickListener}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="?attr/color_main2_000"
android:adjustViewBounds="true"
android:padding="15dp"
android:src="@drawable/share_network"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:tint="?attr/color_main1_500"
app:layout_constraintBottom_toBottomOf="@id/title"
app:layout_constraintEnd_toStartOf="@id/save"
app:layout_constraintTop_toTopOf="@id/title" />
<ImageView
android:id="@+id/save"
android:onClick="@{() -> viewModel.exportToMediaStore()}"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="?attr/color_main2_000"
android:adjustViewBounds="true"
android:padding="15dp"
android:src="@drawable/download_simple"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:tint="?attr/color_main1_500"
app:layout_constraintBottom_toBottomOf="@id/title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style_300"
android:id="@+id/file_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/color_main2_000"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:text="@{viewModel.fileName, default=`nomdufichier.jpg\nenvoyé le 02/05/2023 à 11h05`}"
android:textSize="12sp"
android:textColor="?attr/color_main2_400"
android:textAlignment="center"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -7,7 +7,7 @@
<import type="android.view.View" />
<variable
name="viewModel"
type="org.linphone.ui.main.chat.viewmodel.MediaViewModel" />
type="org.linphone.ui.main.file_media_viewer.viewmodel.MediaViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout

View file

@ -13,7 +13,7 @@
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.main.viewer.viewmodel.FileViewModel" />
type="org.linphone.ui.main.file_media_viewer.viewmodel.FileViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
@ -21,31 +21,6 @@
android:layout_height="match_parent"
android:background="@color/black">
<VideoView
android:id="@+id/video_player"
android:onClick="@{() -> viewModel.toggleFullScreen()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="@{viewModel.isVideo ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/play_pause_video_playback"
android:onClick="@{() -> viewModel.playPauseVideo()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:padding="8dp"
android:src="@{viewModel.isVideoPlaying ? @drawable/pause_fill : @drawable/play_fill, default=@drawable/play_fill}"
android:visibility="@{viewModel.isVideo &amp;&amp; !viewModel.fullScreenMode ? View.VISIBLE : View.GONE, default=gone}"
app:layout_constraintBottom_toTopOf="@id/file_name"
app:layout_constraintStart_toStartOf="@id/pdf_view_pager"
app:layout_constraintEnd_toEndOf="@id/pdf_view_pager"
app:tint="?attr/color_main1_500"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pdf_view_pager"
android:layout_width="match_parent"
@ -71,17 +46,6 @@
app:layout_constraintStart_toStartOf="@id/pdf_view_pager"
app:layout_constraintEnd_toEndOf="@id/pdf_view_pager" />
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/image"
android:onClick="@{() -> viewModel.toggleFullScreen()}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/illu"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
coilFile="@{viewModel.path}"
android:visibility="@{viewModel.isImage ? View.VISIBLE : View.GONE, default=gone}" />
<ScrollView
android:id="@+id/text"
android:background="?attr/color_main2_000"

View file

@ -43,18 +43,6 @@
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
<action
android:id="@+id/action_conversationFragment_to_fileViewerFragment"
app:destination="@id/fileViewerFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
<action
android:id="@+id/action_conversationFragment_to_mediaListViewerFragment"
app:destination="@id/mediaListViewerFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
</fragment>
<action
@ -118,43 +106,6 @@
<argument
android:name="remoteSipUri"
app:argType="string" />
<action
android:id="@+id/action_conversationMediaListFragment_to_fileViewerFragment"
app:destination="@id/fileViewerFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
<action
android:id="@+id/action_conversationMediaListFragment_to_mediaListViewerFragment"
app:destination="@id/mediaListViewerFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
</fragment>
<fragment
android:id="@+id/fileViewerFragment"
android:name="org.linphone.ui.main.viewer.fragment.FileViewerFragment"
android:label="FileViewerFragment"
tools:layout="@layout/file_viewer_fragment">
<argument
android:name="path"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/mediaListViewerFragment"
android:name="org.linphone.ui.main.chat.fragment.MediaListViewerFragment"
android:label="MediaListViewerFragment"
tools:layout="@layout/chat_media_viewer_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
app:argType="string" />
<argument
android:name="path"
app:argType="string" />
</fragment>
</navigation>

View file

@ -238,6 +238,18 @@
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
app:launchSingleTop="true" />
<action
android:id="@+id/action_conversationsListFragment_to_mediaListViewerFragment"
app:destination="@id/mediaListViewerFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
<action
android:id="@+id/action_conversationsListFragment_to_fileViewerFragment"
app:destination="@id/fileViewerFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out" />
</fragment>
<fragment
@ -310,7 +322,9 @@
<action android:id="@+id/action_global_conversationsListFragment"
app:destination="@id/conversationsListFragment"
app:launchSingleTop="true"/>
app:launchSingleTop="true"
app:popUpTo="@id/contactsListFragment"
app:popUpToInclusive="true"/>
<fragment
android:id="@+id/meetingWaitingRoomFragment"
@ -321,4 +335,31 @@
android:name="conferenceUri"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/fileViewerFragment"
android:name="org.linphone.ui.main.file_media_viewer.fragment.FileViewerFragment"
android:label="FileViewerFragment"
tools:layout="@layout/file_viewer_fragment">
<argument
android:name="path"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/mediaListViewerFragment"
android:name="org.linphone.ui.main.file_media_viewer.fragment.MediaListViewerFragment"
android:label="MediaListViewerFragment"
tools:layout="@layout/file_media_viewer_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
app:argType="string" />
<argument
android:name="path"
app:argType="string" />
</fragment>
</navigation>