Adding a basic mechanism to choose overlays (not operational yet)
This commit is contained in:
parent
82e38308a4
commit
8ddbe1bdee
|
@ -5,22 +5,3 @@
|
|||
margin-left: calc(100% - 70px) !important;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
background-color: rgba(14, 116, 144, 0.7);
|
||||
color: white;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.close {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 20px;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import OSM from 'ol/source/OSM';
|
||||
import XYZ from 'ol/source/XYZ';
|
||||
import { Component, createSignal, For } from 'solid-js';
|
||||
import { Component, createEffect, createSignal, For, Show } from 'solid-js';
|
||||
import {
|
||||
I18nContext,
|
||||
createI18nContext,
|
||||
|
@ -11,14 +11,19 @@ import style from './MapTileProvider.module.css';
|
|||
import LayersIcon from '@suid/icons-material/Layers';
|
||||
import CloseIcon from '@suid/icons-material/Close';
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
} from '@suid/material';
|
||||
import { useNavigate, useParams } from '@solidjs/router';
|
||||
import Dialog from '../dialog';
|
||||
import Tree from '../tree';
|
||||
import { createCachedSignal } from '../../workers/cached-signals';
|
||||
import dispatch from '../../workers/dispatcher-main';
|
||||
import getUri from '../../lib/ids';
|
||||
|
||||
const id = getUri('overlays', undefined);
|
||||
|
||||
interface TileProvider {
|
||||
name: string;
|
||||
|
@ -93,6 +98,91 @@ export const mapTileProviders: TileProviders = {
|
|||
},
|
||||
};
|
||||
|
||||
type FeatureSubTypes = Array<string> | '*';
|
||||
type FeatureTypes = Record<string, FeatureSubTypes>;
|
||||
type Overlay = {
|
||||
selected: boolean;
|
||||
highlighted: FeatureTypes;
|
||||
hidden: FeatureTypes;
|
||||
};
|
||||
type Overlays = Record<string, Overlay>;
|
||||
|
||||
const defaultOverlays: Overlays = {
|
||||
none: { selected: true, highlighted: { none: [] }, hidden: {} },
|
||||
hiking: {
|
||||
selected: false,
|
||||
highlighted: {
|
||||
none: [],
|
||||
},
|
||||
hidden: { none: [] },
|
||||
},
|
||||
};
|
||||
|
||||
type OverlayDefinition = Record<string, FeatureTypes>;
|
||||
type OverlayDefinitions = Record<string, OverlayDefinition>;
|
||||
|
||||
export const overlayDefinitions: OverlayDefinitions = {
|
||||
none: {},
|
||||
hiking: {
|
||||
none: {},
|
||||
sleeping: {
|
||||
tourism: '*',
|
||||
},
|
||||
drinking: {
|
||||
amenity: ['bar', 'cafe', 'pub', 'drinking_water', 'water_point'],
|
||||
},
|
||||
eating: {
|
||||
amenity: ['fast_food', 'pub', 'restaurant'],
|
||||
shop: [
|
||||
'bakery',
|
||||
'butcher',
|
||||
'cheese',
|
||||
'chocolate',
|
||||
'convenience',
|
||||
'dairy',
|
||||
'farm',
|
||||
'greengrocer',
|
||||
'health_food',
|
||||
'pastry',
|
||||
'seafood',
|
||||
'department_store',
|
||||
'supermarket',
|
||||
],
|
||||
},
|
||||
health: {
|
||||
amenity: ['doctors', 'hospital', 'pharmacy'],
|
||||
},
|
||||
security: {
|
||||
amenity: ['police', 'fire_station'],
|
||||
},
|
||||
dayToDay: {
|
||||
amenity: ['waste_basket', 'waste_disposal'],
|
||||
shop: ['laundry'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const getOverlays = createCachedSignal({
|
||||
id,
|
||||
method: 'getOverlays',
|
||||
defaultOverlays,
|
||||
}) as () => Overlays;
|
||||
|
||||
const currentOverlayKey = () =>
|
||||
getOverlays()
|
||||
? Object.keys(getOverlays()).filter((key) => getOverlays()[key].selected)[0]
|
||||
: 'none';
|
||||
|
||||
const currentOverlay = () =>
|
||||
getOverlays() ? getOverlays()[currentOverlayKey()] : {};
|
||||
|
||||
const currentOverlayDefinition = () => overlayDefinitions[currentOverlayKey()];
|
||||
|
||||
const currentOverlayHighlightedKey = () =>
|
||||
currentOverlay() && currentOverlay().highlighted
|
||||
? Object.keys(currentOverlay().highlighted)[0]
|
||||
: 'none';
|
||||
|
||||
const MapTilesProvider: Component<{}> = (props) => {
|
||||
const [open, setOpen] = createSignal(false);
|
||||
|
||||
|
@ -116,6 +206,50 @@ const MapTilesProvider: Component<{}> = (props) => {
|
|||
setOpen(false);
|
||||
};
|
||||
|
||||
createEffect(() => {
|
||||
console.log({
|
||||
caller: 'MapTilesProvider',
|
||||
overlays: getOverlays(),
|
||||
currentOverlayKey: currentOverlayKey(),
|
||||
currentOverlay: currentOverlay(),
|
||||
currentOverlayDefinition: currentOverlayDefinition(),
|
||||
currentOverlayHighlightedKey: currentOverlayHighlightedKey(),
|
||||
});
|
||||
});
|
||||
|
||||
const handleOverlayChange = (ev: any) => {
|
||||
const value = ev.target.value;
|
||||
console.log({
|
||||
caller: 'MapTilesProvider / handleOverlayChange',
|
||||
ev,
|
||||
value,
|
||||
});
|
||||
const newOverlays = getOverlays();
|
||||
Object.keys(newOverlays).forEach((key) => {
|
||||
newOverlays[key].selected = key === value;
|
||||
});
|
||||
dispatch({
|
||||
action: 'putOverlays',
|
||||
params: { id, overlays: newOverlays },
|
||||
});
|
||||
};
|
||||
|
||||
const handleOverlayHighlightChange = (ev: any) => {
|
||||
const value = ev.target.value;
|
||||
console.log({
|
||||
caller: 'MapTilesProvider / handleOverlayHighlightChange',
|
||||
ev,
|
||||
value,
|
||||
});
|
||||
const newOverlays = getOverlays();
|
||||
newOverlays[currentOverlayKey()].highlighted = {};
|
||||
newOverlays[currentOverlayKey()].highlighted[value] = [];
|
||||
dispatch({
|
||||
action: 'putOverlays',
|
||||
params: { id, overlays: newOverlays },
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class={style.control}>
|
||||
|
@ -123,28 +257,66 @@ const MapTilesProvider: Component<{}> = (props) => {
|
|||
<LayersIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
<Dialog onClose={handleClose} open={open()} class={style.dialog}>
|
||||
<DialogTitle class={style.title}>
|
||||
<div class={style['title-text']}>{t('chooseYourMap')}</div>
|
||||
<IconButton onClick={handleClose} class={style.close}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</DialogTitle>
|
||||
<RadioGroup
|
||||
defaultValue={params.provider}
|
||||
class={style.body}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<For each={Object.keys(mapTileProviders)}>
|
||||
{(p: string) => (
|
||||
<FormControlLabel
|
||||
value={p}
|
||||
control={<Radio />}
|
||||
label={mapTileProviders[p].name}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</RadioGroup>
|
||||
<Dialog
|
||||
closeHandler={handleClose}
|
||||
open={open()}
|
||||
title={t('chooseYourMap')}
|
||||
>
|
||||
<Tree
|
||||
title={t('overlay')}
|
||||
content={
|
||||
<>
|
||||
<RadioGroup
|
||||
defaultValue={currentOverlayKey()}
|
||||
onChange={handleOverlayChange}
|
||||
>
|
||||
<For each={Object.keys(overlayDefinitions)}>
|
||||
{(p: string) => (
|
||||
<FormControlLabel value={p} control={<Radio />} label={p} />
|
||||
)}
|
||||
</For>
|
||||
</RadioGroup>
|
||||
<Show when={Object.keys(currentOverlayDefinition()).length > 0}>
|
||||
{' '}
|
||||
<div>---</div>
|
||||
<div>Highlight</div>
|
||||
<RadioGroup
|
||||
defaultValue={currentOverlayHighlightedKey()}
|
||||
onChange={handleOverlayHighlightChange}
|
||||
>
|
||||
<For each={Object.keys(currentOverlayDefinition())}>
|
||||
{(p: string) => (
|
||||
<FormControlLabel
|
||||
value={p}
|
||||
control={<Radio />}
|
||||
label={p}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</RadioGroup>
|
||||
</Show>
|
||||
</>
|
||||
}
|
||||
subTree={undefined}
|
||||
></Tree>
|
||||
|
||||
<Tree
|
||||
title={t('baseLayer')}
|
||||
content={
|
||||
<RadioGroup defaultValue={params.provider} onChange={handleChange}>
|
||||
<For each={Object.keys(mapTileProviders)}>
|
||||
{(p: string) => (
|
||||
<FormControlLabel
|
||||
value={p}
|
||||
control={<Radio />}
|
||||
label={mapTileProviders[p].name}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</RadioGroup>
|
||||
}
|
||||
subTree={undefined}
|
||||
></Tree>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -3,6 +3,7 @@ import { getWpt } from '../db/wpt';
|
|||
import { returnAgain } from '../workers/dispatcher-worker';
|
||||
import { getAllGpxes, getGpx } from './gpx';
|
||||
import { put } from './lib';
|
||||
import { getOverlays } from './overlays';
|
||||
import { getRte } from './rte';
|
||||
import { getTrk } from './trk';
|
||||
import { getTrkseg } from './trkseg';
|
||||
|
@ -18,6 +19,7 @@ const methods = {
|
|||
getTrkseg,
|
||||
getWpt,
|
||||
getRte,
|
||||
getOverlays,
|
||||
};
|
||||
|
||||
const sendUpdate = async (params: any) => {
|
||||
|
@ -79,7 +81,9 @@ const changeHandler = async (change: any) => {
|
|||
}
|
||||
|
||||
const parentParams = globalThis.watches.get(parentId);
|
||||
debouncedSendUpdates[parentParams.method](parentParams);
|
||||
if (parentParams) {
|
||||
debouncedSendUpdates[parentParams.method](parentParams);
|
||||
}
|
||||
};
|
||||
|
||||
export default changeHandler;
|
||||
|
|
|
@ -136,6 +136,16 @@ export const initDb = async (params: any) => {
|
|||
console.log({ caller: 'changes / complete', error });
|
||||
});
|
||||
|
||||
const localDbChanges = localDb
|
||||
.changes({ since: 'now', live: true, include_docs: false })
|
||||
.on('change', changeHandler)
|
||||
.on('complete', (info: any) => {
|
||||
console.log({ caller: 'localDb changes / complete', info });
|
||||
})
|
||||
.on('error', (error: any) => {
|
||||
console.log({ caller: 'localDb changes / complete', error });
|
||||
});
|
||||
|
||||
// console.log({ caller: 'initDb / back from db.changes', changes });
|
||||
|
||||
// changes.cancel();
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { get, put } from './lib';
|
||||
|
||||
export const getOverlays = async (params: any) => {
|
||||
const { id, defaultOverlays } = params;
|
||||
try {
|
||||
const overlays = await get(id, true);
|
||||
return overlays.doc;
|
||||
} catch (error: any) {
|
||||
console.error({ caller: 'getOverlays', error });
|
||||
return defaultOverlays;
|
||||
}
|
||||
};
|
||||
|
||||
export const putOverlays = async (params: any) => {
|
||||
const { id, overlays } = params;
|
||||
await put(id, 'overlays', (doc) => overlays, {}, true);
|
||||
return overlays;
|
||||
};
|
|
@ -2,6 +2,9 @@ const dict = {
|
|||
close: 'close',
|
||||
|
||||
chooseYourMap: 'Choose your map',
|
||||
baseLayer: 'Base layer',
|
||||
overlay: 'Overlay',
|
||||
hiking: 'Hiking',
|
||||
|
||||
nearby: 'Nearby',
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ const dict = {
|
|||
close: 'quitter',
|
||||
|
||||
chooseYourMap: 'Choisissez votre carte',
|
||||
baseLayer: 'Fond de carte',
|
||||
overlay: 'Sur couche',
|
||||
hiking: 'Randonnée',
|
||||
|
||||
nearby: 'À proximité',
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ const coding = {
|
|||
const routes = {
|
||||
dbdef: route('dbdef', coding),
|
||||
state: route('state', coding),
|
||||
overlays: route('overlays', coding),
|
||||
account: route('account/:account', coding),
|
||||
settings: route('settings', coding),
|
||||
gpx: route('gpx/:gpx', coding),
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
getAllGpxes,
|
||||
getAllGpxesWithSummary,
|
||||
} from '../db/gpx';
|
||||
import { putOverlays } from '../db/overlays';
|
||||
import { putRte } from '../db/rte';
|
||||
import { putRtept } from '../db/rtept';
|
||||
import { getSettings, putSettings } from '../db/settings';
|
||||
|
@ -59,6 +60,8 @@ onmessage = async function (e) {
|
|||
getState,
|
||||
setState,
|
||||
|
||||
putOverlays,
|
||||
|
||||
getAndWatch,
|
||||
cancelWatch,
|
||||
|
||||
|
|
Loading…
Reference in New Issue