Make LiveAtlas messages translatable

This commit is contained in:
James Lyne 2021-05-20 16:13:25 +01:00
parent 17540b6279
commit 131e1dd685
12 changed files with 124 additions and 88 deletions

View File

@ -32,37 +32,37 @@
creative: {
label: 'Creative',
dynmap: {
configuration: 'http://dynmap.local/standalone/creative/MySQL_configuration.php',
update: 'http://dynmap.local/standalone/creative/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/standalone/creative/MySQL_sendmessage.php',
login: 'http://dynmap.local/standalone/creative/MySQL_login.php',
register: 'http://dynmap.local/standalone/creative/MySQL_register.php',
tiles: 'http://dynmap.local/standalone/creative/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/standalone/creative/MySQL_markers.php?marker='
configuration: 'http://dynmap.local/creative/MySQL_configuration.php',
update: 'http://dynmap.local/creative/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/creative/MySQL_sendmessage.php',
login: 'http://dynmap.local/creative/MySQL_login.php',
register: 'http://dynmap.local/creative/MySQL_register.php',
tiles: 'http://dynmap.local/creative/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/creative/MySQL_markers.php?marker='
}
},
survival: {
label: 'Survival',
dynmap: {
configuration: 'http://dynmap.local/standalone/survival/MySQL_configuration.php',
update: 'http://dynmap.local/standalone/survival/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/standalone/survival/MySQL_sendmessage.php',
login: 'http://dynmap.local/standalone/survival/MySQL_login.php',
register: 'http://dynmap.local/standalone/survival/MySQL_register.php',
tiles: 'http://dynmap.local/standalone/survival/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/standalone/survival/MySQL_markers.php?marker='
configuration: 'http://dynmap.local/survival/MySQL_configuration.php',
update: 'http://dynmap.local/survival/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/survival/MySQL_sendmessage.php',
login: 'http://dynmap.local/survival/MySQL_login.php',
register: 'http://dynmap.local/survival/MySQL_register.php',
tiles: 'http://dynmap.local/survival/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/survival/MySQL_markers.php?marker='
}
},
build: {
label: 'Build',
dynmap: {
configuration: 'http://dynmap.local/standalone/build/MySQL_configuration.php',
update: 'http://dynmap.local/standalone/build/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/standalone/build/MySQL_sendmessage.php',
login: 'http://dynmap.local/standalone/build/MySQL_login.php',
register: 'http://dynmap.local/standalone/build/MySQL_register.php',
tiles: 'http://dynmap.local/standalone/build/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/standalone/build/MySQL_markers.php?marker='
configuration: 'http://dynmap.local/build/MySQL_configuration.php',
update: 'http://dynmap.local/build/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/build/MySQL_sendmessage.php',
login: 'http://dynmap.local/build/MySQL_login.php',
register: 'http://dynmap.local/build/MySQL_register.php',
tiles: 'http://dynmap.local/build/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/build/MySQL_markers.php?marker='
}
},
test: {
@ -78,6 +78,16 @@
markers: 'http://dynmap.local:8123/tiles/'
}
},
},
messages: {
headingServers: 'Servers',
chatNoMessages: 'No chat messages yet...',
chatLogin: 'Please {{link}} to send chat messages',
chatLoginLink: 'login',
chatSend: 'Send',
chatErrorUnknown: 'Unexpected error while sending chat message',
chatErrorDisabled: 'Chat is not enabled',
}
};
</script>

View File

