Merge pull request #2178 from 821938089/little-fix

一些优化
pull/2179/head
kunfei 2 years ago committed by GitHub
commit 3d00bbd72c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  2. 12
      app/src/main/java/io/legado/app/data/dao/RssSourceDao.kt
  3. 4
      app/src/main/java/io/legado/app/help/config/AppConfig.kt
  4. 7
      app/src/main/java/io/legado/app/model/localBook/EpubFile.kt
  5. 16
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  6. 4
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  7. 21
      app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt
  8. 1
      app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt
  9. 17
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  10. 6
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  11. 9
      app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt
  12. 2
      app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt
  13. 6
      app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt
  14. 6
      app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt
  15. 31
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  16. 20
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceAdapter.kt
  17. 7
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceViewModel.kt
  18. 3
      app/src/main/java/io/legado/app/utils/StringExtensions.kt
  19. 4
      app/src/main/res/menu/bookshelf_menage_sel.xml
  20. 4
      app/src/main/res/menu/rss_main_item.xml
  21. 16
      app/src/main/res/menu/rss_source.xml
  22. 5
      app/src/main/res/menu/rss_source_sel.xml
  23. 2
      app/src/main/res/values-es-rES/strings.xml
  24. 2
      app/src/main/res/values-ja-rJP/strings.xml
  25. 2
      app/src/main/res/values-pt-rBR/strings.xml
  26. 2
      app/src/main/res/values-zh-rHK/strings.xml
  27. 2
      app/src/main/res/values-zh-rTW/strings.xml
  28. 2
      app/src/main/res/values-zh/strings.xml
  29. 2
      app/src/main/res/values/strings.xml
  30. 6
      app/src/main/res/xml/pref_config_other.xml

