feat(todo): filters in Todoist's language, and a view of each label (ADR 0033, D35)

A filter is a query read on the device, as the server sees no task, kept
sealed in `saved_filter`. Filters & labels is a screen of its own under
Browse; a label opens its tasks, and favourite filters and labels join
Browse's Favourites. D36 records what of Todoist's Pro stays out.

Whats-New: Filters: keep views like "today & p1", and open a label to see its tasks, under Browse in Filters & labels.
Whats-New-De: Filter: Speichere Ansichten wie „heute & p1“ und öffne ein Label, um seine Aufgaben zu sehen, in der Übersicht unter Filter & Labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-06 19:44:46 +01:00
commit b1f2078357
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
5 changed files with 21688 additions and 71 deletions

View file

@ -31,6 +31,30 @@
"deadlineOn": "Frist {day}",
"deadlineNone": "Keine Frist",
"keysMissing": "Dieses Gerät kann nichts speichern: Es hat die Schlüssel deines Kontos nicht. Melde dich mit deinem Passwort oder deiner Wiederherstellungsphrase an, um sie hinzuzufügen.",
"filtersLabelsTitle": "Filter & Labels",
"filtersLabelsHint": "Gespeicherte Ansichten deiner Aufgaben",
"filtersTitle": "Meine Filter",
"filtersNone": "Noch keine Filter.",
"filterAdd": "Neuer Filter",
"filterEdit": "Filter bearbeiten",
"filterDelete": "Filter löschen",
"filterDeleteTitle": "Filter löschen?",
"filterName": "Name",
"filterDescription": "Beschreibung",
"filterQuery": "Abfrage",
"filterQueryHint": "heute & p1",
"filterFavorite": "Zu Favoriten hinzufügen",
"filterUnfavorite": "Aus Favoriten entfernen",
"filterPreviewEmpty": "Noch passt nichts.",
"filterNothing": "Gerade sind keine Aufgaben in diesem Filter.",
"filterHelp": "heute, morgen, überfällig, ohne datum, 7 tage, p1 bis p4, #Projekt, ##Projekt mit Unterprojekten, /Abschnitt, @label, suche: Wort. Verbinde sie mit & (und), | (oder), ! (nicht) und Klammern; * steht für Beliebiges in einem Namen.",
"filterMenu": "Filtermenü",
"labelMenu": "Labelmenü",
"labelNothing": "Keine offene Aufgabe hat dieses Label.",
"labelEditEntry": "Label bearbeiten",
"filterMatches": "{count, plural, =1{1 Aufgabe passt} other{{count} Aufgaben passen}}",
"filterNotRead": "Nicht verstanden bei „{near}“",
"filterNotReadEnd": "Die Abfrage endet zu früh",
"labelsTitle": "Labels",
"labelsNone": "Noch keine Labels.",
"labelsNoneSet": "Keine Labels",

View file

@ -72,6 +72,49 @@
},
"deadlineNone": "No deadline",
"keysMissing": "This device can't save: it doesn't hold your account's keys. Sign in with your password or recovery phrase to add them.",
"filtersLabelsTitle": "Filters & labels",
"filtersLabelsHint": "Views of your tasks, kept",
"filtersTitle": "My filters",
"filtersNone": "No filters yet.",
"filterAdd": "New filter",
"filterEdit": "Edit filter",
"filterDelete": "Delete filter",
"filterDeleteTitle": "Delete the filter?",
"filterName": "Name",
"filterDescription": "Description",
"filterQuery": "Query",
"filterQueryHint": "today & p1",
"filterFavorite": "Add to favourites",
"filterUnfavorite": "Remove from favourites",
"filterPreviewEmpty": "Nothing matches yet.",
"filterNothing": "No tasks in this filter at the moment.",
"filterHelp": "today, tomorrow, overdue, no date, 7 days, p1 to p4, #Project, ##Project with its sub-projects, /Section, @label, search: word. Combine them with & (and), | (or), ! (not) and parentheses; * stands for anything in a name.",
"filterMenu": "Filter menu",
"labelMenu": "Label menu",
"labelNothing": "No open tasks have this label.",
"labelEditEntry": "Edit label",
"filterMatches": "{count, plural, =1{1 task matches} other{{count} tasks match}}",
"@filterMatches": {
"description": "The filter editor's preview.",
"placeholders": {
"count": {
"type": "int"
}
}
},
"filterNotRead": "Not understood near “{near}”",
"@filterNotRead": {
"description": "The filter editor when its query cannot be read.",
"placeholders": {
"near": {
"type": "String"
}
}
},
"filterNotReadEnd": "This query ends too soon",
"@filterNotReadEnd": {
"description": "The filter editor when its query stops before it is complete."
},
"labelsTitle": "Labels",
"labelsNone": "No labels yet.",
"labelsNoneSet": "No labels",

