@@ -25,7 +25,6 @@ import androidx.lifecycle.viewModelScope
2525import anki.card_rendering.EmptyCardsReport
2626import anki.collection.OpChanges
2727import anki.decks.SetDeckCollapsedRequest
28- import anki.i18n.GeneratedTranslations
2928import anki.sync.SyncStatusResponse
3029import com.ichi2.anki.CollectionManager
3130import com.ichi2.anki.CollectionManager.TR
@@ -207,11 +206,7 @@ class DeckPickerViewModel :
207206 // to match and avoid unnecessary scrolls in `renderPage()`.
208207 focusedDeck = Consts .DEFAULT_DECK_ID
209208
210- events.emit(
211- UiEvent .DeckDeleted (
212- DeckDeletionResult (deckName = deckName, cardsDeleted = changes.count),
213- ),
214- )
209+ events.emit(UiEvent .DeckDeleted (deckName = deckName, cardsDeleted = changes.count))
215210 }
216211
217212 /* *
@@ -249,7 +244,7 @@ class DeckPickerViewModel :
249244 }
250245 }
251246 val result = undoableOp { removeCardsAndOrphanedNotes(toDelete) }
252- events.emit(UiEvent .EmptyCardsDeleted (EmptyCardsResult ( cardsDeleted = result.count) ))
247+ events.emit(UiEvent .EmptyCardsDeleted (cardsDeleted = result.count))
253248 }
254249
255250 // TODO: move withProgress to the ViewModel, so we don't return 'Job'
@@ -462,11 +457,9 @@ class DeckPickerViewModel :
462457 }
463458 events.emit(
464459 UiEvent .CreateShortcut (
465- ShortcutData (
466- deckId = deckId,
467- shortLabel = shortLabel,
468- longLabel = longLabel,
469- ),
460+ deckId = deckId,
461+ shortLabel = shortLabel,
462+ longLabel = longLabel,
470463 ),
471464 )
472465 }
@@ -647,46 +640,8 @@ class DeckPickerViewModel :
647640 }
648641}
649642
650- /* * Result of [DeckPickerViewModel.deleteDeck] */
651- data class DeckDeletionResult (
652- val deckName : String ,
653- val cardsDeleted : Int ,
654- ) {
655- /* *
656- * @see GeneratedTranslations.browsingCardsDeletedWithDeckname
657- */
658- // TODO: Somewhat questionable meaning: {count} cards deleted from {deck_name}.
659- @CheckResult
660- fun toHumanReadableString () =
661- TR .browsingCardsDeletedWithDeckname(
662- count = cardsDeleted,
663- deckName = deckName,
664- )
665- }
666-
667- /* * Result of [DeckPickerViewModel.deleteEmptyCards] */
668- data class EmptyCardsResult (
669- val cardsDeleted : Int ,
670- ) {
671- /* *
672- * @see GeneratedTranslations.emptyCardsDeletedCount */
673- @CheckResult
674- fun toHumanReadableString () = TR .emptyCardsDeletedCount(cardsDeleted)
675- }
676-
677643fun DeckNode.onlyHasDefaultDeck () = children.singleOrNull()?.did == DEFAULT_DECK_ID
678644
679- /* *
680- * Data for creating a deck shortcut
681- * @param shortLabel the basename of the deck (e.g., "Verbs" for "Language::English::Verbs")
682- * @param longLabel the full deck name (e.g., "Language::English::Verbs")
683- */
684- data class ShortcutData (
685- val deckId : DeckId ,
686- val shortLabel : String ,
687- val longLabel : String ,
688- )
689-
690645enum class SyncIconState {
691646 Normal ,
692647 PendingChanges ,
@@ -695,18 +650,36 @@ enum class SyncIconState {
695650}
696651
697652/* *
698- * One-shot UI events emitted by [DeckPickerViewModel].
699- *
700- * @see com.ichi2.anki.ui.UiEventHost
653+ * One-shot UI events emitted by [DeckPickerViewModel] over a single channel and
654+ * collected by [DeckPicker]. Use for navigation, snackbars, dialogs, errors —
655+ * not for ongoing state (use a `StateFlow` for that).
701656 */
702657sealed interface UiEvent {
658+ /* * A deck (and possibly child decks) was deleted. @see DeckPickerViewModel.deleteDeck */
703659 data class DeckDeleted (
704- val result : DeckDeletionResult ,
705- ) : UiEvent
660+ val deckName : String ,
661+ val cardsDeleted : Int ,
662+ ) : UiEvent {
663+ /* *
664+ * @see anki.i18n.GeneratedTranslations.browsingCardsDeletedWithDeckname
665+ */
666+ // TODO: Somewhat questionable meaning: {count} cards deleted from {deck_name}.
667+ @CheckResult
668+ fun toHumanReadableString () =
669+ TR .browsingCardsDeletedWithDeckname(
670+ count = cardsDeleted,
671+ deckName = deckName,
672+ )
673+ }
706674
675+ /* * Empty cards were removed. @see DeckPickerViewModel.deleteEmptyCards */
707676 data class EmptyCardsDeleted (
708- val result : EmptyCardsResult ,
709- ) : UiEvent
677+ val cardsDeleted : Int ,
678+ ) : UiEvent {
679+ /* * @see anki.i18n.GeneratedTranslations.emptyCardsDeletedCount */
680+ @CheckResult
681+ fun toHumanReadableString () = TR .emptyCardsDeletedCount(cardsDeleted)
682+ }
710683
711684 data class Navigate (
712685 val destination : Destination ,
@@ -720,8 +693,15 @@ sealed interface UiEvent {
720693 val deckId : DeckId ,
721694 ) : UiEvent
722695
696+ /* *
697+ * Request to create a launcher shortcut for a deck.
698+ * @param shortLabel the basename of the deck (e.g., "Verbs" for "Language::English::Verbs")
699+ * @param longLabel the full deck name (e.g., "Language::English::Verbs")
700+ */
723701 data class CreateShortcut (
724- val data : ShortcutData ,
702+ val deckId : DeckId ,
703+ val shortLabel : String ,
704+ val longLabel : String ,
725705 ) : UiEvent
726706
727707 data class DisableShortcuts (
0 commit comments