screentinker/frontend/js
screentinker 65a24682f0
Stop schedules landing on the wrong date (#284)
Three separate defects all showed up as "I saved a schedule and it moved".

1. expandSchedule emitted two different wire formats. A one-off returned
   start_time untouched - a naive wall-clock string, which the browser parses
   in its own zone - while a recurring instance returned cursor.toISOString(),
   an absolute instant derived by reading that same string in the SERVER's
   zone. The browser converted it back and the two conversions do not cancel:
   an operator in Tokyo saving Wednesday 20:00 got Thursday 10:00 from a
   US-Central server. Only recurring schedules were affected, which is why it
   looked intermittent.

   The calendar was also the odd one out. services/scheduler.js compares
   start_time as a string and never builds a Date from it, so expandSchedule
   was the only place in the codebase treating a wall-clock time as an
   instant - the drawing disagreed with playback as well as with the browser.

2. Saving an edit moved the schedule to today. The save handler rebuilds
   start_time from `pendingCreateDate || new Date()`, and editSchedule()
   restored only HH:MM - it never recorded the date being edited. Changing a
   colour on a block dated 5 Aug rewrote it to this week. No timezone
   mismatch required; this one hit everybody and silently altered stored data.

3. A cancelled drag-create leaked its date into the next schedule.
   pendingCreateDate was cleared only on a successful save, and the modal's
   two dismissers are inline onclick="...display='none'" attributes that
   cannot reach that scope. The date is now assigned by every path that OPENS
   the modal, so no dismissal path can leave a stale value behind.

Tests assert the property rather than a literal: that the wire value is
wall-clock and that the day survives a server/browser zone mismatch in BOTH
directions. A literal-string assertion would pass just as happily with the
bug present on a differently-configured CI box. Both new files fail on the
parent commit and pass here; the schedule, calendar and timezone suites are
green at 85 tests.


Claude-Session: https://claude.ai/code/session_014kfhrUPit5MCqxeTQyqr56

Co-authored-by: Dan Walters <dan.walters@bytetinker.net>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:14:23 -05:00
..
components Merge pull request #254 from ChrisChrome/main 2026-08-11 15:45:39 -05:00
i18n Check what is IN a cached update, and add a way to throw it away (#274) 2026-08-14 08:37:05 -05:00
lib Preview a rotated display the way people see it, not the way its framebuffer is 2026-08-06 09:38:31 -05:00
views Stop schedules landing on the wrong date (#284) 2026-08-18 09:14:23 -05:00
agency-portal.js feat(agency): per-token upload folder — auto-created, subtree-confined (#158) (#171) 2026-07-12 21:23:25 -05:00
api.js Opt-in install statistics (#267) 2026-08-13 17:27:10 -05:00
app.js Merge pull request #254 from ChrisChrome/main 2026-08-11 15:45:39 -05:00
brand-prime.js fix(branding): inject instance branding into the app shell, no default flash (#76) 2026-06-11 09:30:23 -05:00
branding.js fix(branding): no ScreenTinker default flash on load/switch (#38) 2026-06-09 11:43:42 -05:00
i18n.js i18n: register Italian locale in language registry (followup to PR #2) 2026-05-11 20:05:09 -05:00
socket.js Surface the screenshot-request verdict as a toast 2026-08-07 08:52:19 +01:00
utils.js fix(dashboard): make auth-image hydration lazy by default (#182 follow-up) (#185) 2026-07-14 13:28:12 -05:00