feat(i18n): standardize English and Simplified Chinese localization across UI
feat(i18n): standardize English and Simplified Chinese UI strings - Move hardcoded user-facing text from Compose screens and dialogs into string resources - Add and refine English and zh-rCN translations for settings, theme, about, backup, TOC, and book info flows - Keep internal logs, exceptions, parser text, and comments unchanged unless user-facing - Preserve existing behavior while improving localization consistency
This commit is contained in:
@@ -17,3 +17,4 @@ package-lock.json
|
||||
# Kotlin 2.0
|
||||
.kotlin/
|
||||
/.vscode/settings.json
|
||||
/.codex/skills
|
||||
|
||||
@@ -85,6 +85,9 @@ private fun MaterialAboutScreen(
|
||||
versionName: String,
|
||||
) {
|
||||
val scrollBehavior = GlassTopAppBarDefaults.defaultScrollBehavior()
|
||||
val privacyPolicyTitle = stringResource(R.string.about_privacy_policy_title)
|
||||
val licenseTitle = stringResource(R.string.about_license_title)
|
||||
val disclaimerTitle = stringResource(R.string.about_disclaimer_title)
|
||||
|
||||
AppScaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
@@ -178,7 +181,7 @@ private fun MaterialAboutScreen(
|
||||
onClick = {
|
||||
onIntent(
|
||||
AboutIntent.ShowMdFile(
|
||||
"隐私政策",
|
||||
privacyPolicyTitle,
|
||||
"privacyPolicy.md"
|
||||
)
|
||||
)
|
||||
@@ -188,13 +191,13 @@ private fun MaterialAboutScreen(
|
||||
SettingItemWithDivider {
|
||||
SettingItem(
|
||||
title = stringResource(R.string.license),
|
||||
onClick = { onIntent(AboutIntent.ShowMdFile("许可证", "LICENSE.md")) }
|
||||
onClick = { onIntent(AboutIntent.ShowMdFile(licenseTitle, "LICENSE.md")) }
|
||||
)
|
||||
}
|
||||
SettingItemWithDivider {
|
||||
SettingItem(
|
||||
title = stringResource(R.string.disclaimer),
|
||||
onClick = { onIntent(AboutIntent.ShowMdFile("免责声明", "disclaimer.md")) }
|
||||
onClick = { onIntent(AboutIntent.ShowMdFile(disclaimerTitle, "disclaimer.md")) }
|
||||
)
|
||||
}
|
||||
SettingItemWithDivider {
|
||||
|
||||
@@ -80,7 +80,7 @@ fun UpdateSheet(
|
||||
) {
|
||||
val title = when (mode) {
|
||||
UpdateMode.UPDATE -> stringResource(R.string.check_update)
|
||||
UpdateMode.VIEW_LOG -> "已经更新至"
|
||||
UpdateMode.VIEW_LOG -> stringResource(R.string.about_installed_version_title)
|
||||
}
|
||||
|
||||
AppModalBottomSheet(
|
||||
@@ -99,7 +99,7 @@ fun UpdateSheet(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
AppText(
|
||||
text = "当前版本",
|
||||
text = stringResource(R.string.about_current_version),
|
||||
style = LegadoTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
@@ -114,7 +114,7 @@ fun UpdateSheet(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
AppText(
|
||||
text = "新版本",
|
||||
text = stringResource(R.string.about_new_version),
|
||||
style = LegadoTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
@@ -144,7 +144,7 @@ fun UpdateSheet(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
AppText(
|
||||
text = "渠道",
|
||||
text = stringResource(R.string.about_update_channel),
|
||||
style = LegadoTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
@@ -182,7 +182,7 @@ fun UpdateSheet(
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
PrimaryButton(
|
||||
onClick = onStartDownload,
|
||||
text = "更新",
|
||||
text = stringResource(R.string.about_update_action),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -152,17 +152,17 @@ class AboutViewModel(application: Application) : BaseViewModel(application) {
|
||||
private fun saveLog() {
|
||||
execute {
|
||||
val backupPath = AppConfig.backupPath ?: run {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("未设置备份目录"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_backup_dir_not_set)))
|
||||
return@execute
|
||||
}
|
||||
if (!AppConfig.recordLog) {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("未开启日志记录,请去其他设置里打开记录日志"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_log_recording_disabled)))
|
||||
delay(3000)
|
||||
}
|
||||
val doc = FileDoc.fromUri(backupPath.toUri(), true)
|
||||
copyLogs(doc)
|
||||
copyHeapDump(doc)
|
||||
_effects.tryEmit(AboutEffect.ShowToast("已保存至备份目录"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_saved_to_backup_dir)))
|
||||
}.onError {
|
||||
AppLog.put("保存日志出错\n${it.localizedMessage}", it, true)
|
||||
}
|
||||
@@ -171,21 +171,21 @@ class AboutViewModel(application: Application) : BaseViewModel(application) {
|
||||
private fun createHeapDump() {
|
||||
execute {
|
||||
val backupPath = AppConfig.backupPath ?: run {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("未设置备份目录"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_backup_dir_not_set)))
|
||||
return@execute
|
||||
}
|
||||
if (!AppConfig.recordHeapDump) {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("未开启堆转储记录,请去其他设置里打开记录堆转储"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_heap_dump_recording_disabled)))
|
||||
delay(3000)
|
||||
}
|
||||
_effects.tryEmit(AboutEffect.ShowToast("开始创建堆转储"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_heap_dump_creating)))
|
||||
System.gc()
|
||||
CrashHandler.doHeapDump(true)
|
||||
val doc = FileDoc.fromUri(backupPath.toUri(), true)
|
||||
if (!copyHeapDump(doc)) {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("未找到堆转储文件"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_heap_dump_not_found)))
|
||||
} else {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("已保存至备份目录"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_saved_to_backup_dir)))
|
||||
}
|
||||
}.onError {
|
||||
AppLog.put("保存堆转储失败\n${it.localizedMessage}", it)
|
||||
@@ -197,7 +197,7 @@ class AboutViewModel(application: Application) : BaseViewModel(application) {
|
||||
if (sheet is AboutSheet.Update) {
|
||||
val info = sheet.updateInfo
|
||||
if (info.downloadUrl.isBlank() || info.fileName.isBlank()) {
|
||||
_effects.tryEmit(AboutEffect.ShowToast("下载信息不完整"))
|
||||
_effects.tryEmit(AboutEffect.ShowToast(context.getString(R.string.about_download_info_incomplete)))
|
||||
} else {
|
||||
_effects.tryEmit(AboutEffect.StartDownload(info.downloadUrl, info.fileName))
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ fun MiuixAboutScreen(
|
||||
val topAppBarScrollBehavior = MiuixScrollBehavior()
|
||||
val lazyListState = rememberLazyListState()
|
||||
val isWideScreen = shouldShowSplitPane()
|
||||
val licenseTitle = stringResource(R.string.about_license_title)
|
||||
|
||||
val scrollProgress by remember {
|
||||
derivedStateOf {
|
||||
@@ -119,7 +120,7 @@ fun MiuixAboutScreen(
|
||||
if (scrollProgress == 1f) MiuixTheme.colorScheme.surface else Color.Transparent
|
||||
}
|
||||
|
||||
val navigator = remember {
|
||||
val navigator = remember(licenseTitle) {
|
||||
object : MiuixNavigator {
|
||||
override fun pop() {
|
||||
onBack()
|
||||
@@ -127,7 +128,7 @@ fun MiuixAboutScreen(
|
||||
|
||||
override fun push(route: Any) {
|
||||
if (route == "License") {
|
||||
onIntent(AboutIntent.ShowMdFile("许可证", "LICENSE.md"))
|
||||
onIntent(AboutIntent.ShowMdFile(licenseTitle, "LICENSE.md"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,6 +181,9 @@ private fun AboutContent(
|
||||
) {
|
||||
val appState = LocalAppState.current
|
||||
val isWideScreen = LocalIsWideScreen.current
|
||||
val privacyPolicyTitle = stringResource(R.string.about_privacy_policy_title)
|
||||
val licenseTitle = stringResource(R.string.about_license_title)
|
||||
val disclaimerTitle = stringResource(R.string.about_disclaimer_title)
|
||||
|
||||
val backdrop = rememberBlurBackdrop()
|
||||
var blurRadius by remember { mutableFloatStateOf(60f) }
|
||||
@@ -427,7 +431,7 @@ private fun AboutContent(
|
||||
onClick = {
|
||||
onIntent(
|
||||
AboutIntent.ShowMdFile(
|
||||
"隐私政策",
|
||||
privacyPolicyTitle,
|
||||
"privacyPolicy.md"
|
||||
)
|
||||
)
|
||||
@@ -435,14 +439,14 @@ private fun AboutContent(
|
||||
)
|
||||
ArrowPreference(
|
||||
title = stringResource(R.string.license),
|
||||
onClick = { onIntent(AboutIntent.ShowMdFile("许可证", "LICENSE.md")) },
|
||||
onClick = { onIntent(AboutIntent.ShowMdFile(licenseTitle, "LICENSE.md")) },
|
||||
)
|
||||
ArrowPreference(
|
||||
title = stringResource(R.string.disclaimer),
|
||||
onClick = {
|
||||
onIntent(
|
||||
AboutIntent.ShowMdFile(
|
||||
"免责声明",
|
||||
disclaimerTitle,
|
||||
"disclaimer.md"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
|
||||
|
||||
val updateBody = arguments?.getString("updateBody")
|
||||
if (updateBody.isNullOrBlank()) {
|
||||
toastOnUi("没有数据")
|
||||
toastOnUi(R.string.about_no_data)
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
@@ -77,16 +77,16 @@ class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
|
||||
binding.tvUrl.text = url
|
||||
binding.btnUpdate.setOnClickListener {
|
||||
if (url.isNullOrBlank() || fileName.isNullOrBlank()) {
|
||||
toastOnUi("下载信息不完整")
|
||||
toastOnUi(R.string.about_download_info_incomplete)
|
||||
return@setOnClickListener
|
||||
}
|
||||
Download.start(requireContext(), url, fileName)
|
||||
toastOnUi("开始下载: $fileName")
|
||||
toastOnUi(getString(R.string.about_start_download, fileName))
|
||||
}
|
||||
}
|
||||
|
||||
Mode.VIEW_LOG -> {
|
||||
binding.bottomSheetTitle.text = "已经更新至"
|
||||
binding.bottomSheetTitle.setText(R.string.about_installed_version_title)
|
||||
binding.tvVersion.text = BuildConfig.VERSION_NAME
|
||||
binding.btnUpdate.gone()
|
||||
binding.llCurrent.gone()
|
||||
|
||||
@@ -178,7 +178,11 @@ fun BookInfoEditContent(
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
BookTypeDropdown(
|
||||
bookTypes = uiState.bookTypes,
|
||||
bookTypes = listOf(
|
||||
BookInfoEditType.TEXT to stringResource(R.string.book_type_text),
|
||||
BookInfoEditType.AUDIO to stringResource(R.string.book_type_audio),
|
||||
BookInfoEditType.IMAGE to stringResource(R.string.book_type_image)
|
||||
),
|
||||
selectedType = uiState.selectedType,
|
||||
onTypeSelected = { viewModel.onBookTypeChange(it) }
|
||||
)
|
||||
@@ -186,8 +190,8 @@ fun BookInfoEditContent(
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
SwitchSettingItem(
|
||||
title = "固定书籍类型",
|
||||
description = "书籍更新后不覆盖书籍类型",
|
||||
title = stringResource(R.string.fixed_book_type),
|
||||
description = stringResource(R.string.fixed_book_type_summary),
|
||||
checked = uiState.fixedType,
|
||||
onCheckedChange = { viewModel.onFixedTypeChange(it) }
|
||||
)
|
||||
@@ -201,7 +205,7 @@ fun BookInfoEditContent(
|
||||
AppTextField(
|
||||
value = uiState.name,
|
||||
onValueChange = { viewModel.onNameChange(it) },
|
||||
label = "书名",
|
||||
label = stringResource(R.string.book_name),
|
||||
backgroundColor = inputBackgroundColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -209,7 +213,7 @@ fun BookInfoEditContent(
|
||||
AppTextField(
|
||||
value = uiState.author,
|
||||
onValueChange = { viewModel.onAuthorChange(it) },
|
||||
label = "作者",
|
||||
label = stringResource(R.string.author),
|
||||
backgroundColor = inputBackgroundColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -217,7 +221,7 @@ fun BookInfoEditContent(
|
||||
AppTextField(
|
||||
value = uiState.coverUrl ?: "",
|
||||
onValueChange = { viewModel.onCoverUrlChange(it) },
|
||||
label = "封面链接",
|
||||
label = stringResource(R.string.cover_url),
|
||||
backgroundColor = inputBackgroundColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -232,7 +236,7 @@ fun BookInfoEditContent(
|
||||
AppTextField(
|
||||
value = uiState.intro ?: "",
|
||||
onValueChange = { viewModel.onIntroChange(it) },
|
||||
label = "简介",
|
||||
label = stringResource(R.string.book_intro),
|
||||
backgroundColor = inputBackgroundColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -240,7 +244,7 @@ fun BookInfoEditContent(
|
||||
AppTextField(
|
||||
value = uiState.remark ?: "",
|
||||
onValueChange = { viewModel.onRemarkChange(it) },
|
||||
label = "备注",
|
||||
label = stringResource(R.string.book_remark),
|
||||
backgroundColor = inputBackgroundColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -250,18 +254,19 @@ fun BookInfoEditContent(
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun BookTypeDropdown(
|
||||
bookTypes: List<String>,
|
||||
selectedType: String,
|
||||
onTypeSelected: (String) -> Unit
|
||||
bookTypes: List<Pair<BookInfoEditType, String>>,
|
||||
selectedType: BookInfoEditType,
|
||||
onTypeSelected: (BookInfoEditType) -> Unit
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
val selectedTypeLabel = bookTypes.firstOrNull { it.first == selectedType }?.second.orEmpty()
|
||||
|
||||
val textFieldState = rememberTextFieldState(
|
||||
initialText = selectedType
|
||||
initialText = selectedTypeLabel
|
||||
)
|
||||
|
||||
LaunchedEffect(selectedType) {
|
||||
textFieldState.setTextAndPlaceCursorAtEnd(selectedType)
|
||||
LaunchedEffect(selectedTypeLabel) {
|
||||
textFieldState.setTextAndPlaceCursorAtEnd(selectedTypeLabel)
|
||||
}
|
||||
|
||||
val bookInfoInputColor = ThemeConfig.bookInfoInputColor
|
||||
@@ -280,7 +285,7 @@ fun BookTypeDropdown(
|
||||
state = textFieldState,
|
||||
readOnly = true,
|
||||
lineLimits = TextFieldLineLimits.SingleLine,
|
||||
label = "书籍类型",
|
||||
label = stringResource(R.string.book_type_label),
|
||||
backgroundColor = inputBackgroundColor,
|
||||
trailingIcon = {
|
||||
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
|
||||
@@ -297,11 +302,11 @@ fun BookTypeDropdown(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
bookTypes.forEach { option ->
|
||||
bookTypes.forEach { (type, label) ->
|
||||
RoundDropdownMenuItem(
|
||||
text = option,
|
||||
text = label,
|
||||
onClick = {
|
||||
onTypeSelected(option)
|
||||
onTypeSelected(type)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
@@ -387,12 +392,16 @@ fun KindEditor(
|
||||
AppAlertDialog(
|
||||
show = true,
|
||||
onDismissRequest = { editingIndex = null },
|
||||
title = if (isAdding) "添加标签" else "编辑标签",
|
||||
title = if (isAdding) {
|
||||
stringResource(R.string.add_tag)
|
||||
} else {
|
||||
stringResource(R.string.edit_tag)
|
||||
},
|
||||
content = {
|
||||
AppTextField(
|
||||
value = editText,
|
||||
onValueChange = { editText = it },
|
||||
label = "标签",
|
||||
label = stringResource(R.string.tag),
|
||||
backgroundColor = backgroundColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
@@ -25,6 +25,12 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
||||
enum class BookInfoEditType {
|
||||
TEXT,
|
||||
AUDIO,
|
||||
IMAGE
|
||||
}
|
||||
|
||||
data class BookInfoEditUiState(
|
||||
val name: String = "",
|
||||
val author: String = "",
|
||||
@@ -33,8 +39,7 @@ data class BookInfoEditUiState(
|
||||
val remark: String? = null,
|
||||
val kindList: List<String> = emptyList(),
|
||||
val originalKindList: List<String> = emptyList(),
|
||||
val selectedType: String = "文本",
|
||||
val bookTypes: List<String> = listOf("文本", "音频", "图片"),
|
||||
val selectedType: BookInfoEditType = BookInfoEditType.TEXT,
|
||||
val fixedType: Boolean = false,
|
||||
val book: Book? = null,
|
||||
)
|
||||
@@ -49,9 +54,9 @@ class BookInfoEditViewModel(application: Application) : BaseViewModel(applicatio
|
||||
book = appDb.bookDao.getBook(bookUrl)
|
||||
book?.let {
|
||||
val selectedTypeIndex = when {
|
||||
it.isImage -> 2
|
||||
it.isAudio -> 1
|
||||
else -> 0
|
||||
it.isImage -> BookInfoEditType.IMAGE
|
||||
it.isAudio -> BookInfoEditType.AUDIO
|
||||
else -> BookInfoEditType.TEXT
|
||||
}
|
||||
val kinds =
|
||||
it.kind?.split(",", "\n")?.filter { kind -> kind.isNotBlank() }.orEmpty()
|
||||
@@ -63,7 +68,7 @@ class BookInfoEditViewModel(application: Application) : BaseViewModel(applicatio
|
||||
remark = it.remark,
|
||||
kindList = kinds,
|
||||
originalKindList = kinds,
|
||||
selectedType = _uiState.value.bookTypes[selectedTypeIndex],
|
||||
selectedType = selectedTypeIndex,
|
||||
fixedType = it.config.fixedType,
|
||||
book = it
|
||||
)
|
||||
@@ -99,7 +104,7 @@ class BookInfoEditViewModel(application: Application) : BaseViewModel(applicatio
|
||||
_uiState.value = _uiState.value.copy(kindList = kindList)
|
||||
}
|
||||
|
||||
fun onBookTypeChange(bookType: String) {
|
||||
fun onBookTypeChange(bookType: BookInfoEditType) {
|
||||
_uiState.value = _uiState.value.copy(selectedType = bookType)
|
||||
}
|
||||
|
||||
@@ -121,8 +126,8 @@ class BookInfoEditViewModel(application: Application) : BaseViewModel(applicatio
|
||||
book.remark = currentState.remark
|
||||
val local = if (book.isLocal) BookType.local else 0
|
||||
val bookType = when (currentState.selectedType) {
|
||||
currentState.bookTypes[2] -> BookType.image or local
|
||||
currentState.bookTypes[1] -> BookType.audio or local
|
||||
BookInfoEditType.IMAGE -> BookType.image or local
|
||||
BookInfoEditType.AUDIO -> BookType.audio or local
|
||||
else -> BookType.text or local
|
||||
}
|
||||
book.removeType(BookType.local, BookType.image, BookType.audio, BookType.text)
|
||||
|
||||
@@ -40,4 +40,4 @@ class TocActivity : BaseComposeActivity() {
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,12 +71,14 @@ import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.zIndex
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import io.legado.app.R
|
||||
import io.legado.app.data.entities.Bookmark
|
||||
import io.legado.app.help.book.isLocal
|
||||
import io.legado.app.ui.book.toc.rule.TxtTocRuleActivity
|
||||
@@ -151,6 +153,15 @@ fun TocScreen(
|
||||
|
||||
val useReplace = viewModel.useReplace
|
||||
val showWordCount = viewModel.showWordCount
|
||||
val bookmarkManagementTitle = stringResource(R.string.bookmark_management)
|
||||
val locateCurrentReadingText = stringResource(R.string.locate_current_reading)
|
||||
val moveToTopText = stringResource(R.string.move_to_top)
|
||||
val moveToBottomText = stringResource(R.string.move_to_bottom)
|
||||
val downloadAllText = stringResource(R.string.download_all)
|
||||
val invertSelectionText = stringResource(R.string.invert_selection)
|
||||
val selectFollowingText = stringResource(R.string.select_following)
|
||||
val addBookmarkText = stringResource(R.string.bookmark_add)
|
||||
val bookmarkDefaultFileName = stringResource(R.string.bookmark)
|
||||
|
||||
val topBarTitle = remember(
|
||||
pagerState.currentPage,
|
||||
@@ -162,7 +173,7 @@ fun TocScreen(
|
||||
book?.durChapterTitle?.takeIf { it.isNotBlank() } ?: (book?.name ?: "")
|
||||
}
|
||||
|
||||
1 -> "书签管理"
|
||||
1 -> bookmarkManagementTitle
|
||||
else -> book?.name ?: ""
|
||||
}
|
||||
}
|
||||
@@ -206,9 +217,15 @@ fun TocScreen(
|
||||
}
|
||||
}
|
||||
|
||||
val fabItems = remember(state.items) {
|
||||
val fabItems = remember(
|
||||
state.items,
|
||||
locateCurrentReadingText,
|
||||
moveToTopText,
|
||||
moveToBottomText,
|
||||
downloadAllText
|
||||
) {
|
||||
listOf(
|
||||
FabMenuItem(Icons.Default.LocationOn, "定位至当前阅读") {
|
||||
FabMenuItem(Icons.Default.LocationOn, locateCurrentReadingText) {
|
||||
scope.launch {
|
||||
val target = state.items.indexOfFirst { it.isDur }
|
||||
if (target != -1) {
|
||||
@@ -219,32 +236,37 @@ fun TocScreen(
|
||||
}
|
||||
}
|
||||
},
|
||||
FabMenuItem(Icons.Default.VerticalAlignTop, "移至顶部") {
|
||||
FabMenuItem(Icons.Default.VerticalAlignTop, moveToTopText) {
|
||||
scope.launch { listState.animateScrollToItem(0) }
|
||||
},
|
||||
FabMenuItem(Icons.Default.VerticalAlignBottom, "移至底部") {
|
||||
FabMenuItem(Icons.Default.VerticalAlignBottom, moveToBottomText) {
|
||||
scope.launch { listState.animateScrollToItem(state.items.size) }
|
||||
},
|
||||
FabMenuItem(Icons.Default.DownloadForOffline, "下载全部") {
|
||||
FabMenuItem(Icons.Default.DownloadForOffline, downloadAllText) {
|
||||
viewModel.downloadAll()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val selectionSecondaryActions = remember(state.selectedIds) {
|
||||
val selectionSecondaryActions = remember(
|
||||
state.selectedIds,
|
||||
invertSelectionText,
|
||||
selectFollowingText,
|
||||
addBookmarkText
|
||||
) {
|
||||
listOf(
|
||||
ActionItem(
|
||||
text = "反选",
|
||||
text = invertSelectionText,
|
||||
icon = Icons.Default.Refresh,
|
||||
onClick = { viewModel.invertSelection() }
|
||||
),
|
||||
ActionItem(
|
||||
text = "选择后续",
|
||||
text = selectFollowingText,
|
||||
icon = Icons.Default.ExpandMore,
|
||||
onClick = { viewModel.selectFromLast() }
|
||||
),
|
||||
ActionItem(
|
||||
text = "添加书签",
|
||||
text = addBookmarkText,
|
||||
icon = Icons.Default.BookmarkAdd,
|
||||
onClick = { viewModel.addBookmarksForSelected() }
|
||||
)
|
||||
@@ -332,35 +354,35 @@ fun TocScreen(
|
||||
onBackClick = onBackClick,
|
||||
onSearchToggle = { viewModel.setSearchMode(it) },
|
||||
onSearchQueryChange = { viewModel.setSearchKey(it) },
|
||||
searchPlaceholder = "搜索章节...",
|
||||
searchPlaceholder = stringResource(R.string.search_chapters),
|
||||
onClearSelection = { viewModel.clearSelection() },
|
||||
dropDownMenuContent = { dismiss ->
|
||||
when (pagerState.currentPage) {
|
||||
0 -> {
|
||||
RoundDropdownMenuItem(
|
||||
text = "使用替换规则",
|
||||
text = stringResource(R.string.use_replace_rule),
|
||||
isSelected = useReplace,
|
||||
onClick = { viewModel.toggleUseReplace() }
|
||||
)
|
||||
RoundDropdownMenuItem(
|
||||
text = "显示字数",
|
||||
text = stringResource(R.string.show_word_count),
|
||||
isSelected = showWordCount,
|
||||
onClick = { viewModel.toggleShowWordCount() }
|
||||
)
|
||||
RoundDropdownMenuItem(
|
||||
text = "反转目录",
|
||||
text = stringResource(R.string.reverse_toc),
|
||||
onClick = { viewModel.reverseToc() }
|
||||
)
|
||||
PillDivider()
|
||||
RoundDropdownMenuItem(
|
||||
text = "替换规则",
|
||||
text = stringResource(R.string.replace_rule_title),
|
||||
onClick = {
|
||||
onOpenReplaceRule(null)
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
RoundDropdownMenuItem(
|
||||
text = "新建替换规则",
|
||||
text = stringResource(R.string.add_replace_rule),
|
||||
onClick = {
|
||||
val scopes = mutableListOf<String>()
|
||||
book?.name?.let { scopes.add(it) }
|
||||
@@ -378,9 +400,9 @@ fun TocScreen(
|
||||
}
|
||||
)
|
||||
if (book?.isLocal == true) {
|
||||
PillHeaderDivider(title = "本地书籍选项")
|
||||
PillHeaderDivider(title = stringResource(R.string.local_book_options))
|
||||
RoundDropdownMenuItem(
|
||||
text = "本地书籍目录规则",
|
||||
text = stringResource(R.string.local_book_toc_rule),
|
||||
onClick = {
|
||||
val intent =
|
||||
Intent(context, TxtTocRuleActivity::class.java).apply {
|
||||
@@ -391,7 +413,7 @@ fun TocScreen(
|
||||
}
|
||||
)
|
||||
RoundDropdownMenuItem(
|
||||
text = "拆分超长章节",
|
||||
text = stringResource(R.string.split_long_chapters),
|
||||
isSelected = viewModel.isSplitLongChapter,
|
||||
onClick = {
|
||||
viewModel.toggleSplitLongChapter()
|
||||
@@ -403,25 +425,27 @@ fun TocScreen(
|
||||
|
||||
else -> {
|
||||
RoundDropdownMenuItem(
|
||||
text = "导出书签为JSON",
|
||||
text = stringResource(R.string.export_bookmarks_json),
|
||||
onClick = {
|
||||
val dateFormat = SimpleDateFormat(
|
||||
"yyyyMMdd_HHmm",
|
||||
Locale.getDefault()
|
||||
).format(Date())
|
||||
val initialName = "${book?.name ?: "书签"}_$dateFormat.json"
|
||||
val initialName =
|
||||
"${book?.name ?: bookmarkDefaultFileName}_$dateFormat.json"
|
||||
exportLauncher.launch(initialName)
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
RoundDropdownMenuItem(
|
||||
text = "导出书签为MarkDown",
|
||||
text = stringResource(R.string.export_bookmarks_markdown),
|
||||
onClick = {
|
||||
val dateFormat = SimpleDateFormat(
|
||||
"yyyyMMdd_HHmm",
|
||||
Locale.getDefault()
|
||||
).format(Date())
|
||||
val initialName = "${book?.name ?: "书签"}_$dateFormat.md"
|
||||
val initialName =
|
||||
"${book?.name ?: bookmarkDefaultFileName}_$dateFormat.md"
|
||||
exportLauncher.launch(initialName)
|
||||
dismiss()
|
||||
}
|
||||
@@ -437,7 +461,10 @@ fun TocScreen(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
AppTabRow(
|
||||
tabTitles = listOf("目录", "书签"),
|
||||
tabTitles = listOf(
|
||||
stringResource(R.string.chapter_list),
|
||||
stringResource(R.string.bookmark)
|
||||
),
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
onTabSelected = { index ->
|
||||
scope.launch {
|
||||
@@ -453,20 +480,20 @@ fun TocScreen(
|
||||
checked = showVolumeMenu,
|
||||
onCheckedChange = { showVolumeMenu = it },
|
||||
imageVector = Icons.AutoMirrored.Filled.FormatListBulleted,
|
||||
contentDescription = "卷管理"
|
||||
contentDescription = stringResource(R.string.volume_management)
|
||||
)
|
||||
RoundDropdownMenu(
|
||||
expanded = showVolumeMenu,
|
||||
onDismissRequest = { showVolumeMenu = false }
|
||||
) {
|
||||
RoundDropdownMenuItem(
|
||||
text = "展开所有卷",
|
||||
text = stringResource(R.string.expand_volume),
|
||||
onClick = {
|
||||
viewModel.expandAllVolumes(); showVolumeMenu = false
|
||||
}
|
||||
)
|
||||
RoundDropdownMenuItem(
|
||||
text = "收起所有卷",
|
||||
text = stringResource(R.string.coll_volume),
|
||||
onClick = {
|
||||
viewModel.collapseAllVolumes(); showVolumeMenu = false
|
||||
}
|
||||
@@ -475,7 +502,7 @@ fun TocScreen(
|
||||
val volumeItems =
|
||||
remember(state.items) { state.items.filter { it.isVolume } }
|
||||
if (volumeItems.isNotEmpty()) {
|
||||
PillHeaderDivider(title = "快速跳转")
|
||||
PillHeaderDivider(title = stringResource(R.string.quick_jump))
|
||||
volumeItems.forEach { uiItem ->
|
||||
RoundDropdownMenuItem(
|
||||
text = uiItem.title,
|
||||
@@ -528,7 +555,10 @@ fun TocScreen(
|
||||
onSelectAll = { viewModel.selectAll() },
|
||||
onSelectInvert = { viewModel.invertSelection() },
|
||||
primaryAction = ActionItem(
|
||||
text = "下载已选 (${state.selectedIds.size})",
|
||||
text = stringResource(
|
||||
R.string.download_selected_count,
|
||||
state.selectedIds.size
|
||||
),
|
||||
icon = Icons.Default.Download,
|
||||
onClick = { viewModel.downloadSelected() }
|
||||
),
|
||||
@@ -818,7 +848,7 @@ fun BookmarkListContent(
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
EmptyMessage(
|
||||
message = "暂无书签"
|
||||
message = stringResource(R.string.no_bookmark)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ import androidx.compose.runtime.snapshotFlow
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseRuleViewModel
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.Book
|
||||
@@ -424,9 +425,13 @@ class TocViewModel(
|
||||
val book = bookState.value ?: return
|
||||
book.tocUrl = newRegex
|
||||
upBookTocRule(book) { error ->
|
||||
if (error != null) context.toastOnUi("更新目录规则失败: ${error.localizedMessage}")
|
||||
if (error != null) {
|
||||
context.toastOnUi(
|
||||
context.getString(R.string.toc_rule_update_failed, error.localizedMessage)
|
||||
)
|
||||
}
|
||||
else {
|
||||
context.toastOnUi("目录规则已更新")
|
||||
context.toastOnUi(R.string.toc_rule_updated)
|
||||
if (ReadBook.book?.bookUrl == book.bookUrl) ReadBook.upMsg(null)
|
||||
}
|
||||
}
|
||||
@@ -437,8 +442,14 @@ class TocViewModel(
|
||||
val newState = !isSplitLongChapter
|
||||
book.setSplitLongChapter(newState)
|
||||
upBookTocRule(book) { error ->
|
||||
if (error != null) context.toastOnUi("设置失败: ${error.localizedMessage}")
|
||||
else context.toastOnUi(if (newState) "已开启长章节拆分" else "已关闭长章节拆分")
|
||||
if (error != null) {
|
||||
context.toastOnUi(context.getString(R.string.setting_failed, error.localizedMessage))
|
||||
} else {
|
||||
context.toastOnUi(
|
||||
if (newState) R.string.split_long_chapters_enabled
|
||||
else R.string.split_long_chapters_disabled
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,16 +478,16 @@ class TocViewModel(
|
||||
val book = bookState.value ?: return@launch
|
||||
val bookmarks = appDb.bookmarkDao.getByBook(book.name, book.author)
|
||||
if (bookmarks.isEmpty()) {
|
||||
context.toastOnUi("没有可导出的书签")
|
||||
context.toastOnUi(R.string.no_bookmarks_to_export)
|
||||
return@launch
|
||||
}
|
||||
BookmarkExporter.exportToUri(
|
||||
context = getApplication(), fileUri = fileUri, bookmarks = bookmarks,
|
||||
isMd = isMd, bookName = book.name, author = book.author
|
||||
)
|
||||
context.toastOnUi("保存成功")
|
||||
context.toastOnUi(R.string.save_success)
|
||||
} catch (e: Exception) {
|
||||
context.toastOnUi("保存失败: ${e.message}")
|
||||
context.toastOnUi(context.getString(R.string.save_failed_with_error, e.message))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +506,7 @@ class TocViewModel(
|
||||
.toList()
|
||||
|
||||
if (selectedItems.isEmpty()) {
|
||||
context.toastOnUi("请选择章节")
|
||||
context.toastOnUi(R.string.select_chapters)
|
||||
return@launch
|
||||
}
|
||||
|
||||
@@ -512,7 +523,7 @@ class TocViewModel(
|
||||
}
|
||||
|
||||
appDb.bookmarkDao.insert(*bookmarks.toTypedArray())
|
||||
context.toastOnUi("已添加 ${bookmarks.size} 个书签")
|
||||
context.toastOnUi(context.getString(R.string.bookmarks_added_count, bookmarks.size))
|
||||
withContext(Dispatchers.Main) {
|
||||
clearSelection()
|
||||
}
|
||||
@@ -525,7 +536,9 @@ class TocViewModel(
|
||||
execute {
|
||||
cacheBookChaptersUseCase.execute(book.bookUrl, indices)
|
||||
}.onSuccess { count ->
|
||||
getApplication<Application>().toastOnUi("开始下载 $count 个章节")
|
||||
getApplication<Application>().toastOnUi(
|
||||
context.getString(R.string.start_downloading_chapters, count)
|
||||
)
|
||||
clearSelection()
|
||||
}
|
||||
}
|
||||
@@ -535,7 +548,7 @@ class TocViewModel(
|
||||
execute {
|
||||
cacheBookChaptersUseCase.execute(book.bookUrl, listOf(index))
|
||||
}.onSuccess {
|
||||
getApplication<Application>().toastOnUi("开始下载章节")
|
||||
getApplication<Application>().toastOnUi(R.string.start_downloading_chapter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,14 +559,16 @@ class TocViewModel(
|
||||
.map { it.id }
|
||||
|
||||
if (targetIndices.isEmpty()) {
|
||||
getApplication<Application>().toastOnUi("所有章节已缓存")
|
||||
getApplication<Application>().toastOnUi(R.string.all_chapters_cached)
|
||||
return
|
||||
}
|
||||
|
||||
execute {
|
||||
cacheBookChaptersUseCase.execute(book.bookUrl, targetIndices)
|
||||
}.onSuccess { count ->
|
||||
getApplication<Application>().toastOnUi("开始下载剩余 $count 个章节")
|
||||
getApplication<Application>().toastOnUi(
|
||||
context.getString(R.string.start_downloading_remaining_chapters, count)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ fun TxtRuleScreen(
|
||||
)
|
||||
|
||||
BatchImportDialog(
|
||||
title = "导入词典规则",
|
||||
title = stringResource(R.string.import_txt_toc_rule),
|
||||
importState = importState,
|
||||
onDismissRequest = { viewModel.cancelImport() },
|
||||
onToggleItem = { viewModel.toggleImportSelection(it) },
|
||||
@@ -262,7 +262,11 @@ fun TxtRuleScreen(
|
||||
)
|
||||
|
||||
RuleListScaffold(
|
||||
title = if (isPickMode) "选择目录规则" else "目录规则",
|
||||
title = if (isPickMode) {
|
||||
stringResource(R.string.select_toc_rule)
|
||||
} else {
|
||||
stringResource(R.string.txt_toc_rule)
|
||||
},
|
||||
state = uiState,
|
||||
onBackClick = { onBackClick() },
|
||||
onSearchToggle = { active ->
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.legado.app.ui.book.toc.rule
|
||||
import android.app.Application
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseRuleViewModel
|
||||
import io.legado.app.data.entities.TxtTocRule
|
||||
import io.legado.app.data.repository.TxtTocRuleRepository
|
||||
@@ -147,14 +148,14 @@ class TxtTocRuleViewModel(
|
||||
fun pasteRule(): TxtTocRule? {
|
||||
val text = context.getClipText()
|
||||
if (text.isNullOrBlank()) {
|
||||
context.toastOnUi("剪贴板没有内容")
|
||||
context.toastOnUi(R.string.clipboard_empty)
|
||||
return null
|
||||
}
|
||||
return try {
|
||||
GSON.fromJsonObject<TxtTocRule>(text).getOrThrow()
|
||||
} catch (e: Exception) {
|
||||
context.toastOnUi("格式不对")
|
||||
context.toastOnUi(R.string.invalid_format)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,15 +168,17 @@ fun BackupConfigScreen(
|
||||
) { uri ->
|
||||
uri?.let {
|
||||
showLoadingDialog = true
|
||||
loadingText = "恢复中…"
|
||||
loadingText = context.getString(R.string.on_restore)
|
||||
scope.launch {
|
||||
try {
|
||||
Restore.restore(context, uri)
|
||||
showLoadingDialog = false
|
||||
snackbarHostState.showSnackbar("恢复成功")
|
||||
snackbarHostState.showSnackbar(context.getString(R.string.restore_success))
|
||||
} catch (e: Exception) {
|
||||
showLoadingDialog = false
|
||||
snackbarHostState.showSnackbar("恢复出错: ${e.localizedMessage}")
|
||||
snackbarHostState.showSnackbar(
|
||||
context.getString(R.string.restore_fail_with_error, e.localizedMessage)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,20 +362,24 @@ fun BackupConfigScreen(
|
||||
value = tempAccount,
|
||||
onValueChange = { tempAccount = it },
|
||||
backgroundColor = LegadoTheme.colorScheme.surface,
|
||||
label = "账号"
|
||||
label = stringResource(R.string.web_dav_account)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
AppTextField(
|
||||
value = tempPassword,
|
||||
onValueChange = { tempPassword = it },
|
||||
backgroundColor = MiuixTheme.colorScheme.surface,
|
||||
label = "密码",
|
||||
label = stringResource(R.string.web_dav_pw),
|
||||
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
||||
trailingIcon = {
|
||||
val image =
|
||||
if (passwordVisible) Icons.Filled.Visibility else Icons.Filled.VisibilityOff
|
||||
val description = if (passwordVisible) "隐藏密码" else "显示密码"
|
||||
val description = if (passwordVisible) {
|
||||
stringResource(R.string.hide_password)
|
||||
} else {
|
||||
stringResource(R.string.show_password)
|
||||
}
|
||||
IconButton(onClick = { passwordVisible = !passwordVisible }) {
|
||||
Icon(imageVector = image, contentDescription = description)
|
||||
}
|
||||
@@ -387,13 +393,13 @@ fun BackupConfigScreen(
|
||||
showWebDavAuthDialog = false
|
||||
scope.launch {
|
||||
showLoadingDialog = true
|
||||
loadingText = "测试中…"
|
||||
loadingText = context.getString(R.string.test_sync_loading_text)
|
||||
val success = viewModel.testWebDav()
|
||||
showLoadingDialog = false
|
||||
if (success) {
|
||||
snackbarHostState.showSnackbar("WebDav 配置正确")
|
||||
snackbarHostState.showSnackbar(context.getString(R.string.test_sync_status_success))
|
||||
} else {
|
||||
snackbarHostState.showSnackbar("WebDav 配置错误")
|
||||
snackbarHostState.showSnackbar(context.getString(R.string.test_sync_status_fail))
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -483,7 +489,7 @@ fun BackupConfigScreen(
|
||||
) {
|
||||
OptionCard(
|
||||
icon = Icons.Default.PhoneAndroid,
|
||||
text = "本地恢复",
|
||||
text = stringResource(R.string.restore_from_local),
|
||||
onClick = {
|
||||
showRestoreOptionSheet = false
|
||||
restoreFileLauncher.launch(arrayOf("application/zip"))
|
||||
@@ -491,20 +497,23 @@ fun BackupConfigScreen(
|
||||
)
|
||||
OptionCard(
|
||||
icon = Icons.Default.Cloud,
|
||||
text = "网络恢复",
|
||||
text = stringResource(R.string.restore_from_network),
|
||||
onClick = {
|
||||
showRestoreOptionSheet = false
|
||||
scope.launch {
|
||||
showLoadingDialog = true
|
||||
loadingText = "加载中"
|
||||
loadingText = context.getString(R.string.loading)
|
||||
try {
|
||||
val names = viewModel.getBackupNames()
|
||||
backupNames = names
|
||||
showRestoreSheet = true
|
||||
} catch (e: Exception) {
|
||||
confirmDialogTitle = "恢复"
|
||||
confirmDialogTitle = context.getString(R.string.restore)
|
||||
confirmDialogText =
|
||||
"WebDavError\n${e.localizedMessage}\n将从本地备份恢复。"
|
||||
context.getString(
|
||||
R.string.webdav_restore_fallback_message,
|
||||
e.localizedMessage
|
||||
)
|
||||
onConfirmAction = {
|
||||
restoreFileLauncher.launch(arrayOf("application/zip"))
|
||||
}
|
||||
@@ -535,19 +544,21 @@ fun BackupConfigScreen(
|
||||
onToggleSelection = {
|
||||
showRestoreSheet = false
|
||||
showLoadingDialog = true
|
||||
loadingText = "恢复中…"
|
||||
loadingText = context.getString(R.string.on_restore)
|
||||
viewModel.restoreWebDav(
|
||||
it,
|
||||
{
|
||||
showLoadingDialog = false
|
||||
scope.launch {
|
||||
snackbarHostState.showSnackbar("恢复成功")
|
||||
snackbarHostState.showSnackbar(context.getString(R.string.restore_success))
|
||||
}
|
||||
},
|
||||
{ error ->
|
||||
showLoadingDialog = false
|
||||
scope.launch {
|
||||
snackbarHostState.showSnackbar("WebDav恢复出错\n$error")
|
||||
snackbarHostState.showSnackbar(
|
||||
context.getString(R.string.webdav_restore_fail, error)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.legado.app.ui.config.backupConfig
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.legado.app.R
|
||||
import io.legado.app.domain.usecase.WebDavBackupUseCase
|
||||
import io.legado.app.help.storage.Backup
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -55,7 +56,7 @@ class BackupConfigViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
onError(e.localizedMessage ?: "备份出错")
|
||||
onError(e.localizedMessage ?: appCtx.getString(R.string.backup_error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,7 +77,7 @@ class BackupConfigViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
onError(e.localizedMessage ?: "恢复出错")
|
||||
onError(e.localizedMessage ?: appCtx.getString(R.string.restore_error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,9 +134,11 @@ fun CoverConfigScreen(
|
||||
val coverCount = CoverConfig.defaultCover.split(",").filter { it.isNotBlank() }.size
|
||||
ClickableSettingItem(
|
||||
title = stringResource(R.string.default_cover),
|
||||
description = if (coverCount > 0) "已选择 $coverCount 张图片" else stringResource(
|
||||
R.string.select_image
|
||||
),
|
||||
description = if (coverCount > 0) {
|
||||
stringResource(R.string.cover_selected_images_count, coverCount)
|
||||
} else {
|
||||
stringResource(R.string.select_image)
|
||||
},
|
||||
onClick = { manageKey = PreferKey.defaultCover }
|
||||
)
|
||||
|
||||
@@ -191,9 +193,11 @@ fun CoverConfigScreen(
|
||||
CoverConfig.defaultCoverDark.split(",").filter { it.isNotBlank() }.size
|
||||
ClickableSettingItem(
|
||||
title = stringResource(R.string.default_cover),
|
||||
description = if (coverCount > 0) "已选择 $coverCount 张图片" else stringResource(
|
||||
R.string.select_image
|
||||
),
|
||||
description = if (coverCount > 0) {
|
||||
stringResource(R.string.cover_selected_images_count, coverCount)
|
||||
} else {
|
||||
stringResource(R.string.select_image)
|
||||
},
|
||||
onClick = { manageKey = PreferKey.defaultCoverDark }
|
||||
)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ fun CoverRuleConfigSheet(
|
||||
imageVector = Icons.Default.Save,
|
||||
onClick = {
|
||||
if (searchUrl.isBlank() || coverRule.isBlank()) {
|
||||
appCtx.toastOnUi("搜索url和cover规则不能为空")
|
||||
appCtx.toastOnUi(R.string.cover_rule_fields_required)
|
||||
} else {
|
||||
val newConfig = ruleState?.copy(
|
||||
enable = enable,
|
||||
|
||||
@@ -72,7 +72,7 @@ fun CustomThemeScreen(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
GlassMediumFlexibleTopAppBar(
|
||||
title = "自定义颜色",
|
||||
title = stringResource(R.string.custom_theme_colors),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = {
|
||||
TopBarNavigationButton(onClick = onBackClick)
|
||||
@@ -91,7 +91,7 @@ fun CustomThemeScreen(
|
||||
item {
|
||||
SplicedColumnGroup {
|
||||
SwitchSettingItem(
|
||||
title = "使用色板生成颜色",
|
||||
title = stringResource(R.string.theme_manage_use_palette_colors),
|
||||
checked = !enableDeepPersonalization,
|
||||
onCheckedChange = { ThemeConfig.enableDeepPersonalization = !it }
|
||||
)
|
||||
@@ -104,7 +104,7 @@ fun CustomThemeScreen(
|
||||
SplicedColumnGroup(title = stringResource(R.string.color_setting)) {
|
||||
// Primary colors
|
||||
ClickableSettingItem(
|
||||
title = "主题色",
|
||||
title = stringResource(R.string.theme_manage_primary_color),
|
||||
option = if (themeColor != 0) "#${Integer.toHexString(themeColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
currentColorKey = "themeColor"
|
||||
@@ -128,7 +128,7 @@ fun CustomThemeScreen(
|
||||
)
|
||||
|
||||
ClickableSettingItem(
|
||||
title = "次要主题色",
|
||||
title = stringResource(R.string.theme_manage_secondary_color),
|
||||
option = if (secondaryThemeColor != 0) "#${Integer.toHexString(secondaryThemeColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
currentColorKey = "secondaryThemeColor"
|
||||
@@ -152,7 +152,7 @@ fun CustomThemeScreen(
|
||||
)
|
||||
|
||||
ClickableSettingItem(
|
||||
title = "主要字体色",
|
||||
title = stringResource(R.string.theme_manage_primary_text_color),
|
||||
option = if (primaryTextColor != 0) "#${Integer.toHexString(primaryTextColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
currentColorKey = "primaryTextColor"
|
||||
@@ -176,7 +176,7 @@ fun CustomThemeScreen(
|
||||
)
|
||||
|
||||
ClickableSettingItem(
|
||||
title = "次要字体色",
|
||||
title = stringResource(R.string.theme_manage_secondary_text_color),
|
||||
option = if (secondaryTextColor != 0) "#${Integer.toHexString(secondaryTextColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
currentColorKey = "secondaryTextColor"
|
||||
@@ -200,7 +200,7 @@ fun CustomThemeScreen(
|
||||
)
|
||||
|
||||
ClickableSettingItem(
|
||||
title = "背景色",
|
||||
title = stringResource(R.string.theme_manage_background_color),
|
||||
option = if (themeBackgroundColor != 0) "#${Integer.toHexString(themeBackgroundColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
currentColorKey = "themeBackgroundColor"
|
||||
@@ -224,7 +224,7 @@ fun CustomThemeScreen(
|
||||
)
|
||||
|
||||
ClickableSettingItem(
|
||||
title = "标签容器色",
|
||||
title = stringResource(R.string.theme_manage_label_container_color),
|
||||
option = if (labelContainerColor != 0) "#${Integer.toHexString(labelContainerColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
currentColorKey = "labelContainerColor"
|
||||
|
||||
+3
-3
@@ -88,7 +88,7 @@ fun DirectLinkUploadBottomSheet(
|
||||
onDismissRequest = { showMenu = false }
|
||||
) {
|
||||
RoundDropdownMenuItem(
|
||||
text = "导入默认",
|
||||
text = stringResource(R.string.import_default_rule),
|
||||
leadingIcon = { Icon(Icons.Default.Download, null) },
|
||||
onClick = {
|
||||
showMenu = false
|
||||
@@ -124,7 +124,7 @@ fun DirectLinkUploadBottomSheet(
|
||||
viewModel.upView(rule)
|
||||
}
|
||||
}.onFailure {
|
||||
context.toastOnUi("剪贴板为空或格式不对")
|
||||
context.toastOnUi(R.string.clipboard_empty_or_invalid)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -186,7 +186,7 @@ fun DirectLinkUploadBottomSheet(
|
||||
if (viewModel.saveDirectLinkRule()) {
|
||||
onDismiss()
|
||||
} else {
|
||||
context.toastOnUi("请填写完整信息")
|
||||
context.toastOnUi(R.string.complete_required_information)
|
||||
}
|
||||
},
|
||||
dismissText = stringResource(R.string.cancel),
|
||||
|
||||
@@ -147,7 +147,7 @@ fun OtherConfigScreen(
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||
} else {
|
||||
Toast.makeText(context, "无需申请", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context, R.string.permission_not_required, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -97,7 +97,7 @@ fun BackgroundImageManageSheet(
|
||||
) {
|
||||
AppIcon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "Add",
|
||||
contentDescription = stringResource(R.string.add),
|
||||
modifier = Modifier.size(48.dp),
|
||||
tint = LegadoTheme.colorScheme.primary
|
||||
)
|
||||
|
||||
@@ -24,8 +24,10 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import io.legado.app.R
|
||||
import io.legado.app.help.config.TagColorGenerator
|
||||
import io.legado.app.ui.theme.LegadoTheme
|
||||
import io.legado.app.ui.widget.components.button.MediumOutlinedIconButton
|
||||
@@ -53,7 +55,7 @@ fun LabelColorManageSheet(
|
||||
AppModalBottomSheet(
|
||||
show = show,
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = "管理标签颜色",
|
||||
title = stringResource(R.string.theme_config_manage_label_colors),
|
||||
startAction = {
|
||||
MediumOutlinedIconButton(
|
||||
onClick = {
|
||||
@@ -84,7 +86,7 @@ fun LabelColorManageSheet(
|
||||
) {
|
||||
items(tagColors.size) { index ->
|
||||
val colorPair = tagColors[index]
|
||||
val label = "标签 ${index + 1}"
|
||||
val label = stringResource(R.string.theme_config_label_color_name, index + 1)
|
||||
NormalCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
containerColor = LegadoTheme.colorScheme.onSheetContent
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.legado.app.ui.config.themeConfig
|
||||
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -24,8 +25,10 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import io.legado.app.R
|
||||
import io.legado.app.ui.theme.LegadoTheme
|
||||
import io.legado.app.ui.widget.components.button.SmallTonalIconButton
|
||||
import io.legado.app.ui.widget.components.card.NormalCard
|
||||
@@ -36,7 +39,7 @@ import java.io.File
|
||||
|
||||
private data class NavIconDestination(
|
||||
val key: String,
|
||||
val label: String,
|
||||
@param:StringRes val labelRes: Int,
|
||||
val path: String,
|
||||
val onSetPath: (String) -> Unit,
|
||||
)
|
||||
@@ -51,10 +54,10 @@ fun NavIconManageSheet(
|
||||
var activeDest by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
val destinations = listOf(
|
||||
NavIconDestination("bookshelf", "书架", ThemeConfig.navIconBookshelf) { ThemeConfig.navIconBookshelf = it },
|
||||
NavIconDestination("explore", "发现", ThemeConfig.navIconExplore) { ThemeConfig.navIconExplore = it },
|
||||
NavIconDestination("rss", "订阅", ThemeConfig.navIconRss) { ThemeConfig.navIconRss = it },
|
||||
NavIconDestination("my", "我的", ThemeConfig.navIconMy) { ThemeConfig.navIconMy = it },
|
||||
NavIconDestination("bookshelf", R.string.bookshelf, ThemeConfig.navIconBookshelf) { ThemeConfig.navIconBookshelf = it },
|
||||
NavIconDestination("explore", R.string.discovery, ThemeConfig.navIconExplore) { ThemeConfig.navIconExplore = it },
|
||||
NavIconDestination("rss", R.string.rss, ThemeConfig.navIconRss) { ThemeConfig.navIconRss = it },
|
||||
NavIconDestination("my", R.string.my, ThemeConfig.navIconMy) { ThemeConfig.navIconMy = it },
|
||||
)
|
||||
|
||||
val selectImage = rememberLauncherForActivityResult(
|
||||
@@ -79,7 +82,7 @@ fun NavIconManageSheet(
|
||||
AppModalBottomSheet(
|
||||
show = show,
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = "导航栏图标",
|
||||
title = stringResource(R.string.theme_config_nav_icons),
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth().padding(bottom = 24.dp)) {
|
||||
Row(
|
||||
@@ -89,6 +92,7 @@ fun NavIconManageSheet(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
destinations.forEach { dest ->
|
||||
val label = stringResource(dest.labelRes)
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
@@ -108,7 +112,7 @@ fun NavIconManageSheet(
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
AsyncImage(
|
||||
model = dest.path,
|
||||
contentDescription = dest.label,
|
||||
contentDescription = label,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Fit
|
||||
)
|
||||
@@ -128,7 +132,10 @@ fun NavIconManageSheet(
|
||||
) {
|
||||
AppIcon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "添加${dest.label}图标",
|
||||
contentDescription = stringResource(
|
||||
R.string.theme_config_add_nav_icon,
|
||||
label
|
||||
),
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = LegadoTheme.colorScheme.primary
|
||||
)
|
||||
@@ -136,7 +143,7 @@ fun NavIconManageSheet(
|
||||
}
|
||||
}
|
||||
AppText(
|
||||
text = dest.label,
|
||||
text = label,
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ fun ThemeConfigScreen(
|
||||
contentColor = MiuixTheme.colorScheme.onPrimary
|
||||
)
|
||||
) {
|
||||
MiuixText("Miuix 目前为测试主题,且不对基于View的界面生效!")
|
||||
MiuixText(stringResource(R.string.theme_config_miuix_experimental_warning))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,8 +420,8 @@ fun ThemeConfigScreen(
|
||||
onCheckedChange = { ThemeConfig.useFloatingBottomBarLiquidGlass = it }
|
||||
)
|
||||
SliderSettingItem(
|
||||
title = "底栏模糊强度",
|
||||
description = "控制液态玻璃的扭曲程度",
|
||||
title = stringResource(R.string.theme_config_bottom_bar_lens_radius),
|
||||
description = stringResource(R.string.theme_config_bottom_bar_lens_radius_summary),
|
||||
value = ThemeConfig.bottomBarLensRadius,
|
||||
defaultValue = 24f,
|
||||
valueRange = 0f..50f,
|
||||
@@ -483,30 +483,30 @@ fun ThemeConfigScreen(
|
||||
}
|
||||
if (ThemeConfig.enableBlur) {
|
||||
SliderSettingItem(
|
||||
title = "顶栏模糊半径",
|
||||
description = "模糊半径越大,系统运行越卡顿",
|
||||
title = stringResource(R.string.theme_manage_top_bar_blur_radius),
|
||||
description = stringResource(R.string.theme_config_blur_radius_performance_summary),
|
||||
value = ThemeConfig.topBarBlurRadius.toFloat(),
|
||||
defaultValue = 24f,
|
||||
valueRange = 0f..30f,
|
||||
onValueChange = { ThemeConfig.topBarBlurRadius = it.toInt() }
|
||||
)
|
||||
SliderSettingItem(
|
||||
title = "底栏模糊半径",
|
||||
description = "模糊半径越大,系统运行越卡顿",
|
||||
title = stringResource(R.string.theme_manage_bottom_bar_blur_radius),
|
||||
description = stringResource(R.string.theme_config_blur_radius_performance_summary),
|
||||
value = ThemeConfig.bottomBarBlurRadius.toFloat(),
|
||||
defaultValue = 8f,
|
||||
valueRange = 0f..10f,
|
||||
onValueChange = { ThemeConfig.bottomBarBlurRadius = it.toInt() }
|
||||
)
|
||||
SliderSettingItem(
|
||||
title = "顶栏模糊透明度",
|
||||
title = stringResource(R.string.theme_manage_top_bar_blur_opacity),
|
||||
value = ThemeConfig.topBarBlurAlpha.toFloat(),
|
||||
defaultValue = 73f,
|
||||
valueRange = 0f..100f,
|
||||
onValueChange = { ThemeConfig.topBarBlurAlpha = it.toInt() }
|
||||
)
|
||||
SliderSettingItem(
|
||||
title = "底栏模糊透明度",
|
||||
title = stringResource(R.string.theme_manage_bottom_bar_blur_opacity),
|
||||
value = ThemeConfig.bottomBarBlurAlpha.toFloat(),
|
||||
defaultValue = 40f,
|
||||
valueRange = 0f..100f,
|
||||
@@ -610,15 +610,15 @@ fun ThemeConfigScreen(
|
||||
|
||||
// Container settings
|
||||
item {
|
||||
SplicedColumnGroup(title = "容器设置") {
|
||||
SplicedColumnGroup(title = stringResource(R.string.theme_manage_section_container)) {
|
||||
SwitchSettingItem(
|
||||
title = "显示分割线",
|
||||
title = stringResource(R.string.show_divider_line),
|
||||
checked = ThemeConfig.enableItemDivider,
|
||||
onCheckedChange = { ThemeConfig.enableItemDivider = it }
|
||||
)
|
||||
if (ThemeConfig.enableItemDivider) {
|
||||
SliderSettingItem(
|
||||
title = "分割线粗细",
|
||||
title = stringResource(R.string.theme_config_divider_width),
|
||||
description = "${ThemeConfig.itemDividerWidth}dp",
|
||||
value = ThemeConfig.itemDividerWidth,
|
||||
defaultValue = 1f,
|
||||
@@ -627,7 +627,7 @@ fun ThemeConfigScreen(
|
||||
onValueChange = { ThemeConfig.itemDividerWidth = it }
|
||||
)
|
||||
SliderSettingItem(
|
||||
title = "分割线长度",
|
||||
title = stringResource(R.string.theme_config_divider_length),
|
||||
description = "${ThemeConfig.itemDividerLength.toInt()}%",
|
||||
value = ThemeConfig.itemDividerLength,
|
||||
defaultValue = 80f,
|
||||
@@ -636,7 +636,7 @@ fun ThemeConfigScreen(
|
||||
onValueChange = { ThemeConfig.itemDividerLength = it }
|
||||
)
|
||||
ClickableSettingItem(
|
||||
title = "分割线颜色",
|
||||
title = stringResource(R.string.tip_divider_color),
|
||||
option = if (ThemeConfig.itemDividerColor != 0) "#${Integer.toHexString(ThemeConfig.itemDividerColor).uppercase()}" else stringResource(R.string.click_to_select),
|
||||
onClick = {
|
||||
showBorderColorPicker = true
|
||||
@@ -659,7 +659,7 @@ fun ThemeConfigScreen(
|
||||
|
||||
// Nav icon settings
|
||||
item {
|
||||
SplicedColumnGroup(title = "导航栏图标设置") {
|
||||
SplicedColumnGroup(title = stringResource(R.string.theme_config_nav_icon_settings)) {
|
||||
val customCount = listOf(
|
||||
ThemeConfig.navIconBookshelf,
|
||||
ThemeConfig.navIconExplore,
|
||||
@@ -667,8 +667,12 @@ fun ThemeConfigScreen(
|
||||
ThemeConfig.navIconMy
|
||||
).count { it.isNotEmpty() }
|
||||
ClickableSettingItem(
|
||||
title = "导航栏图标",
|
||||
description = if (customCount > 0) "已设置 $customCount 个自定义图标" else "使用默认图标",
|
||||
title = stringResource(R.string.theme_config_nav_icons),
|
||||
description = if (customCount > 0) {
|
||||
stringResource(R.string.theme_config_nav_icons_custom_count, customCount)
|
||||
} else {
|
||||
stringResource(R.string.theme_config_nav_icons_default)
|
||||
},
|
||||
onClick = { showNavIconSheet = true }
|
||||
)
|
||||
}
|
||||
@@ -676,10 +680,10 @@ fun ThemeConfigScreen(
|
||||
|
||||
// Theme management
|
||||
item {
|
||||
SplicedColumnGroup(title = "主题管理") {
|
||||
SplicedColumnGroup(title = stringResource(R.string.theme_pack)) {
|
||||
ClickableSettingItem(
|
||||
title = "主题管理",
|
||||
description = "保存、导入、导出主题配置",
|
||||
title = stringResource(R.string.theme_pack),
|
||||
description = stringResource(R.string.theme_pack_s),
|
||||
onClick = onNavigateToThemeManage
|
||||
)
|
||||
}
|
||||
@@ -750,7 +754,7 @@ fun ThemeConfigScreen(
|
||||
startAction = {
|
||||
SmallIconButton(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "清除",
|
||||
contentDescription = stringResource(R.string.clear),
|
||||
onClick = {
|
||||
ThemeConfig.appFontPath = null
|
||||
showFontSheet = false
|
||||
@@ -760,7 +764,7 @@ fun ThemeConfigScreen(
|
||||
endAction = {
|
||||
SmallIconButton(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = "选择文件夹",
|
||||
contentDescription = stringResource(R.string.select_folder),
|
||||
onClick = { fontFolderLauncher.launch(null) }
|
||||
)
|
||||
},
|
||||
@@ -771,7 +775,7 @@ fun ThemeConfigScreen(
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "没有字体文件",
|
||||
text = stringResource(R.string.theme_config_no_font_files),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
|
||||
@@ -79,4 +79,4 @@ class ThemeConfigViewModel : ViewModel() {
|
||||
ThemeConfig.bgImageLight = newPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringArrayResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.legado.app.R
|
||||
import io.legado.app.help.config.ThemeExportData
|
||||
@@ -58,7 +59,7 @@ fun EditThemeSheet(
|
||||
AppModalBottomSheet(
|
||||
show = show,
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = "编辑主题",
|
||||
title = stringResource(R.string.theme_manage_edit_theme),
|
||||
endAction = {
|
||||
MediumIconButton(
|
||||
onClick = {
|
||||
@@ -92,30 +93,30 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Basic settings
|
||||
SectionTitle("基础设置")
|
||||
SectionTitle(stringResource(R.string.theme_manage_section_basic))
|
||||
CompactDropdownSettingItem(
|
||||
title = "主题模式",
|
||||
title = stringResource(R.string.theme_mode),
|
||||
selectedValue = data.themeMode,
|
||||
displayEntries = stringArrayResource(R.array.theme_mode),
|
||||
entryValues = stringArrayResource(R.array.theme_mode_v),
|
||||
onValueChange = { data = data.copy(themeMode = it) }
|
||||
)
|
||||
CompactDropdownSettingItem(
|
||||
title = "调色板风格",
|
||||
title = stringResource(R.string.palette_style),
|
||||
selectedValue = data.paletteStyle,
|
||||
displayEntries = stringArrayResource(R.array.paletteStyle),
|
||||
entryValues = stringArrayResource(R.array.paletteStyle_value),
|
||||
onValueChange = { data = data.copy(paletteStyle = it) }
|
||||
)
|
||||
CompactDropdownSettingItem(
|
||||
title = "Material 版本",
|
||||
title = stringResource(R.string.material_version),
|
||||
selectedValue = data.materialVersion,
|
||||
displayEntries = stringArrayResource(R.array.materialVersion),
|
||||
entryValues = stringArrayResource(R.array.materialVersion_value),
|
||||
onValueChange = { data = data.copy(materialVersion = it) }
|
||||
)
|
||||
CompactDropdownSettingItem(
|
||||
title = "对比度偏好",
|
||||
title = stringResource(R.string.preferred_contrast),
|
||||
selectedValue = data.customContrast,
|
||||
displayEntries = stringArrayResource(R.array.customContrast),
|
||||
entryValues = stringArrayResource(R.array.customContrast_value),
|
||||
@@ -125,36 +126,36 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Colors
|
||||
SectionTitle("颜色设置")
|
||||
SectionTitle(stringResource(R.string.theme_manage_section_colors))
|
||||
CompactSwitchSettingItem(
|
||||
title = "使用色板生成颜色",
|
||||
title = stringResource(R.string.theme_manage_use_palette_colors),
|
||||
checked = !data.enableDeepPersonalization,
|
||||
onCheckedChange = { data = data.copy(enableDeepPersonalization = !it) }
|
||||
)
|
||||
if (data.enableDeepPersonalization) {
|
||||
ColorItem("主题色", data.themeColor) {
|
||||
ColorItem(stringResource(R.string.theme_manage_primary_color), data.themeColor) {
|
||||
currentColorKey = "themeColor"; showColorPicker = true
|
||||
}
|
||||
ColorItem("次要主题色", data.secondaryThemeColor) {
|
||||
ColorItem(stringResource(R.string.theme_manage_secondary_color), data.secondaryThemeColor) {
|
||||
currentColorKey = "secondaryThemeColor"; showColorPicker = true
|
||||
}
|
||||
ColorItem("主要字体色", data.primaryTextColor) {
|
||||
ColorItem(stringResource(R.string.theme_manage_primary_text_color), data.primaryTextColor) {
|
||||
currentColorKey = "primaryTextColor"; showColorPicker = true
|
||||
}
|
||||
ColorItem("次要字体色", data.secondaryTextColor) {
|
||||
ColorItem(stringResource(R.string.theme_manage_secondary_text_color), data.secondaryTextColor) {
|
||||
currentColorKey = "secondaryTextColor"; showColorPicker = true
|
||||
}
|
||||
ColorItem("背景色", data.themeBackgroundColor) {
|
||||
ColorItem(stringResource(R.string.theme_manage_background_color), data.themeBackgroundColor) {
|
||||
currentColorKey = "themeBackgroundColor"; showColorPicker = true
|
||||
}
|
||||
ColorItem("标签容器色", data.labelContainerColor) {
|
||||
ColorItem(stringResource(R.string.theme_manage_label_container_color), data.labelContainerColor) {
|
||||
currentColorKey = "labelContainerColor"; showColorPicker = true
|
||||
}
|
||||
} else {
|
||||
ColorItem("日间种子色", data.cPrimary) {
|
||||
ColorItem(stringResource(R.string.theme_manage_day_seed_color), data.cPrimary) {
|
||||
currentColorKey = "cPrimary"; showColorPicker = true
|
||||
}
|
||||
ColorItem("夜间种子色", data.cNPrimary) {
|
||||
ColorItem(stringResource(R.string.theme_manage_night_seed_color), data.cNPrimary) {
|
||||
currentColorKey = "cNPrimary"; showColorPicker = true
|
||||
}
|
||||
}
|
||||
@@ -162,9 +163,9 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Interface layout
|
||||
SectionTitle("界面布局")
|
||||
SectionTitle(stringResource(R.string.theme_manage_section_layout))
|
||||
CompactSwitchSettingItem(
|
||||
title = "发现",
|
||||
title = stringResource(R.string.theme_manage_show_discovery),
|
||||
checked = data.showDiscovery,
|
||||
onCheckedChange = { data = data.copy(showDiscovery = it) }
|
||||
)
|
||||
@@ -174,41 +175,41 @@ fun EditThemeSheet(
|
||||
onCheckedChange = { data = data.copy(showRss = it) }
|
||||
)
|
||||
CompactSwitchSettingItem(
|
||||
title = "显示底栏",
|
||||
title = stringResource(R.string.show_bottom_nav),
|
||||
checked = data.showBottomView,
|
||||
onCheckedChange = { data = data.copy(showBottomView = it) }
|
||||
)
|
||||
CompactSwitchSettingItem(
|
||||
title = "浮动底栏",
|
||||
title = stringResource(R.string.floating_bottom_bar),
|
||||
checked = data.useFloatingBottomBar,
|
||||
onCheckedChange = { data = data.copy(useFloatingBottomBar = it) }
|
||||
)
|
||||
CompactSwitchSettingItem(
|
||||
title = "状态栏",
|
||||
title = stringResource(R.string.theme_manage_status_bar),
|
||||
checked = data.showStatusBar,
|
||||
onCheckedChange = { data = data.copy(showStatusBar = it) }
|
||||
)
|
||||
CompactSwitchSettingItem(
|
||||
title = "翻页动画",
|
||||
title = stringResource(R.string.theme_manage_page_turn_animation),
|
||||
checked = data.swipeAnimation,
|
||||
onCheckedChange = { data = data.copy(swipeAnimation = it) }
|
||||
)
|
||||
CompactDropdownSettingItem(
|
||||
title = "平板模式",
|
||||
title = stringResource(R.string.tabletInterface),
|
||||
selectedValue = data.tabletInterface,
|
||||
displayEntries = stringArrayResource(R.array.tabletInterface),
|
||||
entryValues = stringArrayResource(R.array.tabletInterface_value),
|
||||
onValueChange = { data = data.copy(tabletInterface = it) }
|
||||
)
|
||||
CompactDropdownSettingItem(
|
||||
title = "标签显示",
|
||||
title = stringResource(R.string.theme_manage_label_visibility),
|
||||
selectedValue = data.labelVisibilityMode,
|
||||
displayEntries = stringArrayResource(R.array.label_vis_mode),
|
||||
entryValues = stringArrayResource(R.array.label_vis_mode_value),
|
||||
onValueChange = { data = data.copy(labelVisibilityMode = it) }
|
||||
)
|
||||
CompactDropdownSettingItem(
|
||||
title = "默认主页",
|
||||
title = stringResource(R.string.default_home_page),
|
||||
selectedValue = data.defaultHomePage,
|
||||
displayEntries = stringArrayResource(R.array.default_home_page),
|
||||
entryValues = stringArrayResource(R.array.default_home_page_value),
|
||||
@@ -218,33 +219,33 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Blur
|
||||
SectionTitle("模糊效果")
|
||||
SectionTitle(stringResource(R.string.theme_manage_section_blur))
|
||||
CompactSwitchSettingItem(
|
||||
title = "启用模糊",
|
||||
title = stringResource(R.string.is_blur_enable),
|
||||
checked = data.enableBlur,
|
||||
onCheckedChange = { data = data.copy(enableBlur = it) }
|
||||
)
|
||||
if (data.enableBlur) {
|
||||
CompactSliderSettingItem(
|
||||
title = "顶栏模糊半径",
|
||||
title = stringResource(R.string.theme_manage_top_bar_blur_radius),
|
||||
value = data.topBarBlurRadius.toFloat(),
|
||||
valueRange = 1f..60f,
|
||||
onValueChange = { data = data.copy(topBarBlurRadius = it.toInt()) }
|
||||
)
|
||||
CompactSliderSettingItem(
|
||||
title = "底栏模糊半径",
|
||||
title = stringResource(R.string.theme_manage_bottom_bar_blur_radius),
|
||||
value = data.bottomBarBlurRadius.toFloat(),
|
||||
valueRange = 1f..60f,
|
||||
onValueChange = { data = data.copy(bottomBarBlurRadius = it.toInt()) }
|
||||
)
|
||||
CompactSliderSettingItem(
|
||||
title = "顶栏透明度",
|
||||
title = stringResource(R.string.theme_manage_top_bar_blur_opacity),
|
||||
value = data.topBarBlurAlpha.toFloat(),
|
||||
valueRange = 0f..255f,
|
||||
onValueChange = { data = data.copy(topBarBlurAlpha = it.toInt()) }
|
||||
)
|
||||
CompactSliderSettingItem(
|
||||
title = "底栏透明度",
|
||||
title = stringResource(R.string.theme_manage_bottom_bar_blur_opacity),
|
||||
value = data.bottomBarBlurAlpha.toFloat(),
|
||||
valueRange = 0f..255f,
|
||||
onValueChange = { data = data.copy(bottomBarBlurAlpha = it.toInt()) }
|
||||
@@ -254,15 +255,15 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Opacity
|
||||
SectionTitle("透明度")
|
||||
SectionTitle(stringResource(R.string.theme_manage_section_opacity))
|
||||
CompactSliderSettingItem(
|
||||
title = "顶栏透明度",
|
||||
title = stringResource(R.string.top_bar_opacity),
|
||||
value = data.topBarOpacity.toFloat(),
|
||||
valueRange = 0f..100f,
|
||||
onValueChange = { data = data.copy(topBarOpacity = it.toInt()) }
|
||||
)
|
||||
CompactSliderSettingItem(
|
||||
title = "底栏透明度",
|
||||
title = stringResource(R.string.bottom_bar_opacity),
|
||||
value = data.bottomBarOpacity.toFloat(),
|
||||
valueRange = 0f..100f,
|
||||
onValueChange = { data = data.copy(bottomBarOpacity = it.toInt()) }
|
||||
@@ -271,9 +272,9 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Container
|
||||
SectionTitle("容器设置")
|
||||
SectionTitle(stringResource(R.string.theme_manage_section_container))
|
||||
CompactSliderSettingItem(
|
||||
title = "容器不透明度",
|
||||
title = stringResource(R.string.container_opacity),
|
||||
value = data.containerOpacity.toFloat(),
|
||||
valueRange = 0f..100f,
|
||||
onValueChange = { data = data.copy(containerOpacity = it.toInt()) }
|
||||
@@ -282,14 +283,14 @@ fun EditThemeSheet(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Other
|
||||
SectionTitle("其他")
|
||||
SectionTitle(stringResource(R.string.other))
|
||||
CompactSwitchSettingItem(
|
||||
title = "纯黑模式",
|
||||
title = stringResource(R.string.pure_black),
|
||||
checked = data.isPureBlack,
|
||||
onCheckedChange = { data = data.copy(isPureBlack = it) }
|
||||
)
|
||||
CompactSwitchSettingItem(
|
||||
title = "弹性顶栏",
|
||||
title = stringResource(R.string.use_flexible_top_bar),
|
||||
checked = data.useFlexibleTopAppBar,
|
||||
onCheckedChange = { data = data.copy(useFlexibleTopAppBar = it) }
|
||||
)
|
||||
|
||||
@@ -83,14 +83,14 @@ fun ThemeManageScreen(
|
||||
if (target != null) {
|
||||
exportTarget = null
|
||||
if (ThemeImportExport.exportSavedThemeToFile(context, target, it)) {
|
||||
context.toastOnUi("主题导出成功")
|
||||
context.toastOnUi(R.string.theme_manage_export_success)
|
||||
} else {
|
||||
context.toastOnUi("主题导出失败")
|
||||
context.toastOnUi(R.string.theme_manage_export_failed)
|
||||
}
|
||||
} else if (ThemeImportExport.exportToFile(context, it)) {
|
||||
context.toastOnUi("主题导出成功")
|
||||
context.toastOnUi(R.string.theme_manage_export_success)
|
||||
} else {
|
||||
context.toastOnUi("主题导出失败")
|
||||
context.toastOnUi(R.string.theme_manage_export_failed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,10 +100,10 @@ fun ThemeManageScreen(
|
||||
) { uri ->
|
||||
uri?.let {
|
||||
if (ThemeImportExport.importFromUri(context, it)) {
|
||||
context.toastOnUi("主题导入成功,部分设置需要重启生效")
|
||||
context.toastOnUi(R.string.theme_manage_import_success)
|
||||
showRestartDialog = true
|
||||
} else {
|
||||
context.toastOnUi("主题导入失败")
|
||||
context.toastOnUi(R.string.theme_manage_import_failed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ fun ThemeManageScreen(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
GlassMediumFlexibleTopAppBar(
|
||||
title = "主题管理",
|
||||
title = stringResource(R.string.theme_pack),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = {
|
||||
TopBarNavigationButton(onClick = onBackClick)
|
||||
@@ -133,24 +133,24 @@ fun ThemeManageScreen(
|
||||
item(span = { GridItemSpan(maxLineSpan) }) {
|
||||
SplicedColumnGroup {
|
||||
ClickableSettingItem(
|
||||
title = "保存当前设置",
|
||||
description = "保存当前主题配置为新主题",
|
||||
title = stringResource(R.string.theme_manage_save_current),
|
||||
description = stringResource(R.string.theme_manage_save_current_summary),
|
||||
onClick = {
|
||||
newThemeName = ""
|
||||
showSaveDialog = true
|
||||
}
|
||||
)
|
||||
ClickableSettingItem(
|
||||
title = "导出当前主题",
|
||||
description = "将当前主题配置导出为JSON文件",
|
||||
title = stringResource(R.string.theme_manage_export_current),
|
||||
description = stringResource(R.string.theme_manage_export_current_summary),
|
||||
onClick = {
|
||||
exportTarget = null
|
||||
exportLauncher.launch("legado_theme_${System.currentTimeMillis()}.json")
|
||||
}
|
||||
)
|
||||
ClickableSettingItem(
|
||||
title = "导入主题配置",
|
||||
description = "从JSON文件导入主题配置",
|
||||
title = stringResource(R.string.theme_manage_import_config),
|
||||
description = stringResource(R.string.theme_manage_import_config_summary),
|
||||
onClick = {
|
||||
importLauncher.launch(arrayOf("application/json"))
|
||||
}
|
||||
@@ -161,7 +161,7 @@ fun ThemeManageScreen(
|
||||
if (savedThemes.isNotEmpty()) {
|
||||
item(span = { GridItemSpan(maxLineSpan) }) {
|
||||
AppText(
|
||||
text = "已保存的主题",
|
||||
text = stringResource(R.string.theme_manage_saved_themes),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 8.dp, bottom = 4.dp)
|
||||
@@ -207,8 +207,8 @@ fun ThemeManageScreen(
|
||||
AppAlertDialog(
|
||||
show = showSaveDialog,
|
||||
onDismissRequest = { showSaveDialog = false },
|
||||
title = "保存主题",
|
||||
confirmText = "保存",
|
||||
title = stringResource(R.string.theme_manage_save_theme),
|
||||
confirmText = stringResource(R.string.theme_manage_save),
|
||||
onConfirm = {
|
||||
if (newThemeName.isNotBlank()) {
|
||||
ThemeImportExport.saveCurrentAsTheme(newThemeName)
|
||||
@@ -216,13 +216,13 @@ fun ThemeManageScreen(
|
||||
showSaveDialog = false
|
||||
}
|
||||
},
|
||||
dismissText = "取消",
|
||||
dismissText = stringResource(R.string.cancel),
|
||||
onDismiss = { showSaveDialog = false },
|
||||
content = {
|
||||
AppTextField(
|
||||
value = newThemeName,
|
||||
onValueChange = { newThemeName = it },
|
||||
placeholder = { AppText(text = "请输入主题名称") },
|
||||
placeholder = { AppText(text = stringResource(R.string.theme_manage_name_hint)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -233,8 +233,8 @@ fun ThemeManageScreen(
|
||||
AppAlertDialog(
|
||||
show = applyTarget != null,
|
||||
onDismissRequest = { applyTarget = null },
|
||||
title = "应用主题",
|
||||
confirmText = "应用",
|
||||
title = stringResource(R.string.theme_manage_apply_theme),
|
||||
confirmText = stringResource(R.string.theme_manage_apply),
|
||||
onConfirm = {
|
||||
applyTarget?.let { theme ->
|
||||
ThemeImportExport.applySavedTheme(theme)
|
||||
@@ -242,17 +242,17 @@ fun ThemeManageScreen(
|
||||
}
|
||||
applyTarget = null
|
||||
},
|
||||
dismissText = "取消",
|
||||
dismissText = stringResource(R.string.cancel),
|
||||
onDismiss = { applyTarget = null },
|
||||
text = "确定应用主题「${applyTarget?.name}」?应用后需要重启才能完全生效。"
|
||||
text = stringResource(R.string.theme_manage_apply_message, applyTarget?.name.orEmpty())
|
||||
)
|
||||
|
||||
// Delete theme dialog
|
||||
AppAlertDialog(
|
||||
show = deleteTarget != null,
|
||||
onDismissRequest = { deleteTarget = null },
|
||||
title = "删除主题",
|
||||
confirmText = "删除",
|
||||
title = stringResource(R.string.theme_manage_delete_theme),
|
||||
confirmText = stringResource(R.string.delete),
|
||||
onConfirm = {
|
||||
deleteTarget?.let { theme ->
|
||||
ThemeImportExport.deleteSavedTheme(theme)
|
||||
@@ -260,9 +260,9 @@ fun ThemeManageScreen(
|
||||
}
|
||||
deleteTarget = null
|
||||
},
|
||||
dismissText = "取消",
|
||||
dismissText = stringResource(R.string.cancel),
|
||||
onDismiss = { deleteTarget = null },
|
||||
text = "确定删除主题「${deleteTarget?.name}」?此操作不可恢复。"
|
||||
text = stringResource(R.string.theme_manage_delete_message, deleteTarget?.name.orEmpty())
|
||||
)
|
||||
|
||||
// Edit theme sheet
|
||||
@@ -323,7 +323,7 @@ private fun SavedThemeItem(
|
||||
.background(lightBg)
|
||||
) {
|
||||
AppText(
|
||||
text = "日间",
|
||||
text = stringResource(R.string.theme_manage_preview_day),
|
||||
style = MaterialTheme.typography.labelMediumEmphasized,
|
||||
color = if (theme.data.primaryTextColor != 0) Color(theme.data.primaryTextColor).copy(alpha = 0.6f)
|
||||
else Color.Black.copy(alpha = 0.5f),
|
||||
@@ -355,7 +355,7 @@ private fun SavedThemeItem(
|
||||
.background(darkBg)
|
||||
) {
|
||||
AppText(
|
||||
text = "夜间",
|
||||
text = stringResource(R.string.theme_manage_preview_night),
|
||||
style = MaterialTheme.typography.labelMediumEmphasized,
|
||||
color = Color.White.copy(alpha = 0.5f),
|
||||
modifier = Modifier
|
||||
|
||||
@@ -41,7 +41,9 @@ import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.legado.app.R
|
||||
import io.legado.app.ui.theme.LegadoTheme
|
||||
import io.legado.app.ui.theme.ThemeResolver
|
||||
import io.legado.app.ui.widget.components.text.AppText
|
||||
@@ -193,7 +195,7 @@ fun AppFloatingActionButtonMenu(
|
||||
tint = Color.White
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text("菜单", color = Color.White)
|
||||
Text(stringResource(R.string.menu), color = Color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.legado.app.R
|
||||
import io.legado.app.ui.theme.LegadoTheme.composeEngine
|
||||
import io.legado.app.ui.theme.ThemeResolver
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -57,10 +59,10 @@ fun AppPullToRefresh(
|
||||
contentPadding = PaddingValues(top = topPadding + 16.dp),
|
||||
pullToRefreshState = miuixRememberPullToRefreshState(),
|
||||
refreshTexts = listOf(
|
||||
"下拉刷新",
|
||||
"松开刷新",
|
||||
"正在刷新",
|
||||
"正在刷新"
|
||||
stringResource(R.string.pull_to_refresh),
|
||||
stringResource(R.string.release_to_refresh),
|
||||
stringResource(R.string.refreshing),
|
||||
stringResource(R.string.refreshing)
|
||||
)
|
||||
) {
|
||||
content()
|
||||
|
||||
@@ -15,9 +15,11 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.legado.app.R
|
||||
import io.legado.app.ui.theme.LegadoTheme
|
||||
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
||||
import io.legado.app.ui.widget.components.card.GlassCard
|
||||
@@ -83,11 +85,15 @@ fun CollapsibleHeader(
|
||||
if (showIcon) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.ExpandMore,
|
||||
contentDescription = if (isCollapsed) "展开" else "折叠",
|
||||
contentDescription = if (isCollapsed) {
|
||||
stringResource(R.string.expand)
|
||||
} else {
|
||||
stringResource(R.string.collapse)
|
||||
},
|
||||
modifier = Modifier.rotate(rotation),
|
||||
tint = LegadoTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ fun ColorPickerSheet(
|
||||
AppModalBottomSheet(
|
||||
show = show,
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = "选择颜色",
|
||||
title = stringResource(R.string.select_color),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -123,7 +123,7 @@ fun ColorPickerSheet(
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = "色值",
|
||||
label = stringResource(R.string.color_value),
|
||||
singleLine = true,
|
||||
isError = isHexInputError,
|
||||
backgroundColor = LegadoTheme.colorScheme.surface,
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<string name="predictive_back_summary">启用系统预见性返回手势</string>
|
||||
<string name="restart_to_apply">重启以应用</string>
|
||||
<string name="custom_theme">自定义主题</string>
|
||||
<string name="custom_theme_colors">自定义颜色</string>
|
||||
<string name="appearance_setting">外观设置</string>
|
||||
<string name="click_to_select">点击选择</string>
|
||||
<string name="compose_related">Compose 相关</string>
|
||||
@@ -106,6 +107,16 @@
|
||||
<string name="origin_format">来源:%s</string>
|
||||
<string name="read_dur_progress">最近:%s</string>
|
||||
<string name="book_name">书名</string>
|
||||
<string name="cover_url">封面链接</string>
|
||||
<string name="fixed_book_type">固定书籍类型</string>
|
||||
<string name="fixed_book_type_summary">书籍更新后不覆盖书籍类型</string>
|
||||
<string name="book_type_label">书籍类型</string>
|
||||
<string name="book_type_text">文本</string>
|
||||
<string name="book_type_audio">音频</string>
|
||||
<string name="book_type_image">图片</string>
|
||||
<string name="add_tag">添加标签</string>
|
||||
<string name="edit_tag">编辑标签</string>
|
||||
<string name="tag">标签</string>
|
||||
<string name="lasted_show">最新 · %s</string>
|
||||
<string name="check_add_bookshelf">是否将《%s》放入书架?</string>
|
||||
<string name="import_books_count">共 %s 个文本文件</string>
|
||||
@@ -130,6 +141,8 @@
|
||||
<string name="pt_auto_download">自动下载最新章节</string>
|
||||
<string name="ps_auto_download">更新书籍时自动下载最新章节</string>
|
||||
<string name="backup_restore">备份与恢复</string>
|
||||
<string name="backup_error">备份出错</string>
|
||||
<string name="restore_error">恢复出错</string>
|
||||
<string name="web_dav_set">WebDav 设置</string>
|
||||
<string name="web_dav_set_import_old">WebDav 设置 • 导入旧版本数据</string>
|
||||
<string name="backup">备份</string>
|
||||
@@ -147,6 +160,11 @@
|
||||
<string name="on_restore">正在恢复</string>
|
||||
<string name="restore_success">恢复成功</string>
|
||||
<string name="restore_fail">恢复失败</string>
|
||||
<string name="restore_fail_with_error">恢复出错:%1$s</string>
|
||||
<string name="restore_from_local">本地恢复</string>
|
||||
<string name="restore_from_network">网络恢复</string>
|
||||
<string name="webdav_restore_fallback_message">WebDAV 出错\n%1$s\n将从本地备份恢复。</string>
|
||||
<string name="webdav_restore_fail">WebDAV 恢复出错\n%1$s</string>
|
||||
<string name="screen_direction">屏幕方向</string>
|
||||
<string name="screen_sensor">跟随传感器</string>
|
||||
<string name="screen_landscape">横向</string>
|
||||
@@ -170,6 +188,13 @@
|
||||
<string name="audio_pause">播放暂停</string>
|
||||
<string name="text_return">返回</string>
|
||||
<string name="refresh">刷新</string>
|
||||
<string name="pull_to_refresh">下拉刷新</string>
|
||||
<string name="release_to_refresh">松开刷新</string>
|
||||
<string name="refreshing">正在刷新</string>
|
||||
<string name="expand">展开</string>
|
||||
<string name="collapse">折叠</string>
|
||||
<string name="select_color">选择颜色</string>
|
||||
<string name="color_value">色值</string>
|
||||
<string name="start">开始</string>
|
||||
<string name="stop">停止</string>
|
||||
<string name="pause">暂停</string>
|
||||
@@ -645,6 +670,8 @@
|
||||
<string name="tts">TTS</string>
|
||||
<string name="web_dav_pw">WebDav 密码</string>
|
||||
<string name="web_dav_pw_s">输入你的 WebDav 授权密码</string>
|
||||
<string name="show_password">显示密码</string>
|
||||
<string name="hide_password">隐藏密码</string>
|
||||
<string name="web_dav_url_s">输入你的WebDav服务器地址</string>
|
||||
<string name="web_dav_url">WebDav 服务器地址</string>
|
||||
<string name="web_dav_account">WebDav 账号</string>
|
||||
@@ -945,6 +972,10 @@
|
||||
<string name="pref_anti_alias_summary">绘制图片时抗锯齿</string>
|
||||
<string name="upload_url">上传 URL</string>
|
||||
<string name="download_url_rule">下载 URL 规则</string>
|
||||
<string name="clipboard_empty">剪贴板没有内容</string>
|
||||
<string name="clipboard_empty_or_invalid">剪贴板为空或格式不正确</string>
|
||||
<string name="invalid_format">格式不正确</string>
|
||||
<string name="complete_required_information">请填写完整信息</string>
|
||||
<string name="sort_by_respondTime">响应时间排序</string>
|
||||
<string name="respondTime">响应时间:%1$d ms</string>
|
||||
<string name="export_success">导出成功</string>
|
||||
@@ -1040,6 +1071,8 @@
|
||||
<string name="search_via_url">搜索URL</string>
|
||||
<string name="cover_rule_edit">封面规则</string>
|
||||
<string name="cover_rule_summary">进入详情页时使用封面规则重新获取封面</string>
|
||||
<string name="cover_rule_fields_required">搜索 URL 和封面规则不能为空</string>
|
||||
<string name="cover_selected_images_count">已选择 %1$d 张图片</string>
|
||||
<string name="scroll_to_dur_source">定位到当前书源</string>
|
||||
<string name="sys_tts_config">系统 TTS 设置</string>
|
||||
<string name="sys_tts_config_summary">打开系统 TTS 设置界面</string>
|
||||
@@ -1137,6 +1170,7 @@
|
||||
<string name="same_title_removed">移除重复标题</string>
|
||||
<string name="update_book_fail">更新失败</string>
|
||||
<string name="notification_permission_rationale">阅读需要发送通知来显示朗读控制和下载进度。</string>
|
||||
<string name="permission_not_required">无需申请</string>
|
||||
<string name="webdav_after_local_restore_confirm">WebDav 书源比本地新,是否恢复</string>
|
||||
<string name="c_whitelist">白名单(contentWhitelist)</string>
|
||||
<string name="c_blacklist">黑名单(contentBlacklist)</string>
|
||||
@@ -1223,6 +1257,23 @@
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="create_heap_dump">创建堆转储</string>
|
||||
<string name="about_privacy_policy_title">隐私政策</string>
|
||||
<string name="about_license_title">许可证</string>
|
||||
<string name="about_disclaimer_title">免责声明</string>
|
||||
<string name="about_installed_version_title">当前版本</string>
|
||||
<string name="about_current_version">当前版本</string>
|
||||
<string name="about_new_version">新版本</string>
|
||||
<string name="about_update_channel">渠道</string>
|
||||
<string name="about_update_action">更新</string>
|
||||
<string name="about_backup_dir_not_set">未设置备份目录</string>
|
||||
<string name="about_log_recording_disabled">未开启日志记录,请去其他设置里打开记录日志</string>
|
||||
<string name="about_saved_to_backup_dir">已保存至备份目录</string>
|
||||
<string name="about_heap_dump_recording_disabled">未开启堆转储记录,请去其他设置里打开记录堆转储</string>
|
||||
<string name="about_heap_dump_creating">开始创建堆转储</string>
|
||||
<string name="about_heap_dump_not_found">未找到堆转储文件</string>
|
||||
<string name="about_download_info_incomplete">下载信息不完整</string>
|
||||
<string name="about_no_data">没有数据</string>
|
||||
<string name="about_start_download">开始下载: %s</string>
|
||||
<string name="crash_report">崩溃报告</string>
|
||||
<string name="crash_report_message">应用发生崩溃。报告问题时,请复制以下错误信息。</string>
|
||||
<string name="crash_report_empty">未找到崩溃信息。</string>
|
||||
@@ -1284,6 +1335,65 @@
|
||||
<string name="ungroup">未分组</string>
|
||||
<string name="dynamic_colors">动态取色</string>
|
||||
<string name="dynamic_colors_summary">使用基于壁纸的主题颜色</string>
|
||||
<string name="theme_manage_export_success">主题导出成功</string>
|
||||
<string name="theme_manage_export_failed">主题导出失败</string>
|
||||
<string name="theme_manage_import_success">主题导入成功,部分设置需要重启生效</string>
|
||||
<string name="theme_manage_import_failed">主题导入失败</string>
|
||||
<string name="theme_manage_save_current">保存当前设置</string>
|
||||
<string name="theme_manage_save_current_summary">保存当前主题配置为新主题</string>
|
||||
<string name="theme_manage_export_current">导出当前主题</string>
|
||||
<string name="theme_manage_export_current_summary">将当前主题配置导出为 JSON 文件</string>
|
||||
<string name="theme_manage_import_config">导入主题配置</string>
|
||||
<string name="theme_manage_import_config_summary">从 JSON 文件导入主题配置</string>
|
||||
<string name="theme_manage_saved_themes">已保存的主题</string>
|
||||
<string name="theme_manage_save_theme">保存主题</string>
|
||||
<string name="theme_manage_save">保存</string>
|
||||
<string name="theme_manage_name_hint">请输入主题名称</string>
|
||||
<string name="theme_manage_apply_theme">应用主题</string>
|
||||
<string name="theme_manage_apply">应用</string>
|
||||
<string name="theme_manage_apply_message">确定应用主题「%s」?应用后需要重启才能完全生效。</string>
|
||||
<string name="theme_manage_delete_theme">删除主题</string>
|
||||
<string name="theme_manage_delete_message">确定删除主题「%s」?此操作不可恢复。</string>
|
||||
<string name="theme_manage_preview_day">日间</string>
|
||||
<string name="theme_manage_preview_night">夜间</string>
|
||||
<string name="theme_manage_edit_theme">编辑主题</string>
|
||||
<string name="theme_manage_section_basic">基础设置</string>
|
||||
<string name="theme_manage_section_colors">颜色设置</string>
|
||||
<string name="theme_manage_use_palette_colors">使用色板生成颜色</string>
|
||||
<string name="theme_manage_primary_color">主题色</string>
|
||||
<string name="theme_manage_secondary_color">次要主题色</string>
|
||||
<string name="theme_manage_primary_text_color">主要字体色</string>
|
||||
<string name="theme_manage_secondary_text_color">次要字体色</string>
|
||||
<string name="theme_manage_background_color">背景色</string>
|
||||
<string name="theme_manage_label_container_color">标签容器色</string>
|
||||
<string name="theme_manage_day_seed_color">日间种子色</string>
|
||||
<string name="theme_manage_night_seed_color">夜间种子色</string>
|
||||
<string name="theme_manage_section_layout">界面布局</string>
|
||||
<string name="theme_manage_show_discovery">发现</string>
|
||||
<string name="theme_manage_status_bar">状态栏</string>
|
||||
<string name="theme_manage_page_turn_animation">翻页动画</string>
|
||||
<string name="theme_manage_label_visibility">标签显示</string>
|
||||
<string name="theme_manage_section_blur">模糊效果</string>
|
||||
<string name="theme_manage_top_bar_blur_radius">顶栏模糊半径</string>
|
||||
<string name="theme_manage_bottom_bar_blur_radius">底栏模糊半径</string>
|
||||
<string name="theme_manage_top_bar_blur_opacity">顶栏模糊不透明度</string>
|
||||
<string name="theme_manage_bottom_bar_blur_opacity">底栏模糊不透明度</string>
|
||||
<string name="theme_manage_section_opacity">透明度</string>
|
||||
<string name="theme_manage_section_container">容器设置</string>
|
||||
<string name="theme_config_manage_label_colors">管理标签颜色</string>
|
||||
<string name="theme_config_label_color_name">标签 %1$d</string>
|
||||
<string name="theme_config_miuix_experimental_warning">Miuix 目前为测试主题,且不对基于 View 的界面生效。</string>
|
||||
<string name="theme_config_bottom_bar_lens_radius">底栏模糊强度</string>
|
||||
<string name="theme_config_bottom_bar_lens_radius_summary">控制液态玻璃的扭曲程度</string>
|
||||
<string name="theme_config_blur_radius_performance_summary">模糊半径越大,系统运行越卡顿</string>
|
||||
<string name="theme_config_divider_width">分割线粗细</string>
|
||||
<string name="theme_config_divider_length">分割线长度</string>
|
||||
<string name="theme_config_nav_icon_settings">导航栏图标设置</string>
|
||||
<string name="theme_config_nav_icons">导航栏图标</string>
|
||||
<string name="theme_config_nav_icons_custom_count">已设置 %1$d 个自定义图标</string>
|
||||
<string name="theme_config_nav_icons_default">使用默认图标</string>
|
||||
<string name="theme_config_add_nav_icon">添加%1$s图标</string>
|
||||
<string name="theme_config_no_font_files">没有字体文件</string>
|
||||
<string name="input_value_range">输入数值(%1$d-%2$d)</string>
|
||||
<string name="change_icon_success">图标已修改</string>
|
||||
<string name="replace_rule_title_setting">配置替换规则</string>
|
||||
@@ -1331,6 +1441,38 @@
|
||||
<string name="abi_arm64_v8a">ABI: arm64-v8a</string>
|
||||
<string name="download_link">下载链接</string>
|
||||
<string name="no_bookmark">暂无书签</string>
|
||||
<string name="bookmark_management">书签管理</string>
|
||||
<string name="locate_current_reading">定位至当前阅读</string>
|
||||
<string name="move_to_top">移至顶部</string>
|
||||
<string name="move_to_bottom">移至底部</string>
|
||||
<string name="invert_selection">反选</string>
|
||||
<string name="select_following">选择后续</string>
|
||||
<string name="search_chapters">搜索章节…</string>
|
||||
<string name="use_replace_rule">使用替换规则</string>
|
||||
<string name="show_word_count">显示字数</string>
|
||||
<string name="local_book_options">本地书籍选项</string>
|
||||
<string name="local_book_toc_rule">本地书籍目录规则</string>
|
||||
<string name="select_toc_rule">选择目录规则</string>
|
||||
<string name="split_long_chapters">拆分超长章节</string>
|
||||
<string name="export_bookmarks_json">导出书签为 JSON</string>
|
||||
<string name="export_bookmarks_markdown">导出书签为 Markdown</string>
|
||||
<string name="volume_management">卷管理</string>
|
||||
<string name="quick_jump">快速跳转</string>
|
||||
<string name="download_selected_count">下载已选(%1$d)</string>
|
||||
<string name="toc_rule_update_failed">更新目录规则失败:%1$s</string>
|
||||
<string name="toc_rule_updated">目录规则已更新</string>
|
||||
<string name="setting_failed">设置失败:%1$s</string>
|
||||
<string name="split_long_chapters_enabled">已开启长章节拆分</string>
|
||||
<string name="split_long_chapters_disabled">已关闭长章节拆分</string>
|
||||
<string name="no_bookmarks_to_export">没有可导出的书签</string>
|
||||
<string name="save_success">保存成功</string>
|
||||
<string name="save_failed_with_error">保存失败:%1$s</string>
|
||||
<string name="select_chapters">请选择章节</string>
|
||||
<string name="bookmarks_added_count">已添加 %1$d 个书签</string>
|
||||
<string name="start_downloading_chapters">开始下载 %1$d 个章节</string>
|
||||
<string name="start_downloading_chapter">开始下载章节</string>
|
||||
<string name="all_chapters_cached">所有章节已缓存</string>
|
||||
<string name="start_downloading_remaining_chapters">开始下载剩余 %1$d 个章节</string>
|
||||
<string name="read_end">已读完</string>
|
||||
<string name="system_engine">系统引擎</string>
|
||||
<string name="copy_from">剪切板导入</string>
|
||||
|
||||
@@ -13,17 +13,17 @@
|
||||
</string-array>
|
||||
|
||||
<string-array name="layout_type">
|
||||
<item>列表</item>
|
||||
<item>单列</item>
|
||||
<item>双列</item>
|
||||
<item>瀑布</item>
|
||||
<item>三列</item>
|
||||
<item>List</item>
|
||||
<item>Single Column</item>
|
||||
<item>Two Columns</item>
|
||||
<item>Waterfall</item>
|
||||
<item>Three Columns</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="rss_type">
|
||||
<item>网页</item>
|
||||
<item>图片</item>
|
||||
<item>视频</item>
|
||||
<item>Web Page</item>
|
||||
<item>Image</item>
|
||||
<item>Video</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="group_style">
|
||||
|
||||
+261
-119
@@ -38,7 +38,8 @@
|
||||
<string name="predictive_back_summary">Enable system predictive back gestures</string>
|
||||
<string name="restart_to_apply">Restart to apply</string>
|
||||
<string name="custom_theme">Custom Theme</string>
|
||||
<string name="appearance_setting">外观设置</string>
|
||||
<string name="custom_theme_colors">Custom Colors</string>
|
||||
<string name="appearance_setting">Appearance Settings</string>
|
||||
<string name="click_to_select">Click to select</string>
|
||||
<string name="compose_related">Compose Related</string>
|
||||
<string name="use_flexible_top_bar">Use Flexible App Top Bar</string>
|
||||
@@ -92,25 +93,25 @@
|
||||
<string name="setting">Settings</string>
|
||||
<string name="theme_setting">Theme Settings</string>
|
||||
<string name="theme_setting_s">Some settings related to interface or color</string>
|
||||
<string name="personalization_setting">深度个性化设置</string>
|
||||
<string name="personalization_setting_s">字体等深度个性化设置</string>
|
||||
<string name="theme_pack">主题管理</string>
|
||||
<string name="theme_pack_s">管理、导入导出完整主题包</string>
|
||||
<string name="font_setting">字体设置</string>
|
||||
<string name="font_setting_s">选择应用字体</string>
|
||||
<string name="color_setting">颜色设置</string>
|
||||
<string name="reset_color">重置颜色</string>
|
||||
<string name="top_bar_color">应用栏颜色</string>
|
||||
<string name="nav_bar_color">导航栏颜色</string>
|
||||
<string name="font_color">字体颜色</string>
|
||||
<string name="background_color">背景颜色</string>
|
||||
<string name="border_setting">边框设置</string>
|
||||
<string name="show_container_border">显示容器边框</string>
|
||||
<string name="border_width">边框粗细</string>
|
||||
<string name="border_style">边框样式</string>
|
||||
<string name="solid_border">实线</string>
|
||||
<string name="dashed_border">虚线</string>
|
||||
<string name="dash_gap">虚线间隔</string>
|
||||
<string name="personalization_setting">Advanced Personalization</string>
|
||||
<string name="personalization_setting_s">Fine-tune fonts and other appearance details</string>
|
||||
<string name="theme_pack">Theme Management</string>
|
||||
<string name="theme_pack_s">Manage, import, and export complete theme packs</string>
|
||||
<string name="font_setting">Font Settings</string>
|
||||
<string name="font_setting_s">Choose the app font</string>
|
||||
<string name="color_setting">Color Settings</string>
|
||||
<string name="reset_color">Reset Colors</string>
|
||||
<string name="top_bar_color">App Bar Color</string>
|
||||
<string name="nav_bar_color">Navigation Bar Color</string>
|
||||
<string name="font_color">Font Color</string>
|
||||
<string name="background_color">Background Color</string>
|
||||
<string name="border_setting">Border Settings</string>
|
||||
<string name="show_container_border">Show Container Border</string>
|
||||
<string name="border_width">Border Width</string>
|
||||
<string name="border_style">Border Style</string>
|
||||
<string name="solid_border">Solid</string>
|
||||
<string name="dashed_border">Dashed</string>
|
||||
<string name="dash_gap">Dash Gap</string>
|
||||
<string name="other_setting">Other Settings</string>
|
||||
<string name="other_setting_s">Language • Other Settings</string>
|
||||
<string name="about">About</string>
|
||||
@@ -125,6 +126,16 @@
|
||||
<string name="origin_format">Origin: %s</string>
|
||||
<string name="read_dur_progress">Origin: %s</string>
|
||||
<string name="book_name">Title</string>
|
||||
<string name="cover_url">Cover URL</string>
|
||||
<string name="fixed_book_type">Lock Book Type</string>
|
||||
<string name="fixed_book_type_summary">Do not overwrite the book type when the book updates</string>
|
||||
<string name="book_type_label">Book Type</string>
|
||||
<string name="book_type_text">Text</string>
|
||||
<string name="book_type_audio">Audio</string>
|
||||
<string name="book_type_image">Image</string>
|
||||
<string name="add_tag">Add Tag</string>
|
||||
<string name="edit_tag">Edit Tag</string>
|
||||
<string name="tag">Tag</string>
|
||||
<string name="lasted_show">Latest: %s</string>
|
||||
<string name="check_add_bookshelf">Would you like to add %s to your Bookshelf?</string>
|
||||
<string name="import_books_count">%s text file(s) in total</string>
|
||||
@@ -151,6 +162,8 @@
|
||||
<string name="pt_auto_download">Auto-download</string>
|
||||
<string name="ps_auto_download">Download the latest chapters automatically when updating books</string>
|
||||
<string name="backup_restore">Backup and Restore</string>
|
||||
<string name="backup_error">Backup failed</string>
|
||||
<string name="restore_error">Restore failed</string>
|
||||
<string name="web_dav_set">WebDAV settings</string>
|
||||
<string name="web_dav_set_import_old">WebDAV settings • Import legacy data</string>
|
||||
<string name="backup">Backup</string>
|
||||
@@ -168,6 +181,11 @@
|
||||
<string name="on_restore">Restoring</string>
|
||||
<string name="restore_success">Restore succeed</string>
|
||||
<string name="restore_fail">Backup failed</string>
|
||||
<string name="restore_fail_with_error">Restore failed: %1$s</string>
|
||||
<string name="restore_from_local">Restore from Local</string>
|
||||
<string name="restore_from_network">Restore from Network</string>
|
||||
<string name="webdav_restore_fallback_message">WebDAV error\n%1$s\nRestore from a local backup instead.</string>
|
||||
<string name="webdav_restore_fail">WebDAV restore failed\n%1$s</string>
|
||||
<string name="screen_direction">Screen Orientation</string>
|
||||
<string name="screen_sensor">Auto(sensor)</string>
|
||||
<string name="screen_landscape">Landscape</string>
|
||||
@@ -191,6 +209,13 @@
|
||||
<string name="audio_pause">Pause</string>
|
||||
<string name="text_return">Back</string>
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="pull_to_refresh">Pull to refresh</string>
|
||||
<string name="release_to_refresh">Release to refresh</string>
|
||||
<string name="refreshing">Refreshing</string>
|
||||
<string name="expand">Expand</string>
|
||||
<string name="collapse">Collapse</string>
|
||||
<string name="select_color">Select Color</string>
|
||||
<string name="color_value">Color Value</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="pause">Pause</string>
|
||||
@@ -643,12 +668,12 @@
|
||||
<string name="bg_image">Background Images</string>
|
||||
<string name="bg_color">Background color</string>
|
||||
<string name="text_color">Text Color</string>
|
||||
<string name="header_color">页眉</string>
|
||||
<string name="footer_color">页脚</string>
|
||||
<string name="header_font">设置字体</string>
|
||||
<string name="footer_font">页脚字体</string>
|
||||
<string name="header_font_size">设置字号</string>
|
||||
<string name="footer_font_size">页脚字号</string>
|
||||
<string name="header_color">Header</string>
|
||||
<string name="footer_color">Footer</string>
|
||||
<string name="header_font">Header Font</string>
|
||||
<string name="footer_font">Footer Font</string>
|
||||
<string name="header_font_size">Header Font Size</string>
|
||||
<string name="footer_font_size">Footer Font Size</string>
|
||||
<string name="select_image">Select a picture</string>
|
||||
<string name="group_manage">Group Management</string>
|
||||
<string name="group_select">Group selection</string>
|
||||
@@ -671,6 +696,8 @@
|
||||
<string name="tts">TTS</string>
|
||||
<string name="web_dav_pw">WebDAV password</string>
|
||||
<string name="web_dav_pw_s">Input you WebDAV authorized password</string>
|
||||
<string name="show_password">Show password</string>
|
||||
<string name="hide_password">Hide password</string>
|
||||
<string name="web_dav_url">WebDAV Server Address</string>
|
||||
<string name="web_dav_url_s">Input your WebDAV server address</string>
|
||||
<string name="web_dav_account">WebDAV Account</string>
|
||||
@@ -770,11 +797,11 @@
|
||||
<string name="contact">Contact</string>
|
||||
<string name="license">License</string>
|
||||
<string name="other">More Settings</string>
|
||||
<string name="official_account">开源阅读</string>
|
||||
<string name="official_account">Open Source Reading</string>
|
||||
<string name="follow_official_account">Follow WeChat Official Accounts</string>
|
||||
<string name="wechat">WeChat</string>
|
||||
<string name="thanks">Supporting me will be appreciated</string>
|
||||
<string name="about_official_account">Official Accounts[开源阅读]</string>
|
||||
<string name="about_official_account">Official Account [Open Source Reading]</string>
|
||||
<string name="source_auto_changing">Changing source</string>
|
||||
<string name="click_to_apply">Tap to join</string>
|
||||
<string name="middle">Middle</string>
|
||||
@@ -818,7 +845,7 @@
|
||||
<string name="starting_download">Starting download</string>
|
||||
<string name="already_in_download">This book is already in Download list</string>
|
||||
<string name="click_to_open">Click to open</string>
|
||||
<string name="follow_public_account_summary">Follow [开源阅读] to support me by clicking on ads</string>
|
||||
<string name="follow_public_account_summary">Follow [Open Source Reading] to support me by clicking on ads</string>
|
||||
<string name="weChat_appreciation_code">WeChat Tipping Code</string>
|
||||
<string name="alipay">AliPay</string>
|
||||
<string name="alipay_red_envelope_search_code">AliPay red envelope search code</string>
|
||||
@@ -849,7 +876,7 @@
|
||||
<string name="language">Language</string>
|
||||
<string name="import_rss_source">Import rss source</string>
|
||||
<string name="donate_summary">Your donation makes this app better</string>
|
||||
<string name="about_summary">Wechat official account [开源阅读软件]</string>
|
||||
<string name="about_summary">WeChat official account [Open Source Reading]</string>
|
||||
<string name="read_record">Read Record</string>
|
||||
<string name="del_read_record">Delete Read record</string>
|
||||
<string name="read_record_summary">Read record summary</string>
|
||||
@@ -976,6 +1003,10 @@
|
||||
<string name="pref_anti_alias_summary">Anti-Aliasing when draw picture</string>
|
||||
<string name="upload_url">upload URL</string>
|
||||
<string name="download_url_rule">downloadUrlRule(downloadUrls)</string>
|
||||
<string name="clipboard_empty">Clipboard is empty</string>
|
||||
<string name="clipboard_empty_or_invalid">Clipboard is empty or has an invalid format</string>
|
||||
<string name="invalid_format">Invalid format</string>
|
||||
<string name="complete_required_information">Fill in all required information</string>
|
||||
<string name="export_success">export success</string>
|
||||
<string name="path">path</string>
|
||||
<string name="direct_link_upload_rule">Direct Link Upload Rules</string>
|
||||
@@ -1042,7 +1073,7 @@
|
||||
<string name="scope_title">Act on the title</string>
|
||||
<string name="scope_content">Act on the content</string>
|
||||
<string name="join_qq_channel">Join QQ channel</string>
|
||||
<string name="qq_channel_summary">点击加入阅读QQ频道</string>
|
||||
<string name="qq_channel_summary">Tap to join the Reading QQ channel</string>
|
||||
<string name="menu_refresh_dur">Refresh the current chapter</string>
|
||||
<string name="menu_refresh_after">Refresh the chapter after</string>
|
||||
<string name="menu_refresh_all">Refresh all chapters</string>
|
||||
@@ -1057,7 +1088,7 @@
|
||||
<string name="welcome_style">Launch interface style</string>
|
||||
<string name="welcome_style_summary">Startup screen image and whether to display text, etc.</string>
|
||||
<string name="show_welcome_text">Display text</string>
|
||||
<string name="welcome_text">阅读|享受美好时光</string>
|
||||
<string name="welcome_text">Read | Enjoy the Moment</string>
|
||||
<string name="custom_welcome">Customize the welcome page</string>
|
||||
<string name="custom_welcome_summary">Whether to use a customized welcome page</string>
|
||||
<string name="show_icon">Show icon</string>
|
||||
@@ -1071,6 +1102,8 @@
|
||||
<string name="search_via_url">Search via URL</string>
|
||||
<string name="cover_rule_edit">Cover Rules</string>
|
||||
<string name="cover_rule_summary">Use the cover rule to retrieve the cover when entering the details page</string>
|
||||
<string name="cover_rule_fields_required">Search URL and cover rule cannot be empty</string>
|
||||
<string name="cover_selected_images_count">%1$d images selected</string>
|
||||
<string name="scroll_to_dur_source">Navigate to the current book source</string>
|
||||
<string name="sys_tts_config">System tts Settings</string>
|
||||
<string name="sys_tts_config_summary">Open the system tts settings interface</string>
|
||||
@@ -1103,7 +1136,7 @@
|
||||
<!-- string end -->
|
||||
<string name="error_decode_bitmap">Fail to decode bitmap</string>
|
||||
<string name="error_image_url_empty">Image URL is empty, check replacement rules</string>
|
||||
<string name="variable_comment">变量说明(variableComment)</string>
|
||||
<string name="variable_comment">Variable Description (variableComment)</string>
|
||||
<string name="remote_book">Remote book</string>
|
||||
<string name="reading_time_sort">Sort by reading duration</string>
|
||||
<string name="last_read_time_sort">Sort by read time</string>
|
||||
@@ -1116,8 +1149,8 @@
|
||||
<string name="show_add_to_shelf_alert_title">Prompt to Add to Bookshelf When Return</string>
|
||||
<string name="show_add_to_shelf_alert_summary">Prompt to add to bookshelf when return from reading books that are not on the bookshelf</string>
|
||||
<string name="review">Review</string>
|
||||
<string name="rule_avatar">段评发布者头像(avatarRule)</string>
|
||||
<string name="rule_review_url">段评URL(reviewUrl)</string>
|
||||
<string name="rule_avatar">Paragraph Review Author Avatar (avatarRule)</string>
|
||||
<string name="rule_review_url">Paragraph Review URL (reviewUrl)</string>
|
||||
<string name="rule_review_content">Paragraph review content(contentRule)</string>
|
||||
<string name="rule_post_time">Release time of paragraph comments(postTimeRule)</string>
|
||||
<string name="rule_review_quote">Paragraph comment replied to URL(reviewQuoteUrl)</string>
|
||||
@@ -1167,28 +1200,29 @@
|
||||
<string name="same_title_removed">Remove Duplicate Title</string>
|
||||
<string name="update_book_fail">Update failed</string>
|
||||
<string name="notification_permission_rationale">Reading requires sending notifications to show reading control and download progress</string>
|
||||
<string name="permission_not_required">Permission not required</string>
|
||||
<string name="webdav_after_local_restore_confirm">The WebDAV book source is newer than the local one. Do you want to restore it?</string>
|
||||
<string name="c_whitelist">白名单(contentWhitelist)</string>
|
||||
<string name="c_blacklist">黑名单(contentBlacklist)</string>
|
||||
<string name="c_whitelist">Whitelist (contentWhitelist)</string>
|
||||
<string name="c_blacklist">Blacklist (contentBlacklist)</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="jump_to_another_app">Jump to another app</string>
|
||||
<string name="clear_webview_data">Clear WebView Data</string>
|
||||
<string name="clear_webview_data_summary">Clear all data in WebView</string>
|
||||
<string name="source_tab_list">List</string>
|
||||
<string name="source_tab_start">启动</string>
|
||||
<string name="r_startHtml">启动页html文本</string>
|
||||
<string name="r_startStyle">启动页style文本</string>
|
||||
<string name="r_startJs">启动页Js(startJs)</string>
|
||||
<string name="r_preloadJs">预注入Js(preloadJs)</string>
|
||||
<string name="enable_preload">预加载</string>
|
||||
<string name="load_with_web_log">显示WebView日志</string>
|
||||
<string name="cache_first">优先缓存</string>
|
||||
<string name="layout_type">布局</string>
|
||||
<string name="source_tab_start">Startup</string>
|
||||
<string name="r_startHtml">Startup page HTML text</string>
|
||||
<string name="r_startStyle">Startup page style text</string>
|
||||
<string name="r_startJs">Startup page JS (startJs)</string>
|
||||
<string name="r_preloadJs">Pre-injected JS (preloadJs)</string>
|
||||
<string name="enable_preload">Preload</string>
|
||||
<string name="load_with_web_log">Show WebView Logs</string>
|
||||
<string name="cache_first">Cache First</string>
|
||||
<string name="layout_type">Layout</string>
|
||||
<string name="dict_rule">Dictionary Rules</string>
|
||||
<string name="config_dict_rule">Config dict rule</string>
|
||||
<string name="create">Create</string>
|
||||
<string name="url_rule">URL规则(urlRule)</string>
|
||||
<string name="show_rule">显示规则(showRule)</string>
|
||||
<string name="url_rule">URL Rule (urlRule)</string>
|
||||
<string name="show_rule">Display Rule (showRule)</string>
|
||||
<string name="config_txt_toc_rule">Configure txt catalog rules</string>
|
||||
<string name="import_dict_rule">Import dict rule</string>
|
||||
<string name="keep_group">Keep group</string>
|
||||
@@ -1217,7 +1251,7 @@
|
||||
<string name="respondTime">respondTime: %1$d ms</string>
|
||||
<string name="load_word_count">Load word count</string>
|
||||
<string name="replace_exclude_scope">Exclude range, optional title or source URL</string>
|
||||
<string name="format_js_rule">格式化规则(formatJs)</string>
|
||||
<string name="format_js_rule">Format Rule (formatJs)</string>
|
||||
<string name="adjust_pos">Adjustment position</string>
|
||||
<string name="error_scope_input">Please enter the correct range</string>
|
||||
<string name="custom_export">Custom Export</string>
|
||||
@@ -1255,6 +1289,23 @@
|
||||
<string name="key_page_on_long_press">Press and Hold the Key to Turn Page</string>
|
||||
<string name="save_log">Save logs</string>
|
||||
<string name="create_heap_dump">Create Heap Dump</string>
|
||||
<string name="about_privacy_policy_title">Privacy Policy</string>
|
||||
<string name="about_license_title">License</string>
|
||||
<string name="about_disclaimer_title">Disclaimer</string>
|
||||
<string name="about_installed_version_title">Installed Version</string>
|
||||
<string name="about_current_version">Installed Version</string>
|
||||
<string name="about_new_version">Latest Version</string>
|
||||
<string name="about_update_channel">Release Channel</string>
|
||||
<string name="about_update_action">Download Update</string>
|
||||
<string name="about_backup_dir_not_set">Set a backup directory first</string>
|
||||
<string name="about_log_recording_disabled">Log recording is off. Turn it on in Other Settings first.</string>
|
||||
<string name="about_saved_to_backup_dir">Saved to backup folder</string>
|
||||
<string name="about_heap_dump_recording_disabled">Heap dump recording is off. Turn it on in Other Settings first.</string>
|
||||
<string name="about_heap_dump_creating">Creating heap dump…</string>
|
||||
<string name="about_heap_dump_not_found">Heap dump file not found</string>
|
||||
<string name="about_download_info_incomplete">Update download information is incomplete</string>
|
||||
<string name="about_no_data">No update log available</string>
|
||||
<string name="about_start_download">Downloading %s</string>
|
||||
<string name="crash_report">Crash report</string>
|
||||
<string name="crash_report_message">The app crashed. Copy the error information below when reporting the issue.</string>
|
||||
<string name="crash_report_empty">No crash information found.</string>
|
||||
@@ -1283,7 +1334,7 @@
|
||||
<string name="read_aloud_read_phone_state_permission_rationale">Reading requires phone state access to pause reading aloud during calls</string>
|
||||
<string name="read_aloud_by_media_button_title">Start Read Aloud via Headset Buttons</string>
|
||||
<string name="read_aloud_by_media_button_summary">Use headset buttons to start reading aloud</string>
|
||||
<string name="group_sources_by_domain">按域名分组显示</string>
|
||||
<string name="group_sources_by_domain">Group Sources by Domain</string>
|
||||
<string name="theme_config">Theme Configuration</string>
|
||||
<string name="show_manga_ui">Manga Viewer</string>
|
||||
<string name="disable_manga_scale">Disable Manga Zoom</string>
|
||||
@@ -1316,6 +1367,65 @@
|
||||
<string name="ungroup">Ungrouped</string>
|
||||
<string name="dynamic_colors">Dynamic Colors</string>
|
||||
<string name="dynamic_colors_summary">Use wallpaper-based theme colors</string>
|
||||
<string name="theme_manage_export_success">Theme exported</string>
|
||||
<string name="theme_manage_export_failed">Could not export theme</string>
|
||||
<string name="theme_manage_import_success">Theme imported. Some changes require a restart.</string>
|
||||
<string name="theme_manage_import_failed">Could not import theme</string>
|
||||
<string name="theme_manage_save_current">Save Current Theme</string>
|
||||
<string name="theme_manage_save_current_summary">Save the current appearance settings as a theme</string>
|
||||
<string name="theme_manage_export_current">Export Current Theme</string>
|
||||
<string name="theme_manage_export_current_summary">Export the current theme settings as a JSON file</string>
|
||||
<string name="theme_manage_import_config">Import Theme File</string>
|
||||
<string name="theme_manage_import_config_summary">Import theme settings from a JSON file</string>
|
||||
<string name="theme_manage_saved_themes">Saved Themes</string>
|
||||
<string name="theme_manage_save_theme">Save Theme</string>
|
||||
<string name="theme_manage_save">Save</string>
|
||||
<string name="theme_manage_name_hint">Enter a theme name</string>
|
||||
<string name="theme_manage_apply_theme">Apply Theme</string>
|
||||
<string name="theme_manage_apply">Apply</string>
|
||||
<string name="theme_manage_apply_message">Apply theme \"%s\"? A restart is required for all changes to take effect.</string>
|
||||
<string name="theme_manage_delete_theme">Delete Theme</string>
|
||||
<string name="theme_manage_delete_message">Delete theme \"%s\"? This cannot be undone.</string>
|
||||
<string name="theme_manage_preview_day">Day</string>
|
||||
<string name="theme_manage_preview_night">Night</string>
|
||||
<string name="theme_manage_edit_theme">Edit Theme</string>
|
||||
<string name="theme_manage_section_basic">Basic Settings</string>
|
||||
<string name="theme_manage_section_colors">Colors</string>
|
||||
<string name="theme_manage_use_palette_colors">Generate Colors from Palette</string>
|
||||
<string name="theme_manage_primary_color">Primary Color</string>
|
||||
<string name="theme_manage_secondary_color">Secondary Color</string>
|
||||
<string name="theme_manage_primary_text_color">Primary Text Color</string>
|
||||
<string name="theme_manage_secondary_text_color">Secondary Text Color</string>
|
||||
<string name="theme_manage_background_color">Background Color</string>
|
||||
<string name="theme_manage_label_container_color">Label Container Color</string>
|
||||
<string name="theme_manage_day_seed_color">Day Seed Color</string>
|
||||
<string name="theme_manage_night_seed_color">Night Seed Color</string>
|
||||
<string name="theme_manage_section_layout">Interface Layout</string>
|
||||
<string name="theme_manage_show_discovery">Show Discovery</string>
|
||||
<string name="theme_manage_status_bar">Status Bar</string>
|
||||
<string name="theme_manage_page_turn_animation">Page Turn Animation</string>
|
||||
<string name="theme_manage_label_visibility">Label Visibility</string>
|
||||
<string name="theme_manage_section_blur">Blur Effects</string>
|
||||
<string name="theme_manage_top_bar_blur_radius">Top Bar Blur Radius</string>
|
||||
<string name="theme_manage_bottom_bar_blur_radius">Bottom Bar Blur Radius</string>
|
||||
<string name="theme_manage_top_bar_blur_opacity">Top Bar Blur Opacity</string>
|
||||
<string name="theme_manage_bottom_bar_blur_opacity">Bottom Bar Blur Opacity</string>
|
||||
<string name="theme_manage_section_opacity">Opacity</string>
|
||||
<string name="theme_manage_section_container">Container</string>
|
||||
<string name="theme_config_manage_label_colors">Manage Label Colors</string>
|
||||
<string name="theme_config_label_color_name">Label %1$d</string>
|
||||
<string name="theme_config_miuix_experimental_warning">Miuix is currently experimental and does not apply to View-based screens.</string>
|
||||
<string name="theme_config_bottom_bar_lens_radius">Bottom Bar Blur Strength</string>
|
||||
<string name="theme_config_bottom_bar_lens_radius_summary">Controls the liquid glass distortion strength</string>
|
||||
<string name="theme_config_blur_radius_performance_summary">Higher blur radius may reduce performance</string>
|
||||
<string name="theme_config_divider_width">Divider Width</string>
|
||||
<string name="theme_config_divider_length">Divider Length</string>
|
||||
<string name="theme_config_nav_icon_settings">Navigation Bar Icon Settings</string>
|
||||
<string name="theme_config_nav_icons">Navigation Bar Icons</string>
|
||||
<string name="theme_config_nav_icons_custom_count">%1$d custom icons set</string>
|
||||
<string name="theme_config_nav_icons_default">Using default icons</string>
|
||||
<string name="theme_config_add_nav_icon">Add %1$s icon</string>
|
||||
<string name="theme_config_no_font_files">No font files</string>
|
||||
<string name="input_value_range">Enter value (%1$d-%2$d)</string>
|
||||
<string name="change_icon_success">Icon Updated</string>
|
||||
<string name="replace_rule_title_setting">Configure Replace Rules</string>
|
||||
@@ -1363,6 +1473,38 @@
|
||||
<string name="abi_arm64_v8a">ABI: arm64-v8a</string>
|
||||
<string name="download_link">Download Link</string>
|
||||
<string name="no_bookmark">No Bookmarks</string>
|
||||
<string name="bookmark_management">Bookmark Management</string>
|
||||
<string name="locate_current_reading">Go to Current Reading</string>
|
||||
<string name="move_to_top">Move to Top</string>
|
||||
<string name="move_to_bottom">Move to Bottom</string>
|
||||
<string name="invert_selection">Invert Selection</string>
|
||||
<string name="select_following">Select Following</string>
|
||||
<string name="search_chapters">Search chapters…</string>
|
||||
<string name="use_replace_rule">Use Replacement Rules</string>
|
||||
<string name="show_word_count">Show Word Count</string>
|
||||
<string name="local_book_options">Local Book Options</string>
|
||||
<string name="local_book_toc_rule">Local Book Chapter Rule</string>
|
||||
<string name="select_toc_rule">Select Chapter Rule</string>
|
||||
<string name="split_long_chapters">Split Long Chapters</string>
|
||||
<string name="export_bookmarks_json">Export Bookmarks as JSON</string>
|
||||
<string name="export_bookmarks_markdown">Export Bookmarks as Markdown</string>
|
||||
<string name="volume_management">Volume Management</string>
|
||||
<string name="quick_jump">Quick Jump</string>
|
||||
<string name="download_selected_count">Download Selected (%1$d)</string>
|
||||
<string name="toc_rule_update_failed">Failed to update chapter rule: %1$s</string>
|
||||
<string name="toc_rule_updated">Chapter rule updated</string>
|
||||
<string name="setting_failed">Setting failed: %1$s</string>
|
||||
<string name="split_long_chapters_enabled">Long chapter splitting enabled</string>
|
||||
<string name="split_long_chapters_disabled">Long chapter splitting disabled</string>
|
||||
<string name="no_bookmarks_to_export">No bookmarks to export</string>
|
||||
<string name="save_success">Saved</string>
|
||||
<string name="save_failed_with_error">Save failed: %1$s</string>
|
||||
<string name="select_chapters">Select chapters</string>
|
||||
<string name="bookmarks_added_count">%1$d bookmarks added</string>
|
||||
<string name="start_downloading_chapters">Downloading %1$d chapters</string>
|
||||
<string name="start_downloading_chapter">Downloading chapter</string>
|
||||
<string name="all_chapters_cached">All chapters are cached</string>
|
||||
<string name="start_downloading_remaining_chapters">Downloading remaining %1$d chapters</string>
|
||||
<string name="read_end">Finished Reading</string>
|
||||
<string name="system_engine">System Engine</string>
|
||||
<string name="copy_from">Import from Clipboard</string>
|
||||
@@ -1394,61 +1536,61 @@
|
||||
<string name="author_read">%1$s • %2$d Not read</string>
|
||||
<string name="menu_alpha_sum">Current %d%%</string>
|
||||
<string name="menu_alpha">Menu Transparency</string>
|
||||
<string name="change_source_option_title">请选择操作</string>
|
||||
<string name="replace_current_book">替换本书</string>
|
||||
<string name="add_as_new_book">新增书籍</string>
|
||||
<string name="quick_add_to_shelf">快速添加到书架</string>
|
||||
<string name="book_added_to_shelf">书籍已添加到书架</string>
|
||||
<string name="seed_photo_summary">使用图片生成主题颜色</string>
|
||||
<string name="seed_photo_alart">若需使用种子颜色,请取消种子图片选择</string>
|
||||
<string name="change_source_option_title">Choose an Action</string>
|
||||
<string name="replace_current_book">Replace This Book</string>
|
||||
<string name="add_as_new_book">Add as New Book</string>
|
||||
<string name="quick_add_to_shelf">Quick Add to Bookshelf</string>
|
||||
<string name="book_added_to_shelf">Book added to bookshelf</string>
|
||||
<string name="seed_photo_summary">Generate theme colors from an image</string>
|
||||
<string name="seed_photo_alart">To use a seed color, clear the selected seed image first</string>
|
||||
<string name="click_to_delete">Click to delete or change</string>
|
||||
<string name="tip_custom_mode">由于主题引擎依赖Monet,对于低于Android12的设备,动态取色与自定义主题不会生效。</string>
|
||||
<string name="restart_required_message">修改该选项需要重启</string>
|
||||
<string name="restart_later_message">稍后重启</string>
|
||||
<string name="search_select_group">选择书源分组</string>
|
||||
<string name="day_night_switch">深浅色模式开关</string>
|
||||
<string name="manga_long_click">长按保存图片</string>
|
||||
<string name="read_type_long">长按设置为全局默认模式</string>
|
||||
<string name="read_slider_mode">滑动条显示样式</string>
|
||||
<string name="bookshelf_update_limit">书架更新数量限制</string>
|
||||
<string name="text_shadow_x">X轴距离</string>
|
||||
<string name="text_shadow_y">Y轴距离</string>
|
||||
<string name="text_shadow_radius">阴影半径</string>
|
||||
<string name="text_shadow_color">阴影</string>
|
||||
<string name="global_read_setting">阅读显示 • 漫画相关</string>
|
||||
<string name="screen_settings">屏幕显示与亮度</string>
|
||||
<string name="tip_custom_mode">The theme engine depends on Monet. Dynamic colors and custom themes do not take effect on devices below Android 12.</string>
|
||||
<string name="restart_required_message">Changing this option requires a restart</string>
|
||||
<string name="restart_later_message">Restart Later</string>
|
||||
<string name="search_select_group">Select Book Source Group</string>
|
||||
<string name="day_night_switch">Light/Dark Mode Switch</string>
|
||||
<string name="manga_long_click">Long press to save image</string>
|
||||
<string name="read_type_long">Long press to set as the global default mode</string>
|
||||
<string name="read_slider_mode">Slider Display Style</string>
|
||||
<string name="bookshelf_update_limit">Bookshelf Update Limit</string>
|
||||
<string name="text_shadow_x">X Offset</string>
|
||||
<string name="text_shadow_y">Y Offset</string>
|
||||
<string name="text_shadow_radius">Shadow Radius</string>
|
||||
<string name="text_shadow_color">Shadow</string>
|
||||
<string name="global_read_setting">Reading Display • Manga</string>
|
||||
<string name="screen_settings">Display and Brightness</string>
|
||||
<string name="refresh_limit_unlimited">Unlimited</string>
|
||||
<string name="refresh_limit_books">%1$d Books</string>
|
||||
|
||||
<string name="reading_behavior">阅读行为</string>
|
||||
<string name="page_control">翻页控制</string>
|
||||
<string name="redirect_policy">网页重定向策略</string>
|
||||
<string name="redirect_allow_all">允许所有重定向</string>
|
||||
<string name="redirect_ask_always">总是询问</string>
|
||||
<string name="redirect_ask_cross_origin">域名不同时询问</string>
|
||||
<string name="redirect_block_cross_origin">阻止跨域名重定向</string>
|
||||
<string name="redirect_block_all">阻止所有重定向</string>
|
||||
<string name="redirect_ask_same_domain_block_cross">域内询问且域外阻止</string>
|
||||
<string name="reading_behavior">Reading Behavior</string>
|
||||
<string name="page_control">Page Turn Controls</string>
|
||||
<string name="redirect_policy">Web Redirect Policy</string>
|
||||
<string name="redirect_allow_all">Allow All Redirects</string>
|
||||
<string name="redirect_ask_always">Always Ask</string>
|
||||
<string name="redirect_ask_cross_origin">Ask When Domain Changes</string>
|
||||
<string name="redirect_block_cross_origin">Block Cross-Domain Redirects</string>
|
||||
<string name="redirect_block_all">Block All Redirects</string>
|
||||
<string name="redirect_ask_same_domain_block_cross">Ask Within Domain, Block Cross-Domain</string>
|
||||
<string name="show_status">Show Status Bar</string>
|
||||
<string name="sort_old_to_new">从旧到新</string>
|
||||
<string name="sort_new_to_old">从新到旧</string>
|
||||
<string name="sort_name_asc">名称升序</string>
|
||||
<string name="sort_name_desc">名称降序</string>
|
||||
<string name="text_dottedline">下划虚线</string>
|
||||
<string name="jump_to_volume">跳转到卷</string>
|
||||
<string name="cancel_select">取消选择</string>
|
||||
<string name="coll_volume">折叠所有卷</string>
|
||||
<string name="expand_volume">展开所有卷</string>
|
||||
<string name="custom">自定义</string>
|
||||
<string name="global_setting">全局设置</string>
|
||||
<string name="text_typeface">字体样式</string>
|
||||
<string name="shadow_typeface">阴影样式</string>
|
||||
<string name="sort_old_to_new">Oldest First</string>
|
||||
<string name="sort_new_to_old">Newest First</string>
|
||||
<string name="sort_name_asc">Name Ascending</string>
|
||||
<string name="sort_name_desc">Name Descending</string>
|
||||
<string name="text_dottedline">Dotted Underline</string>
|
||||
<string name="jump_to_volume">Jump to Volume</string>
|
||||
<string name="cancel_select">Cancel Selection</string>
|
||||
<string name="coll_volume">Collapse All Volumes</string>
|
||||
<string name="expand_volume">Expand All Volumes</string>
|
||||
<string name="custom">Custom</string>
|
||||
<string name="global_setting">Global Settings</string>
|
||||
<string name="text_typeface">Font Style</string>
|
||||
<string name="shadow_typeface">Shadow Style</string>
|
||||
<string name="long_click_to_custom">Long Tap to Customize</string>
|
||||
<string name="disable_manga_scroll_animation">禁用翻页动画</string>
|
||||
<string name="manga_cross_fade">禁用加载淡入动画</string>
|
||||
<string name="text_shadow_set">阴影设置</string>
|
||||
<string name="paragraph_typeface">段落样式</string>
|
||||
<string name="same_name_book">已有相同书籍</string>
|
||||
<string name="disable_manga_scroll_animation">Disable Page Turn Animation</string>
|
||||
<string name="manga_cross_fade">Disable Loading Fade-In Animation</string>
|
||||
<string name="text_shadow_set">Shadow Settings</string>
|
||||
<string name="paragraph_typeface">Paragraph Style</string>
|
||||
<string name="same_name_book">A book with the same name already exists</string>
|
||||
<string name="underline_color">Underline Color</string>
|
||||
<string name="dotted_line_black">Dash Length</string>
|
||||
<string name="dotted_line_while">Gap Length</string>
|
||||
@@ -1457,7 +1599,7 @@
|
||||
<string name="sure_cache_book">Cache the Book?</string>
|
||||
<string name="auto_check_new_backup_t">Auto-Check for New Backups</string>
|
||||
<string name="auto_check_new_backup_s">Check for new backups when opening the app, if new backups are found, prompt the user to update.</string>
|
||||
<string name="replace_purify_badge">计数替换净化</string>
|
||||
<string name="replace_purify_badge">Count Replacements and Purify Rules</string>
|
||||
<string name="page_anim_fade">Fade</string>
|
||||
<string name="show_bookshelf_tab_menu">Show More Bookshelf Tab</string>
|
||||
<string name="show_unread_new">Show New Chapter Flag</string>
|
||||
@@ -1480,32 +1622,32 @@
|
||||
<string name="select_operation">Select an operation</string>
|
||||
<string name="text_accent_color">Accent Color</string>
|
||||
<string name="read_color">Color Style</string>
|
||||
<string name="reverse_volume_key_page">反转音量键翻页方向</string>
|
||||
<string name="palette_style">调色板样式</string>
|
||||
<string name="material_version">颜色规格</string>
|
||||
<string name="tip_compose_set">这里的选项仅可以控制使用Compose重写的界面。对于禁用的选项,会在日后实现时开放,现在仅作占位。</string>
|
||||
<string name="reverse_volume_key_page">Reverse Volume-Key Page Turn Direction</string>
|
||||
<string name="palette_style">Palette Style</string>
|
||||
<string name="material_version">Color Specification</string>
|
||||
<string name="tip_compose_set">These options only affect screens rewritten in Compose. Disabled options are placeholders and will be enabled after implementation.</string>
|
||||
<string name="is_blur_enable">Enable Element Blur</string>
|
||||
<string name="use_underline">总是使用下划线表示强调文本</string>
|
||||
<string name="adapt_special_style">适配特殊样式</string>
|
||||
<string name="use_underline">Always Use Underline for Emphasized Text</string>
|
||||
<string name="adapt_special_style">Adapt Special Styles</string>
|
||||
<string name="compose_engine">Theme Style</string>
|
||||
<string name="container_opacity">Container Opacity</string>
|
||||
<string name="container_opacity_summary">%d</string>
|
||||
<string name="top_bar_opacity">顶栏不透明度</string>
|
||||
<string name="top_bar_opacity">Top Bar Opacity</string>
|
||||
<string name="top_bar_opacity_summary">%d</string>
|
||||
<string name="bottom_bar_opacity">底栏不透明度</string>
|
||||
<string name="bottom_bar_opacity">Bottom Bar Opacity</string>
|
||||
<string name="bottom_bar_opacity_summary">%d</string>
|
||||
<string name="web_service_auto_start">启动应用时打开Web服务</string>
|
||||
<string name="read_aloud_preload">听书预加载数量</string>
|
||||
<string name="web_service_auto_start">Start Web Service When App Opens</string>
|
||||
<string name="read_aloud_preload">Read-Aloud Preload Count</string>
|
||||
<string name="read_aloud_preload_summary">%d</string>
|
||||
<string name="audio_cache_clean_time">音频缓存保留时间(分钟)</string>
|
||||
<string name="audio_cache_clean_time_summary">当前%d, 输入 0 代表退出即刻清理。</string>
|
||||
<string name="show_swipe_animation">启用滑动时动画</string>
|
||||
<string name="click_image_way">点击图片行为</string>
|
||||
<string name="show_web_log">输出日志</string>
|
||||
<string name="is_blur_progressive_enable">启用渐变模糊</string>
|
||||
<string name="enable_select_vibrator">选择文本时震动</string>
|
||||
<string name="re_sync_webdav">重新同步远程书籍</string>
|
||||
<string name="underline_padding">离字间距</string>
|
||||
<string name="audio_cache_clean_time">Audio Cache Retention Time (minutes)</string>
|
||||
<string name="audio_cache_clean_time_summary">Current: %d. Enter 0 to clear immediately on exit.</string>
|
||||
<string name="show_swipe_animation">Enable Animation While Swiping</string>
|
||||
<string name="click_image_way">Image Tap Action</string>
|
||||
<string name="show_web_log">Output Logs</string>
|
||||
<string name="is_blur_progressive_enable">Enable Progressive Blur</string>
|
||||
<string name="enable_select_vibrator">Vibrate When Selecting Text</string>
|
||||
<string name="re_sync_webdav">Resync Remote Books</string>
|
||||
<string name="underline_padding">Underline Gap</string>
|
||||
|
||||
<!-- Missing strings -->
|
||||
<string name="cover_info_orientation">Cover orientation</string>
|
||||
|
||||
Reference in New Issue
Block a user