Make LiveAtlas messages translatable

This commit is contained in:
James Lyne 2021-05-20 16:39:41 +01:00
parent 131e1dd685
commit fcf124c9ef
16 changed files with 177 additions and 95 deletions

View File

@ -28,66 +28,84 @@
window.liveAtlasConfig = { window.liveAtlasConfig = {
// Server URLS can be defined here instead of using the standalone/config.js file. // Server URLS can be defined here instead of using the standalone/config.js file.
// Multiple servers are supported, see https://github.com/JLyne/LiveAtlas/wiki/Configuring-Multiple-Servers. // Multiple servers are supported, see https://github.com/JLyne/LiveAtlas/wiki/Configuring-Multiple-Servers.
servers: { // servers: {
creative: { // creative: {
label: 'Creative', // label: 'Creative',
dynmap: { // dynmap: {
configuration: 'http://dynmap.local/creative/MySQL_configuration.php', // configuration: 'http://dynmap.local/creative/MySQL_configuration.php',
update: 'http://dynmap.local/creative/MySQL_update.php?world={world}&ts={timestamp}', // update: 'http://dynmap.local/creative/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/creative/MySQL_sendmessage.php', // sendmessage: 'http://dynmap.local/creative/MySQL_sendmessage.php',
login: 'http://dynmap.local/creative/MySQL_login.php', // login: 'http://dynmap.local/creative/MySQL_login.php',
register: 'http://dynmap.local/creative/MySQL_register.php', // register: 'http://dynmap.local/creative/MySQL_register.php',
tiles: 'http://dynmap.local/creative/MySQL_tiles.php?tile=', // tiles: 'http://dynmap.local/creative/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/creative/MySQL_markers.php?marker=' // markers: 'http://dynmap.local/creative/MySQL_markers.php?marker='
} // }
}, // },
survival: { // survival: {
label: 'Survival', // label: 'Survival',
dynmap: { // dynmap: {
configuration: 'http://dynmap.local/survival/MySQL_configuration.php', // configuration: 'http://dynmap.local/survival/MySQL_configuration.php',
update: 'http://dynmap.local/survival/MySQL_update.php?world={world}&ts={timestamp}', // update: 'http://dynmap.local/survival/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/survival/MySQL_sendmessage.php', // sendmessage: 'http://dynmap.local/survival/MySQL_sendmessage.php',
login: 'http://dynmap.local/survival/MySQL_login.php', // login: 'http://dynmap.local/survival/MySQL_login.php',
register: 'http://dynmap.local/survival/MySQL_register.php', // register: 'http://dynmap.local/survival/MySQL_register.php',
tiles: 'http://dynmap.local/survival/MySQL_tiles.php?tile=', // tiles: 'http://dynmap.local/survival/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/survival/MySQL_markers.php?marker=' // markers: 'http://dynmap.local/survival/MySQL_markers.php?marker='
} // }
}, // },
build: { // build: {
label: 'Build', // label: 'Build',
dynmap: { // dynmap: {
configuration: 'http://dynmap.local/build/MySQL_configuration.php', // configuration: 'http://dynmap.local/build/MySQL_configuration.php',
update: 'http://dynmap.local/build/MySQL_update.php?world={world}&ts={timestamp}', // update: 'http://dynmap.local/build/MySQL_update.php?world={world}&ts={timestamp}',
sendmessage: 'http://dynmap.local/build/MySQL_sendmessage.php', // sendmessage: 'http://dynmap.local/build/MySQL_sendmessage.php',
login: 'http://dynmap.local/build/MySQL_login.php', // login: 'http://dynmap.local/build/MySQL_login.php',
register: 'http://dynmap.local/build/MySQL_register.php', // register: 'http://dynmap.local/build/MySQL_register.php',
tiles: 'http://dynmap.local/build/MySQL_tiles.php?tile=', // tiles: 'http://dynmap.local/build/MySQL_tiles.php?tile=',
markers: 'http://dynmap.local/build/MySQL_markers.php?marker=' // markers: 'http://dynmap.local/build/MySQL_markers.php?marker='
} // }
}, // },
test: { // test: {
label: 'Local Test', // label: 'Local Test',
url: '/map/test', // url: '/map/test',
dynmap: { // dynmap: {
configuration: 'http://dynmap.local:8123/up/configuration', // configuration: 'http://dynmap.local:8123/up/configuration',
update: 'http://dynmap.local:8123/up/world/{world}/{timestamp}', // update: 'http://dynmap.local:8123/up/world/{world}/{timestamp}',
sendmessage: 'http://dynmap.local:8123/up/sendmessage', // sendmessage: 'http://dynmap.local:8123/up/sendmessage',
login: 'http://dynmap.local:8123/up/login', // login: 'http://dynmap.local:8123/up/login',
register: 'http://dynmap.local:8123/up/register', // register: 'http://dynmap.local:8123/up/register',
tiles: 'http://dynmap.local:8123/tiles/', // tiles: 'http://dynmap.local:8123/tiles/',
markers: 'http://dynmap.local:8123/tiles/' // markers: 'http://dynmap.local:8123/tiles/'
} // }
}, // },
}, // },
// These messages are used throughout LiveAtlas and can be translated here
// If a message you want to translate isn't here, it is likely controlled by dynmap itself
// see https://github.com/webbukkit/dynmap/wiki/Configuration.txt
messages: { messages: {
headingServers: 'Servers',
chatNoMessages: 'No chat messages yet...', chatNoMessages: 'No chat messages yet...',
chatTitle: 'Chat',
chatLogin: 'Please {{link}} to send chat messages', chatLogin: 'Please {{link}} to send chat messages',
chatLoginLink: 'login', chatLoginLink: 'login',
chatSend: 'Send', chatSend: 'Send',
chatPlaceholder: 'Type your chat message here...',
chatErrorUnknown: 'Unexpected error while sending chat message', chatErrorUnknown: 'Unexpected error while sending chat message',
chatErrorDisabled: 'Chat is not enabled', chatErrorDisabled: 'Chat is not enabled',
serversHeading: 'Servers',
worldsSkeleton: 'No maps have been configured',
playersSkeleton: 'No players are currently online',
playersTitle: 'Click to center on player\nDouble-click to follow player',
playersTitleHidden: 'This player is currently hidden from the map\nDouble-click to follow player when they become visible',
playersTitleOtherWorld: 'This player is in another world.\nClick to center on player\nDouble-click to follow player',
followingHeading: 'Following',
followingUnfollow: 'Unfollow',
followingTitleUnfollow: 'Stop following this player',
followingHidden: 'Currently hidden',
linkTitle: 'Copy link to current location',
loadingTitle: 'Loading...',
locationRegion: 'Region',
locationChunk: 'Chunk',
} }
}; };
</script> </script>

