Add option to disable list item animations (#997)

It may crash on some devices.
This commit is contained in:
FooIbar authored and GitHub committed 2024-04-07 13:57:27 +08:00
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>
+2
View File
@@ -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>