Configuration improvements

- Default playersAboveMarkers to true to match previous behaviour
- Move all window.liveAtlasConfig handling to main.ts and a single mutation
- Rename server configuration mutations to differentiate server and global configurations
This commit is contained in:
James Lyne 2021-07-20 21:12:08 +01:00
parent c67db75586
commit 649f571a20
10 changed files with 136 additions and 94 deletions

View File

@ -117,7 +117,7 @@
ui: {
// If true, player markers will always be displayed in front of other marker types
playersAboveMarkers: false
playersAboveMarkers: true
}
};
</script>

View File

@ -33,7 +33,7 @@ import {
} from "@/dynmap";
import {useStore} from "@/store";
import ChatError from "@/errors/ChatError";
import {LiveAtlasMessageConfig, LiveAtlasWorld} from "@/index";
import {LiveAtlasServerMessageConfig, LiveAtlasWorld} from "@/index";
const titleColours = /§[0-9a-f]/ig;
@ -56,48 +56,17 @@ function buildServerConfig(response: any): DynmapServerConfig {
};
}
function buildMessagesConfig(response: any): LiveAtlasMessageConfig {
const liveAtlasMessages = window.liveAtlasConfig?.messages || {};
function buildMessagesConfig(response: any): LiveAtlasServerMessageConfig {
return {
chatPlayerJoin: response.joinmessage || '',
chatPlayerQuit: response.quitmessage || '',
chatAnonymousJoin: response['msg-hiddennamejoin'] || '',
chatAnonymousQuit: response['msg-hiddennamequit'] || '',
chatTitle: liveAtlasMessages.chatTitle || '',
chatLogin: liveAtlasMessages.chatLogin || '',
chatLoginLink: liveAtlasMessages.chatLoginLink || '',
chatNoMessages: liveAtlasMessages.chatNoMessages || '',
chatSend: liveAtlasMessages.chatSend || '',
chatPlaceholder: liveAtlasMessages.chatPlaceholder || '',
chatErrorNotAllowed: response['msg-chatnotallowed'] || '',
chatErrorRequiresLogin: response['msg-chatrequireslogin'] || '',
chatErrorCooldown: response.spammessage || '',
chatErrorDisabled: liveAtlasMessages.chatErrorDisabled || '',
chatErrorUnknown: liveAtlasMessages.chatErrorUnknown || '',
serversHeading: liveAtlasMessages.serversHeading || '',
worldsHeading: response['msg-maptypes'] || '',
worldsSkeleton: liveAtlasMessages.worldsSkeleton || '',
playersHeading: response['msg-players'] || '',
playersSkeleton: liveAtlasMessages.playersSkeleton || '',
playersTitle: liveAtlasMessages.playersTitle || '',
playersTitleHidden: liveAtlasMessages.playersTitleHidden || '',
playersTitleOtherWorld: liveAtlasMessages.playersTitleOtherWorld || '',
followingHeading: liveAtlasMessages.followingHeading || '',
followingHidden: liveAtlasMessages.followingHidden || '',
followingUnfollow: liveAtlasMessages.followingUnfollow || '',
followingTitleUnfollow: liveAtlasMessages.followingTitleUnfollow || '',
linkTitle: liveAtlasMessages.linkTitle || '',
loadingTitle: liveAtlasMessages.loadingTitle || '',
locationRegion: liveAtlasMessages.locationRegion || '',
locationChunk: liveAtlasMessages.locationChunk || '',
contextMenuCopyLink: liveAtlasMessages.contextMenuCopyLink || '',
contextMenuCenterHere: liveAtlasMessages.contextMenuCenterHere || '',
toggleTitle: liveAtlasMessages.toggleTitle || '',
mapTitle: liveAtlasMessages.mapTitle || '',
layersTitle: liveAtlasMessages.layersTitle || '',
copyToClipboardSuccess: liveAtlasMessages.copyToClipboardSuccess || '',
copyToClipboardError: liveAtlasMessages.copyToClipboardError || '',
}
}

11
src/dynmap.d.ts vendored
View File

@ -18,13 +18,18 @@ import {PathOptions, PointTuple, PolylineOptions} from "leaflet";
import {CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl";
import {LogoControlOptions} from "@/leaflet/control/LogoControl";
import {ClockControlOptions} from "@/leaflet/control/ClockControl";
import {Coordinate, LiveAtlasLocation, LiveAtlasMessageConfig, LiveAtlasWorld, LiveAtlasWorldState} from "@/index";
import {
Coordinate,
LiveAtlasLocation,
LiveAtlasServerMessageConfig,
LiveAtlasWorld,
LiveAtlasWorldState
} from "@/index";
declare global {
// noinspection JSUnusedGlobalSymbols
interface Window {
config: { url: DynmapUrlConfig };
liveAtlasConfig: any,
}
}
@ -96,7 +101,7 @@ interface DynmapChatSendingConfig {
interface DynmapConfigurationResponse {
config: DynmapServerConfig,
messages: LiveAtlasMessageConfig,
messages: LiveAtlasServerMessageConfig,
worlds: Array<LiveAtlasWorld>,
components: DynmapComponentConfig,
loggedIn: boolean,

44
src/index.d.ts vendored
View File

@ -12,6 +12,13 @@ declare module '*.vue' {
export default component
}
declare global {
// noinspection JSUnusedGlobalSymbols
interface Window {
liveAtlasConfig: LiveAtlasGlobalConfig,
}
}
interface Coordinate {
x: number;
y: number;
@ -25,6 +32,12 @@ interface LiveAtlasLocation {
world?: string;
}
interface LiveAtlasGlobalConfig {
servers: Map<string, LiveAtlasServerDefinition>;
messages: LiveAtlasGlobalMessageConfig;
ui: LiveAtlasUIConfig;
}
interface LiveAtlasServerDefinition {
id: string
label?: string
@ -35,27 +48,19 @@ interface LiveAtlasDynmapServerDefinition extends LiveAtlasServerDefinition {
dynmap: DynmapUrlConfig,
}
interface LiveAtlasMessageConfig {
chatPlayerJoin: string;
chatPlayerQuit: string;
chatAnonymousJoin: string;
chatAnonymousQuit: string;
// Messages defined directly in LiveAtlas and used for all servers
interface LiveAtlasGlobalMessageConfig {
chatNoMessages: string;
chatTitle: string;
chatLogin: string;
chatLoginLink: string;
chatSend: string;
chatPlaceholder: string;
chatErrorNotAllowed: string;
chatErrorRequiresLogin: string;
chatErrorCooldown: string;
chatErrorDisabled: string;
chatErrorUnknown: string;
serversHeading: string;
worldsHeading: string;
worldsSkeleton: string;
playersSkeleton: string;
playersHeading: string;
playersTitle: string;
playersTitleHidden: string;
playersTitleOtherWorld: string;
@ -76,6 +81,25 @@ interface LiveAtlasMessageConfig {
copyToClipboardError: string;
}
// Messages defined by dynmap configuration responses and can vary per server
interface LiveAtlasServerMessageConfig {
chatPlayerJoin: string;
chatPlayerQuit: string;
chatAnonymousJoin: string;
chatAnonymousQuit: string;
chatErrorNotAllowed: string;
chatErrorRequiresLogin: string;
chatErrorCooldown: string;
worldsHeading: string;
playersHeading: string;
}
type LiveAtlasMessageConfig = LiveAtlasGlobalMessageConfig & LiveAtlasServerMessageConfig;
interface LiveAtlasUIConfig {
playersAboveMarkers: boolean;
}
export type LiveAtlasUIElement = 'layers' | 'chat' | 'players' | 'maps' | 'settings';
export type LiveAtlasSidebarSection = 'servers' | 'players' | 'maps';

View File

@ -24,10 +24,10 @@ import '@/scss/style.scss';
import 'focus-visible';
import {MutationTypes} from "@/store/mutation-types";
import {validateConfiguration} from "@/util/config";
import {showSplashError} from "@/util/splash";
import { VueClipboard } from '@soerenmartius/vue3-clipboard';
import Notifications from '@kyvg/vue3-notification'
import {getServerDefinitions} from "@/util/config";
const splash = document.getElementById('splash'),
svgs = import.meta.globEager('/assets/icons/*.svg');
@ -49,14 +49,14 @@ store.subscribe((mutation, state) => {
});
try {
const config = validateConfiguration();
const config = window.liveAtlasConfig;
config.servers = getServerDefinitions(config);
store.commit(MutationTypes.INIT, undefined);
store.commit(MutationTypes.SET_SERVERS, config);
store.commit(MutationTypes.INIT, config);
if(config.size > 1) {
if(store.state.servers.size > 1) {
const lastSegment = window.location.pathname.split('/').pop(),
serverName = lastSegment && config.has(lastSegment) ? lastSegment : config.keys().next().value;
serverName = lastSegment && store.state.servers.has(lastSegment) ? lastSegment : store.state.servers.keys().next().value;
//Update url if server doesn't exist
if(serverName !== lastSegment) {
@ -65,7 +65,7 @@ try {
store.commit(MutationTypes.SET_CURRENT_SERVER, serverName);
} else {
store.commit(MutationTypes.SET_CURRENT_SERVER, config.keys().next().value);
store.commit(MutationTypes.SET_CURRENT_SERVER, store.state.servers.keys().next().value);
}
const app = createApp(App)

View File

@ -80,12 +80,12 @@ export interface Actions {
export const actions: ActionTree<State, State> & Actions = {
async [ActionTypes.LOAD_CONFIGURATION]({commit, state}): Promise<DynmapConfigurationResponse> {
//Clear any existing has to avoid triggering a second config load, after this load changes the hash
commit(MutationTypes.CLEAR_CONFIGURATION_HASH, undefined);
commit(MutationTypes.CLEAR_SERVER_CONFIGURATION_HASH, undefined);
const config = await getAPI().getConfiguration();
commit(MutationTypes.SET_CONFIGURATION, config.config);
commit(MutationTypes.SET_MESSAGES, config.messages);
commit(MutationTypes.SET_SERVER_CONFIGURATION, config.config);
commit(MutationTypes.SET_SERVER_MESSAGES, config.messages);
commit(MutationTypes.SET_WORLDS, config.worlds);
commit(MutationTypes.SET_COMPONENTS, config.components);
commit(MutationTypes.SET_LOGGED_IN, config.loggedIn);
@ -159,7 +159,7 @@ export const actions: ActionTree<State, State> & Actions = {
commit(MutationTypes.ADD_MARKER_SET_UPDATES, update.updates.markerSets);
commit(MutationTypes.ADD_TILE_UPDATES, update.updates.tiles);
commit(MutationTypes.ADD_CHAT, update.updates.chat);
commit(MutationTypes.SET_CONFIGURATION_HASH, update.configHash);
commit(MutationTypes.SET_SERVER_CONFIGURATION_HASH, update.configHash);
await dispatch(ActionTypes.SET_PLAYERS, update.players);
return update;

View File

@ -17,11 +17,10 @@
export enum MutationTypes {
INIT ='init',
SET_SERVERS ='setServers',
SET_CONFIGURATION = 'setConfiguration',
SET_CONFIGURATION_HASH = 'setConfigurationHash',
CLEAR_CONFIGURATION_HASH = 'clearConfigurationHash',
SET_MESSAGES = 'setMessages',
SET_SERVER_CONFIGURATION = 'setServerConfiguration',
SET_SERVER_CONFIGURATION_HASH = 'setServerConfigurationHash',
CLEAR_SERVER_CONFIGURATION_HASH = 'clearServerConfigurationHash',
SET_SERVER_MESSAGES = 'setServerMessages',
SET_WORLDS = 'setWorlds',
CLEAR_WORLDS = 'clearWorlds',
SET_COMPONENTS = 'setComponents',

View File

@ -30,12 +30,16 @@ import {
} from "@/dynmap";
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
import {
Coordinate, LiveAtlasWorldState,
LiveAtlasMessageConfig,
LiveAtlasServerDefinition,
Coordinate,
LiveAtlasWorldState,
LiveAtlasSidebarSection,
LiveAtlasSortedPlayers,
LiveAtlasUIElement, LiveAtlasWorld, LiveAtlasParsedUrl
LiveAtlasUIElement,
LiveAtlasWorld,
LiveAtlasParsedUrl,
LiveAtlasGlobalConfig,
LiveAtlasGlobalMessageConfig,
LiveAtlasServerMessageConfig
} from "@/index";
export type CurrentMapPayload = {
@ -44,12 +48,11 @@ export type CurrentMapPayload = {
}
export type Mutations<S = State> = {
[MutationTypes.INIT](state: S): void
[MutationTypes.SET_SERVERS](state: S, servers: Map<string, LiveAtlasServerDefinition>): void
[MutationTypes.SET_CONFIGURATION](state: S, config: DynmapServerConfig): void
[MutationTypes.SET_CONFIGURATION_HASH](state: S, hash: number): void
[MutationTypes.CLEAR_CONFIGURATION_HASH](state: S): void
[MutationTypes.SET_MESSAGES](state: S, messages: LiveAtlasMessageConfig): void
[MutationTypes.INIT](state: S, config: LiveAtlasGlobalConfig): void
[MutationTypes.SET_SERVER_CONFIGURATION](state: S, config: DynmapServerConfig): void
[MutationTypes.SET_SERVER_CONFIGURATION_HASH](state: S, hash: number): void
[MutationTypes.CLEAR_SERVER_CONFIGURATION_HASH](state: S): void
[MutationTypes.SET_SERVER_MESSAGES](state: S, messages: LiveAtlasServerMessageConfig): void
[MutationTypes.SET_WORLDS](state: S, worlds: Array<LiveAtlasWorld>): void
[MutationTypes.CLEAR_WORLDS](state: S): void
[MutationTypes.SET_COMPONENTS](state: S, worlds: DynmapComponentConfig): void
@ -96,17 +99,54 @@ export type Mutations<S = State> = {
}
export const mutations: MutationTree<State> & Mutations = {
[MutationTypes.INIT](state: State) {
const collapsedSections = localStorage.getItem('collapsedSections');
[MutationTypes.INIT](state: State, config: LiveAtlasGlobalConfig) {
const collapsedSections = localStorage.getItem('collapsedSections'),
messageConfig = config?.messages || {},
uiConfig = config?.ui || {};
if(collapsedSections) {
state.ui.sidebar.collapsedSections = new Set(JSON.parse(collapsedSections));
}
},
// Sets configuration options from the initial config fetch
[MutationTypes.SET_SERVERS](state: State, config: Map<string, LiveAtlasServerDefinition>) {
state.servers = config;
const messages: LiveAtlasGlobalMessageConfig = {
chatTitle: messageConfig.chatTitle || '',
chatLogin: messageConfig.chatLogin || '',
chatLoginLink: messageConfig.chatLoginLink || '',
chatNoMessages: messageConfig.chatNoMessages || '',
chatSend: messageConfig.chatSend || '',
chatPlaceholder: messageConfig.chatPlaceholder || '',
chatErrorDisabled: messageConfig.chatErrorDisabled || '',
chatErrorUnknown: messageConfig.chatErrorUnknown || '',
serversHeading: messageConfig.serversHeading || '',
worldsSkeleton: messageConfig.worldsSkeleton || '',
playersSkeleton: messageConfig.playersSkeleton || '',
playersTitle: messageConfig.playersTitle || '',
playersTitleHidden: messageConfig.playersTitleHidden || '',
playersTitleOtherWorld: messageConfig.playersTitleOtherWorld || '',
followingHeading: messageConfig.followingHeading || '',
followingHidden: messageConfig.followingHidden || '',
followingUnfollow: messageConfig.followingUnfollow || '',
followingTitleUnfollow: messageConfig.followingTitleUnfollow || '',
linkTitle: messageConfig.linkTitle || '',
loadingTitle: messageConfig.loadingTitle || '',
locationRegion: messageConfig.locationRegion || '',
locationChunk: messageConfig.locationChunk || '',
contextMenuCopyLink: messageConfig.contextMenuCopyLink || '',
contextMenuCenterHere: messageConfig.contextMenuCenterHere || '',
toggleTitle: messageConfig.toggleTitle || '',
mapTitle: messageConfig.mapTitle || '',
layersTitle: messageConfig.layersTitle || '',
copyToClipboardSuccess: messageConfig.copyToClipboardSuccess || '',
copyToClipboardError: messageConfig.copyToClipboardError || '',
}
state.messages = Object.assign(state.messages, messages);
if(typeof uiConfig.playersAboveMarkers === 'boolean') {
state.ui.playersAboveMarkers = uiConfig.playersAboveMarkers;
}
state.servers = config.servers;
if(state.currentServer && !state.servers.has(state.currentServer.id)) {
state.currentServer = undefined;
@ -114,23 +154,23 @@ export const mutations: MutationTree<State> & Mutations = {
},
// Sets configuration options from the initial config fetch
[MutationTypes.SET_CONFIGURATION](state: State, config: DynmapServerConfig) {
[MutationTypes.SET_SERVER_CONFIGURATION](state: State, config: DynmapServerConfig) {
state.configuration = Object.assign(state.configuration, config);
state.configurationHash = config.hash;
},
// Sets configuration hash
[MutationTypes.SET_CONFIGURATION_HASH](state: State, hash: number) {
[MutationTypes.SET_SERVER_CONFIGURATION_HASH](state: State, hash: number) {
state.configurationHash = hash;
},
// Sets configuration hash
[MutationTypes.CLEAR_CONFIGURATION_HASH](state: State) {
[MutationTypes.CLEAR_SERVER_CONFIGURATION_HASH](state: State) {
state.configurationHash = undefined;
},
//Set messages from the initial config fetch
[MutationTypes.SET_MESSAGES](state: State, messages: LiveAtlasMessageConfig) {
// Sets messages from the initial config fetch
[MutationTypes.SET_SERVER_MESSAGES](state: State, messages: LiveAtlasServerMessageConfig) {
state.messages = Object.assign(state.messages, messages);
},

View File

@ -22,12 +22,16 @@ import {
} from "@/dynmap";
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
import {
Coordinate, LiveAtlasWorldState,
LiveAtlasMessageConfig,
Coordinate,
LiveAtlasWorldState,
LiveAtlasServerDefinition,
LiveAtlasSidebarSection,
LiveAtlasSortedPlayers,
LiveAtlasUIElement, LiveAtlasWorld, LiveAtlasWorldMap, LiveAtlasParsedUrl
LiveAtlasUIElement,
LiveAtlasWorld,
LiveAtlasWorldMap,
LiveAtlasParsedUrl,
LiveAtlasMessageConfig
} from "@/index";
export type State = {
@ -222,7 +226,7 @@ export const state: State = {
updateTimestamp: new Date(),
ui: {
playersAboveMarkers: window.liveAtlasConfig?.ui?.playersAboveMarkers || false,
playersAboveMarkers: true,
smallScreen: false,
visibleElements: new Set(),

View File

@ -1,4 +1,4 @@
import {LiveAtlasDynmapServerDefinition, LiveAtlasServerDefinition} from "@/index";
import {LiveAtlasDynmapServerDefinition, LiveAtlasGlobalConfig, LiveAtlasServerDefinition} from "@/index";
import ConfigurationError from "@/errors/ConfigurationError";
import {DynmapUrlConfig} from "@/dynmap";
@ -102,14 +102,15 @@ const validateDynmapConfiguration = (config: DynmapUrlConfig): Map<string, LiveA
return result;
};
export const validateConfiguration = (): Map<string, LiveAtlasServerDefinition> => {
if (!window.liveAtlasConfig) {
export const getServerDefinitions = (config: LiveAtlasGlobalConfig): Map<string, LiveAtlasServerDefinition> => {
if (!config) {
throw new ConfigurationError(`Configuration object is missing`);
}
if (typeof window.liveAtlasConfig.servers !== 'undefined') {
return validateLiveAtlasConfiguration(window.liveAtlasConfig.servers || {});
if (typeof config !== 'undefined') {
return validateLiveAtlasConfiguration(config.servers || {});
}
return validateDynmapConfiguration(window.config?.url || null);
};