@@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
14
14
import androidx.compose.foundation.layout.fillMaxWidth
15
15
import androidx.compose.foundation.layout.padding
16
16
import androidx.compose.foundation.lazy.LazyColumn
17
- import androidx.compose.foundation.lazy.LazyListItemInfo
18
17
import androidx.compose.foundation.lazy.items
19
18
import androidx.compose.foundation.lazy.itemsIndexed
20
19
import androidx.compose.foundation.lazy.rememberLazyListState
@@ -74,13 +73,11 @@ import app.revanced.manager.util.saver.snapshotStateListSaver
74
73
import app.revanced.manager.util.saver.snapshotStateSetSaver
75
74
import app.revanced.manager.util.toast
76
75
import app.revanced.manager.util.transparentListItemColors
77
- import kotlinx.coroutines.CoroutineScope
78
76
import kotlinx.parcelize.Parcelize
79
77
import org.koin.compose.koinInject
80
78
import org.koin.core.component.KoinComponent
81
79
import org.koin.core.component.get
82
80
import sh.calvin.reorderable.ReorderableItem
83
- import sh.calvin.reorderable.rememberReorderableLazyColumnState
84
81
import sh.calvin.reorderable.rememberReorderableLazyListState
85
82
import java.io.Serializable
86
83
import kotlin.random.Random
@@ -91,15 +88,28 @@ private class OptionEditorScope<T : Any>(
91
88
val option : Option <T >,
92
89
val openDialog : () -> Unit ,
93
90
val dismissDialog : () -> Unit ,
91
+ val selectionWarningEnabled : Boolean ,
92
+ val showSelectionWarning : () -> Unit ,
94
93
val value : T ? ,
95
- val setValue : (T ? ) -> Unit ,
94
+ val setValue : (T ? ) -> Unit
96
95
) {
97
96
fun submitDialog (value : T ? ) {
98
97
setValue(value)
99
98
dismissDialog()
100
99
}
101
100
102
- fun clickAction () = editor.clickAction(this )
101
+ fun checkSafeguard (block : () -> Unit ) {
102
+ if (! option.required && selectionWarningEnabled)
103
+ showSelectionWarning()
104
+ else
105
+ block()
106
+ }
107
+
108
+ fun clickAction () {
109
+ checkSafeguard {
110
+ editor.clickAction(this )
111
+ }
112
+ }
103
113
104
114
@Composable
105
115
fun ListItemTrailingContent () = editor.ListItemTrailingContent (this )
@@ -113,7 +123,7 @@ private interface OptionEditor<T : Any> {
113
123
114
124
@Composable
115
125
fun ListItemTrailingContent (scope : OptionEditorScope <T >) {
116
- IconButton (onClick = { clickAction(scope) }) {
126
+ IconButton (onClick = { scope.checkSafeguard { clickAction(scope) } }) {
117
127
Icon (Icons .Outlined .Edit , stringResource(R .string.edit))
118
128
}
119
129
}
@@ -141,11 +151,14 @@ private inline fun <T : Any> WithOptionEditor(
141
151
option : Option <T >,
142
152
value : T ? ,
143
153
noinline setValue : (T ? ) -> Unit ,
154
+ selectionWarningEnabled : Boolean ,
144
155
crossinline onDismissDialog : @DisallowComposableCalls () -> Unit = {},
145
156
block : OptionEditorScope <T >.() -> Unit
146
157
) {
147
158
var showDialog by rememberSaveable { mutableStateOf(false ) }
148
- val scope = remember(editor, option, value, setValue) {
159
+ var showSelectionWarningDialog by rememberSaveable { mutableStateOf(false ) }
160
+
161
+ val scope = remember(editor, option, value, setValue, selectionWarningEnabled) {
149
162
OptionEditorScope (
150
163
editor,
151
164
option,
@@ -154,11 +167,18 @@ private inline fun <T : Any> WithOptionEditor(
154
167
showDialog = false
155
168
onDismissDialog()
156
169
},
170
+ selectionWarningEnabled,
171
+ showSelectionWarning = { showSelectionWarningDialog = true },
157
172
value,
158
173
setValue
159
174
)
160
175
}
161
176
177
+ if (showSelectionWarningDialog)
178
+ SelectionWarningDialog (
179
+ onDismiss = { showSelectionWarningDialog = false }
180
+ )
181
+
162
182
if (showDialog) scope.Dialog ()
163
183
164
184
scope.block()
@@ -169,6 +189,7 @@ fun <T : Any> OptionItem(
169
189
option : Option <T >,
170
190
value : T ? ,
171
191
setValue : (T ? ) -> Unit ,
192
+ selectionWarningEnabled : Boolean
172
193
) {
173
194
val editor = remember(option.type, option.presets) {
174
195
@Suppress(" UNCHECKED_CAST" )
@@ -181,7 +202,7 @@ fun <T : Any> OptionItem(
181
202
else baseOptionEditor
182
203
}
183
204
184
- WithOptionEditor (editor, option, value, setValue) {
205
+ WithOptionEditor (editor, option, value, setValue, selectionWarningEnabled ) {
185
206
ListItem (
186
207
modifier = Modifier .clickable(onClick = ::clickAction),
187
208
headlineContent = { Text (option.title) },
@@ -300,7 +321,7 @@ private object StringOptionEditor : OptionEditor<String> {
300
321
301
322
private abstract class NumberOptionEditor <T : Number > : OptionEditor <T > {
302
323
@Composable
303
- protected abstract fun NumberDialog (
324
+ abstract fun NumberDialog (
304
325
title : String ,
305
326
current : T ? ,
306
327
validator : (T ? ) -> Boolean ,
@@ -354,7 +375,14 @@ private object BooleanOptionEditor : OptionEditor<Boolean> {
354
375
355
376
@Composable
356
377
override fun ListItemTrailingContent (scope : OptionEditorScope <Boolean >) {
357
- HapticSwitch (checked = scope.current, onCheckedChange = scope.setValue)
378
+ HapticSwitch (
379
+ checked = scope.current,
380
+ onCheckedChange = { value ->
381
+ scope.checkSafeguard {
382
+ scope.setValue(value)
383
+ }
384
+ }
385
+ )
358
386
}
359
387
360
388
@Composable
@@ -393,6 +421,7 @@ private class PresetOptionEditor<T : Any>(private val innerEditor: OptionEditor<
393
421
scope.option,
394
422
scope.value,
395
423
scope.setValue,
424
+ scope.selectionWarningEnabled,
396
425
onDismissDialog = scope.dismissDialog
397
426
) inner@{
398
427
var hidePresetsDialog by rememberSaveable {
@@ -614,7 +643,8 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
614
643
elementEditor,
615
644
elementOption,
616
645
value = item.value,
617
- setValue = { items[index] = item.copy(value = it) }
646
+ setValue = { items[index] = item.copy(value = it) },
647
+ selectionWarningEnabled = scope.selectionWarningEnabled
618
648
) {
619
649
ListItem (
620
650
modifier = Modifier .combinedClickable(
0 commit comments