This commit is contained in:
Horis
2023-09-01 22:33:44 +08:00
parent 59aad58cc2
commit 5b69647abb
24 changed files with 134 additions and 49 deletions
@@ -133,6 +133,8 @@ object PreferKey {
const val onlyLatestBackup = "onlyLatestBackup" const val onlyLatestBackup = "onlyLatestBackup"
const val brightnessVwPos = "brightnessVwPos" const val brightnessVwPos = "brightnessVwPos"
const val shrinkDatabase = "shrinkDatabase" const val shrinkDatabase = "shrinkDatabase"
const val batchChangeSourceDelay = "batchChangeSourceDelay"
const val openBookInfoByClickTitle = "openBookInfoByClickTitle"
const val cPrimary = "colorPrimary" const val cPrimary = "colorPrimary"
const val cAccent = "colorAccent" const val cAccent = "colorAccent"
@@ -380,12 +380,24 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
appCtx.putPrefBoolean(PreferKey.changeSourceLoadWordCount, value) appCtx.putPrefBoolean(PreferKey.changeSourceLoadWordCount, value)
} }
var openBookInfoByClickTitle: Boolean
get() = appCtx.getPrefBoolean(PreferKey.openBookInfoByClickTitle, true)
set(value) {
appCtx.putPrefBoolean(PreferKey.openBookInfoByClickTitle, value)
}
var contentSelectSpeakMod: Int var contentSelectSpeakMod: Int
get() = appCtx.getPrefInt(PreferKey.contentSelectSpeakMod) get() = appCtx.getPrefInt(PreferKey.contentSelectSpeakMod)
set(value) { set(value) {
appCtx.putPrefInt(PreferKey.contentSelectSpeakMod, value) appCtx.putPrefInt(PreferKey.contentSelectSpeakMod, value)
} }
var batchChangeSourceDelay: Int
get() = appCtx.getPrefInt(PreferKey.batchChangeSourceDelay)
set(value) {
appCtx.putPrefInt(PreferKey.batchChangeSourceDelay, value)
}
val importKeepName get() = appCtx.getPrefBoolean(PreferKey.importKeepName) val importKeepName get() = appCtx.getPrefBoolean(PreferKey.importKeepName)
val importKeepGroup get() = appCtx.getPrefBoolean(PreferKey.importKeepGroup) val importKeepGroup get() = appCtx.getPrefBoolean(PreferKey.importKeepGroup)
@@ -18,6 +18,7 @@ import io.legado.app.utils.postEvent
import io.legado.app.utils.startService import io.legado.app.utils.startService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -243,7 +244,7 @@ object CacheBook {
waitDownloadSet.remove(chapterIndex) waitDownloadSet.remove(chapterIndex)
onDownloadSet.add(chapterIndex) onDownloadSet.add(chapterIndex)
if (BookHelp.hasContent(book, chapter)) { if (BookHelp.hasContent(book, chapter)) {
Coroutine.async { Coroutine.async(executeContext = context) {
BookHelp.getContent(book, chapter)?.let { BookHelp.getContent(book, chapter)?.let {
BookHelp.saveImages(bookSource, book, chapter, it) BookHelp.saveImages(bookSource, book, chapter, it)
} }
@@ -266,7 +267,8 @@ object CacheBook {
bookSource, bookSource,
book, book,
chapter, chapter,
context = context context = context,
executeContext = context
).onSuccess { content -> ).onSuccess { content ->
onSuccess(chapter) onSuccess(chapter)
downloadFinish(chapter, content) downloadFinish(chapter, content)
@@ -295,7 +297,7 @@ object CacheBook {
postEvent(EventBus.UP_DOWNLOAD, book.bookUrl) postEvent(EventBus.UP_DOWNLOAD, book.bookUrl)
onDownloadSet.add(chapter.index) onDownloadSet.add(chapter.index)
waitDownloadSet.remove(chapter.index) waitDownloadSet.remove(chapter.index)
WebBook.getContent(scope, bookSource, book, chapter) WebBook.getContent(scope, bookSource, book, chapter, executeContext = IO)
.onSuccess { content -> .onSuccess { content ->
onSuccess(chapter) onSuccess(chapter)
downloadFinish(chapter, content, resetPageOffset) downloadFinish(chapter, content, resetPageOffset)
@@ -441,38 +441,40 @@ object ReadBook : CoroutineScope by MainScope() {
pageChanged: Boolean, pageChanged: Boolean,
success: (() -> Unit)? = null success: (() -> Unit)? = null
) { ) {
if (chapter.index !in durChapterIndex - 1..durChapterIndex + 1) {
return
}
Coroutine.async { Coroutine.async {
removeLoading(chapter.index) removeLoading(chapter.index)
if (chapter.index in durChapterIndex - 1..durChapterIndex + 1) { val contentProcessor = ContentProcessor.get(book.name, book.origin)
val contentProcessor = ContentProcessor.get(book.name, book.origin) val displayTitle = chapter.getDisplayTitle(
val displayTitle = chapter.getDisplayTitle( contentProcessor.getTitleReplaceRules(),
contentProcessor.getTitleReplaceRules(), book.getUseReplaceRule()
book.getUseReplaceRule() )
) val contents = contentProcessor
val contents = contentProcessor .getContent(book, chapter, content, includeTitle = false)
.getContent(book, chapter, content, includeTitle = false) val textChapter = ChapterProvider
val textChapter = ChapterProvider .getTextChapter(book, chapter, displayTitle, contents, chapterSize)
.getTextChapter(book, chapter, displayTitle, contents, chapterSize) when (val offset = chapter.index - durChapterIndex) {
when (val offset = chapter.index - durChapterIndex) { 0 -> {
0 -> { curTextChapter = textChapter
curTextChapter = textChapter if (upContent) callBack?.upContent(offset, resetPageOffset)
if (upContent) callBack?.upContent(offset, resetPageOffset) callBack?.upMenuView()
callBack?.upMenuView() if (pageChanged) curPageChanged()
if (pageChanged) curPageChanged() callBack?.contentLoadFinish()
callBack?.contentLoadFinish() }
}
-1 -> { -1 -> {
prevTextChapter = textChapter prevTextChapter = textChapter
if (upContent) callBack?.upContent(offset, resetPageOffset) if (upContent) callBack?.upContent(offset, resetPageOffset)
} }
1 -> { 1 -> {
nextTextChapter = textChapter nextTextChapter = textChapter
if (upContent) callBack?.upContent(offset, resetPageOffset) if (upContent) callBack?.upContent(offset, resetPageOffset)
}
} }
} }
Unit
}.onError { }.onError {
AppLog.put("ChapterProvider ERROR", it) AppLog.put("ChapterProvider ERROR", it)
appCtx.toastOnUi("ChapterProvider ERROR:\n${it.stackTraceStr}") appCtx.toastOnUi("ChapterProvider ERROR:\n${it.stackTraceStr}")
@@ -265,9 +265,10 @@ object WebBook {
bookChapter: BookChapter, bookChapter: BookChapter,
nextChapterUrl: String? = null, nextChapterUrl: String? = null,
needSave: Boolean = true, needSave: Boolean = true,
context: CoroutineContext = Dispatchers.IO context: CoroutineContext = Dispatchers.IO,
executeContext: CoroutineContext = Dispatchers.Main,
): Coroutine<String> { ): Coroutine<String> {
return Coroutine.async(scope, context) { return Coroutine.async(scope, context, executeContext = executeContext) {
getContentAwait(bookSource, book, bookChapter, nextChapterUrl, needSave) getContentAwait(bookSource, book, bookChapter, nextChapterUrl, needSave)
} }
} }
@@ -152,8 +152,7 @@ class HttpReadAloudService : BaseReadAloudService(),
} }
} }
}.onError { }.onError {
toastOnUi("朗读出错:${it.localizedMessage}") AppLog.put("朗读下载出错\n${it.localizedMessage}", it, true)
AppLog.put("朗读下载出错\n${it.localizedMessage}", it)
} }
} }
@@ -196,8 +195,7 @@ class HttpReadAloudService : BaseReadAloudService(),
is CancellationException -> throw e is CancellationException -> throw e
is ConcurrentException -> delay(e.waitTime.toLong()) is ConcurrentException -> delay(e.waitTime.toLong())
is ScriptException, is WrappedException -> { is ScriptException, is WrappedException -> {
AppLog.put("js错误\n${e.localizedMessage}", e) AppLog.put("js错误\n${e.localizedMessage}", e, true)
toastOnUi("js错误\n${e.localizedMessage}")
e.printOnDebug() e.printOnDebug()
throw e throw e
} }
@@ -206,8 +204,7 @@ class HttpReadAloudService : BaseReadAloudService(),
downloadErrorNo++ downloadErrorNo++
if (downloadErrorNo > 5) { if (downloadErrorNo > 5) {
val msg = "tts超时或连接错误超过5次\n${e.localizedMessage}" val msg = "tts超时或连接错误超过5次\n${e.localizedMessage}"
AppLog.put(msg, e) AppLog.put(msg, e, true)
toastOnUi(msg)
throw e throw e
} }
} }
@@ -219,8 +216,7 @@ class HttpReadAloudService : BaseReadAloudService(),
e.printOnDebug() e.printOnDebug()
if (downloadErrorNo > 5) { if (downloadErrorNo > 5) {
val msg1 = "TTS服务器连续5次错误,已暂停阅读。" val msg1 = "TTS服务器连续5次错误,已暂停阅读。"
AppLog.put(msg1) AppLog.put(msg1, e, true)
toastOnUi(msg1)
throw e throw e
} else { } else {
AppLog.put("TTS下载音频出错,使用无声音频代替。\n朗读文本:$speakText") AppLog.put("TTS下载音频出错,使用无声音频代替。\n朗读文本:$speakText")
@@ -117,8 +117,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
} }
} }
}.onError { }.onError {
AppLog.put("tts朗读出错", it) AppLog.put("tts朗读出错\n${it.localizedMessage}", it, true)
toastOnUi(it.localizedMessage)
} }
} }
@@ -13,6 +13,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.ItemArrangeBookBinding import io.legado.app.databinding.ItemArrangeBookBinding
import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocal
import io.legado.app.help.config.AppConfig
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
@@ -89,9 +90,11 @@ class BookAdapter(context: Context, val callBack: CallBack) :
callBack.upSelectCount() callBack.upSelectCount()
} }
} }
tvName.setOnClickListener { if (AppConfig.openBookInfoByClickTitle) {
getItem(holder.layoutPosition)?.let { tvName.setOnClickListener {
callBack.openBook(it) getItem(holder.layoutPosition)?.let {
callBack.openBook(it)
}
} }
} }
tvDelete.setOnClickListener { tvDelete.setOnClickListener {
@@ -120,6 +120,8 @@ class BookshelfManageActivity :
override fun onPrepareOptionsMenu(menu: Menu): Boolean { override fun onPrepareOptionsMenu(menu: Menu): Boolean {
this.menu = menu this.menu = menu
menu.findItem(R.id.menu_open_book_info_by_click_title)?.isChecked =
AppConfig.openBookInfoByClickTitle
upMenu() upMenu()
return super.onPrepareOptionsMenu(menu) return super.onPrepareOptionsMenu(menu)
} }
@@ -248,6 +250,11 @@ class BookshelfManageActivity :
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>() R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
R.id.menu_open_book_info_by_click_title -> {
AppConfig.openBookInfoByClickTitle = !item.isChecked
adapter.notifyItemRangeChanged(0, adapter.itemCount)
}
else -> if (item.groupId == R.id.menu_group) { else -> if (item.groupId == R.id.menu_group) {
viewModel.groupName = item.title.toString() viewModel.groupName = item.title.toString()
upTitle() upTitle()
@@ -10,10 +10,11 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocal
import io.legado.app.help.book.removeType import io.legado.app.help.book.removeType
import io.legado.app.help.config.AppConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.toastOnUi import kotlinx.coroutines.delay
class BookshelfManageViewModel(application: Application) : BaseViewModel(application) { class BookshelfManageViewModel(application: Application) : BaseViewModel(application) {
@@ -52,6 +53,7 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica
fun changeSource(books: List<Book>, source: BookSource) { fun changeSource(books: List<Book>, source: BookSource) {
batchChangeSourceCoroutine?.cancel() batchChangeSourceCoroutine?.cancel()
batchChangeSourceCoroutine = execute { batchChangeSourceCoroutine = execute {
val changeSourceDelay = AppConfig.batchChangeSourceDelay * 1000L
books.forEachIndexed { index, book -> books.forEachIndexed { index, book ->
batchChangeSourceProcessLiveData.postValue("${index + 1} / ${books.size}") batchChangeSourceProcessLiveData.postValue("${index + 1} / ${books.size}")
if (book.isLocal) return@forEachIndexed if (book.isLocal) return@forEachIndexed
@@ -69,6 +71,7 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica
appDb.bookDao.insert(newBook) appDb.bookDao.insert(newBook)
appDb.bookChapterDao.insert(*toc.toTypedArray()) appDb.bookChapterDao.insert(*toc.toTypedArray())
} }
delay(changeSourceDelay)
} }
}.onStart { }.onStart {
batchChangeSourceState.postValue(true) batchChangeSourceState.postValue(true)
@@ -2,9 +2,11 @@ package io.legado.app.ui.book.manage
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.core.view.setPadding import androidx.core.view.setPadding
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@@ -17,8 +19,10 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart import io.legado.app.data.entities.BookSourcePart
import io.legado.app.databinding.DialogSourcePickerBinding import io.legado.app.databinding.DialogSourcePickerBinding
import io.legado.app.databinding.Item1lineTextBinding import io.legado.app.databinding.Item1lineTextBinding
import io.legado.app.help.config.AppConfig
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.lib.theme.primaryTextColor import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.ui.widget.number.NumberPickerDialog
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.dpToPx import io.legado.app.utils.dpToPx
import io.legado.app.utils.setLayout import io.legado.app.utils.setLayout
@@ -27,12 +31,16 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import splitties.views.onClick import splitties.views.onClick
class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) { class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker),
Toolbar.OnMenuItemClickListener {
private val binding by viewBinding(DialogSourcePickerBinding::bind) private val binding by viewBinding(DialogSourcePickerBinding::bind)
private val searchView: SearchView by lazy { private val searchView: SearchView by lazy {
binding.toolBar.findViewById(R.id.search_view) binding.toolBar.findViewById(R.id.search_view)
} }
private val toolBar: Toolbar by lazy {
binding.toolBar.toolbar
}
private val adapter by lazy { private val adapter by lazy {
SourceAdapter(requireContext()) SourceAdapter(requireContext())
} }
@@ -46,6 +54,7 @@ class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) {
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
initView() initView()
initData() initData()
initMenu()
} }
private fun initView() { private fun initView() {
@@ -82,6 +91,26 @@ class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) {
} }
} }
private fun initMenu() {
toolBar.setOnMenuItemClickListener(this)
toolBar.inflateMenu(R.menu.source_picker)
toolBar.menu.applyTint(requireContext())
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_change_source_delay -> NumberPickerDialog(requireContext())
.setTitle(getString(R.string.change_source_delay))
.setMaxValue(9999)
.setMinValue(0)
.setValue(AppConfig.batchChangeSourceDelay)
.show {
AppConfig.batchChangeSourceDelay = it
}
}
return true
}
inner class SourceAdapter(context: Context) : inner class SourceAdapter(context: Context) :
RecyclerAdapter<BookSourcePart, Item1lineTextBinding>(context) { RecyclerAdapter<BookSourcePart, Item1lineTextBinding>(context) {
@@ -21,6 +21,7 @@ import io.legado.app.databinding.DialogMultipleEditTextBinding
import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.Item1lineTextAndDelBinding import io.legado.app.databinding.Item1lineTextAndDelBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
@@ -132,6 +133,7 @@ class KeyboardAssistsConfig : BaseDialogFragment(R.layout.dialog_recycler_view),
item: KeyboardAssist, item: KeyboardAssist,
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
binding.root.setBackgroundColor(context.backgroundColor)
binding.textView.text = item.key binding.textView.text = item.key
} }
@@ -11,7 +11,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="?attr/actionBarStyle" android:theme="?attr/actionBarStyle"
android:paddingRight="16dp"
app:attachToActivity="false" app:attachToActivity="false"
app:contentLayout="@layout/view_search" app:contentLayout="@layout/view_search"
app:fitStatusBar="false" app:fitStatusBar="false"
@@ -14,7 +14,6 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:singleLine="true" android:singleLine="true"
android:textColor="@color/primaryText" /> android:textColor="@color/primaryText" />
+6 -1
View File
@@ -20,4 +20,9 @@
</item> </item>
</menu> <item
android:id="@+id/menu_open_book_info_by_click_title"
android:checkable="true"
android:title="@string/open_book_info_by_click_title" />
</menu>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_change_source_delay"
android:title="@string/change_source_delay" />
</menu>
@@ -1125,4 +1125,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
@@ -1128,4 +1128,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
@@ -1128,4 +1128,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
+2
View File
@@ -1124,4 +1124,6 @@ Còn </string>
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
@@ -1125,4 +1125,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
@@ -1127,4 +1127,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
+2
View File
@@ -1127,4 +1127,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>
+2
View File
@@ -1128,4 +1128,6 @@
<string name="export_book">导出书籍</string> <string name="export_book">导出书籍</string>
<string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string> <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
<string name="export_md">导出(MD)</string> <string name="export_md">导出(MD)</string>
<string name="change_source_delay">换源间隔</string>
<string name="open_book_info_by_click_title">点击书名打开详情</string>
</resources> </resources>