Commit Graph
55 Commits
Author SHA1 Message Date
Lotus CIandClaude Opus 5.5 103c6f4624 fix(a11y): closing a header/sidebar menu returns focus to its button
CI / Build & Quality Checks (push) Successful in 1m53s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 11m15s
16 menus (room header, Home/Direct/Space sidebar tabs, create tab, lobby,
room-nav item, history visibility, client root) set
returnFocusOnDeactivate: false, so pressing Escape dropped focus to
<body> and a keyboard user had to start over from the top of the page.
That option was there so focus wouldn't be pulled back to the menu button
when an item opens a dialog; since ce8ed89f dialogs move focus into
themselves (their initial focus runs after the menu's return), so it's no
longer needed. The autocomplete menu (focus must stay in the editor) and
the two menus whose opener disappears are left as they were.

Checked: room header menu → Escape → focus on "More options" (was
<body>); menu → Leave Room → focus inside the Leave Room dialog on
Cancel, same as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-24 13:16:12 -04:00
Lotus CIandClaude Opus 5.5 ce8ed89fdc fix(a11y): 36 modal dialogs announce themselves and take focus (#185)
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
Most modals rendered a folds Dialog/Modal with no role and no name, and
their focus traps used `initialFocus: false`, so focus stayed behind the
modal and a screen reader never announced it.

- 32 dialogs with a visible heading: role="dialog", aria-modal,
  aria-labelledby → the heading (given an id), tabIndex=-1.
- 4 dialogs that already had a name (Leave Room, room topic viewer,
  server ACL, room-nav prompt): role + aria-modal.
- Their focus traps drop `initialFocus: false` for focus-trap's default
  (keep an already-focused autoFocus field, else the first tabbable
  element) with the dialog itself as fallbackFocus, so a dialog without
  a tabbable node can't crash the trap. Traps that live in a parent
  (UIA stages, Logout, Forward, Invite) get the semantics only.
- The file drop overlay is deliberately left alone (not a dialog).

Checked at runtime: Join with Address, Delete Message, Report Message,
Leave Room and Logout open as named dialogs with focus inside and close
with Escape (Tab first when a text field has focus — the shared
stopPropagation keeps Escape from discarding typed text, by design).
The axe e2e spec (6 tests) passes; eslint warnings unchanged (46).
17 modals with no heading (image/file viewers, loading screens) remain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-24 13:06:10 -04:00
jaredandClaude Opus 5 082b8fc879 feat(sidebar): custom room sections via u.* tags (#108)
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
Room context menu → "Add to Section" submenu: every u.<name> tag in use
across your rooms as a checkable item, plus a "New section…" field
(validated: non-empty, ≤ 40 chars, no dots, unique). Toggling writes or
deletes the standard u.<name> room tag (order 0.5), so sections sync
across devices and other clients see the same tags. The menu row reads
"Sections: Raids, Off-topic" once a room is in any.

Home renders each section as a collapsible category between Favorites
and Rooms (alphabetical; members by tag order then name; the same
closed-state store and unread-only-when-collapsed behaviour as the built-in
categories). A sectioned room leaves the plain Rooms list but keeps a
Favorite / Low Priority placement. Empty sections don't exist by
construction; rename is retag (v2). Derivation in utils/roomSections.ts
with unit tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-20 15:05:30 -04:00
jaredandClaude Opus 5 4d4a76214a refactor(time): one timestamp formatter honouring the clock/date settings (#139)
CI / Build & Quality Checks (push) Successful in 1m30s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
Audit of every rendered time found five families of ad-hoc formatting:
the shared Time component + copies of its today/yesterday branch
(forwarded header, thread summary, read receipts, device tile, moderation
alerts, edit history), locale-default toLocale*String calls that ignored
the user's 12/24 h and date-format settings (scheduled tray, reminders,
schedule preview, notification snooze, bookmarks, threads list, search
cache line, room insights, media gallery), a hard-coded en-US date in the
activity log, and three relative-age variants.

utils/formatTimestamp.ts now holds the rules — today → time; yesterday /
tomorrow → day word + time; last 6 days → weekday + time; older → date +
time in dateFormatString — plus autoDate / time / date / dateTime styles,
formatDayDivider (full weekday), formatShortAge (room list) and
formatRelativeAge (list rows). useTimestampFormatter binds them to the
settings. 11 unit tests with an injected 'now'.

Visible changes are limited to consistency: 12 h times keep the existing
zero-padded hh:mm A; the a11y label and Created-by line use the user's
date format instead of a fixed long month.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-20 00:28:47 -04:00
jaredandClaude Opus 5 a475531b2b feat(calls): 'N Live' pill names who is in the call on hover/focus (#157)
CI / Build & Quality Checks (push) Successful in 1m51s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 6s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 1m37s
Tooltip (folds TooltipProvider, 300 ms) on the room-list Live badge listing the
call members' display names — deduped per user, capped at 6 + 'and N more' —
plus an aria-label with the same text so keyboard/screen-reader users get it
too (the badge is focusable). Names come from the same MatrixRTC memberships
that produce the count; no new data.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-19 12:18:20 -04:00
jaredandClaude Opus 5 26c70f5a1d fix(calls): sidebar voice-channel join respects the voice limit
channelFull was computed only in the prescreen; a second click on the
channel in the room nav joined a full channel. Extract
useVoiceChannelFull, use it in both places, and refuse with a
"Channel full (N/N)" toast.

Fixes #30

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-12 19:46:06 -04:00
jaredandClaude Opus 5 7c52027afb fix(rooms): serialize per-room rename writes so back-to-back renames survive
Local room names did a read-modify-write of io.lotus.room_names against
the SDK's local cache, which is stale until the /sync echo, so a second
rename issued before the first echoed overwrote it. Route through
createAccountDataListStore like user notes. Unit-tested with a client
whose setAccountData does not update the local store.

Fixes #17

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-12 14:48:35 -04:00
jaredandClaude Fable 5.1 2b66dcc08c fix(room-nav): expiring timed mute no longer clobbers a manual mode change
CI / Build & Quality Checks (push) Successful in 1m58s
CI / Trigger Desktop Build (push) Successful in 10s
unmuteRoom unconditionally reset the room to Unset when a timed mute expired
(in-session timer and boot-time restore alike), silently reverting a mode the
user had changed by hand during the window. Mute-timer helpers move to
muteTimers.ts; unmuteRoom now reads the live push-rule mode and only resets
when it is still Mute, always dropping the persisted timer. Unit-tested.

Fixes #21

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-12 02:08:03 -04:00
jaredandClaude Sonnet 5 3cc5f0cc6a fix(room-nav): drop pointless dynamic import of setRoomNotificationPreference
RoomNavItem.tsx already statically imported getRoomNotificationModeIcon
and RoomNotificationMode from the same module, so the two
`await import('../../hooks/useRoomsNotificationPreferences')` calls
(in unmuteRoom and handleMuteFor) never achieved real code-splitting —
verified by building and grepping dist/assets: setRoomNotificationPreference
landed in the same eager entry chunk regardless, since Rolldown can't
split a module already reachable via a static import elsewhere. Just
import it statically alongside its siblings instead. No behavior
change — confirmed via 3 independent investigations before starting
and 3 independent reviews of this diff before committing.

Closes LotusGuild/cinny#5

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 21:29:29 -04:00
jaredandClaude Opus 4.8 4708a17961 perf: memoize room-list sorts + gate DM-preview listener (PERF-2/4/5)
PERF-2 (RoomMentionAutocomplete): the #-mention list did
`useAtomValue(allRoomsAtom).sort(...)` inline — `.sort()` MUTATED the shared
allRoomsAtom array in place (reordering it for ~27 other consumers) and re-ran
the O(N log N) getRoom compare every keystroke. Copy then memoize:
`useMemo(() => [...allRoomsList].sort(factoryRoomIdByActivity(mx)), ...)`.

PERF-4 (SearchFilters): the room-filter A-Z sort ran every render; wrap in
useMemo keyed on [searchResult, roomList, mx].

PERF-5 (useRoomLatestRenderedEvent + RoomNavItem): the hook registered a GLOBAL
client `Decrypted` listener for every nav item, but its result is only used for
DM rows. Add an `enabled` param (default true) that skips all work + listeners
when false; RoomNavItem passes `!!direct`. The only other caller keeps the
default.

Verified behavior-preserving by two review passes (PERF-2 also fixes a real
shared-atom mutation bug).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 21:05:39 -04:00
jaredandClaude Opus 4.8 eaf6853910 fix(nav): harden draft indicator after review
Address findings from 2 review agents on the room-nav draft indicator:

- Icon semantics (a11y): Icons.Message read as message activity and
  collided with two existing bubble uses in the same row (call-chat
  toggle, mark-unread), especially next to the unread badge. Replace it
  with the composer's shared DraftDot (a small color.Success.Main dot),
  so both draft surfaces share one visual language. Rendered as a
  role="img" span with aria-label "Unsent draft" (reliably announced,
  unlike a bare aria-labelled svg).

- Precise thread-key filter: hydration skipped any draftKey containing
  '::', which would also skip an IPv6-literal server name in a roomId.
  Match '::$' (thread root is an event id) so only real thread drafts are
  skipped.

- Defensive hasMsgDraft: guard toPlainText so a corrupted/foreign draft
  value can't throw during a nav render.

- Clear the draft atom on send: the send / scheduled-send handlers reset
  the editor and localStorage but left the jotai draft atom set, so the
  composer DraftIndicator could show a stale dot after sending a restored
  draft. Add setMsgDraft([]) to both.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 11:48:35 -04:00
jaredandClaude Opus 4.8 c44ef8d795 feat(nav): draft indicator on room-nav items
Composer drafts persist per room, but nothing in the room list showed
which OTHER rooms had an unsent draft. Add a subtle chat-bubble icon on a
room's nav item when it has a message draft (and isn't the open room), so
half-written messages elsewhere are visible at a glance.

- Shared pure helper hasMsgDraft (utils/draft.ts, unit-tested) replaces
  the inline emptiness check; the composer DraftIndicator now reuses it.
- RoomNavItem reads a memoized selectAtom(draftAtom, hasMsgDraft) so a row
  re-renders only when its draft flag flips (the draft atom is written on
  room-leave, not per keystroke). Uses Icons.Message (pencil is reserved
  for the custom-name marker), muted, aria-label "Unsent draft".
- useHydrateMsgDrafts (mounted in ClientNonUIFeatures) pre-fills the
  per-room draft atoms from draft-msg-* localStorage on startup, so
  indicators are correct after a page reload, not only after revisiting a
  room. Thread drafts (key contains ::) are skipped; room-level only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 11:37:21 -04:00
jaredandClaude Opus 4.8 c2598d21cd fix(dp): address TPVR review findings (DP2 redo, DP4 dedup, DP15 gap)
- DP2: the earlier seed fix was ineffective (allInvitesAtom populates post-mount,
  so first render is still empty). Rewrite to track invite room ids and stay
  'unarmed' until the initial sync settles (+3s grace), notifying only for ids that
  first appear after arming — robust to the async population race.
- DP4: batch the mutually-exclusive tag writes via Promise.all so a failure surfaces
  a single toast instead of one per operation.
- DP15: route the two remaining StateEvent writes (RoomSoundboardPack / RoomImagePack,
  which used an 'as unknown as keyof StateEvents' idiom the sweep missed) through the
  typed sendStateEvent helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 00:02:04 -04:00
jaredandClaude Opus 4.8 b1ee3ada98 DP16: add typed get/setAccountData helpers, remove ~19 any-casts
Add centralized typed helpers in src/app/utils/accountData.ts:
- getAccountData<T>(mx, eventType): T | undefined (returns content)
- setAccountData<T>(mx, eventType, content): Promise<void>

These wrap the single `as any` cast needed because matrix-js-sdk's typed
overloads reject the fork's custom account-data event names. Every call site
now stays fully typed on its content shape.

Route all account-data reads/writes that previously used
`(mx as any).getAccountData/setAccountData` or `mx.getAccountData(... as any)`
through the helpers (or, where a MatrixEvent is needed, through the existing
utils/room.ts getAccountData whose param is widened to accept string keys).
No behavior change: same event types, same content shapes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 23:14:35 -04:00
jaredandClaude Opus 4.8 8eb961b682 fix(errors): surface previously-silent async failures (DP1/DP4/DP6)
Several fire-and-forget promises failed silently:
- RoomInput slash-command exe() rejections reset the editor as if they
  succeeded; now caught and shown via an error toast.
- Favourite / low-priority room-tag toggles (setRoomTag/deleteRoomTag)
  swallowed rejections; now surfaced via the same error toast.
- Call-decline sendEvent(RTCDecline) was uncaught; now logged best-effort
  while the local UI still dismisses.

Adds a shared createErrorToast builder mirroring createDownloadToast.
/kick and /ban route through rateLimitedActions, whose to() helper
swallows non-429 errors, so those two can still resolve on failure — noted
in code; the top-level exe() catch covers everything that does reject.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 22:29:39 -04:00
jaredandClaude Opus 4.8 d46b91b1b8 feat(rooms): Mark as Unread (MSC2867) + Low Priority rooms
Two Matrix protocol gaps (Phase A), gate-green (683 tests):
- Mark as Unread: m.marked_unread room account data (+ com.famedly.marked_unread
  fallback), a new markedUnreadAtom binder that seeds from account data and
  clears on our own read receipt (MSC2867). RoomNavItem gains Mark as Unread /
  Read menu items and lights the row dot for a marked room. Tested.
- Low Priority: m.lowpriority room tag mirroring favourites — a context-menu
  toggle (mutually exclusive with Favorite) and a collapsed Low Priority
  category sorted to the bottom of the Home room list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 00:04:47 -04:00
jaredandClaude Opus 4.8 dcd8201e16 fix(wave-3): audit fixes — ACL guards, presence, moderation, theming perf
Wave-3 bug-hunt fixes (findings in LOTUS_TODO), reviewed + gate-green:
- 🔴 ACL editor [H1–H4]: block saving an empty allow-list (was a one-click
  federation brick), warn on self-ban (case-insensitive glob match of
  mx.getDomain() vs allow/deny), accept real globs (1.2.3.*, *.evil.*), and
  gate Save behind a confirm dialog.
- 🔴 [P1] room context menu no longer acts on the wrong room after a live
  reorder (key by roomId, not list index). 🔴 [P2] status writes no longer
  force presence to online over Invisible/DND (shared presenceStateFromSetting).
- 🟠 [P3] timed mutes restored on boot; [P4] custom-status auto-clear now fires
  (always-mounted StatusExpiryMonitor); [P5] timezone also PUT to the m.tz
  profile field so it's visible to others; [H6] RoomInsights single-pass
  min/max (was Math.min(...spread) stack overflow); [H7/H8] mod-log labels.
- 🟡 [P6/P7] favorites collapse+filter, [P8] charCount reset, [P9] DM preview
  refresh on decrypt; theming [T-P1] lazy decorations, [T-P2] drop the redundant
  always-on body animation, [T-P4] live useReducedMotion, [T-P5] decoration key.
- NATIVE-CINNY LAW: notification presets + Powers permissions use folds icons.

DEFERRED: [H5] invite-QR is fetched from api.qrserver.com (third-party leak);
local generation needs a bundled QR lib (not added). tsc/eslint/prettier clean,
build OK, 677 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 21:40:07 -04:00
jaredandClaude Opus 4.8 c54cb126ff fix(ui): settings modal sizing regression + 17 more folds audit findings
CI / Build & Quality Checks (push) Successful in 10m47s
CI / Trigger Desktop Build (push) Successful in 5s
Fix settings modal regression: Modal500 was wrapped in useModalStyle(560),
forcing maxWidth 560px and squishing the two-pane Settings layout (folds
size="500" is ~50rem). Restore desktop width to the folds recipe while
keeping mobile fullscreen.

N-series fixes:
- N13 ScheduledMessagesTray header: <Box as="button"> -> folds <Button>
- N28 composer char counter: drop undefined --tc-surface-low + opacity,
  use priority="300" and config.space token
- N31 collapsible "Read more" toggle: padded <Button> -> flush inline-button
  pattern matching (edited) link
- N41 UserPrivateNotes "Saving..." now shows a folds <Spinner>
- N43 Night Light slider: add accentColor; label opacity -> priority
- N44 mention-highlight Reset: bare <button> -> folds <Button> (drops
  undefined --border-interactive-normal); Boot button kept (TDS-only)
- N45 SelectTheme trigger variant -> Secondary to match SettingsSelect
- N49 RoomInsights StatTile emoji -> folds <Icon> (Photo/VideoCamera/
  Headphone/File)
- N54/N57 PiP overlay badges + fullscreen button: token discipline
  (config.radii/space, folds Text); dark scrim kept for video legibility
- N60 knock badge: match Pinned Messages pattern (no wrapper div, toRem
  insets, no hardcoded size overrides)
- N62 unverified-device banner: 3px left-accent -> standard border via
  color.Warning.ContainerLine; drop opacity hacks
- N65 Edit History: real "Load more" pagination (accumulate next_batch,
  de-dupe by id, re-sort by ts) replacing passive text
- N66 search date fields: raw <input type="date"> -> folds <Input>
- N67 SeasonalEffect z-index 9999 -> 9997 (below Night Light + modals)
- N73 Pending Requests header uses css.MembersGroupLabel
- N74 remove raw em-sized emoji <span> in RoomNavItem name
- N85/N86 RemindMeDialog: <Box role="dialog"> -> folds <Dialog>; preset
  MenuItems -> Buttons (fixes invalid menuitem-in-dialog ARIA)

Document deliberate WON'T FIX rationale for N9, N51, N61, N71, N75, N77.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 00:15:35 -04:00
jaredandClaude Sonnet 4.6 8dc4c4d072 fix(ui): resolve 29 native UI/UX inconsistencies from folds design audit
CI / Build & Quality Checks (push) Successful in 10m25s
CI / Trigger Desktop Build (push) Successful in 6s
Fixes N1–N94 findings from LOTUS_BUGS.md audit pass. Key changes:

- ProfileDecoration: raw <button> → folds <Button> for save/remove; remove
  undefined --accent-cyan var
- UserRoomProfile: textarea border uses color.SurfaceVariant.ContainerLine
  and config tokens instead of undefined --border-interactive var
- LotusToastContainer: z-index raised from 9997 → 10001 so toasts appear
  above Night Light overlay (9998) and modals (9999)
- Message.tsx: DeliveryStatus replaces Unicode glyphs with Icon components;
  MessageQuickReactions returns null instead of <span />; forward menu item
  gets correct size="100" on after icon
- AudioContent: speed chip variant/radii now matches Play chip (Secondary/300)
- ReadReceiptAvatars: pill border/radius/padding → folds config tokens;
  remove dead receipt-pill-btn className
- EventReaders: Header size 600→500; close button gets radii="300";
  borderBottom shorthand → borderBottomWidth token; remove raw fontSize
- General.tsx: selected background/seasonal picker border uses
  color.Primary.Main instead of color.Critical.Main (error red)
- RoomInsights: SectionHeader drops textTransform/letterSpacing/opacity;
  chart borderRadius → config tokens; remove raw fontSize:9;
  warning banner → SequenceCard
- RoomProfile.tsx: formatting toolbar raw <button> → folds <Button>;
  topic read-mode renders formatted_body via sanitizeCustomHtml
- MsgTypeRenderers: location Open button Chip→Button; opacity:0.65→priority
- UploadCardRenderer: caption raw <input> → folds <Input>
- VoiceMessageRecorder: replace undefined --bg-surface-variant/--tc-*
  vars with color.* tokens; replace bare <audio controls> with
  IconButton play/pause toggle
- App.tsx: mention highlight uses WCAG 2.1 relative luminance (gamma
  linearization) instead of simplified approximation; border now rgba
  semi-transparent instead of same color as background
- RoomNavItem: Mute MenuItem icon moved to before prop
- SearchFilters: HasLink chip variant="Success" outlined to match filter bar
- RoomViewHeader: Server Notice chip radii Pill→300; fix jotai import order
- Fix ESLint import/order errors in DeviceVerificationSetup, RoomTopicViewer,
  MediaGallery, and RoomViewHeader

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 22:46:19 -04:00
jaredandClaude Sonnet 4.6 c5fbc20394 feat: presence avatar border rings (P5-18) + room emoji prefix support (P5-6)
P5-18: PresenceRingAvatar wrapper component applies a 2px box-shadow
ring to user avatars — green (online), yellow (idle/unavailable), red
(DND via status_msg='dnd'), no ring (offline). Applied to: message
timeline sender avatars, members drawer (members + knock requests),
@mention autocomplete, and inbox notification senders.

P5-6: Leading emoji in room names renders at 1.15× in the sidebar via
Unicode emoji regex detection in RoomNavItem. Emoji picker (EmojiBoard
in PopOut) added to all three room-name inputs: Create Room dialog
(converted to controlled input), Room Settings name field (shown only
when canEditName), and the "Rename for me" local rename dialog.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 21:56:19 -04:00
jaredandClaude Sonnet 4.6 08e7f33cba fix: remove copy link, convert mute to PopOut submenu
Copy Link removed — invite link is already in the invite modal.

Flat mute duration items replaced with a single "Mute →" MenuItem
that opens a PopOut submenu (Right/Start) with the 5 durations:
15 minutes / 1 hour / 8 hours / 24 hours / Indefinitely.
Anchor uses RectCords pattern (e.currentTarget.getBoundingClientRect)
matching the existing menu pattern in this file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 17:51:43 -04:00
jaredandClaude Sonnet 4.6 657ca3a5ca feat: GIF previews, room context menu, policy lists, mention pulse, collapsible messages, send animation, D&D fix
P3-5: Giphy/Tenor URL preview cards — full-width thumbnail from og:image
mxc URL, GIF badge overlay, site badge + title footer; GifCard shared by
both; BadgeGiphy (teal) and BadgeTenor (blue) CSS classes

P3-9: Policy list viewer — read-only panel in Room Settings + Space
Settings (admin/50+ PL only); enter room ID or alias; tabs for Users /
Rooms / Servers; glob pattern warning color; Ban badge; entity + reason

P5-8: Mention highlight pulse — 0.6s scale+glow keyframe on incoming
@mention messages; prefers-reduced-motion aware; only fires on new
incoming messages (isNewRef), not on history load; onAnimationEnd cleanup

P5-19: Collapsible long messages — ResizeObserver clamps text bodies
>320px with gradient fade + "Read more ↓" / "Show less ↑" button; resets
on eventId change; skips images/video/audio/file; smooth CSS transition

P5-23: Message send animation — own messages fade+scale in (0.97→1,
0.4→1 opacity, 150ms ease-out); prefers-reduced-motion aware; one-shot
via isNewRef + onAnimationEnd clear

P5-26: Room context menu — Copy Link (matrix.to URL, 1.5s Copied!
feedback), Mute with duration (15m/1h/8h/24h/indefinite, localStorage
timer key io.lotus.mute_timers), Mark as read; Icons.Link + Icons.BellMute

BUG D&D: dragCounter ref replaces fragile dragState machine — enter
increments, leave decrements (hides at 0), drop resets to 0; fixes
spurious dragleave from child element boundary crossings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 15:51:18 -04:00
jaredandClaude Sonnet 4.6 3cbc5112a7 fix: DM preview shows message body for E2EE rooms; filter inputs match members panel style
- RoomNavItem: change isEncrypted() to isDecryptionFailure() so DM
  previews show actual message body for successfully decrypted E2EE
  events instead of always showing 'Encrypted message'
- Home.tsx / Direct.tsx: upgrade filter inputs to size 400 / radii 400
  with search icon prefix to match the members list search bar style

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 00:39:39 -04:00
jaredandClaude Sonnet 4.6 d43044ccbf feat: P1 features — quick switcher, media gallery, DM previews, knock-to-join, syntax highlighting
P1-1: Quick room switcher (Ctrl+K/Cmd+K) — QuickSwitcher.tsx + ClientNonUIFeatures hotkey
P1-2: Media gallery drawer (images/videos/files) — MediaGallery.tsx + RoomViewHeader toggle
P1-4: DM last message preview + relative timestamp in RoomNavItem when direct=true
P1-7: Code syntax highlighting — TDS tokenizer (syntaxHighlight.ts), custom CSS theme
       (.prism-tds-dark/.prism-tds-light), applied in react-custom-html-parser.tsx
P1-11: Knock-to-join — "Request to Join" in RoomIntro + Pending Requests in MembersDrawer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 19:45:57 -04:00
jaredandClaude Sonnet 4.6 afe957015b feat: P1 features — voice speed, private receipts, room filter, favorites, invite link, poll creation
P1-5: Voice message playback speed toggle (0.75×/1×/1.5×/2×) in AudioContent.tsx
P1-10: Private read receipts toggle in Privacy settings; wired to notifications.ts
P1-3: Room filter input on Home tab and DMs tab (client-side, clears on tab switch)
P1-8: Favorite rooms via m.favourite tag — Favorites section in Home sidebar, star/unstar in right-click menu
P1-9: Room invite link + QR code in room settings (Share Room tile, api.qrserver.com QR)
P1-6: Poll creation modal in composer (PollCreator.tsx, sends m.poll.start)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 19:31:30 -04:00
jaredandClaude Sonnet 4.6 0bbfe17559 fix: GIFs, topic display, formatting toolbar, Copy Link in Invite, support URL
- RoomInput: GIF domain check uses endsWith('.giphy.com') — handles all
  Giphy CDN shards; all silent failure paths now show user-facing error
- RoomProfile: topic plain-text field is now HTML-stripped (no markdown
  syntax visible in header); formatting toolbar (B/I/S/code) above the
  textarea wraps selected text with correct markdown syntax
- InviteUserPrompt: Copy Link button added to dialog header with
  'Copied!' confirmation; removed Copy Link from both three-dot menus
- RoomViewHeader/RoomNavItem: unused copy-link imports removed
- nginx (live): support_page URL updated from lotusguild.org →
  matrix.lotusguild.org

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 09:55:04 -04:00
jaredandClaude Sonnet 4.6 16a15efe9b fix: P0 post-deploy bug fixes from live testing
- EditHistoryModal: use raw fetch with /_matrix/client/v1/ path for
  relations API — Synapse only supports relations at v1, not v3 (fixes
  Sentry JAVASCRIPT-REACT-K / 404 error)
- RoomViewHeader: remove useReportRoomSupported spec-version gate —
  Synapse 1.114+ has the endpoint but only advertises spec v1.12;
  button now always shows for non-creator, non-server-notice rooms
- ReportRoomModal: handle M_UNRECOGNIZED/404 with "not supported by
  your homeserver" message
- RoomNavItem: add isServerNotice guard to Room Settings in sidebar
  context menu (was only guarded in header three-dots menu)
- initMatrix: bump setMaxListeners from 50 → 150 to prevent
  MaxListenersExceededWarning with large room lists
- RoomProfile: save topic with formatted_body + format when markdown
  syntax is detected; add markdown hint below topic textarea

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 22:14:21 -04:00
jaredandClaude Sonnet 4.6 fc9ba03943 fix: remove unused useRoomName import, run prettier on all changed files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:38:35 -04:00
jaredandClaude Sonnet 4.6 16dddcb9f0 fix: comprehensive P0 quality pass — audit findings resolved
- ReportRoomModal: use mx.reportRoom() SDK method, fix undefined CSS vars
  (--mx-surface/border → folds color tokens), add role/aria-modal/aria-labelledby,
  accessible select/input labels, per-error-code messages, auto-close on success
- About.tsx: clickable matrix_id + email_address links (Text as="a"), AbortController
  cleanup, runtime JSON type guard, loading state, role display for all role values,
  remove classList theming hack, use mx.getHomeserverUrl()
- RoomViewHeader: useLocalRoomName for header title, useReportRoomSupported gate,
  hide Invite/Settings/Report for server notice rooms, isCreator guard on Report,
  FocusTrap returnFocusOnDeactivate on topic overlay, Server Notice chip tooltip
- RoomInput: replace raw <div> with folds <Box> for server notice read-only message
- EditHistoryModal: isRawEditEvent type guard, handle next_batch truncation,
  getVersionBody handles formatted_body (strips HTML for text display),
  role/aria-modal/aria-labelledby accessibility, guard for undefined eventId,
  use config.space tokens (remove var(--mx-spacing-*) strings)
- RoomNavItem: remove duplicate getExistingContent (use exported getLocalRoomNamesContent),
  maxLength={255} on rename input, fix FocusTrap nesting (renameDialog state moved to
  RoomNavItem_, RenameRoomDialog rendered outside menu, menu closes before dialog opens),
  pencil icon opacity via config.opacity.P300
- useRoomMeta: export getLocalRoomNamesContent for reuse
- RoomIntro: useLocalRoomName, formatted topic viewer with Overlay/FocusTrap/RoomTopicViewer
- CallRoomName: useLocalRoomName for consistent rename display in call overlay
- General.tsx: fix #980000/#FF6B00 hardcoded hex → color tokens/CSS vars, URL Preview
  capitalization, improved encrypted preview warning text + Warning chip, add
  description to plain urlPreview setting
- sanitize.ts: fix hex color regex to support 3/4/6/8 digit hex (CSS4 #RGBA, #RRGGBBAA)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:30:27 -04:00
jaredandClaude Sonnet 4.6 3a72b7c1c5 feat: personal room name overrides (MSC4431-style)
Users can right-click any room and 'Rename for me...' to set a local
display name visible only to them. Stored in account data under
io.lotus.room_names. Shows a pencil indicator on renamed rooms.
useLocalRoomName() hook overrides useRoomName() when a local name exists.

Also includes:
- Rich room topic rendering via RoomTopicContent object (formatted_body
  support in RoomTopicViewer with HTML sanitization via sanitizeCustomHtml)
- Edit history viewer: clicking '(edited)' on a message opens a modal
  showing all prior versions with timestamps (EditHistoryModal.tsx)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 17:21:11 -04:00
jared 46b6fecdde Merge tag 'v4.12.2' into lotus 2026-05-23 11:26:45 -04:00
Ajay Bura 6af3a7ebbe fix: call drop (#2954)
* update matrix-js-sdk and improve call driver

* remove unused room param from call members hook

* downgrade matrix-js-sdk to latest stable release
2026-05-23 21:50:41 +10:00
Lotus Bot 61a1f008d0 chore: upgrade i18next 26, prettier 3, fontsource-variable, domhandler 6, lint-staged 17
- i18next 23->26 + react-i18next 15->17
- prettier 2->3, reformat all files
- replace @fontsource/inter with @fontsource-variable/inter 5, update import path
- domhandler 5->6 (aligns with transitive deps)
- lint-staged 16->17
2026-05-21 23:30:50 -04:00
Lotus BotandClaude Sonnet 4.6 42b9cc2b64 chore: prettier format all files, brotli, Sentry release tagging, CI gates
Prettier: auto-formatted 103 files to fix baseline. Prettier check in CI
  is now a hard gate (removed continue-on-error).

Brotli: installed libnginx-mod-http-brotli-filter/static. Enabled in nginx
  with brotli_static on for pre-compressed assets and comp_level 6.

Sentry releases: deploy script now exports VITE_APP_VERSION=<git-short-sha>
  before building so each Sentry release maps to an exact commit.
  CI also passes github.sha as VITE_APP_VERSION.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 20:49:33 -04:00
Lotus BotandClaude Sonnet 4.6 ee7eabd2c4 fix(bug,perf): poll first-vote race, stale timeline ref, lazy GifPicker/EmojiBoard, focusItem timer leak, RoomNavItem memo
BUG-18: clearTimeout cleanup in focusItem useLayoutEffect prevents leaked timers
BUG-24: Room timeline listener catches first poll vote before Relations object exists
BUG-25: Use timelineRef.current in handleOpenEvent to prevent stale index on rapid navigation
Perf-6: React.lazy + Suspense for GifPicker and EmojiBoard (initial bundle -114 kB)
Perf-7: React.memo on RoomNavItem to prevent re-renders on unrelated state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 21:39:35 -04:00
Ajay BuraandKrishan 389d121c5d feat: Add option to start video call in DM (#2745)
* add option to start video all in DM

* show speaker icon for dm's in call status name

* show call view if call is active in room

* add Atria call ringtone

* update element call and widget api

* add option to start voice/video call in dms

* only show call button if user have permission

* allow call widget to send call notification event

* show incoming call dialog and play sound

* fix call permission checks

* allow option to start call in all rooms

* send notification when starting call in non-voice rooms

* hide header call button from voice rooms

* prevent call join if call not supported and started by other party

* update call menu style

* show call not supported message on incoming call notification

* improve the incoming call layout

* video call with right click without opening menu

* allow call widget to fetch media url

* add webRTC missing error

* improve call permission label

---------

Co-authored-by: Krishan <33421343+kfiven@users.noreply.github.com>
2026-05-14 19:41:12 +10:00
James 3e429c3500 fix: do not attempt to join call on doubleclick if missing permissions (#2798)
* fix: do not attempt to join call on doubleclick if missing permissions

* update comment

* export getPowersLevelFromMatrixEvent for usage elsewhere

* only read vc permissions when actually needed instead of reactively
2026-04-16 22:25:53 +10:00
Ajay Bura 5a3f7fffad Show call support error and disable join button (#2748)
* allow user to end call if error when loading

* show call support missing error if livekit server is not provided

* prevent joining from nav item double click if no livekit support
2026-03-09 21:39:58 +11:00
Ajay Bura b2ea3b41e0 Add own control buttons for element-call (#2744)
* add mutation observer hok

* add hook to read speaking member by observing iframe content

* display speaking member name in call status bar and improve layout

* fix shrining

* add joined call control bar

* remove chat toggle from room header

* change member speaking icon to mic

* fix joined call control appear in other

* show spinner on end call button

* hide call statusbar for mobile view when room is selected

* make call statusbar more mobile friendly

* fix call status bar item align
2026-03-09 08:34:48 +05:30
+4 a0e9ba0f55 feat: Add voice/video room support (#2680)
* Add users on the nav to showcase call activity and who is in the call

* add check to prevent DCing from the call you're currently in...

* Add avatar and username for the space (needs to be moved into RoomNavItem proper)

* Add background variant to buttons

* Update hook to keep method signature (accepting an array of Rooms instead) to support multiple room event tracking of the same event

* Add state listener so the call activity is real time updated on joins/leaves within the space

* Add RoomNavUser for displaying the user avatar + name in the nav for a visual of call activity and participants

* rename CallNavBottom to CallNavStatus

* Rename callnavbottom and fix linking implementation to actually be correct

* temp fix to allow the status to be cleared in some way

* re-add background to active call link button

* prepare to feed this to child elements for visibility handling

* loosely provide nav handling for testing refactoring

* Add CallView

* Update to funnel Outlet context through for Call handling (might not be the best approach, but removes code replication in PersistentCallContainer where we were remaking the roomview entirely)

* update client layout to funnel outlet the iframes for the call container

* funnel through just iframe for now for testing sake

* Update room to use CallView

* Pass forward the backupIframeRef now

* remove unused params

* Add backupIframeRef so we can re-add the lobby screen for non-joined calls (for viewing their text channels)

* Remove unused imports and restructure to support being parent to clientlayout

* Re-add layout as we're no longer oddly passing outlet context

* swap to using ref provider context from to connect to persistentcallcontainer more directly

* Revert to original code as we've moved calling to be more inline with design

* Revert to original code as we've moved the outlet context passing out and made more direct use of the ref

* Fix unexpected visibility in non-room areas

* correctly provide visibility

* re-add mobile chat handling

* Improve call room view stability

* split into two refs

* add ViewedRoom usage

* Disable

* add roomViewId and related

* (broken) juggle the iframe states proper... still needs fixing

* Conditionals to manage the active iframe state better

* add navigateRoom to be in both conditions for the nav button

* Fix the view to correctly display the active iframe based on which is currently hosting the active call (juggling views)

* Testing the iframe juggling. Seems to work for the first and second joins... so likely on the right path with this

* add url as a param for widget url

* fix backup iframe visibility

* Much closer to the call state handling we want w/ hangups and joins

* Fix the position of the member drawer to its correct location

* Ensure drawer doesn't appear in call room

* Better handling of the isCallActive in the join handler

* Add ideal call room join behavior where text rooms to call room simply joins, but doesn't swap current view

* Fix mobile call room default behavior from auto-join to displaying lobby

* swap call status to be bound to call state and not active call id

* Remove clean room ID and add default handler for if no active call has existed yet, but user clicks on show chat

* Applies the correct changes to the call state and removes listeners of old active widget so we don't trigger hang ups on the new one (the element-call widget likes to spam the hang up response back several times for some reason long after you tell it to hang up)

* Remove superfluous comments and Date.now() that was causing loading... bug when widgetId desynced

* Remove Date.now() that was causing widgetId desync

* add listener clearing, camel case es lint rule exception, remove unneeded else statements

* Remove unused

* Add widgetId as a getWidgetUrl param

* Remove no longer needed files

* revert ternary expression change and add to dependency array

* add widgetId to correct pos in getWidgetUrl usage

* Remove CallActivation

* Move and rename RoomCallNavStatus

* update imports and dependency array

* Rename and clean up

* Moved CallProvider

* Fix spelling mistake

* Fix to use shorthand prop

* Remove unneeded logger.errors

* Fixes element-call embedded support (but it seems to run poorly)

* null the default url so that we fallback to the embedded version (would recommend hosting it until performance issue is determined)

* Fix vite build to place element-call correctly for embedded npm package support

* add vite preview as an npm script

* Move files to more correct location

* Add package-lock changes

* Set dep version to exact

* Fix path issue from moving file locations

* Sets initial states so the iframes don't cause the other to fail with the npm embedded package

* Revert navitem change

* Just check for state on both which should only occur at initial

* Fixes call initializing by default on mobile

* Provides correct behavior when call isn't active and no activeClientWidgetApi exists yet

* Corrects the state for the situations where both iframes are "active" (not necessarily visible)

* Reduce code reuse in handleJoin

* Seems to sort out the hangup status button bug the occurred after joining a call via lobby

* Re-add the default view current active room behavior

* Remove repetitive check

* Add storing widget for comparing with (since we already store room id and the clientWidgetApi anyway)

* Update rendering logic to clear up remaining rendering bug (straight to call -> lobby of another room and joining call from that interface -> lobby of that previous room and joining was leading to duplication of the user in lobbies. This was actually from listening to and acknowledging hangups from the viewed widget in CallProvider)

* Prevent null rooms from ever rendering

* This seems to manage the hangup state with the status bar button well enough that black screens should never be encountered

* Remove viewed room setting here and pass the room to hang up (seems state doesn't update fast enough otherwise)

* Remove unused

* Properly declare new hangup method sig

* Seems to avoid almost all invalid states (hang up while viewing another lobby and hitting join seems to black screen, sets the active call as the previous active room id, but does join the viewed room correctly)

* Fix for cases where you're viewing a lobby and hang up your existing call and try to join lobby (was not rendering for the correct room id, but was joining the correct call prior)

* Re-add intended switching behavior

* More correct filter (viewedRoom can return false on that compare in some cases)

* Seems to shore up the remaining state issues with the status bar hangup

* Fix formatting

* In widget hang up button should be handled correct now

* Solves the CHCH sequence issue, CLJH remains

* Fixes CLJH, found CCH

* Solves CCH. Looks like CLCH left

* A bit of an abomination, but adds a state counter to iteratively handle the diverse potential states (where a user can join from the nav bar or the join button, hang up from either as well, and account for the juggling iframes)
Black screens shouldn't be occurring now.

* Fix dependency array

* Technically corrects the hangup button in the widget, should be more precise though

* Bind the on messaging iframe for easier access in hangup/join handling

* Far cleaner and more sensible handling of the call window... I just really don't like the idea of sending a click event, but right now the element-call code treats preload/skipLobby hangups (sent from our end) as if they had no lobby at all and thus black screens. Other implementation was working around that without just sending a click event on the iframe's hangup button.

* Fixes a bug where if you left a call then went to a lobby and joined it didn't update the actual activeCallRoomId

* Fixes complaints of null contentDocument in iframe

* Update to use new icons (thank you)

* Remove unneeded prop

* Re-arrange more options and add checks for each option to see if it is a call room (probably should manage a state to see if a header is already on screen and provide a slightly modified visual based on that for call rooms)

* Invert icons to show the state instead of the action they will perform (more visual clarity)

* Update src/app/features/room-nav/RoomCallNavStatus.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomCallNavStatus.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomCallNavStatus.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomCallNavStatus.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomCallNavStatus.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomCallNavStatus.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomViewHeader.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavItem.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavUser.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavUser.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room-nav/RoomNavUser.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/pages/client/space/Space.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/call/CallView.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/call/CallView.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/call/CallView.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomView.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomView.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* adjust room header for calling

* Remove No Active Call text when not in a call

* update element-call version

* Update src/app/features/room/RoomViewHeader.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomViewHeader.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomViewHeader.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomViewHeader.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Update src/app/features/room/RoomViewHeader.tsx

Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>

* Revert most changes to Space.tsx

* Show call room even if category is collapsed

* changes to RoomNavItem, RoomNavUser and add useCallMembers

* Rename file, sprinkle in the magic one line for matrixRTCSession. and remove comment block

* swap userId to callMembership as a prop and add a nullchecked userId that uses the membership sender

* update references to use callMembership instead

* Simplify RoomNavUser

Discard future functionality since it probably won't exist in time for merging this PR

* Simplify RoomViewHeader.tsx

Remove unused UI elements that don't have implemented functionality. Replace custom function for checking if a room is direct with a standard hook.

* Update Room.tsx to accomodate restructuring of Room, RoomView and CallView

* Update RoomView.tsx to accomodate restructuring of Room, RoomView and CallView

* Update CallView.tsx to accomodate restructuring of Room, RoomView and CallView + suggested changes

* add call related permissions to room permissions

* bump element call to 0.16.3, apply cinny theme to element call ui, replace element call lobby (backup iframe) with custom ui and only use element call for the in-call ui

* update text spacing

* redo roomcallnavstatus ui, force user preferred mute/video states when first joining calls, update variable names and remove unnecessary logic

* set default mic state to enabled

* clean up ts/eslint errors

* remove debug logs

* format using prettier rules from project prettierrc

* fix: show call nav status while active call is ongoing

* fix: clean up call nav/call view console warnings

* fix: keep call media controls visible before joining

* fix: restore header icon button fill behavior

Fixes regression from b074d421b66eb4d8b600dfa55b967e6c4f783044.

* style: blend header and room input button styles in call nav

* fix page header background color on room view header

* fix: permissions and room icon resolution (#2)

* Initialize call state upon room creation for call rooms, remove subsequent useless permission

* handle case of missing call permissions

* use call icon for room item summary when room is call room

* replace previous icon src resolution function with a more robust approach

* replace usages of previous icon resolution function with new implementation

* fix room name not updating for a while when changed

* set up framework for room power level overrides upon room creation

* override join call permission to all members upon room creation

* fix broken usages of RoomIcon

* remove unneeded import

* remove unnecessary logic

* format with prettier

* feat: show connected/connecting call status

* fix: preserve navigation context when opening non-call rooms

* fix: reset room name state when room instance changes

* feat: Disable webcam by default using callIntent='audio'

* Add channel type selecor

* Add option for voice rooms, which for now sets the default selected
option in the creation modal

* Add proper support for room selection from the enu

* Move enums to `types.ts` and change icons selection to use
`getRoomIconSrc`

* fix: group duplicate conditions into one

* fix: typo

* refactor: rename kind/voice to access/type and simplify room creation

- rename CreateRoomVoice to CreateRoomType and modal voice state to type
- rename CreateRoomKind to CreateRoomAccess and KindSelector to AccessSelector
- propagate access/defaultAccess through create room and create space forms
- set voice room power levels via createRoom power_level_content_override

* refactor: unify join rule icon mapping and update call/space icons

- bump folds from 2.5.0 to 2.6.0
- replace separate room/space join-rule icon hooks with useJoinRuleIcons(roomType)
- route join-rule icons through getRoomIconSrc for consistent room type handling
- simplify getRoomIconSrc by removing the locked override path
- use VolumeHighGlobe for public call rooms and VolumeHighLock for private call rooms

* chore(deps): bump matrix-widget-api to 1.17 and remove react-sdk-module-api

* fix: adapt SmallWidget to matrix-widget-api 1.17.0 API

* fix: render call room chat only when chat panel is open

* fix(permissions): show call settings permissions only for call rooms

* refactor: remove redundant room-nav props/guards and minor naming cleanup

* fix: use PhoneDown icon for hang up action

* chore(hooks): remove unused useStateEvents hook

* fix(room): enable members drawer toggle in desktop call rooms

- show filled User icon when the drawer is open

* Revert "fix: adapt SmallWidget to matrix-widget-api 1.17.0 API"

This reverts commit a4c34eff8a.

* fix: semi-revert matrix-widget-api 1.17 bump and migrate to 1.13 API

* fix(call): wait for Element Call contentLoaded before widget handshake

- fixes not working on firefox

* fix missing imports

* improve create room type design and add beta badge for voice room

* add beta badge for voice room in space lobby

* fix create room modal title

* pass missing roomType param to roomicon component

* add roomtype

* Add deafen functionality (#2695)

* feat:(deafen functionality)

* feat:(reworked voice controls for deafen)

* ref:(use muted instead of volume for deafen)

* fix:(backpedal audio_enabled rename)

* ref:(renaming of deafened vars)

* add stack avatar component

* add call status bar - WIP

* remove call status from navigation drawer

* fix deprecated method use in use call members hook

* render new call status bar

* move call widget driver to plugins

* remove old status bar usage from navigation drawer

* add call session and joined hook

* remove unknown changes

* upgrade widget api

* add element call embed plugin

* remove unknown change

* add call embed atom

* add call embed hooks and context

* add call embed provider

* replace old call implementation

* stop joining other call on second click if already in a call

* refactor embed placement hook

* add merge border prop to sequence card

* add call preferences

* add prescreen to call view - WIP

* prevent joining new call if already in call

* make call layout adaptive

* render call chat as right panel

* show call members in prescreen

* render call join leave event in timeline

* remove unknown rewrite in docker-nginx file

* render call event without hidden event enable

---------

Co-authored-by: Gigiaj <gigiaboone@yahoo.com>
Co-authored-by: Jaggar <18173108+GigiaJ@users.noreply.github.com>
Co-authored-by: Gimle Larpes <97182804+GimleLarpes@users.noreply.github.com>
Co-authored-by: Gimle Larpes <gimlelarpes@gmail.com>
Co-authored-by: YoJames2019 <jamesclark1700@gmail.com>
Co-authored-by: YoJames2019 <yobiscuit0@gmail.com>
Co-authored-by: hazre <mail@haz.re>
Co-authored-by: haz <37149950+hazre@users.noreply.github.com>
Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com>
Co-authored-by: James <49845975+YoJames2019@users.noreply.github.com>
Co-authored-by: James Reilly <jreilly1821@gmail.com>
Co-authored-by: Tymek <vonautymek@gmail.com>
Co-authored-by: Thedustbuster <92692948+Thedustbustr@users.noreply.github.com>
2026-03-07 18:03:32 +11:00
Ajay Bura 1b89475fa7 Remove unused javascript (#2470) 2025-08-29 19:34:52 +10:00
Ajay Bura 194299c510 New invite user to room dialog (#2460)
* fix 0 displayed in invite with no timestamp

* support displaying invite reason for receiver

* show invite reason as compact message

* remove unused import

* revert: show invite reason as compact message

* remove unused import

* add new invite prompt
2025-08-24 22:34:21 +10:00
Ajay Bura ba08d0ad86 Support room version 12 (#2399)
* WIP - support room version 12

* add room creators hook

* revert changes from powerlevels

* improve use room creators hook

* add hook to get dm users

* add options to add creators in create room/space

* add member item component in member drawer

* remove unused import

* extract member drawer header component

* get room creators as set only if room version support them

* add room permissions hook

* support room v12 creators power

* make predecessor event id optional

* add info about founders in permissions

* allow to create infinite powers to room creators

* allow everyone with permission to create infinite power

* handle additional creators in room upgrade

* add option to follow space tombstone
2025-08-13 00:12:30 +10:00
Ajay Bura b7cc9d88cb Revert "Fix menus congestion and improve thread reply layout (#2402)" (#2409)
This reverts commit 29364b2e92.
2025-08-04 20:29:12 +05:30
Ajay Bura 29364b2e92 Fix menus congestion and improve thread reply layout (#2402)
* make menus more spacious

* improve threaded reply layout

* fix search filter button spacing
2025-07-27 22:20:23 +10:00
Ajay Bura 0ac8179ed2 Add option to change room notification settings (#2281) 2025-03-20 20:27:00 +11:00
Ajay Bura 411e4f52c6 New room settings, add customizable power levels and dev tools (#2222)
* WIP - add room settings dialog

* join rule setting - WIP

* show emojis & stickers in room settings - WIP

* restyle join rule switcher

* Merge branch 'dev' into new-room-settings

* add join rule hook

* open room settings from global state

* open new room settings from all places

* rearrange settings menu item

* add option for creating new image pack

* room devtools - WIP

* render room state events as list

* add option to open state event

* add option to edit state event

* refactor text area code editor into hook

* add option to send message and state event

* add cutout card component

* add hook for room account data

* display room account data - WIP

* refactor global account data editor component

* add account data editor in room

* fix font style in devtool

* show state events in compact form

* add option to delete room image pack

* add server badge component

* add member tile component

* render members in room settings

* add search in room settings member

* add option to reset member search

* add filter in room members

* fix member virtual item key

* remove color from serve badge in room members

* show room in settings

* fix loading indicator position

* power level tags in room setting - WIP

* generate fallback tag in backward compatible way

* add color picker

* add powers editor - WIP

* add props to stop adding emoji to recent usage

* add beta feature notice badge

* add types for power level tag icon

* refactor image pack rooms code to hook

* option for adding new power levels tags

* remove console log

* refactor power icon

* add option to edit power level tags

* remove power level from powers pill

* fix power level labels

* add option to delete power levels

* fix long power level name shrinks power integer

* room permissions - WIP

* add power level selector component

* add room permissions

* move user default permission setting to other group

* add power permission peek menu

* fix weigh of power switch text

* hide above for max power in permission switcher

* improve beta badge description

* render room profile in room settings

* add option to edit room profile

* make room topic input text area

* add option to enable room encryption in room settings

* add option to change message history visibility

* add option to change join rule

* add option for addresses in room settings

* close encryption dialog after enabling
2025-03-19 23:14:54 +11:00
Ajay Bura 9bacdd1018 Hidden Typing & Read Receipts (#2230)
* add hide activity toggle

* stop sending/receiving typing status

* send private read receipt when setting toggle is activated

* prevent showing read-receipt when feature toggle in on
2025-02-26 21:44:53 +11:00
Ajay Bura 96c329a482 fix room activity indicator appearing on self typing (#2217) 2025-02-19 22:08:58 +11:00
Ajay Bura e1c2430db9 Improve-auth-media (#1933)
* fix set power level broken after sdk update

* add media authentication hook

* fix service worker types

* fix service worker not working in dev mode

* fix env mode check when registering sw
2024-09-09 14:15:20 +05:30