Added dialog when VFS is enabled and in-app viewers can't display a file asking whether to export file or open it as text

This commit is contained in:
Sylvain Berfini 2021-04-22 15:48:49 +02:00
parent d55561878f
commit 9147601a1a
17 changed files with 151 additions and 21 deletions

View file

@ -79,7 +79,12 @@ class ChatBubbleActivity : GenericActivity() {
)
}
chatRoom ?: return
if (chatRoom == null) {
Log.e("[Chat Bubble] Chat room is null, aborting!")
finish()
return
}
chatRoom.markAsRead()
viewModel = ViewModelProvider(

View file

@ -117,7 +117,12 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
}
val chatRoom = sharedViewModel.selectedChatRoom.value
chatRoom ?: return
if (chatRoom == null) {
Log.e("[Chat Room] Chat room is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
Compatibility.setLocusIdInContentCaptureSession(binding.root, chatRoom)
@ -253,7 +258,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
else -> {
if (content.isFileEncrypted) {
Log.w("[Chat Message] File is encrypted and can't be opened in one of our viewers...")
// TODO: show dialog to ask user for consent before trying to export the file first
showDialogForUserConsentBeforeExportingFileInThirdPartyApp(path)
} else if (!FileUtils.openFileInThirdPartyApp(requireActivity(), path)) {
showDialogToSuggestOpeningFileAsText()
}
@ -575,8 +580,8 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
private fun showDialogToSuggestOpeningFileAsText() {
val dialogViewModel = DialogViewModel(
requireContext().getString(R.string.dialog_try_open_file_as_text_body),
requireContext().getString(R.string.dialog_try_open_file_as_text_title)
getString(R.string.dialog_try_open_file_as_text_body),
getString(R.string.dialog_try_open_file_as_text_title)
)
val dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
@ -591,4 +596,30 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
dialog.show()
}
private fun showDialogForUserConsentBeforeExportingFileInThirdPartyApp(path: String) {
val dialogViewModel = DialogViewModel(
getString(R.string.chat_message_cant_open_file_in_app_dialog_message),
getString(R.string.chat_message_cant_open_file_in_app_dialog_title)
)
val dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
dialogViewModel.showDeleteButton({
dialog.dismiss()
if (!FileUtils.openFileInThirdPartyApp(requireActivity(), path)) {
showDialogToSuggestOpeningFileAsText()
}
}, getString(R.string.chat_message_cant_open_file_in_app_dialog_export_button))
dialogViewModel.showOkButton({
dialog.dismiss()
navigateToTextFileViewer(true)
}, getString(R.string.chat_message_cant_open_file_in_app_dialog_open_as_text_button))
dialogViewModel.showCancelButton {
dialog.dismiss()
}
dialog.show()
}
}

View file

@ -24,10 +24,12 @@ import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.chat.viewmodels.DevicesListViewModel
import org.linphone.activities.main.chat.viewmodels.DevicesListViewModelFactory
import org.linphone.activities.main.fragments.SecureFragment
import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatRoomDevicesFragmentBinding
class DevicesFragment : SecureFragment<ChatRoomDevicesFragmentBinding>() {
@ -46,7 +48,12 @@ class DevicesFragment : SecureFragment<ChatRoomDevicesFragmentBinding>() {
}
val chatRoom = sharedViewModel.selectedChatRoom.value
chatRoom ?: return
if (chatRoom == null) {
Log.e("[Devices] Chat room is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
isSecure = chatRoom.currentParams.encryptionEnabled()

View file

@ -24,10 +24,12 @@ import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.chat.viewmodels.EphemeralViewModel
import org.linphone.activities.main.chat.viewmodels.EphemeralViewModelFactory
import org.linphone.activities.main.fragments.SecureFragment
import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatRoomEphemeralFragmentBinding
class EphemeralFragment : SecureFragment<ChatRoomEphemeralFragmentBinding>() {
@ -49,7 +51,12 @@ class EphemeralFragment : SecureFragment<ChatRoomEphemeralFragmentBinding>() {
}
val chatRoom = sharedViewModel.selectedChatRoom.value
chatRoom ?: return
if (chatRoom == null) {
Log.e("[Ephemeral] Chat room is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -26,6 +26,7 @@ import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.chat.adapters.ImdnAdapter
import org.linphone.activities.main.chat.viewmodels.ImdnViewModel
import org.linphone.activities.main.chat.viewmodels.ImdnViewModelFactory
@ -54,7 +55,12 @@ class ImdnFragment : SecureFragment<ChatRoomImdnFragmentBinding>() {
}
val chatRoom = sharedViewModel.selectedChatRoom.value
chatRoom ?: return
if (chatRoom == null) {
Log.e("[IMDN] Chat room is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
isSecure = chatRoom.currentParams.encryptionEnabled()

View file

@ -63,7 +63,12 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
}
val contact = sharedViewModel.selectedContact.value
contact ?: return
if (contact == null) {
Log.e("[Contact] Contact is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -27,8 +27,10 @@ import android.widget.MediaController
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.files.viewmodels.AudioFileViewModel
import org.linphone.activities.main.files.viewmodels.AudioFileViewModelFactory
import org.linphone.core.tools.Log
import org.linphone.databinding.FileAudioViewerFragmentBinding
class AudioViewerFragment : GenericViewerFragment<FileAudioViewerFragmentBinding>() {
@ -45,7 +47,12 @@ class AudioViewerFragment : GenericViewerFragment<FileAudioViewerFragmentBinding
binding.lifecycleOwner = this
val content = sharedViewModel.contentToOpen.value
content ?: return
if (content == null) {
Log.e("[Audio Viewer] Content is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -23,9 +23,12 @@ import android.os.Bundle
import android.view.View
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.fragments.SecureFragment
import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.core.tools.Log
abstract class GenericViewerFragment<T : ViewDataBinding> : SecureFragment<T>() {
protected lateinit var sharedViewModel: SharedMainViewModel
@ -44,7 +47,12 @@ abstract class GenericViewerFragment<T : ViewDataBinding> : SecureFragment<T>()
super.onStart()
val content = sharedViewModel.contentToOpen.value
content ?: return
if (content == null) {
Log.e("[Generic Viewer] Content is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
(childFragmentManager.findFragmentById(R.id.top_bar_fragment) as? TopBarFragment)
?.setContent(content)

View file

@ -23,9 +23,12 @@ import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.files.viewmodels.ImageFileViewModel
import org.linphone.activities.main.files.viewmodels.ImageFileViewModelFactory
import org.linphone.core.tools.Log
import org.linphone.databinding.FileImageViewerFragmentBinding
class ImageViewerFragment : GenericViewerFragment<FileImageViewerFragmentBinding>() {
@ -40,7 +43,12 @@ class ImageViewerFragment : GenericViewerFragment<FileImageViewerFragmentBinding
binding.lifecycleOwner = this
val content = sharedViewModel.contentToOpen.value
content ?: return
if (content == null) {
Log.e("[Image Viewer] Content is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -22,10 +22,13 @@ package org.linphone.activities.main.files.fragments
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.files.adapters.PdfPagesListAdapter
import org.linphone.activities.main.files.viewmodels.PdfFileViewModel
import org.linphone.activities.main.files.viewmodels.PdfFileViewModelFactory
import org.linphone.core.tools.Log
import org.linphone.databinding.FilePdfViewerFragmentBinding
class PdfViewerFragment : GenericViewerFragment<FilePdfViewerFragmentBinding>() {
@ -40,7 +43,12 @@ class PdfViewerFragment : GenericViewerFragment<FilePdfViewerFragmentBinding>()
binding.lifecycleOwner = this
val content = sharedViewModel.contentToOpen.value
content ?: return
if (content == null) {
Log.e("[PDF Viewer] Content is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -22,9 +22,12 @@ package org.linphone.activities.main.files.fragments
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.files.viewmodels.TextFileViewModel
import org.linphone.activities.main.files.viewmodels.TextFileViewModelFactory
import org.linphone.core.tools.Log
import org.linphone.databinding.FileTextViewerFragmentBinding
class TextViewerFragment : GenericViewerFragment<FileTextViewerFragmentBinding>() {
@ -38,7 +41,12 @@ class TextViewerFragment : GenericViewerFragment<FileTextViewerFragmentBinding>(
binding.lifecycleOwner = this
val content = sharedViewModel.contentToOpen.value
content ?: return
if (content == null) {
Log.e("[Text Viewer] Content is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -26,6 +26,7 @@ import android.widget.MediaController
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.files.viewmodels.VideoFileViewModel
import org.linphone.activities.main.files.viewmodels.VideoFileViewModelFactory
import org.linphone.core.tools.Log
@ -44,7 +45,12 @@ class VideoViewerFragment : GenericViewerFragment<FileVideoViewerFragmentBinding
binding.lifecycleOwner = this
val content = sharedViewModel.contentToOpen.value
content ?: return
if (content == null) {
Log.e("[Video Viewer] Content is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -53,7 +53,12 @@ class DetailCallLogFragment : GenericFragment<HistoryDetailFragmentBinding>() {
}
val callLogGroup = sharedViewModel.selectedCallLogGroup.value
callLogGroup ?: return
if (callLogGroup == null) {
Log.e("[History] Call log group is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(
this,

View file

@ -25,6 +25,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.GenericFragment
import org.linphone.activities.main.MainActivity
import org.linphone.activities.main.navigateToPhoneLinking
import org.linphone.activities.main.settings.viewmodels.AccountSettingsViewModel
import org.linphone.activities.main.settings.viewmodels.AccountSettingsViewModelFactory
@ -47,7 +48,14 @@ class AccountSettingsFragment : GenericFragment<SettingsAccountFragmentBinding>(
ViewModelProvider(this).get(SharedMainViewModel::class.java)
}
val identity = arguments?.getString("Identity") ?: ""
val identity = arguments?.getString("Identity")
if (identity == null) {
Log.e("[Account Settings] Identity is null, aborting!")
(activity as MainActivity).showSnackBar(R.string.error)
findNavController().navigateUp()
return
}
viewModel = ViewModelProvider(this, AccountSettingsViewModelFactory(identity)).get(AccountSettingsViewModel::class.java)
binding.viewModel = viewModel

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<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"/>
@ -122,13 +123,15 @@
</LinearLayout>
<LinearLayout
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="15dp"
android:gravity="center"
android:orientation="horizontal">
app:flexWrap="nowrap"
app:alignItems="center"
app:justifyContent="center">
<TextView
android:onClick="@{() -> viewModel.onCancelClicked()}"
@ -171,7 +174,7 @@
android:text="@{viewModel.okLabel, default=OK}"
android:visibility="@{viewModel.showOk ? View.VISIBLE : View.GONE}" />
</LinearLayout>
</com.google.android.flexbox.FlexboxLayout>
</LinearLayout>

View file

@ -576,4 +576,8 @@
<string name="call_settings_ring_during_early_media_title">Sonner durant un appel entrant avec early-media</string>
<string name="call_settings_ring_during_early_media_summary"></string>
<string name="debug_popup_show_config_file">Voir le fichier de config</string>
<string name="chat_message_cant_open_file_in_app_dialog_title">Il semblerait que l\'on ne puisse pas afficher ce fichier.</string>
<string name="chat_message_cant_open_file_in_app_dialog_message">Voulez-vous essayer de l\'ouvrir comme texte ou de l\'exporter (en clair) vers une appli tierce si disponible ?</string>
<string name="chat_message_cant_open_file_in_app_dialog_export_button">Exporter</string>
<string name="chat_message_cant_open_file_in_app_dialog_open_as_text_button">Ouvrir comme texte</string>
</resources>

View file

@ -205,6 +205,10 @@
<string name="chat_message_notification_hidden_content">&lt;Redacted&gt;</string>
<string name="chat_message_no_app_found_to_handle_file_mime_type">No app available for this kind of file</string>
<string name="chat_bubble_cant_open_enrypted_file">Can\'t open encrypted file in chat bubble</string>
<string name="chat_message_cant_open_file_in_app_dialog_title">It seems we can\'t display the file.</string>
<string name="chat_message_cant_open_file_in_app_dialog_message">Would you like to open it as text or export it (unencrypted) to a third party app if available?</string>
<string name="chat_message_cant_open_file_in_app_dialog_export_button">Export</string>
<string name="chat_message_cant_open_file_in_app_dialog_open_as_text_button">Open as text</string>
<!-- Recordings -->
<string name="recordings_empty_list">No recordings</string>