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

@ -4332,4 +4332,363 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get pomodoroTopBarDismiss => 'Nicht mehr vorschlagen';
@override
String get cardBrowserTitle => 'Karteikarten';
@override
String cardBrowserTitleWithName(String title) {
return '$title – Karteikarten';
}
@override
String cardBrowserTitleSubtree(String title) {
return '$title (mit Unter-Lernsets)';
}
@override
String get cardBrowserBrowse => 'Durchsuchen';
@override
String get cardBrowserBrowseTooltip => 'Karteikarten durchsuchen';
@override
String get cardBrowserStudy => 'Lernen';
@override
String get cardBrowserEditor => 'Editor';
@override
String get cardBrowserMore => 'Mehr';
@override
String get cardBrowserImport => 'Karteikarten importieren';
@override
String get cardBrowserGrid => 'Raster';
@override
String get cardBrowserDetail => 'Detail';
@override
String get cardBrowserSearch => 'Suchen';
@override
String get cardBrowserSort => 'Sortieren';
@override
String get cardBrowserFilter => 'Filtern';
@override
String get cardBrowserSelect => 'Auswählen';
@override
String get cardBrowserSortManual => 'Eigene Reihenfolge';
@override
String get cardBrowserSortNewest => 'Neueste zuerst';
@override
String get cardBrowserSortOldest => 'Älteste zuerst';
@override
String get cardBrowserSortAlphabetical => 'A–Z (Vorderseite)';
@override
String get cardBrowserSortDue => 'Fällige zuerst';
@override
String get cardBrowserSearchHint => 'Karteikarten durchsuchen';
@override
String get cardBrowserCloseSearch => 'Suche schließen';
@override
String get cardBrowserClearQuery => 'Suche leeren';
@override
String get cardBrowserFilterTitle => 'Karteikarten filtern';
@override
String get cardBrowserFilterType => 'Art';
@override
String get cardBrowserTypeAll => 'Alle Karten';
@override
String get cardBrowserTypeFrontBack => 'Nur Frage und Antwort';
@override
String get cardBrowserTypeMultipleChoice => 'Nur Multiple Choice';
@override
String get cardBrowserTypeVocabulary => 'Nur Wörter';
@override
String get cardBrowserTypeMatching => 'Nur Zuordnungen';
@override
String get cardBrowserTypeMap => 'Nur Karten';
@override
String get cardBrowserFilterTag => 'Tag';
@override
String get cardBrowserAllTags => 'Alle Tags';
@override
String get cardBrowserFilterStatus => 'Stand';
@override
String get cardBrowserStatusNew => 'Neu';
@override
String get cardBrowserStatusLearning => 'Im Lernen';
@override
String get cardBrowserStatusDue => 'Fällig';
@override
String get cardBrowserStatusBuried => 'Zurückgestellt';
@override
String get cardBrowserStatusReported => 'Gemeldet';
@override
String get cardBrowserClearAll => 'Alle zurücksetzen';
@override
String get cardBrowserApply => 'Anwenden';
@override
String get cardBrowserEmptyTitle => 'Noch keine Karteikarten';
@override
String get cardBrowserEmptyHint =>
'Erstelle welche, um sie hier zu durchsuchen.';
@override
String get cardBrowserCreate => 'Karteikarten erstellen';
@override
String get cardBrowserNoMatches => 'Keine Karteikarte passt';
@override
String get cardBrowserNoMatchesHint =>
'Versuche eine andere Suche oder einen anderen Filter.';
@override
String get cardBrowserClearFilters => 'Suche und Filter zurücksetzen';
@override
String get cardBrowserRetry => 'Erneut versuchen';
@override
String get cardBrowserPrevious => 'Vorige';
@override
String get cardBrowserNext => 'Nächste';
@override
String get cardBrowserBuried => 'Zurückgestellt';
@override
String get cardBrowserSelectAll => 'Alle auswählen';
@override
String get cardBrowserDeselectAll => 'Auswahl aufheben';
@override
String cardBrowserSelected(int count) {
return '$count ausgewählt';
}
@override
String get cardBrowserRangeHintTouch =>
'Halte eine andere Karte gedrückt, um alles dazwischen auszuwählen.';
@override
String get cardBrowserRangeHintPointer =>
'Klicke mit gedrückter Umschalttaste auf eine andere Karte, um alles dazwischen auszuwählen.';
@override
String get cardBrowserMove => 'Verschieben';
@override
String get cardBrowserAddTags => 'Tags hinzufügen';
@override
String get cardBrowserRemoveTags => 'Tags entfernen';
@override
String get cardBrowserResetProgress => 'Fortschritt zurücksetzen';
@override
String get cardBrowserDelete => 'Löschen';
@override
String get cardBrowserMoreActions => 'Weitere Aktionen';
@override
String get cardBrowserDone => 'Fertig';
@override
String cardBrowserDeleted(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten gelöscht',
one: '1 Karteikarte gelöscht',
);
return '$_temp0';
}
@override
String cardBrowserMoveTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten verschieben nach',
one: '1 Karteikarte verschieben nach',
);
return '$_temp0';
}
@override
String cardBrowserMoved(int count, String title) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten nach „$title“ verschoben',
one: '1 Karteikarte nach „$title“ verschoben',
);
return '$_temp0';
}
@override
String cardBrowserAddTagsTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Tags zu $count Karteikarten hinzufügen',
one: 'Tags zu 1 Karteikarte hinzufügen',
);
return '$_temp0';
}
@override
String cardBrowserAddTo(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Zu $count Karteikarten hinzufügen',
one: 'Zu 1 Karteikarte hinzufügen',
);
return '$_temp0';
}
@override
String cardBrowserRemoveTagsTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Tags von $count Karteikarten entfernen',
one: 'Tags von 1 Karteikarte entfernen',
);
return '$_temp0';
}
@override
String cardBrowserRemoveFrom(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Von $count Karteikarten entfernen',
one: 'Von 1 Karteikarte entfernen',
);
return '$_temp0';
}
@override
String get cardBrowserNoTags =>
'Noch keine Tags. Erstelle Tags im Editor einer Karteikarte und weise sie dann hier zu.';
@override
String get cardBrowserNoTagsOnCards =>
'Die ausgewählten Karteikarten haben keine Tags.';
@override
String cardBrowserTagsAdded(int tags, int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten',
one: '1 Karteikarte',
);
String _temp1 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten',
one: '1 Karteikarte',
);
String _temp2 = intl.Intl.pluralLogic(
tags,
locale: localeName,
other: '$tags Tags zu $_temp0 hinzugefügt',
one: '1 Tag zu $_temp1 hinzugefügt',
);
return '$_temp2';
}
@override
String cardBrowserTagsRemoved(int tags, int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten',
one: '1 Karteikarte',
);
String _temp1 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten',
one: '1 Karteikarte',
);
String _temp2 = intl.Intl.pluralLogic(
tags,
locale: localeName,
other: '$tags Tags von $_temp0 entfernt',
one: '1 Tag von $_temp1 entfernt',
);
return '$_temp2';
}
@override
String cardBrowserResetTitle(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten neu beginnen?',
one: '1 Karteikarte neu beginnen?',
);
return '$_temp0';
}
@override
String get cardBrowserResetMessage =>
'Sie gelten wieder als neu. Ihre Wiederholungen bleiben in deinem Verlauf und deinen Serien.';
@override
String get cardBrowserResetConfirm => 'Zurücksetzen';
@override
String cardBrowserReset(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten beginnen neu',
one: '1 Karteikarte beginnt neu',
);
return '$_temp0';
}
}