View File

@ -66,18 +66,33 @@ function buildMessagesConfig(response: any): LiveAtlasMessageConfig {
chatPlayerQuit: response.quitmessage || '', chatPlayerQuit: response.quitmessage || '',
chatAnonymousJoin: response['msg-hiddennamejoin'] || '', chatAnonymousJoin: response['msg-hiddennamejoin'] || '',
chatAnonymousQuit: response['msg-hiddennamequit'] || '', chatAnonymousQuit: response['msg-hiddennamequit'] || '',
chatTitle: liveAtlasMessages.chatTitle || '',
chatLogin: liveAtlasMessages.chatLogin || '', chatLogin: liveAtlasMessages.chatLogin || '',
chatLoginLink: liveAtlasMessages.chatLoginLink || '', chatLoginLink: liveAtlasMessages.chatLoginLink || '',
chatNoMessages: liveAtlasMessages.chatNoMessages || '', chatNoMessages: liveAtlasMessages.chatNoMessages || '',
chatSend: liveAtlasMessages.chatSend || '', chatSend: liveAtlasMessages.chatSend || '',
chatPlaceholder: liveAtlasMessages.chatPlaceholder || '',
chatErrorNotAllowed: response['msg-chatnotallowed'] || '', chatErrorNotAllowed: response['msg-chatnotallowed'] || '',
chatErrorRequiresLogin: response['msg-chatrequireslogin'] || '', chatErrorRequiresLogin: response['msg-chatrequireslogin'] || '',
chatErrorCooldown: response.spammessage || '', chatErrorCooldown: response.spammessage || '',
chatErrorDisabled: liveAtlasMessages.chatErrorDisabled || '', chatErrorDisabled: liveAtlasMessages.chatErrorDisabled || '',
chatErrorUnknown: liveAtlasMessages.chatErrorUnknown || '', chatErrorUnknown: liveAtlasMessages.chatErrorUnknown || '',
headingWorlds: response['msg-maptypes'] || '', serversHeading: liveAtlasMessages.serversHeading || '',
headingPlayers: response['msg-players'] || '', worldsHeading: response['msg-maptypes'] || '',
headingServers: liveAtlasMessages.headingServers || '', 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 || '',
} }
} }

