diff --git a/package-lock.json b/package-lock.json index ce4ae0b..1031623 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,7 @@ "marked": "^15.0.4", "one-webcrypto": "^1.0.3", "openai": "^4.79.3", + "qrcode.react": "^4.2.0", "rbush": "^4.0.1", "react": "^18.2.0", "react-cmdk": "^1.3.9", @@ -80,6 +81,7 @@ }, "engines": { "node": ">=20.0.0" +<<<<<<< HEAD } }, "multmux/packages/cli": { @@ -197,6 +199,8 @@ "utf-8-validate": { "optional": true } +======= +>>>>>>> db7bbbf (feat: add invite/share feature with QR code, URL, NFC, and audio connect) } }, "node_modules/@ai-sdk/provider": { @@ -14887,6 +14891,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/qrcode.react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", + "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", diff --git a/package.json b/package.json index a95efaa..e0a8ee3 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "marked": "^15.0.4", "one-webcrypto": "^1.0.3", "openai": "^4.79.3", + "qrcode.react": "^4.2.0", "rbush": "^4.0.1", "react": "^18.2.0", "react-cmdk": "^1.3.9", diff --git a/src/components/ShareBoardButton.tsx b/src/components/ShareBoardButton.tsx new file mode 100644 index 0000000..b647b4e --- /dev/null +++ b/src/components/ShareBoardButton.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { useParams } from 'react-router-dom'; +import { useDialogs } from 'tldraw'; +import { InviteDialog } from '../ui/InviteDialog'; + +interface ShareBoardButtonProps { + className?: string; +} + +const ShareBoardButton: React.FC = ({ className = '' }) => { + const { slug } = useParams<{ slug: string }>(); + const { addDialog, removeDialog } = useDialogs(); + + const handleShare = () => { + const boardSlug = slug || 'mycofi33'; + const boardUrl = `${window.location.origin}/board/${boardSlug}`; + + addDialog({ + id: "invite-dialog", + component: ({ onClose }: { onClose: () => void }) => ( + { + onClose(); + removeDialog("invite-dialog"); + }} + boardUrl={boardUrl} + boardSlug={boardSlug} + /> + ), + }); + }; + + return ( + + ); +}; + +export default ShareBoardButton; diff --git a/src/ui/CustomToolbar.tsx b/src/ui/CustomToolbar.tsx index 944fb9c..f1cdc6e 100644 --- a/src/ui/CustomToolbar.tsx +++ b/src/ui/CustomToolbar.tsx @@ -8,6 +8,7 @@ import { SettingsDialog } from "./SettingsDialog" import { useAuth } from "../context/AuthContext" import LoginButton from "../components/auth/LoginButton" import StarBoardButton from "../components/StarBoardButton" +import ShareBoardButton from "../components/ShareBoardButton" import { ObsidianVaultBrowser } from "../components/ObsidianVaultBrowser" import { HolonBrowser } from "../components/HolonBrowser" import { ObsNoteShape } from "../shapes/ObsNoteShapeUtil" @@ -652,8 +653,8 @@ export function CustomToolbar() { }} > + - {session.authed && (
+ + + +
+ + {/* Tab content */} +
+ {activeTab === 'qr' && ( +
+
+ +
+

+ Scan this QR code with a mobile device to join the board +

+
+ )} + + {activeTab === 'url' && ( +
+
+ {boardUrl} +
+ +

+ Share this link with anyone to invite them to your board +

+
+ )} + + {activeTab === 'nfc' && ( +
+ {nfcStatus === 'unsupported' ? ( + <> +
+ NFC +
+

+ NFC is not supported on this device +

+

+ Try using a mobile device with NFC capability +

+ + ) : ( + <> +
+ {nfcStatus === 'success' ? '(done)' : nfcStatus === 'error' ? '(!)' : 'NFC'} +
+ + {nfcMessage && ( +

+ {nfcMessage} +

+ )} + {!nfcMessage && ( +

+ Write the board URL to an NFC tag for instant access +

+ )} + + )} +
+ )} + + {activeTab === 'audio' && ( +
+
+ ((( ))) +
+

+ Audio Connect +

+

+ Share the board link via ultrasonic audio +

+
+ Coming soon! Audio-based sharing will allow nearby devices to join by listening for an ultrasonic signal. +
+
+ )} +
+ + + + + Done + + + + + + ) +}