Skip to content

Commit f50f133

Browse files
committed
feat(card-browser): snackbar on sort type change
Prep for issue 17732 Assisted-by: Claude Ops 4.7
1 parent 8ce1058 commit f50f133

3 files changed

Lines changed: 62 additions & 0 deletions

File tree

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,22 @@ class CardBrowserFragment :
11221122
showDialogFragment(dialog)
11231123
}
11241124

1125+
/** Displays a snackbar: Sort by Card Type · A-Z*/
1126+
fun onSortTypeChanged(notification: SortChangeNotification) {
1127+
val (title, subtitle) =
1128+
when (notification) {
1129+
is SortChangeNotification.NoOrdering ->
1130+
getString(R.string.card_browser_order_no_sorting_title) to null
1131+
is SortChangeNotification.CollectionOrdering -> {
1132+
val subtitleRes = notification.type.humanReadableExplanation(descending = notification.reverse)
1133+
getString(R.string.card_browser_order_snackbar_sort_by, notification.columnLabel) to
1134+
subtitleRes?.let(::getString)
1135+
}
1136+
}
1137+
val text = if (subtitle != null) "$title · $subtitle" else title
1138+
showSnackbar(text, Snackbar.LENGTH_SHORT)
1139+
}
1140+
11251141
activityViewModel.flowOfReverseDirection.launchCollectionInLifecycleScope(::reverseDirectionChanged)
11261142
activityViewModel.flowOfIsTruncated.launchCollectionInLifecycleScope(::onIsTruncatedChanged)
11271143
activityViewModel.flowOfSelectedRows.launchCollectionInLifecycleScope(::onSelectedRowsChanged)
@@ -1144,6 +1160,7 @@ class CardBrowserFragment :
11441160
activityViewModel.searchRequestFlow.launchCollectionInLifecycleScope(::onSearchRequestUpdated)
11451161
activityViewModel.flowOfChangeNoteType.launchCollectionInLifecycleScope(::onChangeNoteType)
11461162
activityViewModel.flowOfSaveSearchNamePrompt.launchCollectionInLifecycleScope(::onSaveSearchNamePrompt)
1163+
activityViewModel.flowOfSortTypeChanged.launchCollectionInLifecycleScope(::onSortTypeChanged)
11471164
}
11481165

11491166
private fun setupFragmentResultListeners() {

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ class CardBrowserViewModel(
214214
*/
215215
val flowOfReverseDirection: MutableStateFlow<ReverseDirection?> = MutableStateFlow(null)
216216

217+
/** Emits each time the user changes the sort order, with data for a snackbar */
218+
val flowOfSortTypeChanged = MutableSharedFlow<SortChangeNotification>()
219+
217220
/**
218221
* A map from column backend key to backend column definition
219222
*
@@ -948,9 +951,31 @@ class CardBrowserViewModel(
948951
}
949952
}
950953

954+
flowOfSortTypeChanged.emit(buildSortChangeNotification(sortType))
955+
951956
launchSearchForCards()
952957
}
953958

959+
private fun buildSortChangeNotification(sortType: SortType): SortChangeNotification =
960+
when (sortType) {
961+
is SortType.NoOrdering -> SortChangeNotification.NoOrdering
962+
is SortType.CollectionOrdering -> {
963+
val columnLabel =
964+
flowOfAllColumns.value[sortType.key.value]?.getLabel(cardsOrNotes)
965+
?: sortType.key.value
966+
val type =
967+
runCatching { CardBrowserColumn.fromColumnKey(sortType.key.value) }
968+
.getOrNull()
969+
?.type(cardsOrNotes)
970+
?: ColumnType.UNSPECIFIED
971+
SortChangeNotification.CollectionOrdering(
972+
columnLabel = columnLabel,
973+
type = type,
974+
reverse = sortType.reverse,
975+
)
976+
}
977+
}
978+
954979
/**
955980
* Updates the backend with a new collection of columns
956981
*
@@ -1789,3 +1814,22 @@ data class ColumnHeading(
17891814
val label: String,
17901815
val ankiColumnKey: String,
17911816
) : Parcelable
1817+
1818+
/**
1819+
* Data needed to show a snackbar when the sort order is changed
1820+
*/
1821+
sealed interface SortChangeNotification {
1822+
/** [SortType.NoOrdering] was selected */
1823+
data object NoOrdering : SortChangeNotification
1824+
1825+
/**
1826+
* @param columnLabel The localized label for the column
1827+
* @param type The data type of the column. Used to explain the sort direction
1828+
* @param reverse Whether the sort is ascending/descending
1829+
*/
1830+
data class CollectionOrdering(
1831+
val columnLabel: String,
1832+
val type: ColumnType,
1833+
val reverse: Boolean,
1834+
) : SortChangeNotification
1835+
}

AnkiDroid/src/main/res/values/07-cardbrowser.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
<!-- Sort Order -->
9191
<string name="card_browser_order_no_sorting_title" comment="Title of the 'no sorting' row in the Choose Display Order bottom sheet">No sorting</string>
9292
<string name="card_browser_order_no_sorting_subtitle" comment="Subtitle for the 'no sorting' row noting that no-sort is faster than sorted queries">Faster</string>
93+
<string name="card_browser_order_snackbar_sort_by" comment="Snackbar shown after sort changes. %1$s is the column name (e.g. 'Card Type')">Sort by %1$s</string>
9394

9495
<string name="card_browser_order_subtitle_text_ascending" comment="Sort direction subtitle for text columns when ascending (A before Z)">A–Z</string>
9596
<string name="card_browser_order_subtitle_text_descending" comment="Sort direction subtitle for text columns when descending (Z before A)">Z–A</string>

0 commit comments

Comments
 (0)