View File

@ -23,7 +23,7 @@
<form v-if="sendingEnabled" class="chat__form" @submit.prevent="sendMessage"> <form v-if="sendingEnabled" class="chat__form" @submit.prevent="sendMessage">
<div v-if="sendingError" class="chat__error">{{ sendingError }}</div> <div v-if="sendingError" class="chat__error">{{ sendingError }}</div>
<input ref="chatInput" v-model="enteredMessage" class="chat__input" type="text" :maxlength="maxMessageLength" <input ref="chatInput" v-model="enteredMessage" class="chat__input" type="text" :maxlength="maxMessageLength"
placeholder="Type your chat message here..." :disabled="sendingMessage"> :placeholder="messagePlaceholder" :disabled="sendingMessage">
<button class="chat__send" :disabled="!enteredMessage || sendingMessage">{{ messageSend }}</button> <button class="chat__send" :disabled="!enteredMessage || sendingMessage">{{ messageSend }}</button>
</form> </form>
<div v-if="loginRequired" class="chat__login" v-html="messageLogin"></div> <div v-if="loginRequired" class="chat__login" v-html="messageLogin"></div>
@ -67,9 +67,10 @@
}), }),
messageSend = computed(() => store.state.messages.chatSend), messageSend = computed(() => store.state.messages.chatSend),
messagePlaceholder = computed(() => store.state.messages.chatPlaceholder),
messageNoMessages = computed(() => store.state.messages.chatNoMessages), messageNoMessages = computed(() => store.state.messages.chatNoMessages),
messageLogin = computed(() => store.state.messages.chatLogin.replace( messageLogin = computed(() => store.state.messages.chatLogin.replace(
'{{link}}', store.state.messages.chatLoginLink)), '{{link}}', `<a href="login.html">${store.state.messages.chatLoginLink}</a>`)),
sendMessage = async () => { sendMessage = async () => {
const message = enteredMessage.value.trim().substring(0, maxMessageLength.value); const message = enteredMessage.value.trim().substring(0, maxMessageLength.value);
@ -117,6 +118,7 @@
messageLogin, messageLogin,
messageSend, messageSend,
messageNoMessages, messageNoMessages,
messagePlaceholder,
} }
} }
}) })

View File

@ -18,17 +18,13 @@
<aside class="sidebar"> <aside class="sidebar">
<header class="sidebar__buttons"> <header class="sidebar__buttons">
<button v-if="mapCount > 1" :class="{'button--maps': true, 'active':currentlyVisible.has('maps')}" <button v-if="mapCount > 1" :class="{'button--maps': true, 'active':currentlyVisible.has('maps')}"
@click="toggleElement('maps')" title="Map list" aria-label="Map list"> @click="toggleElement('maps')" :title="messageWorlds" :aria-label="messageWorlds">
<SvgIcon name="maps"></SvgIcon> <SvgIcon name="maps"></SvgIcon>
</button> </button>
<button :class="{'button--players': true, 'active': currentlyVisible.has('players')}" <button :class="{'button--players': true, 'active': currentlyVisible.has('players')}"
@click="toggleElement('players')" title="Player list" aria-label="Player list"> @click="toggleElement('players')" :title="messagePlayers" :aria-label="messagePlayers">
<SvgIcon name="players"></SvgIcon> <SvgIcon name="players"></SvgIcon>
</button> </button>
<!-- <button :class="{'button&#45;&#45;settings': true, 'active': currentlyVisible.has('settings'))}"-->
<!-- @click="toggleElement('settings')" title="Settings" aria-label="Settings">-->
<!-- <SvgIcon name="settings"></SvgIcon>-->
<!-- </button>-->
</header> </header>
<ServerList v-if="serverCount > 1" v-show="currentlyVisible.has('maps')"></ServerList> <ServerList v-if="serverCount > 1" v-show="currentlyVisible.has('maps')"></ServerList>
<WorldList v-if="mapCount > 1" v-show="currentlyVisible.has('maps')"></WorldList> <WorldList v-if="mapCount > 1" v-show="currentlyVisible.has('maps')"></WorldList>
@ -68,6 +64,9 @@ export default defineComponent({
serverCount = computed(() => store.state.servers.size), serverCount = computed(() => store.state.servers.size),
following = computed(() => store.state.followTarget), following = computed(() => store.state.followTarget),
messageWorlds = computed(() => store.state.messages.worldsHeading),
messagePlayers = computed(() => store.state.messages.playersHeading),
toggleElement = (element: DynmapUIElement) => { toggleElement = (element: DynmapUIElement) => {
store.commit(MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY, element); store.commit(MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY, element);
}, },
@ -86,6 +85,8 @@ export default defineComponent({
toggleElement, toggleElement,
followActive, followActive,
following, following,
messageWorlds,
messagePlayers,
} }
} }
}) })

