尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證data sharing
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗This is a Next.js project bootstrapped with create-next-app.
Copy your Supabase project's URL and anon key into .env.local (placeholders are there by default):
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Run the development server:
npm run dev
Open http://localhost:3000 with your browser to see the result.
This milestone proves out the signaling layer (Supabase Realtime Broadcast) that
Milestone 2 will layer WebRTC on top of. No RTCPeerConnection code exists yet —
two tabs just exchange arbitrary broadcast messages over a shared room channel.
lib/supabase.ts — Supabase client singletonlib/roomId.ts — generates a 6-character, unambiguous room codehooks/useSignalingChannel.ts — subscribes to room-<id> and exposes
sendMessage, onMessage, status, and disconnectapp/page.tsx — sender/create-room viewapp/join/page.tsx — receiver/join-room view/join), paste the room ID, and click
Join.<id>". Tab A should flip from
"Waiting for peer..." to "Peer connected" shortly after./join and re-enter the same room ID — it should
reconnect successfully and Tab A should see "Peer connected" fire again./join and enter a made-up/invalid room ID. This
should not crash the app — it will report as "connected" to an empty
channel (see note below), since Supabase Realtime channels don't require
a room to be pre-created. If Supabase itself is unreachable (bad URL/key,
network issue), the status will show a clear "Connection error" state
instead of hanging on "Connecting...".Note on room validity: Supabase Realtime broadcast channels are created implicitly on subscribe — there's no server-side concept of a room "existing" yet. So joining a room nobody created will still show as "connected," it just won't receive any messages. Real room-existence validation (e.g. a
roomstable, or Presence to detect whether the sender is actually there) is deferred to Milestone 6 — see the comment inhooks/useSignalingChannel.ts.
This milestone adds the actual WebRTC layer on top of Milestone 1's signaling.
An RTCPeerConnection is established using the existing Supabase signaling
channel to exchange the SDP offer/answer and ICE candidates, resulting in an
open RTCDataChannel between the two browsers. Once that DataChannel opens,
the signaling channel is disconnected — everything after that is direct
peer-to-peer, no server involved.
lib/webrtc-config.ts — RTCConfiguration with a public STUN server (no
TURN yet — see Milestone 6)hooks/usePeerConnection.ts — wraps useSignalingChannel to run the
offer/answer/ICE handshake and exposes connectionState, sendData,
onData, disconnectapp/page.tsx / app/join/page.tsx — updated to use usePeerConnection
instead of raw signaling broadcasts for the test message boxNote on STUN-only connectivity: only a public STUN server is configured right now. If either side is behind a strict/symmetric NAT or a corporate firewall, the handshake can hit a "Connection failed" state — that's expected until Milestone 6 adds a TURN server.
This milestone replaces the Milestone 2 raw test-string box with a real chat feature: a typed, extensible message protocol over the DataChannel, a proper chat UI, and a clear "connection lost" state if the peer drops mid-chat.
lib/messageTypes.ts — ChatMessage / DataChannelMessage discriminated
union sent over the wire (JSON-stringified in, JSON-parsed + narrowed by
type out); more variants (file-meta, file-chunk, ...) get added here in
Milestone 4hooks/useChat.ts — wraps a usePeerConnection result into
messages / sendMessage(), with sent messages added optimistically and
unrecognized incoming message types ignored (logged, not thrown)components/ChatPanel.tsx — scrollable message list (sender/receiver
bubbles, timestamps, auto-scroll, empty state), input that's disabled
whenever connectionState !== 'connected', and a banner when the
connection is lost mid-chatapp/page.tsx / app/join/page.tsx — render <ChatPanel /> below the
existing connection status indicatorroomId exists, with input disabled until the status reads "Connected
(P2P)".This milestone adds chunked file transfer on the same DataChannel chat already uses, with backpressure handling so large files don't blow up browser memory, and SHA-256 checksum verification so silent corruption on a large transfer gets caught instead of ignored.
lib/messageTypes.ts — adds FileMeta / FileChunk / FileComplete to
DataChannelMessage. Chunks stay base64-in-JSON (not raw binary frames)
to keep one consistent message format with chat on the same channel —
documented tradeoff, see the file header comment in
hooks/useFileTransfer.tshooks/usePeerConnection.ts — gained isOpen(), getBufferedAmount(),
and waitForBufferedAmountBelow(threshold) so a chunked sender can pace
itself against RTCDataChannel.bufferedAmount instead of flooding the
channelhooks/useFileTransfer.ts — sendFile(file) chunks at 16KB, pausing
whenever bufferedAmount exceeds 1MB until the channel's
bufferedamountlow event fires; computes a whole-file SHA-256 and sends
it in file-complete. On receive, chunks are reassembled by index into a
Blob, re-hashed, and compared against the sender's checksum — a
mismatch (or a dropped connection mid-transfer) marks the transfer
failed rather than silently accepting bad datacomponents/FileTransferPanel.tsx — file picker, per-transfer progress
bars (sending/receiving), and download links for completed filescomponents/SessionPanels.tsx — tabs Chat/Files above ChatPanel and
FileTransferPanel; both stay mounted (just hidden) when switching tabs
so neither chat history nor in-flight transfer progress resetsapp/page.tsx / app/join/page.tsx — render <SessionPanels /> instead
of <ChatPanel /> directlybufferedAmount backpressure is actually pausing sends.To learn more about Next.js, take a look at the following resources:
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.