Commit Graph

1072 Commits

Author SHA1 Message Date
Jeff Emmett 29548dad30 Merge branch 'dev' 2026-03-20 17:19:37 -07:00
Jeff Emmett befd70c72b feat(rdata): add content tree view with search, tags, and sort
Adds a new Content Tree tab (default) to rData that indexes all Automerge
docs in a space. Includes /api/content-tree endpoint, folk-content-tree
web component with search, tag filtering, sort modes, expand/collapse,
and demo data fallback. Analytics moves to second tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 17:19:16 -07:00
Jeff Emmett 451801d12c Merge branch 'dev' 2026-03-20 17:14:28 -07:00
Jeff Emmett 1827b34f6b fix(rcal): seed sample data for all spaces, not just demo
Auto-seed calendar sources and events on first visit to any space's
rcal page, and during space creation via seedTemplate hooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 17:14:17 -07:00
Jeff Emmett dfcb2333e3 Merge branch 'dev' 2026-03-20 16:45:43 -07:00
Jeff Emmett 4f1eab3104 fix(spaces): redirect to subdomain URL after space creation
Create-space form redirected to /{slug}/rspace which 404s on subdomain
hosts (jeff.rspace.online/mycofi/rspace → rewritten to /jeff/mycofi/rspace).
Now redirects to https://{slug}.rspace.online/rspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:45:35 -07:00
Jeff Emmett 2a1e8d784e Merge branch 'dev' 2026-03-20 16:31:37 -07:00
Jeff Emmett 93b7251054 fix(rvote): remove /demo route, use subdomain links consistently
Spaces are always subdomains — no path-based space routing or redirects.
Landing page demo links now point to demo.rspace.online/rvote.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:31:34 -07:00
Jeff Emmett 3233f5057c Merge branch 'dev' 2026-03-20 16:29:37 -07:00
Jeff Emmett 8d8ae7e351 fix(rvote): serve demo at demo.rspace.online/rvote instead of /rvote/demo
Extract demo body into renderDemoBody(), serve it from the / route when
space=demo (which is what demo.rspace.online/rvote resolves to via
subdomain routing). Legacy /demo path now 301-redirects to the canonical
demo.rspace.online/rvote URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:29:26 -07:00
Jeff Emmett 7ee0be7718 Merge branch 'dev' 2026-03-20 16:27:20 -07:00
Jeff Emmett 05459ec8a9 feat(rwallet): pagination, transaction tables, and reset view buttons
Paginated transfers endpoint (up to 3000 txs with exponential backoff),
collapsible incoming/outgoing transaction tables below visualizations,
and Reset View buttons on all three D3 charts (Timeline, Flow, Sankey).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:27:06 -07:00
Jeff Emmett 88e108950a Merge branch 'dev' 2026-03-20 16:21:58 -07:00
Jeff Emmett f9fc0ca6ec feat(rvote): add QPR explanations and conviction voting simulator to demo
Add ELI5 cards (quadratic, reddit-style ranking, vote decay) and an
interactive conviction voting simulator with credit budget, quadratic
costs, proposal ranking, and promotion threshold progress bars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:21:50 -07:00
Jeff Emmett 616944fb91 Merge branch 'dev' 2026-03-20 15:54:18 -07:00
Jeff Emmett 34ece96927 feat(rnotes): import converters for Evernote, Roam, file upload & sync
New converters: Evernote (.enex), Roam Research (JSON), generic file
import, and sync service. Enhanced existing Obsidian, Logseq, Google
Docs, and Notion converters. Updated import-export dialog, schemas,
and server routes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 15:53:57 -07:00
Jeff Emmett df489d698c feat(rsocials): newsletter editor with Listmonk integration
Full campaign editor with HTML body textarea, live iframe preview,
list selector with subscriber counts, save draft, send now, and
schedule send. Added edit/delete actions on draft campaigns and
GET/PUT/DELETE single-campaign proxy routes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 15:53:35 -07:00
Jeff Emmett d687ebb6ac Merge branch 'dev' 2026-03-20 15:38:28 -07:00
Jeff Emmett 16b975cf5a fix(rvote): align demo page content with rvote.online
Match the standalone site's demo page: badge, title, description, loading
text, and CTA card for feature parity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 15:38:13 -07:00
Jeff Emmett 2be38e7fee Merge branch 'dev' 2026-03-20 14:28:30 -07:00
Jeff Emmett 0c9b07525f feat(rsocials): merge Posts & Threads nav + Postiz API integration
Rename "Threads" to "Posts & Threads" in hub nav, route title, and subPageInfos.
Thread gallery now shows draft/scheduled posts from campaigns alongside threads.
Add Postiz API client (postiz-client.ts) with settings schema for URL + API key.
Proxy routes: /api/postiz/status, integrations, posts, threads.
Wire workflow executor to call real Postiz API for post/thread/cross-post nodes.
Add "Send to Postiz" button in thread builder (editor + readonly views).
Add approval queue: PendingApproval schema (v5), GET/POST /api/approvals routes,
wait-approval workflow node creates pending approvals and pauses execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 14:28:22 -07:00
Jeff Emmett d45b674326 Merge branch 'dev' 2026-03-20 14:19:52 -07:00
Jeff Emmett ed8274961e chore(rsocials): rename Threads to Posts & Threads
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 14:19:41 -07:00
Jeff Emmett d4972453a3 feat(onboarding): add module-specific connect/import/create CTAs
Declarative onboardingActions on RSpaceModule lets each rApp define its
own onboarding cards (import, upload, link, create). renderOnboarding()
renders them as a responsive card grid with upload handling. Adds ICS
import endpoint to rCal (POST /api/import-ics). 15 modules wired up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 14:17:19 -07:00
Jeff Emmett 31266e75fd Merge branch 'dev' 2026-03-20 13:04:56 -07:00
Jeff Emmett df77c9c903 feat(shell): cross-tab sync via BroadcastChannel + keyboard shortcuts & swipe gestures
Add BroadcastChannel for instant same-browser tab sync — opening/closing
tabs in one window propagates immediately to sibling tabs. Extract
reconcileRemoteLayers() helper shared by BroadcastChannel and Automerge,
which cleans up cached DOM panes on remote removal and handles
active-tab-closed scenarios.

