Compare commits

..
64 Commits
Author SHA1 Message Date
TrèsAbhi a704b291fd fix: consider shells 2025-08-01 12:37:40 -05:00
TrèsAbhi e1b5b21fae feat: cursor 2025-08-01 12:25:09 -05:00
TrèsAbhi 097f2792ae feat: cursor 2025-07-31 20:51:54 -05:00
TrèsAbhi 089d0e9682 feat: prettier 2025-07-31 20:40:02 -05:00
TrèsAbhi 6a92b3ae80 feat: x axis 2025-07-31 20:18:36 -05:00
TrèsAbhi 1e91065033 feat: assault graph 2025-07-31 14:42:12 -05:00
TrèsAbhi b20bb97ea3 feat: reorder stuff 2025-07-31 14:12:14 -05:00
TrèsAbhi ba97a9f28b feat: some implementation 2025-07-31 14:07:21 -05:00
TrèsAbhi 81e480f983 fix: remove debug code 2025-07-31 13:44:55 -05:00
TrèsAbhi 40e4e0a274 feat: start of assault shells 2025-07-31 13:44:14 -05:00
TrèsAbhi 83b7de77de feat: start of assault shells 2025-07-31 13:40:30 -05:00
TrèsAbhi 20f7119854 New translations en.json (Russian) (#158) 2025-07-28 12:19:29 -05:00
TrèsAbhi 275ddcc7a6 New Crowdin updates (#157) 2025-07-27 20:54:42 -05:00
TrèsAbhi 4858f31da4 feat: logs 2025-07-27 20:42:22 -05:00
TrèsAbhi 4bc255a624 fix: clear filters no longer shows up after searching and clearing the search bar 2025-07-27 20:36:23 -05:00
TrèsAbhi 17755641a1 feat: sorting by he shell penetratoin 2025-07-27 20:31:21 -05:00
TrèsAbhi 0e6b0087ce fix: tankopedia compare acknoledge selected equipment 2025-07-27 20:27:43 -05:00
TrèsAbhi fcd084a86f fix: tankopedia compare acknoledge selected shell 2025-07-27 20:26:58 -05:00
TrèsAbhi af699ff5b7 fix: guns don't appear transparent when moved far away from camera 2025-07-27 20:15:08 -05:00
TrèsAbhi 93665df223 feat: scrollable hero 2025-07-27 20:11:16 -05:00
TrèsAbhi f8b4f9372a fix: stop equipment definitions fetch spam 2025-07-27 20:09:08 -05:00
TrèsAbhi e84e15daf4 fix: missing navbar background images 2025-07-27 20:07:47 -05:00
TrèsAbhi d7af7e19dd fix: integrated navbar 2025-07-27 15:36:46 -05:00
TrèsAbhi c5cf172e42 fix: remove text outline, it just doesn't work 2025-07-27 15:34:22 -05:00
TrèsAbhi 2e8cac885c Update rating-na.yml 2025-07-15 23:37:10 -05:00
TrèsAbhi 9ed4a856bf Update rating-asia.yml 2025-07-15 23:36:36 -05:00
TrèsAbhi eedd4b3f27 Update rating-eu.yml 2025-07-15 23:36:03 -05:00
TrèsAbhi 3b7fe0b114 Update averages.yml 2025-07-15 11:17:37 -05:00
TrèsAbhi a6d66b94f5 Update host-bot.yml 2025-07-15 09:43:27 -05:00
TrèsAbhi c7a7bbb809 Update host-bot.yml 2025-07-15 09:41:44 -05:00
TrèsAbhi 02ce6ba8d9 Update index.tsx 2025-07-12 12:46:40 -05:00
TrèsAbhi 9dd057d594 Update host-bot.yml 2025-07-11 18:13:13 -05:00
TrèsAbhi 64ec981496 Update host-bot.yml 2025-07-11 18:11:54 -05:00
TrèsAbhi 8afafdeece Update host-bot.yml 2025-07-11 18:10:46 -05:00
TrèsAbhi 6b9fd1d392 fix: time out handling 2025-07-11 12:34:33 -05:00
TrèsAbhi c1efc50134 feat: disable popular tanks 2025-07-11 12:31:10 -05:00
TrèsAbhi b4b1f4e916 feat: cleaner logging 2025-07-11 12:28:50 -05:00
TrèsAbhi 3de0c40ce3 fix: retry host 2025-07-11 12:27:57 -05:00
TrèsAbhi 893bfa8393 feat: tags 2025-06-26 10:36:51 -05:00
TrèsAbhi cc25535c34 Update Party3.astro 2025-06-26 10:26:13 -05:00
TrèsAbhi a4cdf16fcd Update Party3.astro 2025-06-26 10:26:01 -05:00
TrèsAbhi 36588b11e6 Update package.json 2025-06-26 10:21:25 -05:00
TrèsAbhi e927838c14 Update astro.config.mjs 2025-06-26 10:21:18 -05:00
TrèsAbhi 5197ebb6a7 Update Party3.astro 2025-06-26 10:21:07 -05:00
TrèsAbhi 51089a3e91 Update tankModels.ts 2025-06-26 09:55:23 -05:00
TrèsAbhi c6121fd4bd fix: add base 2025-06-25 19:47:21 -05:00
TrèsAbhi 7dca9d3244 Update tankModels.ts 2025-06-09 11:19:27 -05:00
TrèsAbhi abebfcf6c6 feat: branch 2025-06-08 17:32:13 +00:00
TrèsAbhi 470869418c Update website.yml 2025-06-08 12:24:45 -05:00
TrèsAbhi cd2bad3b27 feat: asset base 2025-06-08 17:20:08 +00:00
TrèsAbhi 5e9555aa57 fix: identity encoding 2025-06-07 12:35:23 -05:00
TrèsAbhi 084d55b853 Update commitMultipleFiles.ts 2025-06-07 10:46:45 -05:00
TrèsAbhi a3879f3fa7 Update commitMultipleFiles.ts 2025-06-07 10:08:52 -05:00
TrèsAbhi 135a2d74c4 Update commitMultipleFiles.ts 2025-06-07 09:34:14 -05:00
TrèsAbhi 233f866c9e Update assets.yml 2025-06-06 23:28:21 -05:00
TrèsAbhi 9e880ff24f Update assets.yml 2025-06-06 21:55:03 -05:00
TrèsAbhi 36039563e0 Update assets.yml 2025-06-06 21:54:16 -05:00
TrèsAbhi 022e970537 Update createBlob.ts 2025-06-06 14:48:36 -05:00
TrèsAbhi 51e99ec442 Update applyPatches.ts 2025-06-05 15:52:06 -05:00
TrèsAbhi caeba34ba1 feat: add internals 2025-06-05 14:22:27 -05:00
TrèsAbhi 6d6a634973 fix: a bunch of stupid things 2025-06-05 13:01:50 -05:00
TrèsAbhi 55e6599eaa Update host-bot.yml 2025-06-05 09:23:45 -05:00
TrèsAbhi e146366385 New Crowdin updates (#156)
* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Russian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Simplified)
2025-06-04 09:16:49 -05:00
TrèsAbhi b1dd319c1e Create discord 2025-05-26 23:31:53 -05:00
155 changed files with 4085 additions and 3373 deletions

No files matched your search

+6 -5
View File
@@ -29,7 +29,7 @@ concurrency:
env:
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
GH_TOKEN: ${{ secrets.ASSET_BOT }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
@@ -37,8 +37,8 @@ env:
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
WOTB_DLC_CDN: ${{ secrets.WOTB_DLC_CDN }}
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
PUBLIC_ASSET_BRANCH: ${{ github.event.inputs.cdn_branch || secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_ASSET_REPO: blitzkit/assets
PUBLIC_ASSET_BRANCH: main
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
@@ -51,8 +51,9 @@ env:
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: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_ASSET_FAST_USER: blitzkit
PUBLIC_ASSET_FAST_REPO: assets
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
jobs:
download_client:
+11
View File
@@ -14,6 +14,17 @@ env:
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 }}
jobs:
build:
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
- name: Download release assets
run: |
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/tresabhi/blitzkit/releases/latest \
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 \")
+11
View File
@@ -27,4 +27,15 @@ jobs:
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 }}
run: bun build:ratingleaderboard --region=asia
+11
View File
@@ -27,4 +27,15 @@ jobs:
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 }}
run: bun build:ratingleaderboard --region=eu
+11
View File
@@ -27,4 +27,15 @@ jobs:
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 }}
run: bun build:ratingleaderboard --region=com
+2 -4
View File
@@ -18,8 +18,6 @@ concurrency:
env:
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
ALLOW_ROBOTS: 'true'
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
@@ -29,8 +27,8 @@ env:
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_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
jobs:
build:
+2 -2
View File
@@ -1,7 +1,7 @@
node_modules
_node_modules
package-lock.json
.env
*.env
/test-results/
/playwright-report/
/playwright/.cache/
@@ -22,7 +22,7 @@ depots
public/sitemap*
/firebase.json
target
# *.ts
# packages/core/src/protos/*.ts
/.vercel
/.astro
.vercel
+3
View File
@@ -4,3 +4,6 @@
[submodule "submodules/CUE4Parse"]
path = submodules/CUE4Parse
url = https://github.com/FabianFG/CUE4Parse
[submodule "submodules/blitzkit-internal"]
path = submodules/blitzkit-internal
url = https://github.com/blitzkit/internal
+1 -6
View File
@@ -33,7 +33,6 @@
"blitzkit",
"blitzrinth",
"blitzstars",
"bufbuild",
"cacheable",
"Callouts",
"Camo",
@@ -76,7 +75,6 @@
"dxgi",
"echarts",
"Everytime",
"FABLEGEAR",
"FASTNAME",
"flexdirection",
"FOURCC",
@@ -88,6 +86,7 @@
"gameplay",
"glsl",
"GLTF",
"gtag",
"haha",
"highp",
"iife",
@@ -110,7 +109,6 @@
"Maddoxkkm",
"malum",
"mantlets",
"MECHA",
"metallicness",
"metalness",
"minitelrose",
@@ -148,11 +146,9 @@
"POSITIVEY",
"POSITIVEZ",
"precompute",
"PROGRESSTON",
"Promisable",
"proto",
"protobuf",
"protoc",
"protos",
"Pyogenics",
"ratingleaderboard",
@@ -208,7 +204,6 @@
"vitepress",
"Vovko",
"wargaming",
"WARHAMMER",
"webp",
"whitespaces",
"WHSS",
Regular → Executable
BIN
View File
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
# BlitzKit 1.27.12
This update only affects the website.
## Features
- Added the ability to sort by HE shell penetration
- The Tankopedia compare bars now account for equipment and selected shells
- Made the hero section of the Tankopedia a bit shorter to show users that the page is scrollable
## Fixes
- The "Clear filters" button no longer shows up after clearing the search bar
- Guns for some tanks no longer go transparent when far away from the camera
- The dynamic armor tab no longer lags and flickers when rotating the turret of a tank
- Reimplemented the missing tool backgrounds in the navigation bar hamburger menu
- The navigation bar now properly goes transparent for pages that request like the Tankopedia pages
- Removed the tank name text outline because it doesn't work on most devices
+3 -12
View File
@@ -1,13 +1,12 @@
{
"name": "@blitzkit",
"name": "blitzkit",
"private": true,
"version": "1.27.11",
"version": "1.27.12",
"description": "🎉 Tools for everything World of Tanks Blitz",
"type": "module",
"types": "./types.d.ts",
"workspaces": [
"packages/*",
"submodules/*"
"packages/*"
],
"scripts": {
"build:assets": "cd packages/scripts && bun run build:assets",
@@ -42,23 +41,15 @@
"license": "MIT",
"dependencies": {
"googleapis": "^144.0.0",
"js-yaml": "^4.1.0",
"lodash-es": "^4.17.21",
"protobufjs": "^7.5.2",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"quicklime": "^1.2.0",
"sharp": "^0.33.5"
},
"devDependencies": {
"@astrojs/react": "^4.3.0",
"@types/bun": "latest",
"@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12",
"@types/react": "^19.1.5",
"@types/react-dom": "^19.1.5",
"@types/node": "^22.14.1",
"astro": "^5.8.0",
"prettier": "^3.5.3",
"prisma": "^6.6.0",
"typescript": "^5.8.3"
+1
View File
@@ -9,6 +9,7 @@
"satori": "^0.10.14",
"@resvg/resvg-js": "^2.6.2",
"discord.js": "^14.16.3",
"react": "^18.3.1",
"@radix-ui/colors": "^3.0.0",
"fuzzysort": "^2.0.4",
"bepaint": "^0.1.0-beta.3",
+1 -8
View File
@@ -1,11 +1,4 @@
{
"extends": "../../tsconfig.json",
"include": [
"src/**/*",
"../core/src/blitzkit/supportedLocales.ts",
"../i18n/src/unwrapper.ts"
],
"compilerOptions": {
"baseUrl": "../../"
}
"include": ["src/**/*", "../core/src/blitzkit/supportedLocales.ts", "../i18n/src/unwrapper.ts"]
}
-1
View File
@@ -4,7 +4,6 @@
"type": "module",
"main": "src/index.ts",
"dependencies": {
"@blitzkit/closed": "workspace:*",
"@octokit/plugin-throttling": "^8.2.0",
"@octokit/rest": "^20.1.1",
"@prisma/client": "^6.6.0",
@@ -1,28 +0,0 @@
import { CatalogItem } from '@protos/blitz_items';
import { Any } from '@protos/google/protobuf/any';
import { MessageFns } from '../protos';
export class CatalogItemAccessor {
private components: Record<string, Any> = {};
constructor(item: CatalogItem) {
for (const component of item.components) {
if (
component.value === undefined ||
component.value.component === undefined
) {
continue;
}
this.components[component.key] = component.value.component;
}
}
get<Type>(Message: MessageFns<Type>, component: string) {
if (component in this.components) {
return Message.decode(this.components[component].value);
}
throw new Error(`Unknown component: ${component}`);
}
}
-4
View File
@@ -1,4 +0,0 @@
export function entityName(entity: string) {
const [_, ...name] = entity.split('.');
return name.join('.');
}
-3
View File
@@ -1,9 +1,7 @@
export * from './canSplash';
export * from './catalogItemAccessor';
export * from './clans';
export * from './classes';
export * from './constants';
export * from './entityName';
export * from './equipmentPrice';
export * from './fetchBlitz';
export * from './fetchGlossary';
@@ -20,7 +18,6 @@ export * from './getTankStats';
export * from './idToRegion';
export * from './isOnGoingRatingSeason';
export * from './isValidBlitzId';
export * from './metadataAccessor';
export * from './nations';
export * from './normalizeExtra';
export * from './normalizeIds';
@@ -1,38 +0,0 @@
import { CatalogItem } from '@protos/blitz_items';
import { Metadata } from '@protos/blitz_metadata';
import { CatalogItemAccessor } from './catalogItemAccessor';
export class UnpackedMetadataAccessor {
private items: Record<string, CatalogItemAccessor> = {};
constructor(metadata: Metadata) {
for (const item of metadata.catalog_items) {
if (item.catalog_id in this.items) {
throw new Error(`Duplicate catalog ID: ${item.catalog_id}`);
}
this.items[item.catalog_id] = new CatalogItemAccessor(item);
}
}
get(item: string) {
if (item in this.items) return this.items[item];
throw new Error(`Unknown catalog ID: ${item}`);
}
}
export class DiscreteMetadataAccessor {
constructor(private base: string) {}
async get(item: string) {
const response = await fetch(`${this.base}/${item}.pb`);
if (!response.ok) throw new Error(`Unknown catalog ID: ${item}`);
const buffer = await response.arrayBuffer();
const catalogItem = CatalogItem.decode(new Uint8Array(buffer));
return new CatalogItemAccessor(catalogItem);
}
}
+1 -8
View File
@@ -1,12 +1,5 @@
import { assertSecret } from './assertSecret';
const repo = assertSecret(import.meta.env.PUBLIC_ASSET_REPO);
const branch = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
const fastUser = assertSecret(import.meta.env.PUBLIC_ASSET_FAST_USER);
const fastRepo = assertSecret(import.meta.env.PUBLIC_ASSET_FAST_REPO);
export function asset(path: string) {
return branch === 'main'
? `https://${fastUser}.github.io/${fastRepo}/${path}`
: `https://raw.githubusercontent.com/${repo}/${branch}/${path}`;
return `${assertSecret(import.meta.env.PUBLIC_ASSET_BASE)}/${path}`;
}
-1
View File
@@ -46,5 +46,4 @@ export * from './gallery';
export * from './metaSortTank';
export * from './popularTanks';
export * from './romanize';
export * from './slugify';
export * from './youtubers';
-16
View File
@@ -1,16 +0,0 @@
import { deburr } from 'lodash-es';
const nonAlphanumericRegex = /[^a-z0-9]/g;
const multipleDashesRegex = /--+/g;
const trailingDashRegex = /-$/g;
const leadingDashRegex = /^-/g;
export function slugify(name: string) {
let slug = deburr(name).toLowerCase();
slug = slug.replaceAll(nonAlphanumericRegex, '-');
slug = slug.replaceAll(multipleDashesRegex, '-');
slug = slug.replaceAll(trailingDashRegex, '');
slug = slug.replaceAll(leadingDashRegex, '');
return slug;
}
+7 -9
View File
@@ -1,5 +1,5 @@
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { deburr } from 'lodash-es';
import { SUPPORTED_LOCALES } from '../../../i18n/src/strings';
import { I18nString } from '../protos';
import { fetchCamouflageDefinitions } from './camouflageDefinitions';
import { fetchTankDefinitions } from './tankDefinitions';
@@ -26,8 +26,8 @@ export async function fetchTankNames() {
searchableNameDeburr,
camouflages: tank.camouflages
?.map((id) =>
locales.supported.map(
({ locale }) =>
SUPPORTED_LOCALES.map(
(locale) =>
camouflageDefinitions.camouflages[id]?.name.locales[locale],
),
)
@@ -42,11 +42,9 @@ export async function fetchTankNames() {
}
export const SEARCH_KEYS = [
...locales.supported
.map(({ locale }) => [
`searchableName.locales.${locale}`,
`searchableNameDeburr.locales.${locale}`,
])
.flat(),
...SUPPORTED_LOCALES.map((locale) => [
`searchableName.locales.${locale}`,
`searchableNameDeburr.locales.${locale}`,
]).flat(),
'camouflages',
];
@@ -1,5 +0,0 @@
import { MessageFns } from '../protos';
export function encodePBBuffer<Type>(message: MessageFns<Type>, data: Type) {
return Buffer.from(message.encode(data).finish());
}
-1
View File
@@ -1,3 +1,2 @@
export * from './encodePBBuffer';
export * from './fetchPB';
export * from './pbMap';
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: average_definitions.proto
// source: packages/core/src/protos/average_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message CamouflageDefinitions {
map<uint32, Camouflage> camouflages = 1;
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: camouflage_definitions.proto
// source: packages/core/src/protos/camouflage_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message ConsumableDefinitions {
map<uint32, Consumable> consumables = 1;
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: consumable_definitions.proto
// source: packages/core/src/protos/consumable_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -11,14 +11,14 @@ import { createBaseI18nString, I18nString } from "./i18n";
export const protobufPackage = "blitzkit";
export enum ConsumableTankCategoryFilterCategory {
CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP = 0,
CLIP = 0,
}
export function consumableTankCategoryFilterCategoryFromJSON(object: any): ConsumableTankCategoryFilterCategory {
switch (object) {
case 0:
case "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP":
return ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP;
return ConsumableTankCategoryFilterCategory.CLIP;
default:
throw new globalThis.Error(
"Unrecognized enum value " + object + " for enum ConsumableTankCategoryFilterCategory",
@@ -28,7 +28,7 @@ export function consumableTankCategoryFilterCategoryFromJSON(object: any): Consu
export function consumableTankCategoryFilterCategoryToJSON(object: ConsumableTankCategoryFilterCategory): string {
switch (object) {
case ConsumableTankCategoryFilterCategory.CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP:
case ConsumableTankCategoryFilterCategory.CLIP:
return "CONSUMABLE_TANK_CATEGORY_FILTER_CATEGORY_CLIP";
default:
throw new globalThis.Error(
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message EquipmentDefinitions {
map<string, EquipmentPreset> presets = 1;
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: equipment_definitions.proto
// source: packages/core/src/protos/equipment_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
+1 -1
View File
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message Gallery {
repeated Avatar avatars = 1;
+1 -1
View File
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: gallery.proto
// source: packages/core/src/protos/gallery.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message GameDefinitions {
required string version = 1;
+1 -1
View File
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: game_definitions.proto
// source: packages/core/src/protos/game_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
+1 -1
View File
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: i18n.proto
// source: packages/core/src/protos/i18n.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message MapDefinitions {
map<int32, MapDefinition> maps = 1;
+1 -1
View File
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: map_definitions.proto
// source: packages/core/src/protos/map_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: model_definitions.proto
// source: packages/core/src/protos/model_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
+1 -1
View File
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: popular_tanks.proto
// source: packages/core/src/protos/popular_tanks.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,8 +2,8 @@ syntax = "proto2";
package blitzkit;
import "consumable_definitions.proto";
import "i18n.proto";
import "packages/core/src/protos/consumable_definitions.proto";
import "packages/core/src/protos/i18n.proto";
message ProvisionDefinitions {
map<uint32, Provision> provisions = 1;
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: provision_definitions.proto
// source: packages/core/src/protos/provision_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: rating_leaderboard.proto
// source: packages/core/src/protos/rating_leaderboard.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
+1 -1
View File
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: reviews.proto
// source: packages/core/src/protos/reviews.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-ts_proto v2.2.2
// protoc v5.28.2
// source: skill_definitions.proto
// source: packages/core/src/protos/skill_definitions.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@@ -2,7 +2,7 @@ syntax = "proto2";
package blitzkit;
import "i18n.proto";
import "packages/core/src/protos/i18n.proto";
message TankDefinitions {
map<uint32, TankDefinition> tanks = 1;
@@ -157,6 +157,17 @@ message GunDefinitionBase {
required float dispersion_damaged = 13;
repeated Unlock unlocks = 14;
required uint32 shell_capacity = 15;
optional AssaultRanges assault_ranges = 16;
}
message AssaultRanges {
repeated AssaultRange ranges = 1;
repeated ShellType types = 2;
}
message AssaultRange {
required float distance = 1;
required float factor = 2;
}
message ShellDefinition {
File diff suppressed because it is too large. Load diff
+1 -4
View File
@@ -1,7 +1,4 @@
{
"extends": "../../tsconfig.json",
"include": ["src/**/*", "../i18n/src/strings.ts"],
"compilerOptions": {
"baseUrl": "../../"
}
"include": ["src/**/*", "../i18n/src/strings.ts"]
}
+87 -2
View File
@@ -1,8 +1,89 @@
import type en from '../strings/en.json';
import { merge } from 'ts-deepmerge';
import en from '../strings/en.json';
import es from '../strings/es.json';
import fr from '../strings/fr.json';
import ja from '../strings/ja.json';
import pl from '../strings/pl.json';
import pt from '../strings/pt.json';
import ru from '../strings/ru.json';
import uk from '../strings/uk.json';
import zh from '../strings/zh.json';
export type BlitzKitStrings = typeof en;
export const SUPPORTED_LOCALE_FLAGS: Record<string, string> = {
const stringsRaw = { en, es, fr, ja, pl, pt, ru, uk, zh };
export const SUPPORTED_LOCALES = Object.keys(stringsRaw) as SupportedLocale[];
export const DEFAULT_LOCALE = SUPPORTED_LOCALES[0];
function redact(string: string) {
const matches = [...string.matchAll(/%s\d+/g)];
const characters = string
.split('')
.map((char) => (char === ' ' ? ' ' : '█')) as string[];
matches.forEach((match) => {
const start = match.index;
const matchText = match[0];
for (let i = 0; i < matchText.length; i++) {
characters[start + i] = matchText[i];
}
});
return characters.join('');
}
function nuke(object: TranslationTree) {
for (const key in object) {
const typedKey = key as keyof typeof object;
if (typeof object[typedKey] === 'string') {
const value = object[typedKey];
object[typedKey] = redact(value as string);
} else nuke(object[typedKey] as TranslationTree);
}
}
const stringsPartial: Partial<Record<SupportedLocale, TranslationTree>> = {};
for (const locale in stringsRaw) {
if (locale === DEFAULT_LOCALE) {
stringsPartial[DEFAULT_LOCALE] = stringsRaw[DEFAULT_LOCALE];
continue;
}
const localeStrings = stringsRaw[locale as SupportedLocale];
stringsPartial[locale as SupportedLocale] = merge(
stringsRaw[DEFAULT_LOCALE],
localeStrings,
);
if (import.meta.env.PUBLIC_DEBUG_MISSING_I18N === 'true') {
nuke(stringsPartial[locale as SupportedLocale]!);
}
}
export const STRINGS = stringsPartial as Record<
SupportedLocale,
BlitzKitStrings
>;
export type SupportedLocale = keyof typeof stringsRaw;
export const SUPPORTED_LOCALE_BLITZ_MAP: Record<SupportedLocale, string> = {
en: 'en',
es: 'es',
fr: 'fr',
ja: 'ja',
pt: 'pt',
ru: 'ru',
uk: 'uk',
zh: 'zh-Hans',
pl: 'pl',
};
export const SUPPORTED_LOCALE_FLAGS: Record<SupportedLocale, string> = {
en: '🇺🇸',
es: '🇪🇸',
fr: '🇫🇷',
@@ -13,3 +94,7 @@ export const SUPPORTED_LOCALE_FLAGS: Record<string, string> = {
zh: '🇨🇳',
pl: '🇵🇱',
};
export type TranslationTree = { [key: string]: TranslationNode };
export type TranslationNode = string | TranslationTree;
+2 -2
View File
@@ -1,5 +1,5 @@
import { I18nString } from '@blitzkit/core';
import locales from '../locales.json' with { type: 'json' };
import { DEFAULT_LOCALE } from './strings';
export function unwrapper(locale: string) {
return function (i18nString: I18nString) {
@@ -7,6 +7,6 @@ export function unwrapper(locale: string) {
return i18nString.locales[locale];
}
return i18nString.locales[locales.default];
return i18nString.locales[DEFAULT_LOCALE];
};
}
+21 -68
View File
@@ -6,18 +6,6 @@
},
"common": {
"tiers": {
"0": "Unknown tier",
"1": "I",
"2": "II",
"3": "III",
"4": "IV",
"5": "V",
"6": "VI",
"7": "VII",
"8": "Vintage"
},
"units": {
"m": "%s1m",
"mm": "%s1mm",
@@ -98,44 +86,15 @@
},
"nations": {
"0": "Unknown nation",
"1": "U.S.S.R.",
"2": "Germany",
"3": "U.S.A.",
"4": "China",
"5": "France",
"6": "U.K.",
"7": "Japan",
"8": "Europe",
"9": "Poland",
"10": "Australia",
"11": "Canada",
"12": "Italy",
"13": "Finland",
"14": "Czech",
"15": "Hybrid Nation",
"16": "GDR",
"17": "Ireland",
"18": "Scotland",
"19": "Sweden",
"20": "Argo Coalition",
"21": "Titan Lab",
"22": "Defender",
"23": "Progresston",
"24": "Wasteland",
"25": "Hunters Moon",
"26": "Cold Front",
"27": "The Explorer",
"28": "Fablegear",
"29": "Outlaws",
"30": "GUP",
"31": "Dune",
"32": "Terminator",
"33": "Warhammer",
"34": "Valkirya Chronicles",
"35": "Mecha",
"36": "TMNT",
"37": "Star Trek"
"ussr": "U.S.S.R.",
"germany": "Germany",
"usa": "U.S.A.",
"china": "China",
"uk": "U.K.",
"france": "France",
"japan": "Japan",
"european": "European Nation",
"other": "Hybrid Nation"
},
"nations_adjectives": {
@@ -150,14 +109,6 @@
"other": "Hybrid"
},
"tank_class": {
"0": "Unknown Class",
"1": "Heavy",
"2": "Light",
"3": "Medium",
"4": "Tank destroyer"
},
"tank_class_short": {
"-1": "unrecognized",
"0": "Light",
@@ -182,10 +133,10 @@
},
"tree_type": {
"0": "Unknown tree type",
"1": "Common",
"2": "Premium",
"3": "Collector"
"-1": "unrecognized",
"0": "Tech tree",
"1": "Premium",
"2": "Collector"
},
"regions": {
@@ -839,6 +790,7 @@
"fire.caliber": "caliber",
"fire.standardPenetration": "standard penetration",
"fire.premiumPenetration": "premium penetration",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "damage",
"fire.moduleDamage": "module damage",
"fire.shellVelocity": "shell velocity",
@@ -935,6 +887,10 @@
"tank_seo_description": "%s1 armor, statistics, equipment, provisions, and more. %s2 DPM, %s3hp alpha, %s4mm penetration, %s5kph top speed, %s6hp health.",
"visualizers": {
"assault": {
"title": "Assault shells"
},
"rotator": {
"hull": "Hull",
"turret": "Turret",
@@ -1037,8 +993,6 @@
},
"meta": {
"compensation": "Compensation",
"free": "Free",
"back": "Back",
"compare": "Compare",
"swap": {
@@ -1052,12 +1006,11 @@
"class": "Class",
"tier": "Tier",
"type": "Type",
"id": "ID",
"dev_id": "DEV: ID",
"purchase": "Purchase price",
"restoration": "Restoration price",
"sale": "Sale price",
"set": "Set",
"price": "Price"
"research": "Research XP"
},
"tech_tree": {
@@ -1130,7 +1083,6 @@
"hull_traverse_speed": "Hull traverse speed",
"camouflage": "Camouflage",
"reload": "Reload",
"crewCount": "Crew count",
"shellNormalization": "Normalization",
"shellRicochet": "Ricochet",
@@ -1144,6 +1096,7 @@
"caliber": "Caliber",
"penetration": "Penetration",
"damage": "Damage",
"damageWithoutAssault": "Damage without assault shells",
"clipDamage": "Clipping potential",
"moduleDamage": "Module damage",
"explosionRadius": "Explosion radius",
+1
View File
@@ -698,6 +698,7 @@
"fire.caliber": "calibre",
"fire.standardPenetration": "penetración estándar",
"fire.premiumPenetration": "penetración prémium",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "daño",
"fire.moduleDamage": "daño al módulo",
"fire.shellVelocity": "velocidad del proyectil",
+1
View File
@@ -698,6 +698,7 @@
"fire.caliber": "caliber",
"fire.standardPenetration": "standard penetration",
"fire.premiumPenetration": "premium penetration",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "damage",
"fire.moduleDamage": "module damage",
"fire.shellVelocity": "shell velocity",
+1
View File
@@ -698,6 +698,7 @@
"fire.caliber": "砲口径",
"fire.standardPenetration": "通常弾貫通力",
"fire.premiumPenetration": "課金弾貫通力",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "ダメージ",
"fire.moduleDamage": "モジュールダメージ",
"fire.shellVelocity": "弾速",
+2 -1
View File
@@ -380,7 +380,7 @@
},
"embeds": {
"name": "osadzenie",
"description": "Jak działa osadzanie"
"description": "Jak działają osadzone"
},
"introduction": {
"name": "wprowadzenie",
@@ -698,6 +698,7 @@
"fire.caliber": "caliber",
"fire.standardPenetration": "standard penetration",
"fire.premiumPenetration": "premium penetration",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "damage",
"fire.moduleDamage": "module damage",
"fire.shellVelocity": "shell velocity",
+1
View File
@@ -698,6 +698,7 @@
"fire.caliber": "calibre",
"fire.standardPenetration": "penetração padrão",
"fire.premiumPenetration": "penetração premium",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "dano",
"fire.moduleDamage": "dano a módulos",
"fire.shellVelocity": "velocidade do projétil",
+4 -3
View File
@@ -697,7 +697,8 @@
"fire.reload": "перезарядка",
"fire.caliber": "калибр",
"fire.standardPenetration": "базовое пробитие",
"fire.premiumPenetration": "улучшенное пробитие ",
"fire.premiumPenetration": "премиумное пробитие ",
"fire.tertiaryPenetration": "пробитие третьего снаряда",
"fire.damage": "урон",
"fire.moduleDamage": "урон по модулям",
"fire.shellVelocity": "скорость снаряда",
@@ -790,8 +791,8 @@
"hull": "Корпус",
"turret": "Башня",
"hard": "Твёрдые",
"medium": "Средний танк",
"soft": "На мягком грунте",
"medium": "Средние",
"soft": "Мягкие",
"effective": "Эффективно"
},
"ricochet": {
+8 -7
View File
@@ -2,7 +2,7 @@
"test": {
"default": "тест",
"long": "This is a long test string. You MUST NEVER see this in the UI. My favorite fruit is %s1 because it has the color of %s2. I like it so much that I will say its name 3 times! %s1! %s1! %s1! Once again, it's %s2, not %s3.",
"fox": "The quick brown fox jumps over the lazy dog."
"fox": "Швидка бура лисиця перестрибує через лінивого собаку."
},
"common": {
"units": {
@@ -12,7 +12,7 @@
"hp": "%s1хп",
"x": "х%s1",
"percentage": "%s1%",
"deg_s": "%s1°/s"
"deg_s": "%s1°/с"
},
"gun_types": {
"auto_loader": "Магазинна система заряджання",
@@ -413,10 +413,10 @@
}
},
"debug": {
"name": "debug",
"description": "Debug information about the bot",
"name": "налагодження",
"description": "Інформація про налагодження бота",
"body": {
"title": "# Debug\n\n",
"title": "# Налагодження\n\n",
"version": "Версія",
"shard": {
"label": "Уламок",
@@ -499,7 +499,7 @@
},
"embed": {
"title": "Невірний обліковий запис?",
"description": "Use the command again and select a username from the search results."
"description": "Використайте команду ще раз і виберіть ім'я користувача з результатів пошуку."
}
},
"search_clans": {
@@ -508,7 +508,7 @@
"options": {
"limit": {
"name": "ліміт",
"description": "The max number of clan results (default: %s1)"
"description": "Максимальна кількість результатів клану (за замовчуванням: %s1)"
}
},
"body": {
@@ -698,6 +698,7 @@
"fire.caliber": "калібр",
"fire.standardPenetration": "базове пробиття",
"fire.premiumPenetration": "преміум пробиття",
"fire.tertiaryPenetration": "tertiary penetration",
"fire.damage": "шкода",
"fire.moduleDamage": "шкода по модулях",
"fire.shellVelocity": "швидкість польоту снаряда",
File diff suppressed because it is too large. Load diff
+2 -3
View File
@@ -8,7 +8,6 @@ import {
Samples,
averageDefinitionsAllStatsKeys,
emptySamples,
encodePBBuffer,
getAccountInfo,
getTankStats,
idToRegion,
@@ -235,11 +234,11 @@ async function postWork() {
commitAssets('averages', [
{
path: `averages/${latest}.pb`,
content: encodePBBuffer(AverageDefinitions, averageDefinitions),
content: AverageDefinitions.encode(averageDefinitions).finish(),
},
{
path: 'averages/manifest.json',
content: Buffer.from(JSON.stringify(manifest), 'utf-8'),
content: new TextEncoder().encode(JSON.stringify(manifest)),
},
]);
}
@@ -7,7 +7,6 @@ import { FileChange } from '../core/github/commitMultipleFiles';
export async function blitzkitTankIcons() {
console.log('Building blitzkit tank icons...');
console.log('Starting website dev server...');
const browser = await launch();
const page = await browser.newPage();
const tanks = Object.values((await fetchTankDefinitions()).tanks);
@@ -19,12 +18,14 @@ export async function blitzkitTankIcons() {
width: BLITZKIT_TANK_ICON_SIZE.width - 1,
height: BLITZKIT_TANK_ICON_SIZE.height,
});
await page.goto(`http://localhost:4321/api/tankopedia/tank-icon/${id}/`, {
waitUntil: 'networkidle0',
});
if (index === 0) {
console.log('Dev server started!');
try {
await page.goto(`http://localhost:4321/api/tankopedia/tank-icon/${id}/`, {
waitUntil: 'networkidle0',
});
} catch (error) {
console.error(`${id} ${name} time out`, error);
continue;
}
const screenshot = await page.screenshot({
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -1,5 +1,5 @@
import { Avatar, encodePBBuffer, fetchGlossary, Gallery } from '@blitzkit/core';
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { Avatar, fetchGlossary, Gallery } from '@blitzkit/core';
import locales from '@blitzkit/i18n/locales.json';
import { extname } from 'path';
import ProgressBar from 'progress';
import { commitAssets } from '../core/github/commitAssets';
@@ -68,13 +68,13 @@ export async function glossary() {
gallery.avatars.push(avatar);
const content = await fetch(url).then((response) =>
response.arrayBuffer(),
);
const content = await fetch(url)
.then((response) => response.arrayBuffer())
.then((buffer) => new Uint8Array(buffer));
changes.push({
path: `gallery/avatars/${key}${avatar.extension}`,
content: Buffer.from(content),
content,
});
bar.tick();
@@ -83,7 +83,7 @@ export async function glossary() {
changes.push({
path: 'definitions/gallery.pb',
content: encodePBBuffer(Gallery, gallery),
content: Gallery.encode(gallery).finish(),
});
await commitAssets('glossary', changes);
+1 -2
View File
@@ -21,7 +21,6 @@ import { gameModeBanners } from './gameModeBanners';
import { glossary } from './glossary';
import { migration } from './migration';
import { moduleIcons } from './moduleIcons';
import { popularTanks } from './popularTanks';
import { shellIcons } from './shellIcons';
import { skillIcons } from './skillIcons';
import { tankArmors } from './tankArmors';
@@ -47,7 +46,7 @@ const methods = [
boosterIcons,
tankIcons,
blitzkitTankIcons,
popularTanks,
// popularTanks,
glossary,
];
@@ -32,7 +32,7 @@ export async function migration() {
await commitAssets('migration', [
{
path: 'definitions/migration.json',
content: Buffer.from(JSON.stringify(map)),
content: new TextEncoder().encode(JSON.stringify(map)),
},
]);
}
@@ -1,6 +1,5 @@
import {
assertSecret,
encodePBBuffer,
fetchTankDefinitions,
PopularTanks,
} from '@blitzkit/core';
@@ -70,7 +69,7 @@ export async function popularTanks() {
await commitAssets('popular tanks', [
{
path: 'definitions/popular-tanks.pb',
content: encodePBBuffer(PopularTanks, popularTanks),
content: PopularTanks.encode(popularTanks).finish(),
},
]);
}
@@ -29,10 +29,11 @@ export async function tankArmors() {
const id = toUniqueId(nation, tank.id);
const model = await extractArmor(DATA, `${nation}-${tankKey}`);
const content = await nodeIO.writeBinary(model);
changes.push({
path: `3d/tanks/armor/${id}.glb`,
content: Buffer.from(await nodeIO.writeBinary(model)),
content,
});
}),
);
@@ -1,7 +1,7 @@
import { toUniqueId } from '@blitzkit/core';
import { NodeIO } from '@gltf-transform/core';
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
import { readdir } from 'fs/promises';
import { readdir, writeFile } from 'fs/promises';
import { extractModel } from '../core/blitz/extractModel';
import { readXMLDVPL } from '../core/blitz/readXMLDVPL';
import { readYAMLDVPL } from '../core/blitz/readYAMLDVPL';
@@ -32,7 +32,6 @@ export async function tankModels() {
if (tankKey.includes('tutorial_bot')) continue;
const id = toUniqueId(nation, tank.id);
const parameters = await readYAMLDVPL<TankParameters>(
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`,
);
@@ -164,7 +164,7 @@ const content = RatingLeaderboard.encode({
const changes: FileChange[] = [
{
path: `regions/${normalizedServer}/rating/${info.current_season}.pb`,
content: Buffer.from(content),
content,
},
];
@@ -1,9 +1,20 @@
import { readFile } from 'fs/promises';
import { DATA_COMPRESSED } from '../../buildAssets/constants';
import { readDVPL } from './readDVPL';
export async function readDVPLFile(file: string) {
const path = `${file}${file.endsWith('.dvpl') ? '' : '.dvpl'}`;
let path: string;
if (DATA_COMPRESSED) {
path = file.endsWith('.dvpl') ? file : `${file}.dvpl`;
} else {
path = file.replace('.dvpl', '');
}
const content = await readFile(path);
if (!DATA_COMPRESSED) return content;
const dvpl = readDVPL(content);
return dvpl;
@@ -1,12 +1,15 @@
import { DdsReadStream, PvrReadStream } from '@blitzkit/core';
import { existsSync } from 'fs';
import sharp from 'sharp';
import { DATA_COMPRESSED } from '../../../buildAssets/constants';
import { readDVPLFile } from '../readDVPLFile';
import { TextureMutation } from './constants';
export async function readTexture(path: string, mutation?: TextureMutation) {
const ddsTexturePath = path.replace('.tex', '.dx11.dds');
const isDds = existsSync(`${ddsTexturePath}.dvpl`);
const isDds = existsSync(
`${ddsTexturePath}${DATA_COMPRESSED ? '.dvpl' : ''}`,
);
const resolvedTexturePath = isDds
? ddsTexturePath
: ddsTexturePath.replace('.dds', '.pvr');
@@ -75,5 +78,4 @@ export async function readTexture(path: string, mutation?: TextureMutation) {
default:
return await sharp(raw.data, { raw }).jpeg().toBuffer();
}
}
@@ -1,10 +1,18 @@
import { asset } from '@blitzkit/core';
import ProgressBar from 'progress';
import { compareUint8Arrays } from './compareUint8Arrays';
import { GithubChangeBlob, createBlob } from './createBlob';
import { octokit } from './octokit';
export interface FileChange {
path: string;
content: Buffer;
content: Uint8Array;
}
enum DiffStatus {
New,
Changed,
Unchanged,
}
const heuristicFormats = ['glb', 'webp', 'jpg', 'png'];
@@ -19,72 +27,61 @@ export async function commitMultipleFiles(
await Promise.all(
changesRaw.map(async (change) => {
const blobPath = `${repoRaw}/${branch}/${change.path}`;
const response = await fetch(
`https://raw.githubusercontent.com/${blobPath}`,
);
let isNew: boolean;
let isDifferent: boolean;
let diff: number;
const response = await fetch(asset(change.path), {
headers: { 'Accept-Encoding': 'identity' },
});
let diff: { change: number; status: DiffStatus };
if (response.status === 404) {
isNew = true;
diff = change.content.length;
isDifferent = true;
diff = { change: change.content.length, status: DiffStatus.New };
} else if (
response.headers.has('Content-Length') &&
parseInt(response.headers.get('Content-Length')!) !==
change.content.length
Number(response.headers.get('Content-Length')) !== change.content.length
) {
isNew = false;
diff =
change.content.length -
parseInt(response.headers.get('Content-Length')!);
isDifferent = true;
diff = {
change:
change.content.length -
Number(response.headers.get('Content-Length')),
status: DiffStatus.Changed,
};
} else if (response.status === 200) {
isNew = false;
const buffer = Buffer.from(await response.arrayBuffer());
if (buffer.equals(change.content)) {
diff = 0;
isDifferent = false;
if (
heuristicFormats.some((format) => change.path.endsWith(`.${format}`))
) {
/**
* Heuristic: if it's a large blob like a .glb, a diff = 0 might end
* up being a false positive with isDifferent = true. So, it's okay
* to assume it's unchanged.
*/
diff = { change: 0, status: DiffStatus.Unchanged };
} else {
diff = change.content.length - buffer.length;
isDifferent = true;
const buffer = new Uint8Array(await response.arrayBuffer());
if (compareUint8Arrays(buffer, change.content)) {
diff = { change: 0, status: DiffStatus.Unchanged };
} else {
diff = {
change: change.content.length - buffer.length,
status: DiffStatus.Changed,
};
}
}
} else {
throw new Error(
`Unexpected status code ${response.status} for ${blobPath}`,
`Unexpected status code ${response.status} for ${change.path}`,
);
}
/**
* Heuristic: if it's a large blob like a .glb, a diff = 0 might end up
* being a false positive with isDifferent = true. So, it's okay to
* assume it's unchanged.
*/
if (
diff === 0 &&
heuristicFormats.some((format) => change.path.endsWith(`.${format}`))
) {
isDifferent = false;
isNew = false;
}
if (isNew) {
console.log(
`🟢 (+${change.content.length.toLocaleString()}B) ${blobPath}`,
);
changes.push(change);
} else if (isDifferent) {
console.log(
`🟡 (${diff > 0 ? '+' : ''}${diff.toLocaleString()}B) ${blobPath}`,
);
changes.push(change);
if (diff.status === DiffStatus.Unchanged) {
// just don't bother
// console.log(`🔵 (${diff.change.toLocaleString()}B) ${change.path}`);
} else {
console.log(
`🔵 (${change.content.length.toLocaleString()}B) ${blobPath}`,
`${
diff.status === DiffStatus.New ? '🟢' : '🟡'
} (${diff.change > 0 ? '+' : ''}${diff.change.toLocaleString()}B) ${change.path}`,
);
changes.push(change);
}
}),
);
@@ -0,0 +1,9 @@
export function compareUint8Arrays(a: Uint8Array, b: Uint8Array) {
if (a.length !== b.length) return false;
for (let index = 0; index < a.length; index++) {
if (a[index] !== b[index]) return false;
}
return true;
}
@@ -20,7 +20,7 @@ export const createBlob = throttle(
await octokit.git.createBlob({
owner,
repo,
content: change.content.toString('base64'),
content: Buffer.from(change.content).toString('base64'),
encoding: 'base64',
})
).data;
@@ -34,6 +34,7 @@ export const createBlob = throttle(
} catch (error) {
console.warn(
`Failed blob ${change.path}; retrying in ${TIME_PER_BLOB}ms...`,
error,
);
await new Promise((resolve) => setTimeout(resolve, TIME_PER_BLOB));
+3 -6
View File
@@ -134,14 +134,12 @@ function post() {
const files = idsChunked.map((chunk, index) => {
const didsWriteStream = new DidsWriteStream().dids(chunk);
const buffer = didsWriteStream.uint8Array;
const compressed = compress(buffer);
const content = compress(buffer);
console.log(
`Chunk ${index} with ${chunk.length} ids (compressed: ${compressed.length}; uncompressed: ${buffer.length})`,
`Chunk ${index} with ${chunk.length} ids (compressed: ${content.length}; uncompressed: ${buffer.length})`,
);
const content = Buffer.from(compressed);
return {
content,
path: `ids/${index}.dids.lz4`,
@@ -151,13 +149,12 @@ function post() {
commitAssets('discovered ids', [
...files,
{
content: Buffer.from(
content: new TextEncoder().encode(
JSON.stringify({
chunks: idsChunked.length,
count: ids.length,
time: Date.now(),
} satisfies DiscoveredIdsDefinitions),
'utf-8',
),
path: 'ids/manifest.json',
},
+30 -38
View File
@@ -1,9 +1,10 @@
import { exec as execSync } from 'child_process';
import { existsSync } from 'fs';
import { readdir, rm, writeFile } from 'fs/promises';
import { chunk } from 'lodash-es';
import { promisify } from 'util';
const ROOT = 'packages/core/src/protos';
const exec = promisify(execSync);
let executableFileExtension: string;
@@ -14,42 +15,33 @@ if (existsSync('node_modules/.bin/protoc-gen-ts_proto.exe')) {
executableFileExtension = '';
}
await compile('packages/core/src/protos');
await compile('submodules/blitzkit-closed/src/protos');
const filesRaw = await readdir(`${ROOT}`);
await Promise.all(
filesRaw.map(async (file) => {
if (!file.endsWith('.proto')) {
await rm(`${ROOT}/${file}`);
}
}),
);
async function compile(root: string) {
const filesRaw = await readdir(root);
const files = filesRaw.filter((file) => file.endsWith('.proto'));
const args = [
`--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`,
'--ts_proto_opt=esModuleInterop=true',
'--ts_proto_opt=oneof=unions-value',
'--ts_proto_opt=removeEnumPrefix=true',
'--ts_proto_opt=unrecognizedEnum=false',
'--ts_proto_opt=snakeToCamel=false',
'--ts_proto_out=.',
...files.map((file) => `${ROOT}/${file}`),
];
for (const file of filesRaw) {
if (!file.endsWith('.ts')) continue;
await rm(`${root}/${file}`);
}
const allFiles = filesRaw.filter((file) => file.endsWith('.proto'));
for (const files of chunk(allFiles, 32)) {
const args = [
`-I=${root}`,
`--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`,
'--ts_proto_opt=esModuleInterop=true',
'--ts_proto_opt=oneof=unions-value',
// '--ts_proto_opt=removeEnumPrefix=true',
'--ts_proto_opt=unrecognizedEnum=false',
'--ts_proto_opt=snakeToCamel=false',
`--ts_proto_out=${root}`,
...files.map((file) => `${root}/${file}`),
];
await exec(`protoc ${args.join(' ')}`);
}
await writeFile(
`${root}/index.ts`,
'// @ts-nocheck\n' +
allFiles
.sort()
.map((file) => file.replace('.proto', ''))
.map((file) => `export * from './${file}.ts';`)
.join('\n'),
);
}
await exec(`protoc ${args.join(' ')}`);
await writeFile(
`${ROOT}/index.ts`,
'// @ts-nocheck\n' +
files
.map((file) => file.replace('.proto', ''))
.map((file) => `export * from './${file}.ts';`)
.join('\n'),
);
+1 -2
View File
@@ -1,6 +1,5 @@
import {
asset,
encodePBBuffer,
fetchTankDefinitions,
Reviews,
Video,
@@ -81,7 +80,7 @@ for (const tank of tanksSanitized) {
}
await commitAssets('reviews', [
{
content: encodePBBuffer(Reviews, reviews),
content: Reviews.encode(reviews).finish(),
path: 'definitions/reviews.pb',
},
]);
+1 -4
View File
@@ -1,7 +1,4 @@
{
"extends": "../../tsconfig.json",
"include": ["src/**/*"],
"compilerOptions": {
"baseUrl": "../../"
}
"include": ["src/**/*"]
}
+4 -5
View File
@@ -1,15 +1,14 @@
// @ts-check
import partytown from '@astrojs/partytown';
import react from '@astrojs/react';
import sitemap from '@astrojs/sitemap';
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
import { defineConfig } from 'astro/config';
export default defineConfig({
i18n: {
defaultLocale: locales.default,
locales: locales.supported.map(({ locale }) => locale),
defaultLocale: 'en',
locales: [...SUPPORTED_LOCALES],
routing: {
prefixDefaultLocale: false,
},
@@ -21,7 +20,7 @@ export default defineConfig({
outDir: '../../dist/website',
prefetch: true,
integrations: [react(), sitemap(), partytown()],
integrations: [react(), sitemap()],
vite: {
resolve: {
alias: {
+10 -7
View File
@@ -10,9 +10,7 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/partytown": "^2.1.4",
"@astrolib/seo": "^1.0.0-beta.8",
"@blitzkit/closed": "workspace:*",
"@blitzkit/core": "workspace:*",
"@blitzkit/i18n": "workspace:*",
"@fontsource/inter": "^5.2.5",
@@ -21,10 +19,10 @@
"@nivo/bar": "^0.87.0",
"@nivo/line": "^0.88.0",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/themes": "^3.2.1",
"@react-three/drei": "^10.0.8",
"@react-three/fiber": "^9.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/themes": "^3.1.4",
"@react-three/drei": "^9.115.0",
"@react-three/fiber": "^8.17.10",
"compare-versions": "^6.1.1",
"echarts": "^5.5.1",
"immer": "^10.1.1",
@@ -32,7 +30,9 @@
"markdown-to-jsx": "^7.5.0",
"nanostores": "^0.11.3",
"quicklime": "^1.2.0",
"react": "^18.3.1",
"react-device-detect": "^2.2.3",
"react-dom": "^18.3.1",
"react-promise-suspense": "^0.3.4",
"three": "^0.169.0",
"urlon": "^3.1.0",
@@ -45,7 +45,10 @@
"@playform/compress": "^0.1.9",
"@playform/inline": "^0.1.2",
"@types/js-cookie": "^3.0.6",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/three": "^0.160.0",
"astro": "^4.16.7"
"astro": "^4.16.7",
"astro-compressor": "^1.0.0"
}
}
@@ -0,0 +1 @@
dh=ecd11a058908f58ccea092ed17aa43ace59 4b9a5
File renamed without changes.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 242 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 251 KiB

After

Width:  |  Height:  |  Size: 251 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 255 KiB

After

Width:  |  Height:  |  Size: 255 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 365 KiB

After

Width:  |  Height:  |  Size: 365 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 771 KiB

After

Width:  |  Height:  |  Size: 771 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 251 KiB

After

Width:  |  Height:  |  Size: 251 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 211 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 379 KiB

After

Width:  |  Height:  |  Size: 379 KiB

File renamed without changes.

Before

Width:  |  Height:  |  Size: 371 KiB

After

Width:  |  Height:  |  Size: 371 KiB

@@ -1,29 +1,16 @@
import { TankClass as TankClass_dava } from '@blitzkit/core';
import { TankClass } from '@protos/blitz_static_tank_component';
import { QuestionMarkIcon } from '@radix-ui/react-icons';
import { TankClass } from '@blitzkit/core';
import type { ComponentProps, ReactNode } from 'react';
import { ClassHeavy } from './components/ClassHeavy';
import { ClassLight } from './components/ClassLight';
import { ClassMedium } from './components/ClassMedium';
import { ClassTankDestroyer } from './components/ClassTankDestroyer';
export const classIcons_ue: Record<
TankClass,
((props: ComponentProps<'svg'>) => ReactNode) | typeof QuestionMarkIcon
> = {
[TankClass.TANK_CLASS_UNSPECIFIED]: QuestionMarkIcon,
[TankClass.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
[TankClass.TANK_CLASS_HEAVY]: ClassHeavy,
[TankClass.TANK_CLASS_LIGHT]: ClassLight,
[TankClass.TANK_CLASS_MEDIUM]: ClassMedium,
};
export const classIcons: Record<
TankClass_dava,
TankClass,
(props: ComponentProps<'svg'>) => ReactNode
> = {
[TankClass_dava.TANK_CLASS_TANK_DESTROYER]: ClassTankDestroyer,
[TankClass_dava.TANK_CLASS_HEAVY]: ClassHeavy,
[TankClass_dava.TANK_CLASS_LIGHT]: ClassLight,
[TankClass_dava.TANK_CLASS_MEDIUM]: ClassMedium,
[TankClass.TANK_DESTROYER]: ClassTankDestroyer,
[TankClass.HEAVY]: ClassHeavy,
[TankClass.LIGHT]: ClassLight,
[TankClass.MEDIUM]: ClassMedium,
};
@@ -79,6 +79,12 @@ export function Body({ stats }: BodyProps) {
<Table.Body>
<CompareRow stats={stats} value="dpm" decimals={0} />
<CompareRow stats={stats} value="damage" decimals={0} />
{hasNonRegularGun && (
<CompareRow stats={stats} indent value="clipDamage" decimals={0} />
)}
<CompareRow stats={stats} value="moduleDamage" decimals={0} />
<CompareRow stats={stats} value="penetration" decimals={0} />
<CompareRow
stats={stats}
name={strings.website.tools.tankopedia.characteristics.values.reload}
@@ -105,12 +111,6 @@ export function Body({ stats }: BodyProps) {
<CompareRow stats={stats} value="shells" decimals={0} />
</>
)}
<CompareRow stats={stats} value="penetration" decimals={0} />
<CompareRow stats={stats} value="damage" decimals={0} />
{hasNonRegularGun && (
<CompareRow stats={stats} indent value="clipDamage" decimals={0} />
)}
<CompareRow stats={stats} value="moduleDamage" decimals={0} />
<CompareRow stats={stats} value="caliber" decimals={0} />
<CompareRow stats={stats} value="shellNormalization" decimals={0} />
<CompareRow
@@ -1,23 +0,0 @@
import type { RewardCurrency } from '@protos/blitz_static_reward_currency';
import { Flex, Text, type TextProps } from '@radix-ui/themes';
import { entityName } from 'packages/core/src';
import { useLocale } from '../hooks/useLocale';
type CurrencyProps = TextProps & {
reward: RewardCurrency;
};
export function Currency({ reward, ...props }: CurrencyProps) {
const { locale } = useLocale();
return (
<Text {...props}>
<Flex align="center" gap="1">
{reward.amount.toLocaleString(locale)}
<img
src={`/api/currencies/${entityName(reward.currency_catalog_id)}.webp`}
/>
</Flex>
</Text>
);
}
+1 -1
View File
@@ -8,7 +8,7 @@ import { LinkI18n } from './LinkI18n';
import { LocaleSwitcherThemeWrapper } from './LocaleSwitcher';
const gameDefinitions = await fetchGameDefinitions();
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH);
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_BRANCH);
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
const strings = getStrings(locale);
---
@@ -1,4 +1,4 @@
import locales from '@blitzkit/i18n/locales.json' with { type: 'json' };
import locales from '@blitzkit/i18n/locales.json';
import { literals } from '@blitzkit/i18n/src/literals';
import { Flex, Text } from '@radix-ui/themes';
import fuzzysort from 'fuzzysort';
@@ -3,16 +3,11 @@ import { Code, Flex, Heading, Text } from '@radix-ui/themes';
import { resolveBranchName } from '../core/blitzkit/branches';
import { getStrings } from '../core/i18n/getStrings';
import { literals } from '@blitzkit/i18n/src/literals';
import type { BlitzKitStrings } from 'packages/i18n/src';
interface Props {
locale: string;
}
const { locale } = Astro.props;
const strings = await getStrings(locale);
const { locale } = Astro.params;
const branchName = resolveBranchName(locale);
const isBranchNamed = branchName !== undefined;
const strings = getStrings(locale);
---
<style>
+4 -4
View File
@@ -1,12 +1,12 @@
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
import { Link, type LinkProps } from '@radix-ui/themes';
import type { LocaleAcceptorProps } from '../hooks/useLocale';
type LinkI18nProps = LinkProps & {
locale: string;
};
type LinkI18nProps = LinkProps & LocaleAcceptorProps;
export function LinkI18n({ locale, href, ...props }: LinkI18nProps) {
const prefix = locale === DEFAULT_LOCALE ? '' : `/${locale}`;
const prefix =
locale === undefined || locale === DEFAULT_LOCALE ? '' : `/${locale}`;
return (
<Link href={href?.startsWith('/') ? `${prefix}${href}` : href} {...props} />
+7 -6
View File
@@ -15,11 +15,11 @@ import { LinkI18n } from './LinkI18n';
export interface Props {
integrated?: boolean;
locale: string;
}
const { integrated, locale } = Astro.props;
const { integrated = false } = Astro.props;
const toolsFiltered = TOOLS.filter((tool) => !('href' in tool));
const { locale } = Astro.params;
const branchName = resolveBranchName(locale);
const isBranchNamed = branchName !== undefined;
const strings = getStrings(locale);
@@ -47,7 +47,7 @@ const strings = getStrings(locale);
height: 100%;
}
.navbar[data-expanded='false'] .content {
.navbar[data-expanded='false'][data-integrated='false'] .content {
background-color: var(--black-a8);
backdrop-filter: blur(4rem);
box-shadow: var(--shadow-3);
@@ -87,6 +87,7 @@ const strings = getStrings(locale);
direction="column"
align="center"
data-expanded="false"
data-integrated={`${integrated}`}
className="navbar"
width="100%"
top="0"
@@ -139,7 +140,7 @@ const strings = getStrings(locale);
toolsFiltered.map((tool) => {
const unavailableOnBranch = tool.branches?.every(
(branch) =>
branch !== assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH),
branch !== assertSecret(import.meta.env.PUBLIC_BRANCH),
);
const selected = Astro.url.pathname.includes(`/${tool.id}`);
const toolStrings =
@@ -211,7 +212,7 @@ const strings = getStrings(locale);
toolsFiltered.map((tool) => {
const unavailableOnBranch = tool.branches?.every(
(branch) =>
branch !== assertSecret(import.meta.env.PUBLIC_ASSET_BRANCH),
branch !== assertSecret(import.meta.env.PUBLIC_BRANCH),
);
if (unavailableOnBranch) return null;
@@ -232,7 +233,7 @@ const strings = getStrings(locale);
<Box
style={{
borderRadius: Var('radius-2'),
backgroundImage: `url(/assets/images/${tool.id}.webp)`,
backgroundImage: `url(/assets/images/tools/${tool.id}.webp)`,
backgroundSize: '200%',
backgroundPosition: 'right center',
}}
Loaded 100 of 155 files, more files were not shown because too many files have changed in this diff. Show more