feat(learn): an assistant proposes flashcards from a text, a note or a PDF page

The cards come as drafts (ADR 0021, D10, D55): one question with one
tool, propose_cards, the cards in a sheet, every one chosen at first,
each changed in a small sheet of its own or left out, and only those
chosen added, marked as an assistant's (origin "assistant"). They are
proposed from a text pasted in Add material, from a note's title and
text, and from a PDF's page or the text selected on it, tied to that page
(D56). A note or a page of a private studyset goes only once agreed to
(D9), the text pasted counting as the person's own; nothing is offered
without an assistant. PDFs give their pages' text (PdfDocumentView.pageText).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-25 21:30:59 +01:00
commit cca10e855e
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
5 changed files with 1553 additions and 15 deletions

View file

@ -1873,6 +1873,19 @@
"studyTypedWhy": "Warum?",
"assistantWhyTyped": "Ich habe „{typed}“ getippt. Warum stimmt das nicht?",
"assistantCheck": "Auf Fehler prüfen",
"proposalsTitle": "Karteikarten von {name}",
"proposalsWriting": "{name} schreibt Karteikarten …",
"proposalsNone": "{name} hat keine Karteikarten vorgeschlagen.",
"proposalsCheck": "Prüf jede Karte, bevor du sie hinzufügst: Ein Assistent kann sich irren.",
"proposalsEdit": "Karteikarte bearbeiten",
"proposalsAdd": "{count, plural, =0{Karteikarten hinzufügen} =1{1 Karteikarte hinzufügen} other{{count} Karteikarten hinzufügen}}",
"proposalsAdded": "{count, plural, =1{1 Karteikarte hinzugefügt} other{{count} Karteikarten hinzugefügt}}",
"proposalsFromNote": "Karteikarten aus dieser Notiz",
"proposalsFromPage": "Aus dieser Seite",
"proposalsFromSelection": "Aus der Auswahl",
"proposalsFromText": "Karteikarten aus einem Text",
"proposalsTextHint": "Füg den Text ein, aus dem Karteikarten werden sollen",
"proposalsPropose": "Karteikarten vorschlagen",
"settingsSearchEngine": "Suchmaschine",
"searchEngineDevice": "Suche des Geräts",
"searchEngineCustom": "Eigene Adresse",

View file

@ -2211,6 +2211,29 @@
"@assistantWhyTyped": {"description": "The question an assistant is asked about a reading typed wrong.", "placeholders": {"typed": {"type": "String"}}},
"assistantCheck": "Check for mistakes",
"@assistantCheck": {"description": "Has an assistant check what was written in the field (D54)."},
"proposalsTitle": "Flashcards by {name}",
"@proposalsTitle": {"description": "The sheet of cards an assistant proposes (ADR 0021, D55).", "placeholders": {"name": {"type": "String"}}},
"proposalsWriting": "{name} is writing flashcards…",
"@proposalsWriting": {"placeholders": {"name": {"type": "String"}}},
"proposalsNone": "{name} proposed no flashcards.",
"@proposalsNone": {"placeholders": {"name": {"type": "String"}}},
"proposalsCheck": "Check each card before adding it: an assistant can be wrong.",
"proposalsEdit": "Edit flashcard",
"@proposalsEdit": {"description": "Changes a card proposed before it is added."},
"proposalsAdd": "{count, plural, =0{Add flashcards} =1{Add 1 flashcard} other{Add {count} flashcards}}",
"@proposalsAdd": {"placeholders": {"count": {"type": "int"}}},
"proposalsAdded": "{count, plural, =1{1 flashcard added} other{{count} flashcards added}}",
"@proposalsAdded": {"placeholders": {"count": {"type": "int"}}},
"proposalsFromNote": "Flashcards from this note",
"@proposalsFromNote": {"description": "Has an assistant propose cards from a note (D56)."},
"proposalsFromPage": "From this page",
"@proposalsFromPage": {"description": "In a PDF's flashcards: has an assistant propose cards from the page shown (D56)."},
"proposalsFromSelection": "From the selection",
"@proposalsFromSelection": {"description": "In a PDF's flashcards: has an assistant propose cards from the text selected (D56)."},
"proposalsFromText": "Flashcards from a text",
"@proposalsFromText": {"description": "Add material: has an assistant propose cards from text pasted (D56)."},
"proposalsTextHint": "Paste the text to make flashcards from",
"proposalsPropose": "Propose flashcards",
"settingsSearchEngine": "Search engine",
"searchEngineDevice": "The device's search",
"searchEngineCustom": "Your own address",

View file

