diff options
author | Anton Tananaev <anton@traccar.org> | 2022-06-26 17:03:00 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-06-26 17:03:00 -0700 |
commit | 6721b7c6c70152fe5c6b19ab38b7a9b9c8357a25 (patch) | |
tree | 65acac4723e8ccd85515c183830e0a79aea7a009 | |
parent | 19bedcceffbb3bbb83ae04f9e88d5d6d9a35a155 (diff) | |
download | trackermap-web-6721b7c6c70152fe5c6b19ab38b7a9b9c8357a25.tar.gz trackermap-web-6721b7c6c70152fe5c6b19ab38b7a9b9c8357a25.tar.bz2 trackermap-web-6721b7c6c70152fe5c6b19ab38b7a9b9c8357a25.zip |
Implement GPX import
-rw-r--r-- | modern/src/other/GeofencesPage.js | 52 | ||||
-rw-r--r-- | modern/src/other/ReplayPage.js | 10 |
2 files changed, 55 insertions, 7 deletions
diff --git a/modern/src/other/GeofencesPage.js b/modern/src/other/GeofencesPage.js index 4ecba888..8af8a711 100644 --- a/modern/src/other/GeofencesPage.js +++ b/modern/src/other/GeofencesPage.js @@ -1,4 +1,5 @@ import React from 'react'; +import { useDispatch } from 'react-redux'; import { Divider, Typography, IconButton, useMediaQuery, Toolbar, } from '@mui/material'; @@ -6,6 +7,7 @@ import makeStyles from '@mui/styles/makeStyles'; import { useTheme } from '@mui/material/styles'; import Drawer from '@mui/material/Drawer'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import UploadFileIcon from '@mui/icons-material/UploadFile'; import { useNavigate } from 'react-router-dom'; import MapView from '../map/core/MapView'; import MapCurrentLocation from '../map/MapCurrentLocation'; @@ -14,6 +16,7 @@ import GeofencesList from './GeofencesList'; import { useTranslation } from '../common/components/LocalizationProvider'; import dimensions from '../common/theme/dimensions'; import MapGeocoder from '../map/geocoder/MapGeocoder'; +import { errorsActions } from '../store'; const useStyles = makeStyles((theme) => ({ root: { @@ -42,16 +45,57 @@ const useStyles = makeStyles((theme) => ({ mapContainer: { flexGrow: 1, }, + title: { + flexGrow: 1, + }, + fileInput: { + display: 'none', + }, })); const GeofencesPage = () => { const theme = useTheme(); const classes = useStyles(); + const dispatch = useDispatch(); const navigate = useNavigate(); const t = useTranslation(); const isPhone = useMediaQuery(theme.breakpoints.down('sm')); + const handleFile = (event) => { + const files = Array.from(event.target.files); + const [file] = files; + const reader = new FileReader(); + reader.onload = async () => { + const xml = new DOMParser().parseFromString(reader.result, 'text/xml'); + const segment = xml.getElementsByTagName('trkseg')[0]; + const coordinates = Array.from(segment.getElementsByTagName('trkpt')) + .map((point) => `${point.getAttribute('lat')} ${point.getAttribute('lon')}`) + .join(', '); + const area = `LINESTRING (${coordinates})`; + const newItem = { name: '', area }; + try { + const response = await fetch('/api/geofences', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(newItem), + }); + if (response.ok) { + const item = await response.json(); + navigate(`/settings/geofence/${item.id}`); + } else { + throw Error(await response.text()); + } + } catch (error) { + dispatch(errorsActions.push(error.message)); + } + }; + reader.onerror = (event) => { + dispatch(errorsActions.push(event.target.error)); + }; + reader.readAsText(file); + }; + return ( <div className={classes.root}> <div className={classes.content}> @@ -64,7 +108,13 @@ const GeofencesPage = () => { <IconButton edge="start" sx={{ mr: 2 }} onClick={() => navigate(-1)}> <ArrowBackIcon /> </IconButton> - <Typography variant="h6">{t('sharedGeofences')}</Typography> + <Typography variant="h6" className={classes.title}>{t('sharedGeofences')}</Typography> + <label htmlFor="upload-gpx"> + <input accept=".gpx" id="upload-gpx" type="file" className={classes.fileInput} onChange={handleFile} /> + <IconButton edge="end" component="span" onClick={() => {}}> + <UploadFileIcon /> + </IconButton> + </label> </Toolbar> <Divider /> <GeofencesList /> diff --git a/modern/src/other/ReplayPage.js b/modern/src/other/ReplayPage.js index fdd78765..a233e8ce 100644 --- a/modern/src/other/ReplayPage.js +++ b/modern/src/other/ReplayPage.js @@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef, useCallback, } from 'react'; import { - Grid, IconButton, Paper, Slider, Toolbar, Tooltip, Typography, + IconButton, Paper, Slider, Toolbar, Tooltip, Typography, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; @@ -157,11 +157,9 @@ const ReplayPage = () => { </IconButton> <Typography variant="h6" className={classes.title}>{t('reportReplay')}</Typography> {!expanded && ( - <Grid item> - <IconButton onClick={() => setExpanded(true)}> - <SettingsIcon /> - </IconButton> - </Grid> + <IconButton edge="end" onClick={() => setExpanded(true)}> + <SettingsIcon /> + </IconButton> )} </Toolbar> </Paper> |