Commit Graph
3 Commits
Author SHA1 Message Date
jcoffey-dev 0fe75b280b Link the documentation from the profile menu
docs.ihasmail.org is where installing, configuring and using ihasmail
are explained, and nothing in the app pointed at it. The profile menu is
where someone looks for the things that are about the app rather than
about their mail, so it goes there, above Settings, and opens in a new
tab: reading the docs is something you do beside your mail, not instead
of it.

`MenuItem` renders a real anchor when given an href, rather than a button
calling window.open. The browser's own handling of a link comes with it --
middle-click, a modifier-click, "open in new tab", the address on hover,
copying it -- none of which a button offers however carefully it is
scripted, and all of which someone expects of a menu entry that leaves the
app. Items without an href are the button they always were.

It also needed a line of CSS. The global rule for `a` coloured and
underlined the one entry that is a link, so the menu had a blue underlined
item among four plain ones, which reads as a mistake rather than a
distinction.

Verified against the mock: the entry sits above Settings, is an anchor to
https://docs.ihasmail.org with target=_blank and rel=noopener noreferrer,
and computes to the same colour, size and decoration as Settings beside
it.
2026-08-27 15:34:30 -07:00
jcoffey-dev 2518605126 Custom date and time pickers that follow the configured format
Browsers render <input type="date"> and datetime-local in their own locale and
ignore the page's, so #1 left a German user on an English browser reading
22.11.2025 everywhere but still entering dates through an mm/dd/yyyy widget.
#3 makes the case that people use the picker rather than typing, which is
where the AM/PM mistakes happen.

New DateField and DateTimeField (web/src/ui/datefield.tsx) replace all nine
native controls — event editor (all-day and timed start/end, recurrence
until), out-of-office, contact birthday, advanced search. They take and emit
the same ISO strings the native inputs did, so call sites barely changed.

Each is a text box in the configured order plus a popover: a month grid
(week start from settings, locale weekday and month names, today and the
selection marked) and, for date-times, a list of times in the configured
clock. Keyboard: arrows move by day, PageUp/PageDown by month, Home/End
across the week, Enter picks, Escape closes, ArrowDown opens; the focused day
holds DOM focus so screen readers follow, and the dialog has an accessible
name (Popover gained an ariaLabel prop).

Text entry is lenient — the configured order with any separator, unseparated
digits (221125), day and month alone, non-Latin digits, and bare ISO always;
times take 18:23, 1823, 6:23pm, 930. What will not parse reverts on blur
rather than clearing the field, and impossible dates like 31 February are
rejected instead of rolling into March.

Editable boxes stay Gregorian and Latin-digit even where display does not
(fa-IR, th-TH, ar-EG): the locale's field order and separator are kept, but a
Buddhist-era year in a text box cannot round-trip against a Gregorian grid.
Noted in the README.

The out-of-office format echo added in #2 is gone — the fields now show the
right format themselves.

Closes #3
2026-08-23 13:12:17 -07:00
jcoffey-dev 645b8b510f ihasmail 2.0: rebuild as Stalwart-first JMAP webmail
Replace the FastAPI/HTMX prototype with a Node/Hono session proxy and a
React 19/Vite SPA. Mail (conversation view, search operators, labels,
sanitised HTML, privacy image proxy, invites, undo send, templates),
calendar (month/week/day/agenda, invites, free/busy, categories,
context menus), contacts (JSContact, groups, vCard), files, Sieve filter
builder (incl. filter-from-message with retroactive apply), vacation,
identities with default + Reply-To, PWA/mobile layout, push via SSE,
in-memory mock Stalwart for dev, Docker + CI.
2026-08-23 01:07:13 -07:00