Improve handing of append_to_world
- Always use the store map list for checking for/retrieving maps, to avoid the non-unique map name problem append_to_world otherwise causes - Change LiveAtlasWorldDefinition maps property to Set as map keys were not unique if appended maps with the same names existed - Add appended map to both original and appended world's map set. The appended world needs this to display the map in the UI, the original world needs this to avoid situations where LiveAtlas needs the "first" map of a world, and that world has 0 non-appended maps (i.e switching worlds when following, URL without a map name) - Add an appendedWorld property to maps to indicate when a map has been appended. This is used by MapContextMenu to show the appended world's map list instead, and in WorldListItem to filter out maps appended to other worlds - Use the map's world property instead of the world prop in the template for WorldListItem. This fixes tooltips and prevents duplicate IDs. Fixes #345
This commit is contained in:
parent
f7b774321b
commit
e91f820322
@ -296,9 +296,8 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
if(targetWorld && (targetWorld !== currentWorld) || (target.map && currentMap !== target.map)) {
|
||||
const mapName = target.map && targetWorld!.maps.has(target.map) ?
|
||||
targetWorld!.maps.get(target.map)!.name :
|
||||
targetWorld!.maps.entries().next().value[1].name;
|
||||
const map = store.state.maps.get(`${targetWorld.name}_${target.map}`),
|
||||
mapName = map ? map.name : targetWorld.maps.values().next().value.name;
|
||||
|
||||
this.scheduledView = target;
|
||||
|
||||
|
@ -15,14 +15,16 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="world">
|
||||
<div v-if="maps.length" class="world">
|
||||
<span class="world__name" aria-hidden="true">{{ world.displayName }}</span>
|
||||
<div class="world__maps menu">
|
||||
<template v-for="[key, map] in world.maps" :key="`${world.name}_${key}`">
|
||||
<input :id="`${name}-${world.name}-${key}`" type="radio" :name="name"
|
||||
v-bind:value="[world.name,map.name]" v-model="currentMap"
|
||||
:aria-labelledby="`${name}-${world.name}-${key}-label`">
|
||||
<label :id="`${name}-${world.name}-${key}-label`" class="map" :for="`${name}-${world.name}-${key}`" :title="`${world.displayName} - ${map.displayName}`">
|
||||
<template v-for="map in maps" :key="`${map.world.name}_${map.name}`">
|
||||
<input :id="`${name}-${map.world.name}-${map.name}`" type="radio" :name="name"
|
||||
v-bind:value="[map.world.name,map.name]" v-model="currentMap"
|
||||
:aria-labelledby="`${name}-${map.world.name}-${map.name}-label`">
|
||||
<label :id="`${name}-${map.world.name}-${map.name}-label`" class="map"
|
||||
:for="`${name}-${map.world.name}-${map.name}`"
|
||||
:title="`${map.world.displayName} - ${map.displayName}`">
|
||||
<img v-if="map.hasCustomIcon()" :src="map.getIcon()" alt="" />
|
||||
<SvgIcon v-else :name="map.getIcon()"></SvgIcon>
|
||||
</label>
|
||||
@ -48,6 +50,7 @@ import "@/assets/icons/block_other.svg";
|
||||
import "@/assets/icons/block_other_flat.svg";
|
||||
import "@/assets/icons/block_skylands.svg";
|
||||
import {LiveAtlasWorldDefinition} from "@/index";
|
||||
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorldListItem',
|
||||
@ -63,8 +66,21 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
setup() {
|
||||
setup(props) {
|
||||
const store = useStore(),
|
||||
maps = computed(() => {
|
||||
const maps: LiveAtlasMapDefinition[] = [];
|
||||
|
||||
//Filter out maps appended to other worlds
|
||||
props.world.maps.forEach(map => {
|
||||
console.log(map.appendedWorld, props.world);
|
||||
if(!map.appendedWorld || map.appendedWorld.name === props.world.name) {
|
||||
maps.push(map);
|
||||
}
|
||||
});
|
||||
|
||||
return maps;
|
||||
}),
|
||||
currentMap = computed({
|
||||
get: () => store.state.currentMap ? [store.state.currentWorld!.name, store.state.currentMap.name] : undefined,
|
||||
set: (value) => value && store.commit(MutationTypes.SET_CURRENT_MAP, {
|
||||
@ -74,7 +90,8 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
return {
|
||||
currentMap
|
||||
currentMap,
|
||||
maps
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -35,7 +35,7 @@
|
||||
<li role="none">
|
||||
<button type="button" role="menuitem" @click.prevent="pan">{{ messageCenterHere }}</button>
|
||||
</li>
|
||||
<WorldListItem v-if="currentWorld && mapCount > 1" :world="currentWorld" name="context"></WorldListItem>
|
||||
<WorldListItem v-if="currentMap && mapCount > 1" :world="currentMap.appendedWorld || currentMap.world" name="context"></WorldListItem>
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
@ -72,10 +72,17 @@ export default defineComponent({
|
||||
menuElement = ref<HTMLInputElement | null>(null),
|
||||
menuVisible = computed(() => !!event.value),
|
||||
|
||||
currentWorld = computed(() => store.state.currentWorld),
|
||||
currentMap = computed(() => store.state.currentMap),
|
||||
currentZoom = computed(() => store.state.currentZoom),
|
||||
mapCount = computed(() => currentWorld.value ? currentWorld.value.maps.size : 0),
|
||||
mapCount = computed(() => {
|
||||
if(!currentMap.value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Use appendedWorld if present for map list
|
||||
return currentMap.value?.appendedWorld ?
|
||||
currentMap.value?.appendedWorld.maps.size : currentMap.value.world.maps.size;
|
||||
}),
|
||||
|
||||
location = computed(() => {
|
||||
if (!event.value || !currentMap.value) {
|
||||
@ -221,7 +228,7 @@ export default defineComponent({
|
||||
|
||||
locationLabel,
|
||||
locationCopy,
|
||||
currentWorld,
|
||||
currentMap,
|
||||
mapCount,
|
||||
style,
|
||||
|
||||
|
2
src/index.d.ts
vendored
2
src/index.d.ts
vendored
@ -156,7 +156,7 @@ interface LiveAtlasWorldDefinition {
|
||||
dimension: LiveAtlasDimension;
|
||||
center: Coordinate;
|
||||
defaultZoom?: number;
|
||||
maps: Map<string, LiveAtlasMapDefinition>;
|
||||
maps: Set<LiveAtlasMapDefinition>;
|
||||
}
|
||||
|
||||
interface LiveAtlasWorldState {
|
||||
|
@ -21,6 +21,7 @@ import {ImageFormat} from "dynmap";
|
||||
|
||||
export interface LiveAtlasMapDefinitionOptions {
|
||||
world: LiveAtlasWorldDefinition;
|
||||
appendedWorld?: LiveAtlasWorldDefinition; // append_to_world
|
||||
name: string;
|
||||
displayName?: string;
|
||||
icon?: string;
|
||||
@ -39,6 +40,7 @@ export interface LiveAtlasMapDefinitionOptions {
|
||||
|
||||
export default class LiveAtlasMapDefinition {
|
||||
readonly world: LiveAtlasWorldDefinition;
|
||||
readonly appendedWorld?: LiveAtlasWorldDefinition;
|
||||
readonly name: string;
|
||||
readonly icon?: string;
|
||||
readonly displayName: string;
|
||||
@ -55,7 +57,8 @@ export default class LiveAtlasMapDefinition {
|
||||
readonly tileUpdateInterval?: number;
|
||||
|
||||
constructor(options: LiveAtlasMapDefinitionOptions) {
|
||||
this.world = options.world; //Ignore append_to_world here otherwise things break
|
||||
this.world = options.world;
|
||||
this.appendedWorld = options.appendedWorld; // append_to_world
|
||||
this.name = options.name;
|
||||
this.icon = options.icon || undefined;
|
||||
this.displayName = options.displayName || '';
|
||||
|
@ -160,7 +160,7 @@ export default class Pl3xmapMapProvider extends MapProvider {
|
||||
dimension = 'end';
|
||||
}
|
||||
|
||||
const maps: Map<string, LiveAtlasMapDefinition> = new Map();
|
||||
const maps: Set<LiveAtlasMapDefinition> = new Set();
|
||||
|
||||
const w = {
|
||||
name: world.name || '(Unnamed world)',
|
||||
@ -172,7 +172,7 @@ export default class Pl3xmapMapProvider extends MapProvider {
|
||||
maps,
|
||||
};
|
||||
|
||||
maps.set('flat', Object.freeze(new LiveAtlasMapDefinition({
|
||||
maps.add(Object.freeze(new LiveAtlasMapDefinition({
|
||||
world: w,
|
||||
|
||||
background: 'transparent',
|
||||
|
@ -112,21 +112,20 @@ export const actions: ActionTree<State, State> & Actions = {
|
||||
}
|
||||
|
||||
if(worldName) {
|
||||
const world = state.worlds.get(worldName) as LiveAtlasWorldDefinition;
|
||||
|
||||
// Use config default map if it exists
|
||||
if(state.configuration.defaultMap && world.maps.has(state.configuration.defaultMap)) {
|
||||
if(state.configuration.defaultMap && state.maps.has(`${worldName}_${state.configuration.defaultMap}`)) {
|
||||
mapName = state.configuration.defaultMap;
|
||||
}
|
||||
|
||||
// Prefer map from parsed url if present and it exists
|
||||
if(state.parsedUrl?.map && world.maps.has(state.parsedUrl.map)) {
|
||||
if(state.parsedUrl?.map && state.maps.has(`${worldName}_${state.parsedUrl.map}`)) {
|
||||
mapName = state.parsedUrl.map;
|
||||
}
|
||||
|
||||
// Use first map, if any, if neither of the above exist
|
||||
if(!mapName) {
|
||||
mapName = world.maps.size ? world.maps.entries().next().value[1].name : undefined;
|
||||
const world = state.worlds.get(worldName) as LiveAtlasWorldDefinition;
|
||||
mapName = world.maps.size ? world.maps.values().next().value.name : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ export const mutations: MutationTree<State> & Mutations = {
|
||||
|
||||
worlds.forEach(world => {
|
||||
state.worlds.set(world.name, world);
|
||||
world.maps.forEach(map => state.maps.set(`${world.name}_${map.name}`, map));
|
||||
world.maps.forEach(map => state.maps.set(`${map.world.name}_${map.name}`, map));
|
||||
});
|
||||
|
||||
//Update current world if a world with the same name still exists, otherwise clear
|
||||
|
@ -110,7 +110,7 @@ export function buildWorlds(response: Configuration): Array<LiveAtlasWorldDefini
|
||||
y: world.center.y || 0,
|
||||
z: world.center.z || 0
|
||||
},
|
||||
maps: new Map(),
|
||||
maps: new Set(),
|
||||
});
|
||||
});
|
||||
|
||||
@ -126,8 +126,11 @@ export function buildWorlds(response: Configuration): Array<LiveAtlasWorldDefini
|
||||
return;
|
||||
}
|
||||
|
||||
assignedWorld.maps.set(map.name, Object.freeze(new LiveAtlasMapDefinition({
|
||||
world: actualWorld, //Ignore append_to_world here for Dynmap URL parity
|
||||
// Maps with append_to_world set are added both the original and target world's map set
|
||||
// The world property is always the original world, an additional appendedWorld property contains the target world
|
||||
const mapDef = Object.freeze(new LiveAtlasMapDefinition({
|
||||
world: actualWorld,
|
||||
appendedWorld: actualWorld !== assignedWorld ? assignedWorld : undefined,
|
||||
background: map.background || '#000000',
|
||||
backgroundDay: map.backgroundday || '#000000',
|
||||
backgroundNight: map.backgroundnight || '#000000',
|
||||
@ -141,7 +144,13 @@ export function buildWorlds(response: Configuration): Array<LiveAtlasWorldDefini
|
||||
worldToMap: map.worldtomap || undefined,
|
||||
nativeZoomLevels: map.mapzoomout || 1,
|
||||
extraZoomLevels: map.mapzoomin || 0
|
||||
})));
|
||||
})) as LiveAtlasMapDefinition;
|
||||
|
||||
actualWorld.maps.add(mapDef);
|
||||
|
||||
if(actualWorld !== assignedWorld) {
|
||||
assignedWorld.maps.add(mapDef);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user