diff --git a/package-lock.json b/package-lock.json
index 4bb6260..37903c2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,6 +28,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.3",
+ "react-qrcode-logo": "^2.8.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"react-syntax-highlighter": "^15.5.0",
@@ -16401,6 +16402,11 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -20353,6 +20359,11 @@
"teleport": ">=0.2.0"
}
},
+ "node_modules/qrcode-generator": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz",
+ "integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw=="
+ },
"node_modules/qs": {
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
@@ -20685,6 +20696,19 @@
"p-defer": "^3.0.0"
}
},
+ "node_modules/react-qrcode-logo": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/react-qrcode-logo/-/react-qrcode-logo-2.8.0.tgz",
+ "integrity": "sha512-dbEgjsg6C4tK6+oGmCRDlJ7urQAWqybaGBLJtp8Z6ZYvVUP302HBXk/F7VRk54yWTwzlHwig3VK6HMKCha2YFw==",
+ "dependencies": {
+ "lodash.isequal": "^4.5.0",
+ "qrcode-generator": "^1.4.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.4.1",
+ "react-dom": ">=16.4.1"
+ }
+ },
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -36682,6 +36706,11 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -39300,6 +39329,11 @@
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw=="
},
+ "qrcode-generator": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz",
+ "integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw=="
+ },
"qs": {
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
@@ -39547,6 +39581,15 @@
"p-defer": "^3.0.0"
}
},
+ "react-qrcode-logo": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/react-qrcode-logo/-/react-qrcode-logo-2.8.0.tgz",
+ "integrity": "sha512-dbEgjsg6C4tK6+oGmCRDlJ7urQAWqybaGBLJtp8Z6ZYvVUP302HBXk/F7VRk54yWTwzlHwig3VK6HMKCha2YFw==",
+ "requires": {
+ "lodash.isequal": "^4.5.0",
+ "qrcode-generator": "^1.4.1"
+ }
+ },
"react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
diff --git a/package.json b/package.json
index a8a0fce..956d447 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.3",
+ "react-qrcode-logo": "^2.8.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"react-syntax-highlighter": "^15.5.0",
diff --git a/src/components/Shell/QRCodeDialog.tsx b/src/components/Shell/QRCodeDialog.tsx
new file mode 100644
index 0000000..2fcb3c8
--- /dev/null
+++ b/src/components/Shell/QRCodeDialog.tsx
@@ -0,0 +1,61 @@
+import {
+ Button,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ IconButton,
+} from '@mui/material'
+import React from 'react'
+import CloseIcon from '@mui/icons-material/Close'
+import { QRCode } from 'react-qrcode-logo'
+
+const QR_CODE_SIZE = 256
+const QR_IMAGE_OPACITY = 0.3
+
+export interface QRCodeDialogProps {
+ isOpen: boolean
+ handleClose: () => void
+}
+
+export function QRCodeDialog({ isOpen, handleClose }: QRCodeDialogProps) {
+ const url = window.location.href
+ return (
+
+ )
+}
diff --git a/src/components/Shell/Shell.tsx b/src/components/Shell/Shell.tsx
index 6d667a0..be2a3a7 100644
--- a/src/components/Shell/Shell.tsx
+++ b/src/components/Shell/Shell.tsx
@@ -24,6 +24,7 @@ import { ShellAppBar } from './ShellAppBar'
import { NotificationArea } from './NotificationArea'
import { RouteContent } from './RouteContent'
import { PeerList } from './PeerList'
+import { QRCodeDialog } from './QRCodeDialog'
export interface ShellProps extends PropsWithChildren {
userPeerId: string
@@ -34,6 +35,7 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
const settingsContext = useContext(SettingsContext)
const [isAlertShowing, setIsAlertShowing] = useState(false)
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
+ const [isQRCodeDialogOpen, setIsQRCodeDialogOpen] = useState(false)
const [doShowPeers, setDoShowPeers] = useState(false)
const [alertSeverity, setAlertSeverity] = useState('info')
const [title, setTitle] = useState('')
@@ -61,6 +63,7 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
setTitle,
showAlert,
isPeerListOpen,
+ setIsQRCodeDialogOpen,
setIsPeerListOpen,
peerList,
setPeerList,
@@ -69,6 +72,7 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
}),
[
isPeerListOpen,
+ setIsQRCodeDialogOpen,
numberOfPeers,
peerList,
tabHasFocus,
@@ -159,6 +163,10 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
setIsDrawerOpen(false)
}
+ const handleQRCodeDialogClose = () => {
+ setIsQRCodeDialogOpen(false)
+ }
+
return (
@@ -186,6 +194,7 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
numberOfPeers={numberOfPeers}
title={title}
onPeerListClick={handlePeerListClick}
+ setIsQRCodeDialogOpen={setIsQRCodeDialogOpen}
/>
{
peerList={peerList}
audioState={audioState}
/>
+
diff --git a/src/components/Shell/ShellAppBar.tsx b/src/components/Shell/ShellAppBar.tsx
index 7c5ff10..cacd9b4 100644
--- a/src/components/Shell/ShellAppBar.tsx
+++ b/src/components/Shell/ShellAppBar.tsx
@@ -7,6 +7,7 @@ import Tooltip from '@mui/material/Tooltip'
import IconButton from '@mui/material/IconButton'
import MenuIcon from '@mui/icons-material/Menu'
import LinkIcon from '@mui/icons-material/Link'
+import QrCode2Icon from '@mui/icons-material/QrCode2'
import { drawerWidth } from './Drawer'
import { peerListWidth } from './PeerList'
@@ -51,6 +52,7 @@ interface ShellAppBarProps {
numberOfPeers: number
title: string
onPeerListClick: () => void
+ setIsQRCodeDialogOpen: (isOpen: boolean) => void
}
export const ShellAppBar = ({
@@ -59,10 +61,12 @@ export const ShellAppBar = ({
onLinkButtonClick,
isDrawerOpen,
isPeerListOpen,
+ setIsQRCodeDialogOpen,
numberOfPeers,
title,
onPeerListClick,
}: ShellAppBarProps) => {
+ const handleQRCodeClick = () => setIsQRCodeDialogOpen(true)
return (
{title}
-
-
-
-
-
{doShowPeers ? (
-
-
-
-
-
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
) : null}