Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 5ece438b authored by Ricki Hirner's avatar Ricki Hirner Committed by GitHub
Browse files

Open-source intro page: don't select a "dont show for... months" option by default (#1287)

Refactor RadioButtons component to support initial selection and update parameter names for clarity
parent acd4e41f
Loading
Loading
Loading
Loading
+30 −12
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
@@ -26,25 +28,26 @@ import at.bitfire.davdroid.ui.AppTheme

@Composable
fun RadioButtons(
    radioOptions: List<String> = listOf<String>(),
    onOptionSelected: (String) -> Unit = {},
    textPaddingPerOption: PaddingValues = PaddingValues(10.dp),
    options: List<String> = listOf<String>(),
    initiallySelectedIdx: Int? = null,
    onOptionSelected: (Int) -> Unit = { _ -> },
    optionTextPadding: PaddingValues = PaddingValues(10.dp),
    modifier: Modifier = Modifier
) {
    val (selectedOption, setSelectedOption) = remember { mutableStateOf(radioOptions[0]) }
    var selectedIdx by remember { mutableStateOf(initiallySelectedIdx) }
    Column(
        // Modifier.selectableGroup() is essential to ensure correct accessibility behavior
        modifier = modifier.selectableGroup()
    ) {
        radioOptions.forEach { text ->
        options.forEachIndexed { idx, text ->
            Row(
                Modifier
                    .fillMaxWidth()
                    .selectable(
                        selected = (text == selectedOption),
                        selected = (selectedIdx == idx),
                        onClick = {
                            setSelectedOption(text)
                            onOptionSelected(text)
                            selectedIdx = idx
                            onOptionSelected(idx)
                        },
                        role = Role.Companion.RadioButton
                    )
@@ -52,13 +55,13 @@ fun RadioButtons(
                verticalAlignment = Alignment.CenterVertically
            ) {
                RadioButton(
                    selected = (text == selectedOption),
                    selected = (idx == selectedIdx),
                    onClick = null, // null recommended for accessibility with screen readers
                )
                Text(
                    text = text,
                    style = MaterialTheme.typography.bodyLarge,
                    modifier = Modifier.padding(textPaddingPerOption)
                    modifier = Modifier.padding(optionTextPadding)
                )
            }
        }
@@ -67,13 +70,28 @@ fun RadioButtons(

@Preview
@Composable
private fun RadioButtonsPreview() {
private fun RadioButtons_Preview_NoInitialSelection() {
    AppTheme {
        RadioButtons(
            radioOptions = listOf(
            options = listOf(
                "Option 1",
                "Option 2 is the longest of all the options, so we can see whether line breaks are not a problem.",
                "Option 3")
        )
    }
}

@Preview
@Composable
private fun RadioButtons_Preview_InitialSelection() {
    AppTheme {
        RadioButtons(
            options = listOf(
                "Option 1",
                "Option 2",
                "Option 3"
            ),
            initiallySelectedIdx = 1
        )
    }
}
 No newline at end of file
+17 −21
Original line number Diff line number Diff line
@@ -53,8 +53,8 @@ class OpenSourcePage @Inject constructor(
    @Composable
    private fun Page(model: Model = viewModel()) {
        OpenSourcePage(
            donationPopupIntervalOptions = model.donationPopupIntervalOptions,
            onChangeDontShowFor = model::setDontShowFor
            dontShowForMonthsOptions = model.donationPopupIntervalOptions,
            onDontShowForMonths = model::setDontShowForMonths
        )
    }

@@ -75,12 +75,13 @@ class OpenSourcePage @Inject constructor(

        /**
         * Set the next time the donation popup should be shown.
         * @param dontShowFor Number of months (30 days) to hide the donation popup for.
         *
         * @param months Number of months (30 days) to hide the donation popup for.
         */
        fun setDontShowFor(dontShowFor: Int) {
            logger.info("Setting next donation popup to $dontShowFor months")
            val month = 30*86400000L            // 30 days (~ 1 month)
            val nextReminder = month * dontShowFor + System.currentTimeMillis()
        fun setDontShowForMonths(months: Int) {
            logger.info("Setting next donation popup to $months months")
            val oneMonth = 30*86400000L            // 30 days (~ 1 month)
            val nextReminder = oneMonth * months + System.currentTimeMillis()
            settings.putLong(SETTING_NEXT_DONATION_POPUP, nextReminder)
        }

@@ -90,8 +91,8 @@ class OpenSourcePage @Inject constructor(

@Composable
fun OpenSourcePage(
    donationPopupIntervalOptions: List<Int>,
    onChangeDontShowFor: (Int) -> Unit = {}
    dontShowForMonthsOptions: List<Int>,
    onDontShowForMonths: (Int) -> Unit = {}
) {
    val uriHandler = LocalUriHandler.current

@@ -132,18 +133,13 @@ fun OpenSourcePage(
                text = stringResource(R.string.intro_open_source_dont_show),
                style = MaterialTheme.typography.bodyLarge
            )
            val radioOptions = donationPopupIntervalOptions.associate { numberOfMonths ->
                pluralStringResource(
                    R.plurals.intro_open_source_dont_show_months,
                    numberOfMonths,
                    numberOfMonths
                ) to numberOfMonths
            }
            RadioButtons(
                radioOptions = radioOptions.keys.toList(),
                onOptionSelected = { option ->
                    val months = radioOptions[option] ?: radioOptions.values.first()
                    onChangeDontShowFor(months)
                options = dontShowForMonthsOptions.map { months ->
                    pluralStringResource(R.plurals.intro_open_source_dont_show_months, months, months)
                },
                onOptionSelected = { idx ->
                    val months = dontShowForMonthsOptions[idx]
                    onDontShowForMonths(months)
                },
                modifier = Modifier.padding(bottom = 12.dp)
            )
@@ -157,7 +153,7 @@ fun OpenSourcePage(
fun OpenSourcePagePreview() {
    AppTheme {
        OpenSourcePage(
            donationPopupIntervalOptions = listOf(1, 3, 9)
            dontShowForMonthsOptions = listOf(1, 3, 9)
        )
    }
}
 No newline at end of file