@@ -31,6 +31,17 @@ function copy(text) {
3131 navigator . clipboard ?. writeText ( text ) . catch ( ( ) => { } )
3232}
3333
34+ // QR Code generator using canvas
35+ function generateQR ( text , size = 200 ) {
36+ const canvas = document . createElement ( 'canvas' )
37+ const ctx = canvas . getContext ( '2d' )
38+
39+ // Simple QR code using Google Charts API
40+ const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${ size } x${ size } &data=${ encodeURIComponent ( text ) } `
41+
42+ return qrUrl
43+ }
44+
3445export default function App ( ) {
3546 const [ cfg , setCfg ] = useLocalStorage ( 'peer.cfg' , defaultConfig )
3647 const [ label , setLabel ] = useLocalStorage ( 'peer.label' , '' )
@@ -42,6 +53,7 @@ export default function App() {
4253 const [ muted , setMuted ] = useState ( false )
4354 const [ connected , setConnected ] = useState ( false )
4455 const [ streamActive , setStreamActive ] = useState ( false )
56+ const [ showQR , setShowQR ] = useState ( false )
4557
4658 const peerRef = useRef ( null )
4759 const connRef = useRef ( null )
@@ -184,6 +196,8 @@ export default function App() {
184196 }
185197
186198 const connectDisabled = ! peerIdInput || status !== 'ready'
199+ const shareableUrl = myId ? `${ window . location . origin } ${ window . location . pathname } ?peer=${ myId } ` : ''
200+ const qrUrl = myId ? generateQR ( shareableUrl ) : ''
187201
188202 return (
189203 < div className = "app" >
@@ -199,8 +213,24 @@ export default function App() {
199213 < div className = "mono" style = { { wordBreak : 'break-all' } } > { myId || 'Starting…' } </ div >
200214 </ div >
201215 < button className = "secondary" onClick = { ( ) => copy ( myId ) } disabled = { ! myId } > Copy ID</ button >
216+ < button className = "secondary" onClick = { ( ) => setShowQR ( ! showQR ) } disabled = { ! myId } >
217+ { showQR ? 'Hide QR' : 'Show QR' }
218+ </ button >
202219 </ div >
203220
221+ { showQR && myId && (
222+ < div className = "card" style = { { marginTop : 16 , padding : 16 , textAlign : 'center' } } >
223+ < div className = "small" style = { { marginBottom : 8 } } > Scan this QR code to share your Peer ID</ div >
224+ < img src = { qrUrl } alt = "QR Code" style = { { maxWidth : '200px' , margin : '0 auto' , display : 'block' } } />
225+ < div className = "small" style = { { marginTop : 8 , opacity : 0.7 , wordBreak : 'break-all' } } >
226+ { shareableUrl }
227+ </ div >
228+ < button className = "secondary" onClick = { ( ) => copy ( shareableUrl ) } style = { { marginTop : 8 } } >
229+ Copy Shareable URL
230+ </ button >
231+ </ div >
232+ ) }
233+
204234 < div className = "grid" style = { { marginTop : 16 } } >
205235 < div className = "card" style = { { padding : 16 } } >
206236 < div className = "small" > 1) Enter a friend's Peer ID</ div >
@@ -250,9 +280,10 @@ export default function App() {
250280 < li > Both users must open this page and share their Peer IDs to connect.</ li >
251281 < li > Audio is sent end-to-end via WebRTC. Without your own TURN, very strict NATs may block audio.</ li >
252282 < li > Over GitHub Pages, only static hosting is available; we use PeerJS public broker for signalling.</ li >
283+ < li > Use the QR code to quickly share your Peer ID with others on the same Wi-Fi.</ li >
253284 </ ul >
254285 </ div >
255286 </ div >
256287 </ div >
257288 )
258- }
289+ }
0 commit comments