feat(app): study with faces on the ratings, centred cards and the session's figures

The study session, reworked:

- Ratings are coloured tiles with a face each (frown, meh, smile,
  laugh), when the card comes back below them with a clock ("in 1
  min", "in 3 days"), always shown, so a card can be rated without
  revealing it; at most 540 dp wide, centred.
- Cards are centred in a section card: the question large, then a line
  with 24 dp on either side and the answer a size smaller, or "Show
  answer" 40 dp below; a tap anywhere on the card shows or hides the
  answer. Read-only rich text takes a text style and an alignment.
- Words show their reading small above the expression once answered,
  and several meanings numbered.
- Choice, matching and map cards: Check below the card, the ratings in
  its place once checked; options marked before their text; matching
  lists the categories first, then what is left to place; the map
  fills the card with one caption below it.
- Header and progress on a band of their own; title start-aligned,
  the Pomodoro timer only to watch, the back-first toggle in every
  state; leaving a round under way asks first.
- Cramming goes round the round; back is there with two cards or more,
  skipping always.
- The end of a round: the cards done of those due, accuracy (OK counts
  half) and time, over the whole session.

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-07 17:40:32 +02:00
commit 369ce4ade1
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -2650,6 +2650,72 @@ abstract class AppLocalizations {
/// **'Check'**
String get studyCheck;
/// No description provided for @studySelectAll.
///
/// In en, this message translates to:
/// **'Select all that apply'**
String get studySelectAll;
/// No description provided for @studySelectOne.
///
/// In en, this message translates to:
/// **'Select the correct answer'**
String get studySelectOne;
/// No description provided for @studyMatchingInstructions.
///
/// In en, this message translates to:
/// **'DRAG AND DROP ONTO CARDS ABOVE'**
String get studyMatchingInstructions;
/// No description provided for @studyMatchingAllPlaced.
///
/// In en, this message translates to:
/// **'All placed'**
String get studyMatchingAllPlaced;
/// No description provided for @studyMatchingDropHere.
///
/// In en, this message translates to:
/// **'Drop here'**
String get studyMatchingDropHere;
/// No description provided for @studyMapTapPrompt.
///
/// In en, this message translates to:
/// **'Tap a region to answer'**
String get studyMapTapPrompt;
/// No description provided for @studyMapSelected.
///
/// In en, this message translates to:
/// **'Selected: {label}'**
String studyMapSelected(String label);
/// No description provided for @studyCorrect.
///
/// In en, this message translates to:
/// **'Correct'**
String get studyCorrect;
/// No description provided for @studyCorrectLabel.
///
/// In en, this message translates to:
/// **'Correct — {label}'**
String studyCorrectLabel(String label);
/// No description provided for @studyMapAnswer.
///
/// In en, this message translates to:
/// **'Answer: {answer}'**
String studyMapAnswer(String answer);
/// No description provided for @studyMapPickedAnswer.
///
/// In en, this message translates to:
/// **'You picked {picked} · Answer: {answer}'**
String studyMapPickedAnswer(String picked, String answer);
/// No description provided for @studyRatingBad.
///
/// In en, this message translates to:
@ -2698,11 +2764,119 @@ abstract class AppLocalizations {
/// **'Done'**
String get studyDone;
/// No description provided for @studyRoundDone.
/// No description provided for @studySessionComplete.
///
/// In en, this message translates to:
/// **'Round complete'**
String get studyRoundDone;
/// **'Session complete'**
String get studySessionComplete;
/// No description provided for @studyProgressReviewed.
///
/// In en, this message translates to:
/// **'{reviewed} / {total} reviewed'**
String studyProgressReviewed(int reviewed, int total);
/// No description provided for @studyReviewedCount.
///
/// In en, this message translates to:
/// **'{reviewed} reviewed'**
String studyReviewedCount(int reviewed);
/// No description provided for @studyStatCards.
///
/// In en, this message translates to:
/// **'Cards'**
String get studyStatCards;
/// No description provided for @studyStatAccuracy.
///
/// In en, this message translates to:
/// **'Accuracy'**
String get studyStatAccuracy;
/// No description provided for @studyStatTime.
///
/// In en, this message translates to:
/// **'Time'**
String get studyStatTime;
/// No description provided for @studyDurationSec.
///
/// In en, this message translates to:
/// **'{sec} sec'**
String studyDurationSec(int sec);
/// No description provided for @studyDurationMin.
///
/// In en, this message translates to:
/// **'{min} min'**
String studyDurationMin(int min);
/// No description provided for @studyDurationMinSec.
///
/// In en, this message translates to:
/// **'{min} min {sec} sec'**
String studyDurationMinSec(int min, int sec);
/// No description provided for @studyLeaveTitle.
///
/// In en, this message translates to:
/// **'Leave this study session?'**
String get studyLeaveTitle;
/// No description provided for @studyLeaveRated.
///
/// In en, this message translates to:
/// **'{count, plural, =1{Your ratings so far are saved, but the last card in this round will be discarded if you leave now.} other{Your ratings so far are saved, but the {count} cards still left in this round will be discarded if you leave now.}}'**
String studyLeaveRated(int count);
/// No description provided for @studyLeaveUnrated.
///
/// In en, this message translates to:
/// **'{count, plural, =1{You haven’t rated this card yet — leaving ends the session without recording any progress for this round.} other{You haven’t rated any of the {count} cards in this round yet — leaving ends the session without recording any progress for it.}}'**
String studyLeaveUnrated(int count);
/// No description provided for @studyLeaveConfirm.
///
/// In en, this message translates to:
/// **'Leave'**
String get studyLeaveConfirm;
/// No description provided for @studyKeepStudying.
///
/// In en, this message translates to:
/// **'Keep studying'**
String get studyKeepStudying;
/// No description provided for @studyInMinutes.
///
/// In en, this message translates to:
/// **'{count, plural, =1{in 1 min} other{in {count} min}}'**
String studyInMinutes(int count);
/// No description provided for @studyInHours.
///
/// In en, this message translates to:
/// **'{count, plural, =1{in 1 hour} other{in {count} hours}}'**
String studyInHours(int count);
/// No description provided for @studyInDays.
///
/// In en, this message translates to:
/// **'{count, plural, =1{in 1 day} other{in {count} days}}'**
String studyInDays(int count);
/// No description provided for @studyInMonths.
///
/// In en, this message translates to:
/// **'{count, plural, =1{in 1 month} other{in {count} months}}'**
String studyInMonths(int count);
/// No description provided for @studyInYears.
///
/// In en, this message translates to:
/// **'{count, plural, =1{in 1 year} other{in {count} years}}'**
String studyInYears(int count);
/// No description provided for @studyContinue.
///
@ -2716,29 +2890,11 @@ abstract class AppLocalizations {
/// **'Previous card'**
String get studyPrevious;
/// No description provided for @studyNext.
/// No description provided for @studySkipCard.
///
/// In en, this message translates to:
/// **'Next card'**
String get studyNext;
/// No description provided for @studyReading.
///
/// In en, this message translates to:
/// **'Reading'**
String get studyReading;
/// No description provided for @studyMeanings.
///
/// In en, this message translates to:
/// **'Meanings'**
String get studyMeanings;
/// No description provided for @studyPlaceItems.
///
/// In en, this message translates to:
/// **'Drag each item onto its category, or tap an item and then a category.'**
String get studyPlaceItems;
/// **'Skip card'**
String get studySkipCard;
/// No description provided for @studyMinutes.
///