Merge branch 'master' into master

pull/1601/head
Xwite 3 years ago committed by GitHub
commit e6446ad82c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      app/build.gradle
  2. 5
      app/src/main/assets/updateLog.md
  3. 3
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  4. 1
      app/src/main/java/io/legado/app/ui/book/toc/BookmarkFragment.kt
  5. 61
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt
  6. 19
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt

@ -192,8 +192,9 @@ dependencies {
implementation(fileTree(dir: 'cronetlib', include: ['*.jar', '*.aar']))
//Glide
implementation('com.github.bumptech.glide:glide:4.12.0')
kapt('com.github.bumptech.glide:compiler:4.12.0')
def glideVersion = "4.13.0"
implementation("com.github.bumptech.glide:glide:$glideVersion")
kapt("com.github.bumptech.glide:compiler:$glideVersion")
//webServer
def nanoHttpdVersion = "2.3.1"

@ -11,14 +11,15 @@
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
**2022/02/08**
**2022/02/09**
* 校验失效分组具体到搜索发现目录正文 by Xwite
* txt文件初次解析目录不选择禁用的正则
* txt单章字数超102400均分txt,添加开关 by Xwite
* 修复tts被回收后无法继续朗读的bug,重新初始化tts
* webDav备份支持自定义文件夹
* tts朗读引擎按书籍配置,未设置的和上一次设置的引擎相同
* tts朗读引擎按书籍配置,其他设置添加默认引擎
* 其它一些优化
**2022/02/03**

@ -16,7 +16,6 @@ import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import splitties.init.appCtx
@Suppress("unused")
@Parcelize
@Entity(
tableName = "chapters",
@ -124,8 +123,10 @@ data class BookChapter(
}
}
@Suppress("unused")
fun getFileName(): String = String.format("%05d-%s.nb", index, MD5Utils.md5Encode16(title))
@Suppress("unused")
fun getFontName(): String = String.format("%05d-%s.ttf", index, MD5Utils.md5Encode16(title))
}

@ -17,7 +17,6 @@ import io.legado.app.utils.setEdgeEffectColor
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

@ -6,39 +6,41 @@ import androidx.recyclerview.widget.DiffUtil
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.help.ContentProcessor
import io.legado.app.lib.theme.ThemeUtils
import io.legado.app.lib.theme.accentColor
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.gone
import io.legado.app.utils.visible
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.launch
class ChapterListAdapter(context: Context, val callback: Callback) :
RecyclerAdapter<BookChapter, ItemChapterListBinding>(context) {
class ChapterListAdapter(context: Context, val callback: Callback, private val scope: CoroutineScope) :
RecyclerAdapter<Pair<BookChapter, Deferred<String>>, ItemChapterListBinding>(context) {
val replaceRules
get() = callback.book?.let {
ContentProcessor.get(it.name, it.origin).getReplaceRules()
}
val useReplace get() = callback.book?.getUseReplaceRule() == true
val cacheFileNames = hashSetOf<String>()
val diffCallBack = object : DiffUtil.ItemCallback<BookChapter>() {
val diffCallBack = object : DiffUtil.ItemCallback<Pair<BookChapter, Deferred<String>>>() {
override fun areItemsTheSame(oldItem: BookChapter, newItem: BookChapter): Boolean {
return oldItem.index == newItem.index
override fun areItemsTheSame(
oldItem: Pair<BookChapter, Deferred<String>>,
newItem: Pair<BookChapter, Deferred<String>>
): Boolean {
return oldItem.first.index == newItem.first.index
}
override fun areContentsTheSame(oldItem: BookChapter, newItem: BookChapter): Boolean {
return oldItem.bookUrl == newItem.bookUrl
&& oldItem.url == newItem.url
&& oldItem.isVip == newItem.isVip
&& oldItem.isPay == newItem.isPay
&& oldItem.title == newItem.title
&& oldItem.tag == newItem.tag
&& oldItem.isVolume == newItem.isVolume
override fun areContentsTheSame(
oldItem: Pair<BookChapter, Deferred<String>>,
newItem: Pair<BookChapter, Deferred<String>>
): Boolean {
return oldItem.first.bookUrl == newItem.first.bookUrl
&& oldItem.first.url == newItem.first.url
&& oldItem.first.isVip == newItem.first.isVip
&& oldItem.first.isPay == newItem.first.isPay
&& oldItem.first.title == newItem.first.title
&& oldItem.first.tag == newItem.first.tag
&& oldItem.first.isVolume == newItem.first.isVolume
}
}
@ -50,20 +52,22 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
override fun convert(
holder: ItemViewHolder,
binding: ItemChapterListBinding,
item: BookChapter,
item: Pair<BookChapter, Deferred<String>>,
payloads: MutableList<Any>
) {
binding.run {
val isDur = callback.durChapterIndex() == item.index
val cached = callback.isLocalBook || cacheFileNames.contains(item.getFileName())
val isDur = callback.durChapterIndex() == item.first.index
val cached = callback.isLocalBook || cacheFileNames.contains(item.first.getFileName())
if (payloads.isEmpty()) {
if (isDur) {
tvChapterName.setTextColor(context.accentColor)
} else {
tvChapterName.setTextColor(context.getCompatColor(R.color.primaryText))
}
tvChapterName.text = item.getDisplayTitle(replaceRules, useReplace)
if (item.isVolume) {
scope.launch {
tvChapterName.text = item.second.await()
}
if (item.first.isVolume) {
//卷名,如第一卷 突出显示
tvChapterItem.setBackgroundColor(context.getCompatColor(R.color.btn_bg_press))
} else {
@ -71,9 +75,9 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
tvChapterItem.background =
ThemeUtils.resolveDrawable(context, android.R.attr.selectableItemBackground)
}
if (!item.tag.isNullOrEmpty() && !item.isVolume) {
if (!item.first.tag.isNullOrEmpty() && !item.first.isVolume) {
//卷名不显示tag(更新时间规则)
tvTag.text = item.tag
tvTag.text = item.first.tag
tvTag.visible()
} else {
tvTag.gone()
@ -88,7 +92,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
override fun registerListener(holder: ItemViewHolder, binding: ItemChapterListBinding) {
holder.itemView.setOnClickListener {
getItem(holder.layoutPosition)?.let {
callback.openChapter(it)
callback.openChapter(it.first)
}
}
}
@ -104,7 +108,6 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
}
interface Callback {
val book: Book?
val isLocalBook: Boolean
fun openChapter(bookChapter: BookChapter)
fun durChapterIndex(): Int

@ -14,6 +14,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.FragmentChapterListBinding
import io.legado.app.help.BookHelp
import io.legado.app.help.ContentProcessor
import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor
import io.legado.app.ui.widget.recycler.UpLinearLayoutManager
@ -24,7 +25,7 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -34,7 +35,7 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
override val viewModel by activityViewModels<TocViewModel>()
private val binding by viewBinding(FragmentChapterListBinding::bind)
private val mLayoutManager by lazy { UpLinearLayoutManager(requireContext()) }
private val adapter by lazy { ChapterListAdapter(requireContext(), this) }
private val adapter by lazy { ChapterListAdapter(requireContext(), this, this) }
private var durChapterIndex = 0
private var tocFlowJob: Job? = null
@ -112,7 +113,16 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
else -> appDb.bookChapterDao.flowSearch(viewModel.bookUrl, searchKey)
}.collect {
if (!(searchKey.isNullOrBlank() && it.isEmpty())) {
adapter.setItems(it, adapter.diffCallBack)
val data = withContext(IO) {
val replaces = viewModel.bookData.value?.let { book ->
ContentProcessor.get(book.name, book.origin).getReplaceRules()
}
val useReplace = viewModel.bookData.value?.getUseReplaceRule() == true
it.map { chapter ->
Pair(chapter, async { chapter.getDisplayTitle(replaces, useReplace) })
}
}
adapter.setItems(data, adapter.diffCallBack)
if (searchKey.isNullOrBlank() && mLayoutManager.findFirstVisibleItemPosition() < 0) {
mLayoutManager.scrollToPositionWithOffset(durChapterIndex, 0)
}
@ -121,9 +131,6 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
}
}
override val book: Book?
get() = viewModel.bookData.value
override val isLocalBook: Boolean
get() = viewModel.bookData.value?.isLocalBook() == true

Loading…
Cancel
Save