Commit Graph

63 Commits

Author SHA1 Message Date
jared 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
jared dedbd54199 feat: typing indicator orange dots, push-to-deafen hotkey, night light filter, message length counter
- #108: TypingIndicator reads lotusTerminal setting; applies var(--lt-accent-orange)
  to container so dots inherit via backgroundColor:currentColor
- #100: CallControls registers KeyM as push-to-deafen (e.code, e.repeat guard,
  ownerDocument.body iframe-safe editable check, [callEmbed] dep array)
- P5-5: nightLightEnabled/nightLightOpacity settings; position:fixed rgba(255,140,0)
  overlay inside JotaiProvider; Night Light tile + intensity slider (5–80%) in
  Settings → Appearance
- #101: RoomInput charCount state via Slate onChange + toPlainText; resets on
  room switch; displayed before send button when count > 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 15:36:45 -04:00
jared 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
jared 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
jared 134ebb231d feat: server support contact display (MSC1929) and server notices UI
- Settings Help/About fetches /.well-known/matrix/support and displays
  admin contact + support page link (graceful 404 degradation)
- Server notice rooms (m.server_notice) now show a Warning badge in the
  room header and hide the message composer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 17:15:01 -04:00
jared 572bc6a4c0 feat: add Report Room (MSC4151) and fix URL preview default for encrypted rooms
- Report Room: new ReportRoomModal with reason + category, POST /rooms/{id}/report
- URL preview: encUrlPreview default changed to true; security note added to settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 17:11:21 -04:00
jared bc63714a07 fix/polish: wave 1+2 improvements across six features
B1 - GIF upload progress: spinner on GIF button + disabled state while
     fetch+upload is in flight; clears on success or error
B2 - PiP position persistence: drag end saves left/top to localStorage;
     entering PiP restores saved position (clamped to current viewport)
B3 - PiP snap-to-corner: double-click the PiP overlay snaps to nearest
     corner with a 180ms CSS transition; saves new position
B4 - Device sessions loading state: useOtherUserDevices now returns
     {status:'loading'|'error'|'success', devices} instead of bare
     array; UserDeviceSessions shows spinner while loading
B5 - Device sessions error state: catch in hook sets status:'error';
     panel shows warning icon + 'Could not load sessions' message
B6 - Screenshare fullscreen Safari guard: hide button when
     document.fullscreenEnabled is false (iOS Safari, some mobile)
B7 - Status save error: show critical-coloured error text below Save
     button when saveState.status === AsyncStatus.Error
B9 - Encrypted search coverage counter: 'X / Y cached' badge next to
     'Encrypted Rooms' heading using existing localResult fields
D2 - PiP screenshare spotlight: track auto-spotlight in a ref; release
     spotlight when screenshare ends while in PiP mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 17:13:54 -04:00
