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();
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);
@ -200,10 +208,12 @@ export default defineComponent({
onMounted(() => {
window.addEventListener('resize', onResize);
window.addEventListener('keydown', onKeydown);
window.addEventListener('hashchange', onUrlChange);
});
onUnmounted(() => {
window.addEventListener('resize', onResize);
window.addEventListener('keydown', onKeydown);
window.addEventListener('hashchange', onUrlChange);
});
return {

View File

@ -86,6 +86,7 @@ export default defineComponent({
followTarget = computed(() => store.state.followTarget),
panTarget = computed(() => store.state.panTarget),
parsedUrl = computed(() => store.state.parsedUrl),
//Location and zoom to pan to upon next projection change
scheduledPan = ref<Coordinate|null>(null),
@ -108,6 +109,7 @@ export default defineComponent({
logoControls,
followTarget,
panTarget,
parsedUrl,
mapBackground,
currentWorld,
@ -167,30 +169,69 @@ export default defineComponent({
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) {
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.
} else if(store.state.panTarget && store.state.panTarget.location.world === newValue.name) {
store.commit(MutationTypes.CLEAR_PAN_TARGET, undefined);
return;
//Otherwise pan to url location, if present and if we have just loaded
} else if(!oldValue && store.state.parsedUrl.location) {
// Otherwise pan to url location, if present
} else if(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 {
location = newValue.center;
}
if(!oldValue) {
this.scheduledZoom = typeof store.state.parsedUrl.zoom !== 'undefined' ?
store.state.parsedUrl.zoom : store.state.configuration.defaultZoom;
this.scheduledZoom = store.state.parsedUrl?.zoom || store.state.configuration.defaultZoom;
}
//Set pan location for when the projection changes
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
if(state.parsedUrl.world && state.worlds.has(state.parsedUrl.world)) {
if(state.parsedUrl?.world && state.worlds.has(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
if(state.parsedUrl.map && world.maps.has(state.parsedUrl.map)) {
if(state.parsedUrl?.map && world.maps.has(state.parsedUrl.map)) {
mapName = state.parsedUrl.map;
}

View File

@ -507,13 +507,7 @@ export const mutations: MutationTree<State> & Mutations = {
//Clear any existing parsed url
[MutationTypes.CLEAR_PARSED_URL](state: State) {
state.parsedUrl = {
world: undefined,
map: undefined,
location: undefined,
zoom: undefined,
legacy: false,
};
state.parsedUrl = undefined;
},
//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 = {
@ -228,13 +228,5 @@ export const state: State = {
sidebar: {
collapsedSections: new Set(),
},
},
parsedUrl: {
world: undefined,
map: undefined,
location: undefined,
zoom: undefined,
legacy: false,
}
};