mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
382a23b661 | ||
|
|
98107291f5 | ||
|
|
c6779a714b | ||
|
|
ef8f0fd72d | ||
|
|
b42df81b48 | ||
|
|
536fed5448 | ||
|
|
d4c0b01343 | ||
|
|
af67126156 | ||
|
|
9930360405 | ||
|
|
4fb61d6dbd | ||
|
|
bcb7ca5c4c | ||
|
|
2be4dbea7a | ||
|
|
b951c81bf5 | ||
|
|
8c221a1295 | ||
|
|
c41f721a96 | ||
|
|
1a92cbd951 | ||
|
|
54c5faf929 | ||
|
|
d1d9e9e4d1 | ||
|
|
5ca64f839e | ||
|
|
4e7cd6f681 | ||
|
|
ba9f593716 | ||
|
|
9d3d74c7c5 | ||
|
|
aae26523ff | ||
|
|
338a2a14bf | ||
|
|
1a66cab435 | ||
|
|
3363c9ab58 | ||
|
|
10f64902aa | ||
|
|
25e1f4caa4 | ||
|
|
222fa89422 | ||
|
|
750e145f03 | ||
|
|
3bbbbfa402 | ||
|
|
f728751fa9 | ||
|
|
f5425d0e54 | ||
|
|
debaaccf4c | ||
|
|
a3e20501af | ||
|
|
c87a75f3fd | ||
|
|
55729c5eda | ||
|
|
06cbcc2339 | ||
|
|
1afe860e76 | ||
|
|
c0ac935652 | ||
|
|
7c76b0f5a5 | ||
|
|
42091c54b7 | ||
|
|
396b48d017 |
No files matched your search
@@ -1,34 +0,0 @@
|
|||||||
name: CD Asia Ratings Latest
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
host:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Use node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
cache: "npm"
|
|
||||||
|
|
||||||
- name: Install Yarn
|
|
||||||
run: npm install --location=global yarn
|
|
||||||
|
|
||||||
- name: Use node_modules cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: "**/node_modules"
|
|
||||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn
|
|
||||||
|
|
||||||
- name: Generate leaderboard
|
|
||||||
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=asia --latest
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
name: CD Asia Ratings Leaderboards
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 17 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
host:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Use node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
cache: "npm"
|
|
||||||
|
|
||||||
- name: Install Yarn
|
|
||||||
run: npm install --location=global yarn
|
|
||||||
|
|
||||||
- name: Use node_modules cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: "**/node_modules"
|
|
||||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn
|
|
||||||
|
|
||||||
- name: Generate leaderboard
|
|
||||||
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=asia
|
|
||||||
@@ -2,7 +2,7 @@ name: CD Docs
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
name: CD Europe Ratings Latest
|
name: CD Ratings Asia
|
||||||
|
|
||||||
|
# latest: '0 0 * * *'
|
||||||
|
# asia midnight: '0 17 * * *'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: '0 0 * * *'
|
||||||
|
- cron: '0 17 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
host:
|
host:
|
||||||
@@ -16,7 +20,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: "npm"
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install Yarn
|
- name: Install Yarn
|
||||||
run: npm install --location=global yarn
|
run: npm install --location=global yarn
|
||||||
@@ -24,11 +28,11 @@ jobs:
|
|||||||
- name: Use node_modules cache
|
- name: Use node_modules cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: "**/node_modules"
|
path: '**/node_modules'
|
||||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Generate leaderboard
|
- name: Generate leaderboard
|
||||||
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=eu --latest
|
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=asia --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
name: CD North America Ratings Latest
|
name: CD Ratings Europe
|
||||||
|
|
||||||
|
# latest: '0 0 * * *'
|
||||||
|
# eu midnight: '0 23 * * *'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 0 * * *'
|
||||||
|
- cron: '0 23 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
host:
|
host:
|
||||||
@@ -31,4 +35,4 @@ jobs:
|
|||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Generate leaderboard
|
- name: Generate leaderboard
|
||||||
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=na --latest
|
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=eu --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }}
|
||||||
+9
-5
@@ -1,8 +1,12 @@
|
|||||||
name: CD Europe Ratings Leaderboards
|
name: CD Ratings North America
|
||||||
|
|
||||||
|
# latest: '0 0 * * *'
|
||||||
|
# na midnight: '0 5 * * *'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 23 * * *"
|
- cron: '0 0 * * *'
|
||||||
|
- cron: '0 5 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
host:
|
host:
|
||||||
@@ -16,7 +20,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: "npm"
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install Yarn
|
- name: Install Yarn
|
||||||
run: npm install --location=global yarn
|
run: npm install --location=global yarn
|
||||||
@@ -24,11 +28,11 @@ jobs:
|
|||||||
- name: Use node_modules cache
|
- name: Use node_modules cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: "**/node_modules"
|
path: '**/node_modules'
|
||||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Generate leaderboard
|
- name: Generate leaderboard
|
||||||
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=eu
|
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=na --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: CI Build Bot
|
name: CI Build Bot
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: push
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: CI Build Docs
|
name: CI Build Docs
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: push
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: CI Build Website
|
name: CI Build Website
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: push
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
name: CD North America Ratings Leaderboards
|
name: CI Version
|
||||||
|
|
||||||
on:
|
on: push
|
||||||
schedule:
|
|
||||||
- cron: '0 5 * * *'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
host:
|
host:
|
||||||
@@ -31,4 +29,4 @@ jobs:
|
|||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Generate leaderboard
|
- name: Generate leaderboard
|
||||||
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=na
|
run: yarn lint:version
|
||||||
Vendored
+2
@@ -15,6 +15,7 @@
|
|||||||
"fuzzysort",
|
"fuzzysort",
|
||||||
"immer",
|
"immer",
|
||||||
"kranvagn",
|
"kranvagn",
|
||||||
|
"krieg",
|
||||||
"Leaderboard",
|
"Leaderboard",
|
||||||
"leaderboards",
|
"leaderboards",
|
||||||
"MURICA",
|
"MURICA",
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
"Unregistering",
|
"Unregistering",
|
||||||
"vickers",
|
"vickers",
|
||||||
"vitepress",
|
"vitepress",
|
||||||
|
"Vovko",
|
||||||
"wargaming",
|
"wargaming",
|
||||||
"webp",
|
"webp",
|
||||||
"winrate",
|
"winrate",
|
||||||
|
|||||||
@@ -14,31 +14,10 @@ Go to [application directory for Blitzkrieg](https://discord.com/application-dir
|
|||||||
|
|
||||||
### https://blitz-krieg.vercel.app/
|
### https://blitz-krieg.vercel.app/
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Visit the documentation website
|
## Visit the documentation website
|
||||||
|
|
||||||
### https://tresabhi.github.io/blitzkrieg/
|
### https://tresabhi.github.io/blitzkrieg/
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Run the bot
|
|
||||||
|
|
||||||
### Install dependencies
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create `.env`
|
|
||||||
|
|
||||||
```env
|
|
||||||
GH_TOKEN={YOUR_GITHUB_TOKEN_HERE}
|
|
||||||
DISCORD_TOKEN={YOUR_DISCORD_TOKE_HERE}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Run the command
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn dev:bot
|
|
||||||
```
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Blitzkrieg 1.15.3
|
||||||
|
|
||||||
|
The bot now gets more expressive!
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- The bot can now have presence messages; examples:
|
||||||
|
- "Living in {number} servers"
|
||||||
|
- "Server {number} users"
|
||||||
|
- "Observing {number} channels"
|
||||||
|
- More will be added in the future! Give me some ideas
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
- Moved `/credits` to `/about creators`
|
||||||
|
- `/debug` command now ditches embeds and has better information to serve
|
||||||
|
|
||||||
|
## Technical Features
|
||||||
|
|
||||||
|
- Added a workflow and lint for package and changelog version miss match
|
||||||
|
|
||||||
|
## Technical Changes
|
||||||
|
|
||||||
|
- Removed manual trigger for Asian latest ratings leaderboard archiver
|
||||||
|
- Leaderboard archiver now accepts an explicit target like `midnight` or `latest`
|
||||||
|
- Combined midnight and latest leaderboard archival workflow into one file
|
||||||
|
|
||||||
|
## Technical Fixed
|
||||||
|
|
||||||
|
- Reviewed all workflow triggers and updated them
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Blitzkrieg 1.15.4
|
||||||
|
|
||||||
|
Unlocking future potential
|
||||||
|
|
||||||
|
## Technical Changes
|
||||||
|
|
||||||
|
- Moved the word "Ratings" to the front of the workflow name
|
||||||
|
- Renamed `blitzkrieg-db` to `blitzkrieg-assets`
|
||||||
|
- Moved the region folders from the root to `regions`
|
||||||
|
|
||||||
|
## Technical Fixes
|
||||||
|
|
||||||
|
- The ratings leaderboard archiver now correctly skips undefined players
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Blitzkrieg 1.15.5
|
||||||
|
|
||||||
|
Oops, this should've been in the last patch.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- User and channel cache is now guild cache exhaustive
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Blitzkrieg 1.15.6
|
||||||
|
|
||||||
|
This should have also been in the last update lol.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
- Changed the format of `/about creators` and added one more person
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Archived ratings leaderboards are now fetched from the correct URL path
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Blitzkrieg 1.15.7
|
||||||
|
|
||||||
|
Simple yet powerful theming options for the session tracker
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- The accent color of the session tracker (hence the embed too) can now be tweaked
|
||||||
|
- Access this setting via the dropdown from Options > Accent color
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Reimplemented the commas for last numbers in the overflow count of the ratings leaderboard
|
||||||
|
- For example, "+1234567 more" will now read "+1,234,567 more"
|
||||||
|
|
||||||
|
## Technical Features
|
||||||
|
|
||||||
|
- Added class names for more in-depth customization for those who are comfortable with CSS
|
||||||
|
- `session-tracker-root`
|
||||||
|
- `session-tracker-row`
|
||||||
|
- `session-tracker-row-stat`
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Blitzkrieg 1.15.8
|
||||||
|
|
||||||
|
A request fulfilled \:\)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Added custom titles in session tracker
|
||||||
|
- Change the title through Options > Edit title...
|
||||||
|
- Colors are shown when selecting a theme color for the session tracker
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Creators
|
||||||
|
|
||||||
|
- **TrèsAbhi** `@tresabhi`: Creator and main programmer
|
||||||
|
- **Prince_NA** `@prince_na`: Game advisor & tester
|
||||||
|
- **Vovko**: Technical advisor
|
||||||
+2
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "blitzkrieg",
|
"name": "blitzkrieg",
|
||||||
"version": "1.15.2",
|
"version": "1.15.8",
|
||||||
"description": "🎉 Tools for everything World of Tanks Blitz",
|
"description": "🎉 Tools for everything World of Tanks Blitz",
|
||||||
"main": "src/server.ts",
|
"main": "src/server.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
"lint": "npx tsc",
|
"lint": "npx tsc",
|
||||||
"lint:website": "next lint",
|
"lint:website": "next lint",
|
||||||
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
|
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
|
||||||
|
"lint:version": "vite-node --script scripts/checkVersionMissMatch",
|
||||||
"knip": "knip",
|
"knip": "knip",
|
||||||
"update": "yarn upgrade --latest"
|
"update": "yarn upgrade --latest"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,12 +23,15 @@ export type BlitzkriegRatingsLeaderboardEntry = { id: number; score: number };
|
|||||||
export type BlitzkriegRatingsLeaderboard = BlitzkriegRatingsLeaderboardEntry[];
|
export type BlitzkriegRatingsLeaderboard = BlitzkriegRatingsLeaderboardEntry[];
|
||||||
|
|
||||||
const publish = argv.includes('--publish');
|
const publish = argv.includes('--publish');
|
||||||
const latest = argv.includes('--latest');
|
const target = argv
|
||||||
|
.find((arg) => arg.startsWith('--target='))
|
||||||
|
?.split('=')[1] as 'midnight' | 'latest' | undefined;
|
||||||
const server = argv.find((arg) => arg.startsWith('--region='))?.split('=')[1];
|
const server = argv.find((arg) => arg.startsWith('--region='))?.split('=')[1];
|
||||||
|
|
||||||
|
if (!target) throw new Error('Target parameter not specified');
|
||||||
if (!server) throw new Error('Region parameter not specified');
|
if (!server) throw new Error('Region parameter not specified');
|
||||||
|
|
||||||
const NEIGHBORS = 1024;
|
const NEIGHBORS = 2 ** 8;
|
||||||
const PLAYERS = await patientFetchJSON<RatingsInfo>(
|
const PLAYERS = await patientFetchJSON<RatingsInfo>(
|
||||||
`https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
`https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
||||||
).then((data) => (data.detail === undefined ? data.count : undefined));
|
).then((data) => (data.detail === undefined ? data.count : undefined));
|
||||||
@@ -98,7 +101,10 @@ await Promise.all([
|
|||||||
console.log('Converting to an array...');
|
console.log('Converting to an array...');
|
||||||
for (let index = 0; index < PLAYERS; index++) {
|
for (let index = 0; index < PLAYERS; index++) {
|
||||||
const listing = players[index + 1];
|
const listing = players[index + 1];
|
||||||
if (!listing) console.warn(`Position ${index + 1} had no player`);
|
if (!listing) {
|
||||||
|
console.warn(`Position ${index + 1} had no player`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
leaderboard[index] = {
|
leaderboard[index] = {
|
||||||
id: listing.spa_id,
|
id: listing.spa_id,
|
||||||
@@ -110,23 +116,19 @@ const leaderboardJSON = JSON.stringify(leaderboard);
|
|||||||
|
|
||||||
if (publish) {
|
if (publish) {
|
||||||
const octokit = new Octokit({ auth: env.GH_TOKEN });
|
const octokit = new Octokit({ auth: env.GH_TOKEN });
|
||||||
|
|
||||||
const info = await patientFetchJSON<RatingsInfo & { detail: undefined }>(
|
const info = await patientFetchJSON<RatingsInfo & { detail: undefined }>(
|
||||||
`https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
`https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
||||||
);
|
);
|
||||||
const normalizedServer = server === 'na' ? 'com' : server;
|
const normalizedServer = server === 'na' ? 'com' : server;
|
||||||
|
const infoPath = `regions/${normalizedServer}/ratings/${info.current_season}/info.json`;
|
||||||
const infoPath = `${normalizedServer}/ratings/${info.current_season}/info.json`;
|
const leaderboardPath = `regions/${normalizedServer}/ratings/${info.current_season}/${target}.json`;
|
||||||
const leaderboardPath = `${normalizedServer}/ratings/${info.current_season}/${
|
|
||||||
latest ? 'latest' : 'midnight'
|
|
||||||
}.json`;
|
|
||||||
const infoJSON = JSON.stringify(info);
|
const infoJSON = JSON.stringify(info);
|
||||||
|
|
||||||
console.log(`Publishing to season ${info.current_season}...`);
|
console.log(`Publishing to season ${info.current_season}...`);
|
||||||
commitMultipleFiles(
|
commitMultipleFiles(
|
||||||
octokit,
|
octokit,
|
||||||
'tresabhi',
|
'tresabhi',
|
||||||
'blitzkrieg-db',
|
'blitzkrieg-assets',
|
||||||
'main',
|
'main',
|
||||||
new Date().toString(),
|
new Date().toString(),
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { readdir } from 'fs/promises';
|
||||||
|
import packageJSON from '../package.json';
|
||||||
|
|
||||||
|
const { version } = packageJSON;
|
||||||
|
const changelogs = await readdir('docs/changelogs');
|
||||||
|
const hasVersion = changelogs.includes(`${version}.md`);
|
||||||
|
|
||||||
|
if (hasVersion) {
|
||||||
|
console.log(`Version ${version} found in changelogs`);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Version ${version} not found in changelogs`);
|
||||||
|
}
|
||||||
@@ -207,15 +207,9 @@ export default function SessionPage() {
|
|||||||
since !== undefined &&
|
since !== undefined &&
|
||||||
diff !== undefined && (
|
diff !== undefined && (
|
||||||
<Breakdown.Row
|
<Breakdown.Row
|
||||||
|
color={session.color}
|
||||||
minimized={!session.showCareer}
|
minimized={!session.showCareer}
|
||||||
title={`Since ${since.toLocaleString(undefined, {
|
title={session.title}
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true,
|
|
||||||
month: 'short',
|
|
||||||
year: 'numeric',
|
|
||||||
day: 'numeric',
|
|
||||||
})}`}
|
|
||||||
stats={session.customColumns.map((customColumn) => {
|
stats={session.customColumns.map((customColumn) => {
|
||||||
const rowStat = totalRowStats[customColumn.display];
|
const rowStat = totalRowStats[customColumn.display];
|
||||||
|
|
||||||
@@ -293,6 +287,7 @@ export default function SessionPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Breakdown.Row
|
<Breakdown.Row
|
||||||
|
color={session.color}
|
||||||
key={stats.tank_id}
|
key={stats.tank_id}
|
||||||
minimized={!session.showCareer}
|
minimized={!session.showCareer}
|
||||||
title={tankopedia?.name ?? `Unknown tank ${stats.tank_id}`}
|
title={tankopedia?.name ?? `Unknown tank ${stats.tank_id}`}
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ export function CustomColumn({ column, Builder }: CustomColumn) {
|
|||||||
<Builder.SubTrigger>Column {column + 1}</Builder.SubTrigger>
|
<Builder.SubTrigger>Column {column + 1}</Builder.SubTrigger>
|
||||||
|
|
||||||
<Builder.SubContent>
|
<Builder.SubContent>
|
||||||
<Builder.Label>Display</Builder.Label>
|
|
||||||
|
|
||||||
<Builder.RadioGroup
|
<Builder.RadioGroup
|
||||||
value={customColumn.display}
|
value={customColumn.display}
|
||||||
onValueChange={(event) =>
|
onValueChange={(event) =>
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
import { ContextMenu, DropdownMenu } from '@radix-ui/themes';
|
import {
|
||||||
|
Button,
|
||||||
|
ContextMenu,
|
||||||
|
Dialog,
|
||||||
|
DropdownMenu,
|
||||||
|
Flex,
|
||||||
|
Heading,
|
||||||
|
TextField,
|
||||||
|
} from '@radix-ui/themes';
|
||||||
|
import { createColors } from 'bepaint';
|
||||||
|
import { useRef, useState } from 'react';
|
||||||
|
import {
|
||||||
|
ACCENT_COLORS,
|
||||||
|
AccentColor,
|
||||||
|
GRAY_COLORS,
|
||||||
|
GrayColor,
|
||||||
|
PALETTES,
|
||||||
|
} from '../../../../constants/radixColors';
|
||||||
import { useSession } from '../../../../stores/session';
|
import { useSession } from '../../../../stores/session';
|
||||||
import { CustomColumn } from './CustomColumn';
|
import { CustomColumn } from './CustomColumn';
|
||||||
|
|
||||||
@@ -9,38 +26,111 @@ interface ContextMenuProps {
|
|||||||
|
|
||||||
export function Menu({ Builder, reset }: ContextMenuProps) {
|
export function Menu({ Builder, reset }: ContextMenuProps) {
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
|
const [showTitleEditor, setShowTitleEditor] = useState(false);
|
||||||
|
const titleInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Builder.Content>
|
<>
|
||||||
<CustomColumn Builder={Builder} column={0} />
|
<Dialog.Root open={showTitleEditor} onOpenChange={setShowTitleEditor}>
|
||||||
<CustomColumn Builder={Builder} column={1} />
|
<Dialog.Content>
|
||||||
<CustomColumn Builder={Builder} column={2} />
|
<Flex direction="column" gap="4">
|
||||||
<CustomColumn Builder={Builder} column={3} />
|
<Heading size="4">Edit title</Heading>
|
||||||
|
|
||||||
<Builder.Separator />
|
<Flex gap="2" style={{ width: '100%' }}>
|
||||||
|
<TextField.Root style={{ flex: 1 }}>
|
||||||
|
<TextField.Input
|
||||||
|
ref={titleInput}
|
||||||
|
defaultValue={session.title}
|
||||||
|
placeholder="Enter title..."
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter' && titleInput.current) {
|
||||||
|
setShowTitleEditor(false);
|
||||||
|
useSession.setState({ title: titleInput.current!.value });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TextField.Root>
|
||||||
|
|
||||||
<Builder.CheckboxItem
|
<Dialog.Close>
|
||||||
checked={session.showTotal}
|
<Button
|
||||||
onCheckedChange={(checked) =>
|
onClick={() =>
|
||||||
useSession.setState({ showTotal: checked })
|
useSession.setState({ title: titleInput.current!.value })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Show total
|
Set
|
||||||
</Builder.CheckboxItem>
|
</Button>
|
||||||
<Builder.CheckboxItem
|
</Dialog.Close>
|
||||||
checked={session.showCareer}
|
</Flex>
|
||||||
onCheckedChange={(checked) =>
|
</Flex>
|
||||||
useSession.setState({ showCareer: checked })
|
</Dialog.Content>
|
||||||
}
|
</Dialog.Root>
|
||||||
>
|
|
||||||
Show career
|
|
||||||
</Builder.CheckboxItem>
|
|
||||||
|
|
||||||
<Builder.Separator />
|
<Builder.Content>
|
||||||
|
<Builder.Sub>
|
||||||
|
<Builder.SubTrigger>Accent color</Builder.SubTrigger>
|
||||||
|
|
||||||
<Builder.Item color="red" onClick={reset}>
|
<Builder.SubContent>
|
||||||
Reset
|
<Builder.RadioGroup
|
||||||
</Builder.Item>
|
value={session.color}
|
||||||
</Builder.Content>
|
onValueChange={(value) =>
|
||||||
|
useSession.setState({ color: value as AccentColor | GrayColor })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{[...ACCENT_COLORS, ...GRAY_COLORS].map((color) => (
|
||||||
|
<Builder.RadioItem value={color} key={color}>
|
||||||
|
<Flex gap="2" align="center">
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: createColors(PALETTES[color])
|
||||||
|
.solidBackground,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
borderRadius: '100%',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{`${color.charAt(0).toUpperCase()}${color.slice(1)}`}
|
||||||
|
</Flex>
|
||||||
|
</Builder.RadioItem>
|
||||||
|
))}
|
||||||
|
</Builder.RadioGroup>
|
||||||
|
</Builder.SubContent>
|
||||||
|
</Builder.Sub>
|
||||||
|
|
||||||
|
<Builder.Separator />
|
||||||
|
|
||||||
|
<Builder.Item onClick={() => setShowTitleEditor(true)}>
|
||||||
|
Edit title...
|
||||||
|
</Builder.Item>
|
||||||
|
<CustomColumn Builder={Builder} column={0} />
|
||||||
|
<CustomColumn Builder={Builder} column={1} />
|
||||||
|
<CustomColumn Builder={Builder} column={2} />
|
||||||
|
<CustomColumn Builder={Builder} column={3} />
|
||||||
|
|
||||||
|
<Builder.Separator />
|
||||||
|
|
||||||
|
<Builder.CheckboxItem
|
||||||
|
checked={session.showTotal}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
useSession.setState({ showTotal: checked })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Show total
|
||||||
|
</Builder.CheckboxItem>
|
||||||
|
<Builder.CheckboxItem
|
||||||
|
checked={session.showCareer}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
useSession.setState({ showCareer: checked })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Show career
|
||||||
|
</Builder.CheckboxItem>
|
||||||
|
|
||||||
|
<Builder.Separator />
|
||||||
|
|
||||||
|
<Builder.Item color="red" onClick={reset}>
|
||||||
|
Reset
|
||||||
|
</Builder.Item>
|
||||||
|
</Builder.Content>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ const DOCS = {
|
|||||||
introduction: 'guide/introduction',
|
introduction: 'guide/introduction',
|
||||||
invite: 'guide/invite',
|
invite: 'guide/invite',
|
||||||
timezones: 'guide/timezones',
|
timezones: 'guide/timezones',
|
||||||
|
creators: 'guide/creators',
|
||||||
};
|
};
|
||||||
const DOC_DESCRIPTIONS: Record<keyof typeof DOCS, string> = {
|
const DOC_DESCRIPTIONS: Record<keyof typeof DOCS, string> = {
|
||||||
permissions: 'The permissions needed for the bot to function',
|
permissions: 'The permissions needed for the bot to function',
|
||||||
@@ -18,6 +19,7 @@ const DOC_DESCRIPTIONS: Record<keyof typeof DOCS, string> = {
|
|||||||
introduction: 'About the bot',
|
introduction: 'About the bot',
|
||||||
invite: 'How to invite the bot',
|
invite: 'How to invite the bot',
|
||||||
timezones: 'How Blitzkrieg infers and uses your timezone',
|
timezones: 'How Blitzkrieg infers and uses your timezone',
|
||||||
|
creators: 'Who created the bot',
|
||||||
};
|
};
|
||||||
|
|
||||||
function addDocsSubcommands(option: SlashCommandSubcommandsOnlyBuilder) {
|
function addDocsSubcommands(option: SlashCommandSubcommandsOnlyBuilder) {
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import { AttachmentBuilder, SlashCommandBuilder } from 'discord.js';
|
|
||||||
import { CommandRegistry } from '../events/interactionCreate';
|
|
||||||
|
|
||||||
export const creditsCommand: CommandRegistry = {
|
|
||||||
inProduction: true,
|
|
||||||
inPublic: true,
|
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
|
||||||
.setName('credits')
|
|
||||||
.setDescription('Me and the people who made this bot'),
|
|
||||||
|
|
||||||
async handler() {
|
|
||||||
return new AttachmentBuilder('https://i.imgur.com/ZF5ch33.png');
|
|
||||||
},
|
|
||||||
};
|
|
||||||
+15
-23
@@ -1,11 +1,6 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
import packageJSON from '../../package.json' assert { type: 'json' };
|
import packageJSON from '../../package.json' assert { type: 'json' };
|
||||||
import getClientId from '../core/blitzkrieg/getClientId';
|
|
||||||
import { tankAverages } from '../core/blitzstars/tankAverages';
|
|
||||||
import { tankopedia } from '../core/blitzstars/tankopedia';
|
|
||||||
import { client } from '../core/discord/client';
|
import { client } from '../core/discord/client';
|
||||||
import embedInfo from '../core/discord/embedInfo';
|
|
||||||
import markdownTable from '../core/discord/markdownTable';
|
|
||||||
import { CommandRegistry } from '../events/interactionCreate';
|
import { CommandRegistry } from '../events/interactionCreate';
|
||||||
|
|
||||||
const executionStart = new Date().getTime();
|
const executionStart = new Date().getTime();
|
||||||
@@ -21,24 +16,21 @@ export const debugCommand: CommandRegistry = {
|
|||||||
async handler(interaction) {
|
async handler(interaction) {
|
||||||
const currentTime = new Date().getTime();
|
const currentTime = new Date().getTime();
|
||||||
const uptime = currentTime - executionStart;
|
const uptime = currentTime - executionStart;
|
||||||
|
const list = [
|
||||||
|
['Version', packageJSON.version],
|
||||||
|
['Shard', client.shard?.ids[0] ?? 'default'],
|
||||||
|
[
|
||||||
|
'Uptime',
|
||||||
|
`${Math.floor((uptime / 1000 / 60 / 60) % 24)}h ${Math.floor(
|
||||||
|
(uptime / 1000 / 60) % 60,
|
||||||
|
)}m ${Math.floor((uptime / 1000) % 60)}s ${Math.floor(
|
||||||
|
uptime % 1000,
|
||||||
|
)}ms`,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
.map(([key, value]) => `- ${key}: ${value}`)
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
return embedInfo(
|
return `# Debug\n\n${list}`;
|
||||||
`${client.user?.username} debug information`,
|
|
||||||
markdownTable([
|
|
||||||
['Version', packageJSON.version],
|
|
||||||
['Client ID', getClientId()],
|
|
||||||
['Tag', interaction.client.user.tag],
|
|
||||||
[
|
|
||||||
'Uptime',
|
|
||||||
`${Math.floor(uptime / 1000 / 60 / 60 / 24)}d ${Math.floor(
|
|
||||||
(uptime / 1000 / 60 / 60) % 24,
|
|
||||||
)}h ${Math.floor((uptime / 1000 / 60) % 60)}m ${Math.floor(
|
|
||||||
(uptime / 1000) % 60,
|
|
||||||
)}s ${Math.floor(uptime % 1000)}ms`,
|
|
||||||
],
|
|
||||||
['Tankopedia cached', `${(await tankopedia) !== undefined}`],
|
|
||||||
['Tank averages cached', `${(await tankAverages) !== undefined}`],
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -17,7 +17,6 @@ import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo';
|
|||||||
import getRatingsInfo from '../core/blitz/getRatingsInfo';
|
import getRatingsInfo from '../core/blitz/getRatingsInfo';
|
||||||
import { getRatingsLeague } from '../core/blitz/getRatingsLeague';
|
import { getRatingsLeague } from '../core/blitz/getRatingsLeague';
|
||||||
import { getRatingsNeighbors } from '../core/blitz/getRatingsNeighbors';
|
import { getRatingsNeighbors } from '../core/blitz/getRatingsNeighbors';
|
||||||
import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain';
|
|
||||||
import { getArchivedLatestSeasonNumber } from '../core/blitzkrieg/getArchivedLatestSeasonNumber';
|
import { getArchivedLatestSeasonNumber } from '../core/blitzkrieg/getArchivedLatestSeasonNumber';
|
||||||
import getArchivedRatingsInfo from '../core/blitzkrieg/getArchivedRatingsInfo';
|
import getArchivedRatingsInfo from '../core/blitzkrieg/getArchivedRatingsInfo';
|
||||||
import { getArchivedRatingsLeaderboard } from '../core/blitzkrieg/getArchivedRatingsLeaderboard';
|
import { getArchivedRatingsLeaderboard } from '../core/blitzkrieg/getArchivedRatingsLeaderboard';
|
||||||
@@ -256,7 +255,6 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
|||||||
|
|
||||||
if (regionRatingsInfo.detail !== undefined) return noOngoingSeason;
|
if (regionRatingsInfo.detail !== undefined) return noOngoingSeason;
|
||||||
|
|
||||||
const regionSubdomain = regionToRegionSubdomain(region);
|
|
||||||
const result =
|
const result =
|
||||||
subcommandGroup === 'current'
|
subcommandGroup === 'current'
|
||||||
? await getRatingsLeague(region, leagueIndex).then(
|
? await getRatingsLeague(region, leagueIndex).then(
|
||||||
@@ -461,11 +459,15 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
|||||||
{items && (
|
{items && (
|
||||||
<Leaderboard.Root>
|
<Leaderboard.Root>
|
||||||
{playersBefore > 0 && (
|
{playersBefore > 0 && (
|
||||||
<Leaderboard.Gap message={`+ ${playersBefore} more`} />
|
<Leaderboard.Gap
|
||||||
|
message={`+ ${playersBefore.toLocaleString()} more`}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{items}
|
{items}
|
||||||
{playersAfter > 0 && (
|
{playersAfter > 0 && (
|
||||||
<Leaderboard.Gap message={`+ ${playersAfter} more`} />
|
<Leaderboard.Gap
|
||||||
|
message={`+ ${playersAfter.toLocaleString()} more`}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</Leaderboard.Root>
|
</Leaderboard.Root>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ export interface RootProps {
|
|||||||
|
|
||||||
export function Root({ children }: RootProps) {
|
export function Root({ children }: RootProps) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
<div
|
||||||
|
className="session-tracker-root"
|
||||||
|
style={{ display: 'flex', flexDirection: 'column', gap: 8 }}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
import { createColors } from 'bepaint';
|
||||||
import { Percentile } from '../../../constants/percentiles';
|
import { Percentile } from '../../../constants/percentiles';
|
||||||
import { theme } from '../../../stitches.config';
|
import {
|
||||||
|
AccentColor,
|
||||||
|
GrayColor,
|
||||||
|
PALETTES,
|
||||||
|
} from '../../../constants/radixColors';
|
||||||
import { TREE_TYPE_ICONS, TreeTypeEnum } from '../../Tanks';
|
import { TREE_TYPE_ICONS, TreeTypeEnum } from '../../Tanks';
|
||||||
import { RowStat } from './RowStat';
|
import { RowStat } from './RowStat';
|
||||||
|
|
||||||
@@ -17,18 +22,29 @@ interface RowProps {
|
|||||||
minimized?: boolean;
|
minimized?: boolean;
|
||||||
treeType?: TreeTypeEnum;
|
treeType?: TreeTypeEnum;
|
||||||
tankType?: string;
|
tankType?: string;
|
||||||
|
color?: AccentColor | GrayColor;
|
||||||
stats: (RowStatItem | undefined)[];
|
stats: (RowStatItem | undefined)[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Row(props: RowProps) {
|
export function Row({
|
||||||
|
color = 'slate',
|
||||||
|
stats,
|
||||||
|
title,
|
||||||
|
minimized,
|
||||||
|
tankType,
|
||||||
|
treeType,
|
||||||
|
type,
|
||||||
|
}: RowProps) {
|
||||||
|
const theme = createColors(PALETTES[`${color}Dark`]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
className="session-tracker-row"
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
backgroundColor: theme.colors.appBackground2,
|
backgroundColor: theme.appBackground2,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -39,16 +55,12 @@ export function Row(props: RowProps) {
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
padding: 8,
|
padding: 8,
|
||||||
gap: 4,
|
gap: 4,
|
||||||
backgroundColor: theme.colors.componentInteractive,
|
backgroundColor: theme.componentInteractive,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.type === 'tank' && props.tankType !== undefined && (
|
{type === 'tank' && tankType !== undefined && (
|
||||||
<img
|
<img
|
||||||
src={
|
src={TREE_TYPE_ICONS[treeType ?? TreeTypeEnum.TechTree][tankType]}
|
||||||
TREE_TYPE_ICONS[props.treeType ?? TreeTypeEnum.TechTree][
|
|
||||||
props.tankType
|
|
||||||
]
|
|
||||||
}
|
|
||||||
style={{ width: 16, height: 16 }}
|
style={{ width: 16, height: 16 }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -56,18 +68,18 @@ export function Row(props: RowProps) {
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color:
|
color:
|
||||||
props.type === 'tank'
|
type === 'tank'
|
||||||
? props.treeType === TreeTypeEnum.Collector
|
? treeType === TreeTypeEnum.Collector
|
||||||
? theme.colors.textLowContrast_blue
|
? theme.textLowContrast_blue
|
||||||
: props.treeType === TreeTypeEnum.Premium
|
: treeType === TreeTypeEnum.Premium
|
||||||
? theme.colors.textLowContrast_amber
|
? theme.textLowContrast_amber
|
||||||
: theme.colors.textHighContrast
|
: theme.textHighContrast
|
||||||
: theme.colors.textLowContrast,
|
: theme.textLowContrast,
|
||||||
fontWeight: 900,
|
fontWeight: 900,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -78,11 +90,11 @@ export function Row(props: RowProps) {
|
|||||||
paddingBottom: 8,
|
paddingBottom: 8,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.stats.map(
|
{stats.map(
|
||||||
(row, index) =>
|
(row, index) =>
|
||||||
row && (
|
row && (
|
||||||
<RowStat
|
<RowStat
|
||||||
minimized={props.minimized}
|
minimized={minimized}
|
||||||
key={index}
|
key={index}
|
||||||
name={`${row.title} • ${row.career ?? '--'}`}
|
name={`${row.title} • ${row.career ?? '--'}`}
|
||||||
value={row.current ?? '--'}
|
value={row.current ?? '--'}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
import { createColors } from 'bepaint';
|
||||||
import { Percentile } from '../../../constants/percentiles';
|
import { Percentile } from '../../../constants/percentiles';
|
||||||
import { theme } from '../../../stitches.config';
|
import {
|
||||||
|
AccentColor,
|
||||||
|
GrayColor,
|
||||||
|
PALETTES,
|
||||||
|
} from '../../../constants/radixColors';
|
||||||
import PercentileIndicator from '../../PercentileIndicator';
|
import PercentileIndicator from '../../PercentileIndicator';
|
||||||
|
|
||||||
export interface RowStatProps {
|
export interface RowStatProps {
|
||||||
@@ -8,6 +13,7 @@ export interface RowStatProps {
|
|||||||
delta?: number;
|
delta?: number;
|
||||||
percentile?: Percentile;
|
percentile?: Percentile;
|
||||||
minimized?: boolean;
|
minimized?: boolean;
|
||||||
|
color?: AccentColor | GrayColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RowStat({
|
export function RowStat({
|
||||||
@@ -16,9 +22,13 @@ export function RowStat({
|
|||||||
delta,
|
delta,
|
||||||
percentile,
|
percentile,
|
||||||
minimized = false,
|
minimized = false,
|
||||||
|
color = 'slate',
|
||||||
}: RowStatProps) {
|
}: RowStatProps) {
|
||||||
|
const theme = createColors(PALETTES[`${color}Dark`]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
className="session-tracker-row-stat"
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
@@ -52,7 +62,7 @@ export function RowStat({
|
|||||||
|
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: theme.colors.textHighContrast,
|
color: theme.textHighContrast,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
@@ -65,7 +75,7 @@ export function RowStat({
|
|||||||
{!minimized && (
|
{!minimized && (
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: theme.colors.textLowContrast,
|
color: theme.textLowContrast,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import * as colors from '@radix-ui/colors';
|
||||||
|
import { Theme } from '@radix-ui/themes';
|
||||||
|
import { ComponentProps } from 'react';
|
||||||
|
|
||||||
|
export type AccentColor = Exclude<
|
||||||
|
ComponentProps<typeof Theme>['accentColor'],
|
||||||
|
'gray' | undefined
|
||||||
|
>;
|
||||||
|
export type AccentColorDark = `${AccentColor}Dark`;
|
||||||
|
export type GrayColor = Exclude<
|
||||||
|
ComponentProps<typeof Theme>['grayColor'],
|
||||||
|
'auto' | undefined
|
||||||
|
>;
|
||||||
|
export type GrayColorDark = `${GrayColor}Dark`;
|
||||||
|
|
||||||
|
export const ACCENT_COLORS: AccentColor[] = [
|
||||||
|
'tomato',
|
||||||
|
'red',
|
||||||
|
'ruby',
|
||||||
|
'crimson',
|
||||||
|
'pink',
|
||||||
|
'plum',
|
||||||
|
'purple',
|
||||||
|
'violet',
|
||||||
|
'iris',
|
||||||
|
'indigo',
|
||||||
|
'blue',
|
||||||
|
'cyan',
|
||||||
|
'teal',
|
||||||
|
'jade',
|
||||||
|
'green',
|
||||||
|
'grass',
|
||||||
|
'brown',
|
||||||
|
'orange',
|
||||||
|
'sky',
|
||||||
|
'mint',
|
||||||
|
'lime',
|
||||||
|
'yellow',
|
||||||
|
'amber',
|
||||||
|
'gold',
|
||||||
|
'bronze',
|
||||||
|
];
|
||||||
|
export const GRAY_COLORS: GrayColor[] = [
|
||||||
|
'gray',
|
||||||
|
'mauve',
|
||||||
|
'slate',
|
||||||
|
'sage',
|
||||||
|
'olive',
|
||||||
|
'sand',
|
||||||
|
];
|
||||||
|
|
||||||
|
export const PALETTES: Record<
|
||||||
|
AccentColor | AccentColorDark | GrayColor | GrayColorDark,
|
||||||
|
{ [key: `${string}${number}`]: string }
|
||||||
|
> = colors;
|
||||||
@@ -8,7 +8,7 @@ export async function getArchivedLatestSeasonNumber() {
|
|||||||
if (ratingsInfo.detail) {
|
if (ratingsInfo.detail) {
|
||||||
const comURL = (
|
const comURL = (
|
||||||
(await fetch(
|
(await fetch(
|
||||||
'https://api.github.com/repos/tresabhi/blitzkrieg-db/git/trees/main',
|
'https://api.github.com/repos/tresabhi/blitzkrieg-assets/git/trees/main/regions',
|
||||||
).then((response) => response.json())) as {
|
).then((response) => response.json())) as {
|
||||||
tree: { path: string; url: string }[];
|
tree: { path: string; url: string }[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default async function getArchivedRatingsInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-db/main/${region}/ratings/${season}/info.json`,
|
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-assets/main/regions/${region}/ratings/${season}/info.json`,
|
||||||
);
|
);
|
||||||
const jsonContent = (await response.json()) as RatingsInfo & {
|
const jsonContent = (await response.json()) as RatingsInfo & {
|
||||||
detail: undefined;
|
detail: undefined;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export async function getArchivedRatingsLeaderboard(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-db/main/${region}/ratings/${season}/latest.json`,
|
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-assets/main/regions/${region}/ratings/${season}/latest.json`,
|
||||||
);
|
);
|
||||||
const json = (await response.json()) as BlitzkriegRatingsLeaderboard;
|
const json = (await response.json()) as BlitzkriegRatingsLeaderboard;
|
||||||
LEADERBOARD_CACHE[region][season] = json;
|
LEADERBOARD_CACHE[region][season] = json;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
|
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
|
||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
|
|
||||||
export const DATABASE_REPO = { owner: 'tresabhi', repo: 'blitzkrieg-db' };
|
export const DATABASE_REPO = { owner: 'tresabhi', repo: 'blitzkrieg-assets' };
|
||||||
|
|
||||||
const MIDNIGHT_LEADERBOARD_CACHE: Record<
|
const MIDNIGHT_LEADERBOARD_CACHE: Record<
|
||||||
Region,
|
Region,
|
||||||
@@ -22,7 +22,7 @@ export default async function getArchivedRatingsMidnightLeaderboard(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-db/main/${region}/ratings/${season}/midnight.json`,
|
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-assets/main/regions/${region}/ratings/${season}/midnight.json`,
|
||||||
);
|
);
|
||||||
const json = (await response.json()) as BlitzkriegRatingsLeaderboard;
|
const json = (await response.json()) as BlitzkriegRatingsLeaderboard;
|
||||||
MIDNIGHT_LEADERBOARD_CACHE[region][season] = json;
|
MIDNIGHT_LEADERBOARD_CACHE[region][season] = json;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ export async function patientFetchJSON<Type extends object>(
|
|||||||
|
|
||||||
while (patientJSON! === undefined) {
|
while (patientJSON! === undefined) {
|
||||||
try {
|
try {
|
||||||
patientJSON = (await fetch(url, options).then(({ json }) =>
|
patientJSON = (await fetch(url, options).then((response) =>
|
||||||
json(),
|
response.json(),
|
||||||
)) as Type;
|
)) as Type;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Client, GatewayIntentBits } from 'discord.js';
|
import { Client, GatewayIntentBits } from 'discord.js';
|
||||||
import guildMemberAdd from '../../events/guildMemberAdd';
|
import guildMemberAdd from '../../events/guildMemberAdd';
|
||||||
import interactionCreate from '../../events/interactionCreate';
|
import interactionCreate from '../../events/interactionCreate';
|
||||||
|
import ready from '../../events/ready';
|
||||||
|
|
||||||
export const client = new Client({
|
export const client = new Client({
|
||||||
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
|
||||||
})
|
})
|
||||||
// .on('ready', ready)
|
.on('ready', ready)
|
||||||
.on('guildMemberAdd', guildMemberAdd)
|
.on('guildMemberAdd', guildMemberAdd)
|
||||||
.on('interactionCreate', interactionCreate);
|
.on('interactionCreate', interactionCreate);
|
||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
import discord from '../../../discord.json' assert { type: 'json' };
|
import discord from '../../../discord.json' assert { type: 'json' };
|
||||||
import { aboutCommand } from '../../commands/about';
|
import { aboutCommand } from '../../commands/about';
|
||||||
import { breakdownCommand } from '../../commands/breakdown';
|
import { breakdownCommand } from '../../commands/breakdown';
|
||||||
import { creditsCommand } from '../../commands/credits';
|
|
||||||
import { debugCommand } from '../../commands/debug';
|
import { debugCommand } from '../../commands/debug';
|
||||||
import { eligibleCommand } from '../../commands/eligible';
|
import { eligibleCommand } from '../../commands/eligible';
|
||||||
import { evolutionCommand } from '../../commands/evolution';
|
import { evolutionCommand } from '../../commands/evolution';
|
||||||
@@ -102,7 +101,6 @@ export const COMMANDS_RAW: CommandRegistry[] = [
|
|||||||
evolutionCommand,
|
evolutionCommand,
|
||||||
statsCommand,
|
statsCommand,
|
||||||
ratingsCommand,
|
ratingsCommand,
|
||||||
creditsCommand,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const commands = Promise.all(COMMANDS_RAW).then((rawCommands) =>
|
export const commands = Promise.all(COMMANDS_RAW).then((rawCommands) =>
|
||||||
|
|||||||
+26
-2
@@ -1,5 +1,29 @@
|
|||||||
import { Client } from 'discord.js';
|
import { ActivityType, Client } from 'discord.js';
|
||||||
|
|
||||||
export default function ready(client: Client<true>) {
|
export default function ready(client: Client<true>) {
|
||||||
console.log(`🟢 Launched bot ${client.shard?.ids[0]}`);
|
console.log(`🟢 Launched bot ${client.shard?.ids[0] ?? 'default'}`);
|
||||||
|
|
||||||
|
const activities: (() => string)[] = [
|
||||||
|
() => `Living in ${client.guilds.cache.size.toLocaleString()} servers`,
|
||||||
|
() =>
|
||||||
|
`Serving ${client.guilds.cache
|
||||||
|
.reduce((accumulator, guild) => accumulator + guild.memberCount, 0)
|
||||||
|
.toLocaleString()} users`,
|
||||||
|
() =>
|
||||||
|
`Observing ${client.guilds.cache
|
||||||
|
.reduce(
|
||||||
|
(accumulator, guild) => accumulator + guild.channels.cache.size,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.toLocaleString()} channels`,
|
||||||
|
];
|
||||||
|
|
||||||
|
client.user.setPresence({
|
||||||
|
activities: [
|
||||||
|
{
|
||||||
|
type: ActivityType.Custom,
|
||||||
|
name: activities[Math.floor(Math.random() * activities.length)](),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ import { produce } from 'immer';
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { CustomColumnDisplay } from '../app/tools/session/components/CustomColumn';
|
import { CustomColumnDisplay } from '../app/tools/session/components/CustomColumn';
|
||||||
|
import { AccentColor, GrayColor } from '../constants/radixColors';
|
||||||
import { Region } from '../constants/regions';
|
import { Region } from '../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from '../core/blitz/fetchBlitz';
|
import fetchBlitz from '../core/blitz/fetchBlitz';
|
||||||
@@ -21,6 +22,7 @@ type Session = (
|
|||||||
time: number;
|
time: number;
|
||||||
}
|
}
|
||||||
) & {
|
) & {
|
||||||
|
title: string;
|
||||||
resetPrompt: boolean;
|
resetPrompt: boolean;
|
||||||
embedPrompt: boolean;
|
embedPrompt: boolean;
|
||||||
customColumns: {
|
customColumns: {
|
||||||
@@ -29,6 +31,7 @@ type Session = (
|
|||||||
}[] & { length: 4 };
|
}[] & { length: 4 };
|
||||||
showTotal: boolean;
|
showTotal: boolean;
|
||||||
showCareer: boolean;
|
showCareer: boolean;
|
||||||
|
color: AccentColor | GrayColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function setSession(region: Region, id: number, nickname: string) {
|
export async function setSession(region: Region, id: number, nickname: string) {
|
||||||
@@ -66,6 +69,7 @@ export const useSession = create<Session>()(
|
|||||||
devtools(
|
devtools(
|
||||||
persist(
|
persist(
|
||||||
(set) => ({
|
(set) => ({
|
||||||
|
title: 'Untitled session',
|
||||||
isTracking: false,
|
isTracking: false,
|
||||||
resetPrompt: true,
|
resetPrompt: true,
|
||||||
showTotal: true,
|
showTotal: true,
|
||||||
@@ -78,10 +82,9 @@ export const useSession = create<Session>()(
|
|||||||
{ display: 'wn8', showDelta: false },
|
{ display: 'wn8', showDelta: false },
|
||||||
{ display: 'damage', showDelta: true },
|
{ display: 'damage', showDelta: true },
|
||||||
],
|
],
|
||||||
|
color: 'slate',
|
||||||
}),
|
}),
|
||||||
{
|
{ name: 'session' },
|
||||||
name: 'session',
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user