@ -24,7 +24,6 @@ import {
DynmapMarker,
DynmapMarkerSet,
DynmapMarkerSetUpdates,
DynmapMessageConfig,
DynmapPlayer,
DynmapServerConfig,
DynmapTileUpdate,
@ -36,6 +35,7 @@ import {
} from "@/dynmap";
import {useStore} from "@/store";
import ChatError from "@/errors/ChatError";
import {LiveAtlasMessageConfig} from "@/index";
const titleColours = /§[0-9a-f]/ig;
@ -58,17 +58,26 @@ function buildServerConfig(response: any): DynmapServerConfig {
};
}
function buildMessagesConfig(response: any): DynmapMessageConfig {
function buildMessagesConfig(response: any): LiveAtlasMessageConfig {
const liveAtlasMessages = window.liveAtlasConfig ? window.liveAtlasConfig.messages || {} : {};
return {
chatNotAllowed: response['msg-chatnotallowed'] || '',
chatRequiresLogin: response['msg-chatrequireslogin'] || '',
chatCooldown: response.spammessage || '',
mapTypes: response['msg-maptypes'] || '',
players: response['msg-players'] || '',
playerJoin: response.joinmessage || '',
playerQuit: response.quitmessage || '',
anonymousJoin: response['msg-hiddennamejoin'] || '',
anonymousQuit: response['msg-hiddennamequit'] || '',
chatPlayerJoin: response.joinmessage || '',
chatPlayerQuit: response.quitmessage || '',
chatAnonymousJoin: response['msg-hiddennamejoin'] || '',
chatAnonymousQuit: response['msg-hiddennamequit'] || '',
chatLogin: liveAtlasMessages.chatLogin || '',
chatLoginLink: liveAtlasMessages.chatLoginLink || '',
chatNoMessages: liveAtlasMessages.chatNoMessages || '',
chatSend: liveAtlasMessages.chatSend || '',
chatErrorNotAllowed: response['msg-chatnotallowed'] || '',
chatErrorRequiresLogin: response['msg-chatrequireslogin'] || '',
chatErrorCooldown: response.spammessage || '',
chatErrorDisabled: liveAtlasMessages.chatErrorDisabled || '',
chatErrorUnknown: liveAtlasMessages.chatErrorUnknown || '',
headingWorlds: response['msg-maptypes'] || '',
headingPlayers: response['msg-players'] || '',
headingServers: liveAtlasMessages.headingServers || '',
}
}
@ -721,7 +730,7 @@ export default {
const store = useStore();
if (!store.state.components.chatSending) {
return Promise.reject(new ChatError("Chat is not enabled"));
return Promise.reject(store.state.messages.chatErrorDisabled);
}
return fetch(useStore().getters.serverConfig.dynmap.sendmessage, {
@ -732,7 +741,7 @@ export default {
})
}).then((response) => {
if (response.status === 403) { //Rate limited
throw new ChatError(store.state.messages.chatCooldown
throw new ChatError(store.state.messages.chatErrorCooldown
.replace('%interval%', store.state.components.chatSending!.cooldown.toString()));
}
@ -743,11 +752,11 @@ export default {
return response.json();
}).then(response => {
if (response.error !== 'none') {
throw new ChatError(store.state.messages.chatNotAllowed);
throw new ChatError(store.state.messages.chatErrorNotAllowed);
}
}).catch(e => {
if (!(e instanceof ChatError)) {
console.error('Unexpected error while sending chat message');
console.error(store.state.messages.chatErrorUnknown);
console.trace(e);
}

View File

@ -17,18 +17,16 @@
<template>
<section class="chat">
<ul class="chat__messages">
<ChatMessage v-for="message in messages" :key="message.timestamp" :message="message"></ChatMessage>
<li v-if="!messages.length" class="message message--skeleton">No chat messages yet...</li>
<ChatMessage v-for="message in chatMessages" :key="message.timestamp" :message="message"></ChatMessage>
<li v-if="!chatMessages.length" class="message message--skeleton">{{ messageNoMessages }}</li>
</ul>
<form v-if="sendingEnabled" class="chat__form" @submit.prevent="sendMessage">
<div v-if="sendingError" class="chat__error">{{ sendingError }}</div>
<input ref="chatInput" v-model="enteredMessage" class="chat__input" type="text" :maxlength="messageMaxLength"
<input ref="chatInput" v-model="enteredMessage" class="chat__input" type="text" :maxlength="maxMessageLength"
placeholder="Type your chat message here..." :disabled="sendingMessage">
<button class="chat__send" :disabled="!enteredMessage || sendingMessage">Send</button>
<button class="chat__send" :disabled="!enteredMessage || sendingMessage">{{ messageSend }}</button>
</form>
<div v-if="loginRequired" class="chat__login">
Please <a href="login.html">login</a> to send chat messages
</div>
<div v-if="loginRequired" class="chat__login" v-html="messageLogin"></div>
</section>
</template>
@ -53,14 +51,14 @@
&& !store.state.loggedIn;
}),
sendingEnabled = computed(() => store.state.components.chatSending && !loginRequired.value),
messageMaxLength = computed(() => store.state.components.chatSending?.maxLength),
maxMessageLength = computed(() => store.state.components.chatSending?.maxLength),
chatInput = ref<HTMLInputElement | null>(null),
enteredMessage = ref<string>(""),
sendingMessage = ref<boolean>(false),
sendingError = ref<string | null>(null),
messages = computed(() => {
chatMessages = computed(() => {
if(componentSettings.value!.messageHistory) {
return store.state.chat.messages.slice(0, componentSettings.value!.messageHistory);
} else {
@ -68,8 +66,13 @@
}
}),
messageSend = computed(() => store.state.messages.chatSend),
messageNoMessages = computed(() => store.state.messages.chatNoMessages),
messageLogin = computed(() => store.state.messages.chatLogin.replace(
'{{link}}', store.state.messages.chatLoginLink)),
sendMessage = async () => {
const message = enteredMessage.value.trim().substring(0, messageMaxLength.value);
const message = enteredMessage.value.trim().substring(0, maxMessageLength.value);
if(!message) {
return;
@ -86,7 +89,7 @@
if(e instanceof ChatError) {
sendingError.value = e.message;
} else {
sendingError.value = `An unexpected error occurred. See console for details.`;
sendingError.value = store.state.messages.chatErrorUnknown;
}
} finally {
sendingMessage.value = false;
@ -105,12 +108,15 @@
chatInput,
enteredMessage,
sendMessage,
messages,
chatMessages,
loginRequired,
sendingEnabled,
sendingMessage,
sendingError,
messageMaxLength
maxMessageLength,
messageLogin,
messageSend,
messageNoMessages,
}
}
})

View File

@ -47,17 +47,17 @@
return props.message.message;
case 'playerjoin':
if(props.message.playerName) {
return store.state.messages.playerJoin
return store.state.messages.chatPlayerJoin
.replace('%playername%', props.message.playerName);
} else {
return store.state.messages.anonymousJoin;
return store.state.messages.chatAnonymousJoin;
}
case 'playerleave':
if(props.message.playerName) {
return store.state.messages.playerQuit
return store.state.messages.chatPlayerQuit
.replace('%playername%', props.message.playerName);
} else {
return store.state.messages.anonymousQuit;
return store.state.messages.chatAnonymousQuit;
}
}
})