View file

@ -286,6 +286,150 @@ abstract class AppLocalizations {
/// **'This device can\'t save: it doesn\'t hold your account\'s keys. Sign in with your password or recovery phrase to add them.'**
String get keysMissing;
/// No description provided for @filtersLabelsTitle.
///
/// In en, this message translates to:
/// **'Filters & labels'**
String get filtersLabelsTitle;
/// No description provided for @filtersLabelsHint.
///
/// In en, this message translates to:
/// **'Views of your tasks, kept'**
String get filtersLabelsHint;
/// No description provided for @filtersTitle.
///
/// In en, this message translates to:
/// **'My filters'**
String get filtersTitle;
/// No description provided for @filtersNone.
///
/// In en, this message translates to:
/// **'No filters yet.'**
String get filtersNone;
/// No description provided for @filterAdd.
///
/// In en, this message translates to:
/// **'New filter'**
String get filterAdd;
/// No description provided for @filterEdit.
///
/// In en, this message translates to:
/// **'Edit filter'**
String get filterEdit;
/// No description provided for @filterDelete.
///
/// In en, this message translates to:
/// **'Delete filter'**
String get filterDelete;
/// No description provided for @filterDeleteTitle.
///
/// In en, this message translates to:
/// **'Delete the filter?'**
String get filterDeleteTitle;
/// No description provided for @filterName.
///
/// In en, this message translates to:
/// **'Name'**
String get filterName;
/// No description provided for @filterDescription.
///
/// In en, this message translates to:
/// **'Description'**
String get filterDescription;
/// No description provided for @filterQuery.
///
/// In en, this message translates to:
/// **'Query'**
String get filterQuery;
/// No description provided for @filterQueryHint.
///
/// In en, this message translates to:
/// **'today & p1'**
String get filterQueryHint;
/// No description provided for @filterFavorite.
///
/// In en, this message translates to:
/// **'Add to favourites'**
String get filterFavorite;
/// No description provided for @filterUnfavorite.
///
/// In en, this message translates to:
/// **'Remove from favourites'**
String get filterUnfavorite;
/// No description provided for @filterPreviewEmpty.
///
/// In en, this message translates to:
/// **'Nothing matches yet.'**
String get filterPreviewEmpty;
/// No description provided for @filterNothing.
///
/// In en, this message translates to:
/// **'No tasks in this filter at the moment.'**
String get filterNothing;
/// No description provided for @filterHelp.
///
/// In en, this message translates to:
/// **'today, tomorrow, overdue, no date, 7 days, p1 to p4, #Project, ##Project with its sub-projects, /Section, @label, search: word. Combine them with & (and), | (or), ! (not) and parentheses; * stands for anything in a name.'**
String get filterHelp;
/// No description provided for @filterMenu.
///
/// In en, this message translates to:
/// **'Filter menu'**
String get filterMenu;
/// No description provided for @labelMenu.
///
/// In en, this message translates to:
/// **'Label menu'**
String get labelMenu;
/// No description provided for @labelNothing.
///
/// In en, this message translates to:
/// **'No open tasks have this label.'**
String get labelNothing;
/// No description provided for @labelEditEntry.
///
/// In en, this message translates to:
/// **'Edit label'**
String get labelEditEntry;
/// The filter editor's preview.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 task matches} other{{count} tasks match}}'**
String filterMatches(int count);
/// The filter editor when its query cannot be read.
///
/// In en, this message translates to:
/// **'Not understood near “{near}”'**
String filterNotRead(String near);
/// The filter editor when its query stops before it is complete.
///
/// In en, this message translates to:
/// **'This query ends too soon'**
String get filterNotReadEnd;
/// No description provided for @labelsTitle.
///
/// In en, this message translates to:

View file

@ -120,6 +120,89 @@ class AppLocalizationsDe extends AppLocalizations {
String get keysMissing =>
'Dieses Gerät kann nichts speichern: Es hat die Schlüssel deines Kontos nicht. Melde dich mit deinem Passwort oder deiner Wiederherstellungsphrase an, um sie hinzuzufügen.';
@override
String get filtersLabelsTitle => 'Filter & Labels';
@override
String get filtersLabelsHint => 'Gespeicherte Ansichten deiner Aufgaben';
@override
String get filtersTitle => 'Meine Filter';
@override
String get filtersNone => 'Noch keine Filter.';
@override
String get filterAdd => 'Neuer Filter';
@override
String get filterEdit => 'Filter bearbeiten';
@override
String get filterDelete => 'Filter löschen';
@override
String get filterDeleteTitle => 'Filter löschen?';
@override
String get filterName => 'Name';
@override
String get filterDescription => 'Beschreibung';
@override
String get filterQuery => 'Abfrage';
@override
String get filterQueryHint => 'heute & p1';
@override
String get filterFavorite => 'Zu Favoriten hinzufügen';
@override
String get filterUnfavorite => 'Aus Favoriten entfernen';
@override
String get filterPreviewEmpty => 'Noch passt nichts.';
@override
String get filterNothing => 'Gerade sind keine Aufgaben in diesem Filter.';
@override
String get filterHelp =>
'heute, morgen, überfällig, ohne datum, 7 tage, p1 bis p4, #Projekt, ##Projekt mit Unterprojekten, /Abschnitt, @label, suche: Wort. Verbinde sie mit & (und), | (oder), ! (nicht) und Klammern; * steht für Beliebiges in einem Namen.';
@override
String get filterMenu => 'Filtermenü';
@override
String get labelMenu => 'Labelmenü';
@override
String get labelNothing => 'Keine offene Aufgabe hat dieses Label.';
@override
String get labelEditEntry => 'Label bearbeiten';
@override
String filterMatches(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Aufgaben passen',
one: '1 Aufgabe passt',
);
return '$_temp0';
}
@override
String filterNotRead(String near) {
return 'Nicht verstanden bei „$near“';
}
@override
String get filterNotReadEnd => 'Die Abfrage endet zu früh';
@override
String get labelsTitle => 'Labels';

View file

@ -120,6 +120,89 @@ class AppLocalizationsEn extends AppLocalizations {
String get keysMissing =>
'This device can\'t save: it doesn\'t hold your account\'s keys. Sign in with your password or recovery phrase to add them.';
@override
String get filtersLabelsTitle => 'Filters & labels';
@override
String get filtersLabelsHint => 'Views of your tasks, kept';
@override
String get filtersTitle => 'My filters';
@override
String get filtersNone => 'No filters yet.';
@override
String get filterAdd => 'New filter';
@override
String get filterEdit => 'Edit filter';
@override
String get filterDelete => 'Delete filter';
@override
String get filterDeleteTitle => 'Delete the filter?';
@override
String get filterName => 'Name';
@override
String get filterDescription => 'Description';
@override
String get filterQuery => 'Query';
@override
String get filterQueryHint => 'today & p1';
@override
String get filterFavorite => 'Add to favourites';
@override
String get filterUnfavorite => 'Remove from favourites';
@override
String get filterPreviewEmpty => 'Nothing matches yet.';
@override
String get filterNothing => 'No tasks in this filter at the moment.';
@override
String get filterHelp =>
'today, tomorrow, overdue, no date, 7 days, p1 to p4, #Project, ##Project with its sub-projects, /Section, @label, search: word. Combine them with & (and), | (or), ! (not) and parentheses; * stands for anything in a name.';
@override
String get filterMenu => 'Filter menu';
@override
String get labelMenu => 'Label menu';
@override
String get labelNothing => 'No open tasks have this label.';
@override
String get labelEditEntry => 'Edit label';
@override
String filterMatches(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count tasks match',
one: '1 task matches',
);
return '$_temp0';
}
@override
String filterNotRead(String near) {
return 'Not understood near “$near”';
}
@override
String get filterNotReadEnd => 'This query ends too soon';
@override
String get labelsTitle => 'Labels';