添加单章换源
This commit is contained in:
@@ -8,7 +8,6 @@ import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseDialogFragment
|
||||
@@ -17,6 +16,7 @@ import io.legado.app.constant.EventBus
|
||||
import io.legado.app.constant.PreferKey
|
||||
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.DialogChapterChangeSourceBinding
|
||||
@@ -33,7 +33,8 @@ import kotlinx.coroutines.launch
|
||||
|
||||
class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_change_source),
|
||||
Toolbar.OnMenuItemClickListener,
|
||||
ChangeChapterSourceAdapter.CallBack {
|
||||
ChangeChapterSourceAdapter.CallBack,
|
||||
ChangeChapterTocAdapter.Callback {
|
||||
|
||||
constructor(name: String, author: String, chapterIndex: Int, chapterTitle: String) : this() {
|
||||
arguments = Bundle().apply {
|
||||
@@ -48,11 +49,17 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
private val groups = linkedSetOf<String>()
|
||||
private val callBack: CallBack? get() = activity as? CallBack
|
||||
private val viewModel: ChangeChapterSourceViewModel by viewModels()
|
||||
private val adapter by lazy { ChangeChapterSourceAdapter(requireContext(), viewModel, this) }
|
||||
private val editSourceResult =
|
||||
registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
|
||||
viewModel.startSearch()
|
||||
}
|
||||
private val searchBookAdapter by lazy {
|
||||
ChangeChapterSourceAdapter(requireContext(), viewModel, this)
|
||||
}
|
||||
private val tocAdapter by lazy {
|
||||
ChangeChapterTocAdapter(requireContext(), this)
|
||||
}
|
||||
private var searchBook: SearchBook? = null
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
@@ -64,14 +71,14 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
viewModel.initData(arguments)
|
||||
showTitle()
|
||||
initMenu()
|
||||
initView()
|
||||
initRecyclerView()
|
||||
initSearchView()
|
||||
initLiveData()
|
||||
}
|
||||
|
||||
private fun showTitle() {
|
||||
binding.toolBar.title = viewModel.name
|
||||
binding.toolBar.subtitle = viewModel.author
|
||||
binding.toolBar.title = viewModel.chapterTitle
|
||||
}
|
||||
|
||||
private fun initMenu() {
|
||||
@@ -86,11 +93,16 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
?.isChecked = AppConfig.changeSourceLoadToc
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.ivHideToc.setOnClickListener {
|
||||
binding.clToc.gone()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initRecyclerView() {
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(context)
|
||||
binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
|
||||
binding.recyclerView.adapter = adapter
|
||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
binding.recyclerView.adapter = searchBookAdapter
|
||||
searchBookAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0) {
|
||||
binding.recyclerView.scrollToPosition(0)
|
||||
@@ -103,6 +115,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
}
|
||||
}
|
||||
})
|
||||
binding.recyclerViewToc.adapter = tocAdapter
|
||||
}
|
||||
|
||||
private fun initSearchView() {
|
||||
@@ -147,7 +160,7 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
launch {
|
||||
viewModel.searchDataFlow
|
||||
.collect {
|
||||
adapter.setItems(it)
|
||||
searchBookAdapter.setItems(it)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
@@ -198,8 +211,22 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
return false
|
||||
}
|
||||
|
||||
private val tocSuccess: (toc: List<BookChapter>) -> Unit = {
|
||||
tocAdapter.durChapterIndex = viewModel.chapterIndex
|
||||
binding.loadingToc.hide()
|
||||
tocAdapter.setItems(it)
|
||||
binding.recyclerViewToc.scrollToPosition(tocAdapter.durChapterIndex - 5)
|
||||
}
|
||||
|
||||
override fun openToc(searchBook: SearchBook) {
|
||||
this.searchBook = searchBook
|
||||
tocAdapter.setItems(null)
|
||||
binding.clToc.visible()
|
||||
binding.loadingToc.show()
|
||||
viewModel.getToc(searchBook, tocSuccess) {
|
||||
binding.clToc.gone()
|
||||
toastOnUi(it)
|
||||
}
|
||||
}
|
||||
|
||||
override val bookUrl: String?
|
||||
@@ -232,6 +259,10 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
}
|
||||
}
|
||||
|
||||
override fun clickChapter(bookChapter: BookChapter) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun changeSource(searchBook: SearchBook) {
|
||||
try {
|
||||
val book = searchBook.toBook()
|
||||
@@ -272,9 +303,9 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
|
||||
override fun observeLiveBus() {
|
||||
observeEvent<String>(EventBus.SOURCE_CHANGED) {
|
||||
adapter.notifyItemRangeChanged(
|
||||
searchBookAdapter.notifyItemRangeChanged(
|
||||
0,
|
||||
adapter.itemCount,
|
||||
searchBookAdapter.itemCount,
|
||||
bundleOf(Pair("upCurSource", bookUrl))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource
|
||||
import io.legado.app.data.entities.SearchBook
|
||||
import io.legado.app.help.AppConfig
|
||||
import io.legado.app.help.coroutine.CompositeCoroutine
|
||||
import io.legado.app.model.NoStackTraceException
|
||||
import io.legado.app.model.webBook.WebBook
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.getPrefString
|
||||
@@ -270,6 +271,29 @@ class ChangeChapterSourceViewModel(application: Application) : BaseViewModel(app
|
||||
searchPool?.close()
|
||||
}
|
||||
|
||||
fun getToc(
|
||||
searchBook: SearchBook,
|
||||
success: (toc: List<BookChapter>) -> Unit,
|
||||
error: (msg: String) -> Unit
|
||||
) {
|
||||
execute {
|
||||
return@execute tocMap[searchBook.bookUrl]
|
||||
?: let {
|
||||
val book = searchBook.toBook()
|
||||
val source = appDb.bookSourceDao.getBookSource(book.origin)
|
||||
?: throw NoStackTraceException("书源不存在")
|
||||
if (book.tocUrl.isEmpty()) {
|
||||
WebBook.getBookInfoAwait(this, source, book)
|
||||
}
|
||||
WebBook.getChapterListAwait(this, source, book)
|
||||
}
|
||||
}.onSuccess {
|
||||
success(it)
|
||||
}.onError {
|
||||
error(it.localizedMessage ?: "获取目录出错")
|
||||
}
|
||||
}
|
||||
|
||||
fun disableSource(searchBook: SearchBook) {
|
||||
execute {
|
||||
appDb.bookSourceDao.getBookSource(searchBook.origin)?.let { source ->
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.view.ViewGroup
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.adapter.ItemViewHolder
|
||||
import io.legado.app.base.adapter.RecyclerAdapter
|
||||
import io.legado.app.data.entities.Book
|
||||
import io.legado.app.data.entities.BookChapter
|
||||
import io.legado.app.databinding.ItemChapterListBinding
|
||||
import io.legado.app.lib.theme.ThemeUtils
|
||||
@@ -17,6 +16,8 @@ import io.legado.app.utils.visible
|
||||
class ChangeChapterTocAdapter(context: Context, val callback: Callback) :
|
||||
RecyclerAdapter<BookChapter, ItemChapterListBinding>(context) {
|
||||
|
||||
var durChapterIndex = 0
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemChapterListBinding {
|
||||
return ItemChapterListBinding.inflate(inflater, parent, false)
|
||||
}
|
||||
@@ -28,7 +29,7 @@ class ChangeChapterTocAdapter(context: Context, val callback: Callback) :
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
binding.run {
|
||||
val isDur = callback.durChapterIndex() == item.index
|
||||
val isDur = durChapterIndex == item.index
|
||||
if (isDur) {
|
||||
tvChapterName.setTextColor(context.accentColor)
|
||||
} else {
|
||||
@@ -58,14 +59,12 @@ class ChangeChapterTocAdapter(context: Context, val callback: Callback) :
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemChapterListBinding) {
|
||||
holder.itemView.setOnClickListener {
|
||||
getItem(holder.layoutPosition)?.let {
|
||||
callback.openChapter(it)
|
||||
callback.clickChapter(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
val book: Book?
|
||||
fun openChapter(bookChapter: BookChapter)
|
||||
fun durChapterIndex(): Int
|
||||
fun clickChapter(bookChapter: BookChapter)
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/refresh_progress_bar" />
|
||||
|
||||
@@ -53,10 +54,12 @@
|
||||
android:id="@+id/recycler_view_toc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iv_hide_toc" />
|
||||
|
||||
<io.legado.app.ui.widget.anima.RotateLoading
|
||||
android:id="@+id/loading_toc"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:visibility="gone"
|
||||
|
||||
Reference in New Issue
Block a user