mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-24 10:25:51 +03:00
Permission and error handling
This commit is contained in:
parent
4c09fb747b
commit
882b143569
5 changed files with 53 additions and 18 deletions
|
@ -45,6 +45,8 @@ import kotlin.math.abs
|
||||||
|
|
||||||
abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventListener {
|
abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventListener {
|
||||||
|
|
||||||
|
protected val rootView: View
|
||||||
|
get() = views.rootContainer
|
||||||
protected val pager2: ViewPager2
|
protected val pager2: ViewPager2
|
||||||
get() = views.attachmentPager
|
get() = views.attachmentPager
|
||||||
protected val imageTransitionView: ImageView
|
protected val imageTransitionView: ImageView
|
||||||
|
@ -301,7 +303,8 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||||
swipeView = views.dismissContainer,
|
swipeView = views.dismissContainer,
|
||||||
shouldAnimateDismiss = { shouldAnimateDismiss() },
|
shouldAnimateDismiss = { shouldAnimateDismiss() },
|
||||||
onDismiss = { animateClose() },
|
onDismiss = { animateClose() },
|
||||||
onSwipeViewMove = ::handleSwipeViewMove)
|
onSwipeViewMove = ::handleSwipeViewMove
|
||||||
|
)
|
||||||
|
|
||||||
private fun createSwipeDirectionDetector() =
|
private fun createSwipeDirectionDetector() =
|
||||||
SwipeDirectionDetector(this) { swipeDirection = it }
|
SwipeDirectionDetector(this) { swipeDirection = it }
|
||||||
|
|
|
@ -2111,7 +2111,6 @@ class TimelineFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO mutualize permission checking creating activity extension or delegation interface?
|
|
||||||
private fun onSaveActionClicked(action: EventSharedAction.Save) {
|
private fun onSaveActionClicked(action: EventSharedAction.Save) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q &&
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q &&
|
||||||
!checkPermissions(PERMISSIONS_FOR_WRITING_FILES, requireActivity(), saveActionActivityResultLauncher)) {
|
!checkPermissions(PERMISSIONS_FOR_WRITING_FILES, requireActivity(), saveActionActivityResultLauncher)) {
|
||||||
|
|
|
@ -17,6 +17,7 @@ package im.vector.app.features.media
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -34,7 +35,13 @@ import com.airbnb.mvrx.viewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.core.extensions.singletonEntryPoint
|
||||||
import im.vector.app.core.intent.getMimeTypeFromUri
|
import im.vector.app.core.intent.getMimeTypeFromUri
|
||||||
|
import im.vector.app.core.platform.showOptimizedSnackbar
|
||||||
|
import im.vector.app.core.utils.PERMISSIONS_FOR_WRITING_FILES
|
||||||
|
import im.vector.app.core.utils.checkPermissions
|
||||||
|
import im.vector.app.core.utils.onPermissionDeniedDialog
|
||||||
|
import im.vector.app.core.utils.registerForPermissionsResult
|
||||||
import im.vector.app.core.utils.shareMedia
|
import im.vector.app.core.utils.shareMedia
|
||||||
import im.vector.app.features.themes.ActivityOtherThemes
|
import im.vector.app.features.themes.ActivityOtherThemes
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
|
@ -81,9 +88,20 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
|
||||||
private val viewModel: VectorAttachmentViewerViewModel by viewModel()
|
private val viewModel: VectorAttachmentViewerViewModel by viewModel()
|
||||||
|
private val errorFormatter by lazy(LazyThreadSafetyMode.NONE) { singletonEntryPoint().errorFormatter() }
|
||||||
private var initialIndex = 0
|
private var initialIndex = 0
|
||||||
private var isAnimatingOut = false
|
private var isAnimatingOut = false
|
||||||
private var currentSourceProvider: BaseAttachmentProvider<*>? = null
|
private var currentSourceProvider: BaseAttachmentProvider<*>? = null
|
||||||
|
private val downloadActionResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||||
|
if (allGranted) {
|
||||||
|
viewModel.pendingAction?.let {
|
||||||
|
viewModel.handle(it)
|
||||||
|
}
|
||||||
|
} else if (deniedPermanently) {
|
||||||
|
onPermissionDeniedDialog(R.string.denied_permission_generic)
|
||||||
|
}
|
||||||
|
viewModel.pendingAction = null
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Lifecycle
|
* Lifecycle
|
||||||
|
@ -254,14 +272,18 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt
|
||||||
|
|
||||||
private fun handleViewEvents(event: VectorAttachmentViewerViewEvents) {
|
private fun handleViewEvents(event: VectorAttachmentViewerViewEvents) {
|
||||||
when (event) {
|
when (event) {
|
||||||
is VectorAttachmentViewerViewEvents.DownloadingMedia -> Unit // TODO show loader?
|
is VectorAttachmentViewerViewEvents.ErrorDownloadingMedia -> showSnackBarError(event.error)
|
||||||
is VectorAttachmentViewerViewEvents.ErrorDownloadingMedia -> {
|
|
||||||
// TODO show snackbar
|
|
||||||
Timber.e("failure saving file: ${event.error}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showSnackBarError(error: Throwable) {
|
||||||
|
rootView.showOptimizedSnackbar(errorFormatter.toHumanReadable(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hasWritePermission() =
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ||
|
||||||
|
checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, downloadActionResultLauncher)
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Specialization AttachmentInteractionListener
|
* Specialization AttachmentInteractionListener
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
@ -294,15 +316,23 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt
|
||||||
|
|
||||||
override fun onDownload() {
|
override fun onDownload() {
|
||||||
// TODO
|
// TODO
|
||||||
// show message on error event: see TimelineFragment
|
// test snackbar error in OnCreate()
|
||||||
// check write file permissions: see TimelineFragment
|
// test write permission checking with Android 9
|
||||||
// should we check if media is saveable?
|
|
||||||
// check if it is already possible to save from menu with long press on video
|
// check if it is already possible to save from menu with long press on video
|
||||||
// check if it works for video or other media type as well
|
// check if it works for video or other media type as well
|
||||||
|
// reorder action for a message according to issue requirements
|
||||||
// add unit tests for usecase? what is the used mock library?
|
// add unit tests for usecase? what is the used mock library?
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
val hasWritePermission = withContext(Dispatchers.Main) {
|
||||||
|
hasWritePermission()
|
||||||
|
}
|
||||||
|
|
||||||
val file = currentSourceProvider?.getFileForSharing(currentPosition) ?: return@launch
|
val file = currentSourceProvider?.getFileForSharing(currentPosition) ?: return@launch
|
||||||
|
if (hasWritePermission) {
|
||||||
viewModel.handle(VectorAttachmentViewerAction.DownloadMedia(file))
|
viewModel.handle(VectorAttachmentViewerAction.DownloadMedia(file))
|
||||||
|
} else {
|
||||||
|
viewModel.pendingAction = VectorAttachmentViewerAction.DownloadMedia(file)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,5 @@ package im.vector.app.features.media
|
||||||
import im.vector.app.core.platform.VectorViewEvents
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
sealed class VectorAttachmentViewerViewEvents : VectorViewEvents {
|
sealed class VectorAttachmentViewerViewEvents : VectorViewEvents {
|
||||||
object DownloadingMedia : VectorAttachmentViewerViewEvents()
|
|
||||||
data class ErrorDownloadingMedia(val error: Throwable) : VectorAttachmentViewerViewEvents()
|
data class ErrorDownloadingMedia(val error: Throwable) : VectorAttachmentViewerViewEvents()
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,12 @@ class VectorAttachmentViewerViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
companion object : MavericksViewModelFactory<VectorAttachmentViewerViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
|
companion object : MavericksViewModelFactory<VectorAttachmentViewerViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
|
/* ==========================================================================================
|
||||||
|
* Public Api
|
||||||
|
* ========================================================================================== */
|
||||||
|
|
||||||
|
var pendingAction: VectorAttachmentViewerAction? = null
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Specialization
|
* Specialization
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
@ -60,9 +66,7 @@ class VectorAttachmentViewerViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun handleDownloadAction(action: VectorAttachmentViewerAction.DownloadMedia) {
|
private fun handleDownloadAction(action: VectorAttachmentViewerAction.DownloadMedia) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_viewEvents.post(VectorAttachmentViewerViewEvents.DownloadingMedia)
|
// Success event is handled via a notification inside the use case
|
||||||
|
|
||||||
// Success event is handled via a notification inside use case
|
|
||||||
downloadMediaUseCase.execute(action.file)
|
downloadMediaUseCase.execute(action.file)
|
||||||
.onFailure { _viewEvents.post(VectorAttachmentViewerViewEvents.ErrorDownloadingMedia(it)) }
|
.onFailure { _viewEvents.post(VectorAttachmentViewerViewEvents.ErrorDownloadingMedia(it)) }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue