Skip to content

Commit a11ecfa

Browse files
committed
refactor(card-browser): inline formatCardCount
* move properties from 'SearchResultMessage' to 'SearchState.Completed' * meaning we can format '0 cards shown' * so make it an extension method Assisted-by: Claude Opus 4.7 - implementation
1 parent 9c8bda9 commit a11ecfa

4 files changed

Lines changed: 24 additions & 28 deletions

File tree

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

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -521,9 +521,7 @@ open class CardBrowser :
521521
}
522522
}
523523
is SearchState.Completed -> {
524-
Timber.i("CardBrowser:: Completed searchCards() Successfully")
525-
// TODO: obtain these values from 'Completed'
526-
findViewById<TextView>(R.id.subtitle)?.text = formatCardCount(viewModel.rowCount, viewModel.cardsOrNotes)
524+
findViewById<TextView>(R.id.subtitle)?.text = searchState.formatCardCount(resources)
527525
// HACK: required now we use MenuProvider for searches
528526
// this causes a very brief flicker, as we call `setQuery` to restore the menu state
529527
searchView?.post { searchView?.clearFocus() }
@@ -824,19 +822,6 @@ open class CardBrowser :
824822
}
825823
}
826824

827-
fun formatCardCount(
828-
count: Int,
829-
cardsOrNotes: CardsOrNotes,
830-
): String {
831-
@androidx.annotation.StringRes val subtitleId =
832-
if (cardsOrNotes == CARDS) {
833-
R.plurals.card_browser_subtitle
834-
} else {
835-
R.plurals.card_browser_subtitle_notes_mode
836-
}
837-
return resources.getQuantityString(subtitleId, count, count)
838-
}
839-
840825
@RustCleanup("this isn't how Desktop Anki does it")
841826
override fun onSelectedTags(
842827
selectedTags: List<String>,
@@ -992,3 +977,11 @@ suspend fun searchForRows(
992977
}.let { ids ->
993978
BrowserRowCollection(cardsOrNotes, ids.map { CardOrNoteId(it) }.toMutableList())
994979
}
980+
981+
/** Renders the row count for [this] event as a localized "X cards/notes" string. */
982+
fun SearchState.Completed.formatCardCount(resources: android.content.res.Resources): String =
983+
resources.getQuantityString(
984+
if (cardsOrNotes == CARDS) R.plurals.card_browser_subtitle else R.plurals.card_browser_subtitle_notes_mode,
985+
rowCount,
986+
rowCount,
987+
)

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import com.ichi2.anki.dialogs.tags.TagsDialogFactory
114114
import com.ichi2.anki.dialogs.tags.TagsDialogListener
115115
import com.ichi2.anki.export.ExportDialogFragment
116116
import com.ichi2.anki.filtered.FilteredDeckOptionsFragment
117+
import com.ichi2.anki.formatCardCount
117118
import com.ichi2.anki.launchCatchingTask
118119
import com.ichi2.anki.libanki.DeckId
119120
import com.ichi2.anki.libanki.undoAvailable
@@ -849,7 +850,7 @@ class CardBrowserFragment :
849850
}
850851
}
851852

852-
fun onSearchResultMessage(result: SearchResultMessage) {
853+
fun onSearchCompleted(state: SearchState.Completed) {
853854
val activity = requireCardBrowserActivity()
854855

855856
// #3592: show the number of cards found the number of cards is not visible in the menu
@@ -869,10 +870,10 @@ class CardBrowserFragment :
869870
}
870871
}
871872

872-
when (result) {
873+
when (val result = state.resultMessage) {
873874
is SearchResultMessage.CardCount ->
874875
showSnackbar(
875-
message = activity.formatCardCount(result.count, result.cardsOrNotes),
876+
message = state.formatCardCount(resources),
876877
searchAllDecks = result.includeSearchAllDecksAction,
877878
)
878879
SearchResultMessage.NoCardsInSelectedDeck ->
@@ -887,7 +888,7 @@ class CardBrowserFragment :
887888
cardsAdapter.notifyDataSetChanged()
888889
progressIndicator.isVisible = searchState == Initializing || searchState == Searching
889890
if (searchState is SearchState.Completed) {
890-
onSearchResultMessage(searchState.resultMessage)
891+
onSearchCompleted(searchState)
891892
invalidateMenu()
892893
}
893894
}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ class CardBrowserViewModel(
180180
sealed interface SearchResultMessage {
181181
/** "X cards/notes shown | Search all decks" */
182182
data class CardCount(
183-
val count: Int,
184-
val cardsOrNotes: CardsOrNotes,
185183
val includeSearchAllDecksAction: Boolean,
186184
) : SearchResultMessage
187185

@@ -1511,12 +1509,14 @@ class CardBrowserViewModel(
15111509
/** Builds a [SearchState.Completed] event reflecting the current ViewModel state. */
15121510
private fun SearchState.Completed.Companion.fromCurrentState(): SearchState.Completed =
15131511
SearchState.Completed(
1512+
rowCount = rowCount,
1513+
cardsOrNotes = cardsOrNotes,
15141514
resultMessage =
15151515
when {
15161516
// TODO: better message if rowCount == 0 AND hasSelectedAllDecks
1517-
hasSelectedAllDecks() -> SearchResultMessage.CardCount(rowCount, cardsOrNotes, includeSearchAllDecksAction = false)
1517+
hasSelectedAllDecks() -> SearchResultMessage.CardCount(includeSearchAllDecksAction = false)
15181518
rowCount == 0 -> SearchResultMessage.NoCardsInSelectedDeck
1519-
else -> SearchResultMessage.CardCount(rowCount, cardsOrNotes, includeSearchAllDecksAction = true)
1519+
else -> SearchResultMessage.CardCount(includeSearchAllDecksAction = true)
15201520
},
15211521
)
15221522

@@ -1637,6 +1637,8 @@ class CardBrowserViewModel(
16371637

16381638
/** A search has been completed */
16391639
data class Completed(
1640+
val rowCount: Int,
1641+
val cardsOrNotes: CardsOrNotes,
16401642
val resultMessage: SearchResultMessage,
16411643
) : SearchState {
16421644
companion object

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,10 +1538,10 @@ class CardBrowserViewModelTest : JvmTest() {
15381538
flowOfSearchState.test {
15391539
ignoreEventsDuringViewModelInit()
15401540
setSelectedDeck(SelectableDeck.AllDecks)
1541-
val message = awaitSearchCompleted().resultMessage
1542-
val card = message as CardBrowserViewModel.SearchResultMessage.CardCount
1543-
assertThat("count", card.count, equalTo(3))
1544-
assertThat("cardsOrNotes", card.cardsOrNotes, equalTo(CardsOrNotes.CARDS))
1541+
val completed = awaitSearchCompleted()
1542+
val card = completed.resultMessage as CardBrowserViewModel.SearchResultMessage.CardCount
1543+
assertThat("count", completed.rowCount, equalTo(3))
1544+
assertThat("cardsOrNotes", completed.cardsOrNotes, equalTo(CardsOrNotes.CARDS))
15451545
assertThat("no all-decks action when already on all decks", card.includeSearchAllDecksAction, equalTo(false))
15461546
}
15471547
}

0 commit comments

Comments
 (0)