|
@@ -122,7 +122,16 @@ import androidx.compose.ui.platform.LocalDensity
|
|
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
|
|
import androidx.compose.ui.platform.LocalWindowInfo
|
|
import androidx.compose.ui.platform.LocalWindowInfo
|
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.res.stringResource
|
|
|
|
|
+import androidx.compose.ui.semantics.ProgressBarRangeInfo
|
|
|
import androidx.compose.ui.semantics.Role
|
|
import androidx.compose.ui.semantics.Role
|
|
|
|
|
+import androidx.compose.ui.semantics.clearAndSetSemantics
|
|
|
|
|
+import androidx.compose.ui.semantics.contentDescription
|
|
|
|
|
+import androidx.compose.ui.semantics.disabled
|
|
|
|
|
+import androidx.compose.ui.semantics.progressBarRangeInfo
|
|
|
|
|
+import androidx.compose.ui.semantics.role
|
|
|
|
|
+import androidx.compose.ui.semantics.semantics
|
|
|
|
|
+import androidx.compose.ui.semantics.setProgress
|
|
|
|
|
+import androidx.compose.ui.semantics.stateDescription
|
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
|
import androidx.compose.ui.unit.Dp
|
|
import androidx.compose.ui.unit.Dp
|
|
|
import androidx.compose.ui.unit.IntOffset
|
|
import androidx.compose.ui.unit.IntOffset
|
|
@@ -799,7 +808,8 @@ private fun ReadBookMenuRoutePage(
|
|
|
) {
|
|
) {
|
|
|
SmallTonalButton(
|
|
SmallTonalButton(
|
|
|
onClick = onBack,
|
|
onClick = onBack,
|
|
|
- icon = Icons.AutoMirrored.Filled.ArrowBack
|
|
|
|
|
|
|
+ icon = Icons.AutoMirrored.Filled.ArrowBack,
|
|
|
|
|
+ contentDescription = stringResource(R.string.back),
|
|
|
)
|
|
)
|
|
|
Text(
|
|
Text(
|
|
|
text = title,
|
|
text = title,
|
|
@@ -934,7 +944,7 @@ private fun MenuTitleBar(
|
|
|
MenuTitleGlassButton(
|
|
MenuTitleGlassButton(
|
|
|
onClick = { onIntent(ReadBookIntent.CloseReadBook()) },
|
|
onClick = { onIntent(ReadBookIntent.CloseReadBook()) },
|
|
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
|
|
- contentDescription = "Back",
|
|
|
|
|
|
|
+ contentDescription = stringResource(R.string.back),
|
|
|
state = state,
|
|
state = state,
|
|
|
colors = colors,
|
|
colors = colors,
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
@@ -1022,6 +1032,7 @@ private fun MenuTitleBar(
|
|
|
MenuTitleGlassButton(
|
|
MenuTitleGlassButton(
|
|
|
onClick = { expanded = true },
|
|
onClick = { expanded = true },
|
|
|
icon = Icons.Default.MoreVert,
|
|
icon = Icons.Default.MoreVert,
|
|
|
|
|
+ contentDescription = stringResource(R.string.more_actions),
|
|
|
state = state,
|
|
state = state,
|
|
|
colors = colors,
|
|
colors = colors,
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
@@ -1198,10 +1209,11 @@ private fun ReadMenuGlassIconButton(
|
|
|
modifier = modifier,
|
|
modifier = modifier,
|
|
|
onLongClick = onLongClick,
|
|
onLongClick = onLongClick,
|
|
|
selected = selected,
|
|
selected = selected,
|
|
|
|
|
+ contentDescription = contentDescription,
|
|
|
) { tint ->
|
|
) { tint ->
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = icon,
|
|
imageVector = icon,
|
|
|
- contentDescription = contentDescription,
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -1219,6 +1231,7 @@ private fun ReadMenuGlassButtonSurface(
|
|
|
modifier: Modifier = Modifier,
|
|
modifier: Modifier = Modifier,
|
|
|
onLongClick: (() -> Unit)? = null,
|
|
onLongClick: (() -> Unit)? = null,
|
|
|
selected: Boolean = false,
|
|
selected: Boolean = false,
|
|
|
|
|
+ contentDescription: String? = null,
|
|
|
content: @Composable (Color) -> Unit,
|
|
content: @Composable (Color) -> Unit,
|
|
|
) {
|
|
) {
|
|
|
val shape = CircleShape
|
|
val shape = CircleShape
|
|
@@ -1272,6 +1285,16 @@ private fun ReadMenuGlassButtonSurface(
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onLongClick = onLongClick,
|
|
onLongClick = onLongClick,
|
|
|
onClick = onClick,
|
|
onClick = onClick,
|
|
|
|
|
+ )
|
|
|
|
|
+ .then(
|
|
|
|
|
+ if (contentDescription != null) {
|
|
|
|
|
+ Modifier.semantics {
|
|
|
|
|
+ this.contentDescription = contentDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Modifier
|
|
|
|
|
+ }
|
|
|
),
|
|
),
|
|
|
) {
|
|
) {
|
|
|
content(tint)
|
|
content(tint)
|
|
@@ -1379,6 +1402,7 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
) {
|
|
) {
|
|
|
// SwapHoriz - change source
|
|
// SwapHoriz - change source
|
|
|
if (!state.isLocalBook) {
|
|
if (!state.isLocalBook) {
|
|
|
|
|
+ val changeSourceDescription = stringResource(R.string.change_origin)
|
|
|
Box(
|
|
Box(
|
|
|
contentAlignment = Alignment.Center,
|
|
contentAlignment = Alignment.Center,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -1389,11 +1413,15 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onClick = { onIntent(ReadBookIntent.MenuChangeSource) },
|
|
onClick = { onIntent(ReadBookIntent.MenuChangeSource) },
|
|
|
onLongClick = { sourceExpanded = true },
|
|
onLongClick = { sourceExpanded = true },
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = changeSourceDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = Icons.Default.SwapHoriz,
|
|
imageVector = Icons.Default.SwapHoriz,
|
|
|
- contentDescription = stringResource(R.string.change_origin),
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -1404,9 +1432,11 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
.width(1.dp)
|
|
.width(1.dp)
|
|
|
.height(20.dp)
|
|
.height(20.dp)
|
|
|
.background(tint.copy(alpha = 0.15f))
|
|
.background(tint.copy(alpha = 0.15f))
|
|
|
|
|
+ .clearAndSetSemantics { }
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Refresh
|
|
// Refresh
|
|
|
|
|
+ val refreshDescription = stringResource(R.string.menu_refresh_after)
|
|
|
Box(
|
|
Box(
|
|
|
contentAlignment = Alignment.Center,
|
|
contentAlignment = Alignment.Center,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -1417,11 +1447,15 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onClick = { onIntent(ReadBookIntent.MenuRefreshAfter) },
|
|
onClick = { onIntent(ReadBookIntent.MenuRefreshAfter) },
|
|
|
onLongClick = { refreshExpanded = true },
|
|
onLongClick = { refreshExpanded = true },
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = refreshDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = Icons.Default.Refresh,
|
|
imageVector = Icons.Default.Refresh,
|
|
|
- contentDescription = stringResource(R.string.menu_refresh_after),
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -1432,9 +1466,11 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
.width(1.dp)
|
|
.width(1.dp)
|
|
|
.height(20.dp)
|
|
.height(20.dp)
|
|
|
.background(tint.copy(alpha = 0.15f))
|
|
.background(tint.copy(alpha = 0.15f))
|
|
|
|
|
+ .clearAndSetSemantics { }
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Download
|
|
// Download
|
|
|
|
|
+ val downloadDescription = stringResource(R.string.offline_cache)
|
|
|
Box(
|
|
Box(
|
|
|
contentAlignment = Alignment.Center,
|
|
contentAlignment = Alignment.Center,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -1444,11 +1480,15 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onClick = { onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.Download)) },
|
|
onClick = { onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.Download)) },
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = downloadDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = Icons.Default.CloudDownload,
|
|
imageVector = Icons.Default.CloudDownload,
|
|
|
- contentDescription = stringResource(R.string.offline_cache),
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -1459,10 +1499,12 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
.width(1.dp)
|
|
.width(1.dp)
|
|
|
.height(20.dp)
|
|
.height(20.dp)
|
|
|
.background(tint.copy(alpha = 0.15f))
|
|
.background(tint.copy(alpha = 0.15f))
|
|
|
|
|
+ .clearAndSetSemantics { }
|
|
|
)
|
|
)
|
|
|
} else {
|
|
} else {
|
|
|
// TXT directory rule
|
|
// TXT directory rule
|
|
|
if (state.isLocalTxt) {
|
|
if (state.isLocalTxt) {
|
|
|
|
|
+ val tocRuleDescription = stringResource(R.string.txt_toc_rule)
|
|
|
Box(
|
|
Box(
|
|
|
contentAlignment = Alignment.Center,
|
|
contentAlignment = Alignment.Center,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -1472,11 +1514,15 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onClick = { onIntent(ReadBookIntent.MenuTocRegex) },
|
|
onClick = { onIntent(ReadBookIntent.MenuTocRegex) },
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = tocRuleDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = Icons.Default.Toc,
|
|
imageVector = Icons.Default.Toc,
|
|
|
- contentDescription = stringResource(R.string.txt_toc_rule),
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -1487,10 +1533,12 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
.width(1.dp)
|
|
.width(1.dp)
|
|
|
.height(20.dp)
|
|
.height(20.dp)
|
|
|
.background(tint.copy(alpha = 0.15f))
|
|
.background(tint.copy(alpha = 0.15f))
|
|
|
|
|
+ .clearAndSetSemantics { }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Text encoding
|
|
// Text encoding
|
|
|
|
|
+ val charsetDescription = stringResource(R.string.set_charset)
|
|
|
Box(
|
|
Box(
|
|
|
contentAlignment = Alignment.Center,
|
|
contentAlignment = Alignment.Center,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -1500,11 +1548,15 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onClick = { onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.Charset)) },
|
|
onClick = { onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.Charset)) },
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = charsetDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = Icons.Default.Translate,
|
|
imageVector = Icons.Default.Translate,
|
|
|
- contentDescription = stringResource(R.string.set_charset),
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -1515,10 +1567,12 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
.width(1.dp)
|
|
.width(1.dp)
|
|
|
.height(20.dp)
|
|
.height(20.dp)
|
|
|
.background(tint.copy(alpha = 0.15f))
|
|
.background(tint.copy(alpha = 0.15f))
|
|
|
|
|
+ .clearAndSetSemantics { }
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// MoreVert - overflow menu
|
|
// MoreVert - overflow menu
|
|
|
|
|
+ val moreActionsDescription = stringResource(R.string.more_actions)
|
|
|
Box(
|
|
Box(
|
|
|
contentAlignment = Alignment.Center,
|
|
contentAlignment = Alignment.Center,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
@@ -1528,7 +1582,11 @@ private fun MenuTitleBarMergedGlassButton(
|
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
interactionSource = remember { MutableInteractionSource() },
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onClick = { overflowExpanded = true },
|
|
onClick = { overflowExpanded = true },
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = moreActionsDescription
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = Icons.Default.MoreVert,
|
|
imageVector = Icons.Default.MoreVert,
|
|
@@ -1750,11 +1808,12 @@ private fun FloatingIconRow(
|
|
|
selected = iconDef.isActive,
|
|
selected = iconDef.isActive,
|
|
|
modifier = Modifier.padding(horizontal = 4.dp),
|
|
modifier = Modifier.padding(horizontal = 4.dp),
|
|
|
onLongClick = iconDef.onLongClick,
|
|
onLongClick = iconDef.onLongClick,
|
|
|
|
|
+ contentDescription = iconDef.label,
|
|
|
) {
|
|
) {
|
|
|
if (isCustom) {
|
|
if (isCustom) {
|
|
|
AsyncImage(
|
|
AsyncImage(
|
|
|
model = customPath,
|
|
model = customPath,
|
|
|
- contentDescription = iconDef.label,
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
contentScale = ContentScale.Crop,
|
|
contentScale = ContentScale.Crop,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
|
.size(36.dp)
|
|
.size(36.dp)
|
|
@@ -1763,7 +1822,7 @@ private fun FloatingIconRow(
|
|
|
} else {
|
|
} else {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = iconDef.icon,
|
|
imageVector = iconDef.icon,
|
|
|
- contentDescription = iconDef.label,
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
tint = if (iconDef.isActive) LegadoTheme.colorScheme.primary else colors.content,
|
|
tint = if (iconDef.isActive) LegadoTheme.colorScheme.primary else colors.content,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
)
|
|
)
|
|
@@ -2052,13 +2111,13 @@ private fun SearchBottomMenuContent(
|
|
|
SearchMenuActionButton(
|
|
SearchMenuActionButton(
|
|
|
modifier = Modifier.weight(1f),
|
|
modifier = Modifier.weight(1f),
|
|
|
icon = Icons.Default.Search,
|
|
icon = Icons.Default.Search,
|
|
|
- text = "搜索内容",
|
|
|
|
|
|
|
+ text = stringResource(R.string.search),
|
|
|
onClick = { onIntent(ReadBookIntent.OpenSearch(null)) },
|
|
onClick = { onIntent(ReadBookIntent.OpenSearch(null)) },
|
|
|
)
|
|
)
|
|
|
SearchMenuActionButton(
|
|
SearchMenuActionButton(
|
|
|
modifier = Modifier.weight(1f),
|
|
modifier = Modifier.weight(1f),
|
|
|
icon = Icons.Default.Menu,
|
|
icon = Icons.Default.Menu,
|
|
|
- text = "主菜单",
|
|
|
|
|
|
|
+ text = stringResource(R.string.main_menu),
|
|
|
onClick = {
|
|
onClick = {
|
|
|
onIntent(ReadBookIntent.HideSearchMenu)
|
|
onIntent(ReadBookIntent.HideSearchMenu)
|
|
|
onIntent(ReadBookIntent.ShowMenu)
|
|
onIntent(ReadBookIntent.ShowMenu)
|
|
@@ -2067,7 +2126,7 @@ private fun SearchBottomMenuContent(
|
|
|
SearchMenuActionButton(
|
|
SearchMenuActionButton(
|
|
|
modifier = Modifier.weight(0.55f),
|
|
modifier = Modifier.weight(0.55f),
|
|
|
icon = Icons.Default.Close,
|
|
icon = Icons.Default.Close,
|
|
|
- text = "退出",
|
|
|
|
|
|
|
+ text = stringResource(R.string.exit),
|
|
|
onClick = { onIntent(ReadBookIntent.ExitSearch) },
|
|
onClick = { onIntent(ReadBookIntent.ExitSearch) },
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
@@ -2149,6 +2208,17 @@ private fun MenuBottomBar(
|
|
|
0.dp
|
|
0.dp
|
|
|
}
|
|
}
|
|
|
val progressBarBehavior = ReadConfig.progressBarBehavior
|
|
val progressBarBehavior = ReadConfig.progressBarBehavior
|
|
|
|
|
+ val progressCurrent = sliderValue.roundToInt().coerceIn(0, seekMax) + 1
|
|
|
|
|
+ val progressTotal = seekMax + 1
|
|
|
|
|
+ val progressValueDescription = stringResource(
|
|
|
|
|
+ if (progressBarBehavior == "page") {
|
|
|
|
|
+ R.string.a11y_read_progress_page
|
|
|
|
|
+ } else {
|
|
|
|
|
+ R.string.a11y_read_progress_chapter
|
|
|
|
|
+ },
|
|
|
|
|
+ progressCurrent,
|
|
|
|
|
+ progressTotal,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
fun commitSliderValue(value: Float) {
|
|
fun commitSliderValue(value: Float) {
|
|
|
val target = value.roundToInt().coerceIn(0, seekMax)
|
|
val target = value.roundToInt().coerceIn(0, seekMax)
|
|
@@ -2230,6 +2300,7 @@ private fun MenuBottomBar(
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
|
menuConfig = state.menuConfig,
|
|
menuConfig = state.menuConfig,
|
|
|
glassEnabled = buttonGlassEnabled,
|
|
glassEnabled = buttonGlassEnabled,
|
|
|
|
|
+ contentDescription = stringResource(R.string.previous_chapter),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
ReadMenuSlider(
|
|
ReadMenuSlider(
|
|
@@ -2244,6 +2315,8 @@ private fun MenuBottomBar(
|
|
|
enabled = seekMax > 0,
|
|
enabled = seekMax > 0,
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
|
glassThumbEnabled = buttonGlassEnabled,
|
|
glassThumbEnabled = buttonGlassEnabled,
|
|
|
|
|
+ accessibilityLabel = stringResource(R.string.progress),
|
|
|
|
|
+ accessibilityValue = progressValueDescription,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
|
.weight(1f)
|
|
.weight(1f)
|
|
|
.padding(horizontal = 8.dp)
|
|
.padding(horizontal = 8.dp)
|
|
@@ -2256,6 +2329,7 @@ private fun MenuBottomBar(
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
|
menuConfig = state.menuConfig,
|
|
menuConfig = state.menuConfig,
|
|
|
glassEnabled = buttonGlassEnabled,
|
|
glassEnabled = buttonGlassEnabled,
|
|
|
|
|
+ contentDescription = stringResource(R.string.next_chapter),
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -2352,18 +2426,23 @@ private fun ReadMenuSlider(
|
|
|
onValueCommit: ((Float) -> Unit)? = null,
|
|
onValueCommit: ((Float) -> Unit)? = null,
|
|
|
backdrop: Backdrop?,
|
|
backdrop: Backdrop?,
|
|
|
glassThumbEnabled: Boolean,
|
|
glassThumbEnabled: Boolean,
|
|
|
|
|
+ accessibilityLabel: String? = null,
|
|
|
|
|
+ accessibilityValue: String? = null,
|
|
|
) {
|
|
) {
|
|
|
if (glassThumbEnabled && backdrop != null) {
|
|
if (glassThumbEnabled && backdrop != null) {
|
|
|
ReadMenuLiquidSlider(
|
|
ReadMenuLiquidSlider(
|
|
|
value = value,
|
|
value = value,
|
|
|
onValueChange = onValueChange,
|
|
onValueChange = onValueChange,
|
|
|
valueRange = valueRange,
|
|
valueRange = valueRange,
|
|
|
|
|
+ steps = steps,
|
|
|
visibilityThreshold = 0.001f,
|
|
visibilityThreshold = 0.001f,
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
|
modifier = modifier,
|
|
modifier = modifier,
|
|
|
enabled = enabled,
|
|
enabled = enabled,
|
|
|
onValueChangeFinished = onValueChangeFinished,
|
|
onValueChangeFinished = onValueChangeFinished,
|
|
|
onValueCommit = onValueCommit,
|
|
onValueCommit = onValueCommit,
|
|
|
|
|
+ accessibilityLabel = accessibilityLabel,
|
|
|
|
|
+ accessibilityValue = accessibilityValue,
|
|
|
)
|
|
)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -2378,6 +2457,8 @@ private fun ReadMenuSlider(
|
|
|
valueRange = valueRange,
|
|
valueRange = valueRange,
|
|
|
steps = steps,
|
|
steps = steps,
|
|
|
onValueChangeFinished = commitAction,
|
|
onValueChangeFinished = commitAction,
|
|
|
|
|
+ accessibilityLabel = accessibilityLabel,
|
|
|
|
|
+ accessibilityValue = accessibilityValue,
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2386,12 +2467,15 @@ private fun ReadMenuLiquidSlider(
|
|
|
value: Float,
|
|
value: Float,
|
|
|
onValueChange: (Float) -> Unit,
|
|
onValueChange: (Float) -> Unit,
|
|
|
valueRange: ClosedFloatingPointRange<Float>,
|
|
valueRange: ClosedFloatingPointRange<Float>,
|
|
|
|
|
+ steps: Int = 0,
|
|
|
visibilityThreshold: Float,
|
|
visibilityThreshold: Float,
|
|
|
backdrop: Backdrop,
|
|
backdrop: Backdrop,
|
|
|
modifier: Modifier = Modifier,
|
|
modifier: Modifier = Modifier,
|
|
|
enabled: Boolean = true,
|
|
enabled: Boolean = true,
|
|
|
onValueChangeFinished: (() -> Unit)? = null,
|
|
onValueChangeFinished: (() -> Unit)? = null,
|
|
|
onValueCommit: ((Float) -> Unit)? = null,
|
|
onValueCommit: ((Float) -> Unit)? = null,
|
|
|
|
|
+ accessibilityLabel: String? = null,
|
|
|
|
|
+ accessibilityValue: String? = null,
|
|
|
) {
|
|
) {
|
|
|
val accentColor = LegadoTheme.colorScheme.secondary
|
|
val accentColor = LegadoTheme.colorScheme.secondary
|
|
|
val trackColor = LegadoTheme.colorScheme.surfaceContainerLow
|
|
val trackColor = LegadoTheme.colorScheme.surfaceContainerLow
|
|
@@ -2401,7 +2485,30 @@ private fun ReadMenuLiquidSlider(
|
|
|
val trackBackdrop = rememberLayerBackdrop()
|
|
val trackBackdrop = rememberLayerBackdrop()
|
|
|
|
|
|
|
|
BoxWithConstraints(
|
|
BoxWithConstraints(
|
|
|
- modifier.fillMaxWidth(),
|
|
|
|
|
|
|
+ modifier
|
|
|
|
|
+ .fillMaxWidth()
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ accessibilityLabel?.let { contentDescription = it }
|
|
|
|
|
+ accessibilityValue?.let { stateDescription = it }
|
|
|
|
|
+ progressBarRangeInfo = ProgressBarRangeInfo(
|
|
|
|
|
+ current = value.coerceIn(valueRange),
|
|
|
|
|
+ range = valueRange,
|
|
|
|
|
+ steps = steps,
|
|
|
|
|
+ )
|
|
|
|
|
+ if (!enabled) {
|
|
|
|
|
+ disabled()
|
|
|
|
|
+ }
|
|
|
|
|
+ setProgress { target ->
|
|
|
|
|
+ if (!enabled) {
|
|
|
|
|
+ false
|
|
|
|
|
+ } else {
|
|
|
|
|
+ val nextValue = target.coerceIn(valueRange)
|
|
|
|
|
+ onValueChange(nextValue)
|
|
|
|
|
+ onValueCommit?.invoke(nextValue) ?: onValueChangeFinished?.invoke()
|
|
|
|
|
+ true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
contentAlignment = Alignment.CenterStart,
|
|
contentAlignment = Alignment.CenterStart,
|
|
|
) {
|
|
) {
|
|
|
val trackWidth = constraints.maxWidth
|
|
val trackWidth = constraints.maxWidth
|
|
@@ -2604,6 +2711,7 @@ private fun ToolButtonItem(
|
|
|
glassEnabled = true,
|
|
glassEnabled = true,
|
|
|
selected = button.isActive,
|
|
selected = button.isActive,
|
|
|
onLongClick = button.onLongClick,
|
|
onLongClick = button.onLongClick,
|
|
|
|
|
+ contentDescription = button.description,
|
|
|
) { tint ->
|
|
) { tint ->
|
|
|
ToolButtonContent(
|
|
ToolButtonContent(
|
|
|
button = button,
|
|
button = button,
|
|
@@ -2630,7 +2738,11 @@ private fun ToolButtonItem(
|
|
|
role = Role.Button,
|
|
role = Role.Button,
|
|
|
onLongClick = button.onLongClick,
|
|
onLongClick = button.onLongClick,
|
|
|
onClick = button.onClick,
|
|
onClick = button.onClick,
|
|
|
- ),
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .semantics {
|
|
|
|
|
+ contentDescription = button.description
|
|
|
|
|
+ role = Role.Button
|
|
|
|
|
+ },
|
|
|
) {
|
|
) {
|
|
|
ToolButtonContent(
|
|
ToolButtonContent(
|
|
|
button = button,
|
|
button = button,
|
|
@@ -2674,14 +2786,14 @@ private fun ToolButtonContent(
|
|
|
if (button.customIconPath.isNullOrBlank()) {
|
|
if (button.customIconPath.isNullOrBlank()) {
|
|
|
Icon(
|
|
Icon(
|
|
|
imageVector = button.icon,
|
|
imageVector = button.icon,
|
|
|
- contentDescription = button.description,
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
modifier = Modifier.size(20.dp),
|
|
modifier = Modifier.size(20.dp),
|
|
|
tint = tint,
|
|
tint = tint,
|
|
|
)
|
|
)
|
|
|
} else {
|
|
} else {
|
|
|
AsyncImage(
|
|
AsyncImage(
|
|
|
model = button.customIconPath,
|
|
model = button.customIconPath,
|
|
|
- contentDescription = button.description,
|
|
|
|
|
|
|
+ contentDescription = null,
|
|
|
contentScale = ContentScale.Crop,
|
|
contentScale = ContentScale.Crop,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
|
.size(36.dp)
|
|
.size(36.dp)
|
|
@@ -3204,6 +3316,11 @@ private fun BrightnessBar(
|
|
|
onToggleAuto()
|
|
onToggleAuto()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ val brightnessValueDescription = stringResource(
|
|
|
|
|
+ R.string.a11y_percent_value,
|
|
|
|
|
+ sliderValue.roundToInt().coerceIn(0, 100),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
if (vertical) {
|
|
if (vertical) {
|
|
|
Column(
|
|
Column(
|
|
|
modifier = modifier
|
|
modifier = modifier
|
|
@@ -3234,6 +3351,8 @@ private fun BrightnessBar(
|
|
|
valueRange = 0f..100f,
|
|
valueRange = 0f..100f,
|
|
|
enabled = !brightnessAuto,
|
|
enabled = !brightnessAuto,
|
|
|
height = 168.dp,
|
|
height = 168.dp,
|
|
|
|
|
+ accessibilityLabel = stringResource(R.string.brightness),
|
|
|
|
|
+ accessibilityValue = brightnessValueDescription,
|
|
|
)
|
|
)
|
|
|
ReadMenuGlassIconButton(
|
|
ReadMenuGlassIconButton(
|
|
|
onClick = onTogglePosition,
|
|
onClick = onTogglePosition,
|
|
@@ -3273,10 +3392,13 @@ private fun BrightnessBar(
|
|
|
onValueChangeFinished = {
|
|
onValueChangeFinished = {
|
|
|
commitSliderValue(sliderValue)
|
|
commitSliderValue(sliderValue)
|
|
|
},
|
|
},
|
|
|
|
|
+ onValueCommit = ::commitSliderValue,
|
|
|
valueRange = 0f..100f,
|
|
valueRange = 0f..100f,
|
|
|
enabled = !brightnessAuto,
|
|
enabled = !brightnessAuto,
|
|
|
backdrop = backdrop,
|
|
backdrop = backdrop,
|
|
|
glassThumbEnabled = glassThumbEnabled,
|
|
glassThumbEnabled = glassThumbEnabled,
|
|
|
|
|
+ accessibilityLabel = stringResource(R.string.brightness),
|
|
|
|
|
+ accessibilityValue = brightnessValueDescription,
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
|
.weight(1f)
|
|
.weight(1f)
|
|
|
.padding(horizontal = 8.dp),
|
|
.padding(horizontal = 8.dp),
|