-
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
667 additions
and
110 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
src/renderer/components/BackgroundMaps/BackgroundMapInfo.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// @ts-check | ||
import { Button, Fade, makeStyles, Paper, Typography } from '@material-ui/core' | ||
import * as React from 'react' | ||
import { defineMessages, useIntl } from 'react-intl' | ||
import DeleteIcon from '@material-ui/icons/DeleteForeverOutlined' | ||
|
||
import Loading from '../Loading' | ||
import { useMapServerQuery } from '../../hooks/useMapServerQuery' | ||
import { MapboxPrevOnly } from './MapCard' | ||
import { convertKbToMb } from '../SettingsView/BackgroundMaps' | ||
|
||
const m = defineMessages({ | ||
// Title for Offline Areas | ||
offlineAreas: 'Offline Areas', | ||
// Button to create an offline area | ||
createOfflineArea: 'Create Offline Area', | ||
// Button to delete style | ||
deleteStyle: 'Delete Style', | ||
// Title for error message when deleting style | ||
deleteErrorTitle: 'Error Deleting Style', | ||
// Description for error message when deleting style, | ||
deleteErrorDescription: 'There was an error deleting the style', | ||
// Zoom Level Title | ||
zoomLevel: 'Zoom Level: {zoom}', | ||
// abbreviation for megabyte | ||
mb: 'MB', | ||
}) | ||
|
||
/** | ||
* @typedef BackgroundMapInfoProps | ||
* @prop {string} id | ||
* @prop {string} url | ||
* @prop {number} size | ||
* @prop {()=>void} unsetMapValue | ||
*/ | ||
|
||
/** @param {BackgroundMapInfoProps} props */ | ||
export const BackgroundMapInfo = ({ id, unsetMapValue, url, size }) => { | ||
const { formatMessage: t } = useIntl() | ||
|
||
const { data } = useMapServerQuery(`/styles/${id}`) | ||
|
||
return ( | ||
<Fade in timeout={0}> | ||
<Paper | ||
style={{ | ||
flex: 1, | ||
width: '100%', | ||
height: '100%', | ||
padding: !data ? 40 : 0, | ||
}} | ||
> | ||
{!data ? ( | ||
<Loading /> | ||
) : ( | ||
<React.Fragment> | ||
<MapInfo name={data.name} id={id} unsetMapValue={unsetMapValue} url={url} /> | ||
{/* Text */} | ||
<div style={{ padding: 20 }}> | ||
<Typography variant='subtitle2' style={{ fontSize: 18 }}> | ||
{data.name} | ||
</Typography> | ||
{data.zoom && <Typography variant='body1'>{t(m.zoomLevel, { zoom: data.zoom })}</Typography>} | ||
<Typography variant='body1'>{`${Math.round(convertKbToMb(size))} ${t(m.mb)}`}</Typography> | ||
</div> | ||
</React.Fragment> | ||
)} | ||
</Paper> | ||
</Fade> | ||
) | ||
} | ||
|
||
/** | ||
* @typedef MapInfoProps | ||
* @prop {string|undefined} name | ||
* @prop {string} id | ||
* @prop {()=>void} unsetMapValue | ||
* @prop {string} url | ||
*/ | ||
|
||
/** @param {MapInfoProps} props */ | ||
const MapInfo = ({ name, id, unsetMapValue, url }) => { | ||
const classes = useStyles() | ||
|
||
const { formatMessage: t } = useIntl() | ||
|
||
/** | ||
* | ||
* @param {string} mapId | ||
*/ | ||
|
||
// To Do, useMapServerMutation.mutate() | ||
function deleteMap (mapId) {} | ||
|
||
return ( | ||
<React.Fragment> | ||
{/* Banner */} | ||
<Paper className={classes.banner}> | ||
<Typography variant='h5'>{name}</Typography> | ||
|
||
<div> | ||
<Button variant='outlined' onClick={() => deleteMap(id)}> | ||
<DeleteIcon /> | ||
<Typography style={{ textTransform: 'none' }} variant='subtitle2'> | ||
{t(m.deleteStyle)} | ||
</Typography> | ||
</Button> | ||
</div> | ||
</Paper> | ||
|
||
{/* Map */} | ||
<MapboxPrevOnly style={url} containerStyle={{ height: '60%', width: '100%' }} zoom={[0]} /> | ||
</React.Fragment> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles({ | ||
buttonContainer: { | ||
display: 'flex', | ||
justifyContent: 'space-between', | ||
alignItems: 'center', | ||
}, | ||
banner: { | ||
width: '100%', | ||
display: 'flex', | ||
justifyContent: 'space-between', | ||
padding: '10px 20px', | ||
}, | ||
textBanner: { | ||
display: 'flex', | ||
justifyContent: 'space-evenly', | ||
}, | ||
offlineCardContainer: { | ||
display: 'flex', | ||
flexWrap: 'wrap', | ||
justifyContent: 'space-evenly', | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// @ts-check | ||
import * as React from 'react' | ||
import Button from '@material-ui/core/Button' | ||
import { makeStyles, Typography } from '@material-ui/core' | ||
import { useIntl, defineMessages } from 'react-intl' | ||
import ReactMapboxGl from 'react-mapbox-gl' | ||
|
||
import { MAPBOX_ACCESS_TOKEN } from '../../../../config' | ||
import { convertKbToMb } from '../SettingsView/BackgroundMaps' | ||
|
||
const m = defineMessages({ | ||
// Abbreviation for megabytes | ||
mb: 'MB', | ||
// indicates how many offline areas | ||
areas: 'offline areas', | ||
}) | ||
|
||
export const MapboxPrevOnly = ReactMapboxGl({ | ||
accessToken: MAPBOX_ACCESS_TOKEN, | ||
dragRotate: false, | ||
pitchWithRotate: false, | ||
attributionControl: false, | ||
injectCSS: false, | ||
}) | ||
|
||
/** | ||
* @typedef MapCardProps | ||
* @prop {import('../Settings/BackgroundMaps').MapServerStyleInfo} offlineMap | ||
* @prop {React.Dispatch<React.SetStateAction<import('../Settings/BackgroundMaps').MapServerStyleInfo['id'] | false>>} setMap | ||
* @prop {boolean } isBeingViewed | ||
*/ | ||
|
||
/** @param {MapCardProps} param */ | ||
export const MapCard = ({ offlineMap, setMap, isBeingViewed }) => { | ||
const classes = useStyles() | ||
const { formatMessage: t } = useIntl() | ||
|
||
return ( | ||
<Button variant='outlined' className={classes.root} onClick={() => setMap(offlineMap.id)}> | ||
<div className={classes.inner} style={{ backgroundColor: !isBeingViewed ? '#CCCCD6' : '#0066FF' }}> | ||
<div style={{ width: '30%' }}> | ||
<MapboxPrevOnly | ||
containerStyle={{ | ||
height: '100%', | ||
width: '100%', | ||
}} | ||
style={offlineMap.url} | ||
zoom={[0]} | ||
/> | ||
</div> | ||
<div className={classes.text}> | ||
<Typography>{offlineMap.name}</Typography> | ||
<Typography variant='subtitle1'> | ||
{`${Math.round(convertKbToMb(offlineMap.bytesStored))} ${t(m.mb)}`} | ||
</Typography> | ||
</div> | ||
</div> | ||
</Button> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles({ | ||
root: { | ||
height: 90, | ||
width: '90%', | ||
marginBottom: 20, | ||
textTransform: 'none', | ||
padding: 0, | ||
'& .MuiButton-root': { | ||
padding: 0, | ||
}, | ||
'& .MuiButton-outlined': { | ||
padding: 0, | ||
}, | ||
'& .MuiButton-label': { | ||
height: '100%', | ||
}, | ||
}, | ||
inner: { | ||
display: 'flex', | ||
flex: 1, | ||
height: '100%', | ||
}, | ||
text: { | ||
alignItems: 'flex-start', | ||
display: 'flex', | ||
flexDirection: 'column', | ||
justifyContent: 'center', | ||
flex: 1, | ||
height: '100%', | ||
marginLeft: 10, | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// @ts-check | ||
import { Button, makeStyles } from '@material-ui/core' | ||
import ChevronLeft from '@material-ui/icons/ChevronLeft' | ||
import * as React from 'react' | ||
import { defineMessages, useIntl } from 'react-intl' | ||
import { useMapServerQuery } from '../../hooks/useMapServerQuery' | ||
import { ImportMapStyleDialog } from '../dialogs/ImportMapStyle' | ||
import Loader from '../Loader' | ||
import { MapCard } from './MapCard' | ||
|
||
const m = defineMessages({ | ||
// Button to add map background | ||
addMap: 'Add Map Background', | ||
// Button to create an offline area for a map backgroun | ||
createOfflineMap: 'Create Offline Map', | ||
// button to go back to settings | ||
backToSettings: 'Back to Settings', | ||
}) | ||
/** | ||
* @typedef SidePanelProps | ||
* @prop {()=>void} openSettings | ||
* @prop {string|false} mapValue | ||
* @prop {React.Dispatch<React.SetStateAction<string | false>>} setMapValue | ||
*/ | ||
|
||
/** @param {SidePanelProps} param */ | ||
export const SidePanel = ({ openSettings, mapValue, setMapValue }) => { | ||
const { formatMessage: t } = useIntl() | ||
|
||
const classes = useStyles() | ||
const [open, setOpen] = React.useState(false) | ||
|
||
const { data, isLoading } = useMapServerQuery('/styles', true) | ||
|
||
return ( | ||
<React.Fragment> | ||
<div className={classes.sidePanel}> | ||
<Button onClick={openSettings} className={classes.backHeader}> | ||
<ChevronLeft /> | ||
{t(m.backToSettings)} | ||
</Button> | ||
<div className={classes.buttonContainer}> | ||
<Button | ||
onClick={() => setOpen(true)} | ||
className={`${classes.button} ${classes.firstButton}`} | ||
variant='outlined' | ||
> | ||
{t(m.addMap)} | ||
</Button> | ||
</div> | ||
|
||
{isLoading ? ( | ||
<Loader /> | ||
) : data ? ( | ||
data.map(offlineMap => ( | ||
<MapCard | ||
setMap={setMapValue} | ||
key={offlineMap.id} | ||
offlineMap={offlineMap} | ||
isBeingViewed={offlineMap.id === mapValue} | ||
/> | ||
)) | ||
) : null} | ||
</div> | ||
<ImportMapStyleDialog open={open} close={() => setOpen(false)} /> | ||
</React.Fragment> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles({ | ||
sidePanel: { | ||
width: 'auto', | ||
borderRight: '1px solid #E0E0E0', | ||
height: '100%', | ||
display: 'flex', | ||
flexDirection: 'column', | ||
alignItems: 'center', | ||
minWidth: '35%', | ||
}, | ||
buttonContainer: { | ||
display: 'flex', | ||
justifyContent: 'space-between', | ||
padding: 20, | ||
}, | ||
button: { | ||
textTransform: 'none', | ||
fontSize: 12, | ||
}, | ||
firstButton: { | ||
marginRight: 10, | ||
}, | ||
backHeader: { | ||
justifyContent: 'flex-start', | ||
alignSelf: 'flex-start', | ||
paddingLeft: 20, | ||
paddingTop: 20, | ||
paddingBottom: 20, | ||
width: '100%', | ||
display: 'flex', | ||
textTransform: 'none', | ||
'& :first-child': { | ||
marginRight: 20, | ||
}, | ||
}, | ||
}) |
Oops, something went wrong.