@ -109,6 +109,7 @@ object PreferKey {
const val welcomeShowIcon = "welcomeShowIcon"
const val welcomeShowIconDark = "welcomeShowIconDark"
const val pageTouchSlop = "pageTouchSlop"
const val showAddToShelfAlert = "showAddToShelfAlert"
const val cPrimary = "colorPrimary"
const val cAccent = "colorAccent"

@ -44,6 +44,15 @@ interface RssSourceDao {
@Query("SELECT * FROM rssSources where enabled = 1 order by customOrder")
fun flowEnabled(): Flow<List<RssSource>>
@Query("SELECT * FROM rssSources where enabled = 0 order by customOrder")
fun flowDisabled(): Flow<List<RssSource>>
@Query("select * from rssSources where loginUrl is not null and loginUrl != ''")
fun flowLogin(): Flow<List<RssSource>>
@Query("select * from rssSources where sourceGroup is null or sourceGroup = '' or sourceGroup like '%未分组%'")
fun flowNoGroup(): Flow<List<RssSource>>
@Query(
"""SELECT * FROM rssSources
where enabled = 1
@ -67,6 +76,9 @@ interface RssSourceDao {
@Query("select distinct sourceGroup from rssSources where trim(sourceGroup) <> ''")
fun flowGroup(): Flow<List<String>>
@Query("select distinct sourceGroup from rssSources where trim(sourceGroup) <> '' and enabled = 1")
fun flowGroupEnabled(): Flow<List<String>>
@get:Query("select distinct sourceGroup from rssSources where trim(sourceGroup) <> ''")
val allGroup: List<String>

@ -310,7 +310,9 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
val recordLog get() = appCtx.getPrefBoolean(PreferKey.recordLog)
val loadCoverOnlyWifi = appCtx.getPrefBoolean(PreferKey.loadCoverOnlyWifi, false)
val loadCoverOnlyWifi get() = appCtx.getPrefBoolean(PreferKey.loadCoverOnlyWifi, false)
val showAddToShelfAlert get() = appCtx.getPrefBoolean(PreferKey.showAddToShelfAlert, true)
val doublePageHorizontal: String?
get() = appCtx.getPrefString(PreferKey.doublePageHorizontal)

@ -18,6 +18,7 @@ import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.net.URLDecoder
import java.nio.charset.Charset
class EpubFile(var book: Book) {
@ -117,7 +118,9 @@ class EpubFile(var book: Book) {
* <image width="1038" height="670" xlink:href="..."/>
* ...titlepage.xhtml
*/
if (chapter.url.contains("titlepage.xhtml")) {
if (chapter.url.contains("titlepage.xhtml") ||
chapter.url.contains("cover.xhtml")
) {
return "<img src=\"cover.jpeg\" />"
}
/*获取当前章节文本*/
@ -190,7 +193,7 @@ class EpubFile(var book: Book) {
private fun getImage(href: String): InputStream? {
if (href == "cover.jpeg") return epubBook?.coverImage?.inputStream
val abHref = href.replace("../", "")
val abHref = URLDecoder.decode(href.replace("../", ""), "UTF-8")
return epubBook?.resources?.getByHref(abHref)?.inputStream
}

@ -6,6 +6,7 @@ import androidx.documentfile.provider.DocumentFile
import com.script.SimpleBindings
import io.legado.app.R
import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog
import io.legado.app.data.appDb
import io.legado.app.data.entities.BaseSource
import io.legado.app.data.entities.Book
@ -16,6 +17,7 @@ import io.legado.app.help.BookHelp
import io.legado.app.help.config.AppConfig
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.*
import org.jsoup.nodes.Entities
import splitties.init.appCtx
import java.io.*
import java.util.regex.Pattern
@ -77,11 +79,12 @@ object LocalBook {
throw TocEmptyException(appCtx.getString(R.string.chapter_list_empty))
}
val lh = LinkedHashSet(chapters)
lh.forEachIndexed { index, bookChapter -> bookChapter.index = index }
return ArrayList(lh)
}
fun getContent(book: Book, chapter: BookChapter): String? {
return try {
val content = try {
when {
book.isEpub() -> {
EpubFile.getContent(book, chapter)
@ -95,8 +98,15 @@ object LocalBook {
}
} catch (e: Exception) {
e.printOnDebug()
e.localizedMessage
}
AppLog.put("获取本地书籍内容失败\n${e.localizedMessage}", e)
"获取本地书籍内容失败\n${e.localizedMessage}"
}?.replace("&lt;img", "&lt; img", true)
content ?: return null
return kotlin.runCatching {
Entities.unescape(content)
}.onFailure {
AppLog.put("HTML实体解码失败\n${it.localizedMessage}", it)
}.getOrElse { content }
}
/**

@ -136,7 +136,7 @@ class CheckSourceService : BaseService() {
source.bookSourceComment = source.bookSourceComment
?.split("\n\n")
?.filterNot {
it.startsWith("Error: ")
it.startsWith("// Error: ")
}?.joinToString("\n")
//校验搜索书籍
if (CheckSource.checkSearch) {
@ -186,7 +186,7 @@ class CheckSourceService : BaseService() {
!is NoStackTraceException -> source.addGroup("网站失效")
}
source.bookSourceComment =
"Error: ${it.localizedMessage}" + if (source.bookSourceComment.isNullOrBlank())
"// Error: ${it.localizedMessage}" + if (source.bookSourceComment.isNullOrBlank())
"" else "\n\n${source.bookSourceComment}"
Debug.updateFinalMessage(source.bookSourceUrl, "校验失败:${it.localizedMessage}")
}.onSuccess(searchCoroutine) {

@ -14,6 +14,8 @@ import io.legado.app.databinding.ItemArrangeBookBinding
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import java.util.*
import kotlin.collections.HashSet
class BookAdapter(context: Context, val callBack: CallBack) :
RecyclerAdapter<Book, ItemArrangeBookBinding>(context),
@ -121,6 +123,25 @@ class BookAdapter(context: Context, val callBack: CallBack) :
callBack.upSelectCount()
}
fun checkSelectedInterval() {
val selectedPosition = linkedSetOf<Int>()
getItems().forEachIndexed { index, it ->
if (selectedBooks.contains(it)) {
selectedPosition.add(index)
}
}
val minPosition = Collections.min(selectedPosition)
val maxPosition = Collections.max(selectedPosition)
val itemCount = maxPosition - minPosition + 1
for (i in minPosition..maxPosition) {
getItem(i)?.let {
selectedBooks.add(it)
}
}
notifyItemRangeChanged(minPosition, itemCount, bundleOf(Pair("selected", null)))
callBack.upSelectCount()
}
private fun getGroupList(groupId: Long): List<String> {
val groupNames = arrayListOf<String>()
callBack.groupList.forEach {

@ -192,6 +192,7 @@ class BookshelfManageActivity :
viewModel.upCanUpdate(adapter.selection, false)
R.id.menu_add_to_group -> selectGroup(addToGroupRequestCode, 0)
R.id.menu_change_source -> showDialogFragment<SourcePickerDialog>()
R.id.menu_check_selected_interval -> adapter.checkSelectedInterval()
}
return false
}

@ -25,6 +25,7 @@ import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp
import io.legado.app.help.IntentData
import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ReadBookConfig
import io.legado.app.help.config.ReadTipConfig
import io.legado.app.help.coroutine.Coroutine
@ -1148,13 +1149,17 @@ class ReadBookActivity : BaseReadBookActivity(),
override fun finish() {
ReadBook.book?.let {
if (!ReadBook.inBookshelf) {
alert(title = getString(R.string.add_to_shelf)) {
setMessage(getString(R.string.check_add_bookshelf, it.name))
okButton {
ReadBook.inBookshelf = true
setResult(Activity.RESULT_OK)
if (!AppConfig.showAddToShelfAlert) {
viewModel.removeFromBookshelf { super.finish() }
} else {
alert(title = getString(R.string.add_to_shelf)) {
setMessage(getString(R.string.check_add_bookshelf, it.name))
okButton {
ReadBook.inBookshelf = true
setResult(Activity.RESULT_OK)
}
noButton { viewModel.removeFromBookshelf { super.finish() } }
}
noButton { viewModel.removeFromBookshelf { super.finish() } }
}
} else {
super.finish()

@ -66,6 +66,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
private var menu: Menu? = null
private var precisionSearchMenuItem: MenuItem? = null
private var groups = linkedSetOf<String>()
private var isManualStopSearch = false
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = searchFinish@{ isEmpty ->
val searchGroup = AppConfig.searchGroup
if (!isEmpty || searchGroup.isEmpty()) return@searchFinish
@ -155,6 +156,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
override fun onQueryTextSubmit(query: String?): Boolean {
searchView.clearFocus()
query?.let {
isManualStopSearch = false
viewModel.saveSearchKey(query)
viewModel.searchKey = ""
viewModel.search(it)
@ -221,6 +223,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
.setPressedColor(ColorUtils.darkenColor(accentColor))
.create()
binding.fbStop.setOnClickListener {
isManualStopSearch = true
viewModel.stop()
binding.refreshProgressBar.isAutoLoading = false
}
@ -266,6 +269,9 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
* 滚动到底部事件
*/
private fun scrollToBottom() {
if (isManualStopSearch) {
return
}
if (viewModel.isSearchLiveData.value == false
&& viewModel.searchKey.isNotEmpty()
&& loadMoreView.hasMore

@ -3,6 +3,7 @@ package io.legado.app.ui.config
import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.text.InputType
import android.view.Menu
import android.view.MenuInflater
@ -116,6 +117,14 @@ class BackupConfigFragment : PreferenceFragment(),
InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT
}
}
findPreference<EditTextPreference>(PreferKey.webDavDir)?.let {
it.setOnBindEditTextListener { editText ->
editText.text = AppConfig.webDavDir?.toEditable()
}
it.setOnPreferenceChangeListener { _, newValue ->
(newValue as String).isNotBlank()
}
}
upPreferenceSummary(PreferKey.webDavUrl, getPrefString(PreferKey.webDavUrl))
upPreferenceSummary(PreferKey.webDavAccount, getPrefString(PreferKey.webDavAccount))
upPreferenceSummary(PreferKey.webDavPassword, getPrefString(PreferKey.webDavPassword))

@ -63,6 +63,7 @@ class RssAdapter(context: Context, val callBack: CallBack) :
R.id.menu_top -> callBack.toTop(rssSource)
R.id.menu_edit -> callBack.edit(rssSource)
R.id.menu_del -> callBack.del(rssSource)
R.id.menu_disable -> callBack.disable(rssSource)
}
true
}
@ -74,5 +75,6 @@ class RssAdapter(context: Context, val callBack: CallBack) :
fun toTop(rssSource: RssSource)
fun edit(rssSource: RssSource)
fun del(rssSource: RssSource)
fun disable(rssSource: RssSource)
}
}

@ -123,7 +123,7 @@ class RssFragment : VMBaseFragment<RssSourceViewModel>(R.layout.fragment_rss),
private fun initGroupData() {
groupsFlowJob?.cancel()
groupsFlowJob = launch {
appDb.rssSourceDao.flowGroup().conflate().collect {
appDb.rssSourceDao.flowGroupEnabled().conflate().collect {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
@ -181,4 +181,8 @@ class RssFragment : VMBaseFragment<RssSourceViewModel>(R.layout.fragment_rss),
override fun del(rssSource: RssSource) {
viewModel.del(rssSource)
}
override fun disable(rssSource: RssSource) {
viewModel.disable(rssSource)
}
}

@ -65,7 +65,11 @@ class GroupManageDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
adapter.setItems(groups.toList())
adapter.setItems(
groups.sortedWith { o1, o2 ->
o1.cnCompare(o2)
}
)
}
}
}

@ -50,6 +50,9 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
override val viewModel by viewModels<RssSourceViewModel>()
private val importRecordKey = "rssSourceRecordKey"
private val adapter by lazy { RssSourceAdapter(this, this) }
private val searchView: SearchView by lazy {
binding.titleBar.findViewById(R.id.search_view)
}
private var sourceFlowJob: Job? = null
private var groups = hashSetOf<String>()
private var groupMenu: SubMenu? = null
@ -120,10 +123,21 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
R.id.menu_import_qr -> qrCodeResult.launch()
R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
R.id.menu_import_default -> viewModel.importDefault()
R.id.menu_enabled_group -> {
searchView.setQuery(getString(R.string.enabled), true)
}
R.id.menu_disabled_group -> {
searchView.setQuery(getString(R.string.disabled), true)
}
R.id.menu_group_login -> {
searchView.setQuery(getString(R.string.need_login), true)
}
R.id.menu_group_null -> {
searchView.setQuery(getString(R.string.no_group), true)
}
R.id.menu_help -> showHelp()
else -> if (item.groupId == R.id.source_group) {
binding.titleBar.findViewById<SearchView>(R.id.search_view)
.setQuery("group:${item.title}", true)
searchView.setQuery("group:${item.title}", true)
}
}
return super.onCompatOptionsItemSelected(item)
@ -144,6 +158,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
R.id.menu_share_source -> viewModel.saveToFile(adapter.selection) {
share(it)
}
R.id.menu_check_selected_interval -> adapter.checkSelectedInterval()
}
return true
}
@ -240,6 +255,18 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
searchKey.isNullOrBlank() -> {
appDb.rssSourceDao.flowAll()
}
searchKey == getString(R.string.enabled) -> {
appDb.rssSourceDao.flowEnabled()
}
searchKey == getString(R.string.disabled) -> {
appDb.rssSourceDao.flowDisabled()
}
searchKey == getString(R.string.need_login) -> {
appDb.rssSourceDao.flowLogin()
}
searchKey == getString(R.string.no_group) -> {
appDb.rssSourceDao.flowNoGroup()
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.rssSourceDao.flowGroupSearch(key)

@ -17,6 +17,7 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.utils.ColorUtils
import java.util.*
class RssSourceAdapter(context: Context, val callBack: CallBack) :
@ -151,6 +152,25 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
callBack.upCountView()
}
fun checkSelectedInterval() {
val selectedPosition = linkedSetOf<Int>()
getItems().forEachIndexed { index, it ->
if (selected.contains(it)) {
selectedPosition.add(index)
}
}
val minPosition = Collections.min(selectedPosition)
val maxPosition = Collections.max(selectedPosition)
val itemCount = maxPosition - minPosition + 1
for (i in minPosition..maxPosition) {
getItem(i)?.let {
selected.add(it)
}
}
notifyItemRangeChanged(minPosition, itemCount, bundleOf(Pair("selected", null)))
callBack.upCountView()
}
private fun showMenu(view: View, position: Int) {
val source = getItem(position) ?: return
val popupMenu = PopupMenu(context, view)

@ -133,4 +133,11 @@ class RssSourceViewModel(application: Application) : BaseViewModel(application)
}
}
fun disable(rssSource: RssSource) {
execute {
rssSource.enabled = false
appDb.rssSourceDao.update(rssSource)
}
}
}

@ -6,6 +6,7 @@ import io.legado.app.constant.AppPattern.dataUriRegex
import android.icu.text.Collator
import android.icu.util.ULocale
import android.net.Uri
import android.text.Editable
import java.io.File
import java.util.*
@ -13,6 +14,8 @@ fun String?.safeTrim() = if (this.isNullOrBlank()) null else this.trim()
fun String?.isContentScheme(): Boolean = this?.startsWith("content://") == true
fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this)
fun String.parseToUri(): Uri {
return if (isContentScheme()) {
Uri.parse(this)

@ -21,4 +21,8 @@
android:id="@+id/menu_change_source"
android:title="@string/change_source_batch" />
<item
android:id="@+id/menu_check_selected_interval"
android:title="@string/check_selected_interval" />
</menu>

@ -9,6 +9,10 @@
android:id="@+id/menu_edit"
android:title="@string/edit" />
<item
android:id="@+id/menu_disable"
android:title="@string/disable_source" />
<item
android:id="@+id/menu_del"
android:title="@string/delete" />

@ -16,6 +16,22 @@
android:id="@+id/menu_group_manage"
android:title="@string/group_manage" />
<item
android:id="@+id/menu_enabled_group"
android:title="@string/enabled" />
<item
android:id="@+id/menu_disabled_group"
android:title="@string/disabled" />
<item
android:id="@+id/menu_group_login"
android:title="@string/need_login" />
<item
android:id="@+id/menu_group_null"
android:title="@string/no_group" />
<group android:id="@+id/source_group">
</group>

@ -27,11 +27,14 @@
android:title="@string/export_selection"
app:showAsAction="never" />
<item
android:id="@+id/menu_share_source"
android:title="@string/share_selected_source"
app:showAsAction="never" />
<item
android:id="@+id/menu_check_selected_interval"
android:title="@string/check_selected_interval"
app:showAsAction="never" />
</menu>

@ -1008,4 +1008,6 @@
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="example">Ejemplo</string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -1011,4 +1011,6 @@
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="example"></string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -1011,4 +1011,6 @@
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="example">Exemplo</string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -1008,4 +1008,6 @@
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="example">示例</string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -1010,4 +1010,6 @@
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="example">示例</string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -1010,4 +1010,6 @@
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="example">示例</string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -1011,4 +1011,6 @@
<string name="page_touch_slop_dialog_title">滑动翻页阈值(0 = 系统默认值)</string>
<string name="page_touch_slop_summary">滑动多长距离才会触发滑动翻页(系统默认值 %s px)</string>
<string name="check_selected_interval">选中所选区间</string>
<string name="show_add_to_shelf_alert_title">返回时提示放入书架</string>
<string name="show_add_to_shelf_alert_summary">阅读未放入书架的书籍在返回时提示放入书架</string>
</resources>

@ -112,6 +112,12 @@
android:summary="@string/auto_clear_expired_summary"
android:title="@string/auto_clear_expired" />
<io.legado.app.lib.prefs.SwitchPreference
android:defaultValue="true"
android:key="showAddToShelfAlert"
android:summary="@string/show_add_to_shelf_alert_summary"
android:title="@string/show_add_to_shelf_alert_title" />
<io.legado.app.lib.prefs.Preference
android:key="webPort"
android:title="@string/web_port_title"

Loading…
Cancel
Save