diff --git a/LOTUS_FEATURES.md b/LOTUS_FEATURES.md index bbc6440e4..fb79a4615 100644 --- a/LOTUS_FEATURES.md +++ b/LOTUS_FEATURES.md @@ -1171,6 +1171,14 @@ Persists via the `homeRoomSort` setting. A toggle in **Settings → Privacy** switches between sending `m.read` (public receipts) and `m.read.private` (private receipts visible only to the sender and the server). +### Tracking-Parameter Stripping (Gitea #103) + +Links you paste, send, edit, or merely _see_ lose ad/analytics identifiers — `utm_*`, `fbclid`, `gclid`, YouTube `si=`, Amazon `ref=`/`tag=`, X `s=`/`t=`, TikTok `_r`/`_t`, and ~40 more, plus host-scoped rules so e.g. `si` is only removed on YouTube/Spotify. Runs entirely on the device (`src/app/utils/urlTracking.ts`, unit-tested). Wired at paste (re-inserted through Slate so multi-line pastes still split into paragraphs), at send/schedule/edit on both `body` and `formatted_body`, and at render (linkify + explicit `` in formatted HTML), so links from other clients are cleaned locally too. `matrix.to` and non-http(s) schemes are never touched; Amazon's `th`/`psc` variant selectors are kept. Toggle in **Settings → Privacy → Strip Tracking Parameters from Links** (default on). + +### Settings Sync Across Devices (Gitea #104) + +The syncable subset of Lotus settings (theme, composer toolbar order, notification/quiet-hour preferences, call keys, privacy toggles, …) is mirrored to the `io.lotus.settings` account-data event on the user's own homeserver and applied on every other device. Device-bound keys stay local (`DEVICE_LOCAL_KEYS` in `src/app/utils/settingsSync.ts`: page zoom, media auto-load, animation pause, glassmorphism, noise-suppression tier/model, bitrates, volumes, notification permission, developer tools, PTT mode, camera-on-join, drawer state). Conflicts are last-write-wins on an `updatedAt` stamp forced monotonic per device; a per-account `lastSyncedAt` marker in localStorage stops a device from echoing a snapshot it just applied. **Settings → General → Sync** has the toggle (itself device-local), **Push now** (make this device win everywhere) and **Clear synced copy**. Hook: `src/app/hooks/useSettingsSync.ts`, mounted from `ClientNonUIFeatures`. + ### Media Gallery `MediaGallery.tsx` — a right-side drawer for browsing room media. diff --git a/LOTUS_TODO.md b/LOTUS_TODO.md index 4aec8681d..4f9f1db4b 100644 --- a/LOTUS_TODO.md +++ b/LOTUS_TODO.md @@ -236,7 +236,7 @@ After Phases A–C the client spec is ~complete. What's left, flagged by **what **✅ Buildable NOW (client-only, no server/infra change):** -- [ ] **Custom room tags / sections** — user-defined room categories in the sidebar via standard `u.*` room tags (beyond the built-in Favourite / Low-Priority). Mirrors the favourite/low-priority category pattern (`RoomNavItem` context-menu + `Home.tsx` categories). _Medium._ The only substantive client-only feature left. +- [ ] **Custom room tags / sections** (Gitea **#108**, milestone _Features 2026-Q4_) — user-defined room categories in the sidebar via standard `u.*` room tags (beyond the built-in Favourite / Low-Priority). Mirrors the favourite/low-priority category pattern (`RoomNavItem` context-menu + `Home.tsx` categories). _Medium._ The only substantive client-only feature left. **🔧 Needs INFRASTRUCTURE (NOT a Synapse-flag flip — you'd have to stand it up):** @@ -258,6 +258,8 @@ After Phases A–C the client spec is ~complete. What's left, flagged by **what ## 📋 Open Feature Backlog +**Features 2026-Q4 milestone (Gitea):** #103 tracking-param stripping ✅ · #104 settings sync ✅ · #105 desktop keychain + idle lock (research) · #106 search operators (research) · #107 paste-as-code (research) · #108 custom room sections. + ### [ ] Basic in-app audio editor / video→audio extractor (LARGE PROJECT) A minimal audio editor for soundboard clips and voice content. Scope: (1) **trim/clip** an audio file to a chosen start/end (waveform scrubber, in/out handles); (2) **upload a video file → strip and discard the video track, keep only the audio** (extract audio, then the source video is dropped — never uploaded/stored); (3) minimal edits only (trim, maybe gain/normalize, fade in/out) — not a full DAW. Likely Web Audio API (`AudioContext.decodeAudioData` → trim `AudioBuffer` → re-encode) + `MediaRecorder`/an encoder for output; video demux via a `