Merge pull request #1400 from vector-im/feature/bma/fixCrashPhoto

Fix crash when user wants to use the camera
This commit is contained in:
Benoit Marty 2023-09-21 16:31:36 +02:00 committed by GitHub
commit 5119ca33dd
47 changed files with 597 additions and 143 deletions

View file

@ -39,6 +39,8 @@ import io.element.android.libraries.matrix.api.room.powerlevels.canSendState
import io.element.android.libraries.matrix.ui.media.AvatarAction
import io.element.android.libraries.mediapickers.api.PickerProvider
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
import io.element.android.libraries.permissions.api.PermissionsEvents
import io.element.android.libraries.permissions.api.PermissionsPresenter
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@ -49,10 +51,15 @@ class RoomDetailsEditPresenter @Inject constructor(
private val room: MatrixRoom,
private val mediaPickerProvider: PickerProvider,
private val mediaPreProcessor: MediaPreProcessor,
permissionsPresenterFactory: PermissionsPresenter.Factory,
) : Presenter<RoomDetailsEditState> {
private val cameraPermissionPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA)
private var pendingPermissionRequest = false
@Composable
override fun present(): RoomDetailsEditState {
val cameraPermissionState = cameraPermissionPresenter.present()
val roomSyncUpdateFlow = room.syncUpdateFlow.collectAsState()
// Since there is no way to obtain the new avatar uri after uploading a new avatar,
@ -92,6 +99,13 @@ class RoomDetailsEditPresenter @Inject constructor(
onResult = { uri -> if (uri != null) roomAvatarUri = uri }
)
LaunchedEffect(cameraPermissionState.permissionGranted) {
if (cameraPermissionState.permissionGranted && pendingPermissionRequest) {
pendingPermissionRequest = false
cameraPhotoPicker.launch()
}
}
val avatarActions by remember(roomAvatarUri) {
derivedStateOf {
listOfNotNull(
@ -110,7 +124,12 @@ class RoomDetailsEditPresenter @Inject constructor(
is RoomDetailsEditEvents.HandleAvatarAction -> {
when (event.action) {
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
AvatarAction.TakePhoto -> cameraPhotoPicker.launch()
AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) {
cameraPhotoPicker.launch()
} else {
pendingPermissionRequest = true
cameraPermissionState.eventSink(PermissionsEvents.RequestPermissions)
}
AvatarAction.Remove -> roomAvatarUri = null
}
}
@ -132,6 +151,7 @@ class RoomDetailsEditPresenter @Inject constructor(
avatarActions = avatarActions,
saveButtonEnabled = saveButtonEnabled,
saveAction = saveAction.value,
cameraPermissionState = cameraPermissionState,
eventSink = ::handleEvents,
)
}

View file

@ -17,8 +17,9 @@
package io.element.android.features.roomdetails.impl.edit
import android.net.Uri
import io.element.android.libraries.matrix.ui.media.AvatarAction
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.matrix.ui.media.AvatarAction
import io.element.android.libraries.permissions.api.PermissionsState
import kotlinx.collections.immutable.ImmutableList
data class RoomDetailsEditState(
@ -32,5 +33,6 @@ data class RoomDetailsEditState(
val avatarActions: ImmutableList<AvatarAction>,
val saveButtonEnabled: Boolean,
val saveAction: Async<Unit>,
val cameraPermissionState: PermissionsState,
val eventSink: (RoomDetailsEditEvents) -> Unit
)

View file

@ -19,6 +19,7 @@ package io.element.android.features.roomdetails.impl.edit
import android.net.Uri
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.permissions.api.aPermissionsState
import kotlinx.collections.immutable.persistentListOf
open class RoomDetailsEditStateProvider : PreviewParameterProvider<RoomDetailsEditState> {
@ -45,5 +46,6 @@ fun aRoomDetailsEditState() = RoomDetailsEditState(
avatarActions = persistentListOf(),
saveButtonEnabled = true,
saveAction = Async.Uninitialized,
cameraPermissionState = aPermissionsState(showDialog = false),
eventSink = {}
)

View file

@ -62,6 +62,7 @@ import io.element.android.libraries.designsystem.theme.components.TextButton
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
import io.element.android.libraries.matrix.ui.components.EditableAvatarView
import io.element.android.libraries.permissions.api.PermissionsView
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.coroutines.launch
@ -193,6 +194,10 @@ fun RoomDetailsEditView(
else -> Unit
}
PermissionsView(
state = state.cameraPermissionState,
)
}
@Composable