diff options
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/common/components/StatusCard.jsx | 20 | ||||
-rw-r--r-- | modern/src/resources/l10n/en.json | 2 |
2 files changed, 22 insertions, 0 deletions
diff --git a/modern/src/common/components/StatusCard.jsx b/modern/src/common/components/StatusCard.jsx index 04e1d172..2e936420 100644 --- a/modern/src/common/components/StatusCard.jsx +++ b/modern/src/common/components/StatusCard.jsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; +import dayjs from 'dayjs'; import Draggable from 'react-draggable'; import { Card, @@ -15,6 +16,7 @@ import { Menu, MenuItem, CardMedia, + Snackbar, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import CloseIcon from '@mui/icons-material/Close'; @@ -130,6 +132,7 @@ const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPaddin const [anchorEl, setAnchorEl] = useState(null); const [removing, setRemoving] = useState(false); + const [shared, setShared] = useState(false); const handleRemove = useCatch(async (removed) => { if (removed) { @@ -169,6 +172,21 @@ const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPaddin } }, [navigate, position]); + const handleShare = useCatchCallback(async () => { + const expiration = dayjs().add(1, 'week').toISOString(); + const response = await fetch('/api/devices/share', { + method: 'POST', + body: new URLSearchParams(`deviceId=${deviceId}&expiration=${expiration}`), + }); + if (response.ok) { + const token = await response.text(); + navigator.clipboard.writeText(`${window.location.origin}?token=${token}`); + setShared(true); + } else { + throw Error(await response.text()); + } + }, [deviceId, setShared]); + return ( <> <div className={classes.root}> @@ -270,6 +288,7 @@ const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPaddin <MenuItem component="a" target="_blank" href={`https://www.google.com/maps/search/?api=1&query=${position.latitude}%2C${position.longitude}`}>{t('linkGoogleMaps')}</MenuItem> <MenuItem component="a" target="_blank" href={`http://maps.apple.com/?ll=${position.latitude},${position.longitude}`}>{t('linkAppleMaps')}</MenuItem> <MenuItem component="a" target="_blank" href={`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${position.latitude}%2C${position.longitude}&heading=${position.course}`}>{t('linkStreetView')}</MenuItem> + <MenuItem onClick={handleShare}>{t('deviceShare')}</MenuItem> </Menu> )} <RemoveDialog @@ -278,6 +297,7 @@ const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPaddin itemId={deviceId} onResult={(removed) => handleRemove(removed)} /> + <Snackbar open={shared} onClose={() => setShared(false)} message={t('sharedLinkCopied')} /> </> ); }; diff --git a/modern/src/resources/l10n/en.json b/modern/src/resources/l10n/en.json index ccbfde6a..0f57b52a 100644 --- a/modern/src/resources/l10n/en.json +++ b/modern/src/resources/l10n/en.json @@ -99,6 +99,7 @@ "sharedImport": "Import", "sharedColumns": "Columns", "sharedDropzoneText": "Drag and drop a file here or click", + "sharedLinkCopied": "Link copied", "calendarSimple": "Simple", "calendarRecurrence": "Recurrence", "calendarOnce": "Once", @@ -206,6 +207,7 @@ "deviceStatusUnknown": "Unknown", "deviceRegisterFirst": "Register your first device", "deviceIdentifierHelp": "IMEI, serial number or other id. It has to match the identifier device reports to the server.", + "deviceShare": "Share Device", "groupDialog": "Group", "groupParent": "Group", "groupNoGroup": "No Group", |