代码优化
This commit is contained in:
@@ -3,9 +3,10 @@ package io.legado.app.help.rhino
|
||||
import com.script.rhino.JavaObjectWrapFactory
|
||||
import org.mozilla.javascript.NativeJavaObject
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.lc.type.TypeInfoFactory
|
||||
|
||||
class NativeBaseSource(scope: Scriptable?, javaObject: Any, staticType: Class<*>?) :
|
||||
NativeJavaObject(scope, javaObject, staticType) {
|
||||
NativeJavaObject(scope, javaObject, staticType?.let { TypeInfoFactory.GLOBAL.create(it) }) {
|
||||
|
||||
override fun has(name: String, start: Scriptable): Boolean {
|
||||
if (name != "setVariable" && name.length > 3 && name.startsWith("set")) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.legado.app.ui.config
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
@@ -21,9 +22,14 @@ import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
interface PrefDelegate<T> : ReadWriteProperty<Any?, T> {
|
||||
val state: State<T>
|
||||
fun dispose()
|
||||
}
|
||||
|
||||
class PrefStateDelegate<T>(private val delegate: PrefDelegate<T>) : ReadWriteProperty<Any?, T> by delegate {
|
||||
val state: State<T> get() = delegate.state
|
||||
}
|
||||
|
||||
fun <T> prefDelegate(
|
||||
key: String,
|
||||
defaultValue: T,
|
||||
@@ -32,6 +38,7 @@ fun <T> prefDelegate(
|
||||
): PrefDelegate<T> {
|
||||
return object : PrefDelegate<T>, SharedPreferences.OnSharedPreferenceChangeListener, DefaultLifecycleObserver {
|
||||
private var _value: MutableState<T> = mutableStateOf(readInitialValue())
|
||||
override val state: State<T> get() = _value
|
||||
|
||||
init {
|
||||
if (lifecycleOwner != null) {
|
||||
@@ -98,4 +105,14 @@ fun <T> prefDelegate(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> prefStateDelegate(
|
||||
key: String,
|
||||
defaultValue: T,
|
||||
lifecycleOwner: LifecycleOwner? = null,
|
||||
onValueChange: ((T) -> Unit)? = null
|
||||
): PrefStateDelegate<T> {
|
||||
val delegate = prefDelegate(key, defaultValue, lifecycleOwner, onValueChange)
|
||||
return PrefStateDelegate(delegate)
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.legado.app.ui.config.bookshelfConfig
|
||||
|
||||
import androidx.compose.runtime.State
|
||||
import io.legado.app.constant.EventBus
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.data.entities.BookGroup
|
||||
import io.legado.app.ui.config.prefDelegate
|
||||
import io.legado.app.ui.config.prefStateDelegate
|
||||
import io.legado.app.utils.postEvent
|
||||
|
||||
/**
|
||||
@@ -14,213 +15,295 @@ object BookshelfConfig {
|
||||
/**
|
||||
* 书架分组样式: 0: Tab, 1:隐藏Tab, 2:文件夹
|
||||
*/
|
||||
var bookGroupStyle by prefDelegate(PreferKey.bookGroupStyle, 0) {
|
||||
private val _bookGroupStyle = prefStateDelegate(PreferKey.bookGroupStyle, 0) {
|
||||
postEvent(EventBus.NOTIFY_MAIN, false)
|
||||
}
|
||||
var bookGroupStyle by _bookGroupStyle
|
||||
val bookGroupStyleState: State<Int> get() = _bookGroupStyle.state
|
||||
|
||||
/**
|
||||
* 书架排序方式
|
||||
*/
|
||||
var bookshelfSort by prefDelegate(PreferKey.bookshelfSort, 0)
|
||||
private val _bookshelfSort = prefStateDelegate(PreferKey.bookshelfSort, 0)
|
||||
var bookshelfSort by _bookshelfSort
|
||||
val bookshelfSortState: State<Int> get() = _bookshelfSort.state
|
||||
|
||||
/**
|
||||
* 书架排序顺序
|
||||
*/
|
||||
var bookshelfSortOrder by prefDelegate(PreferKey.bookshelfSortOrder, 1)
|
||||
private val _bookshelfSortOrder = prefStateDelegate(PreferKey.bookshelfSortOrder, 1)
|
||||
var bookshelfSortOrder by _bookshelfSortOrder
|
||||
val bookshelfSortOrderState: State<Int> get() = _bookshelfSortOrder.state
|
||||
|
||||
/**
|
||||
* 是否显示未读标志
|
||||
*/
|
||||
var showUnread by prefDelegate(PreferKey.showUnread, true)
|
||||
private val _showUnread = prefStateDelegate(PreferKey.showUnread, true)
|
||||
var showUnread by _showUnread
|
||||
val showUnreadState: State<Boolean> get() = _showUnread.state
|
||||
|
||||
/**
|
||||
* 是否显示新未读标志(小圆点)
|
||||
*/
|
||||
var showUnreadNew by prefDelegate(PreferKey.showUnreadNew, true)
|
||||
private val _showUnreadNew = prefStateDelegate(PreferKey.showUnreadNew, true)
|
||||
var showUnreadNew by _showUnreadNew
|
||||
val showUnreadNewState: State<Boolean> get() = _showUnreadNew.state
|
||||
|
||||
/**
|
||||
* 是否显示更新提示
|
||||
*/
|
||||
var showTip by prefDelegate(PreferKey.showTip, false)
|
||||
private val _showTip = prefStateDelegate(PreferKey.showTip, false)
|
||||
var showTip by _showTip
|
||||
val showTipState: State<Boolean> get() = _showTip.state
|
||||
|
||||
/**
|
||||
* 鏄惁鏄剧ず鍒嗙粍鍐呬功绫嶆暟閲?
|
||||
*/
|
||||
var showBookCount by prefDelegate(PreferKey.showBookCount, true)
|
||||
private val _showBookCount = prefStateDelegate(PreferKey.showBookCount, true)
|
||||
var showBookCount by _showBookCount
|
||||
val showBookCountState: State<Boolean> get() = _showBookCount.state
|
||||
|
||||
/**
|
||||
* 是否在列表中显示最后更新时间
|
||||
*/
|
||||
var showLastUpdateTime by prefDelegate(PreferKey.showLastUpdateTime, false)
|
||||
private val _showLastUpdateTime = prefStateDelegate(PreferKey.showLastUpdateTime, false)
|
||||
var showLastUpdateTime by _showLastUpdateTime
|
||||
val showLastUpdateTimeState: State<Boolean> get() = _showLastUpdateTime.state
|
||||
|
||||
/**
|
||||
* 是否在列表中显示书籍简介
|
||||
*/
|
||||
var showBookIntro by prefDelegate(PreferKey.showBookIntro, false)
|
||||
private val _showBookIntro = prefStateDelegate(PreferKey.showBookIntro, false)
|
||||
var showBookIntro by _showBookIntro
|
||||
val showBookIntroState: State<Boolean> get() = _showBookIntro.state
|
||||
|
||||
/**
|
||||
* 是否显示简介
|
||||
*/
|
||||
var bookshelfShowIntro by prefDelegate(PreferKey.bookshelfShowIntro, true)
|
||||
private val _bookshelfShowIntro = prefStateDelegate(PreferKey.bookshelfShowIntro, true)
|
||||
var bookshelfShowIntro by _bookshelfShowIntro
|
||||
val bookshelfShowIntroState: State<Boolean> get() = _bookshelfShowIntro.state
|
||||
|
||||
/**
|
||||
* 是否显示标签
|
||||
*/
|
||||
var bookshelfShowTag by prefDelegate(PreferKey.bookshelfShowTag, true)
|
||||
private val _bookshelfShowTag = prefStateDelegate(PreferKey.bookshelfShowTag, true)
|
||||
var bookshelfShowTag by _bookshelfShowTag
|
||||
val bookshelfShowTagState: State<Boolean> get() = _bookshelfShowTag.state
|
||||
|
||||
/**
|
||||
* 列表模式下简介显示行数 (0为显示全部)
|
||||
*/
|
||||
var bookshelfIntroMaxLines by prefDelegate(PreferKey.bookshelfIntroMaxLines, 0)
|
||||
private val _bookshelfIntroMaxLines = prefStateDelegate(PreferKey.bookshelfIntroMaxLines, 0)
|
||||
var bookshelfIntroMaxLines by _bookshelfIntroMaxLines
|
||||
val bookshelfIntroMaxLinesState: State<Int> get() = _bookshelfIntroMaxLines.state
|
||||
|
||||
/**
|
||||
* 是否显示等待更新的书籍数量
|
||||
*/
|
||||
var showWaitUpCount by prefDelegate(PreferKey.showWaitUpCount, false)
|
||||
private val _showWaitUpCount = prefStateDelegate(PreferKey.showWaitUpCount, false)
|
||||
var showWaitUpCount by _showWaitUpCount
|
||||
val showWaitUpCountState: State<Boolean> get() = _showWaitUpCount.state
|
||||
|
||||
/**
|
||||
* 是否显示书架快速滚动条
|
||||
*/
|
||||
var showBookshelfFastScroller by prefDelegate(PreferKey.showBookshelfFastScroller, false)
|
||||
private val _showBookshelfFastScroller = prefStateDelegate(PreferKey.showBookshelfFastScroller, false)
|
||||
var showBookshelfFastScroller by _showBookshelfFastScroller
|
||||
val showBookshelfFastScrollerState: State<Boolean> get() = _showBookshelfFastScroller.state
|
||||
|
||||
/**
|
||||
* 是否在书架Tab处显示分类展开按钮
|
||||
*/
|
||||
var shouldShowExpandButton by prefDelegate(PreferKey.shouldShowExpandButton, false)
|
||||
private val _shouldShowExpandButton = prefStateDelegate(PreferKey.shouldShowExpandButton, false)
|
||||
var shouldShowExpandButton by _shouldShowExpandButton
|
||||
val shouldShowExpandButtonState: State<Boolean> get() = _shouldShowExpandButton.state
|
||||
|
||||
/**
|
||||
* 书架同时更新书籍数量限制 (0为无限制)
|
||||
*/
|
||||
var bookshelfRefreshingLimit by prefDelegate(PreferKey.bookshelfRefreshingLimit, 0)
|
||||
private val _bookshelfRefreshingLimit = prefStateDelegate(PreferKey.bookshelfRefreshingLimit, 0)
|
||||
var bookshelfRefreshingLimit by _bookshelfRefreshingLimit
|
||||
val bookshelfRefreshingLimitState: State<Int> get() = _bookshelfRefreshingLimit.state
|
||||
|
||||
/**
|
||||
* 竖屏书架布局模式: 0:列表, 1:网格
|
||||
*/
|
||||
var bookshelfLayoutModePortrait by prefDelegate(PreferKey.bookshelfLayoutModePortrait, 1)
|
||||
private val _bookshelfLayoutModePortrait = prefStateDelegate(PreferKey.bookshelfLayoutModePortrait, 1)
|
||||
var bookshelfLayoutModePortrait by _bookshelfLayoutModePortrait
|
||||
val bookshelfLayoutModePortraitState: State<Int> get() = _bookshelfLayoutModePortrait.state
|
||||
|
||||
/**
|
||||
* 竖屏书架网格列数
|
||||
*/
|
||||
var bookshelfLayoutGridPortrait by prefDelegate(PreferKey.bookshelfLayoutGridPortrait, 3)
|
||||
private val _bookshelfLayoutGridPortrait = prefStateDelegate(PreferKey.bookshelfLayoutGridPortrait, 3)
|
||||
var bookshelfLayoutGridPortrait by _bookshelfLayoutGridPortrait
|
||||
val bookshelfLayoutGridPortraitState: State<Int> get() = _bookshelfLayoutGridPortrait.state
|
||||
|
||||
/**
|
||||
* 横屏书架布局模式: 0:列表, 1:网格
|
||||
*/
|
||||
var bookshelfLayoutModeLandscape by prefDelegate(PreferKey.bookshelfLayoutModeLandscape, 1)
|
||||
private val _bookshelfLayoutModeLandscape = prefStateDelegate(PreferKey.bookshelfLayoutModeLandscape, 1)
|
||||
var bookshelfLayoutModeLandscape by _bookshelfLayoutModeLandscape
|
||||
val bookshelfLayoutModeLandscapeState: State<Int> get() = _bookshelfLayoutModeLandscape.state
|
||||
|
||||
/**
|
||||
* 横屏书架网格列数
|
||||
*/
|
||||
var bookshelfLayoutGridLandscape by prefDelegate(PreferKey.bookshelfLayoutGridLandscape, 7)
|
||||
private val _bookshelfLayoutGridLandscape = prefStateDelegate(PreferKey.bookshelfLayoutGridLandscape, 7)
|
||||
var bookshelfLayoutGridLandscape by _bookshelfLayoutGridLandscape
|
||||
val bookshelfLayoutGridLandscapeState: State<Int> get() = _bookshelfLayoutGridLandscape.state
|
||||
|
||||
/**
|
||||
* 竖屏书架列表列数
|
||||
*/
|
||||
var bookshelfLayoutListPortrait by prefDelegate(PreferKey.bookshelfLayoutListPortrait, 1)
|
||||
private val _bookshelfLayoutListPortrait = prefStateDelegate(PreferKey.bookshelfLayoutListPortrait, 1)
|
||||
var bookshelfLayoutListPortrait by _bookshelfLayoutListPortrait
|
||||
val bookshelfLayoutListPortraitState: State<Int> get() = _bookshelfLayoutListPortrait.state
|
||||
|
||||
/**
|
||||
* 横屏书架列表列数
|
||||
*/
|
||||
var bookshelfLayoutListLandscape by prefDelegate(PreferKey.bookshelfLayoutListLandscape, 1)
|
||||
private val _bookshelfLayoutListLandscape = prefStateDelegate(PreferKey.bookshelfLayoutListLandscape, 1)
|
||||
var bookshelfLayoutListLandscape by _bookshelfLayoutListLandscape
|
||||
val bookshelfLayoutListLandscapeState: State<Int> get() = _bookshelfLayoutListLandscape.state
|
||||
|
||||
/**
|
||||
* 文件夹竖屏布局模式: 0:列表, 1:网格
|
||||
*/
|
||||
var bookshelfFolderLayoutModePortrait by prefDelegate(PreferKey.bookshelfFolderLayoutModePortrait, 1)
|
||||
private val _bookshelfFolderLayoutModePortrait = prefStateDelegate(PreferKey.bookshelfFolderLayoutModePortrait, 1)
|
||||
var bookshelfFolderLayoutModePortrait by _bookshelfFolderLayoutModePortrait
|
||||
val bookshelfFolderLayoutModePortraitState: State<Int> get() = _bookshelfFolderLayoutModePortrait.state
|
||||
|
||||
/**
|
||||
* 文件夹竖屏网格列数
|
||||
*/
|
||||
var bookshelfFolderLayoutGridPortrait by prefDelegate(PreferKey.bookshelfFolderLayoutGridPortrait, 3)
|
||||
private val _bookshelfFolderLayoutGridPortrait = prefStateDelegate(PreferKey.bookshelfFolderLayoutGridPortrait, 3)
|
||||
var bookshelfFolderLayoutGridPortrait by _bookshelfFolderLayoutGridPortrait
|
||||
val bookshelfFolderLayoutGridPortraitState: State<Int> get() = _bookshelfFolderLayoutGridPortrait.state
|
||||
|
||||
/**
|
||||
* 文件夹横屏布局模式: 0:列表, 1:网格
|
||||
*/
|
||||
var bookshelfFolderLayoutModeLandscape by prefDelegate(PreferKey.bookshelfFolderLayoutModeLandscape, 1)
|
||||
private val _bookshelfFolderLayoutModeLandscape = prefStateDelegate(PreferKey.bookshelfFolderLayoutModeLandscape, 1)
|
||||
var bookshelfFolderLayoutModeLandscape by _bookshelfFolderLayoutModeLandscape
|
||||
val bookshelfFolderLayoutModeLandscapeState: State<Int> get() = _bookshelfFolderLayoutModeLandscape.state
|
||||
|
||||
/**
|
||||
* 文件夹横屏网格列数
|
||||
*/
|
||||
var bookshelfFolderLayoutGridLandscape by prefDelegate(PreferKey.bookshelfFolderLayoutGridLandscape, 7)
|
||||
private val _bookshelfFolderLayoutGridLandscape = prefStateDelegate(PreferKey.bookshelfFolderLayoutGridLandscape, 7)
|
||||
var bookshelfFolderLayoutGridLandscape by _bookshelfFolderLayoutGridLandscape
|
||||
val bookshelfFolderLayoutGridLandscapeState: State<Int> get() = _bookshelfFolderLayoutGridLandscape.state
|
||||
|
||||
/**
|
||||
* 文件夹竖屏列表列数
|
||||
*/
|
||||
var bookshelfFolderLayoutListPortrait by prefDelegate(PreferKey.bookshelfFolderLayoutListPortrait, 1)
|
||||
private val _bookshelfFolderLayoutListPortrait = prefStateDelegate(PreferKey.bookshelfFolderLayoutListPortrait, 1)
|
||||
var bookshelfFolderLayoutListPortrait by _bookshelfFolderLayoutListPortrait
|
||||
val bookshelfFolderLayoutListPortraitState: State<Int> get() = _bookshelfFolderLayoutListPortrait.state
|
||||
|
||||
/**
|
||||
* 文件夹横屏列表列数
|
||||
*/
|
||||
var bookshelfFolderLayoutListLandscape by prefDelegate(PreferKey.bookshelfFolderLayoutListLandscape, 1)
|
||||
private val _bookshelfFolderLayoutListLandscape = prefStateDelegate(PreferKey.bookshelfFolderLayoutListLandscape, 1)
|
||||
var bookshelfFolderLayoutListLandscape by _bookshelfFolderLayoutListLandscape
|
||||
val bookshelfFolderLayoutListLandscapeState: State<Int> get() = _bookshelfFolderLayoutListLandscape.state
|
||||
|
||||
/**
|
||||
* 网格模式布局样式: 0:标准, 1:紧凑, 2:仅封面
|
||||
*/
|
||||
var bookshelfGridLayout by prefDelegate(PreferKey.bookshelfGridLayout, 0)
|
||||
private val _bookshelfGridLayout = prefStateDelegate(PreferKey.bookshelfGridLayout, 0)
|
||||
var bookshelfGridLayout by _bookshelfGridLayout
|
||||
val bookshelfGridLayoutState: State<Int> get() = _bookshelfGridLayout.state
|
||||
|
||||
/**
|
||||
* 紧凑模式
|
||||
*/
|
||||
var bookshelfLayoutCompact by prefDelegate(PreferKey.bookshelfLayoutCompact, false)
|
||||
private val _bookshelfLayoutCompact = prefStateDelegate(PreferKey.bookshelfLayoutCompact, false)
|
||||
var bookshelfLayoutCompact by _bookshelfLayoutCompact
|
||||
val bookshelfLayoutCompactState: State<Boolean> get() = _bookshelfLayoutCompact.state
|
||||
|
||||
/**
|
||||
* 是否显示书架分隔线
|
||||
*/
|
||||
var bookshelfShowDivider by prefDelegate(PreferKey.bookshelfShowDivider, true)
|
||||
private val _bookshelfShowDivider = prefStateDelegate(PreferKey.bookshelfShowDivider, true)
|
||||
var bookshelfShowDivider by _bookshelfShowDivider
|
||||
val bookshelfShowDividerState: State<Boolean> get() = _bookshelfShowDivider.state
|
||||
|
||||
/**
|
||||
* 书架标题小字体
|
||||
*/
|
||||
var bookshelfTitleSmallFont by prefDelegate(PreferKey.bookshelfTitleSmallFont, false)
|
||||
private val _bookshelfTitleSmallFont = prefStateDelegate(PreferKey.bookshelfTitleSmallFont, false)
|
||||
var bookshelfTitleSmallFont by _bookshelfTitleSmallFont
|
||||
val bookshelfTitleSmallFontState: State<Boolean> get() = _bookshelfTitleSmallFont.state
|
||||
|
||||
/**
|
||||
* 书架标题居中
|
||||
*/
|
||||
var bookshelfTitleCenter by prefDelegate(PreferKey.bookshelfTitleCenter, true)
|
||||
private val _bookshelfTitleCenter = prefStateDelegate(PreferKey.bookshelfTitleCenter, true)
|
||||
var bookshelfTitleCenter by _bookshelfTitleCenter
|
||||
val bookshelfTitleCenterState: State<Boolean> get() = _bookshelfTitleCenter.state
|
||||
|
||||
/**
|
||||
* 书架标题最大行数
|
||||
*/
|
||||
var bookshelfTitleMaxLines by prefDelegate(PreferKey.bookshelfTitleMaxLines, 2)
|
||||
private val _bookshelfTitleMaxLines = prefStateDelegate(PreferKey.bookshelfTitleMaxLines, 2)
|
||||
var bookshelfTitleMaxLines by _bookshelfTitleMaxLines
|
||||
val bookshelfTitleMaxLinesState: State<Int> get() = _bookshelfTitleMaxLines.state
|
||||
|
||||
/**
|
||||
* 书架封面阴影
|
||||
*/
|
||||
var bookshelfCoverShadow by prefDelegate(PreferKey.bookshelfCoverShadow, false)
|
||||
private val _bookshelfCoverShadow = prefStateDelegate(PreferKey.bookshelfCoverShadow, false)
|
||||
var bookshelfCoverShadow by _bookshelfCoverShadow
|
||||
val bookshelfCoverShadowState: State<Boolean> get() = _bookshelfCoverShadow.state
|
||||
|
||||
/**
|
||||
* 书架卡片背景颜色
|
||||
*/
|
||||
var bookshelfCardColor by prefDelegate(PreferKey.bookshelfCardColor, 0) {
|
||||
private val _bookshelfCardColor = prefStateDelegate(PreferKey.bookshelfCardColor, 0) {
|
||||
postEvent(EventBus.NOTIFY_MAIN, false)
|
||||
}
|
||||
var bookshelfCardColor by _bookshelfCardColor
|
||||
val bookshelfCardColorState: State<Int> get() = _bookshelfCardColor.state
|
||||
|
||||
/**
|
||||
* 文件夹在列表模式下的样式: 0: 默认, 2: 横排封面
|
||||
*/
|
||||
var bookshelfGroupListStyle by prefDelegate(PreferKey.bookshelfGroupListStyle, 0)
|
||||
private val _bookshelfGroupListStyle = prefStateDelegate(PreferKey.bookshelfGroupListStyle, 0)
|
||||
var bookshelfGroupListStyle by _bookshelfGroupListStyle
|
||||
val bookshelfGroupListStyleState: State<Int> get() = _bookshelfGroupListStyle.state
|
||||
|
||||
/**
|
||||
* 文件夹在列表模式下横排封面的数量
|
||||
*/
|
||||
var bookshelfGroupCoverCount by prefDelegate(PreferKey.bookshelfGroupCoverCount, 4)
|
||||
private val _bookshelfGroupCoverCount = prefStateDelegate(PreferKey.bookshelfGroupCoverCount, 4)
|
||||
var bookshelfGroupCoverCount by _bookshelfGroupCoverCount
|
||||
val bookshelfGroupCoverCountState: State<Int> get() = _bookshelfGroupCoverCount.state
|
||||
|
||||
/**
|
||||
* 书架搜索按钮是否直接跳转搜索页
|
||||
*/
|
||||
var bookshelfSearchActionDirectToSearch by prefDelegate(
|
||||
private val _bookshelfSearchActionDirectToSearch = prefStateDelegate(
|
||||
PreferKey.bookshelfSearchActionDirectToSearch,
|
||||
true
|
||||
)
|
||||
var bookshelfSearchActionDirectToSearch by _bookshelfSearchActionDirectToSearch
|
||||
val bookshelfSearchActionDirectToSearchState: State<Boolean> get() = _bookshelfSearchActionDirectToSearch.state
|
||||
|
||||
/**
|
||||
* 启动时自动刷新书架
|
||||
*/
|
||||
var autoRefreshBook by prefDelegate(PreferKey.autoRefresh, false)
|
||||
private val _autoRefreshBook = prefStateDelegate(PreferKey.autoRefresh, false)
|
||||
var autoRefreshBook by _autoRefreshBook
|
||||
val autoRefreshBookState: State<Boolean> get() = _autoRefreshBook.state
|
||||
|
||||
/**
|
||||
* 保存上次停留的分组Id
|
||||
*/
|
||||
var saveTabPosition by prefDelegate(PreferKey.saveTabPosition, BookGroup.IdAll)
|
||||
private val _saveTabPosition = prefStateDelegate(PreferKey.saveTabPosition, BookGroup.IdAll)
|
||||
var saveTabPosition by _saveTabPosition
|
||||
val saveTabPositionState: State<Long> get() = _saveTabPosition.state
|
||||
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.testTagsAsResourceId
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -241,7 +244,9 @@ fun MainScreen(
|
||||
val haptic = LocalHapticFeedback.current
|
||||
|
||||
WideNavigationRailItem(
|
||||
modifier = Modifier.testTag("nav_${destination.route}"),
|
||||
modifier = Modifier.semantics(mergeDescendants = true) {
|
||||
contentDescription = "nav_${destination.route}"
|
||||
},
|
||||
railExpanded = navState.targetValue == WideNavigationRailValue.Expanded,
|
||||
selected = selected,
|
||||
onClick = {
|
||||
@@ -310,7 +315,9 @@ fun MainScreen(
|
||||
MainDestination.My -> ThemeConfig.navIconMy
|
||||
}
|
||||
AppNavigationBarItem(
|
||||
modifier = Modifier.testTag("nav_${destination.route}"),
|
||||
modifier = Modifier.semantics(mergeDescendants = true) {
|
||||
contentDescription = "nav_${destination.route}"
|
||||
},
|
||||
selected = selected,
|
||||
onClick = {
|
||||
coroutineScope.launch { pagerState.animateScrollToPage(index) }
|
||||
@@ -457,7 +464,11 @@ fun MainScreen(
|
||||
pagerState.animateScrollToPage(index)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.defaultMinSize(minWidth = 76.dp)
|
||||
modifier = Modifier
|
||||
.defaultMinSize(minWidth = 76.dp)
|
||||
.semantics(mergeDescendants = true) {
|
||||
contentDescription = "nav_${destination.route}"
|
||||
}
|
||||
) {
|
||||
NavigationIcon(
|
||||
destination = destination,
|
||||
|
||||
@@ -83,7 +83,11 @@ import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@@ -123,6 +127,9 @@ 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.tabRow.AppTabRow
|
||||
import io.legado.app.ui.widget.components.text.AppText
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
@@ -321,32 +328,38 @@ fun BookshelfScreen(
|
||||
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
val bookshelfLayoutMode by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscape else BookshelfConfig.bookshelfLayoutModePortrait
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscapeState.value
|
||||
else BookshelfConfig.bookshelfLayoutModePortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfLayoutGrid by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutGridLandscape else BookshelfConfig.bookshelfLayoutGridPortrait
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutGridLandscapeState.value
|
||||
else BookshelfConfig.bookshelfLayoutGridPortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfLayoutList by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscape else BookshelfConfig.bookshelfLayoutListPortrait
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscapeState.value
|
||||
else BookshelfConfig.bookshelfLayoutListPortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfFolderLayoutMode by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutModeLandscape else BookshelfConfig.bookshelfFolderLayoutModePortrait
|
||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutModeLandscapeState.value
|
||||
else BookshelfConfig.bookshelfFolderLayoutModePortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfFolderLayoutGrid by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutGridLandscape else BookshelfConfig.bookshelfFolderLayoutGridPortrait
|
||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutGridLandscapeState.value
|
||||
else BookshelfConfig.bookshelfFolderLayoutGridPortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfFolderLayoutList by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutListLandscape else BookshelfConfig.bookshelfFolderLayoutListPortrait
|
||||
if (isLandscape) BookshelfConfig.bookshelfFolderLayoutListLandscapeState.value
|
||||
else BookshelfConfig.bookshelfFolderLayoutListPortraitState.value
|
||||
}
|
||||
}
|
||||
val currentMenuGroupId by remember {
|
||||
@@ -388,7 +401,7 @@ fun BookshelfScreen(
|
||||
backNavigationIcon = AppIcons.Close,
|
||||
showSearchAction = true,
|
||||
onSearchToggle = { active ->
|
||||
if (BookshelfConfig.bookshelfSearchActionDirectToSearch) {
|
||||
if (BookshelfConfig.bookshelfSearchActionDirectToSearchState.value) {
|
||||
onNavigateToSearch(uiState.searchKey.trim())
|
||||
} else {
|
||||
viewModel.setSearchMode(active)
|
||||
@@ -561,7 +574,8 @@ fun BookshelfScreen(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
if (BookshelfConfig.shouldShowExpandButton) {
|
||||
val showExpandButton by BookshelfConfig.shouldShowExpandButtonState
|
||||
if (showExpandButton) {
|
||||
Box(modifier = Modifier) {
|
||||
SmallOutlinedIconToggleButton(
|
||||
checked = showGroupMenu,
|
||||
@@ -716,12 +730,12 @@ fun BookshelfScreen(
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
||||
showFastScroll = BookshelfConfig.showBookshelfFastScroller
|
||||
showFastScroll = BookshelfConfig.showBookshelfFastScrollerState.value
|
||||
) {
|
||||
itemsIndexed(
|
||||
uiState.groups,
|
||||
key = { _, it -> it.groupId }) { index, group ->
|
||||
val countText = if (BookshelfConfig.showBookCount) {
|
||||
val countText = if (BookshelfConfig.showBookCountState.value) {
|
||||
uiState.groupBookCounts[group.groupId]?.let {
|
||||
stringResource(R.string.book_count, it)
|
||||
}
|
||||
@@ -734,11 +748,11 @@ fun BookshelfScreen(
|
||||
previewBooks = uiState.groupPreviews[group.groupId]
|
||||
?: emptyList(),
|
||||
countText = countText,
|
||||
isCompact = BookshelfConfig.bookshelfLayoutCompact,
|
||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
||||
titleCenter = BookshelfConfig.bookshelfTitleCenter,
|
||||
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLines,
|
||||
coverShadow = BookshelfConfig.bookshelfCoverShadow,
|
||||
isCompact = BookshelfConfig.bookshelfLayoutCompactState.value,
|
||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFontState.value,
|
||||
titleCenter = BookshelfConfig.bookshelfTitleCenterState.value,
|
||||
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLinesState.value,
|
||||
coverShadow = BookshelfConfig.bookshelfCoverShadowState.value,
|
||||
onClick = {
|
||||
scope.launch { pagerState.scrollToPage(index) }
|
||||
viewModel.setInFolderRoot(false)
|
||||
@@ -754,11 +768,11 @@ fun BookshelfScreen(
|
||||
previewBooks = uiState.groupPreviews[group.groupId]
|
||||
?: emptyList(),
|
||||
countText = countText,
|
||||
gridStyle = BookshelfConfig.bookshelfGridLayout,
|
||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
||||
titleCenter = BookshelfConfig.bookshelfTitleCenter,
|
||||
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLines,
|
||||
coverShadow = BookshelfConfig.bookshelfCoverShadow,
|
||||
gridStyle = BookshelfConfig.bookshelfGridLayoutState.value,
|
||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFontState.value,
|
||||
titleCenter = BookshelfConfig.bookshelfTitleCenterState.value,
|
||||
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLinesState.value,
|
||||
coverShadow = BookshelfConfig.bookshelfCoverShadowState.value,
|
||||
onClick = {
|
||||
scope.launch { pagerState.scrollToPage(index) }
|
||||
viewModel.setInFolderRoot(false)
|
||||
@@ -810,7 +824,7 @@ fun BookshelfScreen(
|
||||
val isSelectedGroup = group.groupId == uiState.selectedGroupId
|
||||
val books = uiState.allGroupBooks[group.groupId]
|
||||
?: if (isSelectedGroup) uiState.items
|
||||
else emptyList()
|
||||
else persistentListOf()
|
||||
val canReorderBooks = isEditMode &&
|
||||
!uiState.isSearch &&
|
||||
(group.bookSort.takeIf { it >= 0 }
|
||||
@@ -1155,17 +1169,17 @@ private data class BookshelfEditStickySummary(
|
||||
@Composable
|
||||
fun BookshelfPage(
|
||||
paddingValues: PaddingValues,
|
||||
books: List<BookShelfItem>,
|
||||
books: ImmutableList<BookShelfItem>,
|
||||
uiState: BookshelfUiState,
|
||||
selectedBookUrls: Set<String>,
|
||||
selectedBookUrls: ImmutableSet<String>,
|
||||
canReorderBooks: Boolean,
|
||||
onToggleBookSelection: (BookShelfItem) -> Unit,
|
||||
draggingBooks: List<BookShelfItem>?,
|
||||
pendingSavedBooks: List<BookShelfItem>?,
|
||||
onDragStarted: (List<BookShelfItem>) -> Unit,
|
||||
onMoveBook: (fromIndex: Int, toIndex: Int, currentBooks: List<BookShelfItem>) -> Unit,
|
||||
draggingBooks: ImmutableList<BookShelfItem>?,
|
||||
pendingSavedBooks: ImmutableList<BookShelfItem>?,
|
||||
onDragStarted: (ImmutableList<BookShelfItem>) -> Unit,
|
||||
onMoveBook: (fromIndex: Int, toIndex: Int, currentBooks: ImmutableList<BookShelfItem>) -> Unit,
|
||||
onDragFinished: () -> Unit,
|
||||
onSyncDragState: (books: List<BookShelfItem>, canReorderBooks: Boolean) -> Unit,
|
||||
onSyncDragState: (books: ImmutableList<BookShelfItem>, canReorderBooks: Boolean) -> Unit,
|
||||
onGlobalSearch: () -> Unit,
|
||||
onBookClick: (BookShelfItem) -> Unit,
|
||||
onBookLongClick: (BookShelfItem) -> Unit,
|
||||
@@ -1203,14 +1217,37 @@ fun BookshelfPage(
|
||||
|
||||
val configuration = LocalConfiguration.current
|
||||
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
val bookshelfLayoutMode =
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscape else BookshelfConfig.bookshelfLayoutModePortrait
|
||||
val bookshelfLayoutGrid =
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutGridLandscape else BookshelfConfig.bookshelfLayoutGridPortrait
|
||||
val bookshelfLayoutList =
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscape else BookshelfConfig.bookshelfLayoutListPortrait
|
||||
val columns = if (bookshelfLayoutMode == 0) bookshelfLayoutList else bookshelfLayoutGrid
|
||||
val isGridMode = bookshelfLayoutMode != 0
|
||||
val bookshelfLayoutMode by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscapeState.value
|
||||
else BookshelfConfig.bookshelfLayoutModePortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfLayoutGrid by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutGridLandscapeState.value
|
||||
else BookshelfConfig.bookshelfLayoutGridPortraitState.value
|
||||
}
|
||||
}
|
||||
val bookshelfLayoutList by remember {
|
||||
derivedStateOf {
|
||||
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscapeState.value
|
||||
else BookshelfConfig.bookshelfLayoutListPortraitState.value
|
||||
}
|
||||
}
|
||||
val columns by remember {
|
||||
derivedStateOf {
|
||||
if (bookshelfLayoutMode == 0) bookshelfLayoutList else bookshelfLayoutGrid
|
||||
}
|
||||
}
|
||||
val isGridMode by remember { derivedStateOf { bookshelfLayoutMode != 0 } }
|
||||
val bookItemGridStyle by BookshelfConfig.bookshelfGridLayoutState
|
||||
val bookItemIsCompact by BookshelfConfig.bookshelfLayoutCompactState
|
||||
val bookItemTitleSmallFont by BookshelfConfig.bookshelfTitleSmallFontState
|
||||
val bookItemTitleCenter by BookshelfConfig.bookshelfTitleCenterState
|
||||
val bookItemTitleMaxLines by BookshelfConfig.bookshelfTitleMaxLinesState
|
||||
val bookItemCoverShadow by BookshelfConfig.bookshelfCoverShadowState
|
||||
val showFastScroll by BookshelfConfig.showBookshelfFastScrollerState
|
||||
val totalHorizontalPadding =
|
||||
if (ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)) 12.dp else 16.dp
|
||||
val gridContentHorizontalPadding = totalHorizontalPadding / 2
|
||||
@@ -1247,7 +1284,7 @@ fun BookshelfPage(
|
||||
state = gridState,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.testTag("bookshelf_list")
|
||||
.semantics(mergeDescendants = true) { contentDescription = "bookshelf_list" }
|
||||
.then(
|
||||
with(sharedTransitionScope) {
|
||||
if (this != null) Modifier.skipToLookaheadSize() else Modifier
|
||||
@@ -1260,7 +1297,7 @@ fun BookshelfPage(
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(if (isGridMode) 8.dp else 0.dp),
|
||||
showFastScroll = BookshelfConfig.showBookshelfFastScroller
|
||||
showFastScroll = showFastScroll
|
||||
) {
|
||||
items(displayBooks, key = { it.bookUrl }) { book ->
|
||||
val isSelected = selectedBookUrls.contains(book.bookUrl)
|
||||
@@ -1292,13 +1329,13 @@ fun BookshelfPage(
|
||||
),
|
||||
layoutMode = bookshelfLayoutMode,
|
||||
isSelected = isSelected,
|
||||
gridStyle = BookshelfConfig.bookshelfGridLayout,
|
||||
isCompact = BookshelfConfig.bookshelfLayoutCompact,
|
||||
gridStyle = bookItemGridStyle,
|
||||
isCompact = bookItemIsCompact,
|
||||
isUpdating = uiState.updatingBooks.contains(book.bookUrl),
|
||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
||||
titleCenter = BookshelfConfig.bookshelfTitleCenter,
|
||||
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLines,
|
||||
coverShadow = BookshelfConfig.bookshelfCoverShadow,
|
||||
titleSmallFont = bookItemTitleSmallFont,
|
||||
titleCenter = bookItemTitleCenter,
|
||||
titleMaxLines = bookItemTitleMaxLines,
|
||||
coverShadow = bookItemCoverShadow,
|
||||
isSearchMode = uiState.isSearch,
|
||||
searchKey = uiState.searchKey,
|
||||
sharedTransitionScope = sharedTransitionScope,
|
||||
|
||||
@@ -21,7 +21,8 @@ android {
|
||||
targetSdk = 37
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE"
|
||||
}
|
||||
|
||||
targetProjectPath = ":app"
|
||||
|
||||
|
||||
+27
-22
@@ -30,36 +30,41 @@ class BaselineProfileGenerator {
|
||||
packageName = packageName,
|
||||
includeInStartupProfile = true
|
||||
) {
|
||||
// 1. 启动应用
|
||||
pressHome()
|
||||
startActivityAndWait()
|
||||
|
||||
// 2. 等待书架加载 (我们在 BookshelfScreen 中添加了 ReportDrawnWhen)
|
||||
// 等待书架列表 testTag 出现
|
||||
device.wait(Until.hasObject(By.res(packageName, "bookshelf_list")), 10000)
|
||||
val bookshelfSelector = By.desc("bookshelf_list")
|
||||
device.wait(Until.hasObject(bookshelfSelector), 10000)
|
||||
|
||||
// 3. 模拟滑动书架 (优化列表渲染性能)
|
||||
val bookshelf = device.findObject(By.res(packageName, "bookshelf_list"))
|
||||
bookshelf?.apply {
|
||||
setGestureMargin(device.displayWidth / 10)
|
||||
fling(Direction.DOWN)
|
||||
device.waitForIdle()
|
||||
fling(Direction.UP)
|
||||
device.waitForIdle()
|
||||
device.waitForIdle()
|
||||
Thread.sleep(2000)
|
||||
|
||||
val screenWidth = device.displayWidth
|
||||
val screenHeight = device.displayHeight
|
||||
val startX = screenWidth / 2
|
||||
val startY = (screenHeight * 0.75).toInt()
|
||||
val endY = (screenHeight * 0.25).toInt()
|
||||
|
||||
repeat(3) {
|
||||
device.swipe(startX, startY, startX, endY, 25)
|
||||
Thread.sleep(1000)
|
||||
}
|
||||
|
||||
// 4. 遍历主要 Tab (优化 Compose 导航和各页面初始化)
|
||||
val tabs = listOf("nav_explore", "nav_rss", "nav_my", "nav_bookshelf")
|
||||
for (tabTag in tabs) {
|
||||
val tab = device.findObject(By.res(packageName, tabTag))
|
||||
repeat(2) {
|
||||
device.swipe(startX, endY, startX, startY, 10)
|
||||
Thread.sleep(1000)
|
||||
}
|
||||
|
||||
// "nav_my"
|
||||
/* val tabs = listOf("nav_explore", "nav_rss", "nav_bookshelf")
|
||||
for (tabDesc in tabs) {
|
||||
val tab = device.wait(Until.findObject(By.desc(tabDesc)), 5000)
|
||||
if (tab != null) {
|
||||
tab.click()
|
||||
device.waitForIdle()
|
||||
// 稍微等待页面加载
|
||||
Thread.sleep(500)
|
||||
val bounds = tab.visibleBounds
|
||||
device.click(bounds.centerX(), bounds.centerY())
|
||||
Thread.sleep(3000)
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,21 +44,19 @@ class StartupBenchmarks {
|
||||
val rule = MacrobenchmarkRule()
|
||||
|
||||
@Test
|
||||
fun startupCompilationNone() =
|
||||
benchmark(CompilationMode.None())
|
||||
fun startupCompilationNone() = benchmark(CompilationMode.None())
|
||||
|
||||
@Test
|
||||
fun startupCompilationBaselineProfiles() =
|
||||
benchmark(CompilationMode.Partial(BaselineProfileMode.Require))
|
||||
|
||||
private fun benchmark(compilationMode: CompilationMode) {
|
||||
// The application id for the running build variant is read from the instrumentation arguments.
|
||||
val packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
|
||||
?: "io.legado.app"
|
||||
|
||||
rule.measureRepeated(
|
||||
packageName = packageName,
|
||||
metrics = listOf(StartupTimingMetric(), FrameTimingMetric()),
|
||||
metrics = listOf(StartupTimingMetric()),
|
||||
compilationMode = compilationMode,
|
||||
startupMode = StartupMode.COLD,
|
||||
iterations = 3,
|
||||
@@ -67,18 +65,6 @@ class StartupBenchmarks {
|
||||
},
|
||||
measureBlock = {
|
||||
startActivityAndWait()
|
||||
|
||||
// 等待书架列表加载完成
|
||||
// 我们在 BookshelfScreen 中添加了 testTag("bookshelf_list")
|
||||
device.wait(Until.hasObject(By.res(packageName, "bookshelf_list")), 10000)
|
||||
|
||||
// 模拟交互:在书架上进行滑动,以确保 Profile 捕获到列表渲染和图片加载的路径
|
||||
val bookshelfList = device.findObject(By.res(packageName, "bookshelf_list"))
|
||||
bookshelfList?.apply {
|
||||
setGestureMargin(device.displayWidth / 10)
|
||||
fling(Direction.DOWN)
|
||||
device.waitForIdle()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@ adaptive = "1.3.0-beta01"
|
||||
adaptiveLayout = "1.3.0-beta01"
|
||||
adaptiveNavigation = "1.3.0-beta01"
|
||||
animation = "1.11.1"
|
||||
biometric = "1.4.0-alpha06"
|
||||
biometric = "1.4.0-alpha07"
|
||||
coilCompose = "2.7.0"
|
||||
composeBom = "2026.05.00"
|
||||
constraintlayoutCompose = "1.1.1"
|
||||
coreSplashscreen = "1.2.0"
|
||||
datastorePreferences = "1.2.1"
|
||||
foundation = "1.11.1"
|
||||
kotlin = "2.3.10"
|
||||
kotlin = "2.3.21"
|
||||
kotlinxSerialization = "1.11.0"
|
||||
kotlinxCoroutinesAndroid = "1.10.2"
|
||||
kotlinxSerializationJson = "1.11.0"
|
||||
@@ -35,8 +35,8 @@ hutool = "5.8.22"
|
||||
libarchive = "1.1.6"
|
||||
lifecycle = "2.10.0"
|
||||
glide = "5.0.7"
|
||||
gson = "2.13.2"
|
||||
jsonPath = "2.10.0"
|
||||
gson = "2.14.0"
|
||||
jsonPath = "3.0.0"
|
||||
# issue #3811,不要更新版本,新版引入了一个破坏性变更(详见https://github.com/jhy/jsoup/pull/2017)
|
||||
# 若要升级请确保相关代码不会受此变更影响(如AnalyzeByJSoup.kt、JsoupXpath库等)
|
||||
jsoup = "1.16.2"
|
||||
@@ -51,7 +51,7 @@ material = "1.14.0-rc01"
|
||||
material3 = "1.5.0-alpha19"
|
||||
material3IconsExtended = "1.7.8"
|
||||
materialKolor = "4.1.1"
|
||||
media = "1.7.1"
|
||||
media = "1.8.0"
|
||||
media3 = "1.8.0"
|
||||
nanoHttpd = "2.3.1"
|
||||
navigationCompose = "2.9.8"
|
||||
@@ -62,7 +62,7 @@ protobufJavalite = "4.26.1"
|
||||
quickChineseTransfer = "0.2.16"
|
||||
room = "2.8.4"
|
||||
splitties = "3.0.0"
|
||||
rhino = "1.8.1"
|
||||
rhino = "1.9.1"
|
||||
desugar = "2.1.5"
|
||||
|
||||
activity = "1.13.0"
|
||||
@@ -77,7 +77,7 @@ viewpager2 = "1.1.0"
|
||||
webkit = "1.16.0"
|
||||
collection = "1.6.0"
|
||||
|
||||
zxingLite = "3.3.0"
|
||||
zxingLite = "3.4.1"
|
||||
|
||||
koin-bom = "4.2.1"
|
||||
biometricKtx = "1.1.0"
|
||||
|
||||
@@ -2,9 +2,10 @@ package com.script.rhino
|
||||
|
||||
import org.mozilla.javascript.NativeJavaObject
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.lc.type.TypeInfoFactory
|
||||
|
||||
class ReadOnlyJavaObject(scope: Scriptable?, javaObject: Any, staticType: Class<*>?) :
|
||||
NativeJavaObject(scope, javaObject, staticType) {
|
||||
NativeJavaObject(scope, javaObject, staticType?.let { TypeInfoFactory.GLOBAL.create(it) }) {
|
||||
|
||||
override fun has(name: String, start: Scriptable): Boolean {
|
||||
if (name.length > 3 && name.startsWith("set")) {
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
package com.script.rhino
|
||||
|
||||
import org.mozilla.javascript.VMBridge
|
||||
import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.ContextFactory
|
||||
|
||||
object VMBridgeReflect {
|
||||
|
||||
val instance: VMBridge by lazy {
|
||||
VMBridge::class.java.getDeclaredField("instance").apply {
|
||||
isAccessible = true
|
||||
}.get(null) as VMBridge
|
||||
}
|
||||
|
||||
val contextLocal: ThreadLocal<Any> by lazy {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
instance::class.java.getDeclaredField("contextLocal").apply {
|
||||
isAccessible = true
|
||||
}.get(null) as ThreadLocal<Any>
|
||||
try {
|
||||
// Rhino 1.9.1+ uses threadContextLocal directly in Context class
|
||||
val field = Context::class.java.getDeclaredField("threadContextLocal")
|
||||
field.isAccessible = true
|
||||
field.get(null) as ThreadLocal<Any>
|
||||
} catch (e: Exception) {
|
||||
try {
|
||||
// Fallback for some versions or custom builds
|
||||
val factory = ContextFactory.getGlobal()
|
||||
val field = ContextFactory::class.java.getDeclaredField("localContext")
|
||||
field.isAccessible = true
|
||||
field.get(factory) as ThreadLocal<Any>
|
||||
} catch (e2: Exception) {
|
||||
// Older versions used threadContextHelper (Object) which held a ThreadLocal
|
||||
val field = Context::class.java.getDeclaredField("threadContextHelper")
|
||||
field.isAccessible = true
|
||||
field.get(null) as ThreadLocal<Any>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,3 +54,4 @@ include ':app'
|
||||
include ':modules:book'
|
||||
include ':modules:rhino'
|
||||
include ':baselineprofile'
|
||||
project(':baselineprofile').projectDir = file('baselineProfile')
|
||||
|
||||
Reference in New Issue
Block a user