Create GalleryOrCameraDialogHelper to factorize code

This commit is contained in:
Benoit Marty 2020-10-20 11:49:56 +02:00 committed by Benoit Marty
parent 02d3893b6b
commit 77c5b320d1
2 changed files with 111 additions and 58 deletions

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.dialogs
import android.app.Activity
import android.net.Uri
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.registerForPermissionsResult
import im.vector.lib.multipicker.MultiPicker
import im.vector.lib.multipicker.entity.MultiPickerImageType
class GalleryOrCameraDialogHelper(
private val fragment: Fragment
) {
interface Listener {
fun onImageReady(image: MultiPickerImageType)
}
private val activity by lazy { fragment.requireActivity() }
private val listener: Listener = fragment as? Listener ?: error("Fragment must implements GalleryOrCameraDialogHelper.Listener")
private val takePhotoPermissionActivityResultLauncher = fragment.registerForPermissionsResult { allGranted ->
if (allGranted) {
doOpenCamera()
}
}
private val takePhotoActivityResultLauncher = fragment.registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
avatarCameraUri?.let { uri ->
MultiPicker.get(MultiPicker.CAMERA)
.getTakenPhoto(fragment.requireContext(), uri)
?.let {
listener.onImageReady(it)
}
}
}
}
private val pickImageActivityResultLauncher = fragment.registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
MultiPicker
.get(MultiPicker.IMAGE)
.getSelectedFiles(fragment.requireContext(), activityResult.data)
.firstOrNull()?.let {
listener.onImageReady(it)
}
}
}
private enum class Type {
Gallery,
Camera
}
fun show() {
AlertDialog.Builder(fragment.requireContext())
.setItems(arrayOf(
fragment.getString(R.string.attachment_type_camera),
fragment.getString(R.string.attachment_type_gallery)
)) { dialog, which ->
dialog.cancel()
onAvatarTypeSelected(if (which == 0) Type.Camera else Type.Gallery)
}
.show()
}
private fun onAvatarTypeSelected(type: Type) {
when (type) {
Type.Gallery ->
MultiPicker.get(MultiPicker.IMAGE).single().startWith(pickImageActivityResultLauncher)
Type.Camera ->
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, activity, takePhotoPermissionActivityResultLauncher)) {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(fragment.requireContext(), takePhotoActivityResultLauncher)
}
}
}
private var avatarCameraUri: Uri? = null
private fun doOpenCamera() {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(activity, takePhotoActivityResultLauncher)
}
}

View file

@ -38,6 +38,7 @@ import com.yalantis.ucrop.UCrop
import im.vector.app.R
import im.vector.app.core.animations.AppBarStateChangeListener
import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.copyOnLongClick
@ -46,10 +47,7 @@ import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.copyToClipboard
import im.vector.app.core.utils.registerForPermissionsResult
import im.vector.app.core.utils.startSharePlainTextIntent
import im.vector.app.features.crypto.util.toImageRes
import im.vector.app.features.home.AvatarRenderer
@ -59,7 +57,6 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
import im.vector.app.features.media.BigImageViewerActivity
import im.vector.app.features.media.createUCropWithDefaultSettings
import im.vector.lib.multipicker.MultiPicker
import im.vector.lib.multipicker.entity.MultiPickerImageType
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_matrix_profile.*
@ -80,7 +77,9 @@ class RoomProfileFragment @Inject constructor(
private val roomProfileController: RoomProfileController,
private val avatarRenderer: AvatarRenderer,
val roomProfileViewModelFactory: RoomProfileViewModel.Factory
) : VectorBaseFragment(), RoomProfileController.Callback {
) : VectorBaseFragment(),
RoomProfileController.Callback,
GalleryOrCameraDialogHelper.Listener {
private val roomProfileArgs: RoomProfileArgs by args()
private lateinit var roomListQuickActionsSharedActionViewModel: RoomListQuickActionsSharedActionViewModel
@ -93,6 +92,8 @@ class RoomProfileFragment @Inject constructor(
override fun getMenuRes() = R.menu.vector_room_profile
private val galleryOrCameraDialogHelper = GalleryOrCameraDialogHelper(this)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
roomListQuickActionsSharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java)
@ -272,40 +273,12 @@ class RoomProfileFragment @Inject constructor(
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(requireActivity(), view, ViewCompat.getTransitionName(view) ?: "")
bigImageStartForActivityResult.launch(intent, options)
} else if (it.canChangeAvatar) {
showAvatarSelector()
galleryOrCameraDialogHelper.show()
}
}
private fun showAvatarSelector() {
AlertDialog.Builder(requireContext())
.setItems(arrayOf(
getString(R.string.attachment_type_camera),
getString(R.string.attachment_type_gallery)
)) { dialog, which ->
dialog.cancel()
onAvatarTypeSelected(isCamera = (which == 0))
}
.show()
}
private val takePhotoPermissionActivityResultLauncher = registerForPermissionsResult { allGranted ->
if (allGranted) {
onAvatarTypeSelected(true)
}
}
private var avatarCameraUri: Uri? = null
private fun onAvatarTypeSelected(isCamera: Boolean) {
if (isCamera) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), takePhotoPermissionActivityResultLauncher)) {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(requireActivity(), takePhotoActivityResultLauncher)
}
} else {
MultiPicker.get(MultiPicker.IMAGE).single().startWith(pickImageActivityResultLauncher)
}
}
private fun onRoomAvatarSelected(image: MultiPickerImageType) {
override fun onImageReady(image: MultiPickerImageType) {
val destinationFile = File(requireContext().cacheDir, "${image.displayName}_edited_image_${System.currentTimeMillis()}")
val uri = image.contentUri
createUCropWithDefaultSettings(requireContext(), uri, destinationFile.toUri(), image.displayName)
@ -313,29 +286,6 @@ class RoomProfileFragment @Inject constructor(
.start(requireContext(), this)
}
private val takePhotoActivityResultLauncher = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
avatarCameraUri?.let { uri ->
MultiPicker.get(MultiPicker.CAMERA)
.getTakenPhoto(requireContext(), uri)
?.let {
onRoomAvatarSelected(it)
}
}
}
}
private val pickImageActivityResultLauncher = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
MultiPicker
.get(MultiPicker.IMAGE)
.getSelectedFiles(requireContext(), activityResult.data)
.firstOrNull()?.let {
onRoomAvatarSelected(it)
}
}
}
private val bigImageStartForActivityResult = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
activityResult.data?.let { onAvatarCropped(it.data) }