From c74e61716c80b683e8cc9daa3d88da47d990e8a5 Mon Sep 17 00:00:00 2001 From: Aelita4 Date: Wed, 7 Aug 2024 23:31:55 +0200 Subject: [PATCH] Overhaul language driver and move lang data to db --- public/lang/en/buildings.json | 37 ----------------------------- public/lang/en/game.json | 23 ------------------ public/lang/en/navbar.json | 17 -------------- public/lang/en/research.json | 39 ------------------------------- public/lang/en/resourcebar.json | 7 ------ public/lang/en/resources.json | 15 ------------ public/lang/en/ships.json | 12 ---------- public/lang/metadata.json | 6 ----- src/components/BuildingCard.astro | 6 ++--- src/components/NavBar.astro | 28 +++++++++++----------- src/components/ResourceBar.astro | 13 ++++++----- src/lib/data/research.json | 4 +++- src/lib/db/lang.ts | 12 ++++++++++ src/lib/db/mongodb.ts | 14 +++++++++-- src/lib/utils/langDriver.ts | 26 ++++++++++----------- src/pages/api/lang.json.ts | 14 +++++++++++ src/pages/api/lang/[id].json.ts | 35 +++++++++++++++++++++++++++ src/pages/game/buildings.astro | 8 +++---- src/pages/game/profile.astro | 28 +++++++++++----------- src/pages/game/research.astro | 18 +++++++------- src/pages/game/ships.astro | 2 +- 21 files changed, 141 insertions(+), 223 deletions(-) delete mode 100644 public/lang/en/buildings.json delete mode 100644 public/lang/en/game.json delete mode 100644 public/lang/en/navbar.json delete mode 100644 public/lang/en/research.json delete mode 100644 public/lang/en/resourcebar.json delete mode 100644 public/lang/en/resources.json delete mode 100644 public/lang/en/ships.json delete mode 100644 public/lang/metadata.json create mode 100644 src/lib/db/lang.ts create mode 100644 src/pages/api/lang.json.ts create mode 100644 src/pages/api/lang/[id].json.ts diff --git a/public/lang/en/buildings.json b/public/lang/en/buildings.json deleted file mode 100644 index 740120b..0000000 --- a/public/lang/en/buildings.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "Label": { - "mines": "Mines", - "iron-mine": { - "name": "Iron mine", - "description": "Iron mines produce iron ore, which is used to build and upgrade buildings." - }, - "gold-mine": { - "name": "Gold mine", - "description": "Gold mines produce gold ore, useful for trading and building." - }, - "coal-mine": { - "name": "Coal mine", - "description": "Coal mines produce coal, which is used to power buildings." - }, - - "utilities": "Utilities", - "research-lab": { - "name": "Research lab", - "description": "Research labs are used to research new technologies and improve existing ones." - }, - "research-facility": { - "name": "Research facility", - "description": "Research facilities are used to research advanced technologies." - }, - - "power-plants": "Power plants", - "coal-power-plant": { - "name": "Coal power plant", - "description": "Coal power plants produce electricity using coal." - }, - "nuclear-power-plant": { - "name": "Nuclear power plant", - "description": "Nuclear power plants produce electricity using uranium." - } - } -} \ No newline at end of file diff --git a/public/lang/en/game.json b/public/lang/en/game.json deleted file mode 100644 index 8845f98..0000000 --- a/public/lang/en/game.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "Header": { - "user": "user {}" - }, - "Label": { - "userCreationDate": "Account created at {}", - "newUsernamePlaceholder": "new username", - "newEmailPlaceholder": "new email", - "newPasswordPlaceholder": "new password", - "newPasswordVerifyPlaceholder": "verify", - "passwordPlaceholder": "password", - "oldPasswordPlaceholder": "old password" - }, - "Link": { - "build": "[build]", - "research": "[research]", - - "changeUsername": "Change username", - "changeEmail": "Change email", - "changePassword": "Change password", - "logout": "[log out]" - } -} \ No newline at end of file diff --git a/public/lang/en/navbar.json b/public/lang/en/navbar.json deleted file mode 100644 index 0e68593..0000000 --- a/public/lang/en/navbar.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "Link": { - "home": "[home]", - "login": "[login]", - "register": "[register]", - "about": "[about]", - "api": "[api]", - - "overview": "[overview]", - "buildings": "[buildings]", - "research": "[research]", - "ships": "[ships]", - "fleet": "[fleet]", - "galaxyView": "[galaxy view]", - "profile": "[profile]" - } -} \ No newline at end of file diff --git a/public/lang/en/research.json b/public/lang/en/research.json deleted file mode 100644 index 52b3014..0000000 --- a/public/lang/en/research.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "Label": { - "none": "None", - "required": "Required research", - - "basic-engine": { - "name": "Basic Engine", - "description": "Simple engine with a single gear" - }, - "advanced-engine": { - "name": "Advanced Engine", - "description": "Advanced engine with multiple gears" - }, - "combat-utilities": { - "name": "Combat Utilities", - "description": "Utilities for combat" - }, - "defensive-utilities": { - "name": "Defensive Utilities", - "description": "Allows for advanced defensive capabilities" - }, - "oxygen-production": { - "name": "Oxygen Production", - "description": "Various tools and technologies for working with oxygen" - }, - "terraforming": { - "name": "Terraforming", - "description": "Allows for changing landscape of planets, making them habitable" - }, - "advanced-technologies": { - "name": "Advanced Technologies", - "description": "Various advanced technologies" - }, - "nuclear-power": { - "name": "Nuclear Power", - "description": "Advanced power generation using nuclear energy" - } - } -} \ No newline at end of file diff --git a/public/lang/en/resourcebar.json b/public/lang/en/resourcebar.json deleted file mode 100644 index 0f63d22..0000000 --- a/public/lang/en/resourcebar.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Label": { - "avaliable": "Avaliable", - "production": "Production", - "capacity": "Storage capacity" - } -} \ No newline at end of file diff --git a/public/lang/en/resources.json b/public/lang/en/resources.json deleted file mode 100644 index 2768675..0000000 --- a/public/lang/en/resources.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Label": { - "coal": "Coal (C)", - "iron": "Iron (Fe)", - "gold": "Gold (Au)", - - "water": "Water (H₂O)", - "sulfuricAcid": "Sulfuric Acid (H₂SO₄)", - "liquidNitrogen": "Liquid Nitrogen (N₂)", - - "hydrogen": "Hydrogen (H₂)", - "oxygen": "Oxygen (O₂)", - "helium3": "Helium-3 (³He)" - } -} \ No newline at end of file diff --git a/public/lang/en/ships.json b/public/lang/en/ships.json deleted file mode 100644 index a18c256..0000000 --- a/public/lang/en/ships.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Label": { - "transporter": { - "name": "Transporter", - "description": "Transporter can move resources between planets." - }, - "fighter": { - "name": "Fighter", - "description": "Fighter can attack enemy ships and planets." - } - } -} \ No newline at end of file diff --git a/public/lang/metadata.json b/public/lang/metadata.json deleted file mode 100644 index 617238c..0000000 --- a/public/lang/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "id": "en", - "name": "English" - } -] \ No newline at end of file diff --git a/src/components/BuildingCard.astro b/src/components/BuildingCard.astro index 6db65b9..e7fdbcb 100644 --- a/src/components/BuildingCard.astro +++ b/src/components/BuildingCard.astro @@ -1,5 +1,5 @@ --- -import { getHighestWeightedLanguage, getLocales } from '../lib/utils/langDriver'; +import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver'; interface Props { id: string; @@ -8,7 +8,7 @@ interface Props { image: string; } -const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), ['resources', 'game', 'buildings', 'research']); +const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'))); --- @@ -17,7 +17,7 @@ const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.hea
{Astro.props.name}
{Astro.props.description}
- {lang["game"]['Link_build']} + {getName(lang, "general", "nav-build")}
i
diff --git a/src/components/NavBar.astro b/src/components/NavBar.astro index 2664d67..ac4b460 100644 --- a/src/components/NavBar.astro +++ b/src/components/NavBar.astro @@ -1,5 +1,5 @@ --- -import { getHighestWeightedLanguage, getLocales } from '../lib/utils/langDriver'; +import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver'; interface Props { loggedIn: string; active: string; @@ -19,88 +19,88 @@ interface NavElement { dropdowns?: Array; } -const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), ['navbar']); +const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'))); const listOfElements: Array = [{ id: "home", - title: lang["navbar"]["Link_home"], + title: getName(lang, "general", "nav-home"), type: "simple", url: "/", show: "always", position: "top" }, { id: "about", - title: lang["navbar"]["Link_about"], + title: getName(lang, "general", "nav-about"), type: "simple", url: "#", show: "always", position: "top" }, { id: "api", - title: lang["navbar"]["Link_api"], + title: getName(lang, "general", "nav-api"), type: "simple", url: "#", show: "always", position: "top" }, { id: "login", - title: lang["navbar"]["Link_login"], + title: getName(lang, "general", "nav-login"), type: "simple", url: "/login", show: "notLoggedInOnly", position: "bottom" }, { id: "register", - title: lang["navbar"]["Link_register"], + title: getName(lang, "general", "nav-register"), type: "simple", url: "/register", show: "notLoggedInOnly", position: "bottom" },{ id: "overview", - title: lang["navbar"]["Link_overview"], + title: getName(lang, "general", "nav-overview"), type: "simple", url: "/game", show: "loggedInOnly", position: "bottom" }, { id: "buildings", - title: lang["navbar"]["Link_buildings"], + title: getName(lang, "general", "nav-buildings"), type: "simple", url: "/game/buildings", show: "loggedInOnly", position: "bottom" }, { id: "research", - title: lang["navbar"]["Link_research"], + title: getName(lang, "general", "nav-research"), type: "simple", url: "/game/research", show: "loggedInOnly", position: "bottom" }, { id: "ships", - title: lang["navbar"]["Link_ships"], + title: getName(lang, "general", "nav-ships"), type: "simple", url: "/game/ships", show: "loggedInOnly", position: "bottom" }, { id: "fleet", - title: lang["navbar"]["Link_fleet"], + title: getName(lang, "general", "nav-fleet"), type: "simple", url: "/game/fleet", show: "loggedInOnly", position: "bottom" }, { id: "galaxyView", - title: lang["navbar"]["Link_galaxyView"], + title: getName(lang, "general", "nav-galaxy-view"), type: "simple", url: "/game/galaxyView", show: "loggedInOnly", position: "bottom" }, { id: "profile", - title: lang["navbar"]["Link_profile"], + title: getName(lang, "general", "nav-profile"), type: "simple", url: "/game/profile", show: "loggedInOnly", diff --git a/src/components/ResourceBar.astro b/src/components/ResourceBar.astro index d56ea57..ab39313 100644 --- a/src/components/ResourceBar.astro +++ b/src/components/ResourceBar.astro @@ -1,11 +1,11 @@ --- import { ObjectId } from 'mongodb'; import { calculateCurrentAvailableResources } from '../lib/utils/resourceManager'; -import { getHighestWeightedLanguage, getLocales } from '../lib/utils/langDriver'; +import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver'; import resourceTypes from '../lib/data/resources.json'; -const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), ['resourcebar', 'resources']); +const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'))); const resources = await calculateCurrentAvailableResources(new ObjectId(Astro.cookies.get('planetid')?.value ?? '')); @@ -13,6 +13,7 @@ const resourceArray = []; for(const key in resources) { resourceArray.push(resources[key as never]); } + ---
@@ -30,13 +31,13 @@ for(const key in resources) { x.name === res.name)?.icon ?? "#"} alt={res.name} />
-
{lang["resources"][`Label_${res.name}`]}
+
{getName(lang, 'resources', res.name)}
[fetching]
-
{lang["resourcebar"]['Label_avaliable']} - {Math.floor(res.amount).toString()}
-
{lang["resourcebar"]['Label_production']} - {res.perHourMiningRate.toString()}
-
{lang["resourcebar"]['Label_capacity']} - {'21372137'}
+
{getName(lang, 'general', 'avaliable')} - {Math.floor(res.amount).toString()}
+
{getName(lang, 'general', 'production')} - {res.perHourMiningRate.toString()}
+
{getName(lang, 'general', 'capacity')} - {'21372137'}
)} diff --git a/src/lib/data/research.json b/src/lib/data/research.json index 630f4b3..991486c 100644 --- a/src/lib/data/research.json +++ b/src/lib/data/research.json @@ -137,6 +137,8 @@ "iron": 1000, "gold": 500 } - } + }, + "time": 3000, + "multiplier": 5 } ] \ No newline at end of file diff --git a/src/lib/db/lang.ts b/src/lib/db/lang.ts new file mode 100644 index 0000000..d5054d1 --- /dev/null +++ b/src/lib/db/lang.ts @@ -0,0 +1,12 @@ +import { Lang } from "./mongodb"; + +export const getLang = async (language = "en") => { + const lang = await Lang(language); + return { + general: await lang[0].find({}).toArray(), + buildings: await lang[1].find({}).toArray(), + ships: await lang[2].find({}).toArray(), + resources: await lang[3].find({}).toArray(), + research: await lang[4].find({}).toArray() + } +} \ No newline at end of file diff --git a/src/lib/db/mongodb.ts b/src/lib/db/mongodb.ts index d0a1ef4..776c8a6 100644 --- a/src/lib/db/mongodb.ts +++ b/src/lib/db/mongodb.ts @@ -2,7 +2,6 @@ import { MongoClient } from "mongodb"; import config from '../../../config.json' const uri = config.MONGODB_URI; -const dbName = config.MONGODB_DB; const options = {}; const mongo = new MongoClient(uri, options); @@ -16,7 +15,7 @@ export const disconnect = async () => { mongo.close(); } -export const getDB = async () => { +export const getDB = async (dbName = config.MONGODB_DB) => { await connect(); return mongo.db(dbName); } @@ -34,4 +33,15 @@ export const AccessTokens = async () => { export const Planets = async () => { const db = await getDB(); return db.collection('planets'); +} + +export const Lang = async (language = "en") => { + const db = await getDB(`${config.MONGODB_DB}_${language}`); + return [ + await db.collection('general'), + await db.collection('buildings'), + await db.collection('ships'), + await db.collection('resources'), + await db.collection('research') + ] } \ No newline at end of file diff --git a/src/lib/utils/langDriver.ts b/src/lib/utils/langDriver.ts index a27e440..82b0d4c 100644 --- a/src/lib/utils/langDriver.ts +++ b/src/lib/utils/langDriver.ts @@ -1,5 +1,7 @@ +import { GET as langs } from '../../pages/api/lang.json'; + export async function getSupportedLanguages() { - const metadata: [] = await (await fetch('http://localhost:4321/lang/metadata.json')).json(); + const metadata: { id: string, name: string }[] = await (await langs()).json(); const response: Array = []; @@ -32,23 +34,21 @@ export async function getHighestWeightedLanguage(header: string | null): Promise return highestWeightedLang; } -export async function getLocales(language: string, types: string[]) { +export async function getLocales(language: string) { if(!(await getSupportedLanguages()).includes(language)) { console.log(await getSupportedLanguages(), language) return null; } - const out: any = {}; + const lang = await (await fetch(`http://localhost:4321/api/lang/${language}.json`)).json(); - for(const type of types) { - const lang = await (await fetch(`http://localhost:4321/lang/${language}/${type}.json`)).json(); - out[type] = {}; - for(const category in lang) { - for(const element in lang[category]) { - out[type][`${category}_${element}`] = lang[category][element]; - } - } - } + return lang.data; +} - return out; +export function getName(locale: { [key: string]: { id: string, name: string }[] }, type: string, name: string) { + return locale[type].find((element: { id: string }) => element.id === name)?.name ?? `NTL_${name}`; +} + +export function getObj(locale: { [key: string]: { id: string, name: string, description: string | null }[] }, type: string, name: string) { + return locale[type].find((element: { id: string }) => element.id === name) ?? { id: name, name: `NTL_${name}`, description: `NTL_${name}` }; } \ No newline at end of file diff --git a/src/pages/api/lang.json.ts b/src/pages/api/lang.json.ts new file mode 100644 index 0000000..2c05b51 --- /dev/null +++ b/src/pages/api/lang.json.ts @@ -0,0 +1,14 @@ +export async function GET() { + return new Response( + JSON.stringify([ + { + "id": "en", + "name": "English" + }, + { + "id": "pl", + "name": "Polish" + } + ]), + ) +} \ No newline at end of file diff --git a/src/pages/api/lang/[id].json.ts b/src/pages/api/lang/[id].json.ts new file mode 100644 index 0000000..caf115a --- /dev/null +++ b/src/pages/api/lang/[id].json.ts @@ -0,0 +1,35 @@ +import type { APIRoute } from 'astro'; +import { GET as langs } from '../lang.json'; +import { getLang } from '../../../lib/db/lang'; + +const supportedLanguages: { id: string, name: string }[] = await (await langs()).json(); + +export const GET: APIRoute = async ({ params, request }) => { + const id = params.id; + if (!supportedLanguages.find(lang => lang.id === id)) { + return new Response( + JSON.stringify({ + code: 404, + message: "Language not found" + }), { status: 404 } + ) + } + + const lang = await getLang(id); + if (!lang) { + return new Response( + JSON.stringify({ + code: 500, + message: "Internal Server Error" + }), { status: 500 } + ) + } + + return new Response( + JSON.stringify({ + code: 200, + message: "OK", + data: lang + }) + ) +} \ No newline at end of file diff --git a/src/pages/game/buildings.astro b/src/pages/game/buildings.astro index 7103f81..8908f2e 100644 --- a/src/pages/game/buildings.astro +++ b/src/pages/game/buildings.astro @@ -3,7 +3,7 @@ import Layout from '../../layouts/Layout.astro'; import NavBar from '../../components/NavBar.astro'; import BuildingCard from '../../components/BuildingCard.astro'; import { getUserByAccessToken } from '../../lib/db/users'; -import { getHighestWeightedLanguage, getLocales } from '../../lib/utils/langDriver'; +import { getHighestWeightedLanguage, getLocales, getObj } from '../../lib/utils/langDriver'; import ResourceBar from '../../components/ResourceBar.astro'; const buildingsList = (await import('../../lib/data/buildings.json')).default; @@ -17,7 +17,7 @@ if(checkUser === null || checkUser.username !== username) return Astro.redirect( const locale = await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')); -const lang = await getLocales(locale, ['resources', 'game', 'buildings', 'research']); +const lang = await getLocales(locale); const modalSet: { [key: string]: { resources: Array, research: Array, buildings: Array, energy: number } } = {}; @@ -55,8 +55,8 @@ buildingsList.forEach(cat => {
{cat.buildings.map(building => )}
diff --git a/src/pages/game/profile.astro b/src/pages/game/profile.astro index 22a5fdd..b6b06ac 100644 --- a/src/pages/game/profile.astro +++ b/src/pages/game/profile.astro @@ -2,7 +2,7 @@ import Layout from '../../layouts/Layout.astro'; import NavBar from '../../components/NavBar.astro'; import { getUserByAccessToken, getUserByNickOrEmail } from '../../lib/db/users'; -import { getHighestWeightedLanguage, getLocales } from '../../lib/utils/langDriver'; +import { getHighestWeightedLanguage, getLocales, getName } from '../../lib/utils/langDriver'; import ResourceBar from '../../components/ResourceBar.astro'; import format from '../../lib/utils/format'; @@ -17,7 +17,7 @@ const locale = await getHighestWeightedLanguage(Astro.request.headers.get('accep const user = await getUserByNickOrEmail(username); -const lang = await getLocales(locale, ['game']); +const lang = await getLocales(locale); --- @@ -25,24 +25,24 @@ const lang = await getLocales(locale, ['game']);
-

{format(lang["game"]['Label_userCreationDate'], user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}

- {lang["game"]['Link_logout']} +

{format(getName(lang, 'general', 'user-creation-date'), user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}

+ {getName(lang, 'general', 'nav-logout')}
- - - + + +
- - - + + +
- - - - + + + +
diff --git a/src/pages/game/research.astro b/src/pages/game/research.astro index ac63d97..21bd05c 100644 --- a/src/pages/game/research.astro +++ b/src/pages/game/research.astro @@ -4,7 +4,7 @@ import { Icon } from 'astro-icon/components' import Layout from '../../layouts/Layout.astro'; import NavBar from '../../components/NavBar.astro'; import { getUserByAccessToken } from '../../lib/db/users'; -import { getHighestWeightedLanguage, getLocales } from '../../lib/utils/langDriver'; +import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver'; import ResourceBar from '../../components/ResourceBar.astro'; type ResearchDetail = { id: string, level: number, requiredResearch: { id: string, level: number}[], cost: { [key: string]: number } }; @@ -20,7 +20,7 @@ if(checkUser === null || checkUser.username !== username) return Astro.redirect( const locale = await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')); -const lang = await getLocales(locale, ['game', 'resources', 'buildings', 'research']); +const lang = await getLocales(locale); const researchDetails: ResearchDetail[] = []; //TODO: Add union type for cost keys researchList.forEach(element => { @@ -45,21 +45,21 @@ researchList.forEach(element => { {researchDetails.map(research => (
-

{lang["research"][`Label_${research.id}`].name}

+

{getObj(lang, "research", research.id).name}

- {lang["research"][`Label_${research.id}`].description}
+ {getObj(lang, "research", research.id).description}
- {lang["game"]['Link_research']} + {getName(lang, "general", "nav-research")}
-
{lang["research"]['Label_required']}:
+
{getName(lang, "general", "required")}:
{research.requiredResearch.length !== 0 ? research.requiredResearch.map(req => (
- {lang["research"][`Label_${req.id}`].name} - {req.level} + {getObj(lang, "research", req.id).name} - {req.level}
- )) : lang["research"]['Label_none']} + )) : getName(lang, "general", "none")}
@@ -68,7 +68,7 @@ researchList.forEach(element => {
{Object.entries(research.cost).map(([key, value]) =>
- {lang["resources"][`Label_${key}`]}: {value} || + {getName(lang, "resources", key)}: {value} ||
)}
diff --git a/src/pages/game/ships.astro b/src/pages/game/ships.astro index be8ecab..5bc8108 100644 --- a/src/pages/game/ships.astro +++ b/src/pages/game/ships.astro @@ -20,7 +20,7 @@ const planet = await getPlanetById(new ObjectId(Astro.cookies.get('planetid')?.v if(!planet) return; -const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), ['ships']); +const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'))); ---