Commit Graph

27 Commits

Author SHA1 Message Date
Jeff Emmett 2d0cf499f6 fix: mobile input focus, toolbar UX, and viewport clipping
- folk-shape: skip preventDefault on touch events targeting inputs/textareas
  so mobile keyboards can open inside shapes
- toolbar: replace unreadable emoji-only strip with FAB toggle (+) that
  opens a 3-column grid overlay with emoji + labels; auto-closes on tool
  select; separate always-visible zoom strip at bottom-left
- canvas: remove overflow:hidden from #canvas so viewport moves with
  pan/zoom instead of clipping at initial bounds
- canvas-content: add width/height 100% and overflow:visible for robust
  containing block

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:55:43 +00:00
Jeff Emmett 34a1e3b640 feat: mobile toolbar + infinite canvas pan/zoom
- Mobile toolbar: icon-only scrollable strip with horizontal swipe
- Infinite canvas: separate viewport (grid) from content layer (shapes)
- Single-finger pan via pointer events on empty canvas background
- Widen zoom range from 0.25-4x to 0.05-20x
- Fix Automerge sync fallback to full doc reconciliation when no patches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:32:48 +00:00
Jeff Emmett 048171131b feat: implement FUN model replacing CRUD across rSpace canvas
Forget (F): Soft-delete shapes — close button sets forgotten:true in
Automerge doc instead of removing. Memory panel (toolbar toggle) lets
users browse and Remember forgotten shapes. Server-side forgetShape()
and rememberShape() with WebSocket handlers.

Update (U): New public updateShape(id, fields) method on CommunitySync
for programmatic field updates. Existing auto-capture unchanged.

New (N): Renamed all create/add vocabulary to new — toolbar buttons,
event names (new-shape, shape-new, shape-removed), internal functions
(newShape, newShapeElement).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:21:53 +00:00
Jeff Emmett 33f0ef4077 fix: server-backed auth + show username instead of DID key
Rewrote auth flow to go through EncryptID server instead of
client-side unsigned JWTs. Fixes "Invalid or expired authentication
token" on space creation, and shows username in header.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:26:50 +00:00
Jeff Emmett 9f39e2393b fix: change WebAuthn RP ID from jeffemmett.com to rspace.online
The RP ID jeffemmett.com caused "relying party ID is not a registrable
domain suffix" errors on *.rspace.online subdomains. Related Origins
also exceeded the 5 eTLD+1 browser limit with 18+ domains listed.

Now rspace.online is the RP ID, so all *.rspace.online subdomains
(including cca.rspace.online) are valid automatically. The Related
Origins file only lists non-rspace.online r* ecosystem domains.

Also points rspace-header auth URL to auth.rspace.online.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:32:57 -07:00
Jeff Emmett a3572f7a5f feat: add rChats.online to ecosystem links and EncryptID allowed origins
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:15:42 -07:00
Jeff Emmett 6b06168f11 feat: add offline-first support with IndexedDB persistence and Service Worker
rSpace apps now work fully offline. Automerge documents and sync state
persist to IndexedDB, enabling instant load from cache, offline editing,
and automatic incremental merge on reconnect. A Service Worker caches
the app shell (HTML/JS/WASM) for loading without network.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:39:28 -07:00
Jeff Emmett 20a0796a4d Add folk-choice-* collaborative decision components
Three new canvas shapes for small-group decisions:
- folk-choice-vote: live polling with plurality, approval, and
  quadratic voting modes
- folk-choice-rank: drag-to-reorder with Borda count and
  instant-runoff aggregation
- folk-choice-spider: multi-criteria scoring with SVG radar chart,
  per-user polygon overlays, and weighted mean aggregation

