-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improvement: introduce DeckPickerViewModel #17690
base: main
Are you sure you want to change the base?
improvement: introduce DeckPickerViewModel #17690
Conversation
88b1f80
to
68eb0e2
Compare
It will also be used in the Deck Picker
We want to use a ViewModel for DeckPicker This is the start * extract 'focusedDeck' * will be used in the next commit
* inline confirmDeckDeletion * removing unnecessary 'dismiss' calls * extract `deleteDeck` * introduce `DeckDeletionResult`
68eb0e2
to
2250587
Compare
* @see deleteDeck | ||
* @see DeckDeletionResult | ||
*/ | ||
val deckDeletedNotification = MutableSharedFlow<DeckDeletionResult>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be part of an 'undoableSnackbar' flow, didn't seem useful
@CheckResult // This is a slow operation and should be inside `withProgress` | ||
fun deleteDeck(did: DeckId) = | ||
viewModelScope.launch { | ||
val deckName = withCol { decks.get(did)!!.name } | ||
val changes = undoableOp { decks.remove(listOf(did)) } | ||
// After deletion: decks.current() reverts to Default, necessitating `focusedDeck` | ||
// to match and avoid unnecessary scrolls in `renderPage()`. | ||
focusedDeck = Consts.DEFAULT_DECK_ID | ||
|
||
deckDeletedNotification.emit( | ||
DeckDeletionResult(deckName = deckName, cardsDeleted = changes.count), | ||
) | ||
} | ||
|
||
/** | ||
* Deletes the currently selected deck | ||
* | ||
* This is a slow operation and should be inside `withProgress` | ||
*/ | ||
@CheckResult | ||
fun deleteSelectedDeck() = | ||
viewModelScope.launch { | ||
val targetDeckId = withCol { decks.selected() } | ||
deleteDeck(targetDeckId).join() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We really have 3:
- Delete [collection] Selected Deck
- Delete Focused Deck
- Delete DeckID
At 3, we can potentially parameterize the method: added complexity in the VM, for 4/5 less lines in the Activity
But it's probably best to stop using 'Delete [collection] Selected Deck' to avoid race conditions
decks.name(focusedDeck), | ||
decks.cardCount(focusedDeck, includeSubdecks = true), | ||
decks.isFiltered(focusedDeck), | ||
decks.name(viewModel.focusedDeck), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SanjaySargam showDeleteDeckConfirmationDialog
is only used when pressing 'DEL', in all other cases, we delete unconditionally and show an 'undo' snackbar
Was this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is intentional.
KeyEvent.KEYCODE_DEL -> {
// This action on a deck should only occur when the user see the deck name very clearly,
// that is, when it appears in the trailing study option fragment
if (fragmented) {
if (event.isShiftPressed) {
// Shortcut: Shift + DEL - Delete deck without confirmation dialog
Timber.i("Shift+DEL: Deck deck without confirmation")
deleteDeck(focusedDeck)
} else {
// Shortcut: DEL
Timber.i("Delete Deck from keypress")
showDeleteDeckConfirmationDialog()
}
return true
}
}
Purpose / Description
We want more ViewModels in 2025. Let it start
Approach
remove
How Has This Been Tested?
Deleted a deck in the UI of an API 34 emulator via context menu
Checklist