Add option to disable list item animations (#997)
It may crash on some devices.
This commit is contained in:
1 parent
84c32fb28d
commit
7a5bab41f6
12 files changed
+62
-10
No files matched your search
@@ -116,6 +116,7 @@ object Settings : DataStorePreferences(null) {
|
||||
val showGalleryPages = boolPref("show_gallery_pages", true)
|
||||
val qSSaveProgress = boolPref("qs_save_progress", true)
|
||||
val security = boolPref("require_unlock", false)
|
||||
val animateItems = boolPref("animate_items", true)
|
||||
val recentDownloadLabel = stringOrNullPref("recent_download_label", null)
|
||||
|
||||
var downloadScheme by stringOrNullPref("image_scheme", null)
|
||||
|
||||
@@ -40,7 +40,9 @@ import com.hippo.ehviewer.asMutableState
|
||||
import com.hippo.ehviewer.client.EhTagDatabase
|
||||
import com.hippo.ehviewer.client.EhUtils
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.collectAsState
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.hippo.ehviewer.util.toIntOrDefault
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -68,6 +70,7 @@ fun SearchFilter(
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val dialogState = LocalDialogState.current
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
fun isCategoryChecked(bit: Int) = category and bit != 0
|
||||
val categories = remember(category) { categoryTable.sortedBy { !isCategoryChecked(it.first) } }
|
||||
LazyRow(
|
||||
@@ -82,7 +85,7 @@ fun SearchFilter(
|
||||
selected = isCategoryChecked(it.first),
|
||||
onClick = { onCategoryChanged(category xor it.first) },
|
||||
label = { Text(text = stringResource(id = it.second)) },
|
||||
modifier = Modifier.animateItem(),
|
||||
modifier = Modifier.thenIf(animateItems) { animateItem() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ import com.hippo.ehviewer.ui.tools.SwipeToDismissBox2
|
||||
import com.hippo.ehviewer.ui.tools.delegateSnapshotUpdate
|
||||
import com.hippo.ehviewer.ui.tools.draggingHapticFeedback
|
||||
import com.hippo.ehviewer.ui.tools.rememberInVM
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.hippo.ehviewer.util.findActivity
|
||||
import com.hippo.ehviewer.util.mapToLongArray
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
@@ -135,6 +136,7 @@ fun DownloadsScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
var filterState by rememberSaveable { mutableStateOf(DownloadsFilterState(Settings.recentDownloadLabel.value)) }
|
||||
var invalidateKey by rememberSaveable { mutableStateOf(false) }
|
||||
var searchBarOffsetY by remember(filterState.label) { mutableIntStateOf(0) }
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
|
||||
var fabExpanded by remember { mutableStateOf(false) }
|
||||
var fabHidden by remember { mutableStateOf(false) }
|
||||
@@ -481,7 +483,7 @@ fun DownloadsScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
onClick = ::onItemClick.partially1(info),
|
||||
onLongClick = { navigator.navigate(info.galleryInfo.asDst()) },
|
||||
info = info,
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
modifier = Modifier.thenIf(animateItems) { animateItemPlacement() },
|
||||
badgeText = info.pages.takeIf { it > 0 }?.toString(),
|
||||
)
|
||||
}
|
||||
@@ -494,7 +496,10 @@ fun DownloadsScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
) {
|
||||
items(list, key = { it.gid }) { info ->
|
||||
val checked = info.gid in checkedInfoMap
|
||||
CheckableItem(checked = checked, modifier = Modifier.animateItem()) { interactionSource ->
|
||||
CheckableItem(
|
||||
checked = checked,
|
||||
modifier = Modifier.thenIf(animateItems) { animateItem() },
|
||||
) { interactionSource ->
|
||||
DownloadCard(
|
||||
onClick = {
|
||||
if (selectMode) {
|
||||
|
||||
@@ -77,6 +77,7 @@ import com.hippo.ehviewer.ui.startDownload
|
||||
import com.hippo.ehviewer.ui.tools.delegateSnapshotUpdate
|
||||
import com.hippo.ehviewer.ui.tools.foldToLoadResult
|
||||
import com.hippo.ehviewer.ui.tools.rememberInVM
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.hippo.ehviewer.util.displayString
|
||||
import com.hippo.ehviewer.util.mapToLongArray
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
@@ -97,6 +98,7 @@ fun FavouritesScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
// Immutables
|
||||
val localFavName = stringResource(R.string.local_favorites)
|
||||
val cloudFavName = stringResource(R.string.cloud_favorites)
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
|
||||
// Meta State
|
||||
var urlBuilder by rememberSaveable { mutableStateOf(FavListUrlBuilder(favCat = Settings.recentFavCat)) }
|
||||
@@ -266,7 +268,10 @@ fun FavouritesScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
listMode = listMode,
|
||||
detailItemContent = { info ->
|
||||
val checked = info.gid in checkedInfoMap
|
||||
CheckableItem(checked = checked, modifier = Modifier.animateItemPlacement()) { interactionSource ->
|
||||
CheckableItem(
|
||||
checked = checked,
|
||||
modifier = Modifier.thenIf(animateItems) { animateItemPlacement() },
|
||||
) { interactionSource ->
|
||||
GalleryInfoListItem(
|
||||
onClick = {
|
||||
if (selectMode) {
|
||||
@@ -292,7 +297,10 @@ fun FavouritesScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
},
|
||||
thumbItemContent = { info ->
|
||||
val checked = info.gid in checkedInfoMap
|
||||
CheckableItem(checked = checked, modifier = Modifier.animateItemPlacement()) { interactionSource ->
|
||||
CheckableItem(
|
||||
checked = checked,
|
||||
modifier = Modifier.thenIf(animateItems) { animateItemPlacement() },
|
||||
) { interactionSource ->
|
||||
GalleryInfoGridItem(
|
||||
onClick = {
|
||||
if (selectMode) {
|
||||
|
||||
@@ -74,12 +74,14 @@ import androidx.core.text.inSpans
|
||||
import androidx.core.text.parseAsHtml
|
||||
import com.hippo.ehviewer.EhApplication
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.EhCookieStore
|
||||
import com.hippo.ehviewer.client.EhEngine
|
||||
import com.hippo.ehviewer.client.EhFilter.remember
|
||||
import com.hippo.ehviewer.client.EhUrl
|
||||
import com.hippo.ehviewer.client.data.GalleryComment
|
||||
import com.hippo.ehviewer.client.data.ListUrlBuilder
|
||||
import com.hippo.ehviewer.collectAsState
|
||||
import com.hippo.ehviewer.dao.Filter
|
||||
import com.hippo.ehviewer.dao.FilterMode
|
||||
import com.hippo.ehviewer.ui.LockDrawer
|
||||
@@ -92,6 +94,7 @@ import com.hippo.ehviewer.ui.tools.animateFloatMergePredictiveBackAsState
|
||||
import com.hippo.ehviewer.ui.tools.normalizeSpan
|
||||
import com.hippo.ehviewer.ui.tools.rememberBBCodeTextToolbar
|
||||
import com.hippo.ehviewer.ui.tools.snackBarPadding
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.hippo.ehviewer.ui.tools.toBBCode
|
||||
import com.hippo.ehviewer.ui.tools.updateSpan
|
||||
import com.hippo.ehviewer.util.ReadableTime
|
||||
@@ -152,6 +155,7 @@ fun GalleryCommentsScreen(gid: Long, navigator: DestinationsNavigator) = composi
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
||||
var commenting by rememberSaveable { mutableStateOf(false) }
|
||||
val animationProgress by animateFloatMergePredictiveBackAsState(enable = commenting) { commenting = false }
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
|
||||
val galleryDetail = remember { EhApplication.galleryDetailCache[gid]!! }
|
||||
val userCommentBackField = remember { mutableStateOf(TextFieldValue()) }
|
||||
@@ -356,7 +360,7 @@ fun GalleryCommentsScreen(gid: Long, navigator: DestinationsNavigator) = composi
|
||||
}
|
||||
|
||||
GalleryCommentCard(
|
||||
modifier = Modifier.animateItem(),
|
||||
modifier = Modifier.thenIf(animateItems) { animateItem() },
|
||||
comment = item,
|
||||
onUserClick = {
|
||||
navigate(
|
||||
|
||||
@@ -54,6 +54,7 @@ import com.hippo.ehviewer.ui.tools.Deferred
|
||||
import com.hippo.ehviewer.ui.tools.FastScrollLazyColumn
|
||||
import com.hippo.ehviewer.ui.tools.SwipeToDismissBox2
|
||||
import com.hippo.ehviewer.ui.tools.rememberInVM
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.hippo.ehviewer.util.FavouriteStatusRouter
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||
@@ -67,6 +68,7 @@ import kotlinx.coroutines.launch
|
||||
fun HistoryScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
val title = stringResource(id = R.string.history)
|
||||
val hint = stringResource(R.string.search_bar_hint, title)
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
|
||||
var searchBarOffsetY by remember { mutableIntStateOf(0) }
|
||||
var keyword by rememberSaveable { mutableStateOf("") }
|
||||
@@ -142,7 +144,7 @@ fun HistoryScreen(navigator: DestinationsNavigator) = composing(navigator) {
|
||||
SwipeToDismissBox2(
|
||||
state = dismissState,
|
||||
backgroundContent = {},
|
||||
modifier = Modifier.animateItem(),
|
||||
modifier = Modifier.thenIf(animateItems) { animateItem() },
|
||||
) {
|
||||
GalleryInfoListItem(
|
||||
onClick = { navigate(info.asDst()) },
|
||||
|
||||
@@ -66,12 +66,14 @@ import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.EhTagDatabase
|
||||
import com.hippo.ehviewer.client.data.TagNamespace
|
||||
import com.hippo.ehviewer.collectAsState
|
||||
import com.hippo.ehviewer.dao.Search
|
||||
import com.hippo.ehviewer.dao.SearchDao
|
||||
import com.hippo.ehviewer.ui.LocalNavDrawerState
|
||||
import com.hippo.ehviewer.ui.LockDrawer
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.hippo.ehviewer.ui.tools.rememberCompositionActiveState
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.jamal.composeprefs3.ui.ifNotNullThen
|
||||
import com.jamal.composeprefs3.ui.ifTrueThen
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
@@ -121,6 +123,7 @@ fun SearchBarScreen(
|
||||
val scope = rememberCoroutineScope { Dispatchers.IO }
|
||||
val context = LocalContext.current
|
||||
val dialogState = LocalDialogState.current
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
|
||||
class TagSuggestion(
|
||||
override val hint: String?,
|
||||
@@ -329,7 +332,7 @@ fun SearchBarScreen(
|
||||
}
|
||||
},
|
||||
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||
modifier = Modifier.clickable { it.onClick() }.animateItem(),
|
||||
modifier = Modifier.clickable { it.onClick() }.thenIf(animateItems) { animateItem() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.hippo.ehviewer.BuildConfig
|
||||
import com.hippo.ehviewer.EhDB
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.asMutableState
|
||||
import com.hippo.ehviewer.client.CHROME_USER_AGENT
|
||||
import com.hippo.ehviewer.client.EhCookieStore
|
||||
import com.hippo.ehviewer.client.EhEngine
|
||||
@@ -42,6 +43,8 @@ import com.hippo.ehviewer.ui.tools.observed
|
||||
import com.hippo.ehviewer.util.AppConfig
|
||||
import com.hippo.ehviewer.util.Crash
|
||||
import com.hippo.ehviewer.util.ReadableTime
|
||||
import com.hippo.ehviewer.util.isAtLeastQ
|
||||
import com.jamal.composeprefs3.ui.prefs.SwitchPref
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
@@ -142,6 +145,15 @@ fun AdvancedScreen(navigator: DestinationsNavigator) {
|
||||
title = stringResource(id = R.string.preload_thumb_aggressively),
|
||||
value = Settings::preloadThumbAggressively,
|
||||
)
|
||||
if (!isAtLeastQ) {
|
||||
var animateItems by Settings.animateItems.asMutableState()
|
||||
SwitchPref(
|
||||
checked = animateItems,
|
||||
onMutate = { animateItems = !animateItems },
|
||||
title = stringResource(id = R.string.animate_items),
|
||||
summary = stringResource(id = R.string.animate_items_summary),
|
||||
)
|
||||
}
|
||||
IntSliderPreference(
|
||||
maxValue = 5,
|
||||
minValue = 1,
|
||||
|
||||
@@ -49,14 +49,17 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.EhFilter
|
||||
import com.hippo.ehviewer.client.EhFilter.forget
|
||||
import com.hippo.ehviewer.client.EhFilter.remember
|
||||
import com.hippo.ehviewer.client.EhFilter.trigger
|
||||
import com.hippo.ehviewer.collectAsState
|
||||
import com.hippo.ehviewer.dao.Filter
|
||||
import com.hippo.ehviewer.dao.FilterMode
|
||||
import com.hippo.ehviewer.ui.tools.Deferred
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
@@ -74,6 +77,7 @@ fun FilterScreen(navigator: DestinationsNavigator) {
|
||||
val dialogState = LocalDialogState.current
|
||||
val textIsEmpty = stringResource(R.string.text_is_empty)
|
||||
val labelExist = stringResource(R.string.label_text_exist)
|
||||
val animateItems by Settings.animateItems.collectAsState()
|
||||
|
||||
fun addFilter() {
|
||||
scope.launch {
|
||||
@@ -227,7 +231,7 @@ fun FilterScreen(navigator: DestinationsNavigator) {
|
||||
stickyHeader(key = filterMode) {
|
||||
Text(
|
||||
text = stringResource(id = title),
|
||||
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp).animateItem(),
|
||||
modifier = Modifier.padding(horizontal = 24.dp, vertical = 8.dp).thenIf(animateItems) { animateItem() },
|
||||
color = MaterialTheme.colorScheme.tertiary,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
@@ -235,7 +239,7 @@ fun FilterScreen(navigator: DestinationsNavigator) {
|
||||
items(filters, key = { requireNotNull(it.id) }) { filter ->
|
||||
val filterCheckBoxRecomposeScope = currentRecomposeScope
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().animateItem().clickable { filter.trigger { filterCheckBoxRecomposeScope.invalidate() } },
|
||||
modifier = Modifier.fillMaxWidth().thenIf(animateItems) { animateItem() }.clickable { filter.trigger { filterCheckBoxRecomposeScope.invalidate() } },
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Checkbox(
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.hippo.ehviewer.ui.tools
|
||||
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
inline fun Modifier.thenIf(condition: Boolean, crossinline block: Modifier.() -> Modifier) =
|
||||
if (condition) block() else this
|
||||
@@ -501,6 +501,8 @@
|
||||
<string name="list_tile_thumb_size">详情模式下缩略图大小</string>
|
||||
<string name="account_name">账户</string>
|
||||
<string name="preload_thumb_aggressively">激进地预载缩略图</string>
|
||||
<string name="animate_items">列表项目动画</string>
|
||||
<string name="animate_items_summary">如果应用崩溃请尝试禁用此项</string>
|
||||
<string name="auto_updates">自动检查更新</string>
|
||||
<string name="update_frequency_never">从不</string>
|
||||
<string name="update_frequency_daily">每天</string>
|
||||
|
||||
@@ -564,6 +564,8 @@
|
||||
<string name="list_tile_thumb_size">Thumb size in detail mode</string>
|
||||
<string name="account_name">Account</string>
|
||||
<string name="preload_thumb_aggressively">Preload thumbs aggressively</string>
|
||||
<string name="animate_items">List item animations</string>
|
||||
<string name="animate_items_summary">Try disabling this if you are facing crashes</string>
|
||||
<string name="user_agent">User Agent</string>
|
||||
<string name="auto_updates">Automatically check for updates</string>
|
||||
<string name="update_frequency_never">Never</string>
|
||||
|
||||
Reference in new issue
Block a user