Checked for duplicates?
Does it also happen in the desktop version?
What are the steps to reproduce this bug?
- enable "Don't keep activities" from developer options
- open filtered deck options screen (either make a new filtered deck or open existing one)
- go to some other app and come back, so the screen gets recreated
- then try any of these two:
a) type a name of some deck which already exist
b) change anything like search or limit, then press back
and theres one more which dont even need process death:
5. open a existing filtered deck options, rename it to anything else, then type the original name
back again
Expected behaviour
for (a) it should show that "name already exists" error and Build button should stay disabled, for
(b) it should ask me discard changes before deleting my edits, and in (5) putting back the original
name shouldnt be counted as conflict since its the same deck.
but none of these works. after the screen is restored, typing a existing deck name shows no error
at all and Build stays enabled, so you end up getting some raw backend exception. and back press
just throws away everything without asking anything. and reverting the name marks it as "already
exists" and Rebuild gets disabled.
i wrote few unit tests before reporting to make sure im not imagining it, all 3 fails on main:
DEFECT 1 (restore + existing name) -> expected: but was:
DEFECT 2 (restore + edit) -> Expected value to be true.
DEFECT 3 (revert to own name) -> expected: but was:
(for simulating the process death i just created a second ViewModel on the same SavedStateHandle,
cus thats what basically happens when VM is killed but handle survives)
i think the reason is this early return in FilteredDeckOptionsViewModel's init:
val previousState = savedStateHandle.get<FilteredDeckOptions>(ARG_DATA)
if (previousState != null) {
state.update { previousState }
return@launch
}
because of this return it skips two lines below - decksNames = withCol { safeGetDecksNames() } and
initialState = this. so decksNames remains emptyList() and thats why decksNames.contains(name)
inside onDeckNameChange never becomes true. and initialState remains null so wasStateModified()
hits val initial = initialState ?: return false and returns false always, which means
hasUnsavedChanges is always false and the back handler never gets enabled.
for the 3rd one, safeGetDecksNames() is using includeFiltered = true so the list also contain the
same deck which you are editing right now, thats why setting original name back collides with
itself
Debug info
AnkiDroid Version = 2.24.0 (ebcf8e0e34921628b9b8a496c66ffd4adbb3705f)
Backend Version = 0.1.64-anki25.09.2 (25.09.2 3890e12c9e48c028c3f12aa58cb64bd9f8895e30)
Android Version = 13 (SDK 33)
ProductFlavor = play
Device Info = OnePlus | OnePlus | OP555BL1 | IV2201_IND | IV2201 | mt6877
WebView Info = [com.google.android.webview | 787118103]: Mozilla/5.0 (Linux; Android 13; IV2201 Build/TP1A.220905.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/150.0.7871.181 Mobile Safari/537.36
ACRA UUID = bbe8603c-4564-4f9f-9621-e2c7e5b9b556
FSRS = 5.1.0 (Enabled: false)
Crash Reports Enabled = true
(Optional) Anything else you want to share?
No response
Research
Checked for duplicates?
Does it also happen in the desktop version?
What are the steps to reproduce this bug?
a) type a name of some deck which already exist
b) change anything like search or limit, then press back
and theres one more which dont even need process death:
5. open a existing filtered deck options, rename it to anything else, then type the original name
back again
Expected behaviour
for (a) it should show that "name already exists" error and Build button should stay disabled, for
(b) it should ask me discard changes before deleting my edits, and in (5) putting back the original
name shouldnt be counted as conflict since its the same deck.
but none of these works. after the screen is restored, typing a existing deck name shows no error
at all and Build stays enabled, so you end up getting some raw backend exception. and back press
just throws away everything without asking anything. and reverting the name marks it as "already
exists" and Rebuild gets disabled.
i wrote few unit tests before reporting to make sure im not imagining it, all 3 fails on main:
DEFECT 1 (restore + existing name) -> expected: but was:
DEFECT 2 (restore + edit) -> Expected value to be true.
DEFECT 3 (revert to own name) -> expected: but was:
(for simulating the process death i just created a second ViewModel on the same SavedStateHandle,
cus thats what basically happens when VM is killed but handle survives)
i think the reason is this early return in FilteredDeckOptionsViewModel's init:
because of this return it skips two lines below - decksNames = withCol { safeGetDecksNames() } and
initialState = this. so decksNames remains emptyList() and thats why decksNames.contains(name)
inside onDeckNameChange never becomes true. and initialState remains null so wasStateModified()
hits
val initial = initialState ?: return falseand returns false always, which meanshasUnsavedChanges is always false and the back handler never gets enabled.
for the 3rd one, safeGetDecksNames() is using includeFiltered = true so the list also contain the
same deck which you are editing right now, thats why setting original name back collides with
itself
Debug info
(Optional) Anything else you want to share?
No response
Research