Also adds configurable rApp shortcuts (Ctrl/Alt+1-9), header swipe
gestures for rApp cycling, and body data-module-id attr for swipe context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:04:31 -07:00
Jeff Emmett 75fba6da89 feat(shell): add rApp keyboard shortcuts and swipe gestures
Configurable shortcuts (1-9 slots) stored in localStorage. Ctrl+1-9
in PWA mode, Alt+1-9 in browser. Swipe left/right on header to cycle.
Settings UI added to account modal with 3x3 slot grid.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:03:35 -07:00
Jeff Emmett 8741f5dbd5 feat(rnotes): add presence indicators on notebook cards and note items
Show colored dots on notebook cards and note list items indicating which
peers are currently viewing/editing. Uses existing presence message relay
with zero server changes — heartbeat every 10s, stale peer GC at 20s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 12:43:04 -07:00
Jeff Emmett ad9e54dbe9 refactor(rinbox): replace forwarding banner with popup modal
Convert inline forwarding banner to a click-triggered modal overlay.
Fix API field name bug (data.target → data.forwardsTo). Add email
input for no-email state with sovereignty messaging. Remove dismiss
logic in favor of modal open/close.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 12:15:53 -07:00
Jeff Emmett 42a84cb72e refactor(rsocials): consolidate threads + thread editor into single nav item
The thread gallery already has a "New Thread" button linking to the editor,
so a separate hub button and subnav pill for the editor is redundant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 12:11:24 -07:00
Jeff Emmett d9b298a56e chore(backlog): add CrowdSurf integration task definitions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 12:00:14 -07:00
Jeff Emmett 88c6c70f9e fix(rmaps): add cache-busting version to JS/CSS script tags
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:56:35 -07:00
Jeff Emmett 8bd8348529 feat(encryptid): fix DID consistency, add PRF key derivation, stepper signup, and magic link login
- Fix DID mismatch: server now stores and reads proper did🔑z6Mk... DIDs
  from database instead of deriving truncated did🔑${slice(0,32)}
