Commit graph halkyon/apps/todo/halkyon_todo_flutter/test/feature
Author SHA1 Message Date
f5b657dfad
feat(todo): reminders at a time of their own planned and set in a task's sheet, durations in its date sheet
planReminders plans each reminder at a time of its own of an open task,
whatever its date, under an ID of its own; the notification says
"Reminder" for a task without a time. The task's sheet always has its
reminders' row: those before its time where it has one, those at a time
of their own each with its remove button and "Remind at a time" (a day,
then a time), the permission asked as a first one is chosen. The date
sheet sets a duration once there is a time (none, 15 minutes to 4
hours, as Todoist's), a time cleared taking it with it. Recorded as
ADR 0033, D18 (the developer's, 3 Nov 2026).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-04 09:31:55 +01:00
d40eca6e50
feat(todo): quick add reads on before a day, durations, every !30m and !1pm
`on` (German `am`) before a day is taken with it, as `at` before a time;
`for 2h`, `for 1h30m`, `for 90 min`, `für 1,5 Std.` set the date's
duration where there is a time, and stay text without one; every `!30m`
counts, each once, sorted, a task without a date due at the latest; and
`!1pm`, `!13:00`, `!tomorrow 9am`, `!Monday 8:30` are reminders at a time
of their own, a time without a day on the task's day, else the next to
come. Todoist's newsletter's four examples parse whole (ADR 0033, D18).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-04 09:31:55 +01:00
3c68a22a5f
feat(todo): a task holds reminders at a time of their own, and keeps the fields it doesn't know
ReminderTime is a day and minutes after midnight, the wall clock without
a zone as TaskDate's; a task's reminderTimes are written as
[{"day", "time"}] and left out where there are none, so older payloads
read with none. The payload's schema stays 1 (as D17's view): what a
newer version wrote at its top that this one doesn't read is kept in
TaskContent.unknown and written back beneath the fields it knows, so a
task changed here keeps it (ADR 0033, D18).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-04 09:31:54 +01:00
e26ba47fb9
feat(todo): Snooze on a reminder on iOS, macOS and Windows (ADR 0033, D4)
Apple's systems take actions from categories registered at start: one
for each length a snooze can be, its action in the language the app
starts in, not to the foreground, so that iOS snoozes in the plugin's
isolate with the app closed (AppDelegate registers the plugins for it).
Windows hands back only the button's arguments, which carry the
notification's ID and payload. macOS and Windows launch the app for an
action while it is closed, and the gateway snoozes what launched it as
it starts. Not yet tried on any of the three devices.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 21:57:00 +01:00
0b6f79244f
feat(todo): a project's Calendar as a month on wide windows (ADR 0033, D17)
From 720 pixels of the Calendar's own width on, a month grid in place
of the agenda: the month's weeks from the week's first day, the days
of the months beside it muted, each day with as many of its tasks as
fit and the rest counted, opening the day's tasks in a sheet; past
days with their overdue and done tasks. A task held and dropped on
another day moves there (moveTask), a day's free space tapped adds a
task on it, a line tapped opens its task.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 21:57:00 +01:00
51ebed41cd
feat(todo): Settings' Tasks and Reminders, with Snooze on a reminder (ADR 0033, D4)
Settings gains Todo's own groups, kept in the person's sealed settings
row on every device. Tasks: the weekday weeks start on (the language's
unless set), which the week strip, the date and repeat pickers and the
filters follow; and whether a recurring task done opens its sub-tasks
again (on at first). Reminders: an automatic reminder (none at first)
that TaskRepository writes into a task gaining a time without reminders
of its own, and how long a reminder is snoozed for (15 minutes at first).

Each reminder's notification has a Snooze action on Android and Linux:
the reminder comes back that much later under an ID of its own,
scheduled from what the notification carries, so on Android with the
app closed too (the plugin's ActionBroadcastReceiver declared); the plan
of the person's reminders leaves snoozed ones alone. iOS, macOS and
Windows get it later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 20:25:15 +01:00
2939437c74
feat(todo): a project's Calendar, Upcoming's Display and its 3-day grid (ADR 0033, D17)
A project's Display gains the Calendar layout: Upcoming's week strip
and agenda, now shared as DayAgenda, over the project's tasks it keeps,
with No date beside the month and Future occurrences, each repeating
task also on the days it will come back (calendarOf on Repeat.next),
muted, neither ticked off nor dragged.

Upcoming gets a Display of its own, the same sheet over another target
(DisplayTarget): Agenda or 3-day, done tasks, future occurrences,
sorting, the filters by deadline, priority and label, and in the grid
Colouring by priority, label or project. It is kept in the person's
settings, one sealed row under an ID keyed by the account in the new
synced table todo_settings (migration settings: the table, its index
on spaceId and its foreign key to the space, cascading on delete).

The 3-day grid shows today and the two days after, stepped or swiped
three at a time: tasks without a time all day, timed ones as blocks as
long as they last, overlapping ones side by side (layOutDay). A long
press on a half hour adds a task there for half an hour; Overdue opens
the overdue tasks with Reschedule.

The board's separator builder names its BuildContext, as the root's
analyzer plugin asks (never_discard_build_context).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 20:01:00 +01:00
7d1de304c8
feat(todo): each project's Display: completed tasks, grouping, sorting and filters, synced (ADR 0033, D17)
- A Display button beside a project's menu (the Inbox's too), a dot
  on it while the project shows otherwise than at first, opens its
  sheet: completed tasks, grouping (date, deadline, added date,
  priority, label), sorting (name, date, deadline, added date,
  priority), filters by date, deadline, priority and label, and
  Reset all.
- The choices live in the project's sealed payload (ProjectView,
  written only once set), so every device shows the project alike.
