locale support

This commit is contained in:
BinarySandia04 2024-09-22 23:57:15 +02:00
parent 58c04ec3b9
commit 85b8f8cc69
16 changed files with 24984 additions and 24811 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,54 @@
{ {
"main-menu": "Menú Principal" "general": {
"create": "Create",
"join": "Join",
"view": "View",
"players": "Jugadores"
},
"main-menu": {
"title": "Dragonroll",
"main-menu": "Main Menu",
"campaigns": "Campaigns",
"cosmic-compendium": "The Cosmic Compendium",
"book-anvil": "Book Anvil",
"edit-profile": "Edit Profile",
"settings": "Settings",
"log-out": "Log Out"
},
"settings": {
"title": "Dragonroll settings",
"account": {
"account-settings": "Account Settings",
"language": "Language:"
},
"site-administration": {}
},
"campaigns": {
"title": "Campaigns",
"your-campaigns": "Your Campaigns",
"other-campaigns": "Other Campaigns",
"create": {
"title": "Create Campaign",
"enter": "Enter campaign name..."
},
"join": {
"title": "Join Campaign",
"enter": "Enter campaign code...",
"success": "Successfully joined the campaign!",
"already": "You are already in that campaign!",
"error": "Error joining this campaign, check if the code is correct"
},
"preview": {
"title": "Campaign preview",
"copy-code": "Copy invite code",
"copy-explain": "Click this button to copy the invite code of your campaign to the clipboard",
"copy-success": "Copied invite code successfully!",
"launch-game": "Launch game",
"exit-game": "Exit game"
}
},
"systems": {
"title": "Select a game system",
"not-selected": "No game system selected"
}
} }

View File

@ -1,5 +1,12 @@
{ {
"general": {
"create": "Create",
"join": "Join",
"view": "View",
"players": "Jugadores"
},
"main-menu": { "main-menu": {
"title": "Dragonroll",
"main-menu": "Main Menu", "main-menu": "Main Menu",
"campaigns": "Campaigns", "campaigns": "Campaigns",
"cosmic-compendium": "The Cosmic Compendium", "cosmic-compendium": "The Cosmic Compendium",
@ -7,5 +14,44 @@
"edit-profile": "Edit Profile", "edit-profile": "Edit Profile",
"settings": "Settings", "settings": "Settings",
"log-out": "Log Out" "log-out": "Log Out"
},
"settings": {
"title": "Dragonroll settings",
"account": {
"account-settings": "Account Settings",
"language": "Language:"
},
"site-administration": {
}
},
"campaigns": {
"title": "Campaigns",
"your-campaigns": "Your Campaigns",
"other-campaigns": "Other Campaigns",
"create": {
"title": "Create Campaign",
"enter": "Enter campaign name..."
},
"join": {
"title": "Join Campaign",
"enter": "Enter campaign code...",
"success": "Successfully joined the campaign!",
"already": "You are already in that campaign!",
"error": "Error joining this campaign, check if the code is correct"
},
"preview": {
"title": "Campaign preview",
"copy-code": "Copy invite code",
"copy-explain": "Click this button to copy the invite code of your campaign to the clipboard",
"copy-success": "Copied invite code successfully!",
"launch-game": "Launch game",
"exit-game": "Exit game"
}
},
"systems": {
"title": "Select a game system",
"not-selected": "No game system selected"
} }
} }

View File

