Skip to content

Commit c9d2b10

Browse files
committed
fix(split-cardbrowser): list is empty when toggling to notes only mode
1 parent 9bf44b2 commit c9d2b10

File tree

5 files changed

+29
-14
lines changed

5 files changed

+29
-14
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -713,19 +713,19 @@ open class CardBrowser :
713713
* We use the Card ID to specify the preview target */
714714
@NeedsTest("note edits are saved")
715715
@NeedsTest("I/O edits are saved")
716-
fun openNoteEditorForCard(cardId: CardId) {
716+
fun openNoteEditorForCard(cardId: CardId?) {
717717
viewModel.openNoteEditorForCard(cardId)
718718
}
719719

720720
/**
721721
* In case of selection, the first card that was selected, otherwise the first card of the list.
722722
*/
723-
private suspend fun getCardIdForNoteEditor(): CardId {
723+
private suspend fun getCardIdForNoteEditor(): CardId? {
724724
// Just select the first one if there's a multiselect occurring.
725725
return if (viewModel.isInMultiSelectMode) {
726726
viewModel.querySelectedCardIdAtPosition(0)
727727
} else {
728-
viewModel.getRowAtPosition(0).toCardId(viewModel.cardsOrNotes)
728+
viewModel.getRowAtPosition(0)?.toCardId(viewModel.cardsOrNotes)
729729
}
730730
}
731731

@@ -1146,7 +1146,7 @@ open class CardBrowser :
11461146
// Hide note editor frame if deck is empty and fragmented
11471147
binding.noteEditorFrame?.visibility =
11481148
if (fragmented && !isDeckEmpty) {
1149-
viewModel.currentCardId = (viewModel.focusedRow ?: viewModel.cards[0]).toCardId(viewModel.cardsOrNotes)
1149+
viewModel.currentCardId = viewModel.safeGetCurrentCardId()
11501150
loadNoteEditorFragmentIfFragmented()
11511151
View.VISIBLE
11521152
} else {

AnkiDroid/src/main/java/com/ichi2/anki/browser/CardBrowserViewModel.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,22 @@ class CardBrowserViewModel(
168168
val cardsOrNotes get() = flowOfCardsOrNotes.value
169169

170170
// card that was clicked (not marked)
171-
var currentCardId: CardId = 0
171+
var currentCardId: CardId? = null
172+
173+
/**
174+
* Safely determines the current card ID to display in the note editor.
175+
*/
176+
suspend fun safeGetCurrentCardId(): CardId? {
177+
// Early return if no cards available
178+
if (cards.isEmpty()) return 0
179+
180+
// Try to use editor row first
181+
val focusedCard = focusedRow?.toCardId(cardsOrNotes)
182+
if (focusedCard != null) return focusedCard
183+
184+
// Fallback to first card in list
185+
return cards.firstOrNull()?.toCardId(cardsOrNotes)
186+
}
172187

173188
var cardIdToBeScrolledTo: CardId? = null
174189
private set
@@ -332,7 +347,7 @@ class CardBrowserViewModel(
332347
return CardInfoDestination(firstSelectedCard, TR.currentCardBrowse())
333348
}
334349

335-
suspend fun queryDataForCardEdit(id: CardOrNoteId): CardId = id.toCardId(cardsOrNotes)
350+
suspend fun queryDataForCardEdit(id: CardOrNoteId): CardId? = id.toCardId(cardsOrNotes)
336351

337352
private suspend fun getInitialDeck(): SelectableDeck {
338353
// TODO: Handle the launch intent
@@ -565,7 +580,7 @@ class CardBrowserViewModel(
565580
}
566581

567582
// on a row tap
568-
fun openNoteEditorForCard(cardId: CardId) {
583+
fun openNoteEditorForCard(cardId: CardId?) {
569584
currentCardId = cardId
570585
if (!isFragmented) {
571586
endMultiSelectMode(SingleSelectCause.OpenNoteEditorActivity)
@@ -1236,7 +1251,7 @@ class CardBrowserViewModel(
12361251

12371252
suspend fun queryCardIdAtPosition(index: Int): CardId = cards.queryCardIdsAt(index).first()
12381253

1239-
suspend fun querySelectedCardIdAtPosition(index: Int): CardId = selectedRows.toList()[index].toCardId(cardsOrNotes)
1254+
suspend fun querySelectedCardIdAtPosition(index: Int): CardId? = selectedRows.toList()[index].toCardId(cardsOrNotes)
12401255

12411256
/**
12421257
* Obtains two lists of column headings with preview data

AnkiDroid/src/main/java/com/ichi2/anki/browser/CardOrNoteId.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ value class CardOrNoteId(
3939

4040
// TODO: We use this for 'Edit Note' or 'Card Info'. We should reconsider whether we ever want
4141
// to move from NoteId to CardId. Our move to 'Notes' mode wasn't well thought-through
42-
suspend fun toCardId(type: CardsOrNotes): CardId =
42+
suspend fun toCardId(type: CardsOrNotes): CardId? =
4343
when (type) {
4444
CardsOrNotes.CARDS -> cardOrNoteId
45-
CardsOrNotes.NOTES -> withCol { cardIdsOfNote(cardOrNoteId).first() }
45+
CardsOrNotes.NOTES -> withCol { cardIdsOfNote(cardOrNoteId).firstOrNull() }
4646
}
4747
}

AnkiDroid/src/main/java/com/ichi2/anki/noteeditor/NoteEditorLauncher.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ sealed interface NoteEditorLauncher : Destination {
169169
* @property animation The animation direction.
170170
*/
171171
data class EditCard(
172-
val cardId: CardId,
172+
val cardId: CardId?,
173173
val animation: ActivityTransitionAnimation.Direction,
174174
val inCardBrowserActivity: Boolean = false,
175175
) : NoteEditorLauncher {

AnkiDroid/src/test/java/com/ichi2/anki/browser/CardBrowserViewModelTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class CardBrowserViewModelTest : JvmTest() {
154154
assertThat("Deck should be changed", col.getCard(cardId).did, equalTo(newDeck))
155155
}
156156

157-
val hasSomeDecksUnchanged = cards.any { row -> col.getCard(row.toCardId(cardsOrNotes)).did != newDeck }
157+
val hasSomeDecksUnchanged = cards.any { row -> row.toCardId(cardsOrNotes)?.let { col.getCard(it) }?.did != newDeck }
158158
assertThat("some decks are unchanged", hasSomeDecksUnchanged)
159159
}
160160

@@ -633,7 +633,7 @@ class CardBrowserViewModelTest : JvmTest() {
633633
@Test
634634
fun `suspend - cards - some suspended`() =
635635
runViewModelTest(notes = 2) {
636-
suspendCards(cards.first().toCardId(cardsOrNotes))
636+
cards.first().toCardId(cardsOrNotes)?.let { suspendCards(it) }
637637
ensureOpsExecuted(1) {
638638
selectAll()
639639
toggleSuspendCards()
@@ -689,7 +689,7 @@ class CardBrowserViewModelTest : JvmTest() {
689689
fun `suspend - notes - some cards suspended`() =
690690
runViewModelNotesTest(notes = 2) {
691691
// this suspends o single cid from a nid
692-
suspendCards(cards.first().toCardId(cardsOrNotes))
692+
cards.first().toCardId(cardsOrNotes)?.let { suspendCards(it) }
693693
ensureOpsExecuted(1) {
694694
selectAll()
695695
toggleSuspendCards()

0 commit comments

Comments
 (0)