- Grouped, the groups stand in the sections' place under pinned
  headings; rows are dragged only while sorted by hand by sections.
- Show done tasks moves from the menu into Display.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 18:41:12 +01:00
36f1e9a25c
feat(todo): tasks dragged into place or under another, the add button dropped where the task goes (ADR 0033, D16)
- A project's row, held, is dragged before or after another, or a
  little to the right to become its sub-task, or onto a section's
  heading; its sub-tasks go with it, and Order changed offers Undo
  (TaskRepository.place). The list scrolls at its edges.
- The add button is dragged onto a project's list to add the task
  between two rows, onto a day in Upcoming for that day, onto Today
  for today; dropped back on its place, an ×, it gives up.
- Holding a row now drags it; a swipe to the right selects it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 17:28:37 +01:00
4960234a63
feat(todo): tasks chosen together, quick add reading what is typed (ADR 0033, D14, D15)
- A section's heading stays atop a project's list while its tasks
  scroll beneath it (slivers, PinnedHeaderSliver).
- Upcoming's month unfolds in place beneath its strip, from its name
  or its handle; a button beside the month goes back to today.
- Tasks are chosen together: a row swiped right or held, or Select
  tasks in Today's, Upcoming's and a project's menu; a bar of date,
  move, labels, priority and more (complete, duplicate, deadline,
  delete) takes the navigation bar's place. A row swiped left asks
  for its date.
- TaskRepository.move moves tasks with their sub-tasks.
- parseQuickAdd reads #project, @label (an unknown one made),
  {deadline}, !!1 and p1 to p4, !30m, dates, times and recurrences
  (tomorrow 9am, Mon 18:00, ev Tue 7pm, every 2 days, every weekday),
  from a table of words per language: English, and German beside it.
- Each token is highlighted and shown on its chip; a tap keeps it as
  text, and a chip picked takes it out of the title.
- Quick add shows its title alone at first, its chips once typing
  starts, and the description and deadline behind its + (the
  description also from the down arrow).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 16:53:59 +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
666e8dbcbb
feat(todo): reminders on the device, Upcoming's week strip, the task pane and search (ADR 0033, D2, D5, D8)
A task with a time takes reminders, minutes before it, in its sealed
payload; each device plans the coming ones whenever the tasks change and
schedules them with the system through flutter_local_notifications
(Android, iOS, macOS, Windows; on Linux the running app shows them), at
the minute where Android allows exact alarms. Notifying is asked for
when a task first gets a reminder; signing out or switching person
cancels them. Upcoming gets its week strip: the month opening
Material's calendar, the weeks before and after, a dot under each day
with tasks; a day picked scrolls the agenda to it, and scrolling moves
the strip along. From expanded windows on, a task opens in a pane
beside the list rather than in a dialog. Search, from every tab's app
bar, finds projects by name and tasks by every word typed, in their
title, description or labels, whatever the case and accents, on the
device alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 12:16:19 +01:00
aa013f5a00
feat(todo): recurring tasks, set through a picker (ADR 0033, D7)
A task's date may recur: every n days, weeks (on which weekdays),
months (on its day, or its nth or last weekday), years, from its date
or from when it is done, until a day or for n times. Done, it moves on
to the next day after both its date and today, its deadline as far, its
time kept, its done sub-tasks open again and when it was done kept in
its payload; undo writes all of it back. The date sheet offers the rules
that fit the task's day and a rule of the person's own; rows show a
recurring date with its own icon, the task sheet the rule in words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 12:15:51 +01:00
030c62ddde
feat(todo): Today, Upcoming, Inbox, projects, quick add and the task sheet (ADR 0033, D8, D9)
The tabs hold the person's tasks: Today what is overdue (Reschedule
moving it all to a day, times kept) and what is due today; Upcoming the
overdue ones and the next four weeks day by day; Inbox and each
project's screen from Browse the tasks above and in their sections, done
ones on asking; Browse the projects with their open counts and the
labels. A task's row shows its check in its priority's colour, its date
in the colour of how near it is, its deadline, its sub-tasks done and
its labels; quick add takes its title, date, priority, project, labels
and description and stays for the next; its sheet edits all of it, adds
sub-tasks and deletes it with them after asking. Colours are the
palette's, cerise for overdue and P1 against the strawberry wash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 10:25:34 +01:00
bd3710ae58
feat(todo): the person's tasks, sections and labels, sealed and synced (ADR 0033, D6)
A table's rows are sealed for their table and row by one SealedRows,
which the repositories of projects, sections, tasks and labels share,
each table with its own sync gateway, a deletion blanking its rows first
in one transaction. A task's payload holds its title, description,
project, section, parent, place, date (a day, an optional wall-clock
time and duration), deadline, priority, labels and when it was done;
deleting a task deletes its sub-tasks, and a project or a section goes
with its tasks. Rows that don't open show locked; a device without the
account's keys writes nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-01 01:14:54 +01:00
60a8f5b617
feat(todo): the person's projects, sealed and synced, the Inbox made once (ADR 0033, D5, D6)
TodoPerson opens the person's own sync database in their folder,
halkyon_app's SyncService behind AppCompatibility, their key (TodoKeys,
Train's copied with Todo's own key IDs) and their projects, and closes
them in that order, the key last. A project is sealed for its row; a
readable, foreign or moved row shows locked, and a device without the
account's keys reads and writes nothing. The Inbox is the row under an
ID keyed by the account, so every device makes the same one and the
instance can't tell which it is; it can't be deleted. Settings shows
Sync's card first and the cog its dot while sync fails, as Learn's.

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