@ -1,11 +1,54 @@
{ {
"main-menu": { "general": {
"main-menu": "Menú Principal", "create": "Crear",
"campaigns": "Campañas", "join": "Entrar",
"cosmic-compendium": "La Libreria Cósmica", "view": "Abrir",
"book-anvil": "Forjador de Libros", "players": "Jugadores"
"edit-profile": "Editar Perfil", },
"settings": "Ajustes", "main-menu": {
"log-out": "Cerrar sesión" "title": "Dragonroll",
"main-menu": "Menú Principal",
"campaigns": "Campañas",
"cosmic-compendium": "La librería cósmica",
"book-anvil": "Forjador de libros",
"edit-profile": "Editar perfil",
"settings": "Ajustes",
"log-out": "Cerrar sesión"
},
"settings": {
"title": "Ajustes de Dragonroll",
"account": {
"account-settings": "Ajustes de la cuenta",
"language": "Idioma:"
},
"site-administration": {}
},
"campaigns": {
"title": "Campañas",
"your-campaigns": "Tus campañas",
"other-campaigns": "Otras campañas",
"create": {
"title": "Crear campaña",
"enter": "Introduce el nombre de la campaña..."
},
"join": {
"title": "Entrar en la campaña",
"enter": "Introduce el código de la campaña...",
"success": "Has entrado en la campaña correctamente!",
"already": "Ya estás dentro de esta campaña!",
"error": "Ha habido un error al entrar en esta campaña, acaso el código existe?"
},
"preview": {
"title": "Previsualización de la campaña",
"copy-code": "Copiar codigo",
"copy-explain": "Haz clic en este botón para copiar el código de invitación a tu cortapapeles",
"copy-success": "Se ha copiado el código correctamente!",
"launch-game": "Abrir juego",
"exit-game": "Cerrar juego"
} }
},
"systems": {
"title": "Selecciona un sistema de juego",
"not-selected": "Ningún sistema de juego seleccionado"
}
} }

View File

@ -38,7 +38,9 @@ function SetUserSetting(key, value){
function GetUserSetting(key){ function GetUserSetting(key){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Api().get('/user/get-settings').then(response => { Api().get('/user/get-settings').then(response => {
resolve(response.data.settings[key]); if(response.data.settings)
resolve(response.data.settings[key]);
else resolve(undefined);
}); });
}); });
} }

View File

