Commit graph halkyon/halkyon_learn_flutter/lib/l10n/app_en.arb
Author SHA1 Message Date
7f6147d689
feat: public profiles, a handle on the account domain with name, bio, links and picture
Stage 1 of the public tier (ADR 0005). A person with an identity has a
public profile: a handle by Mastodon's rules (1 to 30 letters, digits or
underscores, unique whatever its case, a few kept for the instance),
changeable until they first publish, on the instance's account domain
(ACCOUNT_DOMAIN, else the server's host; the instance info names it), so
`raisondetredev@halkyon.eu`; a display name, a bio, up to four links and
an avatar. The table is server only: the app gets a Profile without the
person's id. ProfileEndpoint (identified only) reads, saves and removes
the caller's own; ProfilesEndpoint finds anyone's by handle.

An avatar is a PNG of at most 1 MB that the app draws anew from the
picture chosen, its middle square at 400 pixels, so a photo's metadata
never leaves the device. The server keeps it in the public storage named
by its content, so its URL tells nothing about whose it is, and deletes it
once no profile shows it. Deleting a person deletes their profile and its
picture.

In the app, the Profile tab holds the profile as a form, laid out as the
old app's; anonymous people are told GitHub sign-in gives them one.

Migration 20261009184924904-public-profiles creates public_profile with a
unique index on the person and one on the handle in lower case; it touches
no other table, and the old server never sees it.

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 09:46:37 +02:00
44cee0d6c6
feat: a dictionary's corrections reach the cards made from it, by offer
All checks were successful
CI / check (push) Successful in 12m33s
CI / deploy (push) Successful in 1m26s
Every dictionary entry now has a version: 16 hex digits of the SHA-256 of
what cards take of it (headword, reading, entry), made by the loader and
carried on every hit. A card keeps the version it took (card schema 8).
DictionaryEndpoint.changed returns, of the entries named with the
versions cards keep (1,000 at most a call; the app asks 500 at a time),
those whose version is another now.

The card browser says how many cards are behind their dictionary and takes
the corrections at a tap (decided 2026-10-09: by offer, never by
themselves). Taking one writes the entry as it is now over the revision
in which the card last took it, beside whatever came after, so the
revisions merge per side as two devices' edits do (ADR 0003): a side only
the dictionary changed takes the correction, a side the person changed
too is a conflict settled in the composer, whose words now name that
case. Cards made before versions are never offered one.

The server rereads its dictionary folder hourly now, not daily: the
dictionaries service fills its volume after an instance's first start,
and an hour with nothing changed costs a hash of each file.

Migration 20261009145434785-dictionary-entry-version: adds
dictionary_entry.version, text NOT NULL DEFAULT '' (rows loaded before
have none and are never reported as corrected), and by hand empties
dictionary_source."fileHash", so every source loads once more and its
entries get their versions; the schema stays as definition.sql says. The
old server goes on working until the switch.

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-09 18:09:37 +02:00
9bb3826556
docs: credit KanjiVG in About, and name the kanji dictionary
About lists the data the app comes with beside the instance's
dictionaries: KanjiVG's strokes, by Ulrich Apel under CC BY-SA 3.0, with
the link its licence asks for. The server's README names the dictionary
of kanji and kana beside JMdict.

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-09 18:09:35 +02:00
89ad2c237d
feat(app): write kanji, kana and words by hand, each stroke checked
The study option Write by hand (settings schema 7) has character cards
and words written in a session, on a schedule of their own (review mode
`write`; older apps skip a mode they don't know): what to write on top, a
character's meanings and readings or a word's reading and meanings, and
below it a square to write it in, character by character.

Each stroke is checked as it ends against KanjiVG's: both resampled to 22
points, then their shape once centred, where they lie, how long they are
and which way they go, each against what a loose hand strays by; a stroke
closer to one still to come is out of order. One that counts is drawn as
KanjiVG draws it, and the hand's offset from the middle is forgiven in the
strokes after; any other flashes red, says why and counts as a mistake, as
does a hint. Two misses in a row show the next stroke faintly. Once
written, or given up on (Show it), the rating the mistakes suggest is
outlined: none Good, one or two OK, more Bad.

The square takes every touch on it at once, so writing never scrolls the
card or swipes to rate. Characters without a stroke order (in a word) are
written for the person.

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-09 18:09:34 +02:00
ed5bb3f6b1
feat(app): stroke order for kanji and kana, from KanjiVG
KanjiVG's strokes come with the app (assets/kanjivg/, CC BY-SA 3.0, its
notice in the licence list): 94 gzipped files, one per 256 code points,
2.7 MB in all, a file read the first time a character of it is asked for
(StrokeRepository, app-wide beside the maps). The strokes are SVG path
data, read with path_parsing (the Flutter team's, pure Dart, already in
the build through flutter_svg), so the model can flatten them into points
without dart:ui, as checking handwriting will.

A character's sheet traces its strokes in order over those to come, with
its stroke count, meanings, readings, level and the components KanjiVG
splits it into, each a tap away. It opens from a studied character's
answer (Stroke order) and from a character found in the dictionary.

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-09 18:09:34 +02:00
cec518350a
feat(app): kanji and kana in the dictionary, beside the words
Where the instance holds the characters of a studyset's language, the
dictionary screen has a tab for them, Kanji & kana: search by character,
reading (kana or romaji) or meaning, and whole levels to add, under their
names: the kana (hiragana, katakana), the JLPT levels and the school
grades. A character becomes a character card, its meanings (a kana's
romaji) and readings, tagged with its level (JLPT-N5), school grade
(Grade 1 … Grade 6, Secondary school) and script (Hiragana, Katakana). A
character card's Look up searches the characters, and an entry looked up
again on a card swaps the tags the one before brought, as words do.

A dictionary's entries are now words or characters (DictionaryItem), as
its kind says.

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-09 18:09:33 +02:00
2fc4205010
feat(app): a character card for kanji and kana
One card type for both (card schema 7): the character on the front, its
meanings and a kanji's on and kun readings, each merging on its own. A
kana's romaji is its meaning, so kana are studied, and later written,
exactly as kanji are. The composer offers it beside the other kinds, each
kind of reading on one line (ショク、ジキ); studying shows the character
large and, with the answer, its meanings and readings (the other way round
when asked from the back); the card browser filters by it and finds a kun
reading without its okurigana dot; the Markdown export writes its meanings
and readings.

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-09 18:09:33 +02:00
42c57bd40a
feat(app): a card browser to search, filter, sort and change many cards at once
Browse beside the flashcards' tab opens the studyset's cards over the
tabs (with everything inside it when it has sub-studysets), laid out as
the older design had it:
- a grid of tiles (each card's two sides) or one card at a time beside
  the list (on a phone above a strip of them, swiped through), as last
  left for the studyset on this device;
- a search over front, back, reading, meanings, hints, explanation and
  tag names, katakana found as hiragana and kana by romaji;
- sorting by own order, newest, oldest, A–Z (words by reading), due
  first; a filter sheet by kind, tag and state (new, learning, due,
  buried, reported);
- choosing cards (a toggle; shift-click or long-press for a range,
  select all) to move into another or a new studyset, add or remove
  tags, start afresh, or delete with Undo; the actions in the row on
  wide windows, in a bar at the foot below.

Moving cards between studysets is new in the card repository and its
gateway (studysetId and position written, named columns).

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-09 18:09:31 +02:00
084af278b5
fix(app): Reorder among older items, export and text import that hold up
- Reorder: rows from before an order existed all share one position, and
  one moved among them landed at their end; the run it goes into now
  gets positions of its own (placeAmong), for notes, files, paths,
  steps and sub-studysets. Rows whose deletion can still be undone count
  for nothing, as the list leaves them out, and a dropped row takes its
  place at once instead of snapping back until the order is read again.
- Export: two studysets inside each other (moved so on two devices
  offline) no longer make it run forever; links to files whose names
  hold #, % or brackets work; PDFs, images and sounds go into the zip
  without being compressed again; any error says the export failed.
- Text import: a real CSV reader (quoted fields over several lines, a
  back over several quoted fields, a stray quote spoiling only its own
  line), the separator guessed from the text (semicolons from German
  spreadsheets), and files in UTF-16 or Windows-1252 read as meant.
- A tab whose notes, paths or files couldn't be read says so rather than
  "No … yet"; an Anki import from the Library that fails leaves no empty
  studyset behind.

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-09 18:09:30 +02:00
4aed71c8db
fix(app): glyph shapes, languages, licences and the side bar's foot
- A Japanese front keeps Japanese shapes whatever the back's language
  (Japanese learnt in Chinese or Korean took Chinese or Korean shapes).
- A change of languages no longer rebuilds the screen below: the scope
  keeps one shape, so a study session keeps its Undo.
- The PDF reader, with the cards and notes written beside it, takes its
  studyset's languages too.
- Licences: GPL-3.0 and AGPL-3.0 mean "only", as SPDX defines them (not
  "or later"); GPLv3 and "public domain" stay as typed; words around a
  Creative Commons licence ("International", "Unported", "Deed") and its
  name written out are read; 4.0 takes no jurisdiction.
- A new sub-studyset takes its parent's licence, not its holder or year.
- The year says it is wrong once typed whole or left; full-width digits
  count; the year's range comes from clock.
- New sub-studyset shows whole in the side bar, no longer cut at half.
- The languages switch says that neither side set means inheriting;
  "license" as the British verb.

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-09 18:09:29 +02:00
49e10895f4
fix(app): the dictionary adds each word once, says when it can't, and Look up tags hold
- A word tapped twice, or added while a level is being added, makes one
  card: adds run one at a time, and the word counts as in the studyset
  at once. The adder reads the studyset's cards once rather than for
  every word.
- Adding that fails says so, and a level shows "Making the cards…" once
  its words have come.
- Finding a studyset's dictionary tells finding, none and unreachable
  apart: the dictionary screen says there is none or offers Retry, and
  an instance unreachable at start is asked again once a sync goes
  through (Look up and From the dictionary appear then).
- Look up's tags wait on the card by name and are made when it is saved:
  leaving the card at once no longer saves it untagged, a word replaced
  leaves no tag behind, and a new word replaces any level or word class
  on the card, pinned ones too. Look up marks words already made into
  cards of the studyset.
- The tag picker's Create keeps the case typed.

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-09 18:09:28 +02:00
c20578e421
feat(app): tags keep their case; dictionary tags read JLPT-N5, Noun
A tag is still its name, but no longer in lowercase: the name keeps the
case it was written in, and names that differ only in case are one tag
(ADR 0004, rule 2, amended). Two such tags from two devices fold into the
one with the smaller id, its case with it. Tags stored before stay
lowercase until renamed.

Words from the dictionary are tagged JLPT-N5 to JLPT-N1 and with their
word class (Noun, Verb, i-Adjective, na-Adjective, ...). Anki tags and
PDF chapter tags arrive as written.

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-09 18:09:27 +02:00
02d6542cfa
feat(app): type a word's reading while studying
A new study option, Type the reading (settings schema 6, beside the
vocabulary quiz; turning one on turns the other off): a word with kanji
shows alone, and its reading is typed, in kana; romaji turn into kana as
they are typed (doubled consonants, n before a consonant, nn and n'), and
the device's own Japanese input works as it does. Check, or Enter, says
whether it was right (katakana counts as hiragana) and what was typed
beside the reading, then shows the meanings and the ratings; the person
still rates, as Anki's typed answers have it. A word written in kana, one
usually written so, and a card asked back first flip as before.

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-09 18:09:27 +02:00
30dde3b8fa
feat(app): furigana in rich text
Text within a line can carry its reading now (`ruby` on the text's
attributes, `かんじ` on `漢字`), word by word, in lessons, example
sentences, notes and cards alike. Shown, the reading sits above the text,
smaller and centred, the text level with the line around it; while
editing, the text is dotted underneath and the caret moves through it as
text, as with formulas. The format bar's Furigana asks for the reading of
the text selected, starting from the one it has, and takes it away.

An Anki field's `<ruby>` keeps its reading as furigana now, each base its
own, instead of "漢(かん)"; Anki's `漢字[かんじ]` stays as written, as
telling it apart from other brackets is guesswork. The Markdown export
writes furigana as HTML's `<ruby>漢字<rt>かんじ</rt></ruby>`.

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-09 18:09:26 +02:00
add1c76842
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>
2026-10-09 18:09:26 +02:00
bd6016ee1b
feat(app): choose a studyset's licence, its year and holder
The studyset sheet gains Licence, as before: "Help me choose" asks three
questions (keep any rights? commercial use? adaptations, alike?) and
recommends one of the six current Creative Commons licences or CC0, with
what it lets others do and a link to its terms; the licence field
suggests well-known licences and takes any other as typed, kept in one
spelling (`cc by-nc-sa 3.0 us` is `CC-BY-NC-SA-3.0-US`); the year sits at
its end (1000 to next year), the holder below. An older or ported
Creative Commons licence gets a note naming its current version. A new
sub-studyset starts with the licence of the one it is in.

Left out until publishing exists: the warnings about sub-studysets'
licences that a parent's doesn't cover. The licence shows for every
studyset, as there is no visibility yet.

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-09 18:09:25 +02:00
b1ef9b9d3a
feat(app): a studyset's languages, and Chinese and Korean fonts
The studyset sheet gains Languages, as before: off until "Set
languages", then the language of the cards' fronts and of their backs
(22 languages, Chinese in its two scripts). A studyset without its own
takes those of the nearest studyset above it, both together; set for the
first time, they start from those it took. The payload held both fields
already.

They set its text: Noto Sans SC, TC and KR join Noto Sans JP (bundled,
never fetched; 34 MB more, fonts 42 MB in all, your call), and since
Han characters take the shapes of the first font that has them, every
screen inside a studyset (its screen, cards, notes, paths, studying it)
puts the font of its front's language first, else of its back's,
Japanese otherwise. Every studyset route goes through one helper now.

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-09 18:09:24 +02:00
02efa2cdcf
feat(app): every empty studyset tab says how to add some, as Files did
Paths, flashcards and notes now show what Files showed when empty: an
icon for what the tab holds, "No … yet", and the menus that add some
("Add material → Create a path", "⋮ → Import content", …), through one
shared widget, EmptyListMessage. The icons are those the app uses for
each already: the route, the study screen's card stack, the note pen,
the folder.

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-09 18:09:22 +02:00
7975586994
feat: files in an order of one's own, with Reorder beside the tabs
A PDF now has a position among its studyset's files, as notes and paths
have: a fractional index in a column of its own (so moving it on one
device and renaming it on another don't overwrite each other), last
writer wins. The migration adds it to pdf_source on the server and on
each device with 'a0', so PDFs from before stand in the order they were
added (ties sort by id), and new ones go at the end.

The Files tab lists them in that order by default (Custom order, first
in the Sort menu; newest first was the default before). With two files
or more, Reorder beside the tabs shows the custom order whatever they
were sorted by, a grip in place of each file's options and the Sort menu
put away, until Done.

The next release changes synced tables anyway (card.buriedAt, since
v0.2.2), so older apps have to update for that already.

Also: card.position's doc no longer speaks of moving cards.

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-09 18:09:22 +02:00
04cbf00e3c
feat(app): notes in an order of one's own, with Reorder beside the tabs
With two notes or more, Reorder beside the tabs gives each note a grip
in place of its options, as paths have, until Done; e.g. to follow a
reading order. A note's position was stored already; the repository
now moves it (only that column changes, and it syncs).

The notes' bloc sits with the studyset's other lists now, above the
tabs, so the button knows how many there are. The position helpers the
paths kept to themselves are shared (core/sync/fractional_position.dart),
and so is the grip (ReorderGrip).

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-09 18:09:22 +02:00
6c9dfadf27
refactor(app): flashcards keep the order they came in, without Reorder
Studying breaks the order of due cards anyway; what follows the list
order is new cards and cramming, and that order comes from creating and
importing, with sub-studysets putting lessons in order. No one drags a
card among a thousand (decided 2026-10-08).

Gone: Reorder and the grip on flashcards, CardListEventMoved,
CardRepository.move and the gateway's updatePosition, with their tests.
Each card keeps its stored position, so the order stays the same on
every device. liftWhileDragged is Material's plain lift again, for the
lists that keep Reorder.

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-09 18:09:21 +02:00
bb23ca2478
fix(app): studyset tabs built as they scroll, and a Reorder mode for flashcards
A studyset of 1,200 flashcards froze the window for seconds on opening
(7.4 s in a debug test; a release build is faster but still grows with
every card), long enough for the desktop to offer to kill the app: the
tabs held each list as one child of a scrolling view, shrink-wrapped, so
every row was built and laid out at once, and again on every change.

The tabs are now CustomScrollViews holding each list's slivers, built as
they scroll into view (0.07 s for the same 1,200 cards). What a list says
in place of its rows sits in SliverCentered.

On the desktop, Flutter's default drag handle lay over each card's "…",
so a press there began a drag rather than opening the options. Cards now
move in a Reorder mode, as paths do: Reorder beside the tabs (with two
cards or more, all showing), a grip in place of each card's options,
Done to end it. ReorderToggle and liftWhileDragged are shared with the
paths.

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-09 18:09:21 +02:00
882b669c3e
feat(app): export a studyset as Markdown
Export content, in the studyset's options, writes the studyset and
everything inside it as one readable Markdown document (decided
2026-10-08: no re-importable archive before the public tier's release
files): its title, secondary title, description and licence, then its
flashcards (answers below their questions, choices as task lists),
notes, learning paths (steps with their kinds, answers, feedback and
sources), PDFs and bibliography, then each sub-studyset a level deeper.
Rich text keeps its formatting; formulas go between dollars, callouts
become quotes, spoilers HTML details, YouTube videos links. With files
(images, sounds, PDFs) it keeps a .zip of the document and them under
files/; a file this device can't have is named and counted.

Saving goes through a FileSaver: file_selector's dialog on the desktop,
file_picker's (Android's Storage Access Framework) on phones, a direct
dependency now at the version the editor already brings.

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-09 18:09:20 +02:00
a26150a314
feat(app): Import in the Library's bar
Beside search, as in the old app: Import offers an Anki deck, which
becomes a studyset of its own named after its top deck (or its file),
its subdecks inside as chosen. The studyset is made only once the
import starts, so closing the sheet before leaves nothing behind.

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-09 18:09:20 +02:00
18c1370bf6
feat(app): import flashcards from text
Import content gains Flashcards: pasted, or from a CSV or TSV file, one
card per line, split at its first tab, comma or semicolon (a .csv picks
commas), lines without both sides left out. Quoted fields are read as
spreadsheets write them, and a UTF-8 byte order mark is ignored. The
cards come in at the studyset's end with the origin "text", so the
dashboard doesn't count them as written.

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-09 18:09:20 +02:00
a35318a5a6
feat(app): More info for studysets, paths, notes and PDFs
Wherever the old menus offered it: the studyset's options, a path's
(in the list and in the runner), a note's, and a PDF's, all on the
shared sheet the cards use: when it was made (from its UUID v7 id) and
last changed where that is kept, its ids to copy (parent, studyset,
PDF), and for a PDF its file.

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-09 18:09:20 +02:00
252110832a
feat(app): the path editor in two cards, as before
On the tinted ground, one card holds the path's details (title,
secondary title, a line, the description row, a line, its tags behind an
Add tags chip) and one below holds its steps under their header, lines
between them, filling the window at least.

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-09 18:09:20 +02:00
0d46c04a44
feat(app): a note as one card, as before
A note is one card on the tinted ground: its title, its tags behind an
Add tags chip, a line, then its text. The app bar says only how saving
stands; its "Note in …" title goes.

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-09 18:09:19 +02:00
43b2d86fc0
feat(app): path tiles, Profile and Explore laid out as before
A path shows its route and its secondary title above its title, dimmed
once completed; its options open below the … button, or where the finger
presses for a long press, and resetting its progress asks first. While
the paths are reordered, each keeps its route and secondary title beside
the handle.

Profile sits on the screen itself, a list as wide as readable text,
without a card; Explore on the plain surface too.

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
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
aa69be47d1
feat(app): Home, the Library and the studyset sheets laid out as before
Home: plain cards on the surface, 16 dp apart, the goal first and the
Pomodoro timer after it in a new dashboard. The streak chip sits centred
in the app bar, and its sheet shows the days inside a big flame and the
week as marks over the weekdays' initials, with a word on today in a box.
The week names its day as "Thursday, Oct 8" and its days carry no
tooltip. The heatmap scrolls its weekdays with the weeks, outlines the
days to come, and names a day's activities with its date. The goal card
has a ring of 5 dp, a check once met and a pencil, and its sheet saves
across its width with Remove goal below. Arranging puts an eye on each
widget's corner and lifts the one picked up, with a tap the hand feels;
with every widget hidden, Customise brings arranging back. The stepper
moves to core, where the goal's sheet takes it too.

Library: the counts line includes files (PDFs); Refresh in the app bar
and pulling the list down sync now; a list that can't be read offers
Retry, which reads it again; the star keeps its square corners.

Studyset sheet: "Title *", the secondary title explained behind a
question mark, Inherit as a box beside the colour, and the description
in up to three lines with a chevron. Move sheet: round marks, the
studyset itself marked as current, the top level only while it is
inside another, archived studysets last under their heading, the
destination named in the footer, and a new studyset to move into, made
only once the move is.

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
5a9441a717
feat(app): undo every step of a study session, deletions held until it ends
The header's Undo takes back ratings, burials and deletions, last first,
across the session's rounds and from the end of a round, and shows the
card again. A card deleted during a session is held (DelayedDeletions.hold)
until the session ends, then goes after the usual time to undo, so the
message offering Undo still works; if the app is killed first, the card
stays. Undo on a burial's or deletion's message takes back that step alone.

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
72e99ef790
feat(app): offer to review first when reviews are due beyond the tags chosen
With tags narrowing a session, new cards of theirs to learn, and cards
of other tags due for review, the session asks first ("You have reviews
due"): Review first studies the reviews due across every tag, round
after round, the tags not applying until none is left (the session
settings say so meanwhile); Learn anyway learns the tags' new cards;
Cancel leaves. A new session asks again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:16 +02:00
6893db7da8
feat(app): quiz vocabulary as multiple choice
The session settings' new Vocabulary section quizzes words as multiple
choice: their meaning (the default), their reading, the expression for
the meaning, or the reading and the meaning in turn ("Mixed"). The
wrong answers come from the other words studied; none of the word's
own meanings counts as wrong, whatever its case. A word without what is
asked, or without two others to draw from, stays a word to flip. It is
asked the same way each time it comes, and rated as any card.

The settings keep both (`quizVocabulary`, `quizAspect`; settings schema
5), on every device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:16 +02:00
2b188641c3
feat(app): undo deleting a card
Deleting a card, from the list or while studying, asks first ("Delete
flashcard?"), then offers Undo for a few seconds ("Flashcard deleted").
Meanwhile the card leaves every list and session; once the time to
undo is over, its revisions are blanked and it is deleted for good, as
notes and studysets already are (CardDeletions, a DelayedDeletions).
Undo while studying puts the card back into the round where it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:15 +02:00
c5cbc53bdd
feat(app): More info about a card
"More info", in a card's menu while studying or in the list, shows when
it was made and last changed (its ids say), its id and its studyset's
(and its PDF's), each copied with a tap, and how often it was studied
and when last. The sheet is a shared one, for notes and paths to follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:15 +02:00
4c47ec06c1
feat(app): show and write a word's senses with their grammar
A word with senses (as a dictionary gives them) shows them when its
answer shows: numbered when there are several, each with its label, its
translations and its grammar codes, small and slanted, their meaning on
hover. A word usually written in kana shows its reading from the start:
its kanji are rarely seen, so there is nothing to hide. The composer
writes the senses' translations, adds and removes senses, and keeps the
codes as they came.

The codes' short forms and meanings are the dictionary's own English
(JMdict's entities), kept as data beside the cards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:15 +02:00
c19a8e1db2
feat(app): report what is wrong with a card, and bury cards from the list
- "Report an error", from a card's menu while studying or in the list:
  a category (typo, grammar, content, other) and a note. The card is
  marked to be fixed, and still studied; the list shows the category
  (the note on hover), and "Resolve report" takes it back. A report is
  a revision of the card, so it follows it to every device.
- The list buries a card until tomorrow and brings it back ("Unbury"),
  showing "Buried" meanwhile.
- Each of these says so with an Undo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:14 +02:00
9edb23a379
feat(app): give cards hints and an explanation
A card of any type can carry up to six hints and an explanation, both
rich text. They are written in the composer, added from its menu (or
Ctrl+Alt+H / Ctrl+Alt+E), each removed on its own; blank ones aren't
kept. While studying, "Hints" under the question opens them one at a
time, and "Explanation" comes with the answer.

Card schema 5 holds them (`hints`, `explanation`), and with them what a
card needs next: a report that something on it is wrong (`report`:
category, note, when) and a word's senses with their grammar codes
(`senses`; a word's meanings then come from them, and its first sense
says whether it is usually written in kana). Each merges as a field of
its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:14 +02:00
bd00fc0d9a
feat(app): bury a card until tomorrow while studying
"Bury until tomorrow" in a card's menu sets it aside for the rest of the
local day: it leaves the round, and no session or count takes it until
the next day begins; its schedule stays as it was. Undo, offered for a
few seconds, brings it back into the round.

A burial is an entry of its own in the review log (mode "bury"), as a
fresh start is: no synced table changes, older app versions skip it as
a mode they don't know, and it never counts as studying.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:14 +02:00
b72a96f810
feat(app): choose whether studying shows the Pomodoro timer
Settings has a Study card: the Pomodoro profiles, and a switch "Show
the Pomodoro timer while studying" (on unless switched off). Like the
appearance, it is the device's own setting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:13 +02:00
aad6110da3
feat(app): lock the study screen, and undo the last rating
- Lock screen (header): a light scrim takes every touch; a tap shows
  Unlock for three seconds. Time locked doesn't count to the session's,
  and a running Pomodoro timer pauses, going on once unlocked (also
  when the session is left locked).
- Undo last rating (header): takes back one rating at a time within the
  round, its review deleted from the log, the round as it was; the card
  shows again from its question. Starting a round anew, or deleting a
  card, clears what can be undone.
- The review log deletes entries of any kind made at a moment (resets
  and ratings alike).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:13 +02:00
9f1cfc1cdd
feat(app): ask what to study in a studyset with sub-studysets, and say when studying fails
- Studying a studyset that has sub-studysets and cards of its own
  first asks: everything (suggested) or this studyset only. Without
  either, it starts straight away. Alone, the back-first setting
  applies as usual and a turn of it is kept (a study button's focus
  may now leave the side to the settings).
- A session that can't be read says so, with Retry; a rating that
  can't be kept says so below the card, which stays to be rated
  again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:13 +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
369ce4ade1
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>
2026-10-09 18:09:12 +02:00
65976ae63a
feat(app): cite sources in APA, MLA or Chicago, and give studysets a bibliography
A source is now shared by learning paths and studysets (core/citation/):
authors as full names, year, title, what it is a part of, publisher,
ISBN, link, and a citation kept as a file brought it. formatCitation
cites it in APA 7, MLA 9 or Chicago 18: it inverts and abbreviates
names itself (particles, suffixes, names written as already cited stay),
sets a work of its own in italics and a part of something apart from
the whole, and writes a missing year as "n.d." in APA and Chicago.

- Settings: a Citations card per device, with a preview and a link to
  the style's own guide.
- Studysets: a Bibliography button opens the works cited, to read and,
  behind its pencil, to change (studyset schema 4).
- Steps: sources edited through the same sheet, opened from an
  "N sources" button in the runner (step schema 2; schema 1 reads on).
- Path import: steps' sources, text kept as written, the old format's
  "citation" read as what a source is part of.

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
d9f7498cd4
feat(linux): suggest the top bar's extension instead of a notification
Decided 2026-10-07: where GNOME's top bar shows no icons (the
AppIndicator extension missing or off), the timer shows in the app
alone, and no notification stands in for it. The Pomodoro card says
that the timer can count down in the top bar, with a button that asks
GNOME Shell to switch the extension on where it is installed or to
install it (GNOME's own dialog), or opens its page on
extensions.gnome.org where Shell can't be asked; until the person says
not to suggest it again. An app can't install or switch on a Shell
extension by itself. The alert at a phase's end stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-07 12:28:06 +02:00
1921043925
fix(app): a path import that fails says why in the app's language
The importer said what was wrong with a file in English sentences built
in the data layer, the last English left in a German app. It now names
the problem, the step it is in and what the problem names (a field, a
type, a number), and the studyset screen puts it into words: "Step 2:
unknown "type": quiz." or "Schritt 2: unbekannter „type“: quiz.". The
format's own field names stay as they are in the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-07 12:28:03 +02:00
918e10bb2b
feat(app): a Pomodoro timer on Home, in the notification and in the top bar
Home has a Pomodoro timer (decided 2026-10-07, after Goodtime): the
profile it runs, chosen there while no timer is set, the time left of
the phase, and Start, Pause or Resume, Skip and Stop. While studying, a
small countdown sits in the study screen's header, and a tap pauses it
or goes on. A phase that ends leads to the next, which starts by itself
where the profile says so and otherwise waits, paused at its full
length.

Profiles follow the person to every device, in their settings (schema
4, still written as schema 3 while the profiles are as they come, so
older apps go on reading the settings): Classic, 25 minutes of focus,
5 of break and 15 after four, and 52/17 without long breaks, built in;
both can be changed, more added and deleted, from Home's card or from
Settings. A profile can start breaks and focus by themselves, and keep
the device quiet while focusing. The running timer is the device's own,
kept in the person's folder: closed and opened again, the app catches
up with the phases that ran out meanwhile.

Android: the app's own foreground service (Kotlin, specialUse, as
Goodtime does) shows an ongoing notification counting the phase down,
with Pause or Resume, Skip and Stop; on Android 16 it is a Live Update,
its progress bar the profile's cycle, each phase a segment, focus in
cobalt and breaks in copper. An exact alarm (USE_EXACT_ALARM) alerts
with sound and vibration when the phase ends, also with the app
closed, and Do Not Disturb goes on while focusing once the person
allowed it, the filter before given back afterwards. No notification
plugin: flutter_local_notifications has Live Updates only in a
prerelease that needs compileSdk 37; androidx.core 1.18, which the
build resolved already, has every API needed.

Linux, over the session bus (package:dbus, already in the build): where
the desktop shows icons in its top bar (GNOME with the AppIndicator
extension, which Ubuntu has built in; KDE) the timer counts down there,
the buttons in the icon's menu, as a StatusNotifierItem written in Dart
on the names and paths the snap's desktop plug allows; elsewhere a
notification with the buttons says until when the phase runs. An alert
with sound ends each phase while the app runs, and GNOME's banners stay
off while focusing, through gsettings. xdg-desktop-portal's Background
status, the planned fallback, serves Flatpaks only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-07 12:28:02 +02:00
d42afb078a
feat(app): the library's options move, import into and set how a studyset is studied
A studyset's options in the library now offer, as on its own screen,
Edit, Move to…, Study options, Import from Anki, Archive and Delete.
Moving goes through the same sheet and says where the studyset went;
importing reads an Anki deck into it as Add material does.

Study options say how a studyset is studied, on every device: how many
new cards it starts a day (by default as the person's study settings
say), how many reviews it brings a day (no limit by default; cards in
their learning steps come anyway), and whether reviews or new cards
come first, or the new ones spread evenly among the reviews. They live
in the studyset's payload, schema 3; a studyset without them is still
written in schema 2, so that older apps, which skip a payload in a
newer schema whole, keep seeing every studyset nobody gave options.
Editing a studyset keeps its options, and Reset to defaults takes them
away.

The study queue takes each studyset's limits for its own cards and the
order of the studyset studied; a card's schedule now knows when it was
last reviewed, to count the reviews of the day. Sessions, the round's
end and the library's badges all count the same way, the badges now
with the person's own number of new cards a day too.

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