All sync via rSpace's existing Automerge CRDT infrastructure.
Aggregation algorithms are exported as pure functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 11:18:00 +00:00
Jeff Emmett 46d8429082 fix: update header after auth via requireAuth flow
When a user authenticates through the community creation form (via
requireAuth), the header bar now re-renders to show the logged-in
state instead of still displaying the Sign In button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:34:03 -07:00
Jeff Emmett da48f6faf6 feat: add EncryptID auth header and gate community creation behind sign-in
Adds a persistent header bar with sign-in/sign-up across landing and canvas
pages. The "Create Community Space" form now requires EncryptID authentication,
showing a passkey auth modal if the user isn't signed in. Auth tokens are sent
with the community creation API call. EncryptID WebAuthn modules are lazy-loaded
only when auth is triggered.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:50:48 -07:00
Jeff Emmett c2255f1296 feat: add CRDT token issuance system with mint/ledger shapes
Implements BFT-CRDT token infrastructure as FolkShape components that
live in the existing Automerge document — no new server or database needed.
Admins can create token types (mint) and issue them to participants by
DID or email (ledger), with real-time sync across all connected peers.

- folk-token-mint: token definition (name, symbol, supply, color, icon)
- folk-token-ledger: distribution tracker with issuance form, email escrow
- Canvas toolbar "Token" button creates mint+ledger+arrow pair
- Demo seeds: GOV (equal governance) and CRED (contribution credits)
- community-sync: remote property updates for both token shapes
- EncryptID: add rTube, rStack to allowed origins and landing page
- rSpace landing page: add EncryptID and interoperability sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:01:47 -07:00
Jeff Emmett 38636862d8 fix: overhaul canvas shape creation, connections, and sync
- Fix CSS position:absolute missing for 5 trip planning shapes
- Expand arrow connection mode to all 21 shape types (was only 2)
- Center new shapes in viewport instead of clustering top-left
- Extract createAndAddShape() utility, eliminating ~270 lines of duplication
- Add missing Google Item toolbar button
- Add error handling on remote shape creation (try-catch-finally)
- Implement actual WebSocket keep-alive ping (was a no-op)
- Use shape.toJSON() in sync layer to capture all shape properties (was only 3 types)
- Add index signature to ShapeData for arbitrary shape-specific properties

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:27:48 -07:00
Jeff Emmett 2634d02344 Add trip planning components and postMessage bridge for rtrips.online
New folk-* web components for collaborative trip planning:
- folk-itinerary: timeline with day grouping and category icons
- folk-destination: location card with editable notes
- folk-budget: expense tracker with progress bar
- folk-packing-list: collaborative checklist with progress
- folk-booking: booking card with type/status badges

Also adds postMessage broadcasting in community-sync for iframe
embedding in rtrips.online, and toolbar buttons in canvas.html.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:21:03 -07:00
Jeff Emmett 9e32b5a457 fix: Use slot.parentElement instead of :scope selector for ShadowRoot
The :scope selector may not work correctly when querying from a ShadowRoot.
Use slot.parentElement to reliably find the container div to replace.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:09:48 +01:00
Jeff Emmett 42b29ff9d7 fix: Resolve replaceChild and activeElement errors in FolkJS components
- Fix activeElement undefined error by guarding against missing shadowRoot
- Fix replaceChild "parameter 2 is not of type Node" error in all 15 child
  components by using :scope > div selector to find container div directly
  instead of incorrectly searching inside slot.parentElement

The bug was caused by looking for a nested div that doesn't exist - the slot's
parent IS the container div that needs to be replaced.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:38:06 +01:00
Jeff Emmett 8eef5b58b7 feat: Add advanced shapes (task-5)
- folk-video-chat: WebRTC video chat with room joining, mute/video toggle
- folk-obs-note: Rich markdown editor with edit/preview/split modes
- folk-workflow-block: Visual workflow nodes with typed ports

All components integrated into canvas.html with toolbar buttons.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:42:41 +01:00
Jeff Emmett a6d2cdcf86 feat: Add AI integration shapes (task-4)
- folk-image-gen: Image generation with style selection
- folk-video-gen: Video generation with I2V/T2V modes
- folk-prompt: LLM chat interface with model selection
- folk-transcription: Real-time transcription via Web Speech API

All shapes integrated into canvas.html with toolbar buttons.
Backend API endpoints are placeholders to be implemented.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:30:02 +01:00
Jeff Emmett 061b17c264 feat: Add core data shapes (task-3)
- folk-embed: URL embeds for YouTube, Twitter/X, Google Maps
- folk-calendar: Month view calendar with events
- folk-map: MapLibre GL integration with OSM tiles and markers

