mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf04fe21b3 | ||
|
|
84eb3c2da3 | ||
|
|
22bf2dc1d8 | ||
|
|
b9c339daa7 | ||
|
|
ef3006cac1 | ||
|
|
e482fd40c1 | ||
|
|
cc4569966e | ||
|
|
3708a3ced7 | ||
|
|
0ae59c2fd7 | ||
|
|
7027f63236 | ||
|
|
6725e79021 | ||
|
|
5ca3cee9da | ||
|
|
602a5a1e99 | ||
|
|
bfbf3bdc39 | ||
|
|
644686582e | ||
|
|
1c00bc81f8 | ||
|
|
ac3b69bec5 | ||
|
|
3e14c943b6 | ||
|
|
d33633be2c | ||
|
|
4bf70d02d0 | ||
|
|
377bcf0e38 | ||
|
|
884b6d4318 |
No files matched your search
@@ -39,6 +39,17 @@ env:
|
|||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
||||||
PUBLIC_ASSET_BRANCH: ${{ github.event.inputs.cdn_branch || secrets.PUBLIC_ASSET_BRANCH }}
|
PUBLIC_ASSET_BRANCH: ${{ github.event.inputs.cdn_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
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
download_client:
|
download_client:
|
||||||
@@ -106,6 +117,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
- name: Setup bun
|
- name: Setup bun
|
||||||
uses: oven-sh/setup-bun@v1
|
uses: oven-sh/setup-bun@v1
|
||||||
@@ -127,7 +141,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Start server and build assets
|
- name: Start server and build assets
|
||||||
run: |
|
run: |
|
||||||
bun dev:website &
|
bun dev:website --verbosepa &
|
||||||
SERVER_PID=$!
|
SERVER_PID=$!
|
||||||
|
|
||||||
bun run build:assets --all-targets --depot --production
|
bun run build:assets --all-targets --depot --production
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ name: Website
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: main
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
schedule:
|
schedule:
|
||||||
@@ -27,6 +26,8 @@ env:
|
|||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
||||||
|
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
||||||
|
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -53,6 +54,7 @@ jobs:
|
|||||||
path: dist/website
|
path: dist/website
|
||||||
|
|
||||||
deploy-github-pages:
|
deploy-github-pages:
|
||||||
|
if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
name: Deploy to GitHub Pages
|
name: Deploy to GitHub Pages
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
files:
|
files:
|
||||||
- source: /packages/core/lang/en.json
|
- source: /packages/i18n/strings/en.json
|
||||||
translation: /%original_path%/%locale%.json
|
translation: /%original_path%/%locale%.json
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# BlitzKit 1.27.1
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Fixed a crash that occurs if tanks are deleted in Blitz and were once available in BlitzKit
|
||||||
|
- All tank icons are now back
|
||||||
|
- The tank search once again returns results
|
||||||
+3
-2
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "blitzkit",
|
"name": "blitzkit",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.27.0",
|
"version": "1.27.1",
|
||||||
"description": "🎉 Tools for everything World of Tanks Blitz",
|
"description": "🎉 Tools for everything World of Tanks Blitz",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"types": "./types.d.ts",
|
"types": "./types.d.ts",
|
||||||
@@ -35,7 +35,8 @@
|
|||||||
"build:protos": "bun packages/scripts/src/protos.ts",
|
"build:protos": "bun packages/scripts/src/protos.ts",
|
||||||
"preview:website": "cd packages/website && bun run preview",
|
"preview:website": "cd packages/website && bun run preview",
|
||||||
"build:reviews": "cd packages/scripts && bun build:reviews",
|
"build:reviews": "cd packages/scripts && bun build:reviews",
|
||||||
"build:ids": "cd packages/scripts && bun build:ids"
|
"build:ids": "cd packages/scripts && bun build:ids",
|
||||||
|
"prunestrings": "cd packages/scripts && bun prunestrings"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { SEARCH_KEYS } from '@blitzkit/core';
|
||||||
import { literals } from '@blitzkit/i18n';
|
import { literals } from '@blitzkit/i18n';
|
||||||
import { Locale } from 'discord.js';
|
import { Locale } from 'discord.js';
|
||||||
import { go } from 'fuzzysort';
|
import { go } from 'fuzzysort';
|
||||||
@@ -19,10 +20,7 @@ export async function resolveTankId(
|
|||||||
const searchResult = go(
|
const searchResult = go(
|
||||||
`${tank}`,
|
`${tank}`,
|
||||||
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
||||||
{
|
{ keys: SEARCH_KEYS, limit: 1 },
|
||||||
keys: ['searchableName', 'searchableNameDeburr', 'camouflages'],
|
|
||||||
limit: 1,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (searchResult.length === 0) {
|
if (searchResult.length === 0) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { fetchTankNames, TankType } from '@blitzkit/core';
|
import { fetchTankNames, SEARCH_KEYS, TankType } from '@blitzkit/core';
|
||||||
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
|
||||||
import {
|
import {
|
||||||
ApplicationCommandOptionChoiceData,
|
ApplicationCommandOptionChoiceData,
|
||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
@@ -32,16 +31,7 @@ export async function autocompleteTanks(
|
|||||||
go(
|
go(
|
||||||
focusedOption.value,
|
focusedOption.value,
|
||||||
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
await (techTreeOnly ? tankNamesTechTreeOnly : tankNames),
|
||||||
{
|
{ keys: SEARCH_KEYS, limit: 10 },
|
||||||
keys: [
|
|
||||||
...SUPPORTED_LOCALES.map((locale) => [
|
|
||||||
`searchableName.{locale}`,
|
|
||||||
`searchableNameDeburr.{locale}`,
|
|
||||||
]).flat(),
|
|
||||||
'camouflages',
|
|
||||||
],
|
|
||||||
limit: 10,
|
|
||||||
},
|
|
||||||
).map(async (item) => {
|
).map(async (item) => {
|
||||||
let name = unwrap(item.obj.searchableName);
|
let name = unwrap(item.obj.searchableName);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { deburr } from 'lodash-es';
|
import { deburr } from 'lodash-es';
|
||||||
|
import { SUPPORTED_LOCALES } from '../../../i18n/src/strings';
|
||||||
import { I18nString } from '../protos';
|
import { I18nString } from '../protos';
|
||||||
import { fetchCamouflageDefinitions } from './camouflageDefinitions';
|
import { fetchCamouflageDefinitions } from './camouflageDefinitions';
|
||||||
import { fetchTankDefinitions } from './tankDefinitions';
|
import { fetchTankDefinitions } from './tankDefinitions';
|
||||||
@@ -33,3 +34,11 @@ export async function fetchTankNames() {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SEARCH_KEYS = [
|
||||||
|
...SUPPORTED_LOCALES.map((locale) => [
|
||||||
|
`searchableName.locales.${locale}`,
|
||||||
|
`searchableNameDeburr.locales.${locale}`,
|
||||||
|
]).flat(),
|
||||||
|
'camouflages',
|
||||||
|
];
|
||||||
+1588
-217
File diff suppressed because it is too large.
Load diff
+534
-515
File diff suppressed because it is too large.
Load diff
+534
-515
File diff suppressed because it is too large.
Load diff
+559
-482
File diff suppressed because it is too large.
Load diff
+678
-407
File diff suppressed because it is too large.
Load diff
+1774
-87
File diff suppressed because it is too large.
Load diff
+534
-515
File diff suppressed because it is too large.
Load diff
+653
-364
File diff suppressed because it is too large.
Load diff
@@ -10,7 +10,8 @@
|
|||||||
"build:reviews": "bun src/reviews.ts",
|
"build:reviews": "bun src/reviews.ts",
|
||||||
"build:ids": "bun src/discoverIds.ts",
|
"build:ids": "bun src/discoverIds.ts",
|
||||||
"build:bot": "bun src/buildBot.ts",
|
"build:bot": "bun src/buildBot.ts",
|
||||||
"build:ratingleaderboard": "bun src/buildRatingLeaderboard.ts"
|
"build:ratingleaderboard": "bun src/buildRatingLeaderboard.ts",
|
||||||
|
"prunestrings": "bun src/pruneStrings.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzkit/core": "workspace:*",
|
"@blitzkit/core": "workspace:*",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { assertSecret } from '@blitzkit/core';
|
import { assertSecret } from '@blitzkit/core';
|
||||||
|
import { existsSync } from 'fs';
|
||||||
import { mkdir, writeFile } from 'fs/promises';
|
import { mkdir, writeFile } from 'fs/promises';
|
||||||
import { parse as parsePath } from 'path';
|
import { parse as parsePath } from 'path';
|
||||||
import ProgressBar from 'progress';
|
import ProgressBar from 'progress';
|
||||||
@@ -45,19 +46,24 @@ while (true) {
|
|||||||
files.length,
|
files.length,
|
||||||
);
|
);
|
||||||
|
|
||||||
await Promise.all(
|
for (const { path, data } of files) {
|
||||||
files.map(async ({ path, data }) => {
|
console.log(`Patching "${path}"...`);
|
||||||
|
|
||||||
const { dir } = parsePath(path);
|
const { dir } = parsePath(path);
|
||||||
|
|
||||||
|
try {
|
||||||
await mkdir(`${DATA}/${dir}`, { recursive: true });
|
await mkdir(`${DATA}/${dir}`, { recursive: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`Failed to make directory "${dir}"`);
|
||||||
|
}
|
||||||
|
|
||||||
await writeFile(
|
await writeFile(
|
||||||
`${DATA}/${path}`,
|
`${DATA}/${path}`,
|
||||||
new Uint8Array(writeDVPL(Buffer.from(data))),
|
new Uint8Array(writeDVPL(Buffer.from(data))),
|
||||||
);
|
);
|
||||||
|
|
||||||
bar.tick();
|
bar.tick();
|
||||||
}),
|
}
|
||||||
);
|
|
||||||
|
|
||||||
if ('dynamicContentLocalizationsDir' in data) {
|
if ('dynamicContentLocalizationsDir' in data) {
|
||||||
console.log('Found dynamic content localizations; patching...');
|
console.log('Found dynamic content localizations; patching...');
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { DATA_COMPRESSED } from '../../buildAssets/constants';
|
|||||||
import { readDVPL } from './readDVPL';
|
import { readDVPL } from './readDVPL';
|
||||||
|
|
||||||
export async function readDVPLFile(file: string) {
|
export async function readDVPLFile(file: string) {
|
||||||
if (DATA_COMPRESSED) {
|
if (DATA_COMPRESSED && !file.endsWith('.dvpl')) {
|
||||||
return readDVPL(await readFile(`${file}.dvpl`));
|
return readDVPL(await readFile(`${file}.dvpl`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import {
|
||||||
|
DEFAULT_LOCALE,
|
||||||
|
SUPPORTED_LOCALES,
|
||||||
|
TranslationTree,
|
||||||
|
} from '@blitzkit/i18n';
|
||||||
|
import { writeFile } from 'fs/promises';
|
||||||
|
|
||||||
|
const ROOT = '@blitzkit/i18n/strings';
|
||||||
|
const WORKING_ROOT = '../../packages/i18n/strings';
|
||||||
|
|
||||||
|
const defaultStrings = await import(`${ROOT}/${DEFAULT_LOCALE}.json`);
|
||||||
|
const nonDefaultLocales = SUPPORTED_LOCALES.filter(
|
||||||
|
(locale) => locale !== DEFAULT_LOCALE,
|
||||||
|
);
|
||||||
|
|
||||||
|
function prune(defaultStrings: TranslationTree, strings: TranslationTree) {
|
||||||
|
for (const key in strings) {
|
||||||
|
if (key in defaultStrings) {
|
||||||
|
if (typeof defaultStrings[key] === typeof strings[key]) {
|
||||||
|
if (typeof strings[key] === 'string') {
|
||||||
|
if (
|
||||||
|
(defaultStrings[key] as string).replaceAll(/%s\d/g, '%s') ===
|
||||||
|
(strings[key] as string).replaceAll(/%s\d/g, '%s') ||
|
||||||
|
strings[key] === ''
|
||||||
|
) {
|
||||||
|
delete strings[key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prune(defaultStrings[key] as TranslationTree, strings[key]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete strings[key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete strings[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const locale of nonDefaultLocales) {
|
||||||
|
console.log(`Pruning ${locale}...`);
|
||||||
|
|
||||||
|
const strings = await import(`${ROOT}/${locale}.json`);
|
||||||
|
const pruned = prune(defaultStrings, strings);
|
||||||
|
|
||||||
|
writeFile(`${WORKING_ROOT}/${locale}.json`, JSON.stringify(pruned, null, 2));
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
import { asset, TankType, type TankDefinition } from '@blitzkit/core';
|
import {
|
||||||
|
asset,
|
||||||
|
fetchTankDefinitions,
|
||||||
|
TankType,
|
||||||
|
type TankDefinition,
|
||||||
|
} from '@blitzkit/core';
|
||||||
import { Flex, Text, type TextProps } from '@radix-ui/themes';
|
import { Flex, Text, type TextProps } from '@radix-ui/themes';
|
||||||
import { uniq } from 'lodash-es';
|
import { uniq } from 'lodash-es';
|
||||||
import { forwardRef, type ReactNode } from 'react';
|
import { forwardRef, type ReactNode } from 'react';
|
||||||
@@ -16,6 +21,8 @@ type TankCardProps = TextProps & {
|
|||||||
noLink?: boolean;
|
noLink?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const tankDefinitions = await fetchTankDefinitions();
|
||||||
|
|
||||||
export const TankCard = forwardRef<HTMLSpanElement, TankCardProps>(
|
export const TankCard = forwardRef<HTMLSpanElement, TankCardProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -49,10 +56,9 @@ export const TankCard = forwardRef<HTMLSpanElement, TankCardProps>(
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
onSelect?.(tank);
|
onSelect?.(tank);
|
||||||
mutateTankopediaPersistent((draft) => {
|
mutateTankopediaPersistent((draft) => {
|
||||||
draft.recentlyViewed = uniq([
|
draft.recentlyViewed = uniq([tank.id, ...draft.recentlyViewed])
|
||||||
tank.id,
|
.filter((id) => id in tankDefinitions.tanks)
|
||||||
...draft.recentlyViewed,
|
.slice(0, MAX_RECENTLY_VIEWED);
|
||||||
]).slice(0, MAX_RECENTLY_VIEWED);
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="tank-search-card"
|
className="tank-search-card"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export function NoResults({ type = 'filters' }: NoResultsProps) {
|
|||||||
return (
|
return (
|
||||||
<Flex flexGrow="1" align="center" justify="center">
|
<Flex flexGrow="1" align="center" justify="center">
|
||||||
<Text color="gray">
|
<Text color="gray">
|
||||||
{strings.website.common.tank_search.no_tanks_found.body}.{' '}
|
{strings.website.common.tank_search.no_tanks_found.body}{' '}
|
||||||
<Link
|
<Link
|
||||||
href="#"
|
href="#"
|
||||||
underline="always"
|
underline="always"
|
||||||
@@ -25,7 +25,6 @@ export function NoResults({ type = 'filters' }: NoResultsProps) {
|
|||||||
? strings.website.common.tank_search.no_tanks_found.clear_filters
|
? strings.website.common.tank_search.no_tanks_found.clear_filters
|
||||||
: strings.website.common.tank_search.no_tanks_found.search_again}
|
: strings.website.common.tank_search.no_tanks_found.search_again}
|
||||||
</Link>
|
</Link>
|
||||||
.
|
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ export function RecentlyViewed() {
|
|||||||
const tankopediaPersistentStore = TankopediaPersistent.useStore();
|
const tankopediaPersistentStore = TankopediaPersistent.useStore();
|
||||||
const filters = useStore($tankFilters);
|
const filters = useStore($tankFilters);
|
||||||
// non-reactive because it is a little weird that it updates instantly even before the page loads
|
// non-reactive because it is a little weird that it updates instantly even before the page loads
|
||||||
const recentlyViewed = tankopediaPersistentStore.getState().recentlyViewed;
|
const recentlyViewed = tankopediaPersistentStore
|
||||||
|
.getState()
|
||||||
|
.recentlyViewed.filter((id) => id in tankDefinitions.tanks);
|
||||||
const sort = useStore($tankopediaSort);
|
const sort = useStore($tankopediaSort);
|
||||||
const hasFilters = useMemo(
|
const hasFilters = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
metaSortTank,
|
metaSortTank,
|
||||||
normalizeBoundingBox,
|
normalizeBoundingBox,
|
||||||
resolveDpm,
|
resolveDpm,
|
||||||
|
SEARCH_KEYS,
|
||||||
unionBoundingBox,
|
unionBoundingBox,
|
||||||
type TankDefinition,
|
type TankDefinition,
|
||||||
} from '@blitzkit/core';
|
} from '@blitzkit/core';
|
||||||
@@ -410,7 +411,7 @@ export const TankSearch = memo<TankSearchProps>(
|
|||||||
: sorted.reverse();
|
: sorted.reverse();
|
||||||
} else {
|
} else {
|
||||||
const searchedRaw = fuzzysort.go(tankFilters.search, tankNames, {
|
const searchedRaw = fuzzysort.go(tankFilters.search, tankNames, {
|
||||||
keys: ['searchableName', 'searchableNameDeburr', 'camouflages'],
|
keys: SEARCH_KEYS,
|
||||||
});
|
});
|
||||||
const searchedTanks = searchedRaw.map(
|
const searchedTanks = searchedRaw.map(
|
||||||
(result) => tankDefinitions.tanks[result.obj.id],
|
(result) => tankDefinitions.tanks[result.obj.id],
|
||||||
@@ -456,7 +457,9 @@ export const TankSearch = memo<TankSearchProps>(
|
|||||||
draft.recentlyViewed = uniq([
|
draft.recentlyViewed = uniq([
|
||||||
...tanksFiltered.map(({ id }) => id),
|
...tanksFiltered.map(({ id }) => id),
|
||||||
...draft.recentlyViewed,
|
...draft.recentlyViewed,
|
||||||
]).slice(0, MAX_RECENTLY_VIEWED);
|
])
|
||||||
|
.filter((id) => id in tankDefinitions.tanks)
|
||||||
|
.slice(0, MAX_RECENTLY_VIEWED);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { assertSecret } from '@blitzkit/core';
|
import { assertSecret, fetchTankDefinitions } from '@blitzkit/core';
|
||||||
import { MinusCircledIcon } from '@radix-ui/react-icons';
|
import { MinusCircledIcon } from '@radix-ui/react-icons';
|
||||||
import { Callout, Flex } from '@radix-ui/themes';
|
import { Callout, Flex } from '@radix-ui/themes';
|
||||||
import { uniq } from 'lodash-es';
|
import { uniq } from 'lodash-es';
|
||||||
@@ -9,6 +9,8 @@ import { AesonPlug } from '../AesonPlug';
|
|||||||
import { ExperimentIcon } from '../ExperimentIcon';
|
import { ExperimentIcon } from '../ExperimentIcon';
|
||||||
import { MAX_RECENTLY_VIEWED } from '../TankSearch/constants';
|
import { MAX_RECENTLY_VIEWED } from '../TankSearch/constants';
|
||||||
|
|
||||||
|
const tankDefinitions = await fetchTankDefinitions();
|
||||||
|
|
||||||
export function CalloutsSection() {
|
export function CalloutsSection() {
|
||||||
const tank = Duel.use((state) => state.protagonist.tank);
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
|
const mutateTankopediaPersistent = TankopediaPersistent.useMutation();
|
||||||
@@ -17,10 +19,9 @@ export function CalloutsSection() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mutateTankopediaPersistent((draft) => {
|
mutateTankopediaPersistent((draft) => {
|
||||||
draft.recentlyViewed = uniq([tank.id, ...draft.recentlyViewed]).slice(
|
draft.recentlyViewed = uniq([tank.id, ...draft.recentlyViewed])
|
||||||
0,
|
.filter((id) => id in tankDefinitions.tanks)
|
||||||
MAX_RECENTLY_VIEWED,
|
.slice(0, MAX_RECENTLY_VIEWED);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}, [tank]);
|
}, [tank]);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
|||||||
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
import { SUPPORTED_LOCALES } from '@blitzkit/i18n';
|
||||||
import { getBestLocale } from '../core/i18n/getBestLocale';
|
import { getBestLocale } from '../core/i18n/getBestLocale';
|
||||||
|
|
||||||
|
const isAPI = window.location.pathname.startsWith('/api');
|
||||||
const isI18nPath = SUPPORTED_LOCALES.some((locale) =>
|
const isI18nPath = SUPPORTED_LOCALES.some((locale) =>
|
||||||
window.location.pathname.startsWith(`/${locale}`),
|
window.location.pathname.startsWith(`/${locale}`),
|
||||||
);
|
);
|
||||||
@@ -38,7 +39,7 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
|||||||
window.location.pathname.startsWith(`/${locale}`),
|
window.location.pathname.startsWith(`/${locale}`),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (bestLocale !== currentPathLocale) {
|
if (!isAPI && bestLocale !== currentPathLocale) {
|
||||||
window.location.pathname = isI18nPath
|
window.location.pathname = isI18nPath
|
||||||
? window.location.pathname.replace(
|
? window.location.pathname.replace(
|
||||||
`/${currentPathLocale}`,
|
`/${currentPathLocale}`,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { TankSandbox } from '../../../../../components/Tankopedia/HeroSection/co
|
|||||||
import { awaitableModelDefinitions } from '../../../../../core/awaitables/modelDefinitions';
|
import { awaitableModelDefinitions } from '../../../../../core/awaitables/modelDefinitions';
|
||||||
import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions';
|
import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions';
|
||||||
import { awaitableTankDefinitions } from '../../../../../core/awaitables/tankDefinitions';
|
import { awaitableTankDefinitions } from '../../../../../core/awaitables/tankDefinitions';
|
||||||
|
import { LocaleProvider } from '../../../../../hooks/useLocale';
|
||||||
import { App } from '../../../../../stores/app';
|
import { App } from '../../../../../stores/app';
|
||||||
import { Duel } from '../../../../../stores/duel';
|
import { Duel } from '../../../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
||||||
@@ -23,6 +24,7 @@ export function Page({ id }: PageProps) {
|
|||||||
const model = modelDefinitions.models[id];
|
const model = modelDefinitions.models[id];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<LocaleProvider locale="en">
|
||||||
<App.Provider>
|
<App.Provider>
|
||||||
<TankopediaPersistent.Provider>
|
<TankopediaPersistent.Provider>
|
||||||
<Duel.Provider data={{ provisionDefinitions, tank }}>
|
<Duel.Provider data={{ provisionDefinitions, tank }}>
|
||||||
@@ -32,6 +34,7 @@ export function Page({ id }: PageProps) {
|
|||||||
</Duel.Provider>
|
</Duel.Provider>
|
||||||
</TankopediaPersistent.Provider>
|
</TankopediaPersistent.Provider>
|
||||||
</App.Provider>
|
</App.Provider>
|
||||||
|
</LocaleProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user