Commit Graph
5 Commits
Author SHA1 Message Date
jaredandClaude Opus 4.8 29ff16546a fix: avatar-decoration live-update + CDN override + profile 404; DND badge color
Avatar decorations (useAvatarDecoration.ts / ProfileDecoration.tsx):
- invalidateDecorationCache now notifies a per-user listener set (and clears the
  give-up counter), so changing your own decoration updates mounted avatars
  (timeline, member list) live instead of only after a remount. Concurrent
  re-fetches de-dupe via the existing `pending` map.
- Picker grid thumbnails use decorationUrl() instead of the raw DECORATION_CDN
  literal, so a VITE_DECORATION_CDN override no longer breaks the grid while
  real avatars work.
- Settings reads the full /profile/{userId} instead of the /{field}
  sub-resource, which 404s (console error) for anyone without a decoration set
  — matching the pattern already used by useAvatarDecoration.

Presence (Presence.tsx): PresenceBadge renders DND (unavailable + status 'dnd')
as red "Do Not Disturb" to match PresenceRingAvatar and the settings picker;
it was the lone outlier showing a yellow "Idle".

Bug-hunt findings from LOTUS_TODO. Two review agents (correctness +
upstream-behavior); gate-green (tsc, eslint, prettier, 914 tests, build). Both
flagged only pre-existing edge notes (in-flight piggyback staleness, 'dnd'
free-text collision shared with the ring avatar) — neither introduced here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 15:37:16 -04:00
jaredandClaude Opus 4.8 1b2142e6c4 fix(profile): fetch full profile for avatar decoration to avoid 404 spam
CI / Build & Quality Checks (push) Successful in 10m46s
CI / Trigger Desktop Build (push) Successful in 19s
useAvatarDecoration GET /profile/{user}/io.lotus.avatar_decoration returns 404 for
every user without a decoration (most users), which the browser logs as a failed
request — a console 404 per member. Fetch the whole profile (GET /profile/{user},
200 with all MSC4133 fields) and read the decoration field out of it instead. Same
negative-caching behavior; no functional change, just no 404 storm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 20:28:40 -04:00
jaredandClaude Opus 4.8 8192da5a12 fix(notifications): clear thread receipts on mark-read; cap avatar-decoration refetch
CI / Build & Quality Checks (push) Successful in 10m41s
CI / Trigger Desktop Build (push) Successful in 29s
Two federated-room bugs surfaced by the desktop build:

1. markAsRead only sent one unthreaded receipt at the main-timeline tail. With
   threadSupport enabled, thread replies leave the main timeline, so a reply
   newer than that tail was never covered — its per-thread notification count
   (which the room dot sums) lingered, so the unread dot never cleared even
   after reading. It also early-returned when the main timeline was already
   read. Now also send a threaded receipt at each unread thread's latest reply.

2. useAvatarDecoration never cached non-404 failures, so every avatar mount
   re-requested io.lotus.avatar_decoration for federated users whose homeserver
   403s/502s the field — a refetch storm that spammed the console and hammered
   our homeserver's federation. Now cache definitive rejections (400/403/404)
   and give up after ~2 transient (429/5xx) attempts per session.

Gates: tsc/eslint/prettier clean, build OK, 665 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 16:31:10 -04:00
jaredandClaude Opus 4.8 cf839e7345 fix(ui): avatar-decoration reliability, Saved Messages + Media Gallery redesign
CI / Build & Quality Checks (push) Successful in 10m30s
CI / Trigger Desktop Build (push) Successful in 9s
Avatar decorations: useAvatarDecoration cached ALL profile-field fetch
failures as "no decoration" permanently for the session. The member list
and timeline mount many avatars at once, so one rate-limited (429) burst
would wipe everyone's decoration until a full reload. Now only a genuine
404 (field unset) is cached; transient errors retry on the next mount.

Saved Messages panel — full redesign to match the canonical MembersDrawer:
- co-located BookmarksPanel.css.ts: toRem(266) + max-width:750px full-screen
  media query, replacing the old position:absolute/zIndex:100 mobile "modal"
  that had no backdrop or escape
- variant="Background" header; room avatars on each item (was a generic hash)
- priority tokens replace all raw opacity hacks; 3px borderLeft accent removed
- Escape-to-close; multi-line preview is now a proper folds Button (N38)

Media Gallery (N12): moved fixed positioning + width into MediaGallery.css.ts
using toRem(320) + a full-screen media query; border/header use config tokens;
added Escape-to-close on the panel (previously only the lightbox handled it).

Presence (SettingsTab / useUserPresence):
- N16: wrap presence-dot trigger in TooltipProvider; replace undefined
  --bg-surface with color.Background.Container
- N17: add escapeDeactivates + isKeyForward/isKeyBackward to the FocusTrap
- N19: align reader labels (usePresenceLabel) to the setter vocabulary
  (Online/Idle/Offline) so a chosen status matches the tooltip others see

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:21:29 -04:00
jaredandClaude Sonnet 4.6 bf1308dd55 feat: avatar decorations (P5-13)
CI / Build & Quality Checks (push) Successful in 10m30s
Trigger Desktop Build / trigger (push) Successful in 19s
256×256 APNG overlays from avatardecoration.com (open CORS CDN).
Stored in the user's Matrix profile as io.lotus.avatar_decoration via
MSC4133 so all Lotus Chat users see each other's decorations.

- avatarDecorations.ts: curated catalog of 110 original-IP decorations
  across 9 categories (Gaming, Cyber, Space, Fantasy, Elements,
  Japanese, Nature, Spooky, Cozy)
- useAvatarDecoration: per-user profile fetch with module-level cache
  and in-flight deduplication so concurrent renders for the same userId
  share one HTTP request
- AvatarDecoration: position:relative wrapper that overlays the APNG
  8px beyond the avatar on all sides; renders nothing when no decoration
  is set (zero cost for undecorated users)
- ProfileDecoration: scrollable grid picker in Settings → Profile,
  grouped by category with live preview; Save button appears only when
  the selection differs from what's saved
- Applied at all five avatar display sites: message timeline, members
  drawer, knock list, @mention autocomplete, notifications inbox

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 11:24:04 -04:00