Integrated all shapes into canvas.html with toolbar buttons.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 20:27:47 +01:00
Jeff Emmett 5115d03082 feat: Add real-time presence cursors for collaboration
- PresenceManager class tracks remote users' cursors and selections
- SVG cursor with username label and auto-assigned colors
- CommunitySync.sendPresence() broadcasts cursor/selection updates
- Throttled to 50ms to prevent flooding
- Auto-fade after 5s inactivity, auto-remove after 15s
- Selection highlight shows which shape each user has selected

Completes task-7: Real-time presence cursors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 19:13:51 +01:00
Jeff Emmett 10786f5723 feat: Add mobile touch support for canvas
FolkShape:
- Single-touch drag with position delta tracking
- Touch event handling (touchstart, touchmove, touchend)
- Respects viewport zoom level

Canvas:
- Pinch-to-zoom with two-finger gesture
- Two-finger pan for navigation
- Mouse wheel zoom for desktop
- touch-action: none to prevent browser gestures
- Larger touch targets on coarse pointer devices

Completes task-6: Mobile touch support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 18:57:51 +01:00
Jeff Emmett ff3a432c04 feat: Add 4 FolkJS shape components (slide, chat, google-item, piano)
- folk-slide: Presentation slide container with dashed border
- folk-chat: Real-time chat with username persistence
- folk-google-item: Data card for Google services with visibility toggle
- folk-piano: Chrome Music Lab Shared Piano iframe embed

All components extend FolkShape, implement toJSON(), and support
drag via data-drag attribute. Toolbar buttons added for each.

Completes task-2: Phase 1 - Port Simple Shapes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 18:48:36 +01:00
Jeff Emmett aa204a530a feat: Add shared FolkJS utilities (maximize, pinned-view, toJSON)
- maximize.ts: maximizeShape(), restoreShape(), toggleMaximize()
- pinned-view.ts: PinnedViewManager class for viewport-fixed shapes
- folk-shape.ts: Base toJSON() method for Automerge sync
- Updated exports in lib/index.ts

Completes task-8: Port shared hooks as FolkJS utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 18:36:40 +01:00
Jeff Emmett 7ebf45e984 Fix shape dragging - allow drag from header elements 2026-01-02 14:32:02 +01:00
Jeff Emmett f3e18b6124 Add FolkArrow component for shape connections
- Implement folk-arrow web component using perfect-arrows
- Curved bezier arrows with perfect-freehand stroke styling
- Dynamic position tracking via requestAnimationFrame
- Connection mode: click source then target to create arrow
- Sync arrow properties (sourceId, targetId, color) via Automerge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 23:13:25 +01:00
Jeff Emmett ddab22abc2 Add FolkWrapper component for standardized card UI
- Port StandardizedWrapper from React to web component
- Header with title, icon, color theming
- Pin, minimize, close action buttons
- Tags footer with add/remove functionality
- Integrate into canvas with "Card" toolbar button
- Sync wrapper properties via Automerge CRDT

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 23:06:48 +01:00
Jeff Emmett d6042fcfe7 feat: Add Automerge CRDT sync for real-time collaboration
- CommunitySync class bridges FolkJS shapes with Automerge documents
- Server stores Automerge binary format with debounced persistence
- Per-peer sync state for efficient delta synchronization
- WebSocket messages carry Automerge sync protocol
- Automatic migration from JSON to Automerge format
- WASM plugin for Vite to handle Automerge bundle

Enables true CRDT-based collaboration with:
- Conflict-free concurrent editing
- Efficient delta sync (only changed data)
- Offline-capable local documents
- Automatic peer reconnection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 22:59:32 +01:00
Jeff Emmett 1ec463f193 Initial rspace-online: FolkJS collaborative canvas with subdomain routing
- Pure FolkJS implementation with folk-shape, folk-markdown components
- Bun server with WebSocket sync and Host header subdomain detection
- Community creation API at /api/communities
- Docker setup with Traefik labels for wildcard *.rspace.online routing
- Landing page with community creation form
- Canvas page with basic markdown note creation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 16:27:07 +01:00