- Add PRF extension to WebAuthn create/get flows for client-side key derivation
- Derive DID, signing keys, encryption keys, and EOA wallet from passkey PRF
- Auto-upgrade truncated DIDs to proper format on sign-in
- Add POST /api/account/upgrade-did endpoint for DID migration
- Add 5-step educational registration wizard (identity, passkey, DID, wallet, security)
- Add email/username field to sign-in for scoped passkey selection
- Add magic link email login for external devices without passkeys
- Add POST /api/auth/magic-link and GET /magic-login verification page
- Add mintWelcomeBalance() for 5 fUSDC to new users
- Store EOA wallet address during registration when PRF available

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:29:20 -07:00
Jeff Emmett db61e54d7b feat(rmaps): mobile UX overhaul — floating FAB menu, self-marker, bottom sheet, privacy consolidation
- Fix QR code (replace broken Node.js import with api.qrserver.com API)
- Rename "Share Room" → "Share rMap" across UI
- Add "hidden" precision level replacing ghost mode toggle
- Unified 5-level privacy panel (Exact → Hidden/Ghost) as button list
- Pulsing blue dot self-marker (replaces emoji circle for own position)
- Locate-me FAB (bottom-left, both mobile and desktop)
- Mobile: edge-to-edge map, floating FAB menu with staggered animations
- Mobile: bottom sheet for participants (peek/expand with touch drag)
- Mobile: hide sidebar/controls/privacy panel, overlay compact nav bar
- Extract shared participant list helpers for desktop sidebar + mobile sheet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:23:41 -07:00
Jeff Emmett 1c93e3bb67 feat(rinbox): add email forwarding prompt banner and fix auth token reading
Replace broken encryptid-token localStorage reads with getAccessToken/getUsername
from rspace-header. Add forwarding status check against EncryptID API with
enable/disable/dismiss banner on mailboxes view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:23:01 -07:00
Jeff Emmett 92df7d332d fix(canvas): only show reminder calendar on icon click, not on shape select/drag
Remove the auto-opening calendar on shape selection and the drag-to-calendar
compact mode. The 📅 icon on selected shapes remains as the entry point.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:15:18 -07:00
Jeff Emmett 15c118923b fix(spaces): match owner DID format in space list + resolve all TS errors
Space dropdown showed "Request Access" for the owner's own space because
the /api/spaces endpoint only checked claims.sub against ownerDID, missing
the did🔑 format used by auto-provisioned spaces. Now uses dual-check
matching the resolveRole helper pattern.

Also fixes 15 pre-existing TypeScript errors:
- server/index.ts: add Hono AppEnv type for context variables
- modules/rnetwork/mod.ts: cast tuple index to number for arithmetic
- modules/rsplat/folk-splat-viewer.ts: type CDN-loaded three.js as any
- modules/rtube/mod.ts: cast Uint8Array to BlobPart for FormData

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:11:32 -07:00
Jeff Emmett 73ad020812 fix(spaces): fix space creation routing and use /rspace URLs
Space creation was broken because the canvas module has id "rspace" but
all navigation URLs used "/canvas". On production subdomain routing this
resulted in 404s after creating a space.

- Switch create-space form from deprecated /api/communities to /api/spaces
- Replace all /canvas navigation URLs with /rspace to match module ID
- Fix DID matching in space listing to check both sub and did:key formats
- Add proper client DID support in EncryptID registration flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:07:01 -07:00
Jeff Emmett 8bd6e61ffc feat(rsocials): add campaigns dashboard with workflow thumbnail grid
New gallery landing page at /campaigns showing all campaign workflows as
cards with miniature SVG previews. Click a card to open the editor at
?workflow=<id>. Editor gains back-link to dashboard and workflow attribute
for deep-linking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:47:03 -07:00
Jeff Emmett 39ec09bb3b fix(compat): improve cross-browser support for Firefox, Safari, and older browsers
Add global polyfills for AbortSignal.timeout() (Safari <17, Firefox <122)
and crypto.randomUUID() (Safari <15.4, Firefox <95) in shell HTML templates.
Add -webkit-backdrop-filter prefix across 13 files for older Safari support.
Add Firefox scrollbar (scrollbar-width/scrollbar-color), range input
(::-moz-range-thumb/track), and color-mix() rgba fallbacks. Create shared
compat.ts utility module. Lowers browser floor from Safari 17/Firefox 122
to Safari 15.4/Firefox 95.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:43:38 -07:00
Jeff Emmett a736321189 feat(rnotes): add real-time Yjs collaboration, comments, and suggestions
Replace whole-content Automerge sync with character-level Yjs CRDT for
NOTE-type notes. Adds cursor presence, inline comments with threaded
replies, and track-changes suggesting mode.

