Commit graph halkyon/apps/learn/halkyon_learn_flutter/test/feature/studyset
Author SHA1 Message Date
9868dc27c6
feat(learn): a studyset's subject, picked from a fixed list (ADR 0041)
A top studyset is filed under one of 44 subjects in six groups (the
developer's decisions of 9 and 10 Nov 2026): languages as one, computing
in five, Other / not sure last. Each has a Lucide icon and a default
colour, which picking it gives the studyset, its own to change from then
on. The studyset's sheet picks it (pickSubject); a sub-studyset shows its
top studyset's (subjectOf) and offers none. The payload keeps it as
`subject` (schema 8), so archives and published studysets carry it; an
ID this version doesn't know is kept and reads as none.

Whats-New: A studyset can now be filed under a subject, which gives it that subject's colour.
Whats-New-De: Ein Lernset lässt sich jetzt einem Fach zuordnen, das ihm dessen Farbe gibt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-10 19:20:49 +01:00
f47f6b23b5
fix(learn): a tab whose material is in its topics says so in the middle, as an empty tab does
The tab saying that its material is in the studyset's topics stood at the
top of the room below the tabs, while an empty tab's message stands in
its middle (SliverCentered), so switching between them moved the message
up and down (the developer's review, 9 Nov 2026). It stands in the middle
too now.

Whats-New: A studyset's tab whose material is in its topics now says so in the middle, as empty tabs do.
Whats-New-De: Ein Tab eines Lernsets, dessen Material in seinen Themen liegt, sagt das jetzt in der Mitte, wie leere Tabs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-10 14:22:59 +01:00
920e1c6c13
perf(learn): Delete now leaves Recently deleted at once
Deleting a studyset for good blanks and deletes every card, note, path
and PDF of its subtree before the studyset's row goes, which took about
3 s while the studyset stayed in Recently deleted. Now the repository's
Recently deleted leaves it out at once (StudysetRepository.leaving and
stay, applied to the value last read without reading again), the
deletion runs in the background, still one at a time in
StudysetDeletions' queue, and where it fails the studyset shows there
again, read anew with what is left of it, and a snack bar says so.

Whats-New: Delete now in Recently deleted takes a studyset away at once.
Whats-New-De: „Jetzt löschen“ unter „Zuletzt gelöscht“ entfernt ein Lernset sofort.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-08 11:48:40 +01:00
648dfe4051
refactor(learn): the editor's general parts move to halkyon_editor (ADR 0033, D37)
Todo stores editor documents too, so the document, the editor, its view,
the format bar, links, the clipboard, scripts and EditorBlocks move, with
their strings and tests, to a shared package on the same appflowy_editor
fork. What is Learn's alone stays in Learn on top of it, and what the
editor took from it directly is inverted: EditorBlocks gains textMarks,
formatActions and onEditorClosed, RichContentEditor a wrapEditor, and an
InsertableBlock's name takes the BuildContext. Learn's screens use
LearnContentEditor and LearnContentView, which add Learn's blocks and the
grammar check. Learn behaves as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-07 21:49:48 +01:00
df713431dd
feat(learn): the lock beside a studyset no longer changes its privacy, which Edit does
The developer's review of 3 Nov 2026: a studyset is made private, or
non-private, in Edit alone. The lock's sheet still says what its privacy
means, offers publishing one that isn't private, and finishes one only
partly private.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-04 09:32:05 +01:00
a7904bac05
feat(learn): a studyset is made private in Edit, no longer from its options
The developer's review of 3 Nov 2026: Make private and Make non-private
leave a studyset's options (its card's menu, its screen's); a top-level
studyset's Edit has a Visibility section instead, its switch making it
private, or non-private, at once once the person agreed in the dialog as
before (ADR 0019), not on Save, and what that means behind the question
mark. A topic's Edit offers none, its privacy being its tree's. The lock on
a studyset's card still explains its privacy and keeps its own button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-04 09:32:04 +01:00
b7b0b937fe
feat(app): one Profile for every app, the person's own tab first, then each app's (ADR 0014)
The public profile was already one per person for every service of an
instance (the register, ADR 0016); its app side was Learn's alone. It
moves into halkyon_app: the model, the repository on the module's
endpoints, the form, the avatar drawn on the device and the sheet with
someone's profile. They take the Public prefix (PublicProfileRepository,
BasePublicProfileGateway), as Train's own ProfileRepository holds the
body's figures. AppDependencies gains profiles and files, the picker the
avatar is chosen with, which moves out of Learn too.

HalkyonProfile is every app's Profile screen: the person's own tab first,
the same in every app (the account and the ways they sign in, the app's
own cards, then the public profile), then the app's own tabs, folding into
the title. Learn adds its inbox and Statistics. Train adds Progress, Days
and, where nothing records, Plans, and so opens on the person's tab, no
longer on Progress. Todo, which has no Profile tab, opens it from a row at
the top of Browse, where Todoist keeps the account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-02 11:11:11 +01:00
a0bb75f1ad
feat(learn): pick up learning on Home, the studysets studied latest first, and Progress closer to Vaia's
Home gets a widget of its own, Pick up learning, below the goal: the
studysets at the top of the library that were studied, the one rated last
first, so one studied long ago sinks. Three show, the others behind Show
more. Each shows its name, which opens it, how much is learnt, when it was
last studied, and today's task (cards to review, new cards to learn), which
starts studying it, outlined while reviews wait. The progress is the
library's, worked out once for every screen; when each was last studied
comes from the reviews Home reads anyway. With nothing studied it takes no
room.

A dashboard arranged before it gets the widget below the goal, wherever
the goal is: a widget a layout misses now goes after the one before it in
a new dashboard, no longer at the end.

On a studyset's Progress, the tiles are filled without an outline, To
review has a history icon (amber while cards are due), the learnt bar is
thicker, and the exam follows the figures, as Vaia asks for its date
there: an invitation to choose it, opening the study plan's sheet, or,
once chosen, how ready the person is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-02 09:17:07 +01:00
5641285d31
feat(learn): Explore by what a licence allows, a skeleton while the library loads, and an assistant's agreement per provider (ADR 0005, rule 12; ADR 0021, D66)
- Explore filters by what a studyset's licence lets a learner do: adapt
  it (no NoDerivatives) and use it commercially (no NonCommercial),
  which the instance reads from the release's licence
  (ExploreQuery.adaptable, commercial) and the app the same way
  (LicenseUse). An instance from before ignores both.
- While the studysets are read, the Library shows shimmering skeletons
  of their cards rather than a spinner: halkyon_ui's new Shimmer and
  SkeletonBox, still where the system asks for no animations.
- The scope's "Include private studysets" is offered only while the
  person has a private studyset.
- An agreement to what goes where is per provider (protocol and host):
  agreeing to one assistant agrees to every assistant of that provider,
  those granted later too, and the agreement sheet says so. No
  migration: it is written on every grant of the provider, so taking
  one back keeps it for the others, and read per provider from any of
  them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-02 05:19:18 +01:00
b908019969
feat(todo): dialogs on the desktop, the tabs reordered, a task's path and menu (ADR 0033, D11 to D14)
- halkyon_ui: showAdaptiveSheet shows a dialog on Linux, macOS and Windows
  at every width (bottom sheets stay on phones and tablets below expanded
  windows), so Learn and Train follow; SheetScaffold takes a heading in
  the title's place and may leave out its close button.
- Todo: the tabs are Inbox, Today, Upcoming, Browse, Today still opening;
  `serverpod start` launches the app on Linux, as it has no web build.
- A task's sheet shows where the task is (its project, an icon once tasks
  are above it, and the tasks above it, each opening what it names) and a
  ⋮ menu in place of its close button: when it was added (its UUID v7),
  Duplicate with its sub-tasks, hiding its done sub-tasks (synced in its
  payload), Close in the pane, Delete after asking. The description's icon
  stays by its first line.
