feat(app): the dictionary in the app: look words up, add them as cards

A studyset's dictionary follows from its language, as decided: the
instance's dictionary of its front's language, with meanings in its
back's (else English). Nothing to attach or detach; nothing of it shows
where there is none.

- Add material › From the dictionary: search a word (kanji, kana,
  romaji, meaning) and add it as a flashcard, or add a whole level
  (JLPT N5…N1, common words) at once, asked first above 500 words, its
  progress shown. Words already in the studyset show as such and are
  left out. Each card is a vocabulary card (headword, reading, senses
  with their codes), tagged `jlpt-n5` and with its word class, and
  marked as imported from the dictionary.
- Look up beside a vocabulary card's front fills the card with the word
  chosen, keeping its hints, explanation and tags.
- A card keeps the dictionary entry it was made from (card schema 6:
  `dictionary` {source, id}), to be found again and not added twice.
- The dictionary's credits show at its foot and in About, as its licence
  asks.

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 01:33:12 +02:00
commit add1c76842
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -2944,6 +2944,144 @@ abstract class AppLocalizations {
/// **'Senses'**
String get cardSenses;
/// No description provided for @cardDictionaryEntry.
///
/// In en, this message translates to:
/// **'Dictionary entry'**
String get cardDictionaryEntry;
/// No description provided for @studysetFromDictionary.
///
/// In en, this message translates to:
/// **'From the dictionary'**
String get studysetFromDictionary;
/// No description provided for @dictionaryTitle.
///
/// In en, this message translates to:
/// **'Dictionary'**
String get dictionaryTitle;
/// No description provided for @dictionarySearchHint.
///
/// In en, this message translates to:
/// **'A word in kanji, kana or romaji, or a meaning'**
String get dictionarySearchHint;
/// No description provided for @dictionaryNothingFound.
///
/// In en, this message translates to:
/// **'Nothing found for “{query}”.'**
String dictionaryNothingFound(String query);
/// No description provided for @dictionaryUnreachable.
///
/// In en, this message translates to:
/// **'The dictionary can\'t be reached right now.'**
String get dictionaryUnreachable;
/// No description provided for @dictionaryRetry.
///
/// In en, this message translates to:
/// **'Retry'**
String get dictionaryRetry;
/// No description provided for @dictionaryAdd.
///
/// In en, this message translates to:
/// **'Add'**
String get dictionaryAdd;
/// No description provided for @dictionaryInStudyset.
///
/// In en, this message translates to:
/// **'In this studyset'**
String get dictionaryInStudyset;
/// No description provided for @dictionaryAdded.
///
/// In en, this message translates to:
/// **'Added “{word}”.'**
String dictionaryAdded(String word);
/// No description provided for @dictionaryLevels.
///
/// In en, this message translates to:
/// **'Add a whole level'**
String get dictionaryLevels;
/// No description provided for @dictionaryLevelsHint.
///
/// In en, this message translates to:
/// **'Every word of a level becomes a flashcard, in the order of the level\'s list, tagged with its level and word class. Words already in this studyset are left out.'**
String get dictionaryLevelsHint;
/// No description provided for @dictionaryLabelCommon.
///
/// In en, this message translates to:
/// **'Common'**
String get dictionaryLabelCommon;
/// No description provided for @dictionaryAddLevel.
///
/// In en, this message translates to:
/// **'{count, plural, =1{Add 1 word} other{Add {count} words}}'**
String dictionaryAddLevel(int count);
/// No description provided for @dictionaryAddingLevel.
///
/// In en, this message translates to:
/// **'Adding… {done} of {count}'**
String dictionaryAddingLevel(int done, int count);
/// No description provided for @dictionaryWordsAdded.
///
/// In en, this message translates to:
/// **'{count, plural, =0{No new words.} =1{Added 1 word.} other{Added {count} words.}}'**
String dictionaryWordsAdded(int count);
/// No description provided for @dictionaryWordsSkipped.
///
/// In en, this message translates to:
/// **'{count, plural, =1{1 was in this studyset already.} other{{count} were in this studyset already.}}'**
String dictionaryWordsSkipped(int count);
/// No description provided for @dictionaryConfirmTitle.
///
/// In en, this message translates to:
/// **'Add {count} words?'**
String dictionaryConfirmTitle(int count);
/// No description provided for @dictionaryConfirmMessage.
///
/// In en, this message translates to:
/// **'Each becomes a flashcard in this studyset.'**
String get dictionaryConfirmMessage;
/// No description provided for @dictionaryConfirmAdd.
///
/// In en, this message translates to:
/// **'Add'**
String get dictionaryConfirmAdd;
/// No description provided for @dictionaryCredits.
///
/// In en, this message translates to:
/// **'Words from {sources}.'**
String dictionaryCredits(String sources);
/// No description provided for @dictionaryLookUp.
///
/// In en, this message translates to:
/// **'Look up in the dictionary'**
String get dictionaryLookUp;
/// No description provided for @aboutDictionaries.
///
/// In en, this message translates to:
/// **'Dictionaries on this instance'**
String get aboutDictionaries;
/// No description provided for @cardReportTitle.
///
/// In en, this message translates to: