Просмотр исходного кода

书架更新时显示剩余更新数量,在书架布局里配置

kunfei 3 лет назад
Родитель
Сommit
299fe58891

+ 1 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -127,6 +127,7 @@ object PreferKey {
     const val audioPlayWakeLock = "audioPlayWakeLock"
     const val audioPlayWakeLock = "audioPlayWakeLock"
     const val readAloudWakeLock = "readAloudWakeLock"
     const val readAloudWakeLock = "readAloudWakeLock"
     const val showLastUpdateTime = "showLastUpdateTime"
     const val showLastUpdateTime = "showLastUpdateTime"
+    const val showWaitUpCount = "showWaitUpCount"
     const val clearWebViewData = "clearWebViewData"
     const val clearWebViewData = "clearWebViewData"
     const val onlyLatestBackup = "onlyLatestBackup"
     const val onlyLatestBackup = "onlyLatestBackup"
     const val brightnessVwPos = "brightnessVwPos"
     const val brightnessVwPos = "brightnessVwPos"

+ 6 - 0
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -88,6 +88,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
             appCtx.putPrefBoolean(PreferKey.showLastUpdateTime, value)
             appCtx.putPrefBoolean(PreferKey.showLastUpdateTime, value)
         }
         }
 
 
+    var showWaitUpCount: Boolean
+        get() = appCtx.getPrefBoolean(PreferKey.showWaitUpCount, false)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.showWaitUpCount, value)
+        }
+
     var readBrightness: Int
     var readBrightness: Int
         get() = if (isNightTheme) {
         get() = if (isNightTheme) {
             appCtx.getPrefInt(PreferKey.nightBrightness, 100)
             appCtx.getPrefInt(PreferKey.nightBrightness, 100)

+ 15 - 0
app/src/main/java/io/legado/app/lib/theme/view/ThemeBottomNavigationVIew.kt

@@ -2,11 +2,16 @@ package io.legado.app.lib.theme.view
 
 
 import android.content.Context
 import android.content.Context
 import android.util.AttributeSet
 import android.util.AttributeSet
+import android.view.LayoutInflater
+import com.google.android.material.bottomnavigation.BottomNavigationItemView
+import com.google.android.material.bottomnavigation.BottomNavigationMenuView
 import com.google.android.material.bottomnavigation.BottomNavigationView
 import com.google.android.material.bottomnavigation.BottomNavigationView
+import io.legado.app.databinding.ViewNavigationBadgeBinding
 import io.legado.app.lib.theme.Selector
 import io.legado.app.lib.theme.Selector
 import io.legado.app.lib.theme.ThemeStore
 import io.legado.app.lib.theme.ThemeStore
 import io.legado.app.lib.theme.bottomBackground
 import io.legado.app.lib.theme.bottomBackground
 import io.legado.app.lib.theme.getSecondaryTextColor
 import io.legado.app.lib.theme.getSecondaryTextColor
+import io.legado.app.ui.widget.text.BadgeView
 import io.legado.app.utils.ColorUtils
 import io.legado.app.utils.ColorUtils
 
 
 class ThemeBottomNavigationVIew(context: Context, attrs: AttributeSet) :
 class ThemeBottomNavigationVIew(context: Context, attrs: AttributeSet) :
@@ -24,4 +29,14 @@ class ThemeBottomNavigationVIew(context: Context, attrs: AttributeSet) :
         itemTextColor = colorStateList
         itemTextColor = colorStateList
     }
     }
 
 
+    fun addBadgeView(index: Int): BadgeView {
+        //获取底部菜单view
+        val menuView = getChildAt(0) as BottomNavigationMenuView
+        //获取第index个itemView
+        val itemView = menuView.getChildAt(index) as BottomNavigationItemView
+        val badgeBinding = ViewNavigationBadgeBinding.inflate(LayoutInflater.from(context))
+        itemView.addView(badgeBinding.root)
+        return badgeBinding.viewBadge
+    }
+
 }
 }

+ 12 - 0
app/src/main/java/io/legado/app/ui/main/MainActivity.kt

@@ -74,6 +74,9 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
     private val adapter by lazy {
     private val adapter by lazy {
         TabFragmentPageAdapter(supportFragmentManager)
         TabFragmentPageAdapter(supportFragmentManager)
     }
     }
