Merge branch 'gedoor:master' into master
This commit is contained in:
@@ -11,6 +11,11 @@
|
|||||||
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
|
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
|
||||||
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
|
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
|
||||||
|
|
||||||
|
**2022/02/10**
|
||||||
|
|
||||||
|
* 可以单独给书籍设置朗读tts
|
||||||
|
* 目录界面菜单添加替换开关,开启替换加载时间会长一些
|
||||||
|
|
||||||
**2022/02/09**
|
**2022/02/09**
|
||||||
|
|
||||||
* 校验失效分组具体到搜索发现目录正文 by Xwite
|
* 校验失效分组具体到搜索发现目录正文 by Xwite
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ object PreferKey {
|
|||||||
const val defaultBookTreeUri = "defaultBookTreeUri"
|
const val defaultBookTreeUri = "defaultBookTreeUri"
|
||||||
const val checkSource = "checkSource"
|
const val checkSource = "checkSource"
|
||||||
const val uploadRule = "uploadRule"
|
const val uploadRule = "uploadRule"
|
||||||
|
const val tocUiUseReplace = "tocUiUseReplace"
|
||||||
|
|
||||||
const val cPrimary = "colorPrimary"
|
const val cPrimary = "colorPrimary"
|
||||||
const val cAccent = "colorAccent"
|
const val cAccent = "colorAccent"
|
||||||
|
|||||||
@@ -250,6 +250,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||||||
appCtx.putPrefInt(PreferKey.webPort, value)
|
appCtx.putPrefInt(PreferKey.webPort, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tocUiUseReplace: Boolean
|
||||||
|
get() = appCtx.getPrefBoolean(PreferKey.tocUiUseReplace)
|
||||||
|
set(value) {
|
||||||
|
appCtx.putPrefBoolean(PreferKey.tocUiUseReplace, value)
|
||||||
|
}
|
||||||
|
|
||||||
val autoChangeSource: Boolean
|
val autoChangeSource: Boolean
|
||||||
get() = appCtx.getPrefBoolean(PreferKey.autoChangeSource, true)
|
get() = appCtx.getPrefBoolean(PreferKey.autoChangeSource, true)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ object DirectLinkUpload {
|
|||||||
private const val downloadUrlRuleKey = "directLinkDownloadUrlRule"
|
private const val downloadUrlRuleKey = "directLinkDownloadUrlRule"
|
||||||
private const val summaryKey = "directSummary"
|
private const val summaryKey = "directSummary"
|
||||||
|
|
||||||
|
@Throws(NoStackTraceException::class)
|
||||||
suspend fun upLoad(fileName: String, file: Any, contentType: String): String {
|
suspend fun upLoad(fileName: String, file: Any, contentType: String): String {
|
||||||
val url = getUploadUrl()
|
val url = getUploadUrl()
|
||||||
if (url.isNullOrBlank()) {
|
if (url.isNullOrBlank()) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import io.legado.app.utils.activityPendingIntent
|
|||||||
import io.legado.app.utils.postEvent
|
import io.legado.app.utils.postEvent
|
||||||
import io.legado.app.utils.servicePendingIntent
|
import io.legado.app.utils.servicePendingIntent
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.asCoroutineDispatcher
|
import kotlinx.coroutines.asCoroutineDispatcher
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@@ -204,8 +205,9 @@ class CheckSourceService : BaseService() {
|
|||||||
"" else "\n\n${source.bookSourceComment}"
|
"" else "\n\n${source.bookSourceComment}"
|
||||||
Debug.updateFinalMessage(source.bookSourceUrl, "校验失败:${it.localizedMessage}")
|
Debug.updateFinalMessage(source.bookSourceUrl, "校验失败:${it.localizedMessage}")
|
||||||
}.onSuccess(searchCoroutine) {
|
}.onSuccess(searchCoroutine) {
|
||||||
|
source.removeGroup("失效")
|
||||||
Debug.updateFinalMessage(source.bookSourceUrl, "校验成功")
|
Debug.updateFinalMessage(source.bookSourceUrl, "校验成功")
|
||||||
}.onFinally(searchCoroutine) {
|
}.onFinally(IO) {
|
||||||
source.respondTime = Debug.getRespondTime(source.bookSourceUrl)
|
source.respondTime = Debug.getRespondTime(source.bookSourceUrl)
|
||||||
appDb.bookSourceDao.update(source)
|
appDb.bookSourceDao.update(source)
|
||||||
onNext(source.bookSourceUrl, source.bookSourceName)
|
onNext(source.bookSourceUrl, source.bookSourceName)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.os.Bundle
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.RadioButton
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
@@ -21,15 +22,17 @@ import io.legado.app.help.AppConfig
|
|||||||
import io.legado.app.help.DirectLinkUpload
|
import io.legado.app.help.DirectLinkUpload
|
||||||
import io.legado.app.lib.dialogs.SelectItem
|
import io.legado.app.lib.dialogs.SelectItem
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
import io.legado.app.lib.dialogs.selector
|
|
||||||
import io.legado.app.lib.theme.primaryColor
|
import io.legado.app.lib.theme.primaryColor
|
||||||
|
import io.legado.app.model.ReadAloud
|
||||||
|
import io.legado.app.model.ReadBook
|
||||||
import io.legado.app.ui.document.HandleFileContract
|
import io.legado.app.ui.document.HandleFileContract
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tts引擎管理
|
||||||
|
*/
|
||||||
class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
||||||
Toolbar.OnMenuItemClickListener {
|
Toolbar.OnMenuItemClickListener {
|
||||||
|
|
||||||
@@ -37,7 +40,8 @@ class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
|||||||
private val viewModel: SpeakEngineViewModel by viewModels()
|
private val viewModel: SpeakEngineViewModel by viewModels()
|
||||||
private val ttsUrlKey = "ttsUrlKey"
|
private val ttsUrlKey = "ttsUrlKey"
|
||||||
private val adapter by lazy { Adapter(requireContext()) }
|
private val adapter by lazy { Adapter(requireContext()) }
|
||||||
private var ttsEngine: String? = AppConfig.ttsEngine
|
private var ttsEngine: String? = ReadAloud.ttsEngine
|
||||||
|
private val sysTtsViews = arrayListOf<RadioButton>()
|
||||||
private val importDocResult = registerForActivityResult(HandleFileContract()) {
|
private val importDocResult = registerForActivityResult(HandleFileContract()) {
|
||||||
it.uri?.let { uri ->
|
it.uri?.let { uri ->
|
||||||
viewModel.importLocal(uri)
|
viewModel.importLocal(uri)
|
||||||
@@ -80,13 +84,32 @@ class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
|||||||
recyclerView.setEdgeEffectColor(primaryColor)
|
recyclerView.setEdgeEffectColor(primaryColor)
|
||||||
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
tvFooterLeft.setText(R.string.system_tts)
|
viewModel.sysEngines.forEach { engine ->
|
||||||
|
adapter.addHeaderView {
|
||||||
|
ItemHttpTtsBinding.inflate(layoutInflater, recyclerView, false).apply {
|
||||||
|
sysTtsViews.add(cbName)
|
||||||
|
ivEdit.gone()
|
||||||
|
ivMenuDelete.gone()
|
||||||
|
cbName.text = engine.label
|
||||||
|
cbName.tag = engine.name
|
||||||
|
cbName.isChecked =
|
||||||
|
GSON.fromJsonObject<SelectItem<String>>(ttsEngine)?.value == cbName.tag
|
||||||
|
cbName.setOnClickListener {
|
||||||
|
upTts(GSON.toJson(SelectItem(engine.label, engine.name)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tvFooterLeft.setText(R.string.book)
|
||||||
tvFooterLeft.visible()
|
tvFooterLeft.visible()
|
||||||
tvFooterLeft.setOnClickListener {
|
tvFooterLeft.setOnClickListener {
|
||||||
selectSysTts()
|
ReadBook.book?.setTtsEngine(ttsEngine)
|
||||||
|
dismissAllowingStateLoss()
|
||||||
}
|
}
|
||||||
|
tvOk.setText(R.string.general)
|
||||||
tvOk.visible()
|
tvOk.visible()
|
||||||
tvOk.setOnClickListener {
|
tvOk.setOnClickListener {
|
||||||
|
ReadBook.book?.setTtsEngine(null)
|
||||||
AppConfig.ttsEngine = ttsEngine
|
AppConfig.ttsEngine = ttsEngine
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
}
|
}
|
||||||
@@ -131,18 +154,6 @@ class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun selectSysTts() {
|
|
||||||
val ttsItems = viewModel.tts.engines.map {
|
|
||||||
SelectItem(it.label, it.name)
|
|
||||||
}
|
|
||||||
context?.selector(R.string.system_tts, ttsItems) { _, item, _ ->
|
|
||||||
AppConfig.ttsEngine = GSON.toJson(item)
|
|
||||||
ttsEngine = null
|
|
||||||
adapter.notifyItemRangeChanged(0, adapter.itemCount)
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun importAlert() {
|
private fun importAlert() {
|
||||||
val aCache = ACache.get(requireContext(), cacheDir = false)
|
val aCache = ACache.get(requireContext(), cacheDir = false)
|
||||||
val cacheUrls: MutableList<String> = aCache
|
val cacheUrls: MutableList<String> = aCache
|
||||||
@@ -171,6 +182,14 @@ class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun upTts(tts: String) {
|
||||||
|
ttsEngine = tts
|
||||||
|
sysTtsViews.forEach {
|
||||||
|
it.isChecked = GSON.fromJsonObject<SelectItem<String>>(ttsEngine)?.value == it.tag
|
||||||
|
}
|
||||||
|
adapter.notifyItemRangeChanged(adapter.getHeaderCount(), adapter.itemCount)
|
||||||
|
}
|
||||||
|
|
||||||
inner class Adapter(context: Context) :
|
inner class Adapter(context: Context) :
|
||||||
RecyclerAdapter<HttpTTS, ItemHttpTtsBinding>(context) {
|
RecyclerAdapter<HttpTTS, ItemHttpTtsBinding>(context) {
|
||||||
|
|
||||||
@@ -194,8 +213,7 @@ class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
|
|||||||
binding.run {
|
binding.run {
|
||||||
cbName.setOnClickListener {
|
cbName.setOnClickListener {
|
||||||
getItemByLayoutPosition(holder.layoutPosition)?.let { httpTTS ->
|
getItemByLayoutPosition(holder.layoutPosition)?.let { httpTTS ->
|
||||||
ttsEngine = httpTTS.id.toString()
|
upTts(httpTTS.id.toString())
|
||||||
notifyItemRangeChanged(getHeaderCount(), itemCount)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ivEdit.setOnClickListener {
|
ivEdit.setOnClickListener {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import io.legado.app.utils.toastOnUi
|
|||||||
|
|
||||||
class SpeakEngineViewModel(application: Application) : BaseViewModel(application) {
|
class SpeakEngineViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
val tts = TextToSpeech(context, null)
|
val sysEngines = TextToSpeech(context, null).engines
|
||||||
|
|
||||||
fun importDefault() {
|
fun importDefault() {
|
||||||
execute {
|
execute {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Deferred
|
import kotlinx.coroutines.Deferred
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class ChapterListAdapter(context: Context, val callback: Callback, private val scope: CoroutineScope) :
|
class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||||
RecyclerAdapter<Pair<BookChapter, Deferred<String>>, ItemChapterListBinding>(context) {
|
RecyclerAdapter<Pair<BookChapter, Deferred<String>>, ItemChapterListBinding>(context) {
|
||||||
|
|
||||||
val cacheFileNames = hashSetOf<String>()
|
val cacheFileNames = hashSetOf<String>()
|
||||||
@@ -64,7 +64,7 @@ class ChapterListAdapter(context: Context, val callback: Callback, private val s
|
|||||||
} else {
|
} else {
|
||||||
tvChapterName.setTextColor(context.getCompatColor(R.color.primaryText))
|
tvChapterName.setTextColor(context.getCompatColor(R.color.primaryText))
|
||||||
}
|
}
|
||||||
scope.launch {
|
callback.scope.launch {
|
||||||
tvChapterName.text = item.second.await()
|
tvChapterName.text = item.second.await()
|
||||||
}
|
}
|
||||||
if (item.first.isVolume) {
|
if (item.first.isVolume) {
|
||||||
@@ -108,6 +108,7 @@ class ChapterListAdapter(context: Context, val callback: Callback, private val s
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
|
val scope: CoroutineScope
|
||||||
val isLocalBook: Boolean
|
val isLocalBook: Boolean
|
||||||
fun openChapter(bookChapter: BookChapter)
|
fun openChapter(bookChapter: BookChapter)
|
||||||
fun durChapterIndex(): Int
|
fun durChapterIndex(): Int
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import io.legado.app.data.appDb
|
|||||||
import io.legado.app.data.entities.Book
|
import io.legado.app.data.entities.Book
|
||||||
import io.legado.app.data.entities.BookChapter
|
import io.legado.app.data.entities.BookChapter
|
||||||
import io.legado.app.databinding.FragmentChapterListBinding
|
import io.legado.app.databinding.FragmentChapterListBinding
|
||||||
|
import io.legado.app.help.AppConfig
|
||||||
import io.legado.app.help.BookHelp
|
import io.legado.app.help.BookHelp
|
||||||
import io.legado.app.help.ContentProcessor
|
import io.legado.app.help.ContentProcessor
|
||||||
import io.legado.app.lib.theme.bottomBackground
|
import io.legado.app.lib.theme.bottomBackground
|
||||||
@@ -32,7 +33,7 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
|||||||
override val viewModel by activityViewModels<TocViewModel>()
|
override val viewModel by activityViewModels<TocViewModel>()
|
||||||
private val binding by viewBinding(FragmentChapterListBinding::bind)
|
private val binding by viewBinding(FragmentChapterListBinding::bind)
|
||||||
private val mLayoutManager by lazy { UpLinearLayoutManager(requireContext()) }
|
private val mLayoutManager by lazy { UpLinearLayoutManager(requireContext()) }
|
||||||
private val adapter by lazy { ChapterListAdapter(requireContext(), this, this) }
|
private val adapter by lazy { ChapterListAdapter(requireContext(), this) }
|
||||||
private var durChapterIndex = 0
|
private var durChapterIndex = 0
|
||||||
private var tocFlowJob: Job? = null
|
private var tocFlowJob: Job? = null
|
||||||
|
|
||||||
@@ -115,7 +116,8 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
|||||||
val replaces = viewModel.bookData.value?.let { book ->
|
val replaces = viewModel.bookData.value?.let { book ->
|
||||||
ContentProcessor.get(book.name, book.origin).getReplaceRules()
|
ContentProcessor.get(book.name, book.origin).getReplaceRules()
|
||||||
}
|
}
|
||||||
val useReplace = viewModel.bookData.value?.getUseReplaceRule() == true
|
val useReplace =
|
||||||
|
AppConfig.tocUiUseReplace && viewModel.bookData.value?.getUseReplaceRule() == true
|
||||||
it.map { chapter ->
|
it.map { chapter ->
|
||||||
Pair(
|
Pair(
|
||||||
chapter,
|
chapter,
|
||||||
@@ -134,6 +136,9 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val scope: CoroutineScope
|
||||||
|
get() = this
|
||||||
|
|
||||||
override val isLocalBook: Boolean
|
override val isLocalBook: Boolean
|
||||||
get() = viewModel.bookData.value?.isLocalBook() == true
|
get() = viewModel.bookData.value?.isLocalBook() == true
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import com.google.android.material.tabs.TabLayout
|
|||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.base.VMBaseActivity
|
import io.legado.app.base.VMBaseActivity
|
||||||
import io.legado.app.databinding.ActivityChapterListBinding
|
import io.legado.app.databinding.ActivityChapterListBinding
|
||||||
|
import io.legado.app.help.AppConfig
|
||||||
import io.legado.app.lib.theme.accentColor
|
import io.legado.app.lib.theme.accentColor
|
||||||
import io.legado.app.lib.theme.primaryTextColor
|
import io.legado.app.lib.theme.primaryTextColor
|
||||||
import io.legado.app.ui.about.AppLogDialog
|
import io.legado.app.ui.about.AppLogDialog
|
||||||
@@ -74,6 +75,11 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>() {
|
|||||||
return super.onCompatCreateOptionsMenu(menu)
|
return super.onCompatCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMenuOpened(featureId: Int, menu: Menu): Boolean {
|
||||||
|
menu.findItem(R.id.menu_use_replace)?.isChecked = AppConfig.tocUiUseReplace
|
||||||
|
return super.onMenuOpened(featureId, menu)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_reverse_toc -> viewModel.reverseToc {
|
R.id.menu_reverse_toc -> viewModel.reverseToc {
|
||||||
@@ -82,6 +88,10 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>() {
|
|||||||
putExtra("chapterPos", it.durChapterPos)
|
putExtra("chapterPos", it.durChapterPos)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
R.id.menu_use_replace -> {
|
||||||
|
AppConfig.tocUiUseReplace = !item.isChecked
|
||||||
|
viewModel.chapterCallBack?.upChapterList(null)
|
||||||
|
}
|
||||||
R.id.menu_log -> showDialogFragment<AppLogDialog>()
|
R.id.menu_log -> showDialogFragment<AppLogDialog>()
|
||||||
}
|
}
|
||||||
return super.onCompatOptionsItemSelected(item)
|
return super.onCompatOptionsItemSelected(item)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import io.legado.app.utils.*
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import splitties.views.onLongClick
|
import splitties.views.onLongClick
|
||||||
|
|
||||||
class ExploreAdapter(context: Context, private val scope: CoroutineScope, val callBack: CallBack) :
|
class ExploreAdapter(context: Context, val callBack: CallBack) :
|
||||||
RecyclerAdapter<BookSource, ItemFindBookBinding>(context) {
|
RecyclerAdapter<BookSource, ItemFindBookBinding>(context) {
|
||||||
|
|
||||||
private val recycler = arrayListOf<View>()
|
private val recycler = arrayListOf<View>()
|
||||||
@@ -56,7 +56,7 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
|
|||||||
if (scrollTo >= 0) {
|
if (scrollTo >= 0) {
|
||||||
callBack.scrollTo(scrollTo)
|
callBack.scrollTo(scrollTo)
|
||||||
}
|
}
|
||||||
Coroutine.async(scope) {
|
Coroutine.async(callBack.scope) {
|
||||||
item.exploreKinds
|
item.exploreKinds
|
||||||
}.onSuccess { kindList ->
|
}.onSuccess { kindList ->
|
||||||
upKindList(flexbox, item.bookSourceUrl, kindList)
|
upKindList(flexbox, item.bookSourceUrl, kindList)
|
||||||
@@ -167,12 +167,12 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
|
|||||||
putExtra("type", "bookSource")
|
putExtra("type", "bookSource")
|
||||||
putExtra("key", source.bookSourceUrl)
|
putExtra("key", source.bookSourceUrl)
|
||||||
}
|
}
|
||||||
R.id.menu_refresh -> Coroutine.async(scope) {
|
R.id.menu_refresh -> Coroutine.async(callBack.scope) {
|
||||||
ACache.get(context, "explore").remove(source.bookSourceUrl)
|
ACache.get(context, "explore").remove(source.bookSourceUrl)
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
callBack.refreshData()
|
callBack.refreshData()
|
||||||
}
|
}
|
||||||
R.id.menu_del -> Coroutine.async(scope) {
|
R.id.menu_del -> Coroutine.async(callBack.scope) {
|
||||||
appDb.bookSourceDao.delete(source)
|
appDb.bookSourceDao.delete(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,6 +183,7 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface CallBack {
|
interface CallBack {
|
||||||
|
val scope: CoroutineScope
|
||||||
fun refreshData()
|
fun refreshData()
|
||||||
fun scrollTo(pos: Int)
|
fun scrollTo(pos: Int)
|
||||||
fun openExplore(sourceUrl: String, title: String, exploreUrl: String?)
|
fun openExplore(sourceUrl: String, title: String, exploreUrl: String?)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.legado.app.ui.book.explore.ExploreShowActivity
|
|||||||
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
|
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -35,7 +36,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
|
|||||||
ExploreAdapter.CallBack {
|
ExploreAdapter.CallBack {
|
||||||
override val viewModel by viewModels<ExploreViewModel>()
|
override val viewModel by viewModels<ExploreViewModel>()
|
||||||
private val binding by viewBinding(FragmentExploreBinding::bind)
|
private val binding by viewBinding(FragmentExploreBinding::bind)
|
||||||
private val adapter by lazy { ExploreAdapter(requireContext(), lifecycleScope, this) }
|
private val adapter by lazy { ExploreAdapter(requireContext(), this) }
|
||||||
private val linearLayoutManager by lazy { LinearLayoutManager(context) }
|
private val linearLayoutManager by lazy { LinearLayoutManager(context) }
|
||||||
private val searchView: SearchView by lazy {
|
private val searchView: SearchView by lazy {
|
||||||
binding.titleBar.findViewById(R.id.search_view)
|
binding.titleBar.findViewById(R.id.search_view)
|
||||||
@@ -142,6 +143,9 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val scope: CoroutineScope
|
||||||
|
get() = lifecycleScope
|
||||||
|
|
||||||
override fun onCompatOptionsItemSelected(item: MenuItem) {
|
override fun onCompatOptionsItemSelected(item: MenuItem) {
|
||||||
super.onCompatOptionsItemSelected(item)
|
super.onCompatOptionsItemSelected(item)
|
||||||
if (item.groupId == R.id.menu_group_text) {
|
if (item.groupId == R.id.menu_group_text) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:tools="http://schemas.android.com/tools"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:ignore="AlwaysShowAction">
|
tools:ignore="AlwaysShowAction">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
@@ -15,6 +15,12 @@
|
|||||||
android:title="@string/reverse_toc"
|
android:title="@string/reverse_toc"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_use_replace"
|
||||||
|
android:checkable="true"
|
||||||
|
android:title="@string/use_replace"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_log"
|
android:id="@+id/menu_log"
|
||||||
android:title="@string/log"
|
android:title="@string/log"
|
||||||
|
|||||||
@@ -928,5 +928,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">子文件夹</string>
|
<string name="sub_dir">子文件夹</string>
|
||||||
|
<string name="general">全局</string>
|
||||||
|
<string name="use_replace">使用替换</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -931,5 +931,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">子文件夹</string>
|
<string name="sub_dir">子文件夹</string>
|
||||||
|
<string name="general">全局</string>
|
||||||
|
<string name="use_replace">使用替换</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -918,6 +918,8 @@
|
|||||||
<string name="select_book_folder">选择保存书籍的文件夹</string>
|
<string name="select_book_folder">选择保存书籍的文件夹</string>
|
||||||
<string name="user_agent">用户代理</string>
|
<string name="user_agent">用户代理</string>
|
||||||
<string name="bg_alpha">背景透明度</string>
|
<string name="bg_alpha">背景透明度</string>
|
||||||
|
<string name="limit_content_length">限制正文长度</string>
|
||||||
|
<string name="need_more_time_load_content">正文长度过长时,加载正文可能会花费更多时间</string>
|
||||||
|
|
||||||
<!-- check source config string -->
|
<!-- check source config string -->
|
||||||
<string name="check_source_config">校验设置</string>
|
<string name="check_source_config">校验设置</string>
|
||||||
@@ -929,5 +931,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">子文件夹</string>
|
<string name="sub_dir">子文件夹</string>
|
||||||
|
<string name="general">全局</string>
|
||||||
|
<string name="use_replace">使用替换</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -928,5 +928,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">子文件夹</string>
|
<string name="sub_dir">子文件夹</string>
|
||||||
|
<string name="general">全局</string>
|
||||||
|
<string name="use_replace">使用替换</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -930,5 +930,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">子文件夹</string>
|
<string name="sub_dir">子文件夹</string>
|
||||||
|
<string name="general">全局</string>
|
||||||
|
<string name="use_replace">使用替换</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -930,5 +930,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">子文件夹</string>
|
<string name="sub_dir">子文件夹</string>
|
||||||
|
<string name="general">全局</string>
|
||||||
|
<string name="use_replace">使用替换</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -918,8 +918,8 @@
|
|||||||
<string name="book_tree_uri_t">书籍保存位置</string>
|
<string name="book_tree_uri_t">书籍保存位置</string>
|
||||||
<string name="book_tree_uri_s">从其它应用打开的书籍保存位置</string>
|
<string name="book_tree_uri_s">从其它应用打开的书籍保存位置</string>
|
||||||
<string name="select_book_folder">选择保存书籍的文件夹</string>
|
<string name="select_book_folder">选择保存书籍的文件夹</string>
|
||||||
<string name="user_agent">用户代理</string>
|
<string name="user_agent">User agent</string>
|
||||||
<string name="bg_alpha">背景透明度</string>
|
<string name="bg_alpha">Background alpha</string>
|
||||||
|
|
||||||
<!-- check source config string -->
|
<!-- check source config string -->
|
||||||
<string name="check_source_config">校验设置</string>
|
<string name="check_source_config">校验设置</string>
|
||||||
@@ -931,5 +931,7 @@
|
|||||||
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
<string name="check_source_config_summary">校验超时: %1$s秒\n校验项目:%2$s</string>
|
||||||
<string name="record_debug_log">记录调试日志</string>
|
<string name="record_debug_log">记录调试日志</string>
|
||||||
<string name="sub_dir">Sub dir</string>
|
<string name="sub_dir">Sub dir</string>
|
||||||
|
<string name="general">General</string>
|
||||||
|
<string name="use_replace">Use replace</string>
|
||||||
<!-- string end -->
|
<!-- string end -->
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user