diff --git a/feature/media-send/src/main/java/org/signal/mediasend/MediaSendScreen.kt b/feature/media-send/src/main/java/org/signal/mediasend/MediaSendScreen.kt index 911a87213f..985b2e17cf 100644 --- a/feature/media-send/src/main/java/org/signal/mediasend/MediaSendScreen.kt +++ b/feature/media-send/src/main/java/org/signal/mediasend/MediaSendScreen.kt @@ -10,12 +10,14 @@ import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigationevent.NavigationEventDispatcherOwner import androidx.navigationevent.compose.LocalNavigationEventDispatcherOwner import org.signal.core.ui.compose.Dialogs +import org.signal.core.ui.compose.LocalDisplayNameProvider import org.signal.core.ui.compose.theme.SignalTheme import org.signal.mediasend.edit.MediaEditScreenDialogs @@ -71,6 +73,17 @@ fun MediaSendScreen( ) } + viewModel.addToGroupStoryDialog.Content { recipientId, onDismissRequest, onConfirm, _, onDeny -> + val groupName: String by LocalDisplayNameProvider.current(recipientId.id) + + MediaEditScreenDialogs.AddToGroupStoryConfirmationDialog( + groupName = groupName, + onAddToStory = onConfirm, + onDeny = onDeny, + onDismissRequest = onDismissRequest + ) + } + viewModel.writeStoragePermission.Content() MediaSendNavDisplay( diff --git a/feature/media-send/src/main/java/org/signal/mediasend/MediaSendViewModel.kt b/feature/media-send/src/main/java/org/signal/mediasend/MediaSendViewModel.kt index 80d0fca18e..815c9a9319 100644 --- a/feature/media-send/src/main/java/org/signal/mediasend/MediaSendViewModel.kt +++ b/feature/media-send/src/main/java/org/signal/mediasend/MediaSendViewModel.kt @@ -124,6 +124,7 @@ class MediaSendViewModel( internal val usernameScannedDialog = DialogController() internal val linkedDeviceScannedDialog = DialogController() internal val saveToStorageDialog = DialogController() + internal val addToGroupStoryDialog = DialogController() internal val writeStoragePermission = PermissionController( permission = Manifest.permission.WRITE_EXTERNAL_STORAGE, @@ -1108,11 +1109,26 @@ class MediaSendViewModel( //region Send /** - * Leaves the editor, either on to destination selection or straight into the send. + * Advances out of the editor: either on to contact selection, or into the send itself. + * + * The add-to-group-story flow has no review step of its own, so the send is gated behind a confirmation naming the + * group. Denying it leaves the editor exactly as it was — nothing is marked as sending until the user confirms. */ private fun onNextClick() { - if (state.value.isContactSelectionRequired) { + val snapshot = state.value + + if (snapshot.isContactSelectionRequired) { backStack.goToSend() + return + } + + val recipientId = snapshot.recipientId + if (snapshot.isAddToGroupStoryFlow && recipientId != null) { + viewModelScope.launch { + if (addToGroupStoryDialog.show(recipientId) == DialogResult.POSITIVE) { + performSend() + } + } } else { performSend() } diff --git a/feature/media-send/src/main/java/org/signal/mediasend/edit/MediaEditScreenDialogs.kt b/feature/media-send/src/main/java/org/signal/mediasend/edit/MediaEditScreenDialogs.kt index e74432e203..e8ce926c93 100644 --- a/feature/media-send/src/main/java/org/signal/mediasend/edit/MediaEditScreenDialogs.kt +++ b/feature/media-send/src/main/java/org/signal/mediasend/edit/MediaEditScreenDialogs.kt @@ -46,6 +46,27 @@ object MediaEditScreenDialogs { ) } + /** + * Last chance to back out before the media is posted to [groupName]'s story. + */ + @Composable + fun AddToGroupStoryConfirmationDialog( + groupName: String, + onAddToStory: () -> Unit, + onDeny: () -> Unit, + onDismissRequest: () -> Unit + ) { + Dialogs.SimpleAlertDialog( + title = "", + body = stringResource(R.string.MediaSendDialogs__add_to_the_group_story, groupName), + confirm = stringResource(R.string.MediaSendDialogs__add_to_story), + onConfirm = onAddToStory, + dismiss = stringResource(android.R.string.cancel), + onDeny = onDeny, + onDismissRequest = onDismissRequest + ) + } + @Composable fun SaveToStorageConfirmationDialog( onSave: (doNotShowAgain: Boolean) -> Unit, @@ -113,6 +134,19 @@ private fun DiscardEditsConfirmationDialogPreview() { } } +@Preview +@Composable +private fun AddToGroupStoryConfirmationDialogPreview() { + Previews.Preview { + MediaEditScreenDialogs.AddToGroupStoryConfirmationDialog( + groupName = "Signal Android", + onAddToStory = {}, + onDeny = {}, + onDismissRequest = {} + ) + } +} + @Preview @Composable private fun SaveToStorageConfirmationDialogPreview() { diff --git a/feature/media-send/src/main/res/values/strings.xml b/feature/media-send/src/main/res/values/strings.xml index 22d91e11a3..982ba9b317 100644 --- a/feature/media-send/src/main/res/values/strings.xml +++ b/feature/media-send/src/main/res/values/strings.xml @@ -16,6 +16,10 @@ Don\'t show again Saving attachment to storage… + + Add to the group story \"%1$s\" + + Add to story Add a message