diff --git a/astro-i18n.adapter.ts b/astro-i18n.adapter.ts new file mode 100644 index 0000000..f6c3ad1 --- /dev/null +++ b/astro-i18n.adapter.ts @@ -0,0 +1,38 @@ +import type { AstroIntegration } from "astro"; +import { mkdir, rename, access, constants } from 'node:fs/promises' +import {rm} from "fs/promises"; + +const locales = ["de"]; + +export default function configureI18n(): AstroIntegration { + return { + name: "astro-i18n-renamer", + hooks: { + "astro:build:done": async ({pages, dir, logger, routes}) => { + for (let page of pages) { + let [locale, ...rest] = page.pathname.split("/"); + if (locales.includes(locale)) { + let path = rest.join("/"); + let oldPath = `${dir.pathname}${page.pathname}` + let newPath = `${dir.pathname}${path}` + try { + await access(cutPrefix(newPath), constants.R_OK | constants.W_OK) + } catch (e) { + await mkdir(cutPrefix(newPath), {recursive: true}); + } + + await rename(`${cutPrefix(oldPath)}index.html`, `${cutPrefix(newPath)}index.${locale}.html`) + } + } + + for (let locale of locales) { + await rm(`${cutPrefix(dir.pathname)}${locale}`, {recursive: true, force: true}) + } + } + } + } +} + +function cutPrefix(path: string): string { + return process.platform === "win32" ? path.substring(1) : path +} \ No newline at end of file diff --git a/astro-i18n.config.ts b/astro-i18n.config.ts index 643a469..ad95a6c 100644 --- a/astro-i18n.config.ts +++ b/astro-i18n.config.ts @@ -5,17 +5,17 @@ export default defineAstroI18nConfig({ secondaryLocales: ["de"], // other supported locales fallbackLocale: "en", // fallback locale (on missing translation) trailingSlash: "never", // "never" or "always" - run: "server", //"client+server" or "server" + run: "client+server", //"client+server" or "server" showPrimaryLocale: false, // "/en/about" vs "/about" translationLoadingRules: [], // per page group loading - translationDirectory: { - i18n: "i18n", - }, // translation directory names + translationDirectory: {}, // translation directory names translations: {}, // { [translation_group1]: { [locale1]: {}, ... } } routes: { de: { about: "ueber-uns", - join: "jetzt-spielen" + join: "jetzt-spielen", + imprint: "impressum", + "code-of-conduct": "verhaltensrichtlinien", } }, // { [secondary_locale1]: { about: "about-translated", ... } } }) \ No newline at end of file diff --git a/astro.config.mjs b/astro.config.mjs index 39bb5c0..937d314 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,6 +1,7 @@ import { defineConfig, sharpImageService } from 'astro/config'; import svelte from "@astrojs/svelte"; import tailwind from "@astrojs/tailwind"; +import configureI18n from "./astro-i18n.adapter"; // https://astro.build/config export default defineConfig({ @@ -8,7 +9,8 @@ export default defineConfig({ image: { service: sharpImageService(), }, - integrations: [svelte(), tailwind()], + compressHTML: true, + integrations: [svelte(), tailwind(), configureI18n()], vite: { } diff --git a/package.json b/package.json index 4ec140d..58113d9 100644 --- a/package.json +++ b/package.json @@ -18,23 +18,25 @@ "@astrojs/svelte": "^4.0.3", "@astrojs/tailwind": "^5.0.2", "@astropub/icons": "^0.2.0", + "@types/color": "^3.0.5", + "@types/node": "^20.8.10", "cssnano": "^6.0.1", - "esbuild": "^0.19.4", + "esbuild": "^0.19.5", "postcss-nesting": "^12.0.1", - "sass": "^1.69.3", - "svelte": "^4.2.1", - "tailwind-merge": "^1.14.0", - "tailwindcss": "^3.3.3" + "sass": "^1.69.5", + "svelte": "^4.2.2", + "tailwind-merge": "^2.0.0", + "tailwindcss": "^3.3.5" }, "dependencies": { "@codemirror/lang-markdown": "^6.2.2", "@ddietr/codemirror-themes": "^1.4.2", - "astro": "^3.3.0", - "astro-i18n": "^2.0.4", + "astro": "^3.4.3", + "astro-i18n": "^2.1.18", "color": "^4.2.3", "flowbite": "^1.8.1", - "flowbite-svelte": "^0.44.18", - "flowbite-svelte-icons": "^0.4.4", + "flowbite-svelte": "^0.44.19", + "flowbite-svelte-icons": "^0.4.5", "moment": "^2.29.4", "sharp": "^0.32.6", "svelte-awesome": "^3.2.1", diff --git a/src/components/PlayerCount.svelte b/src/components/PlayerCount.svelte new file mode 100644 index 0000000..63708d4 --- /dev/null +++ b/src/components/PlayerCount.svelte @@ -0,0 +1,11 @@ + + +{#await $server} +{:then data} + {data.players.online} +{:catch error} + Error +{/await} \ No newline at end of file diff --git a/src/components/ServerStatus.svelte b/src/components/ServerStatus.svelte new file mode 100644 index 0000000..6d9f511 --- /dev/null +++ b/src/components/ServerStatus.svelte @@ -0,0 +1,19 @@ + + +{#await $server} +

{t("status.loading")}

+{:then data} +

{t("status.status")}: {t("status.online")}

+

{t("status.players", { count: `${data.players.online}/${data.players.max}`})}

+

{t("status.version", { version: generateVersionString(data.version.name)})}

+{:catch error} +

{t("status.status")}: {t("status.offline")}

+{/await} \ No newline at end of file diff --git a/src/components/admin/stores/cached.ts b/src/components/admin/stores/cached.ts index 4eca3c9..b3a3aaf 100644 --- a/src/components/admin/stores/cached.ts +++ b/src/components/admin/stores/cached.ts @@ -33,7 +33,7 @@ export function cachedFamily(normal: K, init: (arg0: T) => Promise): (a const stores: Map> = new Map(); return (arg: T) => { if(stores.has(arg)) { - return stores.get(arg); + return stores.get(arg)!!; } else { const store = writable(normal); let first = true; diff --git a/src/components/stores/server.ts b/src/components/stores/server.ts new file mode 100644 index 0000000..91e3832 --- /dev/null +++ b/src/components/stores/server.ts @@ -0,0 +1,4 @@ +import {readable} from "svelte/store"; +import type {Readable} from "svelte/store"; + +export const server = readable(fetch(import.meta.env.PUBLIC_API_SERVER + "/data/server").then(res => res.json())) \ No newline at end of file diff --git a/src/content/config.ts b/src/content/config.ts index 34ab985..fd69924 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,5 +1,5 @@ // @ts-ignore -import { defineCollection, z } from 'astro:content'; +import {defineCollection, reference, z} from 'astro:content'; export const pages = defineCollection({ type: "content", @@ -10,6 +10,30 @@ export const pages = defineCollection({ }) }) +export const help = defineCollection({ + type: "content", + schema: z.object({ + title: z.string().min(1).max(80), + description: z.string().min(1).max(120), + tags: z.array(z.string()), + related: z.array(reference('help')).optional() + }) +}) + +export const event = defineCollection({ + type: "content", + schema: z.object({ + name: z.string(), + start: z.date(), + end: z.date(), + mode: z.string().optional(), + leader: z.string().array().optional(), + eventId: z.number().gte(0) + }) +}) + export const collections = { - 'pages': pages + 'pages': pages, + 'help': help, + 'event': event } diff --git a/src/content/help/en/how-to.md b/src/content/help/en/how-to.md new file mode 100644 index 0000000..c50521b --- /dev/null +++ b/src/content/help/en/how-to.md @@ -0,0 +1,9 @@ +--- +title: How To +description: How to do anything on SteamWar +tags: +- how-to +slug: how-to +--- + +# How to \ No newline at end of file diff --git a/src/i18n/common/de.json b/src/i18n/common/de.json index f88cbcd..8dd7d0b 100644 --- a/src/i18n/common/de.json +++ b/src/i18n/common/de.json @@ -2,8 +2,8 @@ "home": { "page": "SteamWar - Startseite", "subtitle": { - "1": "Spieler Online: ", - "2": "WarGears, AirShips, WarShips" + "1": "WarGears, AirShips, WarShips", + "2": "Spieler Online: " }, "join": "Jetzt Spielen", "benefits": { @@ -34,6 +34,10 @@ "Arch": "Architekt" } }, + "status": { + "loading": "Lade...", + "players": "Spieler: {# count #}" + }, "navbar": { "links": { "home": { @@ -42,7 +46,7 @@ "downloads": "Downloads", "faq": "FAQ" }, - "announcements": "Ankünigungen", + "announcements": "Ankündigungen", "rules": { "title": "Regeln", "gamemode": "Spielmodi", @@ -60,7 +64,8 @@ "help": { "title": "Hilfe", "docs": "Dokumentation" - } + }, + "account": "Konto" } } } diff --git a/src/i18n/common/en.json b/src/i18n/common/en.json index eda6fbd..5bb056e 100644 --- a/src/i18n/common/en.json +++ b/src/i18n/common/en.json @@ -30,9 +30,18 @@ "title": "Help", "center": "Helpcenter", "docs": "Docs" - } + }, + "account": "Account" } }, + "status": { + "loading": "Loading...", + "status": "Status", + "online": "Online", + "offline": "Offline", + "players": "Players: {# count #}", + "version": "Version: {# version #}" + }, "home": { "page": "SteamWar - Home", "title": { @@ -40,8 +49,8 @@ "second": "War" }, "subtitle": { - "1": "Players Online: ", - "2": "WarGears, AirShips, WarShips", + "1": "WarGears, AirShips, WarShips", + "2": "Players Online: ", "3": "Version: 1.12 - 1.20" }, "join": "Join Now", diff --git a/src/layouts/NavbarLayout.astro b/src/layouts/NavbarLayout.astro index adede9b..f51a8b1 100644 --- a/src/layouts/NavbarLayout.astro +++ b/src/layouts/NavbarLayout.astro @@ -3,8 +3,11 @@ import { Image } from "astro:assets"; import Basic from "./Basic.astro"; import '../styles/button.css'; import localLogo from "../images/logo.png" -import {YoutubeSolid, DiscordSolid} from "flowbite-svelte-icons" -import {l, t} from "astro-i18n"; +import {YoutubeSolid, DiscordSolid, CaretDownOutline} from "flowbite-svelte-icons" +import {t} from "astro-i18n"; +import {l} from "../util/util" + +import ServerStatus from "../components/ServerStatus.svelte"; const { title } = Astro.props; --- @@ -22,11 +25,14 @@ const { title } = Astro.props; {t("navbar.title")} -
+
@@ -91,10 +106,11 @@ const { title } = Astro.props;
-