Browse Source

feat: 阅读界面改成nav3导航

HapeLee 3 months ago
parent
commit
caaebabf3f

+ 11 - 2
app/src/main/java/io/legado/app/ui/book/read/ReadBookContract.kt

@@ -411,10 +411,19 @@ internal val MoreActionIds = listOf(
     "bottom_button_config", "log",
 )
 
+@Immutable
+data class ReadBookInitRequest(
+    val bookUrl: String? = null,
+    val inBookshelf: Boolean = true,
+    val chapterChanged: Boolean = false,
+    val chapterIndex: Int = -1,
+    val chapterPos: Int = -1,
+)
+
 sealed interface ReadBookIntent {
     // Initialization
-    data class InitData(val intent: android.content.Intent) : ReadBookIntent
-    data class InitReadBookConfig(val intent: android.content.Intent) : ReadBookIntent
+    data class InitData(val request: ReadBookInitRequest) : ReadBookIntent
+    data class InitReadBookConfig(val request: ReadBookInitRequest) : ReadBookIntent
     data class CheckSwitchDayNight(val lux: Float) : ReadBookIntent
     data object DismissReminder : ReadBookIntent
 

+ 9 - 10
app/src/main/java/io/legado/app/ui/book/read/ReadBookLoadDelegate.kt

@@ -1,7 +1,6 @@
 package io.legado.app.ui.book.read
 
 import android.content.Context
-import android.content.Intent
 import io.legado.app.R
 import io.legado.app.constant.AppLog
 import io.legado.app.constant.EventBus
@@ -48,7 +47,7 @@ import kotlin.coroutines.coroutineContext
 /**
  * 开书 / 目录加载 / 换源 / 进度同步域(R2.2 续批)。
  *
- * 从 intent 解析出书,装载目录与正文,处理本地文件缺失、换源(手动与自动)、
+ * 从导航请求解析出书,装载目录与正文,处理本地文件缺失、换源(手动与自动)、
  * 以及与云端阅读进度的双向同步。
  *
  * **无自持状态**:唯一的状态是 `isInitFinish`(ReadView 首帧靠它放行前后章排版,
@@ -92,8 +91,8 @@ class ReadBookLoadDelegate(
 
     private var changeSourceCoroutine: Coroutine<*>? = null
 
-    suspend fun initReadBookConfig(intent: Intent) {
-        val bookUrl = intent.getStringExtra("bookUrl")
+    suspend fun initReadBookConfig(request: ReadBookInitRequest) {
+        val bookUrl = request.bookUrl
         val book = when {
             bookUrl.isNullOrEmpty() -> bookRepository.getLastReadBook()
             else -> bookRepository.getBook(bookUrl)
@@ -101,12 +100,12 @@ class ReadBookLoadDelegate(
         ReadBook.upReadBookConfig(book)
     }
 
-    fun initData(intent: Intent, success: (() -> Unit)? = null) {
+    fun initData(request: ReadBookInitRequest, success: (() -> Unit)? = null) {
         Coroutine.async(scope, Dispatchers.IO) {
             host.syncReadPreferencesSnapshot()
-            ReadBook.inBookshelf = intent.getBooleanExtra("inBookshelf", true)
-            ReadBook.chapterChanged = intent.getBooleanExtra("chapterChanged", false)
-            val bookUrl = intent.getStringExtra("bookUrl")
+            ReadBook.inBookshelf = request.inBookshelf
+            ReadBook.chapterChanged = request.chapterChanged
+            val bookUrl = request.bookUrl
             val book = when {
                 bookUrl.isNullOrEmpty() -> bookRepository.getLastReadBook()
                 else -> bookRepository.getBook(bookUrl)
@@ -118,8 +117,8 @@ class ReadBookLoadDelegate(
                     AppLog.put("未找到书籍\nbookUrl:$bookUrl")
                 }
             }
-            val index = intent.getIntExtra("index", -1)
-            val chapterPos = intent.getIntExtra("chapterPos", -1)
+            val index = request.chapterIndex
+            val chapterPos = request.chapterPos
             if (index >= 0 && chapterPos >= 0) {
                 ReadBook.saveCurrentBookProgress()
                 host.openChapter(index, chapterPos)

+ 6 - 6
app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt

@@ -1,7 +1,6 @@
 package io.legado.app.ui.book.read
 
 import android.app.Application
-import android.content.Intent
 import android.net.Uri
 import android.speech.tts.TextToSpeech
 import androidx.lifecycle.viewModelScope
@@ -641,11 +640,11 @@ class ReadBookViewModel(
     fun onIntent(intent: ReadBookIntent) {
         when (intent) {
             is ReadBookIntent.InitData -> {
-                initData(intent.intent)
+                initData(intent.request)
                 justInitData = true
             }
             is ReadBookIntent.InitReadBookConfig -> viewModelScope.launch {
-                initReadBookConfig(intent.intent)
+                initReadBookConfig(intent.request)
             }
             is ReadBookIntent.CheckSwitchDayNight -> styleDelegate.checkSwitchDayNight(intent.lux)
             is ReadBookIntent.DismissReminder -> styleDelegate.dismissReminder()
@@ -1982,10 +1981,11 @@ class ReadBookViewModel(
 
     // 开书 / 目录 / 换源 / 进度同步已迁入 [ReadBookLoadDelegate],这里只留外部入口的转发。
 
-    suspend fun initReadBookConfig(intent: Intent) = loadDelegate.initReadBookConfig(intent)
+    suspend fun initReadBookConfig(request: ReadBookInitRequest) =
+        loadDelegate.initReadBookConfig(request)
 
-    fun initData(intent: Intent, success: (() -> Unit)? = null) =
-        loadDelegate.initData(intent, success)
+    fun initData(request: ReadBookInitRequest, success: (() -> Unit)? = null) =
+        loadDelegate.initData(request, success)
 
     fun markJustInitData() {
         justInitData = true

+ 23 - 5
app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt

@@ -6,13 +6,16 @@ import android.graphics.Bitmap
 import android.graphics.Canvas
 import android.graphics.Typeface
 import android.graphics.drawable.LayerDrawable
+import android.os.Build
 import android.view.LayoutInflater
+import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.core.content.ContextCompat
 import androidx.core.graphics.drawable.toDrawable
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.isGone
+import androidx.core.view.updateLayoutParams
 import io.legado.app.R
 import io.legado.app.constant.AppConst.timeFormat
 import io.legado.app.constant.ReadTipType
@@ -29,13 +32,11 @@ import io.legado.app.ui.book.read.page.provider.TipStyleProvider
 import io.legado.app.ui.book.read.sheet.CustomTipTarget
 import io.legado.app.ui.config.readConfig.ReadConfig
 import io.legado.app.ui.widget.BatteryView
-import androidx.core.view.updateLayoutParams
 import io.legado.app.utils.activity
 import io.legado.app.utils.applyStatusBarPadding
 import io.legado.app.utils.canvasrecorder.CanvasRecorder
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.gone
-import io.legado.app.utils.navigationBarHeight
 import io.legado.app.utils.setOnApplyWindowInsetsListenerCompat
 import io.legado.app.utils.statusBarHeight
 import splitties.views.backgroundColor
@@ -101,9 +102,10 @@ class PageView(
         callBack?.let { binding.contentTextView.setCallBack(it) }
         upStyle()
         binding.vwStatusBar.applyStatusBarPadding()
-        if (ReadSessionState.lastNavigationBarHeight > 0) {
+        val initialNavigationBarHeight = currentNavigationBarHeight()
+        if (initialNavigationBarHeight > 0) {
             binding.vwNavigationBar.updateLayoutParams {
-                height = ReadSessionState.lastNavigationBarHeight
+                height = initialNavigationBarHeight
             }
         }
         binding.vwNavigationBar.setOnApplyWindowInsetsListenerCompat { v, windowInsets ->
@@ -112,7 +114,9 @@ class PageView(
                 return@setOnApplyWindowInsetsListenerCompat windowInsets
             }
             //Log.d("fansangg", "vwNavigationBar OnApplyWindowInsetsListener: navHeight=$navHeight, isImeVisible=${windowInsets.isVisible(WindowInsetsCompat.Type.ime())}, imeHeight=${windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom}, systemBarsHeight=${windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom}")
-            val navHeight = windowInsets.navigationBarHeight
+            val navHeight = windowInsets.getInsetsIgnoringVisibility(
+                WindowInsetsCompat.Type.navigationBars()
+            ).bottom
             if (navHeight > 0) {
                 ReadSessionState.lastNavigationBarHeight = navHeight
             }
@@ -123,6 +127,20 @@ class PageView(
         }
     }
 
+    private fun currentNavigationBarHeight(): Int {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            val stableHeight = activity?.windowManager?.currentWindowMetrics?.windowInsets
+                ?.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars())
+                ?.bottom
+                ?: 0
+            if (stableHeight > 0) {
+                ReadSessionState.lastNavigationBarHeight = stableHeight
+                return stableHeight
+            }
+        }
+        return ReadSessionState.lastNavigationBarHeight
+    }
+
     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
         super.onSizeChanged(w, h, oldw, oldh)
         upBg()

+ 5 - 6
app/src/main/java/io/legado/app/ui/main/MainNavGraph.kt

@@ -64,6 +64,7 @@ import io.legado.app.ui.book.knowledge.deleteCharacterAvatar
 import io.legado.app.ui.book.knowledge.saveCharacterAvatar
 import io.legado.app.ui.book.manage.BookshelfManageRouteScreen
 import io.legado.app.ui.book.read.ReadBookController
+import io.legado.app.ui.book.read.ReadBookInitRequest
 import io.legado.app.ui.book.read.ReadBookIntent
 import io.legado.app.ui.book.read.ReadBookRouteScreen
 import io.legado.app.ui.book.read.ReadBookViewModel
@@ -566,11 +567,9 @@ fun MainActivity.mainEntryProvider(
             readBookViewModel.prepareCachedChapterFallback(route.bookUrl, route.chapterChanged)
         }
         val lifecycleOwner = LocalLifecycleOwner.current
-        val readIntent = remember(route) {
-            MainActivity.createReadBookIntent(
-                context = this@mainEntryProvider,
+        val initRequest = remember(route) {
+            ReadBookInitRequest(
                 bookUrl = route.bookUrl,
-                readAloud = route.readAloud,
                 inBookshelf = route.inBookshelf,
                 chapterChanged = route.chapterChanged,
             )
@@ -658,8 +657,8 @@ fun MainActivity.mainEntryProvider(
         LaunchedEffect(route, readBookViewModel, lifecycleOwner) {
             effectsReady.await()
             collectorReady[0] = true
-            readBookViewModel.initReadBookConfig(readIntent)
-            readBookViewModel.initData(readIntent) {
+            readBookViewModel.initReadBookConfig(initRequest)
+            readBookViewModel.initData(initRequest) {
                 readBookViewModel.markJustInitData()
                 controller.onRouteInitialized()
                 if (lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {

+ 5 - 6
app/src/main/java/io/legado/app/ui/widget/components/FontSelectSheet.kt

@@ -3,9 +3,6 @@ package io.legado.app.ui.widget.components
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.FolderOpen
 import androidx.compose.material.icons.filled.TextFields
-import androidx.compose.material3.DropdownMenu
-import androidx.compose.material3.DropdownMenuItem
-import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -19,6 +16,8 @@ import androidx.documentfile.provider.DocumentFile
 import io.legado.app.R
 import io.legado.app.ui.theme.ProvideAppDensity
 import io.legado.app.ui.widget.components.button.series.MediumTonalButton
+import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
+import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
 import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
 import io.legado.app.utils.FileDoc
 import io.legado.app.utils.isContentScheme
@@ -62,14 +61,14 @@ fun FontSelectSheet(
         startAction = {
             startAction?.invoke()
             if (systemTypefaces != null && onSelectSystemTypeface != null) {
-                DropdownMenu(
+                RoundDropdownMenu(
                     expanded = showTypefaceMenu,
                     onDismissRequest = { showTypefaceMenu = false },
                 ) {
                     ProvideAppDensity {
                         systemTypefaces.forEachIndexed { index, name ->
-                            DropdownMenuItem(
-                                text = { Text(name) },
+                            RoundDropdownMenuItem(
+                                text = name,
                                 onClick = {
                                     onSelectSystemTypeface(index)
                                     showTypefaceMenu = false