diff options
author | Anton Tananaev <anton@traccar.org> | 2023-11-25 14:19:35 -0800 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2023-11-25 14:19:41 -0800 |
commit | 4a7ab9a9b45a43b285e5d649d8f25e821f376ac3 (patch) | |
tree | 98fbb592e56f404de9adb6b070c55531da0f3617 /modern/src/common/components | |
parent | a1dce943fc3f7075b5d2fd887cb9b2f30402f73e (diff) | |
download | trackermap-web-4a7ab9a9b45a43b285e5d649d8f25e821f376ac3.tar.gz trackermap-web-4a7ab9a9b45a43b285e5d649d8f25e821f376ac3.tar.bz2 trackermap-web-4a7ab9a9b45a43b285e5d649d8f25e821f376ac3.zip |
Add device sharing (fix #1118)
Diffstat (limited to 'modern/src/common/components')
-rw-r--r-- | modern/src/common/components/StatusCard.jsx | 20 |
1 files changed, 20 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')} /> </> ); }; |