- A row names its project and section at the end of its date's line; every
  menu entry has its icon.
- Learn: a studyset's path starts at the Library tab's icon, named by its
  tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 16:53:38 +01:00
bf46f8c460
feat(learn): a private studyset goes to an assistant only once agreed
ADR 0021, D9 and D17. Before a question sends a private studyset's
content to a remote model, through the parts chosen or a wider reach
with private studysets switched on, a warning names the studysets, the
provider's host and its terms (where checked: Anthropic, OpenAI,
Google, OpenRouter), and is asked once per studyset and assistant: the
agreement is kept in the person's sealed settings (schema 13,
privateAgreements, folded only where both rows hold it), shown in the
studyset's privacy dialog with Take back, and marked on the folded
button while it holds. Follow-ups and Try again ask again once taken
back, as the scope keeps where the parts came from (partsFrom). No
warning for an own assistant on this machine (loopback or localhost,
halkyon_llm's LlmEndpoint.onThisMachine); the local network may be
shared.

Texts that step 3 made untrue: the consent sheet now says what an
assistant looks up goes too and that conversations are kept encrypted
for the person's devices; the privacy dialogs no longer mention
showing a studyset to Claude; the privacy page says what is looked up
and when a private studyset goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-26 07:17:09 +01:00
4e33133733
feat(base,app)!: GitHub signs nobody in any more (ADR 0020, D36)
Every account signs in with SimpleLogin or a password now, so GitHub
goes from the module, the shared app package, Learn and Todo, ahead of
ADR 0017's GITHUB_SIGN_IN_ENDS.

- halkyon_base: no `gitHubSignIn` endpoint, GitHub identity provider or
  GitHub refusals; no `githubClientId`/`githubClientSecret`, no
  `GITHUB_SIGN_IN_ENDS` and no `forgetGitHubAccounts`; the register
  loses `account-with-github`. `SignInWays.gitHub`, the basics'
  `gitHubClientId` and `gitHubSignInEnds`, and `PasswordRefusal`'s
  `signInAgain` and `noAddress` go. A first password takes a code
  mailed to the person's own address; an account without one sets none
  (`wrongCredentials`).
- Learn's server: `instance.info()` without `gitHubClientId`, the
  pruning without GitHub, and `minimumAppBuild` 24, as builds up to 23
  (v0.20.0) require `SignInWays.gitHub`: the server deploys with the
  release of build 24.
- halkyon_app: no GitHub button or problems on the start screen, no
  password offered after a GitHub sign-in, and `ServerpodAuthGateway`
  without the browser half only GitHub used (`(client, base:)`). The
  account section offers a first password only to an account with an
  address. `LoopbackWebAuth` and the apps' schemes stay, SimpleLogin's
  ways back.
- Learn's Profile lists no GitHub; the texts go (English, German).
- Serverpod's `serverpod_auth_idp_github_account` stays, as its
  migrations make it; a row goes with its account, and ADR 0020's D36
  gives operators the SQL to delete those left.
- deploy/: compose.yaml and .env.example without GitHub. The READMEs,
  AGENTS.md files and ADR 0017 amended.

BREAKING CHANGE: builds up to 23 can't read the instance's answers
about an account's ways in; minimumAppBuild is 24.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-26 07:16:39 +01:00
5b9df73756
feat(app)!: no anonymous accounts on the device (ADR 0020, D4, D25)
Every account has a way in, so the apps make no anonymous account any
more. The start screen shows whenever nobody is signed in, a first
start included, and offers SimpleLogin, a password and GitHub for those
who have it, with no start without an account. An instance out of reach
is said so, with Try again, and one offering no way to create an account
too. An anonymous account's session left from before is deleted as the
app starts (D25), falling back to signing out on the device.

What only anonymous accounts needed goes: signing in anonymously, the
signed-out mark, adding GitHub to an account and switching to a GitHub
account from the Profile tab (with its Cancel, the only one), an
anonymous device's own keys, the warning that signing out deletes the
account, and the texts about keeping progress. Settings says on which
instance the account is signed in. Learn's publishing, reports and
suggestions and its learner count no longer ask whether the person has
an identity: everyone signed in has one.

The server still offers anonymous sign-in until the next commit, so
older apps keep working until v0.20.0 raises the minimum build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-24 16:14:37 +02:00
9fb1ab2f6c
feat(studyset): a studyset's marker says what the instance sees of it (ADR 0019)
The developer's decision of 21 Oct, on the library's cards and the
studyset's Share in its action row alike:
- a lock: private, end-to-end encrypted;
- an open lock: readable by the instance, not published;
- a globe: published.

The lock and the open lock open one dialog saying what that means and
changing it (Make non-private; Make private, or Publish…, which opens the
Publish sheet, while it isn't private); a topic's dialog says its privacy
is its tree's. The globe opens the Publish sheet, whose status for a
studyset not published now says so ("Not published") with an open lock,
as "Private" means something else now. Texts in en and de.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 14:13:10 +02:00
e368bba2dd
feat(privacy): a private studyset's files are sealed with its key (ADR 0019, D5)
- `AssetRepository` seals a file of a private studyset with its tree's key
  for its asset row before hashing it (`AssetSealing`, which `Privacy`
  does): the row's hash and size and the file uploaded are the sealed
  file's, the upload says it is encrypted, and the row's payload, sealed
  too, carries the file name and the hash of what was sealed (asset
  schema 2). A download is checked against the row's hash, opened for its
  row and checked against what was sealed. This device keeps the sealed
  file to upload and the opened one, by its own hash, for what reads files
  by path.
- The same file is a row per key: in a private and a readable studyset, or
  two private trees, it is two.
- Every place adding a file names its studyset: the editors' pictures and
  sounds (`StudysetFiles`, which every screen of a studyset and the PDF
  reader set), PDFs and screenshots, Anki imports, copies and their updates
  (a copy's top studyset is made first, so its files take its key), and
  accepted suggestions (by their item's tree).
- Making a tree private or not, or moving a topic into another tree, moves
  its files: each under another key is added anew under the tree's, the
  content names the new row (whole `asset:` values and a PDF's file, never
  text), and the old row is blanked and deleted once nothing else names it.
- Tests: a private studyset's file never uploads readable; a sealed file
  moved to another row, or under a key not open here, doesn't open; a
  changed file is refused by its hash; one row per key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 14:13:10 +02:00
9cdd4859d1
feat(library): offer once to make every studyset from before private (ADR 0019, D4)
New studysets are private; those from before stay readable until the
person chooses. The library offers once, on this device, where it can
encrypt and some top-level studyset isn't private: Make all private, or
Not now; either answer is remembered (`private_offer` in the person's
folder) and the offer goes. Each studyset's menu changes it later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 14:13:09 +02:00
0e10afcc68
feat(studyset): make a studyset private or not, and what a locked one shows (ADR 0019)
- A top-level studyset's options make it private, with everything inside
  it, or non-private again, after a dialog saying what changes and that
  the instance's backups keep readable copies until they expire; a device
  without the account's keys says how to get them there.
- A locked studyset (its key doesn't open here) is titled Locked, says
  why when opened, and offers only Delete.
- Publishing names the person's tags as the device reads them, and says
  what to do when the studyset is private or a tag has no name.
- The export sheet says an archive is readable by whoever has the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 14:13:09 +02:00
649499be23
chore: Halkyon Learn moves into apps/learn
Its server, client, app and curator, and the tools that write its
assets (maps, Anki fixtures, icons), as they are; paths are fixed in
the commits that follow.

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