From c7a6f5f1b034e5449955e6eb7caf283c02bde314 Mon Sep 17 00:00:00 2001 From: yiekheng Date: Sun, 10 May 2026 12:59:13 +0800 Subject: [PATCH] feat: humanise cron in list summaries; magic-byte detect HEIC; sidebar brand link tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three threads from the recent UX iteration: 1. Reminder list / detail no longer shows raw "Cron: 32 11 * * *" ---------------------------------------------------------------- `describeRecurrence` for a kind=cron spec used to emit "Cron: " verbatim, which is unreadable on the list row's recurrence line. New pure helper `describeCronRule(rule)` parses the cron shapes the recurrence picker produces and renders them as natural sentences: "0 9 * * *" → "Every day at 09:00" "0 9 * * 1-5" → "Every week on Mon, Tue, Wed, Thu, Fri at 09:00" "0 9 * * 1,3,5" → "Every week on Mon, Wed, Fri at 09:00" "0 9 1,15 * *" → "Every month on days 1, 15 at 09:00" "0 9 13 5 *" → "Every year in May on day 13 at 09:00" "30 17 1,15 1,4,7,10 *" → "Every year in Jan, Apr, Jul, Oct on days 1, 15 at 17:30" Multi-line rules ("0 9 * * 1\n0 17 * * 5") join the per-line descriptions with " · " for compactness in the list density. Long DOM lists (>6 days) collapse with a "+N more" tail to keep the line short; same convention the picker's per-row preview uses. Unrecognised shapes (e.g. "*/5 * * * *") fall back to the raw expression — better than swallowing entirely. 2. HEIC/AVIF magic-byte sniffing at upload ---------------------------------------------------------------- The mime-only check we shipped earlier missed iOS Safari's habit of uploading HEIC photos with Content-Type: image/jpeg. The file then made it to the bot, where Sharp's HEIF decoder plugin is missing, the thumbnail extraction failed, and the message went out without a working preview — read by the user as "image still not send". New helper `sniffUnsupportedImage(bytes)` reads bytes 4..11 of the upload and looks for the ISOBMFF "ftyp" marker followed by one of the brands Sharp can't decode (HEIF: heic / heix / hevc / heim / heis / mif1 / msf1; AVIF: avif / avis). Brand match is case-insensitive. Plain JPEG / PNG / unrelated ftyp brands like mp4 are not flagged. `uploadMediaAction` now runs the sniff against the buffered bytes before persisting, returning the same "Images are not supported, please re-upload images" error as the mime path. 3. Sidebar brand link → dashboard tests ---------------------------------------------------------------- Asserts the desktop