Commit graph halkyon/halkyon_learn_flutter/test/core/router
Author SHA1 Message Date
11a16f5686
fix(theme): snack bars float above the navigation bar, lined up with it
Flutter's default snack bar is Material 2's fixed one, a rectangle across
the window's foot, which sat squarely on the floating, rounded
navigation bar. Material 3 places snack bars floating above the
navigation bar with small rounded corners: they now stand 8 dp above
it and 16 dp in from the sides, as the bar does, and from medium
windows on they are 560 dp wide and centred rather than as wide as the
window.

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>
2026-10-13 21:21:42 +02:00
47743ced49
fix(shell): the tab screens run on beneath the floating bar
On a phone, a plain band ran behind the floating navigation bar, the
screen's content cut off at its top (your screenshot from the Pixel 9a,
Home's activity card). The bar's whole slot was kept from the screens,
painted in their background: the content stopped above it, as said when
the bar came, until the screens were made ready.

The shell now lets the tab screens run on beneath the bar (extendBody), as
iOS 26's tab bar floats over content. Flutter gives each screen what the
bar covers as the body's bottom padding, and every list of the four tabs
(Home, the library, Explore, Profile) ends with that much room, so its
last item scrolls out from under the bar. Home leaves the Ask field's slot
out while asking is off, as an empty slot would take that room from its
body; with the field, its sections scroll beneath both. A floating button
keeps clear of the system's bar by itself, not of this one: the library's
lifts by what the bar covers (FloatingNavigationBar.coverOf). Inside a
studyset, where the bar steps aside, nothing changes.

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>
2026-10-11 16:51:37 +02:00
ca8c3659bc
feat(shell): the rail's logo leads Home
From medium windows on, the kingfisher atop the navigation rail is a
button to Home, as a website's logo leads to its start, with the tick the
rail's own choices make.

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>
2026-10-11 15:08:53 +02:00
f9c1f2ae97
feat(studyset): the screens behind a studyset are its path
Deeper studysets, on iOS and Android alike (decided 2026-10-11, after
Material 3's and Apple's guidelines, Android's principles of navigation and
Nielsen Norman Group's on breadcrumbs):

- The screens behind a studyset are its path: below "Japanese › Grammar ›
  Tae Kim's Grammar Guide" lie Grammar's screen, then Japanese's, then the
  library. A topic at any depth opens with the levels between pushed
  beneath it; the path's steps go up by popping to that level's page (they
  replaced the location before, so back could skip levels); a studyset
  opened from elsewhere gets its levels beneath it. Back, Android's
  predictive back, iOS's swipe from the edge and the path all lead one
  level up.
- The path's steps are targets 48 dp high; a long press on back lists the
  levels above, the nearest first and the library last, as iOS's back
  buttons do.
- Below expanded windows the topics open in a sheet from "3 topics ▾" at
  the end of the path's line, where Vaia puts "All topics"; no drawer,
  whose swipe from the edge is iOS's way back and which Material 3
  Expressive deprecates. Topics with topics of their own unfold them, at
  any depth, in the sheet and the side column alike.
- The navigation bar steps aside inside a studyset (its screen, notes,
  paths and dictionary): Material 3 puts it on the top-level screens and
  toolbars below, never both. Apple's guidelines keep the tab bar, lest
  people forget where they are; the path, starting at Library, says where.
  A strip as high as the system's bar keeps those screens clear of it.
- The bar at the bottom keeps Add material and Study.

A trial for review, on its own branch, on top of the floating navigation
bar.

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>
2026-10-11 15:08:52 +02:00
eee3ff1c5d
feat(shell): the navigation bar floats above the bottom edge on phones
Below medium windows, the navigation bar (Material 3 Expressive's shorter
one) is detached from the window's bottom edge, as iOS 26's tab bar
floats: a rounded bar 16 dp in from the sides and 8 dp above the system's
own bar, at the navigation bar's elevation. Material 3 has no floating
navigation bar for phones, only in its guidelines for headsets.

Around it shows the background of the screen in view: every screen with a
TopGradient claims its background along with its colour (ScreenTint), and
the shell's scaffold takes it, changing as the frame's colour does. The
screens' content stops above the bar; letting it scroll beneath, as iOS
does, would mean padding every screen of the tabs.

A trial for review, on its own branch, on top of the shorter bar.

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>
2026-10-11 15:08:51 +02:00
f4c502f128
feat(shell): Material 3 Expressive's shorter navigation bar on phones
The navigation bar below medium windows becomes Material 3 Expressive's
flexible one, which Flutter's Material library doesn't have yet: 64 dp
high instead of 80, the label of the tab in view in the secondary colour
(the tokens of Compose's ShortNavigationBar). Its pill stays Flutter's,
64 dp wide rather than 56, as Flutter fixes it.

A trial for review, on its own branch, beside the floating one.

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>
2026-10-11 15:08:46 +02:00
d76a49b1c4
feat(theme): the gradient on every main screen, and the rail on its colour
Library, Explore, Profile, Settings and Connect Claude now wash cobalt
down from their top as Home does, as far as their header (200 dp);
Home's wash reaches 360 dp, a studyset's 280.

From medium windows on, the window takes the colour of the screen in
view, as Vaia lays it out: the rail sits on it, transparent and without
a divider, and the screen is a rounded panel inset beside it, with its
own wash at the top. The colour is claimed by the screen's TopGradient
while its tab shows and its route is on top (ScreenTint), so the rail
turns maroon beside a cerise studyset and back to cobalt on leaving it,
in a quarter of a second. The frame is as strong as the rail's labels
allow (WCAG AA on onSurfaceVariant, every palette colour, light and
dark), weaker towards the foot.

Two things the panel's 24 dp less room brought out: a long description
was laid out whole for its first frame, before it was measured, and
overflowed a shorter column; it is now laid out whole but shown no
taller than its preview from the start. And between 840 and about 960 dp
of screen, a studyset's app bar (Study, Add material, Share, options)
didn't fit; Add material is an icon there, its label in the tooltip.

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>
2026-10-10 15:11:19 +02:00
306cb964bc
feat(navigation): a light tick on choosing a tab
Choosing a destination in the navigation bar or rail plays the platform's
lightest haptic, the selection click (a clock tick on Android), as a
short, weak confirmation. It follows the system's touch feedback setting
and does nothing where the device has no motor.

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>
2026-10-10 15:11:09 +02:00
72b29c7e80
feat(app): the studyset screen laid out as before
The Study pill reads "Learn 12 flashcards" in the app bar and "Learn 12"
floating, "Study" with nothing due, and is off with nothing to study,
saying so. With a path not finished, a chevron beside it offers to start
or continue the path: a menu in the app bar, a Study mode sheet on
phones. The floating bar rises above the licence line, which takes two
lines at most.

Add material offers a path, flashcards, a note and a PDF, in that order;
imports moved to the options' Import content, which asks for a learning
path or an Anki deck. The options read Edit, Move, Study options, Import
content, Reset progress, Archive, Delete. The bibliography is an outlined
round button above the content, and on phones at the foot of the topics.

The tabs sit on a line of their own across the card, what the tab shown
offers beside them: the flashcards' filter and options, and on the paths
Reorder once there are two, which turns them into handles to drag. An
empty tab says so in its middle; tapping the open tab again returns to
its top, and pulling a tab down syncs. The breadcrumb's steps are plain
links between "›", the studyset itself bold. A long description is cut at
a fixed height, measured, with Read more opening it whole under the
studyset's title. A studyset that no longer exists leads back to the
library.

The topics: All topics on the primary colour, in view also while they
are rearranged; each topic with the study it invites in a round icon,
what it holds ("Empty" with nothing, files counted too), and its options
(now with Reset progress) behind "…" or a long press where the finger
is; New sub-studyset at the foot below a line, the list with its
scrollbar always shown. All topics opens Add material while nothing is
due.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:18 +02:00
770de51bff
feat(app): keep the tabs beside notes and paths, flat app bars, the sync dot on the cogs alone
A studyset's notes and learning paths are routes of the Library tab, as
its screen is, so the navigation stays beside them; studying, cards, PDFs
and settings still take the whole window. App bars stay flat when content
scrolls under them: Material 3's tint flickers as an overscroll crosses
the edge again and again. The sync trouble dot shows on the Settings cogs
only; Home has a cog of its own now, so the Profile tab needn't carry it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:17 +02:00
b0aaecf115
feat(app): tag, edit, delete and swipe cards while studying, with tidier session sheets
- Above every studied card (but a matching one): the PDF it came from,
  its tags on one line ("+2 tags" for the rest) or "Add tags", and a
  menu to tag, edit or delete it; the session follows (an edited card
  shows as saved, a deleted one leaves the round).
- On phones, a front/back or vocabulary card swiped right is rated
  Good, left Bad; it tilts over the colour it heads for, and springs
  back when let go early.
- The session's settings: "Settings", a 48 dp Save that warns mid-round
  ("Heads up!"), steppers in an outlined box ("20 / day", "5 / 50"),
  the order in an outlined dropdown, the chosen tags with the rest
  behind "Filter by tags" / "+3 more".
- A studyset's study options: Save above Reset to defaults, the
  description small, reviews a day in steps of 25.
- One stepper look everywhere (study, Pomodoro profiles), its buttons
  "Decrease" and "Increase".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:12 +02:00
46855ab251
feat(app): study sessions in rounds, by card type, cramming and reversed
A session studies a round of up to the settings' cards per round. In
spaced repetition a card leaves the round once it is a day or more away,
one rated lower comes back when due; cramming walks every card once,
round after round, its reviews moving no schedule, with going back and
on. Asking the back first (a toggle in the header, saved in the
settings) asks front/back and vocabulary cards their back, on their own
schedule. Each type studies its way: a word shows its reading and
meanings, a multiple-choice card is picked and checked, a matching card
sorted by dragging or tapping and checked; then the person rates (Bad,
OK, Good, Perfect, each with when the card comes back). Progress shows
as pills, or a tally bar while cramming; a round ends with how it went.
The session settings gain the mode, cards per round, new cards per day
and the order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-01 21:10:06 +02:00
31d87e8415
feat(app): the studyset screen with its topics, the tree's own screen
All checks were successful
CI / check (push) Successful in 5m28s
CI / deploy (push) Successful in 7s
A studyset's screen, as decided with the tree (2026-09-30/10-01):

- A breadcrumb from the library down to the studyset; its steps go up
  (replacing the location, so back leads further up), and steps that
  don't fit fold into a "…" listing them, nearest first.
- From expanded windows on, two columns: the description over the topics,
  the flashcards beside them, Study and Add material in the app bar. Below
  that, the topics are in a drawer, opened from a bar at the bottom that
  also holds Study and Add material and slides away while reading onwards;
  the back button stays where a drawer would have taken its place.
- The topics: "All topics" for the whole studyset, then the studysets
  inside it in their order, each with the study it invites, what it holds
  and its options (edit, delete), opening on top of this screen; a switch
  rearranges them by dragging; "New sub-studyset" creates one inside.
- Study covers the studyset with everything inside it ("Learn 12" while
  something is due). Add material offers flashcards for now.
- Options: Edit (the sheet, now with the description, edited in the whole
  window, and for a studyset inside another the colour of the one it is
  in, which a new one takes at first), Move to… (the tree and the top
  level, without the studyset itself and what is inside it), Archive or
  Unarchive with Undo, Delete with Undo, which closes the screen.
- The description cut short when long, the whole a tap away; the licence
  as the last line, linking to its text where that is known.

The list's bloc, scoped to a parent, lists its children, works out the
studyset's own progress, creates inside it, reorders and moves. The card
list leaves adding and studying to the screen. The inline editing of the
title and description, and its bloc, are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-01 15:14:57 +02:00
b171b8e1d4
feat(app): studyset payload schema 2, stars and the archive
A studyset is now its content (StudysetContent, everything the synced payload
holds) and the columns that change on their own: where it sits (parent,
position), and when it was archived or starred. Like a card's content, the
payload's part is edited as one value; the columns are written one by one,
so starring or archiving on one device and editing on another all survive a
sync (ADR 0004).

The payload's schema 2 adds the secondary title, the colour (a palette name),
the licence (SPDX identifier or name, holder, year) and the languages of the
cards' two sides (BCP 47), each left out when not given. Schema 1 reads as
schema 2 without them, and a field of the wrong kind makes the payload
unreadable rather than half read. Older app versions skip schema 2 studysets,
which costs nothing before the first release; fields foreseeable for the
first release's features are in, so none of them needs a schema 3 later.

The repository stars, unstars, archives and unarchives (at clock time, in
UTC), writing only that column. A new sync test (run against a server)
checks that a star and an archive on one device and a rename on another all
arrive on both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-01 09:59:44 +02:00
c21ce6232b
feat(app): the UI foundation: theme, tabs and routes, strings
The app gets its look and navigation before more features land on them.

- Theme (core/theme/): hand-written light and dark Material 3 colour schemes around
  cobalt and copper; ThemeExtras for the colours Material has no role for (states, the
  four FSRS ratings); the 20 colours a person can give content. Tests hold text to WCAG
  AA contrast on each palette colour and on the dark theme's primary colour and surface.
- Layout and shared widgets: Material 3's window-size classes (core/layout/);
  SectionCard, AppLoadingIndicator, confirmDestructiveAction and FoundById
  (core/widget/). Lucide icons.
- Navigation with go_router: four tabs (Home, Library, Explore, Profile), each keeping
  its own stack of screens, as a navigation rail with the app's icon from 600 dp and as
  a navigation bar below; choosing the open tab again returns to its first screen. A
  studyset's screen sits in the library; studying, cards and settings cover the tabs.
- Routes carry ids: FoundById finds the item in the repository's live list, so a
  studyset deleted on another device, or an old link, says it no longer exists. A
  screen that deletes its own item keeps showing it while it closes, rather than
  flashing that message.
- Every person gets an app of their own (PersonApp, lib/src/app/): a
  MaterialApp.router with its own GoRouter and PersonScope around the navigator, built
  by SessionGate inside the person's keyed subtree. Screens read the person's
  repositories wherever they are built, so the static route() helpers and the listener
  that closed every pushed screen on a change of person are gone: a change of person
  now disposes the whole router and starts again at home.
- The account dialog becomes the Profile tab, with Settings (sign out, delete the
  account, About) behind a gear. A waiting GitHub sign-in now keeps waiting while
  another tab shows; a change of person still cancels it.
- The new screens' strings come from Flutter's gen-l10n (English for now). The
  generated files are committed, left out of analysis and formatting, and written
  anew by `flutter pub get`, so CI's check of generated code also catches stale ones.

Widget tests now start the whole app (test/support/pump_app.dart) at the screen's path
and move through it as a person would, by tabs and taps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-01 09:59:44 +02:00