Compare commits

...
9 Commits
Author SHA1 Message Date
TrèsAbhi 015d457d23 feat: proper api 2026-02-01 00:14:58 -06:00
TrèsAbhi ba6a83a9cb fix: docs 2026-02-01 00:09:06 -06:00
TrèsAbhi 689985ed93 feat: delete workflows 2026-02-01 00:06:39 -06:00
TrèsAbhi bf9262f1f1 feat: some work on footer 2026-01-31 23:21:43 -06:00
TrèsAbhi 821bd363ad feat: more groups 2026-01-31 23:06:46 -06:00
TrèsAbhi 4a9fc65e71 feat: tanks section 2026-01-31 22:54:00 -06:00
TrèsAbhi 81877f5abd feat: tank cards 2026-01-31 22:32:59 -06:00
TrèsAbhi 01eed3e045 fix: remove unused class test 2026-01-31 21:46:16 -06:00
TrèsAbhi 7bc423b570 fix: stack overflow on closing wss 2026-01-31 21:46:05 -06:00
38 changed files with 440 additions and 611 deletions

No files matched your search

-82
View File
@@ -1,82 +0,0 @@
name: Assets
on:
push:
branches: main
workflow_dispatch:
inputs:
asset_repo:
type: choice
required: false
description: What asset repo to write to
options:
- blitzkit/assets
- blitzkit/assets-preview
- blitzkit/assets-dev
default: blitzkit/assets
asset_source:
type: string
required: false
description: "Archive URL or Steam to download (example: steam:APP_ID/DEPOT_ID or zip:URL_TO_ZIP)"
default: "steam:444200/444202"
schedule:
- cron: "0 2 * * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.asset_repo }}
cancel-in-progress: true
env:
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
WOTB_DLC_CDN: ${{ secrets.WOTB_DLC_CDN }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_REPO: ${{ github.event.inputs.asset_repo != '' && github.event.inputs.asset_repo || secrets.PUBLIC_ASSET_REPO }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: true
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
PUBLIC_PATREON_CLIENT_ID: ${{ secrets.PUBLIC_PATREON_CLIENT_ID }}
PUBLIC_PATREON_REDIRECT_URI: ${{ secrets.PUBLIC_PATREON_REDIRECT_URI }}
PATREON_CLIENT_SECRET: ${{ secrets.PATREON_CLIENT_SECRET }}
PUBLIC_NITROPAY_ID: ${{ secrets.PUBLIC_NITROPAY_ID }}
PUBLIC_DEBUG_MISSING_I18N: false
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_FAST_USER: blitzkit
PUBLIC_ASSET_FAST_REPO: assets
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
jobs:
build_assets:
name: Build assets
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- run: bun run setup
- name: AppArmor hack
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
- name: Build assets
run: bun run build:assets --all-targets --source=${{ github.event.inputs.asset_source || 'steam:444200/444202' }}
-54
View File
@@ -1,54 +0,0 @@
name: Averages
on:
workflow_dispatch:
schedule:
- cron: "0 8 * * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Build averages
env:
PUBLIC_ASSET_BRANCH: main
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
run: bun run build:averages --production
-34
View File
@@ -1,34 +0,0 @@
name: Bot
on:
push:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build bot
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Build bot
run: bun run build:bot
- name: Archive build
uses: actions/upload-artifact@v5
with:
name: bot
path: dist/bot
-36
View File
@@ -1,36 +0,0 @@
name: IDs
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 1"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Discover IDs
run: bun build:ids --production
-67
View File
@@ -1,67 +0,0 @@
name: Host
on:
push:
branches: main
schedule:
- cron: "0 */5 * * *"
workflow_dispatch:
release:
types: [created, published, released, edited]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: ${{ secrets.ALLOW_ROBOTS }}
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
PUBLIC_GUIDE_WEBSITE: ${{ secrets.PUBLIC_GUIDE_WEBSITE }}
SERVICING: ${{ secrets.SERVICING }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
runs-on: ubuntu-latest
steps:
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- name: Download release assets
run: |
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/blitzkit/blitzkit/releases/latest \
| grep "browser_download_url.*bot.zip" \
| cut -d : -f 2,3 \
| tr -d \")
curl -L -o bot.zip $DOWNLOAD_URL
mkdir -p dist/bot
unzip bot.zip -d dist/bot
- name: Install sharp
run: bun init -y && bun add sharp
- name: Move directories
run: mv dist/bot/prisma .
- name: Run bot
run: bun run dist/bot/main.js
-46
View File
@@ -1,46 +0,0 @@
name: Rating Asia
on:
workflow_dispatch:
schedule:
- cron: "0 17 * * *"
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Generate leaderboard
run: bun build:ratingleaderboard --region=asia
-46
View File
@@ -1,46 +0,0 @@
name: Rating Europe
on:
workflow_dispatch:
schedule:
- cron: "0 23 * * *"
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Generate leaderboard
run: bun build:ratingleaderboard --region=eu
-46
View File
@@ -1,46 +0,0 @@
name: Rating North America
on:
workflow_dispatch:
schedule:
- cron: "0 5 * * *"
env:
PUBLIC_ASSET_BRANCH: main
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: "true"
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
host:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Generate leaderboard
run: bun build:ratingleaderboard --region=com
-38
View File
@@ -1,38 +0,0 @@
name: Reviews
on:
workflow_dispatch:
schedule:
- cron: 0 0 * * 2
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- run: bun run setup
- name: Find reviews
run: bun run build:reviews
+1 -1
View File
@@ -1,4 +1,4 @@
name: Website UE
name: Website
on:
push:
-72
View File
@@ -1,72 +0,0 @@
name: Website
on:
push:
workflow_dispatch:
schedule:
- cron: "0 4 * * *"
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref == 'refs/heads/main' }}
env:
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: ${{ secrets.ALLOW_ROBOTS }}
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
PUBLIC_GUIDE_WEBSITE: ${{ secrets.PUBLIC_GUIDE_WEBSITE }}
SERVICING: ${{ secrets.SERVICING }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
jobs:
build:
name: Build website
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
token: ${{ secrets.GH_TOKEN }}
- uses: oven-sh/setup-bun@v2
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GH_TOKEN }}
- uses: actions/configure-pages@v5
- run: bun run setup
- name: Build website
run: bun run build:website
- name: Upload artifact
uses: actions/upload-pages-artifact@v4
with:
path: dist/website
deploy-github-pages:
if: ${{ github.ref == 'refs/heads/main' }}
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
needs: build
environment:
name: Production
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
+14 -4
View File
@@ -75,12 +75,22 @@
"name": "Guesser",
"slogan": "Silhouette mini-game",
"action": "Play"
},
"changelogs": {
"name": "Changelogs",
"slogan": "BlitzKit patch notes",
"action": "Read up"
}
},
"home": {
"search": "Search tanks, players, avatars...",
"credit": "by TrèsAbhi"
"credit": "by TrèsAbhi",
"tanks": "Tanks",
"players": "Players",
"cosmetics": "Cosmetics",
"games": "Games",
"technical": "Technical"
},
"avatars": {
@@ -102,8 +112,8 @@
"settings": "Settings"
},
"recent": {
"title": "Recent",
"no_recent": "Your recently viewed pages will appear here."
"companies": {
"discord": "Discord",
"github": "GitHub"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

@@ -19,6 +19,8 @@ export const LIGHT_TEXT_COLORS = new Set<Color>([
"brown",
"crimson",
"jade",
"blue",
"tomato",
]);
export function Button({
@@ -33,7 +35,7 @@ export function Button({
className={classNames(styles.button, className)}
data-color={color}
data-variant={variant}
data-light-text={color ? LIGHT_TEXT_COLORS.has(color) : undefined}
data-light-text={variant === "solid"}
style={{
backgroundColor: color ? `var(--${color}-9)` : undefined,
...style,
+59 -19
View File
@@ -1,8 +1,10 @@
---
import { DiscordLogoIcon, GitHubLogoIcon } from "@radix-ui/react-icons";
import packageJson from "../../../../package.json";
import { api } from "../core/api/dynamic";
import { BlitzKitIcon } from "../icons/BlitzKit";
import { Code } from "./Code";
import { Link } from "./Link";
import { Text } from "./Text";
interface Props {
@@ -28,20 +30,36 @@ const strings = await api.strings(locale);
flex: 1;
max-width: var(--page-width);
.logo {
display: flex;
align-items: center;
gap: var(--space-4);
display: flex;
flex-direction: column;
gap: var(--space-4);
.icon {
width: var(--space-6);
height: var(--space-6);
.row-info {
display: flex;
justify-content: space-between;
align-items: center;
.logo {
display: flex;
align-items: center;
gap: var(--space-4);
.icon {
width: var(--space-6);
height: var(--space-6);
}
.info {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
}
.info {
.links {
display: flex;
flex-direction: column;
gap: var(--space-1);
align-items: center;
gap: var(--space-5);
}
}
}
@@ -50,17 +68,39 @@ const strings = await api.strings(locale);
<div class="footer">
<div class="content">
<div class="logo">
<BlitzKitIcon className="icon" />
<div class="row-info">
<div class="logo">
<BlitzKitIcon className="icon" />
<div class="info">
<Text lowContrast weight="medium" size="major">
{strings.common.name}
</Text>
<div class="info">
<Text lowContrast weight="medium" size="major">
{strings.common.name}
</Text>
<Code>
{packageJson.version}
</Code>
<Code>
{packageJson.version}
</Code>
</div>
</div>
<div class="links">
<Link
underline="hover"
color="gray"
href="https://discord.gg/nDt7AjGJQH"
>
<DiscordLogoIcon />
{strings.companies.discord}
</Link>
<Link
underline="hover"
color="gray"
href="https://github.com/blitzkit/blitzkit"
>
<GitHubLogoIcon />
{strings.companies.github}
</Link>
</div>
</div>
</div>
@@ -0,0 +1,31 @@
---
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import { Heading } from "./Heading";
import { Section } from "./Section";
import ToolCard from "./ToolCard.astro";
import ToolsWrapper from "./ToolsWrapper.astro";
interface Props {
locale: string;
}
const { locale } = Astro.props;
const strings = await api.strings(locale);
---
<style>
.title {
margin-bottom: var(--space-3);
}
</style>
<Section>
<Heading size="2" className="title">{strings.home.cosmetics}</Heading>
<ToolsWrapper>
<ToolCard {locale} tool={tools.avatars} />
<ToolCard {locale} tool={tools.backgrounds} />
</ToolsWrapper>
</Section>
@@ -0,0 +1,31 @@
---
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import { Heading } from "./Heading";
import { Section } from "./Section";
import ToolCard from "./ToolCard.astro";
import ToolsWrapper from "./ToolsWrapper.astro";
interface Props {
locale: string;
}
const { locale } = Astro.props;
const strings = await api.strings(locale);
---
<style>
.title {
margin-bottom: var(--space-3);
}
</style>
<Section>
<Heading size="2" className="title">{strings.home.games}</Heading>
<ToolsWrapper>
<ToolCard {locale} tool={tools.mixer} />
<ToolCard {locale} tool={tools.guesser} />
</ToolsWrapper>
</Section>
@@ -79,6 +79,10 @@ const strings = await api.strings(locale);
letter-spacing: -0.15em;
}
}
.name {
position: relative;
}
}
.search {
@@ -100,7 +104,7 @@ const strings = await api.strings(locale);
<Code className="version">2.0</Code>
</div>
<Text lowContrast>
<Text className="name" lowContrast>
{strings.home.credit}
</Text>
</div>
@@ -0,0 +1,32 @@
---
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import { Heading } from "./Heading";
import { Section } from "./Section";
import ToolCard from "./ToolCard.astro";
import ToolsWrapper from "./ToolsWrapper.astro";
interface Props {
locale: string;
}
const { locale } = Astro.props;
const strings = await api.strings(locale);
---
<style>
.title {
margin-bottom: var(--space-3);
}
</style>
<Section>
<Heading size="2" className="title">{strings.home.players}</Heading>
<ToolsWrapper>
<ToolCard {locale} tool={tools.players} />
<ToolCard {locale} tool={tools.session} />
<ToolCard {locale} tool={tools.playlist} />
</ToolsWrapper>
</Section>
@@ -0,0 +1,65 @@
---
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import { Heading } from "./Heading";
import { Section } from "./Section";
import { TankCard } from "./TankCard";
import ToolCard from "./ToolCard.astro";
import ToolsWrapper from "./ToolsWrapper.astro";
interface Props {
locale: string;
}
const { locale } = Astro.props;
const strings = await api.strings(locale);
const popular = [
"Concept 1B",
"Obj. 268",
"Grille 15",
"Kpz 70 Missile",
"Concept 1B",
"Concept 1B",
"Concept 1B",
"Concept 1B",
"Concept 1B",
"Concept 1B",
];
---
<style>
.title {
margin-bottom: var(--space-3);
}
.tanks {
/* overflow-x: scroll; */
overflow-x: hidden;
z-index: 1;
.content {
display: flex;
gap: 2rem;
}
}
</style>
<Section>
<Heading size="2" className="title">{strings.home.tanks}</Heading>
<div class="tanks">
<div class="content">
{popular.map((tank) => <TankCard {tank} />)}
</div>
</div>
<ToolCard gradient {locale} tool={tools.tanks} />
<ToolsWrapper>
<ToolCard {locale} tool={tools.compare} />
<ToolCard {locale} tool={tools.performance} />
</ToolsWrapper>
</Section>
@@ -0,0 +1,31 @@
---
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import { Heading } from "./Heading";
import { Section } from "./Section";
import ToolCard from "./ToolCard.astro";
import ToolsWrapper from "./ToolsWrapper.astro";
interface Props {
locale: string;
}
const { locale } = Astro.props;
const strings = await api.strings(locale);
---
<style>
.title {
margin-bottom: var(--space-3);
}
</style>
<Section>
<Heading size="2" className="title">{strings.home.technical}</Heading>
<ToolsWrapper>
<ToolCard {locale} tool={tools.api} />
<ToolCard {locale} tool={tools.changelogs} />
</ToolsWrapper>
</Section>
@@ -1,7 +1,10 @@
.link {
color: var(--accent-11);
text-decoration-color: currentColor;
display: flex;
align-items: center;
gap: var(--space-3);
&[data-underline="hover"],
&[data-underline="never"] {
text-decoration: none;
@@ -12,10 +15,6 @@
text-decoration: underline;
}
&[data-high-contrast="true"] {
color: var(--accent-12);
}
svg {
width: 1.25em;
height: 1.25em;
@@ -1,21 +1,29 @@
import type { ComponentProps } from "react";
import { classNames } from "../../core/ui/classNames";
import "./index.css";
import type { Color } from "../../core/ui/color";
import styles from "./index.module.css";
export interface LinkProps extends ComponentProps<"a"> {
underline?: "always" | "hover" | "never";
highContrast?: boolean;
color?: Color | "accent";
}
export function Link({
highContrast,
className,
underline = "always",
color = "accent",
style,
...props
}: LinkProps) {
return (
<a
className={classNames("link", className)}
className={classNames(styles.link, className)}
style={{
color: `var(--${color}-${highContrast ? 12 : 11})`,
...style,
}}
{...props}
data-underline={underline}
data-high-contrast={highContrast}
@@ -1,10 +1,6 @@
---
import { BlitzKitIcon } from "../icons/BlitzKit";
import { LinkI18n } from "./LinkI18n";
import { Text } from "./Text";
import { api } from "../core/api/dynamic";
import { tools } from "../core/tools/tools";
import type { Tool } from "../core/tools/tools";
import { HamburgerMenuIcon, MagnifyingGlassIcon } from "@radix-ui/react-icons";
interface Props {
@@ -56,9 +52,7 @@ const { locale } = Astro.props;
gap: var(--space-2);
cursor: pointer;
color: var(--color-regular);
text-decoration: none;
color: var(--gray-11);
.selector {
padding: var(--space-2);
@@ -102,7 +96,14 @@ const { locale } = Astro.props;
<div id="navbar">
<div class="content">
<div class="group">
<LinkI18n {locale} href="/" className="action" tabIndex={0}>
<LinkI18n
color="gray"
highContrast
{locale}
href="/"
className="action"
tabIndex={0}
>
<div class="selector">
<BlitzKitIcon className="icon" />
</div>
@@ -110,13 +111,27 @@ const { locale } = Astro.props;
</div>
<div class="group">
<LinkI18n {locale} href="/" className="action" tabIndex={0}>
<LinkI18n
color="gray"
highContrast
{locale}
href="/"
className="action"
tabIndex={0}
>
<div class="selector">
<MagnifyingGlassIcon className="icon" />
</div>
</LinkI18n>
<LinkI18n {locale} href="/" className="action" tabIndex={0}>
<LinkI18n
color="gray"
highContrast
{locale}
href="/"
className="action"
tabIndex={0}
>
<div class="selector">
<HamburgerMenuIcon className="icon" />
</div>
@@ -0,0 +1 @@
export function Scroller() {}
@@ -1,7 +1,7 @@
.section {
display: flex;
justify-content: center;
padding: var(--space-4);
padding: var(--space-5);
.content {
flex: 1;
@@ -1,6 +1,6 @@
import type { ComponentProps } from "react";
import { classNames } from "../../core/ui/classNames";
import "./index.css";
import styles from "./index.module.css";
export interface SectionProps extends ComponentProps<"div"> {
first?: boolean;
@@ -10,10 +10,10 @@ export function Section({ className, children, ...props }: SectionProps) {
return (
<div
data-first={props.first}
className={classNames("section", className)}
className={classNames(styles.section, className)}
{...props}
>
<div className="content">{children}</div>
<div className={styles.content}>{children}</div>
</div>
);
}
@@ -0,0 +1,31 @@
.tank-card {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-2);
.icon-wrapper {
position: relative;
.flag {
position: absolute;
top: 0;
left: 0;
background-size: cover;
background-position: left center;
width: 75%;
height: 50%;
}
.icon {
width: 7rem;
aspect-ratio: 4 / 3;
position: relative;
background-size: 150%;
background-position: center;
}
}
}
@@ -0,0 +1,30 @@
import { Text } from "../Text";
import styles from "./index.module.css";
interface TankCard {
tank: string;
}
export function TankCard({ tank }: TankCard) {
return (
<div className={styles["tank-card"]}>
<div className={styles["icon-wrapper"]}>
<div
className={styles.flag}
style={{
backgroundImage: "url(https://i.imgur.com/QGUfXNo.png)",
}}
/>
<div
className={styles.icon}
style={{
backgroundImage: "url(https://i.imgur.com/HrkTwHc.png)",
}}
/>
</div>
<Text className={styles.name}>{tank}</Text>
</div>
);
}
@@ -9,19 +9,22 @@ import { Text } from "./Text";
interface Props {
tool: Tool;
locale: string;
gradient?: boolean;
}
const { tool, locale } = Astro.props;
const { tool, locale, gradient } = Astro.props;
const strings = await api.strings(locale);
const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
---
<style>
.tool-card {
display: flex;
flex-direction: column;
height: 10rem;
position: relative;
align-items: stretch;
gap: 0;
border-radius: var(--space-3);
@@ -29,9 +32,8 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
background-position: center;
overflow: hidden;
&[data-significant="true"] {
grid-column: 1 / -1;
height: 15rem;
&[data-gradient="true"] {
height: 10rem;
}
.poster {
@@ -39,6 +41,13 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
background-size: cover;
background-position: center;
.gradient {
width: 100%;
height: 100%;
background: linear-gradient(var(--gray-1), transparent);
}
}
.info {
@@ -64,7 +73,7 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
style={{
backgroundImage: `url(/assets/tools/${tool.id}.webp)`,
}}
data-significant={tool.significant}
data-gradient={gradient}
>
<div
class="poster"
@@ -72,6 +81,7 @@ const toolStrings = strings.tools[tool.id as keyof typeof strings.tools];
backgroundImage: `url(/assets/tools/${tool.id}.webp)`,
}}
>
{gradient && <div class="gradient" />}
</div>
<div class="info">
@@ -0,0 +1,11 @@
<style>
.tools {
display: grid;
gap: var(--space-4);
grid-template-columns: repeat(2, 1fr);
}
</style>
<div class="tools">
<slot />
</div>
+11 -7
View File
@@ -10,23 +10,27 @@ const api = defineCollection({
import: "default",
});
const paths: { id: string; body: string }[] = [];
const paths: { id: string; docs: string }[] = [];
for (const path in globbed) {
const id = path.replace("./pages/api/", "").replace(".ts", "");
const body = (globbed[path] as string).replaceAll("\r\n", "\n");
const docs = body.match(
/\/\*\*\n((( \*.*)\n)+) \*\/\nexport (async )?function GET\(/
)?[1].spl;
paths.push({ id, body, docs: docs?.[1] ?? undefined });
const body = (globbed[path] as string).replaceAll("\r\n", "\n");
const docs = body
.match(
/\/\*\*\n((( \*.*)\n)+) \*\/\nexport (async )?function GET\(/,
)?.[1]
.replaceAll(/^ \* ?/gm, "");
if (!docs) continue;
paths.push({ id, docs });
}
return paths;
},
schema: z.object({
body: z.string(),
docs: z.optional(z.string()),
}),
});
+7 -2
View File
@@ -3,7 +3,6 @@ import type { Color } from "../ui/color";
export interface Tool {
id: string;
significant?: boolean;
accent: Color;
banner_background_position: "top" | "center" | "bottom";
}
@@ -12,7 +11,6 @@ export const tools: Record<string, Tool> = {
tanks: {
id: "tanks",
significant: true,
accent: "plum",
banner_background_position: "top",
},
@@ -86,4 +84,11 @@ export const tools: Record<string, Tool> = {
accent: "brown",
banner_background_position: "bottom",
},
changelogs: {
id: "changelogs",
accent: "gray",
banner_background_position: "bottom",
},
};
@@ -3,6 +3,7 @@ import BaseMeta from "../components/BaseMeta.astro";
import BaseStyles from "../components/BaseStyles.astro";
import ColorAlias from "../components/ColorAlias.astro";
import ColorScale from "../components/ColorScale.astro";
import Footer from "../components/Footer.astro";
import Navbar from "../components/Navbar.astro";
import type { Color } from "../core/ui/color";
@@ -66,5 +67,7 @@ const { accent, noNavbar, locale } = Astro.props;
<div class="app">
<slot />
</div>
<Footer {locale} />
</body>
</html>
@@ -1,7 +1,6 @@
---
import "@radix-ui/colors/amber-dark.css";
import { getCollection } from "astro:content";
import { tools } from "../../../core/tools/tools";
import BaseLayout from "../../../layouts/BaseLayout.astro";
export { getStaticPaths } from "../index.astro";
@@ -9,8 +8,6 @@ export { getStaticPaths } from "../index.astro";
const { locale } = Astro.props;
const collection = await getCollection("api");
console.log(collection);
const paths: {
path: string;
documentation: string;
@@ -19,15 +16,14 @@ const paths: {
paths.sort((a, b) => a.path.localeCompare(b.path));
---
<BaseLayout selectedTool={tools.api} {locale} accent="lime">
<BaseLayout {locale} accent="lime">
<h1>api</h1>
{
collection.map(({ id, data }) => (
<>
<h2>{id}</h2>
<pre style="background-color: red;">{data.docs}</pre>
<pre>{data.body}</pre>
<pre>{data.docs}</pre>
</>
))
}
@@ -1,11 +1,13 @@
---
import { Class1 } from "@blitzkit/game";
import locales from "@blitzkit/i18n/locales.json";
import type { GetStaticPaths } from "astro";
import ColorScale from "../../components/ColorScale.astro";
import HomeCosmetics from "../../components/HomeCosmetics.astro";
import HomeGames from "../../components/HomeGames.astro";
import HomeHero from "../../components/HomeHero.astro";
import { Section } from "../../components/Section";
import ToolCard from "../../components/ToolCard.astro";
import HomePlayers from "../../components/HomePlayers.astro";
import HomeTanks from "../../components/HomeTanks.astro";
import HomeTechnical from "../../components/HomeTechnical.astro";
import { tools } from "../../core/tools/tools";
import BaseLayout from "../../layouts/BaseLayout.astro";
@@ -18,31 +20,17 @@ export const getStaticPaths = (() => {
];
}) satisfies GetStaticPaths;
Class1.test();
const { locale } = Astro.props;
---
<style>
.tools {
display: grid;
gap: var(--space-4);
grid-template-columns: repeat(2, 1fr);
}
</style>
<BaseLayout {locale} accent="amber">
<HomeHero {locale} />
{Object.values(tools).map((tool) => <ColorScale color={tool.accent} />)}
<!-- <RecentItems {locale} client:only="react">
<RecentItems {locale} skeleton slot="fallback" />
</RecentItems> -->
<Section>
<div class="tools">
{Object.values(tools).map((tool) => <ToolCard {locale} {tool} />)}
</div>
</Section>
<HomeTanks {locale} />
<HomePlayers {locale} />
<HomeGames {locale} />
<HomeCosmetics {locale} />
<HomeTechnical {locale} />
</BaseLayout>
@@ -4,6 +4,9 @@ import { api } from "../../../core/api/dynamic";
export { getStaticPaths } from "./[id].pb";
/**
* Even Noah can't save these animals.
* Even Noah can't save these animals.
* Even Noah can't save these animals.
* Even Noah can't save these animals.
*/
export async function GET({ params }: APIContext<never, { id: string }>) {