@ -11060,6 +11060,84 @@ abstract class AppLocalizations {
/// **'Check for mistakes'**
String get assistantCheck;
/// The sheet of cards an assistant proposes (ADR 0021, D55).
///
/// In en, this message translates to:
/// **'Flashcards by {name}'**
String proposalsTitle(String name);
/// No description provided for @proposalsWriting.
///
/// In en, this message translates to:
/// **'{name} is writing flashcards…'**
String proposalsWriting(String name);
/// No description provided for @proposalsNone.
///
/// In en, this message translates to:
/// **'{name} proposed no flashcards.'**
String proposalsNone(String name);
/// No description provided for @proposalsCheck.
///
/// In en, this message translates to:
/// **'Check each card before adding it: an assistant can be wrong.'**
String get proposalsCheck;
/// Changes a card proposed before it is added.
///
/// In en, this message translates to:
/// **'Edit flashcard'**
String get proposalsEdit;
/// No description provided for @proposalsAdd.
///
/// In en, this message translates to:
/// **'{count, plural, =0{Add flashcards} =1{Add 1 flashcard} other{Add {count} flashcards}}'**
String proposalsAdd(int count);
/// No description provided for @proposalsAdded.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 flashcard added} other{{count} flashcards added}}'**
String proposalsAdded(int count);
/// Has an assistant propose cards from a note (D56).
///
/// In en, this message translates to:
/// **'Flashcards from this note'**
String get proposalsFromNote;
/// In a PDF's flashcards: has an assistant propose cards from the page shown (D56).
///
/// In en, this message translates to:
/// **'From this page'**
String get proposalsFromPage;
/// In a PDF's flashcards: has an assistant propose cards from the text selected (D56).
///
/// In en, this message translates to:
/// **'From the selection'**
String get proposalsFromSelection;
/// Add material: has an assistant propose cards from text pasted (D56).
///
/// In en, this message translates to:
/// **'Flashcards from a text'**
String get proposalsFromText;
/// No description provided for @proposalsTextHint.
///
/// In en, this message translates to:
/// **'Paste the text to make flashcards from'**
String get proposalsTextHint;
/// No description provided for @proposalsPropose.
///
/// In en, this message translates to:
/// **'Propose flashcards'**
String get proposalsPropose;
/// No description provided for @settingsSearchEngine.
///
/// In en, this message translates to:

View file

@ -6961,6 +6961,70 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get assistantCheck => 'Auf Fehler prüfen';
@override
String proposalsTitle(String name) {
return 'Karteikarten von $name';
}
@override
String proposalsWriting(String name) {
return '$name schreibt Karteikarten …';
}
@override
String proposalsNone(String name) {
return '$name hat keine Karteikarten vorgeschlagen.';
}
@override
String get proposalsCheck =>
'Prüf jede Karte, bevor du sie hinzufügst: Ein Assistent kann sich irren.';
@override
String get proposalsEdit => 'Karteikarte bearbeiten';
@override
String proposalsAdd(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten hinzufügen',
one: '1 Karteikarte hinzufügen',
zero: 'Karteikarten hinzufügen',
);
return '$_temp0';
}
@override
String proposalsAdded(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count Karteikarten hinzugefügt',
one: '1 Karteikarte hinzugefügt',
);
return '$_temp0';
}
@override
String get proposalsFromNote => 'Karteikarten aus dieser Notiz';
@override
String get proposalsFromPage => 'Aus dieser Seite';
@override
String get proposalsFromSelection => 'Aus der Auswahl';
@override
String get proposalsFromText => 'Karteikarten aus einem Text';
@override
String get proposalsTextHint =>
'Füg den Text ein, aus dem Karteikarten werden sollen';
@override
String get proposalsPropose => 'Karteikarten vorschlagen';
@override
String get settingsSearchEngine => 'Suchmaschine';

View file

@ -6897,6 +6897,69 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get assistantCheck => 'Check for mistakes';
@override
String proposalsTitle(String name) {
return 'Flashcards by $name';
}
@override
String proposalsWriting(String name) {
return '$name is writing flashcards…';
}
@override
String proposalsNone(String name) {
return '$name proposed no flashcards.';
}
@override
String get proposalsCheck =>
'Check each card before adding it: an assistant can be wrong.';
@override
String get proposalsEdit => 'Edit flashcard';
@override
String proposalsAdd(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Add $count flashcards',
one: 'Add 1 flashcard',
zero: 'Add flashcards',
);
return '$_temp0';
}
@override
String proposalsAdded(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count flashcards added',
one: '1 flashcard added',
);
return '$_temp0';
}
@override
String get proposalsFromNote => 'Flashcards from this note';
@override
String get proposalsFromPage => 'From this page';
@override
String get proposalsFromSelection => 'From the selection';
@override
String get proposalsFromText => 'Flashcards from a text';
@override
String get proposalsTextHint => 'Paste the text to make flashcards from';
@override
String get proposalsPropose => 'Propose flashcards';
@override
String get settingsSearchEngine => 'Search engine';