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;
-