View File

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

View File

@ -16,17 +16,17 @@
<template> <template>
<section class="sidebar__section following"> <section class="sidebar__section following">
<h2>Following</h2> <h2>{{ heading }}</h2>
<div :class="{'following__target': true, 'following__target--hidden': target.hidden}"> <div :class="{'following__target': true, 'following__target--hidden': target.hidden}">
<img width="32" height="32" class="target__icon" :src="image" alt="" /> <img width="32" height="32" class="target__icon" :src="image" alt="" />
<span class="target__info"> <span class="target__info">
<span class="target__name" v-html="target.name"></span> <span class="target__name" v-html="target.name"></span>
<span class="target__status" v-show="target.hidden">Currently hidden</span> <span class="target__status" v-show="target.hidden">{{ messageHidden }}</span>
</span> </span>
<button class="target__unfollow" type="button" :title="`Stop following this player`" <button class="target__unfollow" type="button" :title="messageUnfollowTitle"
@click.prevent="unfollow" @click.prevent="unfollow"
@keydown="onKeydown">Unfollow</button> @keydown="onKeydown">{{ messageUnfollow }}</button>
</div> </div>
</section> </section>
</template> </template>
@ -35,7 +35,7 @@
import {DynmapPlayer} from "@/dynmap"; import {DynmapPlayer} from "@/dynmap";
import {useStore} from "@/store"; import {useStore} from "@/store";
import {MutationTypes} from "@/store/mutation-types"; import {MutationTypes} from "@/store/mutation-types";
import {defineComponent, onMounted, ref, watch} from "@vue/runtime-core"; import {computed, defineComponent, onMounted, ref, watch} from "@vue/runtime-core";
import {getMinecraftHead} from '@/util'; import {getMinecraftHead} from '@/util';
import defaultImage from '@/assets/images/player_face.png'; import defaultImage from '@/assets/images/player_face.png';
@ -52,6 +52,11 @@ export default defineComponent({
image = ref(defaultImage), image = ref(defaultImage),
account = ref(props.target.account), account = ref(props.target.account),
heading = computed(() => store.state.messages.followingHeading),
messageUnfollow = computed(() => store.state.messages.followingUnfollow),
messageUnfollowTitle = computed(() => store.state.messages.followingTitleUnfollow),
messageHidden = computed(() => store.state.messages.followingHidden),
unfollow = () => { unfollow = () => {
useStore().commit(MutationTypes.CLEAR_FOLLOW_TARGET, undefined); useStore().commit(MutationTypes.CLEAR_FOLLOW_TARGET, undefined);
}, },
@ -79,7 +84,11 @@ export default defineComponent({
return { return {
image, image,
onKeydown, onKeydown,
unfollow unfollow,
heading,
messageUnfollow,
messageUnfollowTitle,
messageHidden,
} }
}, },
}); });

View File

