ClipSpacesClipSpaces Docs
Back to app

All releases

Same-network peer sharing + drag-and-drop files

Added

  • Same-network peer discovery & an ephemeral shared tray (signed-out). Visitors behind the same router can now find each other and open a temporary shared "clipboard" that lasts only as long as both sessions are open.
    • Discovery + signaling ride a Supabase Realtime channel keyed by a salted hash of the visitor's public IP (app/api/network/route.ts — raw IPs never leave the server). Two clients on the same hash see each other as throwaway "Adjective Animal" peers (lib/identity.ts randomAnonName).
    • Connecting is explicit: one peer requests, the other accepts/declines (components/LocalPeersDock.tsx). On accept, the pair upgrade to a direct WebRTC data channel (lib/webrtc.ts) with chunked, back-pressured file transfer — so links, text, and any file move peer-to-peer with no storage bucket.
    • The shared tray (LocalPeersDock) shows every shared item live to both sides; drag an item onto the canvas (or click +) to keep it. Closing the tab tears everything down. Orchestration lives in lib/use-local-peers.ts.
    • Gated to signed-out users (signed-in users have account-based collaboration) and requires Supabase to be configured; otherwise it's silently off.
    • Optional NETWORK_SALT and NEXT_PUBLIC_TURN_* env (see .env.example).
  • Drag-and-drop onto the canvas (components/Canvas.tsx). Drop image files, generic files (PDF/zip/doc/…), dragged URLs, or selected text and each lands at the cursor. A drop overlay highlights the target.
  • File cards (components/cards/FileCard.tsx, FileCard in lib/canvas-store.ts). Non-image files become a download chip; bytes inline as a data URL (capped at 8 MB — larger files keep a metadata-only chip).

Tooling

  • Unit tests (Vitest + jsdom). 39 tests under tests/ cover the new feature logic: WebRTC item/file wire protocol incl. chunked transfer reassembly (tests/webrtc.test.ts), the /api/network IP-hash route (tests/network-route.test.ts), byte formatting + card/edge persistence (tests/canvas-store.test.ts), and the identity helpers (tests/identity.test.ts). Run pnpm test (watch) or pnpm test:run.
  • Logged test runs. pnpm test:log runs the suite once and appends a timestamped record to test-results.log (gitignored) via scripts/test-with-log.mjs.
  • Pre-push gate. pnpm verify runs the logged tests then a full next build. A committed .githooks/pre-push runs it before every push (bypass with git push --no-verify); pnpm install wires core.hooksPath automatically via the prepare script (scripts/setup-hooks.mjs) — no husky dependency.

Changed

  • formatBytes now drops a trailing .0 so sizes read "1 KB" / "5 GB" instead of "1.0 KB" / "5.0 GB".