+    private val onUpBooksBadgeView by lazy {
+        binding.bottomNavigationView.addBadgeView(0)
+    }
 
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         upBottomMenu()
         upBottomMenu()
@@ -128,10 +131,13 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
         when (item.itemId) {
         when (item.itemId) {
             R.id.menu_bookshelf ->
             R.id.menu_bookshelf ->
                 viewPagerMain.setCurrentItem(0, false)
                 viewPagerMain.setCurrentItem(0, false)
+
             R.id.menu_discovery ->
             R.id.menu_discovery ->
                 viewPagerMain.setCurrentItem(realPositions.indexOf(idExplore), false)
                 viewPagerMain.setCurrentItem(realPositions.indexOf(idExplore), false)
+
             R.id.menu_rss ->
             R.id.menu_rss ->
                 viewPagerMain.setCurrentItem(realPositions.indexOf(idRss), false)
                 viewPagerMain.setCurrentItem(realPositions.indexOf(idRss), false)
+
             R.id.menu_my_config ->
             R.id.menu_my_config ->
                 viewPagerMain.setCurrentItem(realPositions.indexOf(idMy), false)
                 viewPagerMain.setCurrentItem(realPositions.indexOf(idMy), false)
         }
         }
@@ -147,6 +153,7 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
                     (fragmentMap[getFragmentId(0)] as? BaseBookshelfFragment)?.gotoTop()
                     (fragmentMap[getFragmentId(0)] as? BaseBookshelfFragment)?.gotoTop()
                 }
                 }
             }
             }
+
             R.id.menu_discovery -> {
             R.id.menu_discovery -> {
                 if (System.currentTimeMillis() - exploreReselected > 300) {
                 if (System.currentTimeMillis() - exploreReselected > 300) {
                     exploreReselected = System.currentTimeMillis()
                     exploreReselected = System.currentTimeMillis()
@@ -304,6 +311,9 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
     }
     }
 
 
     override fun observeLiveBus() {
     override fun observeLiveBus() {
+        viewModel.onUpBooksLiveData.observe(this) {
+            onUpBooksBadgeView.setBadgeCount(it)
+        }
         observeEvent<String>(EventBus.RECREATE) {
         observeEvent<String>(EventBus.RECREATE) {
             recreate()
             recreate()
         }
         }
@@ -400,9 +410,11 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
     }
     }
 
 
     interface Callback {
     interface Callback {
+
         fun onActive()
         fun onActive()
 
 
         fun onInactive()
         fun onInactive()
+
     }
     }
 
 
 }
 }

+ 27 - 2
app/src/main/java/io/legado/app/ui/main/MainViewModel.kt

@@ -1,6 +1,7 @@
 package io.legado.app.ui.main
 package io.legado.app.ui.main
 
 
 import android.app.Application
 import android.app.Application
+import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.viewModelScope
 import androidx.lifecycle.viewModelScope
 import io.legado.app.base.BaseViewModel
 import io.legado.app.base.BaseViewModel
 import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppConst
@@ -12,15 +13,25 @@ import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.BookSource
 import io.legado.app.help.AppWebDav
 import io.legado.app.help.AppWebDav
 import io.legado.app.help.DefaultData
 import io.legado.app.help.DefaultData
-import io.legado.app.help.book.*
+import io.legado.app.help.book.BookHelp
+import io.legado.app.help.book.addType
+import io.legado.app.help.book.isLocal
+import io.legado.app.help.book.isSameNameAuthor
+import io.legado.app.help.book.isUpError
+import io.legado.app.help.book.removeType
+import io.legado.app.help.book.sync
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
 import io.legado.app.model.CacheBook
 import io.legado.app.model.CacheBook
 import io.legado.app.model.ReadBook
 import io.legado.app.model.ReadBook
 import io.legado.app.model.webBook.WebBook
 import io.legado.app.model.webBook.WebBook
 import io.legado.app.service.CacheBookService
 import io.legado.app.service.CacheBookService
 import io.legado.app.utils.postEvent
 import io.legado.app.utils.postEvent
