diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt index c8324ec677..b554ef98f4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/AttachmentsBottomSheet.kt @@ -83,7 +83,7 @@ internal fun AttachmentsBottomSheet( onDismissRequest = { isVisible = false } ) { AttachmentSourcePickerMenu( - eventSink = state.eventSink, + state = state, onSendLocationClicked = onSendLocationClicked, ) } @@ -93,7 +93,7 @@ internal fun AttachmentsBottomSheet( @OptIn(ExperimentalMaterialApi::class) @Composable internal fun AttachmentSourcePickerMenu( - eventSink: (MessageComposerEvents) -> Unit, + state: MessageComposerState, onSendLocationClicked: () -> Unit, modifier: Modifier = Modifier, ) { @@ -102,33 +102,35 @@ internal fun AttachmentSourcePickerMenu( // .navigationBarsPadding() - FIXME after https://issuetracker.google.com/issues/275849044 ) { ListItem( - modifier = Modifier.clickable { eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) }, + modifier = Modifier.clickable { state.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) }, icon = { Icon(Icons.Default.Collections, null) }, text = { Text(stringResource(R.string.screen_room_attachment_source_gallery)) }, ) ListItem( - modifier = Modifier.clickable { eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) }, + modifier = Modifier.clickable { state.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) }, icon = { Icon(Icons.Default.AttachFile, null) }, text = { Text(stringResource(R.string.screen_room_attachment_source_files)) }, ) ListItem( - modifier = Modifier.clickable { eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) }, + modifier = Modifier.clickable { state.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) }, icon = { Icon(Icons.Default.PhotoCamera, null) }, text = { Text(stringResource(R.string.screen_room_attachment_source_camera_photo)) }, ) ListItem( - modifier = Modifier.clickable { eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera) }, + modifier = Modifier.clickable { state.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera) }, icon = { Icon(Icons.Default.Videocam, null) }, text = { Text(stringResource(R.string.screen_room_attachment_source_camera_video)) }, ) - ListItem( - modifier = Modifier.clickable { - eventSink(MessageComposerEvents.PickAttachmentSource.Location) - onSendLocationClicked() - }, - icon = { Icon(Icons.Default.LocationOn, null) }, - text = { Text(stringResource(R.string.screen_room_attachment_source_location)) }, - ) + if (state.canShareLocation) { + ListItem( + modifier = Modifier.clickable { + state.eventSink(MessageComposerEvents.PickAttachmentSource.Location) + onSendLocationClicked() + }, + icon = { Icon(Icons.Default.LocationOn, null) }, + text = { Text(stringResource(R.string.screen_room_attachment_source_location)) }, + ) + } } } @@ -136,7 +138,9 @@ internal fun AttachmentSourcePickerMenu( @Composable internal fun AttachmentSourcePickerMenuPreview() = ElementPreview { AttachmentSourcePickerMenu( - eventSink = {}, + state = aMessageComposerState( + canShareLocation = true, + ), onSendLocationClicked = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 020236e890..ec16d3342d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -74,6 +74,11 @@ class MessageComposerPresenter @Inject constructor( mutableStateOf(AttachmentsState.None) } + val canShareLocation = remember { mutableStateOf(false) } + LaunchedEffect(Unit) { + canShareLocation.value = featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing) + } + val galleryMediaPicker = mediaPickerProvider.registerGalleryPicker { uri, mimeType -> handlePickedMedia(attachmentsState, uri, mimeType) } @@ -140,23 +145,23 @@ class MessageComposerPresenter @Inject constructor( ) ) } - MessageComposerEvents.AddAttachment -> localCoroutineScope.launchIfMediaPickerEnabled { + MessageComposerEvents.AddAttachment -> localCoroutineScope.launch { showAttachmentSourcePicker = true } MessageComposerEvents.DismissAttachmentMenu -> showAttachmentSourcePicker = false - MessageComposerEvents.PickAttachmentSource.FromGallery -> localCoroutineScope.launchIfMediaPickerEnabled { + MessageComposerEvents.PickAttachmentSource.FromGallery -> localCoroutineScope.launch { showAttachmentSourcePicker = false galleryMediaPicker.launch() } - MessageComposerEvents.PickAttachmentSource.FromFiles -> localCoroutineScope.launchIfMediaPickerEnabled { + MessageComposerEvents.PickAttachmentSource.FromFiles -> localCoroutineScope.launch { showAttachmentSourcePicker = false filesPicker.launch() } - MessageComposerEvents.PickAttachmentSource.PhotoFromCamera -> localCoroutineScope.launchIfMediaPickerEnabled { + MessageComposerEvents.PickAttachmentSource.PhotoFromCamera -> localCoroutineScope.launch { showAttachmentSourcePicker = false cameraPhotoPicker.launch() } - MessageComposerEvents.PickAttachmentSource.VideoFromCamera -> localCoroutineScope.launchIfMediaPickerEnabled { + MessageComposerEvents.PickAttachmentSource.VideoFromCamera -> localCoroutineScope.launch { showAttachmentSourcePicker = false cameraVideoPicker.launch() } @@ -173,17 +178,12 @@ class MessageComposerPresenter @Inject constructor( hasFocus = hasFocus.value, mode = messageComposerContext.composerMode, showAttachmentSourcePicker = showAttachmentSourcePicker, + canShareLocation = canShareLocation.value, attachmentsState = attachmentsState.value, eventSink = ::handleEvents ) } - private fun CoroutineScope.launchIfMediaPickerEnabled(action: suspend () -> Unit) = launch { - if (featureFlagService.isFeatureEnabled(FeatureFlags.ShowMediaUploadingFlow)) { - action() - } - } - private fun CoroutineScope.sendMessage( text: String, updateComposerMode: (newComposerMode: MessageComposerMode) -> Unit, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt index 28ec14ffeb..32faaf9d81 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt @@ -28,6 +28,7 @@ data class MessageComposerState( val hasFocus: Boolean, val mode: MessageComposerMode, val showAttachmentSourcePicker: Boolean, + val canShareLocation: Boolean, val attachmentsState: AttachmentsState, val eventSink: (MessageComposerEvents) -> Unit ) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt index 1934154824..a1fbb7ffa0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt @@ -26,12 +26,21 @@ open class MessageComposerStateProvider : PreviewParameterProvider false - FeatureFlags.ShowStartChatFlow -> false - FeatureFlags.ShowMediaUploadingFlow -> false + FeatureFlags.LocationSharing -> true } } else { false diff --git a/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt b/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt index 5f7f01423a..ea9b03acdf 100644 --- a/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt +++ b/libraries/featureflag/impl/src/test/kotlin/io/element/android/libraries/featureflag/impl/DefaultFeatureFlagServiceTest.kt @@ -26,14 +26,14 @@ class DefaultFeatureFlagServiceTest { @Test fun `given service without provider when feature is checked then it returns the default value`() = runTest { val featureFlagService = DefaultFeatureFlagService(emptySet()) - val isFeatureEnabled = featureFlagService.isFeatureEnabled(FeatureFlags.ShowStartChatFlow) - assertThat(isFeatureEnabled).isEqualTo(FeatureFlags.ShowStartChatFlow.defaultValue) + val isFeatureEnabled = featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing) + assertThat(isFeatureEnabled).isEqualTo(FeatureFlags.LocationSharing.defaultValue) } @Test fun `given service without provider when set enabled feature is called then it returns false`() = runTest { val featureFlagService = DefaultFeatureFlagService(emptySet()) - val result = featureFlagService.setFeatureEnabled(FeatureFlags.ShowStartChatFlow, true) + val result = featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true) assertThat(result).isEqualTo(false) } @@ -41,7 +41,7 @@ class DefaultFeatureFlagServiceTest { fun `given service with a runtime provider when set enabled feature is called then it returns true`() = runTest { val featureFlagProvider = FakeRuntimeFeatureFlagProvider(0) val featureFlagService = DefaultFeatureFlagService(setOf(featureFlagProvider)) - val result = featureFlagService.setFeatureEnabled(FeatureFlags.ShowStartChatFlow, true) + val result = featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true) assertThat(result).isEqualTo(true) } @@ -49,10 +49,10 @@ class DefaultFeatureFlagServiceTest { fun `given service with a runtime provider and feature enabled when feature is checked then it returns the correct value`() = runTest { val featureFlagProvider = FakeRuntimeFeatureFlagProvider(0) val featureFlagService = DefaultFeatureFlagService(setOf(featureFlagProvider)) - featureFlagService.setFeatureEnabled(FeatureFlags.ShowStartChatFlow, true) - assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.ShowStartChatFlow)).isEqualTo(true) - featureFlagService.setFeatureEnabled(FeatureFlags.ShowStartChatFlow, false) - assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.ShowStartChatFlow)).isEqualTo(false) + featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true) + assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing)).isEqualTo(true) + featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, false) + assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing)).isEqualTo(false) } @Test @@ -60,8 +60,8 @@ class DefaultFeatureFlagServiceTest { val lowPriorityfeatureFlagProvider = FakeRuntimeFeatureFlagProvider(LOW_PRIORITY) val highPriorityfeatureFlagProvider = FakeRuntimeFeatureFlagProvider(HIGH_PRIORITY) val featureFlagService = DefaultFeatureFlagService(setOf(lowPriorityfeatureFlagProvider, highPriorityfeatureFlagProvider)) - lowPriorityfeatureFlagProvider.setFeatureEnabled(FeatureFlags.ShowStartChatFlow, false) - highPriorityfeatureFlagProvider.setFeatureEnabled(FeatureFlags.ShowStartChatFlow, true) - assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.ShowStartChatFlow)).isEqualTo(true) + lowPriorityfeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, false) + highPriorityfeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, true) + assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing)).isEqualTo(true) } }