@ -20,7 +20,7 @@ const defValues = {
}, },
'main_menu': { 'main_menu': {
id: 'main_menu', id: 'main_menu',
title: "DragonRoll", title: 'main-menu.title',
create: () => { create: () => {
// CreateChildWindow('main_menu', 'welcome'); // CreateChildWindow('main_menu', 'welcome');
} }
@ -37,12 +37,12 @@ const defValues = {
}, },
'settings': { 'settings': {
id: 'settings', id: 'settings',
title: "Dragonroll settings", title: 'settings.title',
close: () => ClearWindow('settings') close: () => ClearWindow('settings')
}, },
'campaign_list': { 'campaign_list': {
id: 'campaign_list', id: 'campaign_list',
title: 'Campaigns', title: 'campaigns.title',
back: () => { back: () => {
ClearWindow('campaign_list'); ClearWindow('campaign_list');
CreateWindow('main_menu'); CreateWindow('main_menu');
@ -50,19 +50,19 @@ const defValues = {
}, },
'new_campaign': { 'new_campaign': {
id: 'new_campaign', id: 'new_campaign',
title: 'Create campaign', title: 'campaigns.create.title',
parent: 'campaign_list', parent: 'campaign_list',
close: () => ClearWindow('new_campaign') close: () => ClearWindow('new_campaign')
}, },
'join_campaign': { 'join_campaign': {
id: 'join_campaign', id: 'join_campaign',
title: 'Join campaign', title: 'campaigns.join.title',
parent: 'campaign_list', parent: 'campaign_list',
close: () => ClearWindow('join_campaign') close: () => ClearWindow('join_campaign')
}, },
'campaign_preview': { 'campaign_preview': {
id: 'campaign_preview', id: 'campaign_preview',
title: "Campaign Preview", title: "campaigns.preview.title",
back: () => { back: () => {
Disconnect(); Disconnect();
ClearWindow('campaign_preview'); ClearWindow('campaign_preview');
@ -91,7 +91,7 @@ const defValues = {
}, },
'system_selector': { 'system_selector': {
id: 'system-selector', id: 'system-selector',
title: "Select a game system", title: 'systems.title',
close: () => ClearWindow('system-selector') close: () => ClearWindow('system-selector')
}, },
'map_window': { 'map_window': {

View File

@ -37,7 +37,7 @@ function ViewCampaign(){
</div> </div>
<div class="campaign-user-actions"> <div class="campaign-user-actions">
<button class="btn-primary button-small sound-click" v-on:click.prevent="ViewCampaign">View</button> <button class="btn-primary button-small sound-click" v-on:click.prevent="ViewCampaign">{{ $t('general.view')}}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -33,7 +33,7 @@ watch(selectedSystem, () => {
<template> <template>
<div class="system-selector" v-on:click="DisplaySystemSelector"> <div class="system-selector" v-on:click="DisplaySystemSelector">
<span v-show="selectedSystem == ''" class="none">No game system selected</span> <span v-show="selectedSystem == ''" class="none">{{ $t('systems.not-selected') }}</span>
<div v-show="selectedSystem != ''" class="yes"> <div v-show="selectedSystem != ''" class="yes">
<img ref="selectedImage" class="system-icon"> <img ref="selectedImage" class="system-icon">
{{ systemTitle }} {{ systemTitle }}

View File

@ -76,7 +76,7 @@ defineExpose({
<img class="icon icon-add-margin" src="/icons/iconoir/regular/arrow-left.svg" draggable="false" ref="backButton" v-if="hasBack" v-on:click="backFunction"> <img class="icon icon-add-margin" src="/icons/iconoir/regular/arrow-left.svg" draggable="false" ref="backButton" v-if="hasBack" v-on:click="backFunction">
</div> </div>
<div class="center" v-if="def"> <div class="center" v-if="def">
<span>{{ title }}</span> <span>{{ $t(title) }}</span>
</div> </div>
<div class="right"> <div class="right">
<img class="icon" src="/icons/iconoir/regular/xmark.svg" draggable="false" ref="closeButton" v-if="close" v-on:click="CloseButton"> <img class="icon" src="/icons/iconoir/regular/xmark.svg" draggable="false" ref="closeButton" v-if="close" v-on:click="CloseButton">

View File

@ -60,7 +60,7 @@ async function OnLanguageChange(value){
<template #account-settings> <template #account-settings>
<div class="form-container"> <div class="form-container">
<div class="form-element"> <div class="form-element">
<label>Language: </label> <label>{{ $t('settings.account.language') }}</label>
<Dropdown :options="languageOptions" :onselect="OnLanguageChange" :selected="currentLanguage"></Dropdown> <Dropdown :options="languageOptions" :onselect="OnLanguageChange" :selected="currentLanguage"></Dropdown>
</div> </div>
</div> </div>

View File

@ -59,7 +59,7 @@ function RefreshCampaigns(){
<!-- Body --> <!-- Body -->
<div class="campaign-list-container"> <div class="campaign-list-container">
<div class="window-second-header"> <div class="window-second-header">
<h2 class="centered">Your campaigns</h2> <h2 class="centered">{{ $t("campaigns.your-campaigns")}}</h2>
<div class="campaign-list"> <div class="campaign-list">
<CampaignEntry v-for="camp in myCampaigns" :key="camp._id" :data="camp"></CampaignEntry> <CampaignEntry v-for="camp in myCampaigns" :key="camp._id" :data="camp"></CampaignEntry>
@ -67,7 +67,7 @@ function RefreshCampaigns(){
</div> </div>
<div class="window-second-header"> <div class="window-second-header">
<h2 class="centered">Other campaigns</h2> <h2 class="centered">{{ $t("campaigns.other-campaigns")}}</h2>
<div class="campaign-list"> <div class="campaign-list">
<CampaignEntry v-for="camp in otherCampaigns" :key="camp._id" :data="camp"></CampaignEntry> <CampaignEntry v-for="camp in otherCampaigns" :key="camp._id" :data="camp"></CampaignEntry>
</div> </div>
@ -76,8 +76,8 @@ function RefreshCampaigns(){
</div> </div>
<div class="buttons-row"> <div class="buttons-row">
<button class="btn-primary button-row sound-click" v-on:click.prevent="CreateCampaign">Create campaign</button> <button class="btn-primary button-row sound-click" v-on:click.prevent="CreateCampaign">{{ $t("campaigns.create.title")}}</button>
<button class="btn-primary button-row sound-click" v-on:click.prevent="JoinCampaign">Join campaign</button> <button class="btn-primary button-row sound-click" v-on:click.prevent="JoinCampaign">{{ $t("campaigns.join.title")}}</button>
</div> </div>
</div> </div>

View File

@ -15,6 +15,9 @@ import { GetModule } from '../../../services/Modules';
import { AddTooltip } from '../../../services/Tooltip'; import { AddTooltip } from '../../../services/Tooltip';
import { Disconnect } from '../../../services/Campaign'; import { Disconnect } from '../../../services/Campaign';
import { useI18n } from 'vue-i18n';
const {t} = useI18n();
const handle = ref(null); const handle = ref(null);
const props = defineProps(['data']); const props = defineProps(['data']);
@ -45,12 +48,12 @@ onMounted(() => {
campaign_title.value.style.backgroundColor = GetModule(data.campaign.system).color ? GetModule(data.campaign.system).color : "#1f1f1f"; campaign_title.value.style.backgroundColor = GetModule(data.campaign.system).color ? GetModule(data.campaign.system).color : "#1f1f1f";
AddTooltip(copy_code_button.value, "<p>Click this button to copy the invite code of your campaign to the clipboard</p>", {max_width: 300}) AddTooltip(copy_code_button.value, `<p>${t('campaigns.preview.copy-explain')}</p>`, {max_width: 300})
}); });
function CopyCode(){ function CopyCode(){
navigator.clipboard.writeText(GetCampaign().invite_code); navigator.clipboard.writeText(GetCampaign().invite_code);
DisplayToast('aqua', "Copied invite code successfully!", 1000); DisplayToast('aqua', $t('campaigns.preview.copy-success'), 1000);
} }
function Launch(){ function Launch(){
@ -76,10 +79,10 @@ function Exit(){
<div class="campaign-preview-container" :class="hide_chat ? 'campaign-preview-compact' : ''" ref="container"> <div class="campaign-preview-container" :class="hide_chat ? 'campaign-preview-compact' : ''" ref="container">
<div class="campaign-preview-column left"> <div class="campaign-preview-column left">
<h2 class="centered">Players</h2> <h2 class="centered">{{$t('general.players')}}</h2>
<PlayerList :campaign="data.campaign"></PlayerList> <PlayerList :campaign="data.campaign"></PlayerList>
<div class="buttons-row"> <div class="buttons-row">
<button class="btn-primary button-row sound-click" v-on:click.prevent="CopyCode" ref="copy_code_button">Copy invite code</button> <button class="btn-primary button-row sound-click" v-on:click.prevent="CopyCode" ref="copy_code_button">{{$t('campaigns.preview.copy-code')}}</button>
</div> </div>
</div> </div>
<div class="campaign-preview-column center"> <div class="campaign-preview-column center">
@ -92,8 +95,8 @@ function Exit(){
</div> </div>
</div> </div>
<div class="buttons-row"> <div class="buttons-row">
<button class="btn-primary button-row sound-click btn-green" v-if="!hide_start" v-on:click.prevent="Launch">Launch game</button> <button class="btn-primary button-row sound-click btn-green" v-if="!hide_start" v-on:click.prevent="Launch">{{$t('campaigns.preview.launch-game')}}</button>
<button class="btn-primary button-row sound-click btn-red" v-if="hide_start" v-on:click.prevent="Exit">Exit game</button> <button class="btn-primary button-row sound-click btn-red" v-if="hide_start" v-on:click.prevent="Exit">{{$t('campaigns.preview.exit-game')}}</button>
</div> </div>
</div> </div>
<div v-if="!hide_chat" class="campaign-preview-column right"> <div v-if="!hide_chat" class="campaign-preview-column right">

View File

@ -27,15 +27,15 @@ function JoinCampaign(){
invite_code invite_code
}).then(response => { }).then(response => {
if(response.data.status == "ok"){ if(response.data.status == "ok"){
DisplayToast('green', "Successfully joined the campaign!", 2000); DisplayToast('green', $t("campaigns.join.success"), 2000);
let campaign = response.data.campaign; let campaign = response.data.campaign;
ConnectToCampaign(campaign); ConnectToCampaign(campaign);
DisplayCampaign(campaign); DisplayCampaign(campaign);
} else if(response.data.msg == "already"){ } else if(response.data.msg == "already"){
DisplayToast('red', "You are already in that campaign!", 2000); DisplayToast('red', $t("campaigns.join.already"), 2000);
} else { } else {
DisplayToast('red', "Error joining this campaign (maybe the code is not valid?)", 2000); DisplayToast('red', $t("campaigns.join.error"), 2000);
} }
}).catch((err) => console.log(err)); }).catch((err) => console.log(err));
} }
@ -50,10 +50,10 @@ function JoinCampaign(){
<!-- Body --> <!-- Body -->
<form v-on:submit.prevent="JoinCampaign"> <form v-on:submit.prevent="JoinCampaign">
<div class="form-field"> <div class="form-field">
<input id="username-field" type="text" placeholder="Enter campaign code..." name="code" v-model="code" autocomplete="off" > <input id="username-field" type="text" :placeholder='$t("campaigns.join.enter")' name="code" v-model="code" autocomplete="off" >
</div> </div>
<div class="form-field"> <div class="form-field">
<button class="btn-primary sound-click" v-on:click.prevent="JoinCampaign">Join</button> <button class="btn-primary sound-click" v-on:click.prevent="JoinCampaign">{{ $t("general.join")}}</button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -24,7 +24,7 @@ let system = "";
onMounted(() => { onMounted(() => {
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {width: 300, height: 240}); SetSize(id, {width: 350, height: 240});
ResetPosition(id, "center"); ResetPosition(id, "center");
GetEmitter().on('select', (system_id) => Select(system_id)) GetEmitter().on('select', (system_id) => Select(system_id))
@ -62,13 +62,13 @@ function NewCampaign(){
<!-- Body --> <!-- Body -->
<form v-on:submit.prevent="NewCampaign"> <form v-on:submit.prevent="NewCampaign">
<div class="form-field"> <div class="form-field">
<input id="username-field" type="text" placeholder="Enter campaign name..." name="campaignName" v-model="campaignName" autocomplete="off" > <input id="username-field" type="text" :placeholder="$t('campaigns.create.enter')" name="campaignName" v-model="campaignName" autocomplete="off" >
</div> </div>
<div class="form-field"> <div class="form-field">
<SystemSelector :windowId="id" ref="systemSelector"></SystemSelector> <SystemSelector :windowId="id" ref="systemSelector"></SystemSelector>
</div> </div>
<div class="form-field"> <div class="form-field">
<button class="btn-primary sound-click">Create</button> <button class="btn-primary sound-click">{{ $t("general.create")}}</button>
</div> </div>
</form> </form>

View File

@ -34,7 +34,35 @@ for(let i = 0; i < folderPaths.length; i++){
} }
}; };
fs.writeFileSync(outputPath, JSON.stringify({files: result}, null, 2)); fs.writeFileSync(outputPath, JSON.stringify({files: result}, null, "\t"));
console.log('File list generated successfully!'); console.log('File list generated successfully!');
console.log("Generated " + iconCount + " icons"); console.log("Generated " + iconCount + " icons");
// Locale generation
const locales = [
'./client/src/locale/en.json',
'./client/src/locale/es.json',
'./client/src/locale/ca.json',
];
function deepMerge(obj1, obj2) {
for (let key in obj2) {
if (obj2.hasOwnProperty(key)) {
if (obj2[key] instanceof Object && obj1[key] instanceof Object) {
obj1[key] = deepMerge(obj1[key], obj2[key]);
} else {
obj1[key] = obj2[key];
}
}
}
return obj1;
}
let originalJson = JSON.parse(fs.readFileSync(locales[0]));
for(let i = 1; i < locales.length; i++){
let data = JSON.parse(fs.readFileSync(locales[i]));
fs.writeFileSync(locales[i], JSON.stringify(deepMerge(structuredClone(originalJson), data), null, 2));
};
console.log("Updated Locales")