-import kotlinx.coroutines.*
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
 import java.util.concurrent.CopyOnWriteArraySet
 import java.util.concurrent.CopyOnWriteArraySet
 import java.util.concurrent.Executors
 import java.util.concurrent.Executors
 import kotlin.math.min
 import kotlin.math.min
@@ -31,6 +42,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
         Executors.newFixedThreadPool(min(threadCount, AppConst.MAX_THREAD)).asCoroutineDispatcher()
         Executors.newFixedThreadPool(min(threadCount, AppConst.MAX_THREAD)).asCoroutineDispatcher()
     private val waitUpTocBooks = arrayListOf<String>()
     private val waitUpTocBooks = arrayListOf<String>()
     private val onUpTocBooks = CopyOnWriteArraySet<String>()
     private val onUpTocBooks = CopyOnWriteArraySet<String>()
+    val onUpBooksLiveData = MutableLiveData<Int>()
     private var upTocJob: Job? = null
     private var upTocJob: Job? = null
     private var cacheBookJob: Job? = null
     private var cacheBookJob: Job? = null
 
 
@@ -79,6 +91,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
     }
     }
 
 
     private fun startUpTocJob() {
     private fun startUpTocJob() {
+        postUpBooksLiveData()
         upTocJob = viewModelScope.launch(upTocPool) {
         upTocJob = viewModelScope.launch(upTocPool) {
             while (isActive) {
             while (isActive) {
                 when {
                 when {
@@ -104,11 +117,13 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
         val bookUrl = waitUpTocBooks.firstOrNull() ?: return
         val bookUrl = waitUpTocBooks.firstOrNull() ?: return
         if (onUpTocBooks.contains(bookUrl)) {
         if (onUpTocBooks.contains(bookUrl)) {
             waitUpTocBooks.remove(bookUrl)
             waitUpTocBooks.remove(bookUrl)
+            postUpBooksLiveData()
             return
             return
         }
         }
         val book = appDb.bookDao.getBook(bookUrl)
         val book = appDb.bookDao.getBook(bookUrl)
         if (book == null) {
         if (book == null) {
             waitUpTocBooks.remove(bookUrl)
             waitUpTocBooks.remove(bookUrl)
+            postUpBooksLiveData()
             return
             return
         }
         }
         val source = appDb.bookSourceDao.getBookSource(book.origin)
         val source = appDb.bookSourceDao.getBookSource(book.origin)
@@ -118,6 +133,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
                 appDb.bookDao.update(book)
                 appDb.bookDao.update(book)
             }
             }
             waitUpTocBooks.remove(book.bookUrl)
             waitUpTocBooks.remove(book.bookUrl)
+            postUpBooksLiveData()
             return
             return
         }
         }
         waitUpTocBooks.remove(bookUrl)
         waitUpTocBooks.remove(bookUrl)
@@ -160,6 +176,15 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
         }.onFinally(upTocPool) {
         }.onFinally(upTocPool) {
             upTocFinally(bookUrl)
             upTocFinally(bookUrl)
             upTocFinally(book.bookUrl)
             upTocFinally(book.bookUrl)
+            postUpBooksLiveData()
+        }
+    }
+
+    fun postUpBooksLiveData() {
+        if (AppConfig.showWaitUpCount) {
+            onUpBooksLiveData.postValue(waitUpTocBooks.size + onUpTocBooks.size)
+        } else {
+            onUpBooksLiveData.postValue(0)
         }
         }
     }
     }
 
 

+ 5 - 0
app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt

@@ -135,6 +135,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
                         spGroupStyle.setSelection(AppConfig.bookGroupStyle)
                         spGroupStyle.setSelection(AppConfig.bookGroupStyle)
                         swShowUnread.isChecked = AppConfig.showUnread
                         swShowUnread.isChecked = AppConfig.showUnread
                         swShowLastUpdateTime.isChecked = AppConfig.showLastUpdateTime
                         swShowLastUpdateTime.isChecked = AppConfig.showLastUpdateTime
+                        swShowWaitUpBooks.isChecked = AppConfig.showWaitUpCount
                         rgLayout.checkByIndex(bookshelfLayout)
                         rgLayout.checkByIndex(bookshelfLayout)
                         rgSort.checkByIndex(bookshelfSort)
                         rgSort.checkByIndex(bookshelfSort)
                     }
                     }
