Merge pull request #1426 from fansangg/feat/merge-padding-headerfooter

feat:页眉页脚的间距设置移到信息,信息改成dialog形式

@fansangg
This commit is contained in:
Kudomaga
2026-06-14 13:23:26 +08:00
committed by GitHub
10 changed files with 209 additions and 151 deletions
@@ -40,6 +40,7 @@ sealed interface ReadBookMenuRoute {
data object ReadAloud : ReadBookMenuRoute
data object AutoRead : ReadBookMenuRoute
data object PaddingConfig : ReadBookMenuRoute
data object HeaderFooterConfig : ReadBookMenuRoute
data class Bookmark(val bookmark: io.legado.app.data.entities.Bookmark) : ReadBookMenuRoute
}
@@ -139,6 +139,7 @@ import io.legado.app.help.config.ReadStyleResolver
import io.legado.app.ui.animation.DampedDragAnimation
import io.legado.app.ui.animation.InteractiveHighlight
import io.legado.app.ui.book.read.sheet.AutoReadContent
import io.legado.app.ui.book.read.sheet.HeaderFooterPage
import io.legado.app.ui.book.read.sheet.PaddingConfigContent
import io.legado.app.ui.book.read.sheet.ReadAloudContent
import io.legado.app.ui.book.read.sheet.ReadMenuButtonInfo
@@ -186,7 +187,7 @@ fun ReadBookMenuBar(
} else {
ReadBookMenuContent.Route(currentRoute)
}
val dialogLikeRoute = currentRoute == ReadBookMenuRoute.PaddingConfig
val dialogLikeRoute = currentRoute == ReadBookMenuRoute.PaddingConfig || currentRoute == ReadBookMenuRoute.HeaderFooterConfig
var readStylePage by remember { mutableIntStateOf(0) }
LaunchedEffect(currentRoute) {
if (currentRoute != ReadBookMenuRoute.ReadStyle) {
@@ -392,7 +393,7 @@ private fun ReadBookMenuSurface(
is ReadBookMenuContent.Route -> contentTarget.route
}
val expanded = route != ReadBookMenuRoute.Main
val dialogLikeRoute = route == ReadBookMenuRoute.PaddingConfig
val dialogLikeRoute = route == ReadBookMenuRoute.PaddingConfig || route == ReadBookMenuRoute.HeaderFooterConfig
val density = LocalDensity.current
val windowSize = LocalWindowInfo.current.containerSize
var surfaceHeightPx by remember { mutableIntStateOf(0) }
@@ -400,18 +401,6 @@ private fun ReadBookMenuSurface(
targetValue = if (dialogLikeRoute) 1f else 0f,
label = "ReadBookMenuMorph",
)
val headerFooterLift by animateDpAsState(
targetValue = if (route == ReadBookMenuRoute.ReadStyle && readStylePage == 2) {
72.dp
} else {
0.dp
},
animationSpec = tween(
durationMillis = 280,
easing = LinearOutSlowInEasing,
),
label = "ReadBookMenuHeaderFooterLift",
)
val maxHeight = with(density) {
windowSize.height.toDp() * 0.64f
}
@@ -518,8 +507,7 @@ private fun ReadBookMenuSurface(
.onSizeChanged { surfaceHeightPx = it.height }
.offset {
val dialogLiftPx = ((windowSize.height - surfaceHeightPx) / 2f) * morphProgress
val liftPx = dialogLiftPx + headerFooterLift.toPx()
IntOffset(x = 0, y = -liftPx.roundToInt())
IntOffset(x = 0, y = -dialogLiftPx.roundToInt())
}
.then(
if (useLiquidGlass) {
@@ -620,6 +608,9 @@ private fun ReadBookMenuSurface(
onOpenPaddingConfig = {
onIntent(ReadBookIntent.OpenReadMenuRoute(ReadBookMenuRoute.PaddingConfig))
},
onOpenHeaderFooterConfig = {
onIntent(ReadBookIntent.OpenReadMenuRoute(ReadBookMenuRoute.HeaderFooterConfig))
},
onOpenMoreConfig = {
onIntent(ReadBookIntent.ShowSheet(ReadBookSheet.MoreConfig))
},
@@ -659,6 +650,20 @@ private fun ReadBookMenuSurface(
}
}
ReadBookMenuRoute.HeaderFooterConfig -> {
ReadBookMenuRoutePage(
title = stringResource(R.string.header_footer),
maxHeight = maxHeight,
scrollContent = false,
bottomPadding = if (extendSurfaceToNavigationBar) navBarHeight else 0.dp,
onBack = { onIntent(ReadBookIntent.ReadMenuBack) },
) {
HeaderFooterPage(
onIntent = onIntent,
)
}
}
ReadBookMenuRoute.TextTitle -> {
ReadBookMenuRoutePage(
title = stringResource(R.string.read_config_text_effects),
@@ -1,25 +1,35 @@
package io.legado.app.ui.book.read.sheet
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material.icons.filled.TextFields
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
@@ -32,11 +42,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -46,6 +54,7 @@ import io.legado.app.data.repository.ReadSettingsRepository
import io.legado.app.help.config.ReadBookConfig
import io.legado.app.ui.book.read.ConfigUpdate
import io.legado.app.ui.book.read.ReadBookIntent
import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.widget.components.FontSelectSheet
import io.legado.app.ui.widget.components.dialog.ColorPickerSheet
import io.legado.app.ui.widget.components.settingItem.TinyClickableSettingItem
@@ -106,6 +115,42 @@ internal fun HeaderFooterPage(
var colorPickerInitial by remember { mutableIntStateOf(0) }
var showFontSelect by remember { mutableStateOf(false) }
var expandHeaderPadding by remember { mutableStateOf(false) }
var expandFooterPadding by remember { mutableStateOf(false) }
val headerScrollState = rememberScrollState()
val footerScrollState = rememberScrollState()
LaunchedEffect(expandHeaderPadding, headerScrollState.maxValue) {
if (expandHeaderPadding) {
headerScrollState.scrollTo(headerScrollState.maxValue)
}
}
LaunchedEffect(expandFooterPadding, footerScrollState.maxValue) {
if (expandFooterPadding) {
footerScrollState.scrollTo(footerScrollState.maxValue)
}
}
DisposableEffect(Unit) {
onDispose {
onIntent(ReadBookIntent.SaveReadStyleConfig)
}
}
// Header padding state
var headerPaddingTop by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingTop.toFloat()) }
var headerPaddingBottom by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingBottom.toFloat()) }
var headerPaddingLeft by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingLeft.toFloat()) }
var headerPaddingRight by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingRight.toFloat()) }
// Footer padding state
var footerPaddingTop by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingTop.toFloat()) }
var footerPaddingBottom by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingBottom.toFloat()) }
var footerPaddingLeft by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingLeft.toFloat()) }
var footerPaddingRight by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingRight.toFloat()) }
val tipNames = remember { ReadBookConfig.tipNames }
val tipValues = remember { ReadBookConfig.tipValues }
@@ -153,7 +198,7 @@ internal fun HeaderFooterPage(
scope.launch {
pagerState.animateScrollToPage(
page = index,
animationSpec = tween(durationMillis = 400, easing = FastOutSlowInEasing)
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)
}
},
@@ -181,7 +226,7 @@ internal fun HeaderFooterPage(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()),
.verticalScroll(headerScrollState),
) {
TinySwitchSettingItem(
title = stringResource(R.string.showLine),
@@ -252,6 +297,56 @@ internal fun HeaderFooterPage(
showColorPicker = true
},
)
Spacer(Modifier.height(8.dp))
TinyClickableSettingItem(
title = stringResource(R.string.padding),
description = stringResource(
R.string.padding_format,
headerPaddingTop.toInt(),
headerPaddingBottom.toInt(),
headerPaddingLeft.toInt(),
headerPaddingRight.toInt(),
),
trailingContent = {
Icon(
imageVector = if (expandHeaderPadding) Icons.Default.ExpandMore else Icons.Default.ChevronRight,
contentDescription = null,
tint = LegadoTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(20.dp),
)
},
onClick = {
expandHeaderPadding = !expandHeaderPadding
},
)
AnimatedVisibility(
visible = expandHeaderPadding,
enter = expandVertically() + fadeIn(),
exit = shrinkVertically() + fadeOut(),
) {
Column(modifier = Modifier.fillMaxWidth()) {
PaddingSliders(
top = headerPaddingTop, bottom = headerPaddingBottom,
left = headerPaddingLeft, right = headerPaddingRight,
onTopChange = {
headerPaddingTop = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingTop(it.toInt())))
},
onBottomChange = {
headerPaddingBottom = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingBottom(it.toInt())))
},
onLeftChange = {
headerPaddingLeft = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingLeft(it.toInt())))
},
onRightChange = {
headerPaddingRight = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingRight(it.toInt())))
},
)
}
}
}
}
@@ -261,7 +356,7 @@ internal fun HeaderFooterPage(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()),
.verticalScroll(footerScrollState),
) {
TinySwitchSettingItem(
title = stringResource(R.string.showLine),
@@ -332,6 +427,56 @@ internal fun HeaderFooterPage(
showColorPicker = true
},
)
Spacer(Modifier.height(8.dp))
TinyClickableSettingItem(
title = stringResource(R.string.padding),
description = stringResource(
R.string.padding_format,
footerPaddingTop.toInt(),
footerPaddingBottom.toInt(),
footerPaddingLeft.toInt(),
footerPaddingRight.toInt(),
),
trailingContent = {
Icon(
imageVector = if (expandFooterPadding) Icons.Default.ExpandMore else Icons.Default.ChevronRight,
contentDescription = null,
tint = LegadoTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(20.dp),
)
},
onClick = {
expandFooterPadding = !expandFooterPadding
},
)
AnimatedVisibility(
visible = expandFooterPadding,
enter = expandVertically() + fadeIn(),
exit = shrinkVertically() + fadeOut(),
) {
Column(modifier = Modifier.fillMaxWidth()) {
PaddingSliders(
top = footerPaddingTop, bottom = footerPaddingBottom,
left = footerPaddingLeft, right = footerPaddingRight,
onTopChange = {
footerPaddingTop = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingTop(it.toInt())))
},
onBottomChange = {
footerPaddingBottom = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingBottom(it.toInt())))
},
onLeftChange = {
footerPaddingLeft = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingLeft(it.toInt())))
},
onRightChange = {
footerPaddingRight = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingRight(it.toInt())))
},
)
}
}
}
}
@@ -3,18 +3,11 @@ package io.legado.app.ui.book.read.sheet
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@@ -24,8 +17,6 @@ import io.legado.app.ui.book.read.ConfigUpdate
import io.legado.app.ui.book.read.ReadBookIntent
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
import io.legado.app.ui.widget.components.settingItem.TinySliderSettingItem
import io.legado.app.ui.widget.components.tabRow.CardTabRow
import kotlinx.coroutines.launch
@Composable
fun PaddingConfigSheet(
@@ -58,122 +49,35 @@ fun PaddingConfigContent(
var paddingBottom by remember { mutableFloatStateOf(ReadBookConfig.paddingBottom.toFloat()) }
var paddingLeft by remember { mutableFloatStateOf(ReadBookConfig.paddingLeft.toFloat()) }
var paddingRight by remember { mutableFloatStateOf(ReadBookConfig.paddingRight.toFloat()) }
// Header padding
var headerPaddingTop by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingTop.toFloat()) }
var headerPaddingBottom by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingBottom.toFloat()) }
var headerPaddingLeft by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingLeft.toFloat()) }
var headerPaddingRight by remember { mutableFloatStateOf(ReadBookConfig.headerPaddingRight.toFloat()) }
// Footer padding
var footerPaddingTop by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingTop.toFloat()) }
var footerPaddingBottom by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingBottom.toFloat()) }
var footerPaddingLeft by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingLeft.toFloat()) }
var footerPaddingRight by remember { mutableFloatStateOf(ReadBookConfig.footerPaddingRight.toFloat()) }
val scope = rememberCoroutineScope()
val tabTitles = listOf(
stringResource(R.string.header),
stringResource(R.string.main_body),
stringResource(R.string.footer),
)
val pagerState = rememberPagerState(pageCount = { 3 })
var selectedTab by remember { mutableIntStateOf(0) }
LaunchedEffect(pagerState) {
snapshotFlow { pagerState.settledPage }.collect { selectedTab = it }
}
Column(
modifier = modifier.fillMaxWidth(),
) {
CardTabRow(
tabTitles = tabTitles,
selectedTabIndex = selectedTab,
onTabSelected = { index ->
selectedTab = index
scope.launch { pagerState.animateScrollToPage(index) }
PaddingSliders(
top = paddingTop, bottom = paddingBottom,
left = paddingLeft, right = paddingRight,
onTopChange = {
paddingTop = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingTop(it.toInt())))
},
onBottomChange = {
paddingBottom = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingBottom(it.toInt())))
},
onLeftChange = {
paddingLeft = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingLeft(it.toInt())))
},
onRightChange = {
paddingRight = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingRight(it.toInt())))
},
modifier = Modifier.padding(bottom = 8.dp),
)
HorizontalPager(
state = pagerState,
modifier = Modifier.fillMaxWidth(),
) { page ->
when (page) {
0 -> Column(modifier = Modifier.padding(vertical = 8.dp)) {
PaddingSliders(
top = headerPaddingTop, bottom = headerPaddingBottom,
left = headerPaddingLeft, right = headerPaddingRight,
onTopChange = {
headerPaddingTop = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingTop(it.toInt())))
},
onBottomChange = {
headerPaddingBottom = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingBottom(it.toInt())))
},
onLeftChange = {
headerPaddingLeft = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingLeft(it.toInt())))
},
onRightChange = {
headerPaddingRight = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.HeaderPaddingRight(it.toInt())))
},
)
}
1 -> Column(modifier = Modifier.padding(vertical = 8.dp)) {
PaddingSliders(
top = paddingTop, bottom = paddingBottom,
left = paddingLeft, right = paddingRight,
onTopChange = {
paddingTop = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingTop(it.toInt())))
},
onBottomChange = {
paddingBottom = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingBottom(it.toInt())))
},
onLeftChange = {
paddingLeft = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingLeft(it.toInt())))
},
onRightChange = {
paddingRight = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.PaddingRight(it.toInt())))
},
)
}
2 -> Column(modifier = Modifier.padding(vertical = 8.dp)) {
PaddingSliders(
top = footerPaddingTop, bottom = footerPaddingBottom,
left = footerPaddingLeft, right = footerPaddingRight,
onTopChange = {
footerPaddingTop = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingTop(it.toInt())))
},
onBottomChange = {
footerPaddingBottom = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingBottom(it.toInt())))
},
onLeftChange = {
footerPaddingLeft = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingLeft(it.toInt())))
},
onRightChange = {
footerPaddingRight = it
onIntent(ReadBookIntent.UpdateConfig(ConfigUpdate.FooterPaddingRight(it.toInt())))
},
)
}
}
}
}
}
@Composable
private fun PaddingSliders(
internal fun PaddingSliders(
top: Float, bottom: Float, left: Float, right: Float,
onTopChange: (Float) -> Unit, onBottomChange: (Float) -> Unit,
onLeftChange: (Float) -> Unit, onRightChange: (Float) -> Unit,
@@ -38,6 +38,7 @@ import kotlinx.coroutines.launch
@Composable
fun ReadStyleContent(
onOpenPaddingConfig: () -> Unit,
onOpenHeaderFooterConfig: () -> Unit,
onOpenMoreConfig: () -> Unit,
onOpenBgTextConfig: (Int) -> Unit,
onOpenTextTitle: () -> Unit,
@@ -51,7 +52,7 @@ fun ReadStyleContent(
styleConfig: ReadBookStyleConfig = ReadBookStyleConfig(),
) {
val scope = rememberCoroutineScope()
val pagerState = rememberPagerState(pageCount = { 3 })
val pagerState = rememberPagerState(pageCount = { 2 })
var currentPage by remember { mutableIntStateOf(0) }
val pageHeights = remember { mutableStateMapOf<Int, Int>() }
@@ -105,10 +106,6 @@ fun ReadStyleContent(
bottomBarButtons = bottomBarButtons,
onIntent = onIntent,
)
2 -> HeaderFooterPage(
onIntent = onIntent,
)
}
}
}
@@ -123,15 +120,17 @@ fun ReadStyleContent(
tabTitles = tabTitles,
selectedTabIndex = currentPage,
onTabSelected = { index ->
if (index < 3) {
scope.launch {
pagerState.animateScrollToPage(
page = index,
animationSpec = tween(durationMillis = 400, easing = FastOutSlowInEasing)
)
when (index) {
0, 1 -> {
scope.launch {
pagerState.animateScrollToPage(
page = index,
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)
}
}
} else {
onOpenMoreConfig()
2 -> onOpenHeaderFooterConfig()
3 -> onOpenMoreConfig()
}
},
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp),
@@ -128,7 +128,7 @@ internal fun SystemMenuPage(
scope.launch {
pagerState.animateScrollToPage(
page = index,
animationSpec = tween(durationMillis = 400, easing = FastOutSlowInEasing)
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)
}
},
@@ -352,6 +352,7 @@
<string name="padding_bottom">下边距</string>
<string name="padding_left">左边距</string>
<string name="padding_right">右边距</string>
<string name="padding_format">上: %1$d 下: %2$d 左: %3$d 右: %4$d</string>
<string name="check_book_source">校验书源</string>
<string name="check_select_source">校验所选</string>
<string name="progress_show">%1$s 进度 %2$d/%3$d</string>
@@ -299,6 +299,7 @@
<string name="padding_bottom">下邊距</string>
<string name="padding_left">左邊距</string>
<string name="padding_right">右邊距</string>
<string name="padding_format">上: %1$d 下: %2$d 左: %3$d 右: %4$d</string>
<string name="check_book_source">校驗書源</string>
<string name="check_select_source">校驗所選</string>
<string name="progress_show">%1$s 進度 %2$d/%3$d</string>
@@ -301,6 +301,7 @@
<string name="padding_bottom">下邊距</string>
<string name="padding_left">左邊距</string>
<string name="padding_right">右邊距</string>
<string name="padding_format">上: %1$d 下: %2$d 左: %3$d 右: %4$d</string>
<string name="check_book_source">校驗書源</string>
<string name="check_select_source">校驗所選</string>
<string name="progress_show">%1$s 進度 %2$d/%3$d</string>
+1
View File
@@ -373,6 +373,7 @@
<string name="padding_bottom">Bottom</string>
<string name="padding_left">Left</string>
<string name="padding_right">Right</string>
<string name="padding_format">Top: %1$d Bottom: %2$d Left: %3$d Right: %4$d</string>
<string name="check_book_source">Check book sources</string>
<string name="check_select_source"