Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -137,6 +137,7 @@ object PreferKey {
|
|||||||
const val openBookInfoByClickTitle = "openBookInfoByClickTitle"
|
const val openBookInfoByClickTitle = "openBookInfoByClickTitle"
|
||||||
const val defaultHomePage = "defaultHomePage"
|
const val defaultHomePage = "defaultHomePage"
|
||||||
const val showBookshelfFastScroller = "showBookshelfFastScroller"
|
const val showBookshelfFastScroller = "showBookshelfFastScroller"
|
||||||
|
const val importKeepEnable = "importKeepEnable"
|
||||||
|
|
||||||
const val cPrimary = "colorPrimary"
|
const val cPrimary = "colorPrimary"
|
||||||
const val cAccent = "colorAccent"
|
const val cAccent = "colorAccent"
|
||||||
|
|||||||
@@ -420,6 +420,11 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||||||
|
|
||||||
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)
|
||||||
|
var importKeepEnable: Boolean
|
||||||
|
get() = appCtx.getPrefBoolean(PreferKey.importKeepEnable, false)
|
||||||
|
set(value) {
|
||||||
|
appCtx.putPrefBoolean(PreferKey.importKeepEnable, value)
|
||||||
|
}
|
||||||
|
|
||||||
var preDownloadNum
|
var preDownloadNum
|
||||||
get() = appCtx.getPrefInt(PreferKey.preDownloadNum, 10)
|
get() = appCtx.getPrefInt(PreferKey.preDownloadNum, 10)
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ class ImportBookSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_vie
|
|||||||
?.isChecked = AppConfig.importKeepName
|
?.isChecked = AppConfig.importKeepName
|
||||||
binding.toolBar.menu.findItem(R.id.menu_keep_group)
|
binding.toolBar.menu.findItem(R.id.menu_keep_group)
|
||||||
?.isChecked = AppConfig.importKeepGroup
|
?.isChecked = AppConfig.importKeepGroup
|
||||||
|
binding.toolBar.menu.findItem(R.id.menu_keep_enable)
|
||||||
|
?.isChecked = AppConfig.importKeepEnable
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InflateParams", "NotifyDataSetChanged")
|
@SuppressLint("InflateParams", "NotifyDataSetChanged")
|
||||||
@@ -179,6 +181,11 @@ class ImportBookSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_vie
|
|||||||
item.isChecked = !item.isChecked
|
item.isChecked = !item.isChecked
|
||||||
putPrefBoolean(PreferKey.importKeepGroup, item.isChecked)
|
putPrefBoolean(PreferKey.importKeepGroup, item.isChecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.menu_keep_enable -> {
|
||||||
|
item.isChecked = !item.isChecked
|
||||||
|
AppConfig.importKeepEnable = item.isChecked
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
val group = groupName?.trim()
|
val group = groupName?.trim()
|
||||||
val keepName = AppConfig.importKeepName
|
val keepName = AppConfig.importKeepName
|
||||||
val keepGroup = AppConfig.importKeepGroup
|
val keepGroup = AppConfig.importKeepGroup
|
||||||
|
val keepEnable = AppConfig.importKeepEnable
|
||||||
val selectSource = arrayListOf<BookSource>()
|
val selectSource = arrayListOf<BookSource>()
|
||||||
selectStatus.forEachIndexed { index, b ->
|
selectStatus.forEachIndexed { index, b ->
|
||||||
if (b) {
|
if (b) {
|
||||||
@@ -98,6 +99,10 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
if (keepGroup) {
|
if (keepGroup) {
|
||||||
source.bookSourceGroup = it.bookSourceGroup
|
source.bookSourceGroup = it.bookSourceGroup
|
||||||
}
|
}
|
||||||
|
if (keepEnable) {
|
||||||
|
source.enabled = it.enabled
|
||||||
|
source.enabledExplore = it.enabledExplore
|
||||||
|
}
|
||||||
source.customOrder = it.customOrder
|
source.customOrder = it.customOrder
|
||||||
}
|
}
|
||||||
if (!group.isNullOrEmpty()) {
|
if (!group.isNullOrEmpty()) {
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ class ChangeBookSourceAdapter(
|
|||||||
override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
|
override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
|
||||||
return oldItem.originName == newItem.originName
|
return oldItem.originName == newItem.originName
|
||||||
&& oldItem.getDisplayLastChapterTitle() == newItem.getDisplayLastChapterTitle()
|
&& oldItem.getDisplayLastChapterTitle() == newItem.getDisplayLastChapterTitle()
|
||||||
|
&& oldItem.chapterWordCountText == newItem.chapterWordCountText
|
||||||
|
&& oldItem.respondTime == newItem.respondTime
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
|
|||||||
private val adapter by lazy { ChangeBookSourceAdapter(requireContext(), viewModel, this) }
|
private val adapter by lazy { ChangeBookSourceAdapter(requireContext(), viewModel, this) }
|
||||||
private val editSourceResult =
|
private val editSourceResult =
|
||||||
registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
|
registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
|
||||||
viewModel.startSearch()
|
val origin = it.data?.getStringExtra("origin") ?: return@registerForActivityResult
|
||||||
|
viewModel.startSearch(origin)
|
||||||
}
|
}
|
||||||
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
|
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
|
||||||
if (it) {
|
if (it) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource
|
|||||||
import io.legado.app.data.entities.SearchBook
|
import io.legado.app.data.entities.SearchBook
|
||||||
import io.legado.app.exception.NoStackTraceException
|
import io.legado.app.exception.NoStackTraceException
|
||||||
import io.legado.app.help.book.BookHelp
|
import io.legado.app.help.book.BookHelp
|
||||||
|
import io.legado.app.help.book.ContentProcessor
|
||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.help.config.SourceConfig
|
import io.legado.app.help.config.SourceConfig
|
||||||
import io.legado.app.help.coroutine.CompositeCoroutine
|
import io.legado.app.help.coroutine.CompositeCoroutine
|
||||||
@@ -50,8 +51,25 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
private var searchBookList = arrayListOf<SearchBook>()
|
private var searchBookList = arrayListOf<SearchBook>()
|
||||||
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
|
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
|
||||||
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
|
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
|
||||||
|
private val contentProcessor by lazy {
|
||||||
|
ContentProcessor.get(oldBook!!)
|
||||||
|
}
|
||||||
private var searchCallback: SourceCallback? = null
|
private var searchCallback: SourceCallback? = null
|
||||||
private val emptyBookSource = BookSource()
|
private val emptyBookSource = BookSource()
|
||||||
|
private val chapterNumRegex = "^\\[(\\d+)]".toRegex()
|
||||||
|
private val comparatorBase by lazy {
|
||||||
|
compareByDescending<SearchBook> { getBookScore(it) }
|
||||||
|
.thenByDescending { SourceConfig.getSourceScore(it.origin) }
|
||||||
|
}
|
||||||
|
private val defaultComparator by lazy {
|
||||||
|
comparatorBase.thenBy { it.originOrder }
|
||||||
|
}
|
||||||
|
private val wordCountComparator by lazy {
|
||||||
|
comparatorBase.thenByDescending { it.chapterWordCount > 1000 }
|
||||||
|
.thenByDescending { getChapterNum(it.chapterWordCountText) }
|
||||||
|
.thenByDescending { it.chapterWordCount }
|
||||||
|
.thenBy { it.originOrder }
|
||||||
|
}
|
||||||
val bookMap = ConcurrentHashMap<String, Book>()
|
val bookMap = ConcurrentHashMap<String, Book>()
|
||||||
val searchDataFlow = callbackFlow {
|
val searchDataFlow = callbackFlow {
|
||||||
|
|
||||||
@@ -88,26 +106,12 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
}
|
}
|
||||||
}.map {
|
}.map {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
searchBooks.sortedWith { o1, o2 ->
|
val comparator = if (AppConfig.changeSourceLoadWordCount) {
|
||||||
val o1bs = SourceConfig.getBookScore(o1.origin, o1.name, o1.author)
|
wordCountComparator
|
||||||
val o2bs = SourceConfig.getBookScore(o2.origin, o2.name, o2.author)
|
} else {
|
||||||
when {
|
defaultComparator
|
||||||
o1bs - o2bs > 0 -> -1
|
|
||||||
o1bs - o2bs < 0 -> 1
|
|
||||||
else -> {
|
|
||||||
val o1ss = SourceConfig.getSourceScore(o1.origin)
|
|
||||||
val o2ss = SourceConfig.getSourceScore(o2.origin)
|
|
||||||
when {
|
|
||||||
o1ss - o2ss > 0 -> -1
|
|
||||||
o1ss - o2ss < 0 -> 1
|
|
||||||
else -> {
|
|
||||||
val n = o1.originOrder - o2.originOrder
|
|
||||||
if (n == 0) -1 else n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
searchBooks.sortedWith(comparator)
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
AppLog.put("换源排序出错\n${it.localizedMessage}", it)
|
AppLog.put("换源排序出错\n${it.localizedMessage}", it)
|
||||||
}.getOrDefault(searchBooks)
|
}.getOrDefault(searchBooks)
|
||||||
@@ -153,9 +157,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
/**
|
/**
|
||||||
* 搜索书籍
|
* 搜索书籍
|
||||||
*/
|
*/
|
||||||
fun startSearch() {
|
fun startSearch(origin: String? = null) {
|
||||||
execute {
|
execute {
|
||||||
stopSearch()
|
stopSearch()
|
||||||
|
origin?.let {
|
||||||
|
bookSourceList.clear()
|
||||||
|
bookSourceList.add(appDb.bookSourceDao.getBookSource(origin)!!)
|
||||||
|
searchStateData.postValue(true)
|
||||||
|
searchBooks.removeIf { it.origin == origin }
|
||||||
|
initSearchPool()
|
||||||
|
search()
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
appDb.searchBookDao.clear(name, author)
|
appDb.searchBookDao.clear(name, author)
|
||||||
searchBooks.clear()
|
searchBooks.clear()
|
||||||
searchCallback?.upAdapter()
|
searchCallback?.upAdapter()
|
||||||
@@ -182,7 +195,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
|
|
||||||
private fun search() {
|
private fun search() {
|
||||||
val searchIndex = synchronized(this) {
|
val searchIndex = synchronized(this) {
|
||||||
if (searchIndex >= bookSourceList.lastIndex) {
|
if (searchIndex > bookSourceList.lastIndex) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
searchIndex++
|
searchIndex++
|
||||||
@@ -256,17 +269,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
)
|
)
|
||||||
} ?: chapters.lastIndex
|
} ?: chapters.lastIndex
|
||||||
} else chapters.lastIndex
|
} else chapters.lastIndex
|
||||||
val bookChapter = chapters.getOrNull(chapterIndex)
|
val bookChapter = chapters[chapterIndex]
|
||||||
|
val title = bookChapter.title.trim()
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
val pair = try {
|
val pair = try {
|
||||||
if (bookChapter == null) throw NoStackTraceException("章节缺失,总章节数${chapters.size}")
|
|
||||||
val nextChapterUrl = chapters.getOrNull(chapterIndex + 1)?.url
|
val nextChapterUrl = chapters.getOrNull(chapterIndex + 1)?.url
|
||||||
WebBook.getContentAwait(source, book, bookChapter, nextChapterUrl, false).length.let {
|
var content = WebBook.getContentAwait(source, book, bookChapter, nextChapterUrl, false)
|
||||||
it to "第${chapterIndex + 1}章 字数:${it}"
|
content = contentProcessor.getContent(oldBook!!, bookChapter, content, false).toString()
|
||||||
}
|
val len = content.length
|
||||||
|
len to "[${chapterIndex + 1}] ${title}\n字数:${len}"
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
if (t is CancellationException) throw t
|
if (t is CancellationException) throw t
|
||||||
-1 to "第${chapterIndex + 1}章 获取字数失败:${t.localizedMessage}"
|
-1 to "[${chapterIndex + 1}] ${title}\n获取字数失败:${t.localizedMessage}"
|
||||||
}
|
}
|
||||||
val endTime = System.currentTimeMillis()
|
val endTime = System.currentTimeMillis()
|
||||||
val searchBook = book.toSearchBook().apply {
|
val searchBook = book.toSearchBook().apply {
|
||||||
@@ -526,6 +540,11 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
return SourceConfig.getBookScore(searchBook.origin, searchBook.name, searchBook.author)
|
return SourceConfig.getBookScore(searchBook.origin, searchBook.name, searchBook.author)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getChapterNum(wordCountText: String?): Int {
|
||||||
|
wordCountText ?: return -1
|
||||||
|
return chapterNumRegex.find(wordCountText)?.groupValues?.get(1)?.toIntOrNull() ?: -1
|
||||||
|
}
|
||||||
|
|
||||||
interface SourceCallback {
|
interface SourceCallback {
|
||||||
|
|
||||||
fun searchSuccess(searchBook: SearchBook)
|
fun searchSuccess(searchBook: SearchBook)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.legado.app.ui.book.source.edit
|
package io.legado.app.ui.book.source.edit
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@@ -119,7 +120,7 @@ class BookSourceEditActivity :
|
|||||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_save -> viewModel.save(getSource()) {
|
R.id.menu_save -> viewModel.save(getSource()) {
|
||||||
setResult(Activity.RESULT_OK)
|
setResult(Activity.RESULT_OK, Intent().putExtra("origin", it.bookSourceUrl))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,8 +411,8 @@ class BookSourceEditActivity :
|
|||||||
"intro" -> searchRule.intro =
|
"intro" -> searchRule.intro =
|
||||||
viewModel.ruleComplete(it.value, searchRule.bookList)
|
viewModel.ruleComplete(it.value, searchRule.bookList)
|
||||||
|
|
||||||
"updateTime" -> searchRule.updateTime =
|
// "updateTime" -> searchRule.updateTime =
|
||||||
viewModel.ruleComplete(it.value, searchRule.bookList)
|
// viewModel.ruleComplete(it.value, searchRule.bookList)
|
||||||
|
|
||||||
"wordCount" -> searchRule.wordCount =
|
"wordCount" -> searchRule.wordCount =
|
||||||
viewModel.ruleComplete(it.value, searchRule.bookList)
|
viewModel.ruleComplete(it.value, searchRule.bookList)
|
||||||
@@ -442,8 +443,8 @@ class BookSourceEditActivity :
|
|||||||
"intro" -> exploreRule.intro =
|
"intro" -> exploreRule.intro =
|
||||||
viewModel.ruleComplete(it.value, exploreRule.bookList)
|
viewModel.ruleComplete(it.value, exploreRule.bookList)
|
||||||
|
|
||||||
"updateTime" -> exploreRule.updateTime =
|
// "updateTime" -> exploreRule.updateTime =
|
||||||
viewModel.ruleComplete(it.value, exploreRule.bookList)
|
// viewModel.ruleComplete(it.value, exploreRule.bookList)
|
||||||
|
|
||||||
"wordCount" -> exploreRule.wordCount =
|
"wordCount" -> exploreRule.wordCount =
|
||||||
viewModel.ruleComplete(it.value, exploreRule.bookList)
|
viewModel.ruleComplete(it.value, exploreRule.bookList)
|
||||||
@@ -471,8 +472,8 @@ class BookSourceEditActivity :
|
|||||||
"intro" -> bookInfoRule.intro =
|
"intro" -> bookInfoRule.intro =
|
||||||
viewModel.ruleComplete(it.value, bookInfoRule.init)
|
viewModel.ruleComplete(it.value, bookInfoRule.init)
|
||||||
|
|
||||||
"updateTime" -> bookInfoRule.updateTime =
|
// "updateTime" -> bookInfoRule.updateTime =
|
||||||
viewModel.ruleComplete(it.value, bookInfoRule.init)
|
// viewModel.ruleComplete(it.value, bookInfoRule.init)
|
||||||
|
|
||||||
"wordCount" -> bookInfoRule.wordCount =
|
"wordCount" -> bookInfoRule.wordCount =
|
||||||
viewModel.ruleComplete(it.value, bookInfoRule.init)
|
viewModel.ruleComplete(it.value, bookInfoRule.init)
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
|
|||||||
if (source.bookSourceUrl.isBlank() || source.bookSourceName.isBlank()) {
|
if (source.bookSourceUrl.isBlank() || source.bookSourceName.isBlank()) {
|
||||||
throw NoStackTraceException(context.getString(R.string.non_null_name_url))
|
throw NoStackTraceException(context.getString(R.string.non_null_name_url))
|
||||||
}
|
}
|
||||||
if (!source.equal(bookSource ?: BookSource())) {
|
if (source.equal(bookSource ?: BookSource())) {
|
||||||
source.lastUpdateTime = System.currentTimeMillis()
|
return@execute source
|
||||||
}
|
}
|
||||||
bookSource?.let {
|
bookSource?.let {
|
||||||
appDb.bookSourceDao.delete(it)
|
appDb.bookSourceDao.delete(it)
|
||||||
@@ -91,6 +91,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
|
|||||||
val text1 = okHttpClient.newCallStrResponse { url(text) }.body
|
val text1 = okHttpClient.newCallStrResponse { url(text) }.body
|
||||||
importSource(text1!!)
|
importSource(text1!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
text.isJsonArray() -> {
|
text.isJsonArray() -> {
|
||||||
if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {
|
if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {
|
||||||
val items: List<Map<String, Any>> = jsonPath.parse(text).read("$")
|
val items: List<Map<String, Any>> = jsonPath.parse(text).read("$")
|
||||||
@@ -100,6 +101,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
|
|||||||
GSON.fromJsonArray<BookSource>(text).getOrThrow()[0]
|
GSON.fromJsonArray<BookSource>(text).getOrThrow()[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text.isJsonObject() -> {
|
text.isJsonObject() -> {
|
||||||
if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {
|
if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {
|
||||||
val jsonItem = jsonPath.parse(text)
|
val jsonItem = jsonPath.parse(text)
|
||||||
@@ -108,6 +110,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
|
|||||||
GSON.fromJsonObject<BookSource>(text).getOrThrow()
|
GSON.fromJsonObject<BookSource>(text).getOrThrow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> throw NoStackTraceException("格式不对")
|
else -> throw NoStackTraceException("格式不对")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
tools:text="word count"
|
tools:text="word count"
|
||||||
android:textColor="@color/secondaryText"
|
android:textColor="@color/secondaryText"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toLeftOf="@+id/iv_checked"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tv_last" />
|
app:layout_constraintTop_toBottomOf="@+id/tv_last" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
android:textColor="@color/secondaryText"
|
android:textColor="@color/secondaryText"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toLeftOf="@+id/iv_checked"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tv_current_chapter_word_count" />
|
app:layout_constraintTop_toBottomOf="@+id/tv_current_chapter_word_count" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
|||||||
@@ -31,4 +31,10 @@
|
|||||||
android:checkable="true"
|
android:checkable="true"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
<item
|
||||||
|
android:id="@+id/menu_keep_enable"
|
||||||
|
android:title="@string/keep_enable"
|
||||||
|
android:checkable="true"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
|
|||||||
@@ -1131,4 +1131,5 @@
|
|||||||
<string name="default_home_page">默认主页</string>
|
<string name="default_home_page">默认主页</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1134,4 +1134,5 @@
|
|||||||
<string name="default_home_page">默认主页</string>
|
<string name="default_home_page">默认主页</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1134,4 +1134,5 @@
|
|||||||
<string name="default_home_page">默认主页</string>
|
<string name="default_home_page">默认主页</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1129,4 +1129,5 @@ Còn </string>
|
|||||||
<string name="export_wait">等待导出</string>
|
<string name="export_wait">等待导出</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1130,4 +1130,5 @@
|
|||||||
<string name="export_wait">等待导出</string>
|
<string name="export_wait">等待导出</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1132,4 +1132,5 @@
|
|||||||
<string name="export_wait">等待导出</string>
|
<string name="export_wait">等待导出</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1132,4 +1132,5 @@
|
|||||||
<string name="export_wait">等待导出</string>
|
<string name="export_wait">等待导出</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1134,4 +1134,5 @@
|
|||||||
<string name="default_home_page">默认主页</string>
|
<string name="default_home_page">默认主页</string>
|
||||||
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
|
||||||
<string name="export_all_use_book_source">导出所有书的书源</string>
|
<string name="export_all_use_book_source">导出所有书的书源</string>
|
||||||
|
<string name="keep_enable">保留启用状态</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user