|
|
@@ -1,577 +0,0 @@
|
|
|
-package io.legado.app.ui.book.changesource
|
|
|
-
|
|
|
-//import io.legado.app.lib.theme.getPrimaryTextColor
|
|
|
-//import io.legado.app.lib.theme.primaryColor
|
|
|
-import android.annotation.SuppressLint
|
|
|
-import android.os.Bundle
|
|
|
-import android.os.Handler
|
|
|
-import android.os.Looper
|
|
|
-import android.view.Menu
|
|
|
-import android.view.MenuItem
|
|
|
-import android.view.View
|
|
|
-import androidx.appcompat.widget.SearchView
|
|
|
-import androidx.appcompat.widget.Toolbar
|
|
|
-import androidx.core.os.bundleOf
|
|
|
-import androidx.core.view.isInvisible
|
|
|
-import androidx.lifecycle.Lifecycle.State.STARTED
|
|
|
-import androidx.lifecycle.lifecycleScope
|
|
|
-import androidx.lifecycle.repeatOnLifecycle
|
|
|
-import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
-import androidx.recyclerview.widget.RecyclerView
|
|
|
-import io.legado.app.R
|
|
|
-import io.legado.app.base.BaseBottomSheetDialogFragment
|
|
|
-import io.legado.app.constant.AppLog
|
|
|
-import io.legado.app.constant.EventBus
|
|
|
-import io.legado.app.data.appDb
|
|
|
-import io.legado.app.data.entities.Book
|
|
|
-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.domain.gateway.ChangeSourceSettingsGateway
|
|
|
-import io.legado.app.domain.gateway.OtherSettingsGateway
|
|
|
-import io.legado.app.domain.gateway.ReadSettingsGateway
|
|
|
-import io.legado.app.domain.model.settings.ChangeSourceSettings
|
|
|
-import io.legado.app.lib.dialogs.alert
|
|
|
-import io.legado.app.model.ReadBook
|
|
|
-import io.legado.app.ui.book.search.SearchScope
|
|
|
-import io.legado.app.ui.main.MainActivity
|
|
|
-import io.legado.app.ui.widget.dialog.WaitDialog
|
|
|
-import io.legado.app.ui.widget.recycler.VerticalDivider
|
|
|
-import io.legado.app.utils.applyTint
|
|
|
-import io.legado.app.utils.dpToPx
|
|
|
-import io.legado.app.utils.getCompatDrawable
|
|
|
-import io.legado.app.utils.observeEvent
|
|
|
-import io.legado.app.utils.toastOnUi
|
|
|
-import io.legado.app.utils.transaction
|
|
|
-import io.legado.app.utils.viewbindingdelegate.viewBinding
|
|
|
-import io.legado.app.utils.visible
|
|
|
-import kotlinx.coroutines.Dispatchers.IO
|
|
|
-import kotlinx.coroutines.delay
|
|
|
-import kotlinx.coroutines.flow.conflate
|
|
|
-import kotlinx.coroutines.flow.drop
|
|
|
-import kotlinx.coroutines.flow.first
|
|
|
-import kotlinx.coroutines.launch
|
|
|
-import org.koin.android.ext.android.inject
|
|
|
-import org.koin.androidx.viewmodel.ext.android.viewModel
|
|
|
-
|
|
|
-/**
|
|
|
- * 换源界面
|
|
|
- */
|
|
|
-class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_change_source),
|
|
|
- Toolbar.OnMenuItemClickListener,
|
|
|
- ChangeBookSourceAdapter.CallBack {
|
|
|
-
|
|
|
- constructor(name: String, author: String) : this() {
|
|
|
- arguments = Bundle().apply {
|
|
|
- putString("name", name)
|
|
|
- putString("author", author)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private val binding by viewBinding(DialogBookChangeSourceBinding::bind)
|
|
|
- private val groups = linkedSetOf<String>()
|
|
|
- private val callBack: CallBack? get() = activity as? CallBack
|
|
|
- private val viewModel: ChangeBookSourceViewModel by viewModel()
|
|
|
- private val changeSourceSettingsGateway by inject<ChangeSourceSettingsGateway>()
|
|
|
- private val otherSettingsGateway by inject<OtherSettingsGateway>()
|
|
|
- private val readSettingsGateway by inject<ReadSettingsGateway>()
|
|
|
- private val waitDialog by lazy { WaitDialog(requireContext()) }
|
|
|
- private val adapter by lazy { ChangeBookSourceAdapter(requireContext(), viewModel, this) }
|
|
|
- private val editSourceResult =
|
|
|
- registerForActivityResult(androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult()) {
|
|
|
- val origin = it.data?.getStringExtra("origin") ?: return@registerForActivityResult
|
|
|
- viewModel.startSearch(origin)
|
|
|
- }
|
|
|
- private var currentSelectedSearchBook: SearchBook? = null
|
|
|
- private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
|
|
|
- if (it) {
|
|
|
- val searchScope = SearchScope(changeSourceSettingsGateway.currentSettings.searchScope)
|
|
|
- val group = searchScope.display
|
|
|
- if (!searchScope.isAll()) {
|
|
|
- lifecycleScope.launch {
|
|
|
- context?.alert("搜索结果为空") {
|
|
|
- setMessage("${group}分组搜索结果为空,是否切换到全部分组")
|
|
|
- cancelButton()
|
|
|
- okButton {
|
|
|
- updateSetting({ it.copy(searchScope = "") }) {
|
|
|
- upGroupMenuName()
|
|
|
- viewModel.startSearch()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
|
|
- //binding.toolBar.setBackgroundColor(primaryColor)
|
|
|
- viewModel.initData(arguments, callBack?.oldBook, MainActivity.hasActiveReadBookRoute)
|
|
|
- showTitle()
|
|
|
- initMenu()
|
|
|
- initRecyclerView()
|
|
|
- initNavigationView()
|
|
|
- initSearchView()
|
|
|
- initBottomBar()
|
|
|
- initLiveData()
|
|
|
- viewModel.searchFinishCallback = searchFinishCallback
|
|
|
- }
|
|
|
-
|
|
|
- override fun onDestroy() {
|
|
|
- super.onDestroy()
|
|
|
- viewModel.searchFinishCallback = null
|
|
|
- viewModel.stopSearch()
|
|
|
- }
|
|
|
-
|
|
|
- private fun showTitle() {
|
|
|
- binding.toolBar.title = viewModel.name
|
|
|
- binding.toolBar.subtitle = viewModel.author
|
|
|
- binding.toolBar.navigationIcon =
|
|
|
- getCompatDrawable(androidx.appcompat.R.drawable.abc_ic_ab_back_material)
|
|
|
- //binding.toolBar.elevation = requireContext().elevation
|
|
|
- }
|
|
|
-
|
|
|
- private fun initMenu() {
|
|
|
- binding.toolBar.inflateMenu(R.menu.change_source)
|
|
|
- binding.toolBar.menu.applyTint(requireContext())
|
|
|
- binding.toolBar.setOnMenuItemClickListener(this)
|
|
|
- binding.toolBar.menu.findItem(R.id.menu_check_author)
|
|
|
- ?.isChecked = changeSourceSettingsGateway.currentSettings.checkAuthor
|
|
|
- binding.toolBar.menu.findItem(R.id.menu_load_info)
|
|
|
- ?.isChecked = changeSourceSettingsGateway.currentSettings.loadInfo
|
|
|
- binding.toolBar.menu.findItem(R.id.menu_load_toc)
|
|
|
- ?.isChecked = changeSourceSettingsGateway.currentSettings.loadToc
|
|
|
- binding.toolBar.menu.findItem(R.id.menu_load_word_count)
|
|
|
- ?.isChecked = changeSourceSettingsGateway.currentSettings.loadWordCount
|
|
|
- }
|
|
|
-
|
|
|
- private fun initRecyclerView() {
|
|
|
- binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
|
|
|
- binding.recyclerView.adapter = adapter
|
|
|
- adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
|
|
- override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
|
|
- if (positionStart == 0) {
|
|
|
- binding.recyclerView.scrollToPosition(0)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
|
|
|
- if (toPosition == 0) {
|
|
|
- binding.recyclerView.scrollToPosition(0)
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- private fun initSearchView() {
|
|
|
- val searchView = binding.toolBar.menu.findItem(R.id.menu_screen).actionView as SearchView
|
|
|
- searchView.setOnCloseListener {
|
|
|
- showTitle()
|
|
|
- false
|
|
|
- }
|
|
|
- searchView.setOnSearchClickListener {
|
|
|
- binding.toolBar.title = ""
|
|
|
- binding.toolBar.subtitle = ""
|
|
|
- binding.toolBar.navigationIcon = null
|
|
|
- }
|
|
|
- searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
|
|
- override fun onQueryTextSubmit(query: String?): Boolean {
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- override fun onQueryTextChange(newText: String?): Boolean {
|
|
|
- viewModel.screen(newText)
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- private fun initNavigationView() {
|
|
|
- binding.toolBar.navigationIcon =
|
|
|
- getCompatDrawable(androidx.appcompat.R.drawable.abc_ic_ab_back_material)
|
|
|
- binding.toolBar.setNavigationContentDescription(
|
|
|
- androidx.appcompat.R.string.abc_action_bar_up_description
|
|
|
- )
|
|
|
- binding.toolBar.setNavigationOnClickListener {
|
|
|
- dismissAllowingStateLoss()
|
|
|
- }
|
|
|
- kotlin.runCatching {
|
|
|
- val mNavButtonViewField = Toolbar::class.java.getDeclaredField("mNavButtonView")
|
|
|
- mNavButtonViewField.isAccessible = true
|
|
|
- //val navigationView = mNavButtonViewField.get(binding.toolBar) as ImageButton
|
|
|
-// val isLight = ColorUtils.isColorLight(primaryColor)
|
|
|
-// val textColor = requireContext().getPrimaryTextColor(isLight)
|
|
|
- //navigationView.setColorFilter(textColor)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun initBottomBar() {
|
|
|
- binding.tvDur.text = callBack?.oldBook?.originName
|
|
|
- binding.tvDur.setOnClickListener {
|
|
|
- scrollToDurSource()
|
|
|
- }
|
|
|
- binding.ivTop.setOnClickListener {
|
|
|
- binding.recyclerView.scrollToPosition(0)
|
|
|
- }
|
|
|
- binding.ivBottom.setOnClickListener {
|
|
|
- binding.recyclerView.scrollToPosition(adapter.itemCount - 1)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private var switchHandler: Handler? = null
|
|
|
- private var switchRunnable: Runnable? = null
|
|
|
-
|
|
|
-
|
|
|
- @SuppressLint("SetTextI18n")
|
|
|
- private fun initLiveData() {
|
|
|
-
|
|
|
- viewModel.searchStateData.observe(viewLifecycleOwner) { isSearching ->
|
|
|
- if (isSearching) {
|
|
|
- binding.refreshProgressBar.isInvisible = false
|
|
|
- startStopMenuItem?.let { item ->
|
|
|
- item.setIcon(R.drawable.ic_stop_black_24dp)
|
|
|
- item.setTitle(R.string.stop)
|
|
|
- }
|
|
|
- } else {
|
|
|
- binding.refreshProgressBar.isIndeterminate = false
|
|
|
- binding.refreshProgressBar.progress = 0
|
|
|
- binding.refreshProgressBar.isInvisible = true
|
|
|
- startStopMenuItem?.let { item ->
|
|
|
- item.setIcon(R.drawable.ic_refresh)
|
|
|
- item.setTitle(R.string.refresh)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- lifecycleScope.launch {
|
|
|
- lifecycle.currentStateFlow.first { it.isAtLeast(STARTED) }
|
|
|
- viewModel.searchDataFlow.conflate().collect {
|
|
|
- adapter.setItems(it)
|
|
|
- delay(1000)
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- lifecycleScope.launch {
|
|
|
- repeatOnLifecycle(STARTED) {
|
|
|
- var canSwitchToDeterminate = false
|
|
|
-
|
|
|
- switchHandler?.removeCallbacks(switchRunnable ?: Runnable { })
|
|
|
- switchHandler = Handler(Looper.getMainLooper())
|
|
|
- switchRunnable = Runnable { canSwitchToDeterminate = true }
|
|
|
- switchHandler?.postDelayed(switchRunnable!!, 5000)
|
|
|
-
|
|
|
- viewModel.changeSourceProgress
|
|
|
- .drop(1)
|
|
|
- .collect { (count, name) ->
|
|
|
- val total = viewModel.totalSourceCount
|
|
|
- val progressPercent = if (total > 0) (count * 100f / total) else 0f
|
|
|
-
|
|
|
- binding.refreshProgressBar.isIndeterminate = true
|
|
|
- binding.refreshProgressBar.show()
|
|
|
-
|
|
|
- binding.llInfo.visible()
|
|
|
-
|
|
|
- if (count == 0) {
|
|
|
- canSwitchToDeterminate = false
|
|
|
- switchHandler?.removeCallbacks(switchRunnable!!)
|
|
|
- switchHandler?.postDelayed(switchRunnable!!, 5000)
|
|
|
- }
|
|
|
-
|
|
|
- val shouldBeIndeterminate = when {
|
|
|
- !canSwitchToDeterminate -> true
|
|
|
- progressPercent in 10f..90f -> false
|
|
|
- else -> true
|
|
|
- }
|
|
|
-
|
|
|
- if (shouldBeIndeterminate) {
|
|
|
- if (!binding.refreshProgressBar.isIndeterminate) {
|
|
|
- binding.refreshProgressBar.isIndeterminate = true
|
|
|
- binding.refreshProgressBar.show()
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (binding.refreshProgressBar.isIndeterminate) {
|
|
|
- binding.refreshProgressBar.isIndeterminate = false
|
|
|
- }
|
|
|
- binding.refreshProgressBar.setProgressCompat(progressPercent.toInt(), true)
|
|
|
- }
|
|
|
-
|
|
|
- binding.tvProgress.text = "$count / $total"
|
|
|
- binding.tvResult.text =
|
|
|
- getString(R.string.change_source_progress, adapter.itemCount)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- lifecycleScope.launch {
|
|
|
- appDb.bookSourceDao.flowEnabledGroups().conflate().collect {
|
|
|
- groups.clear()
|
|
|
- groups.addAll(it)
|
|
|
- upGroupMenu()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private val startStopMenuItem: MenuItem?
|
|
|
- get() = binding.toolBar.menu.findItem(R.id.menu_start_stop)
|
|
|
-
|
|
|
- override fun onMenuItemClick(item: MenuItem?): Boolean {
|
|
|
- when (item?.itemId) {
|
|
|
- R.id.menu_check_author -> {
|
|
|
- val enabled = !item.isChecked
|
|
|
- updateSetting({ it.copy(checkAuthor = enabled) })
|
|
|
- item.isChecked = enabled
|
|
|
- lifecycleScope.launch { viewModel.refresh() }
|
|
|
- }
|
|
|
-
|
|
|
- R.id.menu_load_info -> {
|
|
|
- val enabled = !item.isChecked
|
|
|
- updateSetting({ it.copy(loadInfo = enabled) })
|
|
|
- item.isChecked = enabled
|
|
|
- }
|
|
|
-
|
|
|
- R.id.menu_load_toc -> {
|
|
|
- val enabled = !item.isChecked
|
|
|
- updateSetting({ it.copy(loadToc = enabled) })
|
|
|
- item.isChecked = enabled
|
|
|
- }
|
|
|
-
|
|
|
- R.id.menu_load_word_count -> {
|
|
|
- val enabled = !item.isChecked
|
|
|
- updateSetting({ it.copy(loadWordCount = enabled) })
|
|
|
- item.isChecked = enabled
|
|
|
- viewModel.onLoadWordCountChecked(item.isChecked)
|
|
|
- }
|
|
|
-
|
|
|
- R.id.menu_start_stop -> viewModel.startOrStopSearch()
|
|
|
- R.id.menu_source_manage -> startActivity(
|
|
|
- MainActivity.createBookSourceManageIntent(requireContext())
|
|
|
- )
|
|
|
- R.id.menu_close -> dismissAllowingStateLoss()
|
|
|
- R.id.menu_refresh_list -> viewModel.startRefreshList()
|
|
|
- else -> if (item?.groupId == R.id.source_group && !item.isChecked) {
|
|
|
- item.isChecked = true
|
|
|
- val scope = if (item.title.toString() == getString(R.string.all_source)) {
|
|
|
- ""
|
|
|
- } else {
|
|
|
- item.title.toString()
|
|
|
- }
|
|
|
- updateSetting({ it.copy(searchScope = scope) }) {
|
|
|
- upGroupMenuName()
|
|
|
- lifecycleScope.launch(IO) {
|
|
|
- viewModel.stopSearch()
|
|
|
- if (viewModel.refresh()) {
|
|
|
- viewModel.startSearch()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- private fun scrollToDurSource() {
|
|
|
- adapter.getItems().forEachIndexed { index, searchBook ->
|
|
|
- if (searchBook.bookUrl == oldBookUrl) {
|
|
|
- (binding.recyclerView.layoutManager as LinearLayoutManager)
|
|
|
- .scrollToPositionWithOffset(index, 60.dpToPx())
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- override fun changeTo(searchBook: SearchBook) {
|
|
|
- currentSelectedSearchBook = searchBook
|
|
|
- showChangeSourceOptionDialog(searchBook)
|
|
|
- }
|
|
|
-
|
|
|
- private fun showChangeSourceOptionDialog(searchBook: SearchBook) {
|
|
|
- val oldBookType = callBack?.oldBook?.type ?: 0
|
|
|
-
|
|
|
- if (!searchBook.sameBookTypeLocal(oldBookType)) {
|
|
|
- alert(
|
|
|
- titleResource = R.string.book_type_different,
|
|
|
- messageResource = R.string.soure_change_source
|
|
|
- ) {
|
|
|
- okButton {
|
|
|
- showChangeSourceActionDialog(searchBook)
|
|
|
- }
|
|
|
- cancelButton()
|
|
|
- }
|
|
|
- } else {
|
|
|
- showChangeSourceActionDialog(searchBook)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun showChangeSourceActionDialog(searchBook: SearchBook) {
|
|
|
- context?.alert(getString(R.string.change_source_option_title)) {
|
|
|
- positiveButton(getString(R.string.replace_current_book)) {
|
|
|
- performChangeSource(searchBook, true)
|
|
|
- }
|
|
|
- negativeButton(getString(R.string.add_as_new_book)) {
|
|
|
- performChangeSource(searchBook, false)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun performChangeSource(searchBook: SearchBook, isReplace: Boolean) {
|
|
|
- val baseBook = viewModel.bookMap[searchBook.primaryStr()] ?: searchBook.toBook()
|
|
|
- val book = baseBook
|
|
|
-
|
|
|
- waitDialog.setText(if (isReplace) R.string.load_toc else R.string.load_info)
|
|
|
- waitDialog.show()
|
|
|
-
|
|
|
- val coroutine = viewModel.getToc(book, { toc, source ->
|
|
|
- waitDialog.dismiss()
|
|
|
- if (isReplace) {
|
|
|
-
|
|
|
- callBack?.changeTo(source, book, toc)
|
|
|
- dismissAllowingStateLoss()
|
|
|
- } else {
|
|
|
- ReadBook.book?.migrateTo(
|
|
|
- book,
|
|
|
- toc,
|
|
|
- otherSettingsGateway.currentSettings.replaceEnableDefault,
|
|
|
- readSettingsGateway.currentSettings.chineseConverterType,
|
|
|
- )
|
|
|
- callBack?.addToBookshelf(book, toc)
|
|
|
- context?.toastOnUi(getString(R.string.book_added_to_shelf))
|
|
|
- }
|
|
|
- }, {
|
|
|
- waitDialog.dismiss()
|
|
|
- AppLog.put("${if (isReplace) "换源" else "添加书籍"}获取目录出错\n$it", it, true)
|
|
|
- context?.toastOnUi("${if (isReplace) "换源" else "添加书籍"}失败")
|
|
|
- })
|
|
|
-
|
|
|
- waitDialog.setOnCancelListener {
|
|
|
- coroutine.cancel()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- override val oldBookUrl: String?
|
|
|
- get() = callBack?.oldBook?.bookUrl
|
|
|
-
|
|
|
- override fun topSource(searchBook: SearchBook) {
|
|
|
- viewModel.topSource(searchBook)
|
|
|
- }
|
|
|
-
|
|
|
- override fun bottomSource(searchBook: SearchBook) {
|
|
|
- viewModel.bottomSource(searchBook)
|
|
|
- }
|
|
|
-
|
|
|
- override fun editSource(searchBook: SearchBook) {
|
|
|
- editSourceResult.launch(
|
|
|
- MainActivity.createBookSourceEditIntent(requireContext(), searchBook.origin)
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- override fun disableSource(searchBook: SearchBook) {
|
|
|
- viewModel.disableSource(searchBook)
|
|
|
- }
|
|
|
-
|
|
|
- override fun deleteSource(searchBook: SearchBook) {
|
|
|
- viewModel.del(searchBook)
|
|
|
- if (oldBookUrl == searchBook.bookUrl) {
|
|
|
- viewModel.autoChangeSource(callBack?.oldBook?.type) { book, toc, source ->
|
|
|
- callBack?.changeTo(source, book, toc)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- override fun setBookScore(searchBook: SearchBook, score: Int) {
|
|
|
- viewModel.setBookScore(searchBook, score)
|
|
|
- }
|
|
|
-
|
|
|
- override fun getBookScore(searchBook: SearchBook): Int {
|
|
|
- return viewModel.getBookScore(searchBook)
|
|
|
- }
|
|
|
-
|
|
|
- private fun changeSource(searchBook: SearchBook, onSuccess: (() -> Unit)? = null) {
|
|
|
- waitDialog.setText(R.string.load_toc)
|
|
|
- waitDialog.show()
|
|
|
- val book = viewModel.bookMap[searchBook.primaryStr()] ?: searchBook.toBook()
|
|
|
- val coroutine = viewModel.getToc(book, { toc, source ->
|
|
|
- waitDialog.dismiss()
|
|
|
- callBack?.changeTo(source, book, toc)
|
|
|
- onSuccess?.invoke()
|
|
|
- }, {
|
|
|
- waitDialog.dismiss()
|
|
|
- AppLog.put("换源获取目录出错\n$it", it, true)
|
|
|
- })
|
|
|
- waitDialog.setOnCancelListener {
|
|
|
- coroutine.cancel()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新分组菜单
|
|
|
- */
|
|
|
- private fun upGroupMenu() {
|
|
|
- binding.toolBar.menu.findItem(R.id.menu_group)?.run {
|
|
|
- subMenu?.transaction { menu ->
|
|
|
- val searchScope = SearchScope(changeSourceSettingsGateway.currentSettings.searchScope)
|
|
|
- val selectedGroup = searchScope.displayNames.firstOrNull() ?: ""
|
|
|
- menu.removeGroup(R.id.source_group)
|
|
|
- val allItem = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.all_source)
|
|
|
- var hasSelectedGroup = false
|
|
|
- groups.forEach { group ->
|
|
|
- menu.add(R.id.source_group, Menu.NONE, Menu.NONE, group)?.let {
|
|
|
- if (group == selectedGroup) {
|
|
|
- it.isChecked = true
|
|
|
- hasSelectedGroup = true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- menu.setGroupCheckable(R.id.source_group, true, true)
|
|
|
- if (hasSelectedGroup) {
|
|
|
- title = getString(R.string.group) + "(" + selectedGroup + ")"
|
|
|
- } else {
|
|
|
- allItem.isChecked = true
|
|
|
- title = getString(R.string.group)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新分组菜单名
|
|
|
- */
|
|
|
- private fun upGroupMenuName() {
|
|
|
- val menuGroup = binding.toolBar.menu.findItem(R.id.menu_group)
|
|
|
- val searchScope = SearchScope(changeSourceSettingsGateway.currentSettings.searchScope)
|
|
|
- if (searchScope.isAll()) {
|
|
|
- menuGroup?.title = getString(R.string.group)
|
|
|
- } else {
|
|
|
- menuGroup?.title = getString(R.string.group) + "(${searchScope.display})"
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private fun updateSetting(
|
|
|
- transform: (ChangeSourceSettings) -> ChangeSourceSettings,
|
|
|
- afterUpdate: (() -> Unit)? = null,
|
|
|
- ) {
|
|
|
- lifecycleScope.launch {
|
|
|
- changeSourceSettingsGateway.update(transform)
|
|
|
- afterUpdate?.invoke()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- override fun observeLiveBus() {
|
|
|
- observeEvent<String>(EventBus.SOURCE_CHANGED) {
|
|
|
- adapter.notifyItemRangeChanged(
|
|
|
- 0,
|
|
|
- adapter.itemCount,
|
|
|
- bundleOf(Pair("upCurSource", oldBookUrl))
|
|
|
- )
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- interface CallBack {
|
|
|
- val oldBook: Book?
|
|
|
- fun changeTo(source: BookSource, book: Book, toc: List<BookChapter>)
|
|
|
- fun addToBookshelf(book: Book, toc: List<BookChapter>)
|
|
|
- }
|
|
|
-
|
|
|
-}
|