mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
优化
This commit is contained in:
@@ -272,6 +272,7 @@
|
||||
<!-- WebView界面 -->
|
||||
<activity
|
||||
android:name=".ui.browser.WebViewActivity"
|
||||
android:configChanges="locale|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:launchMode="standard" />
|
||||
<!-- 书源登录 -->
|
||||
<activity
|
||||
|
||||
@@ -116,7 +116,7 @@ interface BookSourceDao {
|
||||
@Query("select * from book_sources where enabled = 1 and bookSourceType = :type")
|
||||
fun getEnabledByType(type: Int): List<BookSource>
|
||||
|
||||
@get:Query("select * from book_sources where trim(bookUrlPattern) <> '' order by enabled desc, customOrder")
|
||||
@get:Query("select * from book_sources where enabled = 1 and trim(bookUrlPattern) <> '' order by enabled desc, customOrder")
|
||||
val hasBookUrlPattern: List<BookSource>
|
||||
|
||||
@get:Query("select * from book_sources where bookSourceGroup is null or bookSourceGroup = ''")
|
||||
|
||||
@@ -62,6 +62,9 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
|
||||
//获取系统信息
|
||||
map["MANUFACTURER"] = Build.MANUFACTURER
|
||||
map["BRAND"] = Build.BRAND
|
||||
map["MODEL"] = Build.MODEL
|
||||
map["SDK_INT"] = Build.VERSION.SDK_INT.toString()
|
||||
map["RELEASE"] = Build.VERSION.RELEASE
|
||||
//获取app版本信息
|
||||
AppConst.appInfo.let {
|
||||
map["versionName"] = it.versionName
|
||||
|
||||
@@ -464,6 +464,9 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
* 预下载
|
||||
*/
|
||||
private fun preDownload() {
|
||||
if (AppConfig.preDownloadNum < 2) {
|
||||
return
|
||||
}
|
||||
Coroutine.async {
|
||||
//预下载
|
||||
val maxChapterIndex = durChapterIndex + AppConfig.preDownloadNum
|
||||
|
||||
@@ -71,7 +71,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
}
|
||||
}
|
||||
cacheChapters[book.bookUrl] = chapterCaches
|
||||
upAdapterLiveData.postValue(book.bookUrl)
|
||||
upAdapterLiveData.sendValue(book.bookUrl)
|
||||
}
|
||||
ensureActive()
|
||||
}
|
||||
@@ -97,7 +97,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
if (exportProgress.contains(book.bookUrl)) return
|
||||
exportProgress[book.bookUrl] = 0
|
||||
exportMsg.remove(book.bookUrl)
|
||||
upAdapterLiveData.postValue(book.bookUrl)
|
||||
upAdapterLiveData.sendValue(book.bookUrl)
|
||||
execute {
|
||||
mutex.withLock {
|
||||
while (exportNumber > 0) {
|
||||
@@ -260,7 +260,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
if (exportProgress.contains(book.bookUrl)) return
|
||||
exportProgress[book.bookUrl] = 0
|
||||
exportMsg.remove(book.bookUrl)
|
||||
upAdapterLiveData.postValue(book.bookUrl)
|
||||
upAdapterLiveData.sendValue(book.bookUrl)
|
||||
execute {
|
||||
mutex.withLock {
|
||||
while (exportNumber > 0) {
|
||||
|
||||
@@ -650,6 +650,10 @@ object ChapterProvider {
|
||||
"0" -> doublePage = false
|
||||
"1" -> doublePage = true
|
||||
"2" -> {
|
||||
doublePage = (viewWidth > viewHeight)
|
||||
&& ReadBook.pageAnim() != 3
|
||||
}
|
||||
"3" -> {
|
||||
doublePage = (viewWidth > viewHeight || appCtx.isPad)
|
||||
&& ReadBook.pageAnim() != 3
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.flexbox.FlexboxLayoutManager
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.VMBaseActivity
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.Book
|
||||
@@ -32,7 +33,9 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import splitties.init.appCtx
|
||||
@@ -288,6 +291,17 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
|
||||
groups = it
|
||||
}
|
||||
}
|
||||
launch {
|
||||
appDb.bookDao.flowAll().conflate().map { books ->
|
||||
books.map { "${it.name}-${it.author}" }
|
||||
}.catch { e ->
|
||||
AppLog.put("加载书架数据失败", e)
|
||||
}.collect {
|
||||
viewModel.bookshelf.clear()
|
||||
viewModel.bookshelf.addAll(it)
|
||||
viewModel.upAdapterLiveData.postValue("isInBookshelf")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,14 +10,10 @@ import io.legado.app.data.entities.SearchKeyword
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.model.webBook.SearchModel
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SearchViewModel(application: Application) : BaseViewModel(application) {
|
||||
val bookshelf = hashSetOf<String>()
|
||||
val upAdapterLiveData = MutableLiveData<String>()
|
||||
@@ -61,18 +57,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
|
||||
}
|
||||
}.flowOn(IO)
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
appDb.bookDao.flowAll().mapLatest { books ->
|
||||
books.map { "${it.name}-${it.author}" }
|
||||
}.collect {
|
||||
bookshelf.clear()
|
||||
bookshelf.addAll(it)
|
||||
upAdapterLiveData.postValue("isInBookshelf")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始搜索
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.BookSource
|
||||
import io.legado.app.data.entities.rule.*
|
||||
import io.legado.app.databinding.ActivityBookSourceEditBinding
|
||||
import io.legado.app.databinding.DialogEditTextBinding
|
||||
import io.legado.app.help.config.LocalConfig
|
||||
import io.legado.app.lib.dialogs.SelectItem
|
||||
import io.legado.app.lib.dialogs.alert
|
||||
@@ -140,6 +141,7 @@ class BookSourceEditActivity :
|
||||
}
|
||||
}
|
||||
}
|
||||
R.id.menu_set_source_variable -> setSourceVariable()
|
||||
}
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
@@ -171,7 +173,12 @@ class BookSourceEditActivity :
|
||||
|
||||
override fun finish() {
|
||||
val source = getSource()
|
||||
if (!source.equal(viewModel.bookSource ?: BookSource())) {
|
||||
val source2 = viewModel.bookSource ?: BookSource().apply {
|
||||
enabledExplore = true
|
||||
enabledCookieJar = true
|
||||
enabledReview = true
|
||||
}
|
||||
if (!source.equal(source2)) {
|
||||
alert(R.string.exit) {
|
||||
setMessage(R.string.exit_no_save)
|
||||
positiveButton(R.string.yes)
|
||||
@@ -569,4 +576,30 @@ class BookSourceEditActivity :
|
||||
showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD))
|
||||
}
|
||||
|
||||
private fun setSourceVariable() {
|
||||
launch {
|
||||
val source = viewModel.bookSource
|
||||
if (source == null) {
|
||||
toastOnUi("书源不存在")
|
||||
return@launch
|
||||
}
|
||||
val variable = withContext(IO) { source.getVariable() }
|
||||
alert(R.string.set_source_variable) {
|
||||
setMessage(source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取"))
|
||||
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
|
||||
editView.hint = "source variable"
|
||||
editView.setText(variable)
|
||||
}
|
||||
customView { alertBinding.root }
|
||||
okButton {
|
||||
viewModel.bookSource?.setVariable(alertBinding.editView.text?.toString())
|
||||
}
|
||||
cancelButton()
|
||||
neutralButton(R.string.delete) {
|
||||
viewModel.bookSource?.setVariable(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package io.legado.app.ui.book.source.manage
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.os.bundleOf
|
||||
@@ -70,9 +69,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
private var sort = Sort.Default
|
||||
private var sortAscending = true
|
||||
private var snackBar: Snackbar? = null
|
||||
private val displayManager by lazy {
|
||||
getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
}
|
||||
private var isPaused = false
|
||||
private val qrResult = registerForActivityResult(QrCodeResult()) {
|
||||
it ?: return@registerForActivityResult
|
||||
showDialogFragment(ImportBookSourceDialog(it))
|
||||
@@ -516,7 +513,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
delay(300L)
|
||||
}
|
||||
}.collect {
|
||||
if (isScreenOn()) {
|
||||
if (SystemUtils.isScreenOn() && !isPaused) {
|
||||
if (lastItem == 0) {
|
||||
adapter.notifyItemRangeChanged(
|
||||
0,
|
||||
@@ -552,11 +549,14 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
|
||||
}
|
||||
}
|
||||
|
||||
private fun isScreenOn(): Boolean {
|
||||
return displayManager.displays.any {
|
||||
it ?: return@any false
|
||||
it.state != Display.STATE_OFF
|
||||
}
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
isPaused = true
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
isPaused = false
|
||||
}
|
||||
|
||||
override fun upCountView() {
|
||||
|
||||
@@ -75,6 +75,11 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
|
||||
return super.onCompatCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||
menu?.findItem(R.id.menu_split_long_chapter)?.isVisible = false
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.menu_add -> showDialogFragment(TxtTocRuleEditDialog())
|
||||
|
||||
@@ -73,6 +73,7 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
|
||||
getItem(holder.layoutPosition)?.let {
|
||||
if (buttonView.isPressed) {
|
||||
it.enable = isChecked
|
||||
callBack.update(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,18 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
upLastUpdateTimeJob?.cancel()
|
||||
booksFlowJob?.cancel()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
startLastUpdateTimeJob()
|
||||
upRecyclerData()
|
||||
}
|
||||
|
||||
private fun startLastUpdateTimeJob() {
|
||||
upLastUpdateTimeJob?.cancel()
|
||||
if (!AppConfig.showLastUpdateTime) {
|
||||
@@ -159,7 +171,9 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
|
||||
}
|
||||
upLastUpdateTimeJob = launch {
|
||||
while (isActive) {
|
||||
booksAdapter.upLastUpdateTime()
|
||||
if (SystemUtils.isScreenOn()) {
|
||||
booksAdapter.upLastUpdateTime()
|
||||
}
|
||||
delay(30 * 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +215,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
|
||||
}
|
||||
|
||||
override fun upStarMenu() {
|
||||
starMenuItem?.isVisible = viewModel.rssArticle != null
|
||||
if (viewModel.rssStar != null) {
|
||||
starMenuItem?.setIcon(R.drawable.ic_star)
|
||||
starMenuItem?.setTitle(R.string.in_favorites)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
||||
private val mainHandler by lazy { Handler(Looper.getMainLooper()) }
|
||||
|
||||
fun <T> MutableLiveData<T>.sendValue(value: T) {
|
||||
mainHandler.post {
|
||||
this@sendValue.value = value
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import android.view.Display
|
||||
import splitties.systemservices.displayManager
|
||||
import splitties.systemservices.powerManager
|
||||
|
||||
|
||||
@@ -28,4 +30,9 @@ object SystemUtils {
|
||||
}
|
||||
}
|
||||
|
||||
fun isScreenOn(): Boolean {
|
||||
return displayManager.displays.filterNotNull().any {
|
||||
it.state != Display.STATE_OFF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@color/md_green_600"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintRight_toRightOf="@id/iv_cover"
|
||||
app:layout_constraintTop_toTopOf="@id/iv_cover" />
|
||||
app:layout_constraintLeft_toRightOf="@id/iv_cover"
|
||||
app:layout_constraintTop_toTopOf="@id/tv_name" />
|
||||
|
||||
<io.legado.app.ui.widget.text.BadgeView
|
||||
android:id="@+id/bv_originCount"
|
||||
@@ -48,16 +48,17 @@
|
||||
android:textColor="@color/primaryText"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toStartOf="@id/bv_originCount"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_cover"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_in_bookshelf"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="3dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/iv_cover"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/tv_name"
|
||||
app:layout_constraintLeft_toRightOf="@+id/iv_cover"
|
||||
app:layout_constraintRight_toRightOf="@id/tv_name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_name">
|
||||
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
android:title="@string/paste_source"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_set_source_variable"
|
||||
android:title="@string/set_source_variable"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_qr_code_camera"
|
||||
android:title="@string/import_by_qr_code"
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
<string-array name="double_page_title">
|
||||
<item>全局单页</item>
|
||||
<item>全局双页</item>
|
||||
<item>横屏双页/竖屏单页</item>
|
||||
<item>横屏双页</item>
|
||||
<item>平板/横屏双页</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="NavBarColors">
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="progress_bar_behavior_value">
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
<string-array name="double_page_title">
|
||||
<item>全局单页</item>
|
||||
<item>全局双页</item>
|
||||
<item>横屏双页 竖屏单页</item>
|
||||
<item>横屏双页</item>
|
||||
<item>平板/横屏双页</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="progress_bar_behavior_title">
|
||||
|
||||
Reference in New Issue
Block a user