Message handling improvements

-Define message keys in a single place
-Add fallback for missing messages
-Slight reduction in filesize
This commit is contained in:
James Lyne 2022-01-12 15:21:01 +00:00
parent 4b834aa0b0
commit b39db090f5
5 changed files with 118 additions and 184 deletions

82
messages.ts Normal file
View File

@ -0,0 +1,82 @@
/*
* Copyright 2022 James Lyne
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const globalMessages = [
'chatNoMessages',
'chatTitle',
'chatLogin',
'chatSend',
'chatPlaceholder',
'chatErrorDisabled',
'chatErrorUnknown',
'serversHeading',
'worldsSkeleton',
'playersSkeleton',
'playersTitle',
'playersTitleHidden',
'playersTitleOtherWorld',
'playersSearchPlaceholder',
'playersSearchSkeleton',
'followingHeading',
'followingUnfollow',
'followingTitleUnfollow',
'followingHidden',
'linkTitle',
'loadingTitle',
'locationRegion',
'locationChunk',
'contextMenuCopyLink',
'contextMenuCenterHere',
'toggleTitle',
'mapTitle',
'layersTitle',
'copyToClipboardSuccess',
'copyToClipboardError',
'loginTitle',
'loginHeading',
'loginUsernameLabel',
'loginPasswordLabel',
'loginSubmit',
'loginErrorUnknown',
'loginErrorDisabled',
'loginErrorIncorrect',
'loginSuccess',
'registerHeading',
'registerDescription',
'registerConfirmPasswordLabel',
'registerCodeLabel',
'registerSubmit',
'registerErrorUnknown',
'registerErrorDisabled',
'registerErrorVerifyFailed',
'registerErrorIncorrect',
'logoutTitle',
'logoutErrorUnknown',
'logoutSuccess',
'closeTitle',
] as const;
export const serverMessages = [
'chatPlayerJoin',
'chatPlayerQuit',
'chatAnonymousJoin',
'chatAnonymousQuit',
'chatErrorNotAllowed',
'chatErrorRequiresLogin',
'chatErrorCooldown',
'worldsHeading',
'playersHeading',
] as const;

68
src/index.d.ts vendored
View File

@ -21,6 +21,7 @@ import {Coords, DoneCallback, InternalTiles, PathOptions, PointTuple, PolylineOp
import {CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl"; import {CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl";
import {ClockControlOptions} from "@/leaflet/control/ClockControl"; import {ClockControlOptions} from "@/leaflet/control/ClockControl";
import {LogoControlOptions} from "@/leaflet/control/LogoControl"; import {LogoControlOptions} from "@/leaflet/control/LogoControl";
import {globalMessages, serverMessages} from "../messages";
declare module "*.png" { declare module "*.png" {
const value: any; const value: any;
@ -80,72 +81,13 @@ interface LiveAtlasServerDefinition {
} }
// Messages defined directly in LiveAtlas and used for all servers // Messages defined directly in LiveAtlas and used for all servers
interface LiveAtlasGlobalMessageConfig { type LiveAtlasGlobalMessageConfig = {
chatNoMessages: string; [K in typeof globalMessages[number]]: string;
chatTitle: string;
chatLogin: string;
chatSend: string;
chatPlaceholder: string;
chatErrorDisabled: string;
chatErrorUnknown: string;
serversHeading: string;
worldsSkeleton: string;
playersSkeleton: string;
playersTitle: string;
playersTitleHidden: string;
playersTitleOtherWorld: string;
playersSearchPlaceholder: string;
playersSearchSkeleton: string;
followingHeading: string;
followingUnfollow: string;
followingTitleUnfollow: string;
followingHidden: string;
linkTitle: string;
loadingTitle: string;
locationRegion: string;
locationChunk: string;
contextMenuCopyLink: string;
contextMenuCenterHere: string;
toggleTitle: string;
mapTitle: string;
layersTitle: string;
copyToClipboardSuccess: string;
copyToClipboardError: string;
loginTitle: string;
loginHeading: string;
loginUsernameLabel: string;
loginPasswordLabel: string;
loginSubmit: string;
loginErrorUnknown: string;
loginErrorDisabled: string;
loginErrorIncorrect: string;
loginSuccess: string;
registerHeading: string;
registerDescription: string;
registerConfirmPasswordLabel: string;
registerCodeLabel: string;
registerSubmit: string;
registerErrorUnknown: string;
registerErrorDisabled: string;
registerErrorVerifyFailed: string;
registerErrorIncorrect: string;
logoutTitle: string;
logoutErrorUnknown: string;
logoutSuccess: string;
closeTitle: string;
} }
// Messages defined by dynmap configuration responses and can vary per server // Messages defined by dynmap configuration responses and can vary per server
interface LiveAtlasServerMessageConfig { type LiveAtlasServerMessageConfig = {
chatPlayerJoin: string; [K in typeof serverMessages[number]]: string;
chatPlayerQuit: string;
chatAnonymousJoin: string;
chatAnonymousQuit: string;
chatErrorNotAllowed: string;
chatErrorRequiresLogin: string;
chatErrorCooldown: string;
worldsHeading: string;
playersHeading: string;
} }
type LiveAtlasMessageConfig = LiveAtlasGlobalMessageConfig & LiveAtlasServerMessageConfig; type LiveAtlasMessageConfig = LiveAtlasGlobalMessageConfig & LiveAtlasServerMessageConfig;

View File

@ -48,6 +48,7 @@ import {
} from "@/index"; } from "@/index";
import DynmapMapProvider from "@/providers/DynmapMapProvider"; import DynmapMapProvider from "@/providers/DynmapMapProvider";
import Pl3xmapMapProvider from "@/providers/Pl3xmapMapProvider"; import Pl3xmapMapProvider from "@/providers/Pl3xmapMapProvider";
import {getGlobalMessages} from "@/util";
export type CurrentMapPayload = { export type CurrentMapPayload = {
worldName: string; worldName: string;
@ -126,62 +127,7 @@ export const mutations: MutationTree<State> & Mutations = {
console.warn('Failed to load saved UI settings', e); console.warn('Failed to load saved UI settings', e);
} }
const messages: LiveAtlasGlobalMessageConfig = { state.messages = Object.assign(state.messages, getGlobalMessages(messageConfig));
chatTitle: messageConfig.chatTitle || '',
chatLogin: messageConfig.chatLogin || '',
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 || '',
playersSearchPlaceholder: messageConfig.playersSearchPlaceholder || '',
playersSearchSkeleton: messageConfig.playersSearchSkeleton || '',
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 || '',
loginTitle: messageConfig.loginTitle || '',
loginHeading: messageConfig.loginHeading || '',
loginUsernameLabel: messageConfig.loginUsernameLabel || '',
loginPasswordLabel: messageConfig.loginPasswordLabel || '',
loginSubmit: messageConfig.loginSubmit || '',
loginErrorUnknown: messageConfig.loginErrorUnknown || '',
loginErrorDisabled: messageConfig.loginErrorDisabled || '',
loginErrorIncorrect: messageConfig.loginErrorIncorrect || '',
loginSuccess: messageConfig.loginSuccess || '',
registerHeading: messageConfig.registerHeading || '',
registerDescription: messageConfig.registerDescription || '',
registerConfirmPasswordLabel: messageConfig.registerConfirmPasswordLabel || '',
registerCodeLabel: messageConfig.registerCodeLabel || '',
registerSubmit: messageConfig.registerSubmit || '',
registerErrorUnknown: messageConfig.registerErrorUnknown || '',
registerErrorDisabled: messageConfig.registerErrorDisabled || '',
registerErrorVerifyFailed: messageConfig.registerErrorVerifyFailed || '',
registerErrorIncorrect: messageConfig.registerErrorIncorrect || '',
logoutTitle: messageConfig.logoutTitle || '',
logoutErrorUnknown: messageConfig.logoutErrorUnknown || '',
logoutSuccess: messageConfig.logoutSuccess || '',
closeTitle: messageConfig.closeTitle || '',
}
state.messages = Object.assign(state.messages, messages);
if(typeof uiConfig.playersAboveMarkers === 'boolean') { if(typeof uiConfig.playersAboveMarkers === 'boolean') {
state.ui.playersAboveMarkers = uiConfig.playersAboveMarkers; state.ui.playersAboveMarkers = uiConfig.playersAboveMarkers;

View File

@ -39,6 +39,7 @@ import {
LiveAtlasMarkerSetContents LiveAtlasMarkerSetContents
} from "@/index"; } from "@/index";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition"; import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import {getMessages} from "@/util";
export type State = { export type State = {
version: string; version: string;
@ -112,69 +113,7 @@ export const state: State = {
}, },
configurationHash: undefined, configurationHash: undefined,
messages: { messages: getMessages(),
chatPlayerJoin: '',
chatPlayerQuit: '',
chatAnonymousJoin: '',
chatAnonymousQuit: '',
chatNoMessages: '',
chatTitle: '',
chatLogin: '',
chatSend: '',
chatPlaceholder: '',
chatErrorNotAllowed: '',
chatErrorRequiresLogin: '',
chatErrorCooldown: '',
chatErrorDisabled: '',
chatErrorUnknown: '',
serversHeading: '',
worldsHeading: '',
worldsSkeleton: '',
playersSkeleton: '',
playersHeading: '',
playersTitle: '',
playersTitleHidden: '',
playersTitleOtherWorld: '',
playersSearchPlaceholder: '',
playersSearchSkeleton: '',
followingHeading: '',
followingUnfollow: '',
followingTitleUnfollow: '',
followingHidden: '',
linkTitle: '',
loadingTitle: '',
locationRegion: '',
locationChunk: '',
contextMenuCopyLink: '',
contextMenuCenterHere: '',
toggleTitle: '',
mapTitle: '',
layersTitle: '',
copyToClipboardSuccess: '',
copyToClipboardError: '',
loginTitle: '',
loginHeading: '',
loginUsernameLabel: '',
loginPasswordLabel: '',
loginSubmit: '',
loginErrorUnknown: '',
loginErrorDisabled: '',
loginErrorIncorrect: '',
loginSuccess: '',
registerHeading: '',
registerDescription: '',
registerConfirmPasswordLabel: '',
registerCodeLabel: '',
registerSubmit: '',
registerErrorUnknown: '',
registerErrorDisabled: '',
registerErrorVerifyFailed: '',
registerErrorIncorrect: '',
logoutTitle: '',
logoutErrorUnknown: '',
logoutSuccess: '',
closeTitle: '',
},
loggedIn: false, loggedIn: false,
loginRequired: false, loginRequired: false,

View File

@ -16,8 +16,15 @@
import {useStore} from "@/store"; import {useStore} from "@/store";
import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition"; import LiveAtlasMapDefinition from "@/model/LiveAtlasMapDefinition";
import {HeadQueueEntry, LiveAtlasPlayer, LiveAtlasPlayerImageSize} from "@/index"; import {
HeadQueueEntry,
LiveAtlasGlobalMessageConfig,
LiveAtlasMessageConfig,
LiveAtlasPlayer,
LiveAtlasPlayerImageSize,
} from "@/index";
import {notify} from "@kyvg/vue3-notification"; import {notify} from "@kyvg/vue3-notification";
import {globalMessages, serverMessages} from "../messages";
const headCache = new Map<string, HTMLImageElement>(), const headCache = new Map<string, HTMLImageElement>(),
headUnresolvedCache = new Map<string, Promise<HTMLImageElement>>(), headUnresolvedCache = new Map<string, Promise<HTMLImageElement>>(),
@ -212,10 +219,28 @@ export const decodeHTMLEntities = (text: string) => {
return decodeTextarea.textContent || ''; return decodeTextarea.textContent || '';
} }
export const clipboardSuccess = () => () => notify(useStore().state.messages.copyToClipboardSuccess); export const clipboardSuccess = () => () => notify(useStore().state.messages.copyToClipboardSuccess);
export const clipboardError = () => (e: Error) => { export const clipboardError = () => (e: Error) => {
notify({ type: 'error', text: useStore().state.messages.copyToClipboardError }); notify({ type: 'error', text: useStore().state.messages.copyToClipboardError });
console.error('Error copying to clipboard', e); console.error('Error copying to clipboard', e);
}; };
export const getMessages = (config: any = {}) => {
return Object.assign(_getMessages(globalMessages, config),
_getMessages(serverMessages, config)) as LiveAtlasMessageConfig;
}
export const getGlobalMessages = (config: any = {}) => {
return _getMessages(globalMessages, config) as LiveAtlasGlobalMessageConfig;
}
const _getMessages = (messageKeys: any, config: any = {}) => {
const messages: any = {};
for(const key of messageKeys) {
messages[key] = config[key] || `Missing message: ${key}`;
}
return messages as LiveAtlasGlobalMessageConfig;
}