Commit Graph
6 Commits
Author SHA1 Message Date
LeoVasanko afa6b967e6 contact messages: unified overlay, corner ✉️ icon for everyone
The admin inbox leaves the short-lived /_m page and joins the visitor panel as one overlay (ContactOverlay shell over paskia's shared blur backdrop, centered dialog, full-screen on mobile): the corner ✉️ icon opens the visitor thread for visitors and the wider sidebar inbox for admins, while {contact:} trigger buttons always open the visitor side so admins can test both. The icon highlights unread state without extra connections: visitors via localStorage seen/last-admin timestamps, admins via the contact_unread count added to the /_api/settings probe, both kept live by the bundle once loaded. MessagesView owns its admin socket only while the overlay is open.
2026-09-28 01:37:37 +00:00
LeoVasanko 9a2435f03a contact messages: centered panel on paskia's shared blur backdrop
The panel was a right-docked sidebar with its own translucent backdrop. It is main content: now centered at the paskia dialog's dimensions (min(36rem,100%) x min(42rem,92vh)), full-screen below 36rem, holding the refcounted global blur backdrop (z 1099) while open with the panel's click-catch overlay at 1100 (below the auth iframe at 9999). Escape closes too.
2026-09-28 01:04:33 +00:00
LeoVasanko f4d1f0ac58 contact messages: optional unvalidated email, plain relative timestamps
Email is no longer required and its format is not checked anywhere
(placeholder notes it's optional); only the name gates the first
message. Timestamps are just the analytics relative format — no full
date on hover.
2026-09-27 18:31:21 +00:00
LeoVasanko 67c19230b4 contact messages: visitor identity, relative timestamps, alternating headers
- The first message of a thread must carry name + email introducing the
  visitor; the panel shows the two fields until the thread has an
  identity (send stays disabled while they look empty, so the draft is
  never lost), prefilled from and saved to localStorage. The identity
  is stored on ContactThread (msgspec defaults — old databases decode
  unchanged) and fixed afterwards; it labels the visitor's messages
  instead of 'you', and the admin inbox lists threads by name with the
  email as a mailto in the thread header.
- Timestamps use the analytics relative formatter (formatWhen), with
  the full date on hover.
- Message headers alternate alignment (own messages right, theirs
  left) as the visual side cue; the sent-from page link is dropped
  from the display (kept as stored metadata).
- Composer gains a sendDisabled prop for the intro gate.
2026-09-27 18:19:03 +00:00
LeoVasanko e810c5f664 contact messages: plain thread view instead of bubbles
Drop the bubble styling (muted/accent backgrounds, rounded boxes,
left/right alignment) from both the visitor panel and the admin inbox:
messages now stack full-width as a flat thread with hairline
separators, a small muted meta line (author + time) above the body,
and 'you'/'visitor' fallback labels carrying the side distinction
instead of color.
2026-09-27 17:41:59 +00:00
LeoVasanko eea89032a2 contact messages: visitor panel and composer
The composer is a constrained contenteditable (plain-text paste,
toolbar formatting, upload chips for images/attachments) serialized to
a Markdown subset by richtext.js — the wire format is text and the
server re-renders it, so no user markup ever reaches a page. Uploads go
to /_contact/files with the session token (admins share the component
via /_api/files). ContactPanel shows the thread pushed live over the
activity socket: pagerite.js lazy-loads the bundle on trigger clicks,
routes socket pushes to it, re-registers the session token on every
reconnect (the resync), and dots trigger buttons on unread replies.
2026-09-26 01:11:14 +00:00