Update map, pan and zoom if the url is edited manually

This commit is contained in:
James Lyne 2021-07-20 03:25:42 +01:00
parent 9bea4519c6
commit 92a854701a
5 changed files with 62 additions and 25 deletions

View File

@ -160,6 +160,14 @@ export default defineComponent({
e.preventDefault(); e.preventDefault();
store.commit(MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY, element); store.commit(MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY, element);
},
onUrlChange = () => {
const parsedUrl = parseUrl();
if(parsedUrl) {
store.commit(MutationTypes.SET_PARSED_URL, parsedUrl);
}
}; };
watch(title, (title) => document.title = title); watch(title, (title) => document.title = title);
@ -200,10 +208,12 @@ export default defineComponent({
onMounted(() => { onMounted(() => {
window.addEventListener('resize', onResize); window.addEventListener('resize', onResize);
window.addEventListener('keydown', onKeydown); window.addEventListener('keydown', onKeydown);
window.addEventListener('hashchange', onUrlChange);
}); });
onUnmounted(() => { onUnmounted(() => {
window.addEventListener('resize', onResize); window.addEventListener('resize', onResize);
window.addEventListener('keydown', onKeydown); window.addEventListener('keydown', onKeydown);
window.addEventListener('hashchange', onUrlChange);
}); });
return { return {

View File

@ -86,6 +86,7 @@ export default defineComponent({
followTarget = computed(() => store.state.followTarget), followTarget = computed(() => store.state.followTarget),
panTarget = computed(() => store.state.panTarget), panTarget = computed(() => store.state.panTarget),
parsedUrl = computed(() => store.state.parsedUrl),
//Location and zoom to pan to upon next projection change //Location and zoom to pan to upon next projection change
scheduledPan = ref<Coordinate|null>(null), scheduledPan = ref<Coordinate|null>(null),
@ -108,6 +109,7 @@ export default defineComponent({
logoControls, logoControls,
followTarget, followTarget,
panTarget, panTarget,
parsedUrl,
mapBackground, mapBackground,
currentWorld, currentWorld,
@ -167,30 +169,69 @@ export default defineComponent({
store.dispatch(ActionTypes.GET_MARKER_SETS, undefined); store.dispatch(ActionTypes.GET_MARKER_SETS, undefined);
//Abort if follow target is present, to avoid panning twice // Abort if follow target is present, to avoid panning twice
if(store.state.followTarget && store.state.followTarget.location.world === newValue.name) { if(store.state.followTarget && store.state.followTarget.location.world === newValue.name) {
return; return;
//Abort if pan target is present, to avoid panning to the wrong place. // Abort if pan target is present, to avoid panning to the wrong place.
// Also clear it to allow repeated panning. // Also clear it to allow repeated panning.
} else if(store.state.panTarget && store.state.panTarget.location.world === newValue.name) { } else if(store.state.panTarget && store.state.panTarget.location.world === newValue.name) {
store.commit(MutationTypes.CLEAR_PAN_TARGET, undefined); store.commit(MutationTypes.CLEAR_PAN_TARGET, undefined);
return; return;
//Otherwise pan to url location, if present and if we have just loaded // Otherwise pan to url location, if present
} else if(!oldValue && store.state.parsedUrl.location) { } else if(store.state.parsedUrl?.location) {
location = store.state.parsedUrl.location; location = store.state.parsedUrl.location;
//Otherwise pan to world center store.commit(MutationTypes.CLEAR_PARSED_URL, undefined);
// Otherwise pan to world center
} else { } else {
location = newValue.center; location = newValue.center;
} }
if(!oldValue) { if(!oldValue) {
this.scheduledZoom = typeof store.state.parsedUrl.zoom !== 'undefined' ? this.scheduledZoom = store.state.parsedUrl?.zoom || store.state.configuration.defaultZoom;
store.state.parsedUrl.zoom : store.state.configuration.defaultZoom;
} }
//Set pan location for when the projection changes //Set pan location for when the projection changes
this.scheduledPan = location; this.scheduledPan = location;
} }
},
parsedUrl: {
handler(newValue) {
if(!newValue || !this.currentWorld || !this.leaflet) {
return;
}
//URL points to different map
if(newValue.world !== this.currentWorld.name || newValue.map !== this.currentMap!.name) {
//Set scheduled pan for after map change
this.scheduledPan = newValue.location;
this.scheduledZoom = newValue.zoom;
try {
useStore().commit(MutationTypes.SET_CURRENT_MAP, {
worldName: newValue.world,
mapName: newValue.map
});
} catch(e) {
//Clear scheduled pan if change fails
console.warn(`Failed to handle URL change`, e);
this.scheduledPan = null;
this.scheduledZoom = null;
}
} else { //Same map, just pan
this.scheduledPan = null;
this.scheduledZoom = null;
this.leaflet.setZoom(newValue.zoom, {
animate: false,
});
this.leaflet.panTo(this.currentProjection.locationToLatLng(newValue.location), {
animate: false,
noMoveStart: true,
});
}
},
deep: true,
} }
}, },

View File

@ -109,7 +109,7 @@ export const actions: ActionTree<State, State> & Actions = {
} }
// Prefer world from parsed url if present and it exists // Prefer world from parsed url if present and it exists
if(state.parsedUrl.world && state.worlds.has(state.parsedUrl.world)) { if(state.parsedUrl?.world && state.worlds.has(state.parsedUrl.world)) {
worldName = state.parsedUrl.world; worldName = state.parsedUrl.world;
} }
@ -127,7 +127,7 @@ export const actions: ActionTree<State, State> & Actions = {
} }
// Prefer map from parsed url if present and it exists // Prefer map from parsed url if present and it exists
if(state.parsedUrl.map && world.maps.has(state.parsedUrl.map)) { if(state.parsedUrl?.map && world.maps.has(state.parsedUrl.map)) {
mapName = state.parsedUrl.map; mapName = state.parsedUrl.map;
} }

View File

@ -507,13 +507,7 @@ export const mutations: MutationTree<State> & Mutations = {
//Clear any existing parsed url //Clear any existing parsed url
[MutationTypes.CLEAR_PARSED_URL](state: State) { [MutationTypes.CLEAR_PARSED_URL](state: State) {
state.parsedUrl = { state.parsedUrl = undefined;
world: undefined,
map: undefined,
location: undefined,
zoom: undefined,
legacy: false,
};
}, },
//Set the follow target, which the map will automatically pan to keep in view //Set the follow target, which the map will automatically pan to keep in view

View File

@ -78,7 +78,7 @@ export type State = {
} }
}; };
parsedUrl: LiveAtlasParsedUrl; parsedUrl?: LiveAtlasParsedUrl;
} }
export const state: State = { export const state: State = {
@ -228,13 +228,5 @@ export const state: State = {
sidebar: { sidebar: {
collapsedSections: new Set(), collapsedSections: new Set(),
}, },
},
parsedUrl: {
world: undefined,
map: undefined,
location: undefined,
zoom: undefined,
legacy: false,
} }
}; };