@@ -153,6 +154,10 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
                         AppConfig.showLastUpdateTime = swShowLastUpdateTime.isChecked
                         AppConfig.showLastUpdateTime = swShowLastUpdateTime.isChecked
                         postEvent(EventBus.BOOKSHELF_REFRESH, "")
                         postEvent(EventBus.BOOKSHELF_REFRESH, "")
                     }
                     }
+                    if (AppConfig.showWaitUpCount != swShowWaitUpBooks.isChecked) {
+                        AppConfig.showWaitUpCount = swShowWaitUpBooks.isChecked
+                        activityViewModel.postUpBooksLiveData()
+                    }
                     var changed = false
                     var changed = false
                     if (bookshelfLayout != rgLayout.getCheckedIndex()) {
                     if (bookshelfLayout != rgLayout.getCheckedIndex()) {
                         putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex())
                         putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex())

+ 11 - 2
app/src/main/res/layout/dialog_bookshelf_config.xml

@@ -49,13 +49,22 @@
         app:layout_constraintTop_toBottomOf="@+id/sw_show_unread"
         app:layout_constraintTop_toBottomOf="@+id/sw_show_unread"
         tools:ignore="TouchTargetSizeCheck" />
         tools:ignore="TouchTargetSizeCheck" />
 
 
+    <io.legado.app.lib.theme.view.ThemeSwitch
+        android:id="@+id/sw_show_wait_up_books"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="6dp"
+        android:text="@string/show_wait_up_count"
+        app:layout_constraintTop_toBottomOf="@+id/sw_show_last_update_time"
+        tools:ignore="TouchTargetSizeCheck" />
+
     <LinearLayout
     <LinearLayout
         android:id="@+id/ll_layout"
         android:id="@+id/ll_layout"
         android:layout_width="0dp"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:orientation="vertical"
         app:layout_constraintRight_toLeftOf="@+id/ll_sort"
         app:layout_constraintRight_toLeftOf="@+id/ll_sort"
-        app:layout_constraintTop_toBottomOf="@+id/sw_show_last_update_time"
+        app:layout_constraintTop_toBottomOf="@+id/sw_show_wait_up_books"
         app:layout_constraintLeft_toLeftOf="parent">
         app:layout_constraintLeft_toLeftOf="parent">
 
 
         <io.legado.app.ui.widget.text.AccentTextView
         <io.legado.app.ui.widget.text.AccentTextView
@@ -110,7 +119,7 @@
         android:layout_height="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:orientation="vertical"
         app:layout_constraintLeft_toRightOf="@+id/ll_layout"
         app:layout_constraintLeft_toRightOf="@+id/ll_layout"
-        app:layout_constraintTop_toBottomOf="@id/sw_show_last_update_time"
+        app:layout_constraintTop_toBottomOf="@id/sw_show_wait_up_books"
         app:layout_constraintRight_toRightOf="parent">
         app:layout_constraintRight_toRightOf="parent">
 
 
         <io.legado.app.ui.widget.text.AccentTextView
         <io.legado.app.ui.widget.text.AccentTextView

+ 16 - 0
app/src/main/res/layout/view_navigation_badge.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <io.legado.app.ui.widget.text.BadgeView
+        android:id="@+id/view_badge"
+        android:layout_width="wrap_content"
+        android:layout_height="18dp"
+        android:layout_marginLeft="12dp"
+        android:layout_marginTop="2dp"
+        android:layout_gravity="center_horizontal"
+        tools:ignore="RtlHardcoded" />
+
+</FrameLayout>

+ 1 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -1115,4 +1115,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -1118,4 +1118,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -1118,4 +1118,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -1115,4 +1115,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -1117,4 +1117,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-zh/strings.xml

@@ -1117,4 +1117,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -1118,4 +1118,5 @@
     <string name="is_compress">是否压缩</string>
     <string name="is_compress">是否压缩</string>
     <string name="sort_desc">反序</string>
     <string name="sort_desc">反序</string>
     <string name="test">测试</string>
     <string name="test">测试</string>
+    <string name="show_wait_up_count">显示等待更新数量</string>
 </resources>
 </resources>