pull/1155/head
gedoor 3 years ago
parent df077da03f
commit 299e27862e
  1. 4
      app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt
  2. 14
      app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt
  3. 4
      app/src/main/java/io/legado/app/data/dao/RuleSubDao.kt
  4. 8
      app/src/main/java/io/legado/app/data/dao/SearchKeywordDao.kt
  5. 15
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  6. 31
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  7. 23
      app/src/main/java/io/legado/app/ui/replace/GroupManageDialog.kt
  8. 51
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt
  9. 13
      app/src/main/java/io/legado/app/ui/rss/subscription/RuleSubActivity.kt

@ -1,8 +1,8 @@
package io.legado.app.data.dao package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import io.legado.app.data.entities.HttpTTS import io.legado.app.data.entities.HttpTTS
import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface HttpTTSDao { interface HttpTTSDao {
@ -11,7 +11,7 @@ interface HttpTTSDao {
val all: List<HttpTTS> val all: List<HttpTTS>
@Query("select * from httpTTS order by name") @Query("select * from httpTTS order by name")
fun observeAll(): LiveData<List<HttpTTS>> fun observeAll(): Flow<List<HttpTTS>>
@get:Query("select count(*) from httpTTS") @get:Query("select count(*) from httpTTS")
val count: Int val count: Int

@ -1,21 +1,24 @@
package io.legado.app.data.dao package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface ReplaceRuleDao { interface ReplaceRuleDao {
@Query("SELECT * FROM replace_rules ORDER BY sortOrder ASC") @Query("SELECT * FROM replace_rules ORDER BY sortOrder ASC")
fun liveDataAll(): LiveData<List<ReplaceRule>> fun liveDataAll(): Flow<List<ReplaceRule>>
@Query("SELECT * FROM replace_rules where `group` like :key or name like :key ORDER BY sortOrder ASC") @Query("SELECT * FROM replace_rules where `group` like :key or name like :key ORDER BY sortOrder ASC")
fun liveDataSearch(key: String): LiveData<List<ReplaceRule>> fun liveDataSearch(key: String): Flow<List<ReplaceRule>>
@Query("SELECT * FROM replace_rules where `group` like :key ORDER BY sortOrder ASC") @Query("SELECT * FROM replace_rules where `group` like :key ORDER BY sortOrder ASC")
fun liveDataGroupSearch(key: String): LiveData<List<ReplaceRule>> fun liveDataGroupSearch(key: String): Flow<List<ReplaceRule>>
@Query("select `group` from replace_rules where `group` is not null and `group` <> ''")
fun liveGroup(): Flow<List<String>>
@get:Query("SELECT MIN(sortOrder) FROM replace_rules") @get:Query("SELECT MIN(sortOrder) FROM replace_rules")
val minOrder: Int val minOrder: Int
@ -44,9 +47,6 @@ interface ReplaceRuleDao {
) )
fun findEnabledByScope(name: String, origin: String): List<ReplaceRule> fun findEnabledByScope(name: String, origin: String): List<ReplaceRule>
@Query("select `group` from replace_rules where `group` is not null and `group` <> ''")
fun liveGroup(): LiveData<List<String>>
@Query("select * from replace_rules where `group` like '%' || :group || '%'") @Query("select * from replace_rules where `group` like '%' || :group || '%'")
fun getByGroup(group: String): List<ReplaceRule> fun getByGroup(group: String): List<ReplaceRule>

@ -1,8 +1,8 @@
package io.legado.app.data.dao package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import io.legado.app.data.entities.RuleSub import io.legado.app.data.entities.RuleSub
import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface RuleSubDao { interface RuleSubDao {
@ -11,7 +11,7 @@ interface RuleSubDao {
val all: List<RuleSub> val all: List<RuleSub>
@Query("select * from ruleSubs order by customOrder") @Query("select * from ruleSubs order by customOrder")
fun observeAll(): LiveData<List<RuleSub>> fun observeAll(): Flow<List<RuleSub>>
@get:Query("select customOrder from ruleSubs order by customOrder limit 0,1") @get:Query("select customOrder from ruleSubs order by customOrder limit 0,1")
val maxOrder: Int val maxOrder: Int

@ -1,8 +1,8 @@
package io.legado.app.data.dao package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import io.legado.app.data.entities.SearchKeyword import io.legado.app.data.entities.SearchKeyword
import kotlinx.coroutines.flow.Flow
@Dao @Dao
@ -12,13 +12,13 @@ interface SearchKeywordDao {
val all: List<SearchKeyword> val all: List<SearchKeyword>
@Query("SELECT * FROM search_keywords ORDER BY usage DESC") @Query("SELECT * FROM search_keywords ORDER BY usage DESC")
fun liveDataByUsage(): LiveData<List<SearchKeyword>> fun liveDataByUsage(): Flow<List<SearchKeyword>>
@Query("SELECT * FROM search_keywords ORDER BY lastUseTime DESC") @Query("SELECT * FROM search_keywords ORDER BY lastUseTime DESC")
fun liveDataByTime(): LiveData<List<SearchKeyword>> fun liveDataByTime(): Flow<List<SearchKeyword>>
@Query("SELECT * FROM search_keywords where word like '%'||:key||'%' ORDER BY usage DESC") @Query("SELECT * FROM search_keywords where word like '%'||:key||'%' ORDER BY usage DESC")
fun liveDataSearch(key: String): LiveData<List<SearchKeyword>> fun liveDataSearch(key: String): Flow<List<SearchKeyword>>
@Query("select * from search_keywords where word = :key") @Query("select * from search_keywords where word = :key")
fun get(key: String): SearchKeyword? fun get(key: String): SearchKeyword?

@ -9,7 +9,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
@ -31,6 +31,8 @@ import io.legado.app.ui.document.FilePickerParam
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
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 splitties.init.appCtx import splitties.init.appCtx
@ -39,7 +41,6 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private val ttsUrlKey = "ttsUrlKey" private val ttsUrlKey = "ttsUrlKey"
lateinit var adapter: Adapter lateinit var adapter: Adapter
private val viewModel: SpeakEngineViewModel by viewModels() private val viewModel: SpeakEngineViewModel by viewModels()
private var httpTTSData: LiveData<List<HttpTTS>>? = null
private var engineId = appCtx.getPrefLong(PreferKey.speakEngine) private var engineId = appCtx.getPrefLong(PreferKey.speakEngine)
private val importDocResult = registerForActivityResult(FilePicker()) { private val importDocResult = registerForActivityResult(FilePicker()) {
it?.let { it?.let {
@ -103,11 +104,11 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
private fun initData() { private fun initData() {
httpTTSData?.removeObservers(this) lifecycleScope.launch {
httpTTSData = appDb.httpTTSDao.observeAll() appDb.httpTTSDao.observeAll().collect {
httpTTSData?.observe(this, { adapter.setItems(it)
adapter.setItems(it) }
}) }
} }
override fun onMenuItemClick(item: MenuItem?): Boolean { override fun onMenuItemClick(item: MenuItem?): Boolean {

@ -10,7 +10,6 @@ import android.view.View.VISIBLE
import android.widget.TextView import android.widget.TextView
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -49,7 +48,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
private lateinit var historyKeyAdapter: HistoryKeyAdapter private lateinit var historyKeyAdapter: HistoryKeyAdapter
private lateinit var loadMoreView: LoadMoreView private lateinit var loadMoreView: LoadMoreView
private lateinit var searchView: SearchView private lateinit var searchView: SearchView
private var historyData: LiveData<List<SearchKeyword>>? = null private var historyFlowJob: Job? = null
private var booksFlowJob: Job? = null private var booksFlowJob: Job? = null
private var menu: Menu? = null private var menu: Menu? = null
private var precisionSearchMenuItem: MenuItem? = null private var precisionSearchMenuItem: MenuItem? = null
@ -292,22 +291,20 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
} }
} }
} }
historyFlowJob?.cancel()
historyData?.removeObservers(this) historyFlowJob = lifecycleScope.launch {
historyData = when {
if (key.isNullOrBlank()) { key.isNullOrBlank() -> appDb.searchKeywordDao.liveDataByUsage()
appDb.searchKeywordDao.liveDataByUsage() else -> appDb.searchKeywordDao.liveDataSearch(key)
} else { }.collect {
appDb.searchKeywordDao.liveDataSearch(key) historyKeyAdapter.setItems(it)
} if (it.isEmpty()) {
historyData?.observe(this, { binding.tvClearHistory.invisible()
historyKeyAdapter.setItems(it) } else {
if (it.isEmpty()) { binding.tvClearHistory.visible()
binding.tvClearHistory.invisible() }
} else {
binding.tvClearHistory.visible()
} }
}) }
} }
/** /**

@ -10,6 +10,7 @@ import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
@ -25,6 +26,8 @@ import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
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
class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
@ -50,10 +53,11 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
view.setBackgroundColor(backgroundColor) view.setBackgroundColor(backgroundColor)
binding.toolBar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
initView()
initData() initData()
} }
private fun initData() = binding.run { private fun initView() = binding.run {
toolBar.title = getString(R.string.group_manage) toolBar.title = getString(R.string.group_manage)
toolBar.inflateMenu(R.menu.group_manage) toolBar.inflateMenu(R.menu.group_manage)
toolBar.menu.applyTint(requireContext()) toolBar.menu.applyTint(requireContext())
@ -62,13 +66,18 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
recyclerView.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.addItemDecoration(VerticalDivider(requireContext())) recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recyclerView.adapter = adapter recyclerView.adapter = adapter
appDb.replaceRuleDao.liveGroup().observe(viewLifecycleOwner, { }
val groups = linkedSetOf<String>()
it.map { group -> private fun initData() {
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) lifecycleScope.launch {
appDb.replaceRuleDao.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 { override fun onMenuItemClick(item: MenuItem?): Boolean {

@ -11,7 +11,7 @@ import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R import io.legado.app.R
@ -39,6 +39,9 @@ import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
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.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import java.io.File import java.io.File
/** /**
@ -56,7 +59,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
private lateinit var searchView: SearchView private lateinit var searchView: SearchView
private var groups = hashSetOf<String>() private var groups = hashSetOf<String>()
private var groupMenu: SubMenu? = null private var groupMenu: SubMenu? = null
private var replaceRuleLiveData: LiveData<List<ReplaceRule>>? = null private var replaceRuleFlowJob: Job? = null
private var dataInit = false private var dataInit = false
private val qrCodeResult = registerForActivityResult(QrCodeResult()) { private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
it ?: return@registerForActivityResult it ?: return@registerForActivityResult
@ -173,37 +176,39 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
private fun observeReplaceRuleData(searchKey: String? = null) { private fun observeReplaceRuleData(searchKey: String? = null) {
dataInit = false dataInit = false
replaceRuleLiveData?.removeObservers(this) replaceRuleFlowJob?.cancel()
replaceRuleLiveData = when { replaceRuleFlowJob = lifecycleScope.launch {
searchKey.isNullOrEmpty() -> { when {
appDb.replaceRuleDao.liveDataAll() searchKey.isNullOrEmpty() -> {
} appDb.replaceRuleDao.liveDataAll()
searchKey.startsWith("group:") -> { }
val key = searchKey.substringAfter("group:") searchKey.startsWith("group:") -> {
appDb.replaceRuleDao.liveDataGroupSearch("%$key%") val key = searchKey.substringAfter("group:")
} appDb.replaceRuleDao.liveDataGroupSearch("%$key%")
else -> { }
appDb.replaceRuleDao.liveDataSearch("%$searchKey%") else -> {
} appDb.replaceRuleDao.liveDataSearch("%$searchKey%")
}.apply { }
observe(this@ReplaceRuleActivity, { }.collect {
if (dataInit) { if (dataInit) {
setResult(Activity.RESULT_OK) setResult(Activity.RESULT_OK)
} }
adapter.setItems(it, adapter.diffItemCallBack) adapter.setItems(it, adapter.diffItemCallBack)
dataInit = true dataInit = true
}) }
} }
} }
private fun observeGroupData() { private fun observeGroupData() {
appDb.replaceRuleDao.liveGroup().observe(this, { lifecycleScope.launch {
groups.clear() appDb.replaceRuleDao.liveGroup().collect {
it.map { group -> groups.clear()
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) it.map { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
upGroupMenu()
} }
upGroupMenu() }
})
} }
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import io.legado.app.R import io.legado.app.R
@ -22,6 +21,7 @@ import io.legado.app.utils.startActivity
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -33,7 +33,6 @@ class RuleSubActivity : BaseActivity<ActivityRuleSubBinding>(),
override val binding by viewBinding(ActivityRuleSubBinding::inflate) override val binding by viewBinding(ActivityRuleSubBinding::inflate)
private lateinit var adapter: RuleSubAdapter private lateinit var adapter: RuleSubAdapter
private var liveData: LiveData<List<RuleSub>>? = null
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initView() initView()
@ -64,11 +63,11 @@ class RuleSubActivity : BaseActivity<ActivityRuleSubBinding>(),
} }
private fun initData() { private fun initData() {
liveData?.removeObservers(this) lifecycleScope.launch {
liveData = appDb.ruleSubDao.observeAll() appDb.ruleSubDao.observeAll().collect {
liveData?.observe(this) { binding.tvEmptyMsg.isGone = it.isNotEmpty()
binding.tvEmptyMsg.isGone = it.isNotEmpty() adapter.setItems(it)
adapter.setItems(it) }
} }
} }

Loading…
Cancel
Save