View File

@ -61,12 +61,12 @@ export default defineComponent({
this.leaflet.getLayerManager().addLayer(
this.layerGroup,
true,
useStore().state.messages.players,
useStore().state.messages.headingPlayers,
this.componentSettings!.layerPriority);
} else {
this.leaflet.getLayerManager().addHiddenLayer(
this.layerGroup,
useStore().state.messages.players,
useStore().state.messages.headingPlayers,
this.componentSettings!.layerPriority);
}
},

View File

@ -38,7 +38,7 @@ export default defineComponent({
computed: {
heading() {
return useStore().state.messages.players;
return useStore().state.messages.headingPlayers;
},
players() {

View File

@ -16,7 +16,7 @@
<template>
<section class="sidebar__section" v-if="servers.size > 1">
<span class="section__heading">Servers</span>
<span class="section__heading">{{ heading }}</span>
<ul class="section__content">
<ServerListItem :server="server" v-for="[name, server] in servers" :key="name"></ServerListItem>
</ul>
@ -36,7 +36,7 @@ export default defineComponent({
computed: {
heading() {
return 'Servers';
return useStore().state.messages.headingServers;
},
servers() {

View File

@ -39,7 +39,7 @@ export default defineComponent({
computed: {
heading() {
return useStore().state.messages.mapTypes;
return useStore().state.messages.headingWorlds;
},
worlds() {

15
src/dynmap.d.ts vendored
View File

@ -18,6 +18,7 @@ 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 {LiveAtlasMessageConfig} from "@/index";
declare global {
interface Window {
@ -56,18 +57,6 @@ interface DynmapServerConfig {
hash: number;
}
interface DynmapMessageConfig {
chatNotAllowed: string;
chatRequiresLogin: string;
chatCooldown: string;
mapTypes: string;
players: string;
playerJoin: string;
playerQuit: string;
anonymousJoin: string;
anonymousQuit: string;
}
interface DynmapComponentConfig {
markers: DynmapMarkersConfig;
playerMarkers?: DynmapPlayerMarkersConfig;
@ -156,7 +145,7 @@ interface DynmapLocation {
interface DynmapConfigurationResponse {
config: DynmapServerConfig,
messages: DynmapMessageConfig,
messages: LiveAtlasMessageConfig,
worlds: Array<DynmapWorld>,
components: DynmapComponentConfig,
loggedIn: boolean,

19
src/index.d.ts vendored
View File

@ -28,3 +28,22 @@ interface LiveAtlasDynmapServerDefinition extends LiveAtlasServerDefinition {
type: 'dynmap',
dynmap: DynmapUrlConfig,
}
interface LiveAtlasMessageConfig {
chatPlayerJoin: string;
chatPlayerQuit: string;
chatAnonymousJoin: string;
chatAnonymousQuit: string;
chatNoMessages: string;
chatLogin: string;
chatLoginLink: string;
chatSend: string;
chatErrorNotAllowed: string;
chatErrorRequiresLogin: string;
chatErrorCooldown: string;
chatErrorDisabled: string;
chatErrorUnknown: string;
headingServers: string;
headingWorlds: string;
headingPlayers: string;
}

View File

@ -25,14 +25,13 @@ import {
DynmapMarker,
DynmapMarkerSet,
DynmapMarkerSetUpdates,
DynmapMessageConfig,
DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate,
DynmapWorld,
DynmapWorldState, DynmapParsedUrl, DynmapChat, DynmapUIElement
} from "@/dynmap";
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
import {LiveAtlasServerDefinition} from "@/index";
import {LiveAtlasMessageConfig, LiveAtlasServerDefinition} from "@/index";
export type CurrentMapPayload = {
worldName: string;
@ -44,7 +43,7 @@ export type Mutations<S = State> = {
[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: DynmapMessageConfig): void
[MutationTypes.SET_MESSAGES](state: S, messages: LiveAtlasMessageConfig): void
[MutationTypes.SET_WORLDS](state: S, worlds: Array<DynmapWorld>): void
[MutationTypes.CLEAR_WORLDS](state: S): void
[MutationTypes.SET_COMPONENTS](state: S, worlds: DynmapComponentConfig): void
@ -114,7 +113,7 @@ export const mutations: MutationTree<State> & Mutations = {
},
//Set messsages from the initial config fetch
[MutationTypes.SET_MESSAGES](state: State, messages: DynmapMessageConfig) {
[MutationTypes.SET_MESSAGES](state: State, messages: LiveAtlasMessageConfig) {
state.messages = Object.assign(state.messages, messages);
},

View File

@ -17,20 +17,19 @@
import {
DynmapComponentConfig,
DynmapWorldMap, DynmapMarkerSet, DynmapMarkerSetUpdates,
DynmapMessageConfig,
DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate,
DynmapWorld, DynmapWorldState, Coordinate, DynmapParsedUrl, DynmapChat, DynmapUIElement
} from "@/dynmap";
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
import {LiveAtlasServerDefinition} from "@/index";
import {LiveAtlasMessageConfig, LiveAtlasServerDefinition} from "@/index";
export type State = {
version: string;
servers: Map<string, LiveAtlasServerDefinition>;
configuration: DynmapServerConfig;
configurationHash: number | undefined;
messages: DynmapMessageConfig;
messages: LiveAtlasMessageConfig;
components: DynmapComponentConfig;
loggedIn: boolean;
@ -94,15 +93,20 @@ export const state: State = {
configurationHash: undefined,
messages: {
chatNotAllowed: '',
chatRequiresLogin: '',
chatCooldown: '',
mapTypes: '',
players: '',
playerJoin: '',
playerQuit: '',
anonymousJoin: '',
anonymousQuit: '',
chatPlayerJoin: '',
chatPlayerQuit: '',
chatAnonymousJoin: '',
chatAnonymousQuit: '',
chatNoMessages: '',
chatLogin: '',
chatErrorNotAllowed: '',
chatErrorCooldown: '',
chatErrorRequiresLogin: '',
chatErrorDisabled: '',
chatErrorUnknown: '',
headingWorlds: '',
headingPlayers: '',
headingServers: '',
},
loggedIn: false,