diff --git a/data/resources/src/commonMain/composeResources/values/strings.xml b/data/resources/src/commonMain/composeResources/values/strings.xml
index ccf7ab6..42c5548 100644
--- a/data/resources/src/commonMain/composeResources/values/strings.xml
+++ b/data/resources/src/commonMain/composeResources/values/strings.xml
@@ -17,6 +17,7 @@
Traduction (FR)
Afficher la traduction française
Taille du texte
+ %1$d %
Réduire la taille du texte
Augmenter la taille du texte
Marques de prononciation
diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/preferences/ui/SubtitlePreferencesBottomSheet.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/preferences/ui/SubtitlePreferencesBottomSheet.kt
index 0a3ff36..2994c74 100644
--- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/preferences/ui/SubtitlePreferencesBottomSheet.kt
+++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/preferences/ui/SubtitlePreferencesBottomSheet.kt
@@ -20,6 +20,14 @@ import androidx.compose.material3.rememberBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.CustomAccessibilityAction
+import androidx.compose.ui.semantics.ProgressBarRangeInfo
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.customActions
+import androidx.compose.ui.semantics.progressBarRangeInfo
+import androidx.compose.ui.semantics.setProgress
+import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.preferences.model.SubtitlePreferences
@@ -30,6 +38,7 @@ import bzh.ajaury.chombev.resources.generated.resources.subtitle_preferences_tit
import bzh.ajaury.chombev.resources.generated.resources.subtitle_text_size_decrease
import bzh.ajaury.chombev.resources.generated.resources.subtitle_text_size_increase
import bzh.ajaury.chombev.resources.generated.resources.subtitle_text_size_label
+import bzh.ajaury.chombev.resources.generated.resources.subtitle_text_size_value
import bzh.ajaury.chombev.resources.generated.resources.subtitle_transcription_description
import bzh.ajaury.chombev.resources.generated.resources.subtitle_transcription_label
import bzh.ajaury.chombev.resources.generated.resources.subtitle_translation_description
@@ -120,10 +129,50 @@ private fun SubtitleTextSizeControl(
onDecrease: () -> Unit = {},
onIncrease: () -> Unit = {},
) {
+ val label = stringResource(Res.string.subtitle_text_size_label)
+ val value = stringResource(Res.string.subtitle_text_size_value, (textScale * 100).roundToInt())
+ val decreaseLabel = stringResource(Res.string.subtitle_text_size_decrease)
+ val increaseLabel = stringResource(Res.string.subtitle_text_size_increase)
+ // The steps are uneven (0.1 then 0.2 apart), so screen readers adjust a step index instead.
+ val steps = SubtitlePreferences.TEXT_SCALE_STEPS
+ val stepIndex = steps.indexOfFirst { it >= textScale - 0.001f }.coerceAtLeast(0)
+
Row(
modifier = Modifier
.fillMaxWidth()
- .padding(vertical = 8.dp),
+ .padding(vertical = 8.dp)
+ // A single adjustable element for screen readers, like a slider: swiping up or down
+ // changes the size and announces the new value. The buttons only serve touch use.
+ .clearAndSetSemantics {
+ contentDescription = label
+ stateDescription = value
+ progressBarRangeInfo = ProgressBarRangeInfo(
+ current = stepIndex.toFloat(),
+ range = 0f..steps.lastIndex.toFloat(),
+ steps = steps.size - 2,
+ )
+ setProgress { target ->
+ val targetIndex = target.roundToInt()
+ when {
+ targetIndex > stepIndex -> onIncrease()
+ targetIndex < stepIndex -> onDecrease()
+ else -> return@setProgress false
+ }
+ true
+ }
+ // Same adjustments from the screen reader's actions menu, for users unaware of the
+ // adjust gesture.
+ customActions = listOf(
+ CustomAccessibilityAction(label = increaseLabel) {
+ onIncrease()
+ true
+ },
+ CustomAccessibilityAction(label = decreaseLabel) {
+ onDecrease()
+ true
+ },
+ )
+ },
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {