pull/1155/head
gedoor 4 years ago
parent 688ee2e986
commit ed891c3e2b
  1. 1
      app/build.gradle
  2. 16
      app/src/main/java/io/legado/app/data/dao/BookDao.kt
  3. 24
      app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt
  4. 28
      app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt
  5. 47
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  6. 16
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  7. 13
      app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
  8. 55
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  9. 83
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  10. 23
      app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt
  11. 24
      app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt
  12. 23
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt
  13. 70
      app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt

@ -169,6 +169,7 @@ dependencies {
//room
def room_version = '2.3.0'
implementation("androidx.room:room-runtime:$room_version")
implementation("androidx.room:room-ktx:$room_version")
kapt("androidx.room:room-compiler:$room_version")
testImplementation("androidx.room:room-testing:$room_version")

@ -1,33 +1,33 @@
package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.*
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import kotlinx.coroutines.flow.Flow
@Dao
interface BookDao {
@Query("SELECT * FROM books order by durChapterTime desc")
fun observeAll(): LiveData<List<Book>>
fun observeAll(): Flow<List<Book>>
@Query("SELECT * FROM books WHERE type = ${BookType.audio}")
fun observeAudio(): LiveData<List<Book>>
fun observeAudio(): Flow<List<Book>>
@Query("SELECT * FROM books WHERE origin = '${BookType.local}'")
fun observeLocal(): LiveData<List<Book>>
fun observeLocal(): Flow<List<Book>>
@Query("select * from books where type != ${BookType.audio} and origin != '${BookType.local}' and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0")
fun observeNoGroup(): LiveData<List<Book>>
fun observeNoGroup(): Flow<List<Book>>
@Query("SELECT bookUrl FROM books WHERE origin = '${BookType.local}'")
fun observeLocalUri(): LiveData<List<String>>
fun observeLocalUri(): Flow<List<String>>
@Query("SELECT * FROM books WHERE (`group` & :group) > 0")
fun observeByGroup(group: Long): LiveData<List<Book>>
fun observeByGroup(group: Long): Flow<List<Book>>
@Query("SELECT * FROM books WHERE name like '%'||:key||'%' or author like '%'||:key||'%'")
fun liveDataSearch(key: String): LiveData<List<Book>>
fun liveDataSearch(key: String): Flow<List<Book>>
@Query("SELECT * FROM books WHERE (`group` & :group) > 0")
fun getBooksByGroup(group: Long): List<Book>

@ -1,14 +1,14 @@
package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.*
import io.legado.app.data.entities.BookSource
import kotlinx.coroutines.flow.Flow
@Dao
interface BookSourceDao {
@Query("select * from book_sources order by customOrder asc")
fun liveDataAll(): LiveData<List<BookSource>>
fun liveDataAll(): Flow<List<BookSource>>
@Query(
"""
@ -20,19 +20,19 @@ interface BookSourceDao {
order by customOrder asc
"""
)
fun liveDataSearch(searchKey: String): LiveData<List<BookSource>>
fun liveDataSearch(searchKey: String): Flow<List<BookSource>>
@Query("select * from book_sources where bookSourceGroup like :searchKey order by customOrder asc")
fun liveDataGroupSearch(searchKey: String): LiveData<List<BookSource>>
fun liveDataGroupSearch(searchKey: String): Flow<List<BookSource>>
@Query("select * from book_sources where enabled = 1 order by customOrder asc")
fun liveDataEnabled(): LiveData<List<BookSource>>
fun liveDataEnabled(): Flow<List<BookSource>>
@Query("select * from book_sources where enabled = 0 order by customOrder asc")
fun liveDataDisabled(): LiveData<List<BookSource>>
fun liveDataDisabled(): Flow<List<BookSource>>
@Query("select * from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' order by customOrder asc")
fun liveExplore(): LiveData<List<BookSource>>
fun liveExplore(): Flow<List<BookSource>>
@Query(
"""
@ -43,7 +43,7 @@ interface BookSourceDao {
order by customOrder asc
"""
)
fun liveExplore(key: String): LiveData<List<BookSource>>
fun liveExplore(key: String): Flow<List<BookSource>>
@Query(
"""
@ -54,13 +54,13 @@ interface BookSourceDao {
order by customOrder asc
"""
)
fun liveGroupExplore(key: String): LiveData<List<BookSource>>
fun liveGroupExplore(key: String): Flow<List<BookSource>>
@Query("select distinct bookSourceGroup from book_sources where trim(bookSourceGroup) <> ''")
fun liveGroup(): LiveData<List<String>>
fun liveGroup(): Flow<List<String>>
@Query("select distinct bookSourceGroup from book_sources where enabled = 1 and trim(bookSourceGroup) <> ''")
fun liveGroupEnabled(): LiveData<List<String>>
fun liveGroupEnabled(): Flow<List<String>>
@Query(
"""
@ -70,7 +70,7 @@ interface BookSourceDao {
and trim(bookSourceGroup) <> ''
"""
)
fun liveExploreGroup(): LiveData<List<String>>
fun liveExploreGroup(): Flow<List<String>>
@Query("select * from book_sources where bookSourceGroup like '%' || :group || '%'")
fun getByGroup(group: String): List<BookSource>

@ -28,6 +28,8 @@ import io.legado.app.utils.cnCompare
import io.legado.app.utils.getPrefInt
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -45,7 +47,7 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
private val addToGroupRequestCode = 34
private lateinit var adapter: ArrangeBookAdapter
private var groupLiveData: LiveData<List<BookGroup>>? = null
private var booksLiveData: LiveData<List<Book>>? = null
private var booksFlowJob: Job? = null
private var menu: Menu? = null
private var groupId: Long = -1
@ -118,26 +120,26 @@ class ArrangeBookActivity : VMBaseActivity<ActivityArrangeBookBinding, ArrangeBo
}
private fun initBookData() {
booksLiveData?.removeObservers(this)
booksLiveData =
booksFlowJob?.cancel()
booksFlowJob = launch {
when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}
booksLiveData?.observe(this, { list ->
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedWith { o1, o2 ->
o1.name.cnCompare(o2.name)
}.collect { list ->
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedWith { o1, o2 ->
o1.name.cnCompare(o2.name)
}
3 -> list.sortedBy { it.order }
else -> list.sortedByDescending { it.durChapterTime }
}
3 -> list.sortedBy { it.order }
else -> list.sortedByDescending { it.durChapterTime }
adapter.setItems(books)
}
adapter.setItems(books)
})
}
}
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {

@ -31,6 +31,8 @@ import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.concurrent.ConcurrentHashMap
@ -45,7 +47,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private val exportBookPathKey = "exportBookPath"
lateinit var adapter: CacheAdapter
private var groupLiveData: LiveData<List<BookGroup>>? = null
private var booksLiveData: LiveData<List<Book>>? = null
private var booksFlowJob: Job? = null
private var menu: Menu? = null
private var exportPosition = -1
private val groupList: ArrayList<BookGroup> = arrayListOf()
@ -147,29 +149,30 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
}
private fun initBookData() {
booksLiveData?.removeObservers(this)
booksLiveData = when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}
booksLiveData?.observe(this, { list ->
val booksDownload = list.filter {
it.isOnLineTxt()
}
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> booksDownload.sortedByDescending { it.latestChapterTime }
2 -> booksDownload.sortedWith { o1, o2 ->
o1.name.cnCompare(o2.name)
booksFlowJob?.cancel()
booksFlowJob = launch {
when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}.collect { list ->
val booksDownload = list.filter {
it.isOnLineTxt()
}
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> booksDownload.sortedByDescending { it.latestChapterTime }
2 -> booksDownload.sortedWith { o1, o2 ->
o1.name.cnCompare(o2.name)
}
3 -> booksDownload.sortedBy { it.order }
else -> booksDownload.sortedByDescending { it.durChapterTime }
}
3 -> booksDownload.sortedBy { it.order }
else -> booksDownload.sortedByDescending { it.durChapterTime }
adapter.setItems(books)
initCacheSize(books)
}
adapter.setItems(books)
initCacheSize(books)
})
}
}
private fun initGroupData() {

@ -22,6 +22,8 @@ import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class ChangeSourceDialog : BaseDialogFragment(),
@ -148,13 +150,15 @@ class ChangeSourceDialog : BaseDialogFragment(),
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, {
adapter.setItems(it)
})
appDb.bookSourceDao.liveGroupEnabled().observe(this, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
launch {
appDb.bookSourceDao.liveGroupEnabled().collect {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupMenu()
}
upGroupMenu()
})
}
}
private val stopMenuItem: MenuItem?

@ -9,7 +9,6 @@ import android.view.MenuItem
import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
@ -27,6 +26,7 @@ import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
@ -46,7 +46,6 @@ class ImportBookActivity : VMBaseActivity<ActivityImportBookBinding, ImportBookV
private var rootDoc: DocumentFile? = null
private val subDocs = arrayListOf<DocumentFile>()
private lateinit var adapter: ImportBookAdapter
private var localUriLiveData: LiveData<List<String>>? = null
private var sdPath = FileUtils.getSdCardPath()
private var path = sdPath
private val selectFolder = registerForActivityResult(FilePicker()) { uri ->
@ -125,11 +124,11 @@ class ImportBookActivity : VMBaseActivity<ActivityImportBookBinding, ImportBookV
}
private fun initData() {
localUriLiveData?.removeObservers(this)
localUriLiveData = appDb.bookDao.observeLocalUri()
localUriLiveData?.observe(this, {
adapter.upBookHas(it)
})
launch {
appDb.bookDao.observeLocalUri().collect {
adapter.upBookHas(it)
}
}
}
private fun initRootDoc() {

@ -30,6 +30,8 @@ import io.legado.app.ui.widget.recycler.LoadMoreView
import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -47,7 +49,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
private lateinit var loadMoreView: LoadMoreView
private lateinit var searchView: SearchView
private var historyData: LiveData<List<SearchKeyword>>? = null
private var bookData: LiveData<List<Book>>? = null
private var booksFlowJob: Job? = null
private var menu: Menu? = null
private var precisionSearchMenuItem: MenuItem? = null
private var groups = linkedSetOf<String>()
@ -58,7 +60,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
initRecyclerView()
initSearchView()
initOtherView()
initLiveData()
initData()
receiptIntent(intent)
}
@ -189,14 +191,16 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
binding.tvClearHistory.setOnClickListener { viewModel.clearHistory() }
}
private fun initLiveData() {
appDb.bookSourceDao.liveGroupEnabled().observe(this, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
private fun initData() {
launch {
appDb.bookSourceDao.liveGroupEnabled().collect {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupMenu()
}
upGroupMenu()
})
}
viewModel.searchBookLiveData.observe(this, {
upSearchItems(it)
})
@ -268,23 +272,26 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
* 更新搜索历史
*/
private fun upHistory(key: String? = null) {
bookData?.removeObservers(this)
if (key.isNullOrBlank()) {
binding.tvBookShow.gone()
binding.rvBookshelfSearch.gone()
} else {
bookData = appDb.bookDao.liveDataSearch(key)
bookData?.observe(this, {
if (it.isEmpty()) {
binding.tvBookShow.gone()
binding.rvBookshelfSearch.gone()
} else {
binding.tvBookShow.visible()
binding.rvBookshelfSearch.visible()
booksFlowJob?.cancel()
booksFlowJob = launch {
if (key.isNullOrBlank()) {
binding.tvBookShow.gone()
binding.rvBookshelfSearch.gone()
} else {
val bookFlow = appDb.bookDao.liveDataSearch(key)
bookFlow.collect {
if (it.isEmpty()) {
binding.tvBookShow.gone()
binding.rvBookshelfSearch.gone()
} else {
binding.tvBookShow.visible()
binding.rvBookshelfSearch.visible()
}
bookAdapter.setItems(it)
}
bookAdapter.setItems(it)
})
}
}
historyData?.removeObservers(this)
historyData =
if (key.isNullOrBlank()) {

@ -10,7 +10,6 @@ import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.ItemTouchHelper
import com.google.android.material.snackbar.Snackbar
import io.legado.app.R
@ -40,6 +39,9 @@ import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import java.io.File
class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceViewModel>(),
@ -52,7 +54,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
private val importRecordKey = "bookSourceRecordKey"
private lateinit var adapter: BookSourceAdapter
private lateinit var searchView: SearchView
private var bookSourceLiveDate: LiveData<List<BookSource>>? = null
private var sourceFlowJob: Job? = null
private val groups = linkedSetOf<String>()
private var groupMenu: SubMenu? = null
private var sort = Sort.Default
@ -94,7 +96,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
searchView = binding.titleBar.findViewById(R.id.search_view)
initRecyclerView()
initSearchView()
initLiveDataBookSource()
upBookSource()
initLiveDataGroup()
initSelectActionBar()
if (!LocalConfig.bookSourcesHelpVersionIsLast) {
@ -134,32 +136,32 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
R.id.menu_sort_manual -> {
item.isChecked = true
sortCheck(Sort.Default)
initLiveDataBookSource(searchView.query?.toString())
upBookSource(searchView.query?.toString())
}
R.id.menu_sort_auto -> {
item.isChecked = true
sortCheck(Sort.Weight)
initLiveDataBookSource(searchView.query?.toString())
upBookSource(searchView.query?.toString())
}
R.id.menu_sort_name -> {
item.isChecked = true
sortCheck(Sort.Name)
initLiveDataBookSource(searchView.query?.toString())
upBookSource(searchView.query?.toString())
}
R.id.menu_sort_url -> {
item.isChecked = true
sortCheck(Sort.Url)
initLiveDataBookSource(searchView.query?.toString())
upBookSource(searchView.query?.toString())
}
R.id.menu_sort_time -> {
item.isChecked = true
sortCheck(Sort.Update)
initLiveDataBookSource(searchView.query?.toString())
upBookSource(searchView.query?.toString())
}
R.id.menu_sort_enable -> {
item.isChecked = true
sortCheck(Sort.Enable)
initLiveDataBookSource(searchView.query?.toString())
upBookSource(searchView.query?.toString())
}
R.id.menu_enabled_group -> {
searchView.setQuery(getString(R.string.enabled), true)
@ -199,27 +201,27 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
searchView.setOnQueryTextListener(this)
}
private fun initLiveDataBookSource(searchKey: String? = null) {
bookSourceLiveDate?.removeObservers(this)
bookSourceLiveDate = when {
searchKey.isNullOrEmpty() -> {
appDb.bookSourceDao.liveDataAll()
}
searchKey == getString(R.string.enabled) -> {
appDb.bookSourceDao.liveDataEnabled()
}
searchKey == getString(R.string.disabled) -> {
appDb.bookSourceDao.liveDataDisabled()
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.bookSourceDao.liveDataGroupSearch("%$key%")
}
else -> {
appDb.bookSourceDao.liveDataSearch("%$searchKey%")
}
}.apply {
observe(this@BookSourceActivity, { data ->
private fun upBookSource(searchKey: String? = null) {
sourceFlowJob?.cancel()
sourceFlowJob = launch {
when {
searchKey.isNullOrEmpty() -> {
appDb.bookSourceDao.liveDataAll()
}
searchKey == getString(R.string.enabled) -> {
appDb.bookSourceDao.liveDataEnabled()
}
searchKey == getString(R.string.disabled) -> {
appDb.bookSourceDao.liveDataDisabled()
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.bookSourceDao.liveDataGroupSearch("%$key%")
}
else -> {
appDb.bookSourceDao.liveDataSearch("%$searchKey%")
}
}.collect { data ->
val sourceList =
if (sortAscending) when (sort) {
Sort.Weight -> data.sortedBy { it.weight }
@ -254,7 +256,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
else -> data.reversed()
}
adapter.setItems(sourceList, adapter.diffItemCallback)
})
}
}
}
@ -273,13 +275,16 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
}
private fun initLiveDataGroup() {
appDb.bookSourceDao.liveGroup().observe(this, {
groups.clear()
it.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupMenu()
})
launch {
appDb.bookSourceDao.liveGroup()
.collect {
groups.clear()
it.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupMenu()
}
}
}
override fun selectAll(selectAll: Boolean) {
@ -453,7 +458,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
override fun onQueryTextChange(newText: String?): Boolean {
newText?.let {
initLiveDataBookSource(it)
upBookSource(it)
}
return false
}

@ -8,10 +8,10 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.constant.AppPattern
@ -28,9 +28,11 @@ import io.legado.app.utils.getSize
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private val viewModel: BookSourceViewModel by activityViewModels()
private lateinit var adapter: GroupAdapter
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
@ -49,8 +51,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
return inflater.inflate(R.layout.dialog_recycler_view, container)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
view.setBackgroundColor(backgroundColor)
binding.toolBar.setBackgroundColor(primaryColor)
binding.toolBar.title = getString(R.string.group_manage)
@ -65,13 +66,15 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
}
private fun initData() {
appDb.bookSourceDao.liveGroup().observe(viewLifecycleOwner, {
val groups = linkedSetOf<String>()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
launch {
appDb.bookSourceDao.liveGroup().collect {
val groups = linkedSetOf<String>()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
adapter.setItems(groups.toList())
}
adapter.setItems(groups.toList())
})
}
}
override fun onMenuItemClick(item: MenuItem?): Boolean {

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.View
import androidx.core.view.isGone
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -29,6 +28,9 @@ import io.legado.app.utils.getPrefInt
import io.legado.app.utils.observeEvent
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlin.math.max
/**
@ -52,7 +54,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
private val activityViewModel: MainViewModel
by activityViewModels()
private lateinit var booksAdapter: BaseBooksAdapter<*>
private var bookshelfLiveData: LiveData<List<Book>>? = null
private var booksFlowJob: Job? = null
private var position = 0
private var groupId = -1L
@ -101,15 +103,15 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
}
private fun upRecyclerData() {
bookshelfLiveData?.removeObservers(this)
bookshelfLiveData = when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}.apply {
observe(viewLifecycleOwner) { list ->
booksFlowJob?.cancel()
booksFlowJob = launch {
when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}.collect { list ->
binding.tvEmptyMsg.isGone = list.isNotEmpty()
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }

@ -32,6 +32,9 @@ import io.legado.app.utils.getPrefInt
import io.legado.app.utils.observeEvent
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlin.math.max
/**
@ -46,7 +49,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
private lateinit var booksAdapter: BaseBooksAdapter<*>
override var groupId = AppConst.bookGroupNoneId
private var bookGroupLiveData: LiveData<List<BookGroup>>? = null
private var bookshelfLiveData: LiveData<List<Book>>? = null
private var booksFlowJob: Job? = null
private var bookGroups: List<BookGroup> = emptyList()
override var books: List<Book> = emptyList()
@ -130,15 +133,15 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
}
private fun initBooksData() {
bookshelfLiveData?.removeObservers(this)
bookshelfLiveData = when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}.apply {
observe(viewLifecycleOwner) { list ->
booksFlowJob?.cancel()
booksFlowJob = launch {
when (groupId) {
AppConst.bookGroupAllId -> appDb.bookDao.observeAll()
AppConst.bookGroupLocalId -> appDb.bookDao.observeLocal()
AppConst.bookGroupAudioId -> appDb.bookDao.observeAudio()
AppConst.bookGroupNoneId -> appDb.bookDao.observeNoGroup()
else -> appDb.bookDao.observeByGroup(groupId)
}.collect { list ->
binding.tvEmptyMsg.isGone = list.isNotEmpty()
books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending {

@ -8,7 +8,6 @@ import android.view.View
import androidx.appcompat.widget.SearchView
import androidx.core.view.isGone
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -27,6 +26,9 @@ import io.legado.app.utils.cnCompare
import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
/**
* 发现界面
@ -39,8 +41,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var searchView: SearchView
private val groups = linkedSetOf<String>()
private var liveGroup: LiveData<List<String>>? = null
private var liveExplore: LiveData<List<BookSource>>? = null
private var exploreFlowJob: Job? = null
private var groupsMenu: SubMenu? = null
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
@ -49,7 +50,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
initSearchView()
initRecyclerView()
initGroupData()
initExploreData()
upExploreData()
}
override fun onCompatCreateOptionsMenu(menu: Menu) {
@ -76,7 +77,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
}
override fun onQueryTextChange(newText: String?): Boolean {
initExploreData(newText)
upExploreData(newText)
return false
}
})
@ -100,38 +101,41 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
}
private fun initGroupData() {
liveGroup?.removeObservers(viewLifecycleOwner)
liveGroup = appDb.bookSourceDao.liveExploreGroup()
liveGroup?.observe(viewLifecycleOwner, {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupsMenu()
})
launch {
appDb.bookSourceDao.liveExploreGroup()
.collect {
groups.clear()
it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupsMenu()
}
}
}
private fun initExploreData(searchKey: String? = null) {
liveExplore?.removeObservers(viewLifecycleOwner)
liveExplore = when {
searchKey.isNullOrBlank() -> {
appDb.bookSourceDao.liveExplore()
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.bookSourceDao.liveGroupExplore("%$key%")
private fun upExploreData(searchKey: String? = null) {
exploreFlowJob?.cancel()
exploreFlowJob = launch {
val exploreFlow = when {
searchKey.isNullOrBlank() -> {
appDb.bookSourceDao.liveExplore()
}
searchKey.startsWith("group:") -> {
val key = searchKey.substringAfter("group:")
appDb.bookSourceDao.liveGroupExplore("%$key%")
}
else -> {
appDb.bookSourceDao.liveExplore("%$searchKey%")
}
}
else -> {
appDb.bookSourceDao.liveExplore("%$searchKey%")
exploreFlow.collect {
binding.tvEmptyMsg.isGone = it.isNotEmpty() || searchView.query.isNotEmpty()
val diffResult = DiffUtil
.calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it)
diffResult.dispatchUpdatesTo(adapter)
}
}
liveExplore?.observe(viewLifecycleOwner, {
binding.tvEmptyMsg.isGone = it.isNotEmpty() || searchView.query.isNotEmpty()
val diffResult = DiffUtil
.calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it)
diffResult.dispatchUpdatesTo(adapter)
})
}
private fun upGroupsMenu() = groupsMenu?.let { subMenu ->
@ -151,7 +155,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
}
override fun refreshData() {
initExploreData(searchView.query?.toString())
upExploreData(searchView.query?.toString())
}
override fun scrollTo(pos: Int) {

Loading…
Cancel
Save