Reintroduce confirm dialog for swipe-to-dismiss (#914)

Observe the state changes instead of using `confirmValueChange`, which
will be called twice.
This commit is contained in:
FooIbar authored and GitHub committed 2024-03-15 18:40:51 +08:00
1 parent 5746e3bb57
commit c5cbcf7418
6 files changed
+54 -28

No files matched your search

@@ -94,12 +94,7 @@ object DownloadManager : OnSpiderListener, CoroutineScope {
if (label == null) {
return false
}
for ((label1) in labelList) {
if (label == label1) {
return true
}
}
return false
return labelList.any { it.label == label }
}
fun containDownloadInfo(gid: Long) = mAllInfoMap.containsKey(gid)
@@ -518,12 +513,14 @@ object DownloadManager : OnSpiderListener, CoroutineScope {
}
suspend fun deleteLabel(label: String) {
labelList.run {
with(labelList) {
val index = indexOfFirst { it.label == label }
val item = get(index)
EhDB.removeDownloadLabel(item)
subList(index + 1, size).forEach {
it.position--
}
EhDB.removeDownloadLabel(removeAt(index))
removeAt(index)
}
allInfoList.forEach {
if (it.label == label) {
@@ -46,11 +46,13 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SwipeToDismissBoxDefaults
import androidx.compose.material3.SwipeToDismissBoxState
import androidx.compose.material3.SwipeToDismissBoxValue
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.rememberSwipeToDismissBoxState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
@@ -61,6 +63,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@@ -142,6 +145,7 @@ fun DownloadsScreen(navigator: DestinationsNavigator) = composing(navigator) {
val activity = remember { findActivity<MainActivity>() }
val density = LocalDensity.current
val view = LocalView.current
val positionalThreshold = SwipeToDismissBoxDefaults.positionalThreshold
val allName = stringResource(R.string.download_all)
val defaultName = stringResource(R.string.default_download_label_name)
val title = stringResource(
@@ -261,21 +265,28 @@ fun DownloadsScreen(navigator: DestinationsNavigator) = composing(navigator) {
},
)
}
itemsIndexed(labelList, key = { _, item -> item.label }) { index, (item) ->
val dismissState = rememberSwipeToDismissBoxState(
confirmValueChange = {
itemsIndexed(labelList, key = { _, item -> item.id!! }) { index, (item) ->
// Not using rememberSwipeToDismissBoxState to prevent LazyColumn from reusing it
val dismissState = remember { SwipeToDismissBoxState(SwipeToDismissBoxValue.Settled, density, positionalThreshold = positionalThreshold) }
LaunchedEffect(dismissState) {
snapshotFlow { dismissState.currentValue }.collect {
if (it == SwipeToDismissBoxValue.EndToStart) {
launch {
runCatching {
awaitPermissionOrCancel(confirmText = R.string.delete) {
Text(text = stringResource(R.string.delete_label, item))
}
}.onSuccess {
DownloadManager.deleteLabel(item)
when (filterState.label) {
item -> switchLabel("")
null -> invalidateKey = !invalidateKey
}
}.onFailure {
dismissState.reset()
}
}
true
},
)
}
}
ReorderableItem(reorderableLabelState, key = item) { isDragging ->
SwipeToDismissBox2(
state = dismissState,
@@ -46,11 +46,12 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SwipeToDismissBoxDefaults
import androidx.compose.material3.SwipeToDismissBoxState
import androidx.compose.material3.SwipeToDismissBoxValue
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.material3.rememberSwipeToDismissBoxState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
@@ -62,6 +63,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@@ -201,6 +203,7 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) = c
onBack = { showSearchLayout = false },
)
val density = LocalDensity.current
val positionalThreshold = SwipeToDismissBoxDefaults.positionalThreshold
val listState = rememberLazyGridState()
val gridState = rememberLazyStaggeredGridState()
val isTopList = remember(urlBuilder) { urlBuilder.mode == MODE_TOPLIST }
@@ -385,21 +388,30 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) = c
}
itemsIndexed(quickSearchList, key = { _, item -> item.id!! }) { index, item ->
ReorderableItem(reorderableLazyListState, key = item.id!!) { isDragging ->
val dismissState = rememberSwipeToDismissBoxState(
confirmValueChange = { value ->
// Not using rememberSwipeToDismissBoxState to prevent LazyColumn from reusing it
val dismissState = remember { SwipeToDismissBoxState(SwipeToDismissBoxValue.Settled, density, positionalThreshold = positionalThreshold) }
LaunchedEffect(dismissState) {
snapshotFlow { dismissState.currentValue }.collect { value ->
if (value == SwipeToDismissBoxValue.EndToStart) {
with(quickSearchList) {
val removeIndex = indexOf(item)
subList(removeIndex + 1, size).forEach {
it.position--
runCatching {
awaitPermissionOrCancel(confirmText = R.string.delete) {
Text(text = stringResource(R.string.delete_quick_search, item.name))
}
removeAt(removeIndex)
}.onSuccess {
EhDB.deleteQuickSearch(item)
with(quickSearchList) {
val removeIndex = indexOf(item)
subList(removeIndex + 1, size).forEach {
it.position--
}
removeAt(removeIndex)
}
}.onFailure {
dismissState.reset()
}
launchIO { EhDB.deleteQuickSearch(item) }
}
true
},
)
}
}
SwipeToDismissBox2(
state = dismissState,
backgroundContent = {},
@@ -85,6 +85,7 @@
<string name="duplicate_quick_search">已存在相同的快速搜索,名称为“%s”。</string>
<string name="duplicate_name">已存在相同名称</string>
<string name="save_progress">保存进度</string>
<string name="delete_quick_search">删除快速搜索“%s”?</string>
<string name="go_to_hint">第 %1$d 页,共 %2$d 页</string>
<!-- search_min_rating -->
<string name="any">不限</string>
@@ -245,6 +246,7 @@
<string name="label_text_is_invalid">“默认”是无效标签</string>
<string name="label_text_exist">标签已存在</string>
<string name="rename_label_title">重命名标签</string>
<string name="delete_label">删除标签“%s”?</string>
<!-- History -->
<string name="no_history">这里是阅读历史</string>
<string name="clear_all">全部清除</string>
@@ -85,6 +85,7 @@
<string name="duplicate_quick_search">已存在相同的快速搜尋,名稱為“%s”。</string>
<string name="duplicate_name">名稱重複</string>
<string name="save_progress">儲存進度</string>
<string name="delete_quick_search">刪除快速搜尋“%s”?</string>
<string name="go_to_hint">第 %1$d 頁,共 %2$d 頁</string>
<!-- search_min_rating -->
<string name="any">不限</string>
@@ -244,6 +245,7 @@
<string name="label_text_is_invalid">“預設”是無效的標籤</string>
<string name="label_text_exist">標籤已存在</string>
<string name="rename_label_title">重新命名標籤</string>
<string name="delete_label">刪除標籤“%s”?</string>
<!-- History -->
<string name="no_history">歷史紀錄將會顯示在這裡</string>
<string name="clear_all">全部清除</string>
+2
View File
@@ -125,6 +125,7 @@
<string name="duplicate_quick_search">A duplicate quick search exists. The name is \"%s\".</string>
<string name="duplicate_name">This name is already in use.</string>
<string name="save_progress">Save progress</string>
<string name="delete_quick_search">Delete quick search \"%s\"?</string>
<string name="go_to_hint">Page %1$d, total %2$d pages</string>
<!-- search_min_rating -->
<string name="any">Any</string>
@@ -287,6 +288,7 @@
<string name="label_text_is_invalid">\"Default\" is an invalid label</string>
<string name="label_text_exist">Label exists</string>
<string name="rename_label_title">Rename label</string>
<string name="delete_label">Delete label \"%s\"?</string>
<!-- History -->
<string name="no_history">Viewed galleries will be shown here</string>
<string name="clear_all">Clear all</string>