Show files shared by chat message in app if possible
This commit is contained in:
parent
5b529e8e3a
commit
b818bf0155
26 changed files with 965 additions and 21 deletions
|
@ -23,6 +23,8 @@ import android.annotation.SuppressLint
|
|||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Display
|
||||
import android.view.Surface
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
|
@ -73,6 +75,8 @@ abstract class GenericActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateScreenSize()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -102,4 +106,14 @@ abstract class GenericActivity : AppCompatActivity() {
|
|||
fun isTablet(): Boolean {
|
||||
return resources.getBoolean(R.bool.isTablet)
|
||||
}
|
||||
|
||||
private fun updateScreenSize() {
|
||||
val metrics = DisplayMetrics()
|
||||
val display: Display = windowManager.defaultDisplay
|
||||
display.getRealMetrics(metrics)
|
||||
val screenWidth = metrics.widthPixels.toFloat()
|
||||
val screenHeight = metrics.heightPixels.toFloat()
|
||||
coreContext.screenWidth = screenWidth
|
||||
coreContext.screenHeight = screenHeight
|
||||
}
|
||||
}
|
||||
|
|
|
@ -348,6 +348,42 @@ internal fun DetailChatRoomFragment.navigateToEphemeralInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
internal fun DetailChatRoomFragment.navigateToTextFileViewer(secure: Boolean) {
|
||||
val bundle = bundleOf("Secure" to secure)
|
||||
findMasterNavController().navigate(
|
||||
R.id.action_global_textViewerFragment,
|
||||
bundle,
|
||||
getRightToLeftAnimationNavOptions()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun DetailChatRoomFragment.navigateToPdfFileViewer(secure: Boolean) {
|
||||
val bundle = bundleOf("Secure" to secure)
|
||||
findMasterNavController().navigate(
|
||||
R.id.action_global_pdfViewerFragment,
|
||||
bundle,
|
||||
getRightToLeftAnimationNavOptions()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun DetailChatRoomFragment.navigateToImageFileViewer(secure: Boolean) {
|
||||
val bundle = bundleOf("Secure" to secure)
|
||||
findMasterNavController().navigate(
|
||||
R.id.action_global_imageViewerFragment,
|
||||
bundle,
|
||||
getRightToLeftAnimationNavOptions()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun DetailChatRoomFragment.navigateToVideoFileViewer(secure: Boolean) {
|
||||
val bundle = bundleOf("Secure" to secure)
|
||||
findMasterNavController().navigate(
|
||||
R.id.action_global_videoViewerFragment,
|
||||
bundle,
|
||||
getRightToLeftAnimationNavOptions()
|
||||
)
|
||||
}
|
||||
|
||||
internal fun ChatRoomCreationFragment.navigateToGroupInfo() {
|
||||
if (findNavController().currentDestination?.id == R.id.chatRoomCreationFragment) {
|
||||
findNavController().navigate(
|
||||
|
|
|
@ -24,8 +24,6 @@ import android.animation.ValueAnimator
|
|||
import android.annotation.TargetApi
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Display
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
|
@ -179,10 +177,7 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
|||
}
|
||||
|
||||
private fun initNumpadLayout() {
|
||||
val metrics = DisplayMetrics()
|
||||
val display: Display = windowManager.defaultDisplay
|
||||
display.getRealMetrics(metrics)
|
||||
val screenWidth = metrics.widthPixels.toFloat()
|
||||
val screenWidth = coreContext.screenWidth
|
||||
numpadAnimator = ValueAnimator.ofFloat(screenWidth, 0f).apply {
|
||||
addUpdateListener {
|
||||
val value = it.animatedValue as Float
|
||||
|
|
|
@ -27,8 +27,6 @@ import android.content.Intent
|
|||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Display
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
|
@ -242,10 +240,7 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
|||
}
|
||||
|
||||
private fun initNumpadLayout() {
|
||||
val metrics = DisplayMetrics()
|
||||
val display: Display = requireActivity().windowManager.defaultDisplay
|
||||
display.getRealMetrics(metrics)
|
||||
val screenWidth = metrics.widthPixels.toFloat()
|
||||
val screenWidth = coreContext.screenWidth
|
||||
numpadAnimator = ValueAnimator.ofFloat(screenWidth, 0f).apply {
|
||||
addUpdateListener {
|
||||
val value = it.animatedValue as Float
|
||||
|
|
|
@ -70,6 +70,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
|||
}
|
||||
|
||||
private lateinit var tabsFragment: FragmentContainerView
|
||||
private lateinit var statusFragment: FragmentContainerView
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -110,6 +111,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
|||
}
|
||||
|
||||
tabsFragment = findViewById(R.id.tabs_fragment)
|
||||
statusFragment = findViewById(R.id.status_fragment)
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
|
@ -154,6 +156,9 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
|||
arguments: Bundle?
|
||||
) {
|
||||
currentFocus?.hideKeyboard()
|
||||
if (statusFragment.visibility == View.GONE) {
|
||||
statusFragment.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
val motionLayout: MotionLayout = binding.content as MotionLayout
|
||||
if (corePreferences.enableAnimations) {
|
||||
|
@ -171,6 +176,10 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin
|
|||
}
|
||||
}
|
||||
|
||||
fun hideStatusFragment() {
|
||||
statusFragment.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun View.hideKeyboard() {
|
||||
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(windowToken, 0)
|
||||
|
|
|
@ -41,6 +41,7 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import java.io.File
|
||||
import kotlinx.coroutines.launch
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||
|
@ -225,7 +226,19 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
|
||||
adapter.openContentEvent.observe(viewLifecycleOwner, {
|
||||
it.consume { path ->
|
||||
openFile(path)
|
||||
if (!File(path).exists()) {
|
||||
(requireActivity() as MainActivity).showSnackBar(R.string.chat_room_file_not_found)
|
||||
} else {
|
||||
Log.i("[Chat Message] Opening file: $path")
|
||||
sharedViewModel.fileToOpen.value = path
|
||||
when {
|
||||
FileUtils.isExtensionImage(path) -> navigateToImageFileViewer(viewModel.chatRoom.currentParams.encryptionEnabled())
|
||||
FileUtils.isExtensionVideo(path) -> navigateToVideoFileViewer(viewModel.chatRoom.currentParams.encryptionEnabled())
|
||||
FileUtils.isExtensionPdf(path) -> navigateToPdfFileViewer(viewModel.chatRoom.currentParams.encryptionEnabled())
|
||||
FileUtils.isPlainTextFile(path) -> navigateToTextFileViewer(viewModel.chatRoom.currentParams.encryptionEnabled())
|
||||
else -> openFile(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -581,14 +594,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
|
||||
dialogViewModel.showOkButton({
|
||||
dialog.dismiss()
|
||||
intent.setDataAndType(contentUri, "text/plain")
|
||||
try {
|
||||
startActivity(intent)
|
||||
} catch (anfe: ActivityNotFoundException) {
|
||||
Log.e("[Chat Message] Couldn't find an activity to handle text/plain MIME type")
|
||||
val activity = requireActivity() as MainActivity
|
||||
activity.showSnackBar(R.string.chat_room_cant_open_file_no_app_found)
|
||||
}
|
||||
navigateToTextFileViewer(viewModel.chatRoom.currentParams.encryptionEnabled())
|
||||
})
|
||||
|
||||
dialog.show()
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.ScaleGestureDetector
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.files.viewmodels.ImageFileViewModel
|
||||
import org.linphone.activities.main.files.viewmodels.ImageFileViewModelFactory
|
||||
import org.linphone.activities.main.fragments.SecureFragment
|
||||
import org.linphone.activities.main.viewmodels.SharedMainViewModel
|
||||
import org.linphone.databinding.ImageViewerFragmentBinding
|
||||
|
||||
class ImageViewerFragment : SecureFragment<ImageViewerFragmentBinding>() {
|
||||
private lateinit var viewModel: ImageFileViewModel
|
||||
private lateinit var sharedViewModel: SharedMainViewModel
|
||||
|
||||
private lateinit var gestureDetector: GestureDetector
|
||||
private lateinit var scaleGestureDetector: ScaleGestureDetector
|
||||
private var scaleFactor = 1.0f
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.image_viewer_fragment
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
|
||||
sharedViewModel = requireActivity().run {
|
||||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||
}
|
||||
|
||||
val filePath = sharedViewModel.fileToOpen.value
|
||||
filePath ?: return
|
||||
|
||||
viewModel = ViewModelProvider(
|
||||
this,
|
||||
ImageFileViewModelFactory(filePath)
|
||||
)[ImageFileViewModel::class.java]
|
||||
binding.viewModel = viewModel
|
||||
|
||||
isSecure = arguments?.getBoolean("Secure") ?: false
|
||||
|
||||
gestureDetector = GestureDetector(requireContext(), object :
|
||||
GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onDoubleTap(e: MotionEvent?): Boolean {
|
||||
scaleFactor = if (scaleFactor == 1.0f) 2.0f else 1.0f
|
||||
binding.imageView.scaleX = scaleFactor
|
||||
binding.imageView.scaleY = scaleFactor
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScroll(
|
||||
e1: MotionEvent?,
|
||||
e2: MotionEvent?,
|
||||
distanceX: Float,
|
||||
distanceY: Float
|
||||
): Boolean {
|
||||
if (scaleFactor <= 1.0f) return false
|
||||
|
||||
val scrollX = binding.imageView.scrollX + distanceX.toInt()
|
||||
binding.imageView.scrollX = scrollX
|
||||
|
||||
val scrollY = binding.imageView.scrollY + distanceY.toInt()
|
||||
binding.imageView.scrollY = scrollY
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
scaleGestureDetector = ScaleGestureDetector(requireContext(), object :
|
||||
ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||
scaleFactor *= detector.scaleFactor
|
||||
scaleFactor = scaleFactor.coerceIn(0.1f, 5.0f)
|
||||
binding.imageView.scaleX = scaleFactor
|
||||
binding.imageView.scaleY = scaleFactor
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
binding.imageView.setOnTouchListener { _, event ->
|
||||
val previousScaleFactor = scaleFactor
|
||||
scaleGestureDetector.onTouchEvent(event)
|
||||
|
||||
if (previousScaleFactor != scaleFactor) {
|
||||
// Prevent touch event from going further
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
|
||||
gestureDetector.onTouchEvent(event)
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.files.viewmodels.PdfFileViewModel
|
||||
import org.linphone.activities.main.files.viewmodels.PdfFileViewModelFactory
|
||||
import org.linphone.activities.main.fragments.SecureFragment
|
||||
import org.linphone.activities.main.viewmodels.SharedMainViewModel
|
||||
import org.linphone.databinding.PdfViewerFragmentBinding
|
||||
|
||||
class PdfViewerFragment : SecureFragment<PdfViewerFragmentBinding>() {
|
||||
private lateinit var viewModel: PdfFileViewModel
|
||||
private lateinit var sharedViewModel: SharedMainViewModel
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.pdf_viewer_fragment
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
|
||||
sharedViewModel = requireActivity().run {
|
||||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||
}
|
||||
|
||||
val filePath = sharedViewModel.fileToOpen.value
|
||||
filePath ?: return
|
||||
|
||||
viewModel = ViewModelProvider(
|
||||
this,
|
||||
PdfFileViewModelFactory(filePath)
|
||||
)[PdfFileViewModel::class.java]
|
||||
binding.viewModel = viewModel
|
||||
|
||||
isSecure = arguments?.getBoolean("Secure") ?: false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.files.viewmodels.TextFileViewModel
|
||||
import org.linphone.activities.main.files.viewmodels.TextFileViewModelFactory
|
||||
import org.linphone.activities.main.fragments.SecureFragment
|
||||
import org.linphone.activities.main.viewmodels.SharedMainViewModel
|
||||
import org.linphone.databinding.TextViewerFragmentBinding
|
||||
|
||||
class TextViewerFragment : SecureFragment<TextViewerFragmentBinding>() {
|
||||
private lateinit var viewModel: TextFileViewModel
|
||||
private lateinit var sharedViewModel: SharedMainViewModel
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.text_viewer_fragment
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
|
||||
sharedViewModel = requireActivity().run {
|
||||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||
}
|
||||
|
||||
val filePath = sharedViewModel.fileToOpen.value
|
||||
filePath ?: return
|
||||
|
||||
viewModel = ViewModelProvider(
|
||||
this,
|
||||
TextFileViewModelFactory(filePath)
|
||||
)[TextFileViewModel::class.java]
|
||||
binding.viewModel = viewModel
|
||||
|
||||
isSecure = arguments?.getBoolean("Secure") ?: false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.GenericFragment
|
||||
import org.linphone.databinding.FileViewerTopBarFragmentBinding
|
||||
|
||||
class TopBarFragment : GenericFragment<FileViewerTopBarFragmentBinding>() {
|
||||
override fun getLayoutId(): Int = R.layout.file_viewer_top_bar_fragment
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
|
||||
binding.setBackClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.MediaController
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.files.viewmodels.VideoFileViewModel
|
||||
import org.linphone.activities.main.files.viewmodels.VideoFileViewModelFactory
|
||||
import org.linphone.activities.main.fragments.SecureFragment
|
||||
import org.linphone.activities.main.viewmodels.SharedMainViewModel
|
||||
import org.linphone.databinding.VideoViewerFragmentBinding
|
||||
|
||||
class VideoViewerFragment : SecureFragment<VideoViewerFragmentBinding>() {
|
||||
private lateinit var viewModel: VideoFileViewModel
|
||||
private lateinit var sharedViewModel: SharedMainViewModel
|
||||
|
||||
override fun getLayoutId(): Int = R.layout.video_viewer_fragment
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
binding.lifecycleOwner = this
|
||||
|
||||
sharedViewModel = requireActivity().run {
|
||||
ViewModelProvider(this).get(SharedMainViewModel::class.java)
|
||||
}
|
||||
|
||||
val filePath = sharedViewModel.fileToOpen.value
|
||||
filePath ?: return
|
||||
|
||||
viewModel = ViewModelProvider(
|
||||
this,
|
||||
VideoFileViewModelFactory(filePath)
|
||||
)[VideoFileViewModel::class.java]
|
||||
binding.viewModel = viewModel
|
||||
|
||||
initVideoControls()
|
||||
|
||||
isSecure = arguments?.getBoolean("Secure") ?: false
|
||||
}
|
||||
|
||||
private fun initVideoControls() {
|
||||
val mediaController = MediaController(requireContext())
|
||||
viewModel.initMediaController(mediaController, binding.videoView)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.viewmodels
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
||||
class ImageFileViewModelFactory(private val filePath: String) :
|
||||
ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return ImageFileViewModel(filePath) as T
|
||||
}
|
||||
}
|
||||
|
||||
class ImageFileViewModel(val filePath: String) : ViewModel()
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.viewmodels
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.pdf.PdfRenderer
|
||||
import android.os.ParcelFileDescriptor
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import java.io.File
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.tools.Log
|
||||
|
||||
class PdfFileViewModelFactory(private val filePath: String) :
|
||||
ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return PdfFileViewModel(filePath) as T
|
||||
}
|
||||
}
|
||||
|
||||
class PdfFileViewModel(filePath: String) : ViewModel() {
|
||||
val operationInProgress = MutableLiveData<Boolean>()
|
||||
|
||||
val pages = MutableLiveData<ArrayList<PdfPageViewModel>>()
|
||||
|
||||
private val pdfRenderer: PdfRenderer
|
||||
|
||||
init {
|
||||
operationInProgress.value = false
|
||||
|
||||
val input = ParcelFileDescriptor.open(File(filePath), ParcelFileDescriptor.MODE_READ_ONLY)
|
||||
pdfRenderer = PdfRenderer(input)
|
||||
Log.i("[PDF Viewer] ${pdfRenderer.pageCount} pages in file $filePath")
|
||||
|
||||
loadPdf()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
for (page in pages.value.orEmpty()) {
|
||||
page.destroy()
|
||||
}
|
||||
pages.value?.clear()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun loadPdf() {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
operationInProgress.postValue(true)
|
||||
|
||||
for (index in 0 until pdfRenderer.pageCount) {
|
||||
val page: PdfRenderer.Page = pdfRenderer.openPage(index)
|
||||
val width = if (coreContext.screenWidth <= coreContext.screenHeight) coreContext.screenWidth else coreContext.screenHeight
|
||||
val bm = Bitmap.createBitmap(
|
||||
width.toInt(),
|
||||
(width / page.width * page.height).toInt(),
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
page.render(bm, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||
page.close()
|
||||
|
||||
val pageViewModel = PdfPageViewModel(bm)
|
||||
val list = arrayListOf<PdfPageViewModel>()
|
||||
list.addAll(pages.value.orEmpty())
|
||||
list.add(pageViewModel)
|
||||
pages.postValue(list)
|
||||
}
|
||||
|
||||
operationInProgress.postValue(false)
|
||||
} catch (e: Exception) {
|
||||
Log.e("[PDF Viewer] Exception: $e")
|
||||
operationInProgress.postValue(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PdfPageViewModel(val bitmap: Bitmap) {
|
||||
fun destroy() {
|
||||
bitmap.recycle()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.viewmodels
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import java.io.BufferedReader
|
||||
import java.io.FileReader
|
||||
import java.lang.StringBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.linphone.core.tools.Log
|
||||
|
||||
class TextFileViewModelFactory(private val filePath: String) :
|
||||
ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return TextFileViewModel(filePath) as T
|
||||
}
|
||||
}
|
||||
|
||||
class TextFileViewModel(filePath: String) : ViewModel() {
|
||||
val operationInProgress = MutableLiveData<Boolean>()
|
||||
|
||||
val text = MutableLiveData<String>()
|
||||
|
||||
init {
|
||||
operationInProgress.value = false
|
||||
|
||||
openFile(filePath)
|
||||
}
|
||||
|
||||
private fun openFile(filePath: String) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
operationInProgress.postValue(true)
|
||||
|
||||
try {
|
||||
val br = BufferedReader(FileReader(filePath))
|
||||
var line: String?
|
||||
var textBuilder = StringBuilder()
|
||||
while (br.readLine().also { line = it } != null) {
|
||||
textBuilder.append(line)
|
||||
textBuilder.append('\n')
|
||||
}
|
||||
br.close()
|
||||
|
||||
text.postValue(textBuilder.toString())
|
||||
operationInProgress.postValue(false)
|
||||
} catch (e: Exception) {
|
||||
Log.e("[Text Viewer] Exception: $e")
|
||||
operationInProgress.postValue(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 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.activities.main.files.viewmodels
|
||||
|
||||
import android.widget.MediaController
|
||||
import android.widget.VideoView
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.core.tools.Log
|
||||
|
||||
class VideoFileViewModelFactory(private val filePath: String) :
|
||||
ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||
return VideoFileViewModel(filePath) as T
|
||||
}
|
||||
}
|
||||
|
||||
class VideoFileViewModel(val filePath: String) : ViewModel() {
|
||||
|
||||
fun initMediaController(mediaController: MediaController, videoView: VideoView) {
|
||||
videoView.setOnPreparedListener { mediaPlayer ->
|
||||
mediaPlayer.setOnVideoSizeChangedListener { _, _, _ ->
|
||||
videoView.setMediaController(mediaController)
|
||||
// The following will make the video controls above the video
|
||||
// mediaController.setAnchorView(videoView)
|
||||
}
|
||||
}
|
||||
|
||||
videoView.setOnCompletionListener { mediaPlayer ->
|
||||
mediaPlayer.release()
|
||||
}
|
||||
|
||||
videoView.setOnErrorListener { _, what, extra ->
|
||||
Log.e("[Video Viewer] Error: $what ($extra)")
|
||||
false
|
||||
}
|
||||
|
||||
videoView.setVideoPath(filePath)
|
||||
videoView.start()
|
||||
}
|
||||
}
|
|
@ -48,6 +48,8 @@ class SharedMainViewModel : ViewModel() {
|
|||
MutableLiveData<Event<ChatMessage>>()
|
||||
}
|
||||
|
||||
val fileToOpen = MutableLiveData<String>()
|
||||
|
||||
var createEncryptedChatRoom: Boolean = false
|
||||
|
||||
val chatRoomParticipants = MutableLiveData<ArrayList<Address>>()
|
||||
|
|
|
@ -56,6 +56,9 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
val core: Core
|
||||
val handler: Handler = Handler(Looper.getMainLooper())
|
||||
|
||||
var screenWidth: Float = 0f
|
||||
var screenHeight: Float = 0f
|
||||
|
||||
val appVersion: String by lazy {
|
||||
val appVersion = org.linphone.BuildConfig.VERSION_NAME
|
||||
val appBranch = context.getString(R.string.linphone_app_branch)
|
||||
|
|
|
@ -59,6 +59,18 @@ class FileUtils {
|
|||
return extension
|
||||
}
|
||||
|
||||
fun isPlainTextFile(path: String): Boolean {
|
||||
val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault())
|
||||
val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
|
||||
return type?.startsWith("text/plain") ?: false
|
||||
}
|
||||
|
||||
fun isExtensionPdf(path: String): Boolean {
|
||||
val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault())
|
||||
val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
|
||||
return type?.startsWith("application/pdf") ?: false
|
||||
}
|
||||
|
||||
fun isExtensionImage(path: String): Boolean {
|
||||
val extension = getExtensionFromFileName(path).toLowerCase(Locale.getDefault())
|
||||
val type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
|
||||
|
|
38
app/src/main/res/layout/file_viewer_top_bar_fragment.xml
Normal file
38
app/src/main/res/layout/file_viewer_top_bar_fragment.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<variable
|
||||
name="backClickListener"
|
||||
type="android.view.View.OnClickListener"/>
|
||||
</data>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/top_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="?attr/lightToolbarBackgroundColor"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back"
|
||||
android:onClick="@{backClickListener}"
|
||||
android:contentDescription="@string/content_description_go_back"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2"
|
||||
android:background="?attr/button_background_drawable"
|
||||
android:padding="18dp"
|
||||
android:src="@drawable/back" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.8"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</layout>
|
43
app/src/main/res/layout/image_viewer_fragment.xml
Normal file
43
app/src/main/res/layout/image_viewer_fragment.xml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.activities.main.files.viewmodels.ImageFileViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black_color">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/top_bar_fragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.TopBarFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
tools:layout="@layout/file_viewer_top_bar_fragment" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/top_bar_fragment"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
glidePath="@{viewModel.filePath}"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
23
app/src/main/res/layout/pdf_viewer_cell.xml
Normal file
23
app/src/main/res/layout/pdf_viewer_cell.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<variable
|
||||
name="data"
|
||||
type="org.linphone.activities.main.files.viewmodels.PdfFileViewModel.PdfPageViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:src="@{data.bitmap}" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
46
app/src/main/res/layout/pdf_viewer_fragment.xml
Normal file
46
app/src/main/res/layout/pdf_viewer_fragment.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.activities.main.files.viewmodels.PdfFileViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/backgroundColor">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/top_bar_fragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.TopBarFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
tools:layout="@layout/file_viewer_top_bar_fragment" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/top_bar_fragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
bind:entries="@{viewModel.pages}"
|
||||
bind:layout="@{@layout/pdf_viewer_cell}"/>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<include
|
||||
layout="@layout/wait_layout"
|
||||
bind:visibility="@{viewModel.operationInProgress}"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
46
app/src/main/res/layout/text_viewer_fragment.xml
Normal file
46
app/src/main/res/layout/text_viewer_fragment.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.activities.main.files.viewmodels.TextFileViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/backgroundColor">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/top_bar_fragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.TopBarFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
tools:layout="@layout/file_viewer_top_bar_fragment" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/top_bar_fragment">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:singleLine="false"
|
||||
android:text="@{viewModel.text}"/>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<include
|
||||
layout="@layout/wait_layout"
|
||||
bind:visibility="@{viewModel.operationInProgress}"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
40
app/src/main/res/layout/video_viewer_fragment.xml
Normal file
40
app/src/main/res/layout/video_viewer_fragment.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
<import type="android.view.View"/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.activities.main.files.viewmodels.VideoFileViewModel" />
|
||||
</data>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black_color">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/top_bar_fragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.TopBarFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
tools:layout="@layout/file_viewer_top_bar_fragment" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/top_bar_fragment">
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/video_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</layout>
|
|
@ -320,5 +320,25 @@
|
|||
android:name="IsLinking"
|
||||
app:argType="boolean" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/textViewerFragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.TextViewerFragment"
|
||||
android:label="TextViewerFragment" />
|
||||
<action android:id="@+id/action_global_textViewerFragment" app:destination="@id/textViewerFragment" />
|
||||
<fragment
|
||||
android:id="@+id/pdfViewerFragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.PdfViewerFragment"
|
||||
android:label="PdfViewerFragment" />
|
||||
<action android:id="@+id/action_global_pdfViewerFragment" app:destination="@id/pdfViewerFragment" />
|
||||
<fragment
|
||||
android:id="@+id/imageViewerFragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.ImageViewerFragment"
|
||||
android:label="ImageViewerFragment" />
|
||||
<action android:id="@+id/action_global_imageViewerFragment" app:destination="@id/imageViewerFragment"/>
|
||||
<fragment
|
||||
android:id="@+id/videoViewerFragment"
|
||||
android:name="org.linphone.activities.main.files.fragments.VideoViewerFragment"
|
||||
android:label="VideoViewerFragment" />
|
||||
<action android:id="@+id/action_global_videoViewerFragment" app:destination="@id/videoViewerFragment"/>
|
||||
|
||||
</navigation>
|
|
@ -173,6 +173,7 @@
|
|||
<string name="chat_room_dummy_subject" translatable="false">dummy subject</string>
|
||||
<string name="chat_room_toast_choose_for_sharing">Select a conversation or create a new one</string>
|
||||
<string name="chat_room_cant_open_file_no_app_found">Can\'t open file, no application available for this format.</string>
|
||||
<string name="chat_room_file_not_found">File not found</string>
|
||||
<string name="chat_room_creation_failed">Chat room creation failed</string>
|
||||
<string name="chat_room_context_menu_group_info">Group info</string>
|
||||
<string name="chat_room_context_menu_participants_devices">Conversation\'s devices</string>
|
||||
|
|
Loading…
Reference in a new issue