feat: a round in the order cards come, shared daily limits, and a start screen

Studying:
- A round is one list in the order its cards come: those done, the one
  shown, those to come. A card due again within the day goes back in
  after 4 more cards when rated Bad, at the end otherwise, so the pills
  above the card follow it; the buttons say "in 4 cards", "at the end",
  "now" (round_order.dart).
- The studied studyset's daily limits hold for everything inside it
  together, as Anki's do for subdecks: twenty topics start 20 new cards
  a day in all, not 20 each.
- The study header's studyset name shows whole on hover or long press.
- The assistant's button sits at the lower left: in the Library across
  from Create studyset, in a studyset above its bar, and higher while
  studying, above the buttons that answer the card.

A studyset:
- Progress also counts the learning paths' steps done and lists the
  PDFs not read to their end, begun first, each opening the reader,
  across its topics (MaterialProgressCubit).
- Next up starts with studying for the exam while one is ahead: its
  reviews due and the new cards its pace leaves for the day.
- Learning paths tagged with a level count towards its automatic exam
  plan and offer it, as cards do.
- A step's first heading equal to its title is dropped on import and
  hidden in paths imported before.

Signing out, or a session the server ended, leads to a start screen
(GitHub, email, without an account, another instance) rather than a new
anonymous account; only the very first start makes one by itself.
Settings names the kind of account and its instance.

Also: the Watch screen reads the cards once for held words and their
progress; its ±10 s buttons tick as the navigation bar does; a map card
keeps its view as its caption changes and brings a picked region
towards the middle; an empty or failed library can be pulled to sync.

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-17 00:39:34 +02:00
commit de6af3efab
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -2093,6 +2093,24 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get instanceWelcome => 'Welcome to Halkyon Learn';
@override
String get startSignedOut => 'Signed out';
@override
String startOn(String instance) {
return 'Start on $instance:';
}
@override
String get startWithoutAccount => 'Start without an account';
@override
String get startNoGitHubAccount =>
'No account here signs in with this GitHub account yet. Start without an account, then add GitHub in Profile.';
@override
String get startOtherInstance => 'Use another instance';
@override
String get instanceFirstStartSubtitle =>
'Choose the instance to keep your studysets on. Someone runs each one; you can add others later.';
@ -2127,6 +2145,22 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get settingsSwitchAccount => 'Switch account';
@override
String settingsAccountAnonymous(String instance) {
return 'Anonymous on $instance';
}
@override
String settingsAccountSignedIn(String instance) {
return 'Signed in on $instance';
}
@override
String get accountAnonymous => 'Anonymous';
@override
String get accountSignedIn => 'Signed in';
@override
String get accountsTitle => 'Accounts';
@ -3542,6 +3576,23 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get studyCheck => 'Check';
@override
String studyComesBackIn(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'in $count cards',
one: 'in 1 card',
);
return '$_temp0';
}
@override
String get studyComesBackAtEnd => 'at the end';
@override
String get studyComesBackNow => 'now';
@override
String get studySelectAll => 'Select all that apply';
@ -7004,6 +7055,55 @@ class AppLocalizationsEn extends AppLocalizations {
return '$hours h $minutes min';
}
@override
String get progressPathsInfo =>
'The steps of this studyset\'s learning paths, and its topics\', that you have done.';
@override
String progressStepsDone(int total) {
String _temp0 = intl.Intl.pluralLogic(
total,
locale: localeName,
other: 'of $total steps done',
one: 'of 1 step done',
);
return '$_temp0';
}
@override
String get progressReading => 'Reading';
@override
String get progressReadingInfo =>
'The PDFs of this studyset and its topics not read to their last page yet. Tap one to read on.';
@override
String progressPdfPage(int page, int count) {
return 'Page $page of $count';
}
@override
String get progressPdfNotBegun => 'Not begun yet';
@override
String progressPdfsAllRead(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'All $count PDFs are read to their end.',
one: 'The PDF is read to its end.',
);
return '$_temp0';
}
@override
String progressShowAllPdfs(int count) {
return 'Show all $count';
}
@override
String get progressShowFewerPdfs => 'Show fewer';
@override
String planPathsDone(int done, int count) {
String _temp0 = intl.Intl.pluralLogic(
@ -7032,6 +7132,17 @@ class AppLocalizationsEn extends AppLocalizations {
return '$_temp0';
}
@override
String planStudyForExam(int count, String exam) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'Study $count flashcards for $exam',
one: 'Study 1 flashcard for $exam',
);
return '$_temp0';
}
@override
String planContinue(String title) {
return 'Continue “$title”';