jared 98cbb32b86 fix: suppress unhandled rejection from saveStatus on rate limit
useAsync re-throws after setting error state, so callers that don't
await or catch the returned promise get an unhandled rejection. Fixes
JAVASCRIPT-REACT-E (429 on presence endpoint).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 19:36:26 -04:00
jared db4a39ff56 refactor: move privacy settings into dedicated Privacy section
Hide Typing & Read Receipts and Hide Online Status were buried in
the Editor section. Extracted into a new Privacy section that sits
between Messages and Calls, where users would naturally look.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 19:31:36 -04:00
jared 08b1a5c2a3 feat: full Discord-style presence tracking
- Announce online immediately on app startup
- Idle detection: unavailable after 10 min of no input, online on return
- Tab visibility: unavailable when hidden, online when focused again
- Page close: offline via fetch+keepalive (survives unload without bfcache penalty)
- hidePresence setting: broadcasts offline and stops all tracking
- Added 'Hide Online Status' toggle in General settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 19:28:52 -04:00
jared eb283c29ff feat: add character counter to status message input
Shows X/64 below the input. Fades in at 56 chars (warning colour) and
turns critical red at the limit so users always know where they stand.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 16:58:37 -04:00
jared f8ab136492 fix: cap status message length and constrain display overflow
Add maxLength=128 to the status input to prevent absurdly long statuses.
In UserHeroName (profile panel), tighten the status display to LineClamp2,
add overflow:hidden on the container, and use overflowWrap:anywhere so
unbroken strings (emoji chains, URLs) wrap instead of overflowing.
Member list already truncates via the truncate prop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 16:29:11 -04:00
jared 221bd825b1 fix: import EmojiBoard directly in ProfileStatus to fix emoji selection
React.lazy + Suspense interacted badly with the nested FocusTraps (the
settings Modal500 outer trap and EmojiBoard's inner trap). During the
suspend/resolve cycle targetFromEvent returned undefined, causing
handleGroupItemClick to bail before calling onEmojiSelect.

Switched to a direct import matching MessageEditor and PowersEditor
which both use EmojiBoard inside settings panels without lazy loading.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 16:01:17 -04:00
jared 60cbfec951 fix: emoji picker works + silence 429 presence rate-limit errors
Emoji bug root cause: EmojiBoard wraps itself in a FocusTrap with
clickOutsideDeactivates:true. When the picker was rendered inside
Input's 'after' prop, the FocusTrap treated clicks on the emoji items
as outside-clicks and deactivated (calling requestClose) before the
onEmojiSelect callback fired. Fixed by moving the emoji PopOut to be
a direct sibling of Input in the form row instead of nesting it inside
Input.after — matching the established pattern used in MessageEditor.

429 rate-limit: mx.setPresence() calls in handleClear and the
auto-clear timer effect had no rejection handling, causing unhandled
promise rejections logged to Sentry when Synapse rate-limits presence
updates. Added .catch(() => undefined) to both call sites. Sentry
issue JAVASCRIPT-REACT-E resolved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:20:42 -04:00
jared 90cb70c128 fix: emoji selection appends correctly to status input
When focus moves to the emoji picker the input loses focus, making
selectionStart/selectionEnd unreliable. Replace the cursor-tracking
insertion with a simple functional state updater that always appends
the emoji to the end — reliable and appropriate for a short status field.

Also removes the now-unused inputRef and useRef import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:41:48 -04:00
jared 01a61e3ec2 feat: auto-clear status after configurable duration
Adds an 'Auto-clear after' dropdown to the Status Message settings tile
with options: Never / 30 min / 1 hr / 4 hr / 8 hr / Until midnight /
1 day / 7 days.

How it works:
- On save, stores the expiry timestamp in localStorage keyed by userId
  (lotus-status-expiry-<userId>) and sets expiryTs state
- A single useEffect on expiryTs drives the timer — re-saving cancels
  the previous timer cleanly via useEffect cleanup
- On mount, reads stored expiry from localStorage so auto-clear
  survives page reloads (fires immediately if already expired)
- Manual Clear Status also removes the stored expiry and cancels any
  active timer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:10:46 -04:00
jared e280f0e312 fix: capture emoji button rect before state updater to avoid null currentTarget
React nullifies synthetic event's currentTarget before async state
updater callbacks run. Capture getBoundingClientRect() synchronously
in the onClick handler, then pass the already-computed rect into
setEmojiAnchor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:06:31 -04:00
jared 46da4458ff feat: custom status message — display + editor with emoji picker
- MembersDrawer: show presence.status as small muted text below
  username in every member row (live via useUserPresence)
- UserHero/UserHeroName: accept optional status prop; render below
  the @username handle in user profile popouts
- UserRoomProfile: pass presence?.status down to UserHeroName
- Profile settings: new ProfileStatus tile below Display Name
  * Input with inline emoji picker (lazy-loaded EmojiBoard)
  * Cursor-aware emoji insertion (preserves caret position)
  * Save via mx.setPresence({ status_msg }) / Clear button
  * Pre-fills from current presence; syncs on remote update

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:39:51 -04:00
Lotus Bot d3fba1d685 fix: reduce ESLint errors and npm audit vulnerabilities
ESLint (476 → 187 errors):
- Fix import/first: move React.lazy() declarations after all imports in RoomInput.tsx and Router.tsx
- Disable react-hooks v7 React Compiler rules (refs, set-state-in-effect, immutability, purity, use-memo, react-compiler) - not using React Compiler yet
- Add eslint-disable for lotus-terminal.css.ts (no-explicit-any in CSS-in-JS)
- Add eslint-disable for cryptE2ERoomKeys.js (intentional bitwise crypto ops)
- Auto-fix 17 remaining fixable errors

npm audit (14 → 11 vulns, 5 → 3 HIGH in prod):
- Upgrade @giphy/react-components 5.9.4 → 10.1.2, js-fetch-api → 5.8.0, js-types → 5.1.0
- Add npm overrides to force dompurify >=3.3.4 and uuid >=11.1.1 in @giphy/js-util
- CI audit now uses --omit=dev to exclude devDep transitive vulns (lodash in commitizen)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:08:50 -04:00
Lotus Bot 266e47f240 chore: upgrade TypeScript 4.9 to 5.9, ESLint 8.29 to 8.57, @typescript-eslint 5 to 7
Resolves all TS2345/TS2347/TS7006 type errors introduced by stricter TypeScript 5.x.
Fix Icons.Settings to Icons.Setting, cast account data returns, fix implicit any.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 11:16:11 -04: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 Bot 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 Bot d707c4441c feat(a11y): form input labels (H-6), remaining button labels (C-1)
H-6: aria-label on all form inputs missing accessible names:
  - Login: username, password (already done)
  - Register: username, password, confirm, token, email
  - Password reset: email, new password, confirm password
  - Settings: display name, user ID to ignore, keyword, page zoom,
    date format, device name, backup passwords (new/confirm/restore)
  - Auth: server URL picker input
C-1: additional icon buttons:
  - RoomInput: toolbar toggle (aria-pressed + label)
  - Lobby/Members: scroll to top, toggle member list
  - UIAFlowOverlay: cancel authentication
  - BackupRestore: backup options menu
  - UrlPreview: previous/next preview buttons
  - RoomPacks: undo remove/remove pack buttons
  - RoomViewHeader: start call, member list toggle
  - ServerPicker: change server button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 12:03:26 -04:00
Lotus Bot 4e80c0a0f5 feat(a11y,perf): comprehensive icon button labels, toolbar a11y, timeline binary search
A11y C-1: aria-label on 30+ remaining icon-only buttons across:
  - settings panels (close, reset, info, expand, remove, undo)
  - editor toolbar (bold, italic, underline, strike, code, spoiler,
    blockquote, code block, ordered/unordered list, headings 1-3)
  - auth stages (cancel buttons in SSO, Password stages)
  - device verification (cancel buttons)
  - password input (show/hide toggle with dynamic label)
  - event readers, account data editor close buttons
  - global emoji packs (add/remove buttons)
Perf-5: Replace O(N×T) getTimelineAndBaseIndex scan with precomputed binary
  search (timelineSegments useMemo) — O(log T) per visible message render

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 21:54:33 -04:00
Lotus Bot d4705f9235 fix(a11y,sec): remove tabIndex=-1 from interactive buttons, npm audit fix
H-3: tabIndex=-1 removed from login info, settings reset, settings info buttons
      + aria-label added to each for screen reader discoverability
SEC: npm audit fix - 18 non-breaking dependency updates (34 vulns -> 16 remaining)
     Remaining 16 require --force (breaking changes, deferred)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 21:47:20 -04:00
root daca1e0cca feat: URL preview TDS styling, settings description update
- UrlPreview.tsx: add data-url-preview attribute for CSS targeting
- lotus-terminal.css.ts: dark cyan border-left accent + transparent bg
  for URL preview cards in TDS mode (dark + light variants)
- General.tsx: mention Escape-to-skip in boot animation description
2026-05-16 02:11:52 -04:00
root 83cbb09bae fix: VideoButton disabled state, PTT listener leak, TS prop errors
- VideoButton now accepts disabled prop with tooltip and visual feedback;
  PrescreenControls passes disabled=true when cameraOnJoin=false
- PTT key listener in settings tracked via ref, cleaned up on unmount,
  guarded against stacking on double-click; useCallback + useRef
- CallControls screenshare cancel button: variant Surface -> Secondary
- General.tsx Box align prop: align -> alignItems (TS2322 fix)
2026-05-15 15:38:02 -04:00
root 038bde8b62 feat(call): PTT, deafen label, camera default off, screenshare confirm, noise suppression setting
- Push to Talk: keydown/keyup binds mic to configurable key (default Space)
  with visual PTT indicator and key-binding UI in Settings > General > Calls
- Camera always defaults OFF on join; cameraOnJoin setting for explicit opt-in
- Deafen button tooltip corrected to Deafen/Undeafen instead of Turn Off/On Sound
- Screenshare confirmation dialog before broadcasting to call participants
- Noise suppression toggle wired from settings through CallEmbed URL params
- CallControl.setMicrophone() public method for programmatic mic control
- Calls settings section added to General settings page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:14:04 -04:00
root dc26e15df1 Audit fixes: Lotus URLs, branding, editor toolbar setting, dynamic version 2026-05-13 23:03:14 -04:00
root 893aa92b38 Deepen TDS integration: full terminal CSS coverage + 3 new backgrounds
Terminal Mode:
- Text selection: orange highlight rgba(255,107,0,0.28)
- Links: cyan (#00D4FF) with orange hover glow (#FF6B00)
- Code/pre: TDS green (#00FF88) on terminal bg, left green border
- Strong/b → orange, em/i → cyan, mark → amber, del → red
- Blockquote: orange left border (matches chat reply quotes)
- HR: cyan border with dim glow
- Input/textarea/[contenteditable] focus: orange glow ring
- Tables: TDS headers (orange+uppercase), cyan borders, hover rows
- List markers: cyan ▸ for ul, orange for ol
- Boot box-drawing alignment fixed (51→52 ═)
- data-theme=\"dark\" set on html element when terminal active
- Updated description: correct TDS palette names
- ▶ Boot replay button in settings (visible when terminal on)

Chat backgrounds (+3):
- Tactical: LotusGuild TDS exact cyan dot-grid (28px)
- Circuit: green grid + node dots on dark terminal bg
- Hex Grid: isometric cyan hexagonal outlines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 22:44:34 -04:00
root f3ec49fe88 Add Lotus Terminal Mode + fix all remaining Cinny branding
- New: Lotus Terminal Mode toggle in Appearance settings
  - Red phosphor color scheme (bg #0a0000, primary #ff3300, accent #00dd66)
  - Monospace font override (JetBrains Mono / Fira Code / Cascadia Code)
  - Retro CRT scanline overlay via CSS pseudo-element
  - Wired into ThemeManager with dedicated lotusTerminalBodyClass
- Branding: replace all user-visible Cinny references with Lotus Chat
  - WelcomePage, AuthLayout, SplashScreen, index.html meta tags
  - Device display names in login/register/token flows
  - System notification brand field
  - (Preserved internal Matrix protocol CinnySpaces event type)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 22:22:06 -04:00
root d67fe80906 Backgrounds: theme-aware patterns and visual preview grid 2026-05-13 21:51:19 -04:00
root 0df997eecf Redesign chat backgrounds: blueprint, carbon, stars, topographic, herringbone, crosshatch 2026-05-13 21:42:12 -04:00
root dcb3ff3129 Phase 2+3: Chat backgrounds and per-message profiles settings 2026-05-13 21:17:59 -04:00
root ccc919d2c8 Use official Lotus.png logo in About and Auth pages 2026-05-13 19:53:29 -04:00
root 5d984a4af4 Phase 1: Lotus Chat branding — title, favicon, logo, meta tags, SVG icons, all icon sizes 2026-05-13 17:56:39 -04:00
Krishan a1053ce8f1 chore(release): v4.11.1 [skip ci] (#2765)
* chore(release): 4.11.0 [skip ci]

* chore(release): 4.11.1 [skip ci]
2026-03-11 23:07:37 +11:00
Krishan d24ad8374b chore(release): 4.11.0 [skip ci] 2026-03-11 04:03:48 +00:00
Krishan 449b2c5a5e Release v4.10.5 (#2692) 2026-02-23 23:05:01 +11:00
Krishan bc80365ba0 Release v4.10.4 (#2688) 2026-02-23 22:32:06 +11:00
Krishan 88c8b0eea8 Release v4.10.3 (#2608) 2026-02-16 22:19:21 +11:00
Krishan 84d699ebd4 Release v4.10.2 (#2528) 2025-11-05 17:49:56 +11:00
Krishan 62a28e3289 Release v4.10.1 (#2495) 2025-09-29 14:34:38 +10:00
Krishan af63b528dc Release v4.10.0 (#2472)
* Release v4.10.0

* update version number in about
2025-08-31 21:05:38 +10:00
Ajay Bura 1b89475fa7 Remove unused javascript (#2470) 2025-08-29 19:34:52 +10:00
Ajay Bura c43d518995 Add option for monochrome mode (#2464) 2025-08-25 23:19:14 +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
Gimle Larpes ac0345d07f Add settings to enable 24-hour time format and customizable date format (#2347)
* Add setting to enable 24-hour time format

* added hour24Clock to TimeProps

* Add incomplete dateFormatString setting

* Move 24-hour  toggle to Appearance

* Add "Date & Time" subheading, cleanup after merge

* Add setting for date formatting

* Fix minor formatting and naming issues

* Document functions

* adress most comments

* add hint for date formatting

* add support for 24hr time to TimePicker

* prevent overflow on small displays
2025-07-27 22:13:00 +10:00
Ajay Bura 589370f1bd Link device account management with OIDC (#2390)
* load auth metadata configs on startup

* deep-link cross-signing reset button with oidc

* deep-link manage devices and delete device with oidc

* fix import typo
2025-07-15 22:40:16 +10:00