@ -19,9 +19,7 @@
<span class="section__heading">{{ heading }} [{{ players.size }}/{{ maxPlayers }}]</span> <span class="section__heading">{{ heading }} [{{ players.size }}/{{ maxPlayers }}]</span>
<ul class="section__content"> <ul class="section__content">
<PlayerListItem v-for="[account, player] in players" :key="account" :player="player"></PlayerListItem> <PlayerListItem v-for="[account, player] in players" :key="account" :player="player"></PlayerListItem>
<li v-if="!players.size" class="section__skeleton"> <li v-if="!players.size" class="section__skeleton">{{ skeletonPlayers }}</li>
No players are currently online
</li>
</ul> </ul>
</section> </section>
</template> </template>
@ -38,7 +36,11 @@ export default defineComponent({
computed: { computed: {
heading() { heading() {
return useStore().state.messages.headingPlayers; return useStore().state.messages.playersHeading;
},
skeletonPlayers() {
return useStore().state.messages.playersSkeleton;
}, },
players() { players() {

View File

@ -50,11 +50,11 @@ export default defineComponent({
title = computed(() => { title = computed(() => {
if(props.player.hidden) { if(props.player.hidden) {
return 'This player is currently hidden from the map\nDouble-click to follow player when they become visible'; return store.state.messages.playersTitleHidden;
} else if(otherWorld.value) { } else if(otherWorld.value) {
return 'This player is in another world.\nClick to center on player\nDouble-click to follow player'; return store.state.messages.playersTitleOtherWorld;
} else { } else {
return 'Click to center on player\nDouble-click to follow player'; return store.state.messages.playersTitle;
} }
}), }),

View File

@ -36,7 +36,7 @@ export default defineComponent({
computed: { computed: {
heading() { heading() {
return useStore().state.messages.headingServers; return useStore().state.messages.serversHeading;
}, },
servers() { servers() {

View File

@ -19,9 +19,7 @@
<span class="section__heading">{{ heading }}</span> <span class="section__heading">{{ heading }}</span>
<ul class="section__content"> <ul class="section__content">
<WorldListItem :world="world" v-for="[name, world] in worlds" :key="name"></WorldListItem> <WorldListItem :world="world" v-for="[name, world] in worlds" :key="name"></WorldListItem>
<li v-if="!worlds.size" class="section__skeleton"> <li v-if="!worlds.size" class="section__skeleton">{{ skeletonWorlds }}</li>
No maps have been configured
</li>
</ul> </ul>
</section> </section>
</template> </template>
@ -39,7 +37,11 @@ export default defineComponent({
computed: { computed: {
heading() { heading() {
return useStore().state.messages.headingWorlds; return useStore().state.messages.worldsHeading;
},
skeletonWorlds() {
return useStore().state.messages.worldsSkeleton;
}, },
worlds() { worlds() {

21
src/index.d.ts vendored
View File

@ -35,15 +35,30 @@ interface LiveAtlasMessageConfig {
chatAnonymousJoin: string; chatAnonymousJoin: string;
chatAnonymousQuit: string; chatAnonymousQuit: string;
chatNoMessages: string; chatNoMessages: string;
chatTitle: string;
chatLogin: string; chatLogin: string;
chatLoginLink: string; chatLoginLink: string;
chatSend: string; chatSend: string;
chatPlaceholder: string;
chatErrorNotAllowed: string; chatErrorNotAllowed: string;
chatErrorRequiresLogin: string; chatErrorRequiresLogin: string;
chatErrorCooldown: string; chatErrorCooldown: string;
chatErrorDisabled: string; chatErrorDisabled: string;
chatErrorUnknown: string; chatErrorUnknown: string;
headingServers: string; serversHeading: string;
headingWorlds: string; worldsHeading: string;
headingPlayers: string; worldsSkeleton: string;
playersSkeleton: string;
playersHeading: string;
playersTitle: string;
playersTitleHidden: string;
playersTitleOtherWorld: string;
followingHeading: string;
followingUnfollow: string;
followingTitleUnfollow: string;
followingHidden: string;
linkTitle: string;
loadingTitle: string;
locationRegion: string;
locationChunk: string;
} }

View File

@ -33,7 +33,7 @@ export class ChatControl extends Control {
const chatButton = DomUtil.create('button', 'leaflet-control-chat') as HTMLButtonElement; const chatButton = DomUtil.create('button', 'leaflet-control-chat') as HTMLButtonElement;
chatButton.type = 'button'; chatButton.type = 'button';
chatButton.title = 'Chat'; chatButton.title = useStore().state.messages.chatTitle;
chatButton.innerHTML = ` chatButton.innerHTML = `
<svg class="svg-icon"> <svg class="svg-icon">
<use xlink:href="#chat" /> <use xlink:href="#chat" />

View File

@ -61,13 +61,13 @@ export class CoordinatesControl extends Control {
if (this.options.showRegion) { if (this.options.showRegion) {
this._regionContainer.textContent = '--------------'; this._regionContainer.textContent = '--------------';
this._regionContainer.dataset.label = 'Region'; this._regionContainer.dataset.label = useStore().state.messages.locationRegion;
container.appendChild(this._regionContainer); container.appendChild(this._regionContainer);
} }
if (this.options.showChunk) { if (this.options.showChunk) {
this._chunkContainer.textContent = '----, ----'; this._chunkContainer.textContent = '----, ----';
this._chunkContainer.dataset.label = 'Chunk'; this._chunkContainer.dataset.label = useStore().state.messages.locationChunk;
container.appendChild(this._chunkContainer); container.appendChild(this._chunkContainer);
} }

View File

@ -36,7 +36,7 @@ export class LinkControl extends Control {
const linkButton = DomUtil.create('button', 'leaflet-control-link') as HTMLButtonElement; const linkButton = DomUtil.create('button', 'leaflet-control-link') as HTMLButtonElement;
linkButton.type = 'button'; linkButton.type = 'button';
linkButton.title = 'Copy link to current location'; linkButton.title = useStore().state.messages.linkTitle;
linkButton.innerHTML = ` linkButton.innerHTML = `
<svg class="svg-icon" aria-hidden="true"> <svg class="svg-icon" aria-hidden="true">
<use xlink:href="#link" /> <use xlink:href="#link" />

View File

@ -31,6 +31,7 @@ import {
Map, TileLayer, Map, TileLayer,
} from 'leaflet'; } from 'leaflet';
import '@/assets/icons/loading.svg'; import '@/assets/icons/loading.svg';
import {useStore} from "@/store";
export interface LoadingControlOptions extends ControlOptions { export interface LoadingControlOptions extends ControlOptions {
delayIndicator?: number; delayIndicator?: number;
@ -51,7 +52,7 @@ export class LoadingControl extends Control {
} }
onAdd(map: Map) { onAdd(map: Map) {
this._loadingIndicator.title = 'Loading...'; this._loadingIndicator.title = useStore().state.messages.loadingTitle;
this._loadingIndicator.hidden = true; this._loadingIndicator.hidden = true;
this._loadingIndicator.innerHTML = ` this._loadingIndicator.innerHTML = `
<svg class="svg-icon"> <svg class="svg-icon">

View File

@ -98,15 +98,32 @@ export const state: State = {
chatAnonymousJoin: '', chatAnonymousJoin: '',
chatAnonymousQuit: '', chatAnonymousQuit: '',
chatNoMessages: '', chatNoMessages: '',
chatTitle: '',
chatLogin: '', chatLogin: '',
chatLoginLink: '',
chatSend: '',
chatPlaceholder: '',
chatErrorNotAllowed: '', chatErrorNotAllowed: '',
chatErrorCooldown: '',
chatErrorRequiresLogin: '', chatErrorRequiresLogin: '',
chatErrorCooldown: '',
chatErrorDisabled: '', chatErrorDisabled: '',
chatErrorUnknown: '', chatErrorUnknown: '',
headingWorlds: '', serversHeading: '',
headingPlayers: '', worldsHeading: '',
headingServers: '', worldsSkeleton: '',
playersSkeleton: '',
playersHeading: '',
playersTitle: '',
playersTitleHidden: '',
playersTitleOtherWorld: '',
followingHeading: '',
followingUnfollow: '',
followingTitleUnfollow: '',
followingHidden: '',
linkTitle: '',
loadingTitle: '',
locationRegion: '',
locationChunk: '',
}, },
loggedIn: false, loggedIn: false,