From 74f7bbb6d5bdab34e4be91d7897d4a59b989fa0b Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:17:16 +1100 Subject: [PATCH] Added bottom options dialog --- .../ui/components/BottomOptionsDialog.kt | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/components/BottomOptionsDialog.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/BottomOptionsDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/BottomOptionsDialog.kt new file mode 100644 index 0000000000..b02ad013b1 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/BottomOptionsDialog.kt @@ -0,0 +1,120 @@ +package org.thoughtcrime.securesms.ui.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment.Companion.CenterVertically +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import org.thoughtcrime.securesms.ui.theme.LocalColors +import org.thoughtcrime.securesms.ui.theme.LocalDimensions +import org.thoughtcrime.securesms.ui.theme.LocalType + +/** + * A bottom sheet dialog that displays a list of options. + * + * @param options The list of options to display. + * @param onDismissRequest Callback to be invoked when the dialog is to be dismissed. + * @param onOptionClick Callback to be invoked when an option is clicked. + * @param optionTitle A function that returns the title of an option. + * @param optionIconRes A function that returns the icon resource of an option. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun BottomOptionsDialog( + options: Collection, + onDismissRequest: () -> Unit, + onOptionClick: (T) -> Unit, + optionTitle: (T) -> String, + optionIconRes: (T) -> Int, +) { + val sheetState = rememberModalBottomSheetState() + + ModalBottomSheet( + onDismissRequest = onDismissRequest, + sheetState = sheetState, + shape = RoundedCornerShape( + topStart = LocalDimensions.current.xsSpacing, + topEnd = LocalDimensions.current.xsSpacing + ), + dragHandle = {}, + containerColor = LocalColors.current.backgroundSecondary, + ) { + for (option in options) { + MemberModalBottomSheetOptionItem( + text = optionTitle(option), + leadingIcon = optionIconRes(option), + onClick = { + onOptionClick(option) + onDismissRequest() + } + ) + } + } +} + +@Composable +private fun MemberModalBottomSheetOptionItem( + leadingIcon: Int, + text: String, + onClick: () -> Unit +) { + Row( + modifier = Modifier + .clickable(onClick = onClick) + .padding(LocalDimensions.current.smallSpacing) + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.spacing), + verticalAlignment = CenterVertically, + ) { + Icon( + painterResource(leadingIcon), + modifier = Modifier.size(24.dp), + contentDescription = null) + Text( + modifier = Modifier.weight(1f), + style = LocalType.current.large, + text = text, + textAlign = TextAlign.Start, + color = LocalColors.current.text, + ) + } +} + + +data class BottomOptionsDialogItem( + val title: String, + val iconRes: Int, + val onClick: () -> Unit, +) + +/** + * A convenience function to display a [BottomOptionsDialog] with a collection of [BottomOptionsDialogItem]. + */ +@Composable +fun BottomOptionsDialog( + items: Collection, + onDismissRequest: () -> Unit +) { + BottomOptionsDialog( + options = items, + onDismissRequest = onDismissRequest, + onOptionClick = { it.onClick() }, + optionTitle = { it.title }, + optionIconRes = { it.iconRes } + ) +} \ No newline at end of file