- Custom Yjs WebSocket provider bridging over existing rSpace WS
- Server-side yjs-sync/yjs-awareness message relay (pure broadcast)
- y-indexeddb for offline persistence, periodic plaintext sync to Automerge
- Comment mark + panel with resolve/reply/delete
- Suggestion insert/delete marks with accept/reject support
- Schema v3→v4 (collabEnabled, comments fields)
- Collab toolbar: comment button, suggesting toggle, peer indicators

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:36:09 -07:00
Jeff Emmett b51dac1b22 test(spaces): add API test script for space creation & member management
Covers 19 test cases: space CRUD, member add by username, role changes
(viewer/member/moderator/admin), email invites, removal, auth guards.
Run with: ./e2e/tests/space-members-api.sh <AUTH_TOKEN>

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 21:15:52 -07:00
Jeff Emmett 1f97a2ceba fix(smtp): use noreply@rmail.online as sender across all modules
Mailcow rejects noreply@rspace.online because the authenticated user
is noreply@rmail.online. Updated all SMTP_FROM and SMTP_USER defaults
to use rmail.online consistently: spaces invites, rSplat notifications,
EncryptID auth emails, and rCart payment receipts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 21:00:41 -07:00
Jeff Emmett 315a29a6d7 fix(shell): hide notification/share/settings icons on mobile, add to identity dropdown
On mobile (<=640px), the header right section was too crowded with icons.
Now hides notification bell, share panel, and settings gear buttons, and
adds equivalent mobile-only items in the identity dropdown menu. Share
uses native navigator.share() when available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:58:52 -07:00
Jeff Emmett 9b81ba70b6 feat(shell): add share button to global header with QR, copy link, email invite
Extract canvas inline share panel into reusable <rstack-share-panel> web component
and add it to the shell header between notification bell and settings gear. Canvas
now uses the component too, removing ~230 lines of inline HTML/CSS/JS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:51:21 -07:00
Jeff Emmett e5814b12c6 fix(rsplat): use fal.ai response_url for result fetch, add poll logging
The result fetch was constructing its own URL instead of using the
response_url returned by fal.ai's status poll. This caused 422 errors.
Now captures response_url from poll and uses it for result retrieval.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:51:05 -07:00
Jeff Emmett 97636235bf fix(spaces): use correct EncryptID internal URL for member operations
The spaces module was defaulting to http://localhost:3000 for EncryptID
API calls, which resolves to the rspace container itself (both run on
port 3000). Changed to http://encryptid:3000 matching server/index.ts.
Also improved error surfacing in /members/add endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:50:13 -07:00
Jeff Emmett d999c98b98 fix(rsplat): resize images with sharp before fal.ai submission
Phone photos (3-4MB, 4000px+) were failing with "Invalid image" on
fal.ai Hunyuan3D. Now resizes to max 1024px JPEG with sharp before
submitting, and uses PUBLIC_ORIGIN HTTPS URL instead of data URI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:36:59 -07:00
Jeff Emmett 05b8e2676a fix(canvas): mobile toolbar uses collapse instead of FAB overlay
Replace the floating action button toggle with the same collapse/expand
behavior as desktop. Toolbar sits as a compact icon column on the left,
panels open to the right, and corner tools move to bottom-right.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:30:20 -07:00
Jeff Emmett be81618b70 fix(tabs): prevent closed tabs from reopening via server sync race
Two race conditions caused closed tabs to resurrect:
1. syncTabsFromServer() fetch completing after a local close, merging
   the stale server response back in
2. Debounced PUT killed by page navigation when closing the active tab,
   so the server never learned about the close

Fix: track closed moduleIds per session to skip during merge, and flush
server PUT with keepalive:true before navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:30:11 -07:00