fix: 迁移换源配置到 DataStore

This commit is contained in:
HapeLee
2026-06-14 13:20:45 +08:00
parent 3577de5f69
commit fef2ebd990
10 changed files with 144 additions and 76 deletions
@@ -82,10 +82,6 @@ object PreferKey {
const val exportNoChapterName = "exportNoChapterName"
const val exportType = "exportType"
const val exportPictureFile = "exportPictureFile"
const val changeSourceCheckAuthor = "changeSourceCheckAuthor"
const val changeSourceLoadToc = "changeSourceLoadToc"
const val changeSourceLoadInfo = "changeSourceLoadInfo"
const val changeSourceLoadWordCount = "changeSourceLoadWordCount"
const val chineseConverterType = "chineseConverterType"
const val launcherIcon = "launcherIcon"
const val textSelectAble = "selectText"
@@ -24,4 +24,11 @@ object LocalPreferencesKeys {
val PASSWORD = stringPreferencesKey("password")
val PRIVACY_POLICY_OK = booleanPreferencesKey("privacy_policy_ok")
val PERMISSION_CHECKED = booleanPreferencesKey("permission_checked")
// Change source options
val CHANGE_SOURCE_CHECK_AUTHOR = booleanPreferencesKey("changeSourceCheckAuthor")
val CHANGE_SOURCE_LOAD_INFO = booleanPreferencesKey("changeSourceLoadInfo")
val CHANGE_SOURCE_LOAD_TOC = booleanPreferencesKey("changeSourceLoadToc")
val CHANGE_SOURCE_LOAD_WORD_COUNT = booleanPreferencesKey("changeSourceLoadWordCount")
val CHANGE_SOURCE_SEARCH_SCOPE = stringPreferencesKey("changeSourceSearchScope")
}
@@ -9,7 +9,7 @@ import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.ContentProcessor
import io.legado.app.help.book.primaryStr
import io.legado.app.help.book.releaseHtmlData
import io.legado.app.help.config.AppConfig
import io.legado.app.ui.book.changesource.ChangeSourceConfig
import io.legado.app.help.source.SourceHelp
import io.legado.app.model.webBook.WebBook
import io.legado.app.ui.book.changesource.ObservableSourceConfig
@@ -135,10 +135,10 @@ class ChangeSourceSearchUseCase(
fromReadBookActivity: Boolean,
contentProcessor: ContentProcessor,
): List<SearchBook> {
val checkAuthor = AppConfig.changeSourceCheckAuthor
val loadInfo = AppConfig.changeSourceLoadInfo
val loadToc = AppConfig.changeSourceLoadToc
val loadWordCount = AppConfig.changeSourceLoadWordCount
val checkAuthor = ChangeSourceConfig.checkAuthor
val loadInfo = ChangeSourceConfig.loadInfo
val loadToc = ChangeSourceConfig.loadToc
val loadWordCount = ChangeSourceConfig.loadWordCount
val resultBooks = WebBook.searchBookAwait(
source, name,
@@ -465,12 +465,6 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
appCtx.putPrefBoolean(PreferKey.parallelExportBook, value)
}
var changeSourceCheckAuthor: Boolean
get() = appCtx.getPrefBoolean(PreferKey.changeSourceCheckAuthor)
set(value) {
appCtx.putPrefBoolean(PreferKey.changeSourceCheckAuthor, value)
}
var ttsEngine: String?
get() = io.legado.app.ui.config.readConfig.ReadConfig.ttsEngine
set(value) {
@@ -504,24 +498,6 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
val autoChangeSource: Boolean
get() = ReadConfig.autoChangeSource
var changeSourceLoadInfo: Boolean
get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadInfo)
set(value) {
appCtx.putPrefBoolean(PreferKey.changeSourceLoadInfo, value)
}
var changeSourceLoadToc: Boolean
get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadToc)
set(value) {
appCtx.putPrefBoolean(PreferKey.changeSourceLoadToc, value)
}
var changeSourceLoadWordCount: Boolean
get() = appCtx.getPrefBoolean(PreferKey.changeSourceLoadWordCount)
set(value) {
appCtx.putPrefBoolean(PreferKey.changeSourceLoadWordCount, value)
}
var openBookInfoByClickTitle: Boolean
get() = appCtx.getPrefBoolean(PreferKey.openBookInfoByClickTitle, true)
set(value) {
@@ -11,7 +11,6 @@ import io.legado.app.base.adapter.DiffRecyclerAdapter
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemChangeSourceBinding
import io.legado.app.help.config.AppConfig
import io.legado.app.lib.dialogs.alert
import io.legado.app.utils.gone
import io.legado.app.utils.invisible
@@ -91,13 +90,13 @@ class ChangeBookSourceAdapter(
binding.ivGood.setImageResource(R.drawable.ic_praise)
}
if (AppConfig.changeSourceLoadWordCount && !item.chapterWordCountText.isNullOrBlank()) {
if (ChangeSourceConfig.loadWordCount && !item.chapterWordCountText.isNullOrBlank()) {
tvCurrentChapterWordCount.visible()
} else {
tvCurrentChapterWordCount.gone()
}
if (AppConfig.changeSourceLoadWordCount && item.respondTime >= 0) {
if (ChangeSourceConfig.loadWordCount && item.respondTime >= 0) {
tvRespondTime.visible()
} else {
tvRespondTime.gone()
@@ -227,11 +227,13 @@ class ChangeBookSourceComposeViewModel(
fun onLoadInfoChange(enabled: Boolean) {
if (ChangeSourceConfig.loadInfo == enabled) return
ChangeSourceConfig.loadInfo = enabled
refresh()
}
fun onLoadTocChange(enabled: Boolean) {
if (ChangeSourceConfig.loadToc == enabled) return
ChangeSourceConfig.loadToc = enabled
refresh()
}
fun onLoadWordCountChange(enabled: Boolean) {
@@ -29,7 +29,6 @@ import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.DialogBookChangeSourceBinding
import io.legado.app.help.config.AppConfig
import io.legado.app.lib.dialogs.alert
import io.legado.app.model.ReadBook
import io.legado.app.ui.book.search.SearchScope
@@ -133,13 +132,13 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
binding.toolBar.menu.applyTint(requireContext())
binding.toolBar.setOnMenuItemClickListener(this)
binding.toolBar.menu.findItem(R.id.menu_check_author)
?.isChecked = AppConfig.changeSourceCheckAuthor
?.isChecked = ChangeSourceConfig.checkAuthor
binding.toolBar.menu.findItem(R.id.menu_load_info)
?.isChecked = AppConfig.changeSourceLoadInfo
?.isChecked = ChangeSourceConfig.loadInfo
binding.toolBar.menu.findItem(R.id.menu_load_toc)
?.isChecked = AppConfig.changeSourceLoadToc
?.isChecked = ChangeSourceConfig.loadToc
binding.toolBar.menu.findItem(R.id.menu_load_word_count)
?.isChecked = AppConfig.changeSourceLoadWordCount
?.isChecked = ChangeSourceConfig.loadWordCount
}
private fun initRecyclerView() {
@@ -316,23 +315,25 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_check_author -> {
AppConfig.changeSourceCheckAuthor = !item.isChecked
ChangeSourceConfig.checkAuthor = !item.isChecked
item.isChecked = !item.isChecked
viewModel.refresh()
}
R.id.menu_load_info -> {
AppConfig.changeSourceLoadInfo = !item.isChecked
ChangeSourceConfig.loadInfo = !item.isChecked
item.isChecked = !item.isChecked
viewModel.refresh()
}
R.id.menu_load_toc -> {
AppConfig.changeSourceLoadToc = !item.isChecked
ChangeSourceConfig.loadToc = !item.isChecked
item.isChecked = !item.isChecked
viewModel.refresh()
}
R.id.menu_load_word_count -> {
AppConfig.changeSourceLoadWordCount = !item.isChecked
ChangeSourceConfig.loadWordCount = !item.isChecked
item.isChecked = !item.isChecked
viewModel.onLoadWordCountChecked(item.isChecked)
}
@@ -19,7 +19,6 @@ import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.ContentProcessor
import io.legado.app.help.book.primaryStr
import io.legado.app.help.book.releaseHtmlData
import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.SourceConfig
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.source.SourceHelp
@@ -137,7 +136,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
}.map {
kotlin.runCatching {
val comparator = if (AppConfig.changeSourceLoadWordCount) {
val comparator = if (ChangeSourceConfig.loadWordCount) {
wordCountComparator
} else {
defaultComparator
@@ -269,10 +268,10 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
private suspend fun search(source: BookSource) {
val checkAuthor = AppConfig.changeSourceCheckAuthor
val loadInfo = AppConfig.changeSourceLoadInfo
val loadToc = AppConfig.changeSourceLoadToc
val loadWordCount = AppConfig.changeSourceLoadWordCount
val checkAuthor = ChangeSourceConfig.checkAuthor
val loadInfo = ChangeSourceConfig.loadInfo
val loadToc = ChangeSourceConfig.loadToc
val loadWordCount = ChangeSourceConfig.loadWordCount
val resultBooks = WebBook.searchBookAwait(
source, name,
filter = { fName, fAuthor, _ ->
@@ -295,7 +294,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
if (book.tocUrl.isEmpty()) {
WebBook.getBookInfoAwait(source, book)
}
if (AppConfig.changeSourceLoadToc || AppConfig.changeSourceLoadWordCount) {
if (ChangeSourceConfig.loadToc || ChangeSourceConfig.loadWordCount) {
loadBookToc(source, book)
} else {
//从详情页里获取最新章节
@@ -315,7 +314,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
bookMap[book.primaryStr()] = book
book.releaseHtmlData()
if (AppConfig.changeSourceLoadWordCount) {
if (ChangeSourceConfig.loadWordCount) {
loadBookWordCount(source, book, chapters)
} else {
val searchBook = book.toSearchBook()
@@ -418,13 +417,13 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
else -> searchScope.displayNames.firstOrNull() ?: ""
}
return if (screenKey.isEmpty()) {
if (AppConfig.changeSourceCheckAuthor) {
if (ChangeSourceConfig.checkAuthor) {
appDb.searchBookDao.changeSourceByGroup(name, author, group)
} else {
appDb.searchBookDao.changeSourceByGroup(name, "", group)
}
} else {
if (AppConfig.changeSourceCheckAuthor) {
if (ChangeSourceConfig.checkAuthor) {
appDb.searchBookDao.changeSourceSearch(name, author, screenKey, group)
} else {
appDb.searchBookDao.changeSourceSearch(name, "", screenKey, group)
@@ -133,11 +133,13 @@ class ChangeChapterSourceViewModel(
is ChangeChapterSourceIntent.SetLoadInfo -> {
ChangeSourceConfig.loadInfo = intent.enabled
_uiState.update { it.copy(loadInfo = intent.enabled) }
refreshResults()
}
is ChangeChapterSourceIntent.SetLoadToc -> {
ChangeSourceConfig.loadToc = intent.enabled
_uiState.update { it.copy(loadToc = intent.enabled) }
refreshResults()
}
is ChangeChapterSourceIntent.SetLoadWordCount -> {
@@ -1,35 +1,83 @@
package io.legado.app.ui.book.changesource
import io.legado.app.constant.PreferKey
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.Snapshot
import io.legado.app.data.local.preferences.LocalPreferencesKeys
import io.legado.app.data.local.preferences.LocalPreferencesRepository
import io.legado.app.domain.usecase.ChangeSourceMigrationOptions
import io.legado.app.ui.config.prefDelegate
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import splitties.init.appCtx
object ChangeSourceConfig {
var searchScope by prefDelegate(
key = "changeSourceSearchScope",
defaultValue = ""
)
private val repo = LocalPreferencesRepository(appCtx)
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
var checkAuthor by prefDelegate(
key = PreferKey.changeSourceCheckAuthor,
defaultValue = false
)
private val _searchScope = mutableStateOf("")
var searchScope: String
get() = _searchScope.value
set(value) {
if (_searchScope.value != value) {
Snapshot.withMutableSnapshot { _searchScope.value = value }
scope.launch {
repo.updatePreference(LocalPreferencesKeys.CHANGE_SOURCE_SEARCH_SCOPE, value)
}
}
}
var loadInfo by prefDelegate(
key = PreferKey.changeSourceLoadInfo,
defaultValue = false
)
private val _checkAuthor = mutableStateOf(false)
var checkAuthor: Boolean
get() = _checkAuthor.value
set(value) {
if (_checkAuthor.value != value) {
Snapshot.withMutableSnapshot { _checkAuthor.value = value }
scope.launch {
repo.updatePreference(LocalPreferencesKeys.CHANGE_SOURCE_CHECK_AUTHOR, value)
}
}
}
var loadToc by prefDelegate(
key = PreferKey.changeSourceLoadToc,
defaultValue = false
)
private val _loadInfo = mutableStateOf(false)
var loadInfo: Boolean
get() = _loadInfo.value
set(value) {
if (_loadInfo.value != value) {
Snapshot.withMutableSnapshot { _loadInfo.value = value }
scope.launch {
repo.updatePreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_INFO, value)
}
}
}
var loadWordCount by prefDelegate(
key = PreferKey.changeSourceLoadWordCount,
defaultValue = false
)
private val _loadToc = mutableStateOf(false)
var loadToc: Boolean
get() = _loadToc.value
set(value) {
if (_loadToc.value != value) {
Snapshot.withMutableSnapshot { _loadToc.value = value }
scope.launch {
repo.updatePreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_TOC, value)
}
}
}
private val _loadWordCount = mutableStateOf(false)
var loadWordCount: Boolean
get() = _loadWordCount.value
set(value) {
if (_loadWordCount.value != value) {
Snapshot.withMutableSnapshot { _loadWordCount.value = value }
scope.launch {
repo.updatePreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_WORD_COUNT, value)
}
}
}
var migrateChapters by prefDelegate(
key = "migrateChapters",
@@ -64,6 +112,44 @@ object ChangeSourceConfig {
defaultValue = false
)
init {
runBlocking(Dispatchers.IO) {
Snapshot.withMutableSnapshot {
_searchScope.value =
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_SEARCH_SCOPE, "").first()
_checkAuthor.value =
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_CHECK_AUTHOR, false).first()
_loadInfo.value =
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_INFO, false).first()
_loadToc.value =
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_TOC, false).first()
_loadWordCount.value =
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_WORD_COUNT, false).first()
}
}
scope.launch {
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_SEARCH_SCOPE, "")
.collect { Snapshot.withMutableSnapshot { _searchScope.value = it } }
}
scope.launch {
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_CHECK_AUTHOR, false)
.collect { Snapshot.withMutableSnapshot { _checkAuthor.value = it } }
}
scope.launch {
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_INFO, false)
.collect { Snapshot.withMutableSnapshot { _loadInfo.value = it } }
}
scope.launch {
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_TOC, false)
.collect { Snapshot.withMutableSnapshot { _loadToc.value = it } }
}
scope.launch {
repo.getPreference(LocalPreferencesKeys.CHANGE_SOURCE_LOAD_WORD_COUNT, false)
.collect { Snapshot.withMutableSnapshot { _loadWordCount.value = it } }
}
}
fun getMigrationOptions(): ChangeSourceMigrationOptions {
return ChangeSourceMigrationOptions(
migrateChapters = migrateChapters,