feat(app): a card browser to search, filter, sort and change many cards at once

Browse beside the flashcards' tab opens the studyset's cards over the
tabs (with everything inside it when it has sub-studysets), laid out as
the older design had it:
- a grid of tiles (each card's two sides) or one card at a time beside
  the list (on a phone above a strip of them, swiped through), as last
  left for the studyset on this device;
- a search over front, back, reading, meanings, hints, explanation and
  tag names, katakana found as hiragana and kana by romaji;
- sorting by own order, newest, oldest, A–Z (words by reading), due
  first; a filter sheet by kind, tag and state (new, learning, due,
  buried, reported);
- choosing cards (a toggle; shift-click or long-press for a range,
  select all) to move into another or a new studyset, add or remove
  tags, start afresh, or delete with Undo; the actions in the row on
  wide windows, in a bar at the foot below.

Moving cards between studysets is new in the card repository and its
gateway (studysetId and position written, named columns).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-09 14:21:01 +02:00
commit 42c57bd40a
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -4299,6 +4299,362 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get pomodoroTopBarDismiss => 'Don\'t suggest again';
@override
String get cardBrowserTitle => 'Flashcards';
@override
String cardBrowserTitleWithName(String title) {
return '$title — flashcards';
}
@override
String cardBrowserTitleSubtree(String title) {
return '$title (incl. sub-studysets)';
}
@override
String get cardBrowserBrowse => 'Browse';
@override
String get cardBrowserBrowseTooltip => 'Browse flashcards';
@override
String get cardBrowserStudy => 'Study';
@override
String get cardBrowserEditor => 'Editor';
@override
String get cardBrowserMore => 'More';
@override
String get cardBrowserImport => 'Import flashcards';
@override
String get cardBrowserGrid => 'Grid';
@override
String get cardBrowserDetail => 'Detail';
@override
String get cardBrowserSearch => 'Search';
@override
String get cardBrowserSort => 'Sort';
@override
String get cardBrowserFilter => 'Filter';
@override
String get cardBrowserSelect => 'Select';
@override
String get cardBrowserSortManual => 'Manual order';
@override
String get cardBrowserSortNewest => 'Newest first';
@override
String get cardBrowserSortOldest => 'Oldest first';
@override
String get cardBrowserSortAlphabetical => 'A–Z (front)';
@override
String get cardBrowserSortDue => 'Due first';
@override
String get cardBrowserSearchHint => 'Search flashcards';
@override
String get cardBrowserCloseSearch => 'Close search';
@override
String get cardBrowserClearQuery => 'Clear query';
@override
String get cardBrowserFilterTitle => 'Filter flashcards';
@override
String get cardBrowserFilterType => 'Type';
@override
String get cardBrowserTypeAll => 'All cards';
@override
String get cardBrowserTypeFrontBack => 'Q&A only';
@override
String get cardBrowserTypeMultipleChoice => 'Multiple-choice only';
@override
String get cardBrowserTypeVocabulary => 'Words only';
@override
String get cardBrowserTypeMatching => 'Matching only';
@override
String get cardBrowserTypeMap => 'Maps only';
@override
String get cardBrowserFilterTag => 'Tag';
@override
String get cardBrowserAllTags => 'All tags';
@override
String get cardBrowserFilterStatus => 'Status';
@override
String get cardBrowserStatusNew => 'New';
@override
String get cardBrowserStatusLearning => 'Learning';
@override
String get cardBrowserStatusDue => 'Due';
@override
String get cardBrowserStatusBuried => 'Buried';
@override
String get cardBrowserStatusReported => 'Reported';
@override
String get cardBrowserClearAll => 'Clear all';
@override
String get cardBrowserApply => 'Apply';
@override
String get cardBrowserEmptyTitle => 'No flashcards yet';
@override
String get cardBrowserEmptyHint => 'Create some to browse them here.';
@override
String get cardBrowserCreate => 'Create flashcards';
@override
String get cardBrowserNoMatches => 'No flashcards match';
@override
String get cardBrowserNoMatchesHint => 'Try a different search or filter.';
@override
String get cardBrowserClearFilters => 'Clear search & filters';
@override
String get cardBrowserRetry => 'Retry';
@override
String get cardBrowserPrevious => 'Previous';
@override
String get cardBrowserNext => 'Next';
@override
String get cardBrowserBuried => 'Buried';
@override
String get cardBrowserSelectAll => 'Select all';
@override
String get cardBrowserDeselectAll => 'Deselect all';
@override
String cardBrowserSelected(int count) {
return '$count selected';
}
@override
String get cardBrowserRangeHintTouch =>
'Long-press another card to select everything in between.';
@override
String get cardBrowserRangeHintPointer =>
'Shift-click another card to select everything in between.';
@override
String get cardBrowserMove => 'Move';
@override
String get cardBrowserAddTags => 'Add tags';
@override
String get cardBrowserRemoveTags => 'Remove tags';
@override
String get cardBrowserResetProgress => 'Reset progress';
@override
String get cardBrowserDelete => 'Delete';
@override
String get cardBrowserMoreActions => 'More actions';
@override
String get cardBrowserDone => 'Done';
@override
String cardBrowserDeleted(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards deleted',
one: '1 flashcard deleted',
);
return '$_temp0';
}
@override
String cardBrowserMoveTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Move $count flashcards to',
one: 'Move 1 flashcard to',
);
return '$_temp0';
}
@override
String cardBrowserMoved(int count, String title) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Moved $count flashcards to “$title”',
one: 'Moved 1 flashcard to “$title”',
);
return '$_temp0';
}
@override
String cardBrowserAddTagsTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Add tags to $count flashcards',
one: 'Add tags to 1 flashcard',
);
return '$_temp0';
}
@override
String cardBrowserAddTo(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Add to $count flashcards',
one: 'Add to 1 flashcard',
);
return '$_temp0';
}
@override
String cardBrowserRemoveTagsTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Remove tags from $count flashcards',
one: 'Remove tags from 1 flashcard',
);
return '$_temp0';
}
@override
String cardBrowserRemoveFrom(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Remove from $count flashcards',
one: 'Remove from 1 flashcard',
);
return '$_temp0';
}
@override
String get cardBrowserNoTags =>
'No tags yet. Create tags from a flashcard\'s editor, then apply them here.';
@override
String get cardBrowserNoTagsOnCards => 'The flashcards chosen have no tags.';
@override
String cardBrowserTagsAdded(int tags, int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards',
one: '1 flashcard',
);
String _temp1 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards',
one: '1 flashcard',
);
String _temp2 = intl.Intl.pluralLogic(
tags,
locale: localeName,
other: 'Added $tags tags to $_temp0',
one: 'Added 1 tag to $_temp1',
);
return '$_temp2';
}
@override
String cardBrowserTagsRemoved(int tags, int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards',
one: '1 flashcard',
);
String _temp1 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards',
one: '1 flashcard',
);
String _temp2 = intl.Intl.pluralLogic(
tags,
locale: localeName,
other: 'Removed $tags tags from $_temp0',
one: 'Removed 1 tag from $_temp1',
);
return '$_temp2';
}
@override
String cardBrowserResetTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Start $count flashcards afresh?',
one: 'Start 1 flashcard afresh?',
);
return '$_temp0';
}
@override
String get cardBrowserResetMessage =>
'They count as new again. Their reviews stay in your history and streaks.';
@override
String get cardBrowserResetConfirm => 'Reset';
@override
String cardBrowserReset(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards start afresh',
one: '1 flashcard starts afresh',
);
return '$_temp0';
}
}
/// The translations for English, as used in the United Kingdom (`en_GB`).