Migrate to Vite

This commit is contained in:
Kalle
2024-02-24 21:12:54 +02:00
parent b35a64c1f8
commit 93ebb6e369
150 changed files with 4319 additions and 3181 deletions

View File

@@ -1,5 +1,4 @@
PORT=5800
BASE_URL=http://localhost:5800
BASE_URL=http://localhost:5173
DB_PATH=db.sqlite3
LOHI_TOKEN=salmon
SESSION_SECRET=secret

View File

@@ -1,6 +0,0 @@
/**
* @type {import('prettier').Config}
*/
module.exports = {
// defaults only so far
};

View File

@@ -52,7 +52,7 @@ There is a sequence of commands you need to run:
3. Make a copy of `.env.example` that's called `.env`. Filling additional values is not necessary unless you want to use real Discord authentication or develop the Lohi bot.
4. `npm run migrate up` to set up the database tables.
5. `npm run dev` to run the project in development mode.
6. Navigate to `http://localhost:5800/admin`. There press the seed button to fill the DB with test data. You can also impersonate any user (Sendou#0043 = admin).
6. Navigate to `http://localhost:5173/admin`. There press the seed button to fill the DB with test data. You can also impersonate any user (Sendou#0043 = admin).
## Contributing
@@ -217,7 +217,7 @@ Note: This is only useful if you have access to a production running on Render.c
11. Fill new weapon IDs by category to `weapon-ids.ts` (easy to take from the diff of English weapons.json)
12. Get gear IDs for each slot from /output folder and update `gear-ids.ts`.
13. Replace `object-dmg.json` with the `object-dmg.json` in /output folder
14. Replace `weapon-params.json` with the `params.json` in /output folder
14. Replace `weapon-params.ts` with the `params.json` in /output folder
15. Delete all images inside `main-weapons`, `main-weapons-outlined`, `main-weapons-outlined-2` and `gear` folders.
16. Replace with images from Lean's repository.
17. Run the `npm run replace-img-names` command

View File

@@ -8,7 +8,7 @@ import type {
UserWithPlusTier,
} from "~/db/types";
import { useIsMounted } from "~/hooks/useIsMounted";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import type {
Ability as AbilityType,
ModeShort,

View File

@@ -1,6 +1,6 @@
import { isRouteErrorResponse, useRouteError } from "@remix-run/react";
import { Button } from "~/components/Button";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import {
ERROR_GIRL_IMAGE_PATH,
LOG_IN_URL,

View File

@@ -6,7 +6,7 @@ import {
import clsx from "clsx";
import type * as React from "react";
import { useMatches } from "react-router";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import type { RootLoaderData } from "~/root";
import { SideNav } from "app/components/layout/SideNav";

View File

@@ -1,10 +1,10 @@
import { useSearchParams } from "@remix-run/react";
import type * as React from "react";
import { useTranslation } from "react-i18next";
import { languages } from "~/modules/i18n";
import { LinkButton } from "../Button";
import { GlobeIcon } from "../icons/Globe";
import { Popover } from "../Popover";
import { languages } from "~/modules/i18n/config";
const addUniqueParam = (
oldParams: URLSearchParams,

View File

@@ -1,6 +1,6 @@
import { Link } from "@remix-run/react";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { userPage } from "~/utils/urls";
import { Avatar } from "../Avatar";
import { LogInIcon } from "../icons/LogIn";

View File

@@ -1,5 +1,5 @@
import allTags from "~/features/calendar/tags.json";
import type { CalendarEventTag } from "./db/types";
import { tags } from "./features/calendar/calendar-constants";
import type { BuildAbilitiesTupleWithUnknown } from "./modules/in-game-lists";
export const TWEET_LENGTH_MAX_LENGTH = 280;
@@ -24,7 +24,7 @@ export const CALENDAR_EVENT = {
DISCORD_INVITE_CODE_MAX_LENGTH: 50,
BRACKET_URL_MAX_LENGTH: 200,
MAX_AMOUNT_OF_DATES: 5,
TAGS: Object.keys(allTags) as Array<CalendarEventTag>,
TAGS: Object.keys(tags) as Array<CalendarEventTag>,
};
export const CALENDAR_EVENT_RESULT = {

View File

@@ -5,7 +5,6 @@ import { nanoid } from "nanoid";
import invariant from "tiny-invariant";
import { ADMIN_DISCORD_ID, ADMIN_ID, INVITE_CODE_LENGTH } from "~/constants";
import { db, sql } from "~/db/sql";
import allTags from "~/features/calendar/tags.json";
import { MapPool } from "~/features/map-list-generator/core/map-pool";
import {
lastCompletedVoting,
@@ -70,6 +69,7 @@ import {
import placements from "./placements.json";
import { BANNED_MAPS } from "~/features/sendouq-settings/banned-maps";
import { AMOUNT_OF_MAPS_IN_POOL_PER_MODE } from "~/features/sendouq-settings/q-settings-constants";
import { tags } from "~/features/calendar/calendar-constants";
const calendarEventWithToToolsRegOpen = () =>
calendarEventWithToTools("PICNIC", true);
@@ -667,7 +667,9 @@ function calendarEvents() {
const userIds = userIdsInRandomOrder();
for (let id = 1; id <= AMOUNT_OF_CALENDAR_EVENTS; id++) {
const tags = shuffle(Object.keys(allTags)).filter((tag) => tag !== "BADGE");
const shuffledTags = shuffle(Object.keys(tags)).filter(
(tag) => tag !== "BADGE",
);
sql
.prepare(
@@ -702,7 +704,7 @@ function calendarEvents() {
authorId: id === 1 ? NZAP_TEST_ID : userIds.pop(),
tags:
Math.random() > 0.2
? tags
? shuffledTags
.slice(
0,
faker.helpers.arrayElement([

View File

@@ -6,8 +6,8 @@ import type {
RankedModeShort,
StageId,
} from "~/modules/in-game-lists";
import type allTags from "~/features/calendar/tags.json";
import type { TieredSkill } from "~/features/mmr/tiered.server";
import type { tags } from "~/features/calendar/calendar-constants";
export interface User {
id: number;
@@ -135,7 +135,7 @@ export interface CalendarEvent {
tournamentId: number | null;
}
export type CalendarEventTag = keyof typeof allTags;
export type CalendarEventTag = keyof typeof tags;
export interface CalendarEventDate {
id: number;

View File

@@ -1,8 +1,8 @@
import { RemixBrowser } from "@remix-run/react";
import { hydrateRoot } from "react-dom/client";
import { i18nLoader } from "./modules/i18n";
import i18next from "i18next";
import { I18nextProvider } from "react-i18next";
import { i18nLoader } from "./modules/i18n/loader";
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {

View File

@@ -11,10 +11,10 @@ import { isbot } from "isbot";
import cron from "node-cron";
import { renderToPipeableStream } from "react-dom/server";
import { I18nextProvider } from "react-i18next";
import { getUser } from "./features/auth/core";
import { i18Instance } from "./modules/i18n";
import { getUser } from "./features/auth/core/user.server";
import { updatePatreonData } from "./modules/patreon";
import { noticeError, setTransactionName } from "./utils/newrelic.server";
import { i18Instance } from "./modules/i18n/loader.server";
const ABORT_DELAY = 5000;

View File

@@ -1,8 +1,8 @@
import { db, sql } from "~/db/sql";
import { syncXPBadges } from "../badges";
import type { Tables } from "~/db/tables";
import { dateToDatabaseTimestamp } from "~/utils/dates";
import invariant from "tiny-invariant";
import { syncXPBadges } from "../badges/queries/syncXPBadges.server";
const removeOldLikesStm = sql.prepare(/*sql*/ `
delete from

View File

@@ -17,8 +17,7 @@ import { Main } from "~/components/Main";
import { SubmitButton } from "~/components/SubmitButton";
import { UserSearch } from "~/components/UserSearch";
import * as AdminRepository from "~/features/admin/AdminRepository.server";
import { makeArtist } from "~/features/art";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import {
getUserId,
isImpersonating,
@@ -35,6 +34,7 @@ import { assertUnreachable } from "~/utils/types";
import { SEED_URL, STOP_IMPERSONATING_URL, impersonateUrl } from "~/utils/urls";
import { adminActionSchema } from "../admin-schemas.server";
import { plusTiersFromVotingAndLeaderboard } from "../core/plus-tier.server";
import { makeArtist } from "~/features/art/queries/makeArtist.server";
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Admin page") }];

View File

@@ -4,10 +4,10 @@ import { db } from "~/db/sql";
import { notFoundIfFalsy, parseParams } from "~/utils/remix";
import { id } from "~/utils/zod";
import type { GetTournamentMatchResponse } from "../schema";
import { i18next } from "~/modules/i18n";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { resolveMapList } from "~/features/tournament-bracket/core/mapList.server";
import { requireBearerAuth } from "../api-public-utils.server";
import i18next from "~/modules/i18n/i18next.server";
const paramsSchema = z.object({
id,

View File

@@ -6,8 +6,8 @@ import { id } from "~/utils/zod";
import type { GetTournamentTeamsResponse } from "../schema";
import { databaseTimestampToDate } from "~/utils/dates";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { i18next } from "~/modules/i18n";
import { requireBearerAuth } from "../api-public-utils.server";
import i18next from "~/modules/i18n/i18next.server";
const paramsSchema = z.object({
id,

View File

@@ -5,7 +5,8 @@ import { safeNumberParse } from "~/utils/number";
import { notFoundIfFalsy, parseParams } from "~/utils/remix";
import type { GetUserResponse } from "../schema";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
("~/modules/i18n");
import { requireBearerAuth } from "../api-public-utils.server";
const paramsSchema = z.object({

View File

@@ -21,4 +21,4 @@ export interface ListedArt {
}
export const ART_SOURCES = ["ALL", "MADE-BY", "MADE-OF"] as const;
export type ArtSouce = (typeof ART_SOURCES)[number];
export type ArtSource = (typeof ART_SOURCES)[number];

View File

@@ -1,10 +0,0 @@
export { ArtGrid } from "./components/ArtGrid";
export { artsByUserId } from "./queries/artsByUserId.server";
export { countArtByUserId } from "./queries/countArtByUserId.server";
export { makeArtist } from "./queries/makeArtist.server";
export { deleteArt } from "./queries/deleteArt.server";
export { findArtById } from "./queries/findArtById.server";
export type { ListedArt, ArtSouce } from "./art-types";
export { ART_SOURCES } from "./art-types";
export { NEW_ART_EXISTING_SEARCH_PARAM_KEY } from "./art-constants";
export { deleteArtSchema } from "./art-schemas.server";

View File

@@ -21,7 +21,7 @@ import { Toggle } from "~/components/Toggle";
import { CrossIcon } from "~/components/icons/Cross";
import { s3UploadHandler } from "~/features/img-upload";
import { useTranslation } from "react-i18next";
import { requireUser } from "~/features/auth/core";
import { requireUser } from "~/features/auth/core/user.server";
import { dateToDatabaseTimestamp } from "~/utils/dates";
import {
validate,

View File

@@ -10,7 +10,6 @@ import { Label } from "~/components/Label";
import { Main } from "~/components/Main";
import { Toggle } from "~/components/Toggle";
import { useTranslation } from "react-i18next";
import { i18next } from "~/modules/i18n";
import { type SendouRouteHandle } from "~/utils/remix";
import { makeTitle } from "~/utils/strings";
import { artPage, navIconUrl } from "~/utils/urls";
@@ -22,6 +21,7 @@ import {
} from "../queries/showcaseArts.server";
import { Button } from "~/components/Button";
import { CrossIcon } from "~/components/icons/Cross";
import i18next from "~/modules/i18n/i18next.server";
const FILTERED_TAG_KEY = "tag";
const OPEN_COMMISIONS_KEY = "open";

View File

@@ -2,7 +2,7 @@ import { Main } from "~/components/Main";
import type { LinksFunction } from "@remix-run/node";
import { json } from "@remix-run/node";
import { mostRecentArticles } from "../core/list.server";
import styles from "~/styles/front.css";
import styles from "~/styles/front.css?url";
import { useTranslation } from "react-i18next";
import type { SendouRouteHandle } from "~/utils/remix";
import { articlePage, ARTICLES_MAIN_PAGE, navIconUrl } from "~/utils/urls";

View File

@@ -1,15 +0,0 @@
export {
callbackLoader,
impersonateAction,
stopImpersonatingAction,
logInAction,
logOutAction,
createLogInLinkAction,
logInViaLinkLoader,
} from "./routes.server";
export { getUser, requireUser } from "./user.server";
export { useUser } from "./user";
export type { AuthErrorCode } from "./errors";

View File

@@ -1 +1 @@
export { callbackLoader as loader } from "~/features/auth/core";
export { callbackLoader as loader } from "~/features/auth/core/routes.server";

View File

@@ -1 +1 @@
export { createLogInLinkAction as action } from "~/features/auth/core";
export { createLogInLinkAction as action } from "~/features/auth/core/routes.server";

View File

@@ -1 +1 @@
export { stopImpersonatingAction as action } from "~/features/auth/core";
export { stopImpersonatingAction as action } from "~/features/auth/core/routes.server";

View File

@@ -1 +1 @@
export { impersonateAction as action } from "~/features/auth/core";
export { impersonateAction as action } from "~/features/auth/core/routes.server";

View File

@@ -1 +1 @@
export { logInViaLinkLoader as loader } from "~/features/auth/core";
export { logInViaLinkLoader as loader } from "~/features/auth/core/routes.server";

View File

@@ -1 +1 @@
export { logOutAction as action } from "~/features/auth/core";
export { logOutAction as action } from "~/features/auth/core/routes.server";

View File

@@ -1 +1 @@
export { logInAction as action } from "~/features/auth/core";
export { logInAction as action } from "~/features/auth/core/routes.server";

View File

@@ -1 +0,0 @@
export { syncXPBadges } from "./queries/syncXPBadges.server";

View File

@@ -9,7 +9,7 @@ import { Label } from "~/components/Label";
import { UserSearch } from "~/components/UserSearch";
import { TrashIcon } from "~/components/icons/Trash";
import type { User } from "~/db/types";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { requireUserId } from "~/features/auth/core/user.server";
import { canEditBadgeManagers, canEditBadgeOwners } from "~/permissions";
import { atOrError } from "~/utils/arrays";

View File

@@ -5,7 +5,7 @@ import { Badge } from "~/components/Badge";
import { LinkButton } from "~/components/Button";
import { Redirect } from "~/components/Redirect";
import { type Badge as BadgeDBType } from "~/db/types";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { canEditBadgeOwners, isMod } from "~/permissions";
import { BADGES_PAGE } from "~/utils/urls";
import { type BadgesLoaderData } from "./badges";

View File

@@ -2,7 +2,7 @@ import type { LinksFunction, SerializeFrom } from "@remix-run/node";
import { Link, NavLink, Outlet, useLoaderData } from "@remix-run/react";
import { Badge } from "~/components/Badge";
import { Main } from "~/components/Main";
import styles from "~/styles/badges.css";
import styles from "~/styles/badges.css?url";
import {
BADGES_PAGE,
BORZOIC_TWITTER,

View File

@@ -5,10 +5,10 @@ import type {
SubWeaponId,
} from "~/modules/in-game-lists";
import type { SPECIAL_EFFECTS } from "./core/specialEffects";
import type weaponParams from "./core/weapon-params.json";
import type abilityValues from "./core/ability-values.json";
import type { DAMAGE_TYPE } from "./analyzer-constants";
import type { AbilityWithUnknown } from "~/modules/in-game-lists/types";
import type { weaponParams } from "./core/weapon-params";
import type { abilityValues } from "./core/utils";
type Overwrites = Record<
string,
@@ -113,7 +113,7 @@ export interface DistanceDamage {
export interface SubWeaponParams {
overwrites?: Overwrites;
SubInkSaveLv: 0 | 1 | 2 | 3;
SubInkSaveLv: 0 | 1 | 2 | 3 | 4;
/** How much ink one usage of the sub consumes */
InkConsume: number;
/** Amount of frames white ink (=no ink recovery during this time) takes */

View File

@@ -1,72 +0,0 @@
{
"ConsumeRt_Main": [0.55, 0.775, 1.0],
"ConsumeRt_Sub_Lv0": [0.8, 0.9, 1.0],
"ConsumeRt_Sub_Lv1": [0.7, 0.85, 1.0],
"ConsumeRt_Sub_Lv2": [0.65, 0.825, 1.0],
"ConsumeRt_Sub_Lv3": [0.6, 0.8, 1.0],
"ConsumeRt_Sub_Lv4": [0.71111, 0.85555, 1.0],
"DamageRt_BombH": [0.5, 0.75, 1.0],
"DamageRt_BombL": [0.6, 0.75, 1.0],
"DamageRt_LineMarker": [0.5, 0.75, 1.0],
"DamageRt_Shield": [0.5, 0.75, 1.0],
"DamageRt_Sprinkler": [0.5, 0.75, 1.0],
"Dying_AroundFrm": [30.0, 60.0, 90.0],
"Dying_ChaseFrm": [90.0, 180.0, 270.0],
"IncreaseRt_Special": [1.3, 1.15, 1.0],
"InkRecoverFrm_Std": [220.0, 410.0, 600.0],
"InkRecoverFrm_Stealth": [117.0, 148.5, 180.0],
"MarkingTimeRt": [0.1, 0.43, 1.0],
"MarkingTimeRt_Trap": [0.1, 0.55, 1.0],
"MoveDownRt_PoisonMist": [0.5, 0.75, 1.0],
"MoveVelRt_Shot": [1.25, 1.125, 1.0],
"MoveVel_Human": [0.144, 0.12, 0.096],
"MoveVel_Human_Fast": [0.144, 0.124, 0.104],
"MoveVel_Human_Slow": [0.144, 0.116, 0.088],
"MoveVel_Stealth": [0.24, 0.216, 0.192],
"MoveVel_Stealth_Fast": [0.24, 0.2208, 0.2016],
"MoveVel_Stealth_Slow": [0.24, 0.216, 0.1728],
"OpInk_ArmorHP": [39.0, 26.0, 0.0],
"OpInk_DamageLmt": [0.2, 0.3, 0.4],
"OpInk_DamagePerFrame": [0.0015, 0.0022, 0.003],
"OpInk_JumpVel": [0.11, 0.098, 0.08],
"OpInk_MoveVel": [0.0768, 0.0557, 0.024],
"OpInk_MoveVel_Shot": [0.042, 0.033, 0.012],
"OpInk_MoveVel_ShotK": [1.0, 0.75, 0.5],
"Overwrite_ConsumeRt_Main": [-1.0, -1.0, -1.0],
"Overwrite_MoveVelRt_Shot": [-1.0, -1.0, -1.0],
"Somersault_MoveVelKd": [1.0, 0.925, 0.85],
"SpecialGaugeRt_Restart": [1.0, 0.8, 0.5],
"SuperJump_ChargeFrm": [20.0, 35.0, 80.0],
"SuperJump_MoveFrm": [96.6, 132.3, 138.0],
"WallJumpChargeFrm": [5.0, 18.0, 45.0],
"ReduceJumpSwerveRate": [1.0, 0.75, 0.0],
"SpawnSpeedZSpecUp": [0.0, 0.0, 0.0],
"MoveSpeed": [0.0, 0.0, 0.0],
"SubSpecUpParam": [0.0, 0.0, 0.0],
"PeriodFirst": [0.0, 0.0, 0.0],
"PeriodSecond": [0.0, 0.0, 0.0],
"MarkingFrameSubSpec": [0.0, 0.0, 0.0],
"SensorRadius": [0.0, 0.0, 0.0],
"ExplosionRadius": [0.0, 0.0, 0.0],
"MaxHP": [0.0, 0.0, 0.0],
"SpecialDurationFrame": [0.0, 0.0, 0.0],
"DistanceDamageDistanceRate": [0.0, 0.0, 0.0],
"PaintRadius": [0.0, 0.0, 0.0],
"MaxFieldHP": [0.0, 0.0, 0.0],
"InkConsume_Hook": [0.0, 0.0, 0.0],
"InkConsume_PerSec": [0.0, 0.0, 0.0],
"TargetInCircleRadius": [0.0, 0.0, 0.0],
"RainyFrame": [0.0, 0.0, 0.0],
"ChargeRateAutoPerFrame": [0.0, 0.0, 0.0],
"MaxFrame": [0.0, 0.0, 0.0],
"MaxRadius": [0.0, 0.0, 0.0],
"RadiusMax": [0.0, 0.0, 0.0],
"RadiusMin": [0.0, 0.0, 0.0],
"LaserFrame": [0.0, 0.0, 0.0],
"SplashAroundVelocityMin": [0.0, 0.0, 0.0],
"SplashAroundVelocityMax": [0.0, 0.0, 0.0],
"SplashAroundPaintRadius": [0.0, 0.0, 0.0],
"SpecialTotalFrame": [0.0, 0.0, 0.0],
"PowerUpFrame": [0.0, 0.0, 0.0],
"CrossPaintRadius": [0.0, 0.0, 0.0]
}

View File

@@ -0,0 +1,72 @@
export const abilityValues = {
ConsumeRt_Main: [0.55, 0.775, 1.0],
ConsumeRt_Sub_Lv0: [0.8, 0.9, 1.0],
ConsumeRt_Sub_Lv1: [0.7, 0.85, 1.0],
ConsumeRt_Sub_Lv2: [0.65, 0.825, 1.0],
ConsumeRt_Sub_Lv3: [0.6, 0.8, 1.0],
ConsumeRt_Sub_Lv4: [0.71111, 0.85555, 1.0],
DamageRt_BombH: [0.5, 0.75, 1.0],
DamageRt_BombL: [0.6, 0.75, 1.0],
DamageRt_LineMarker: [0.5, 0.75, 1.0],
DamageRt_Shield: [0.5, 0.75, 1.0],
DamageRt_Sprinkler: [0.5, 0.75, 1.0],
Dying_AroundFrm: [30.0, 60.0, 90.0],
Dying_ChaseFrm: [90.0, 180.0, 270.0],
IncreaseRt_Special: [1.3, 1.15, 1.0],
InkRecoverFrm_Std: [220.0, 410.0, 600.0],
InkRecoverFrm_Stealth: [117.0, 148.5, 180.0],
MarkingTimeRt: [0.1, 0.43, 1.0],
MarkingTimeRt_Trap: [0.1, 0.55, 1.0],
MoveDownRt_PoisonMist: [0.5, 0.75, 1.0],
MoveVelRt_Shot: [1.25, 1.125, 1.0],
MoveVel_Human: [0.144, 0.12, 0.096],
MoveVel_Human_Fast: [0.144, 0.124, 0.104],
MoveVel_Human_Slow: [0.144, 0.116, 0.088],
MoveVel_Stealth: [0.24, 0.216, 0.192],
MoveVel_Stealth_Fast: [0.24, 0.2208, 0.2016],
MoveVel_Stealth_Slow: [0.24, 0.216, 0.1728],
OpInk_ArmorHP: [39.0, 26.0, 0.0],
OpInk_DamageLmt: [0.2, 0.3, 0.4],
OpInk_DamagePerFrame: [0.0015, 0.0022, 0.003],
OpInk_JumpVel: [0.11, 0.098, 0.08],
OpInk_MoveVel: [0.0768, 0.0557, 0.024],
OpInk_MoveVel_Shot: [0.042, 0.033, 0.012],
OpInk_MoveVel_ShotK: [1.0, 0.75, 0.5],
Overwrite_ConsumeRt_Main: [-1.0, -1.0, -1.0],
Overwrite_MoveVelRt_Shot: [-1.0, -1.0, -1.0],
Somersault_MoveVelKd: [1.0, 0.925, 0.85],
SpecialGaugeRt_Restart: [1.0, 0.8, 0.5],
SuperJump_ChargeFrm: [20.0, 35.0, 80.0],
SuperJump_MoveFrm: [96.6, 132.3, 138.0],
WallJumpChargeFrm: [5.0, 18.0, 45.0],
ReduceJumpSwerveRate: [1.0, 0.75, 0.0],
SpawnSpeedZSpecUp: [0.0, 0.0, 0.0],
MoveSpeed: [0.0, 0.0, 0.0],
SubSpecUpParam: [0.0, 0.0, 0.0],
PeriodFirst: [0.0, 0.0, 0.0],
PeriodSecond: [0.0, 0.0, 0.0],
MarkingFrameSubSpec: [0.0, 0.0, 0.0],
SensorRadius: [0.0, 0.0, 0.0],
ExplosionRadius: [0.0, 0.0, 0.0],
MaxHP: [0.0, 0.0, 0.0],
SpecialDurationFrame: [0.0, 0.0, 0.0],
DistanceDamageDistanceRate: [0.0, 0.0, 0.0],
PaintRadius: [0.0, 0.0, 0.0],
MaxFieldHP: [0.0, 0.0, 0.0],
InkConsume_Hook: [0.0, 0.0, 0.0],
InkConsume_PerSec: [0.0, 0.0, 0.0],
TargetInCircleRadius: [0.0, 0.0, 0.0],
RainyFrame: [0.0, 0.0, 0.0],
ChargeRateAutoPerFrame: [0.0, 0.0, 0.0],
MaxFrame: [0.0, 0.0, 0.0],
MaxRadius: [0.0, 0.0, 0.0],
RadiusMax: [0.0, 0.0, 0.0],
RadiusMin: [0.0, 0.0, 0.0],
LaserFrame: [0.0, 0.0, 0.0],
SplashAroundVelocityMin: [0.0, 0.0, 0.0],
SplashAroundVelocityMax: [0.0, 0.0, 0.0],
SplashAroundPaintRadius: [0.0, 0.0, 0.0],
SpecialTotalFrame: [0.0, 0.0, 0.0],
PowerUpFrame: [0.0, 0.0, 0.0],
CrossPaintRadius: [0.0, 0.0, 0.0],
};

View File

@@ -52,7 +52,7 @@ import {
roundToNDecimalPlaces,
sumArray,
} from "~/utils/number";
import type abilityValuesJson from "./ability-values.json";
import type { abilityValues as abilityValuesJson } from "./ability-values";
export function buildStats({
weaponSplId,

View File

@@ -30,11 +30,11 @@ import type {
SubWeaponDamage,
SubWeaponParams,
} from "../analyzer-types";
import abilityValuesJson from "./ability-values.json";
import weaponParamsJson from "./weapon-params.json";
import { abilityValues as abilityValuesJson } from "./ability-values";
import { weaponParams as rawWeaponParams } from "./weapon-params";
export function weaponParams(): ParamsJson {
return weaponParamsJson as ParamsJson;
return rawWeaponParams as ParamsJson;
}
export function buildToAbilityPoints(build: BuildAbilitiesTupleWithUnknown) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -22,4 +22,3 @@ export {
subStats,
} from "./core/stats";
export { DAMAGE_TYPE, damageTypeToWeaponType } from "./analyzer-constants";
export { default as weaponParams } from "./core/weapon-params.json";

View File

@@ -17,7 +17,7 @@ import { BeakerIcon } from "~/components/icons/Beaker";
import { MAX_AP } from "~/constants";
import { useSetTitle } from "~/hooks/useSetTitle";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import type { Ability as AbilityType } from "~/modules/in-game-lists";
import {
ANGLE_SHOOTER_ID,
@@ -59,7 +59,7 @@ import type {
Stat,
SubWeaponDamage,
} from "../analyzer-types";
import styles from "../analyzer.css";
import styles from "../analyzer.css?url";
import {
ABILITIES_WITHOUT_CHUNKS,
getAbilityChunksMapAsArray,

View File

@@ -9,7 +9,7 @@ import clsx from "clsx";
import { Ability } from "~/components/Ability";
import { Main } from "~/components/Main";
import { useTranslation } from "react-i18next";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { notFoundIfNullLike, type SendouRouteHandle } from "~/utils/remix";
import { makeTitle } from "~/utils/strings";
import { weaponNameSlugToId } from "~/utils/unslugify.server";

View File

@@ -10,7 +10,7 @@ import { weaponNameSlugToId } from "~/utils/unslugify.server";
import { averageAbilityPoints } from "../queries/averageAbilityPoints.server";
import { abilityPointCountsToAverages } from "../build-stats-utils";
import { Ability } from "~/components/Ability";
import styles from "../build-stats.css";
import styles from "../build-stats.css?url";
import { WeaponImage } from "~/components/Image";
import { notFoundIfNullLike, type SendouRouteHandle } from "~/utils/remix";
import { MAX_AP, ONE_HOUR_IN_MS } from "~/constants";
@@ -21,7 +21,7 @@ import {
outlinedMainWeaponImageUrl,
weaponBuildPage,
} from "~/utils/urls";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { makeTitle } from "~/utils/strings";
import { cache, ttl } from "~/utils/cache.server";
import { cachified } from "@epic-web/cachified";

View File

@@ -29,7 +29,7 @@ import {
ONE_HOUR_IN_MS,
PATCHES,
} from "~/constants";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { weaponIdIsNotAlt } from "~/modules/in-game-lists";
import { cache, ttl } from "~/utils/cache.server";
import { safeJSONParse } from "~/utils/json";

View File

@@ -12,7 +12,7 @@ import {
weaponCategoryUrl,
} from "~/utils/urls";
import { type SendouRouteHandle } from "~/utils/remix";
import styles from "~/styles/builds.css";
import styles from "~/styles/builds.css?url";
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { Main } from "~/components/Main";
import { makeTitle } from "~/utils/strings";

View File

@@ -0,0 +1,50 @@
export const tags = {
BADGE: {
color: "#000",
},
SPECIAL: {
color: "#CE93D8",
},
ART: {
color: "#C158F6",
},
MONEY: {
color: "#96F29D",
},
REGION: {
color: "#FF8C8C",
},
LOW: {
color: "#BBDEFB",
},
COUNT: {
color: "#62E8F5",
},
LAN: {
color: "#FFF",
},
QUALIFIER: {
color: "#FFC0CB",
},
SZ: {
color: "#F44336",
},
TW: {
color: "#D50000",
},
S1: {
color: "#E5E4E2",
},
S2: {
color: "#388E3C",
},
SR: {
color: "#FBCEB1",
},
CARDS: {
color: "#E4D00A",
},
FULL_TOURNAMENT: {
color: "#FFC0CB",
},
};

View File

@@ -0,0 +1,103 @@
import { z } from "zod";
import { CALENDAR_EVENT } from "~/constants";
import type { CalendarEventTag } from "~/db/types";
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
import {
FORMATS_SHORT,
TOURNAMENT,
} from "~/features/tournament/tournament-constants";
import {
actualNumber,
checkboxValueToBoolean,
date,
falsyToNull,
id,
processMany,
removeDuplicates,
safeJSONParse,
toArray,
} from "~/utils/zod";
import { calendarEventMaxDate, calendarEventMinDate } from "./calendar-utils";
export const newCalendarEventActionSchema = z
.object({
eventToEditId: z.preprocess(actualNumber, id.nullish()),
name: z
.string()
.min(CALENDAR_EVENT.NAME_MIN_LENGTH)
.max(CALENDAR_EVENT.NAME_MAX_LENGTH),
description: z.preprocess(
falsyToNull,
z.string().max(CALENDAR_EVENT.DESCRIPTION_MAX_LENGTH).nullable(),
),
date: z.preprocess(
toArray,
z
.array(
z.preprocess(
date,
z.date().min(calendarEventMinDate()).max(calendarEventMaxDate()),
),
)
.min(1)
.max(CALENDAR_EVENT.MAX_AMOUNT_OF_DATES),
),
bracketUrl: z
.string()
.url()
.max(CALENDAR_EVENT.BRACKET_URL_MAX_LENGTH)
.default("https://sendou.ink"),
discordInviteCode: z.preprocess(
falsyToNull,
z.string().max(CALENDAR_EVENT.DISCORD_INVITE_CODE_MAX_LENGTH).nullable(),
),
tags: z.preprocess(
processMany(safeJSONParse, removeDuplicates),
z
.array(
z
.string()
.refine((val) =>
CALENDAR_EVENT.TAGS.includes(val as CalendarEventTag),
),
)
.nullable(),
),
badges: z.preprocess(
processMany(safeJSONParse, removeDuplicates),
z.array(id).nullable(),
),
pool: z.string().optional(),
toToolsEnabled: z.preprocess(checkboxValueToBoolean, z.boolean()),
toToolsMode: z.enum(["ALL", "SZ", "TC", "RM", "CB"]).optional(),
//
// tournament format related fields
//
format: z.enum(FORMATS_SHORT).nullish(),
withUndergroundBracket: z.preprocess(checkboxValueToBoolean, z.boolean()),
teamsPerGroup: z.coerce
.number()
.min(TOURNAMENT.MIN_GROUP_SIZE)
.max(TOURNAMENT.MAX_GROUP_SIZE)
.nullish(),
advancingCount: z.coerce
.number()
.min(1)
.max(TOURNAMENT.MAX_GROUP_SIZE)
.nullish(),
})
.refine(
async (schema) => {
if (schema.eventToEditId) {
const eventToEdit = await CalendarRepository.findById({
id: schema.eventToEditId,
});
return schema.date.length === 1 || !eventToEdit?.tournamentId;
} else {
return schema.date.length === 1 || !schema.toToolsEnabled;
}
},
{
message: "Tournament must have exactly one date",
},
);

View File

@@ -1,9 +1,9 @@
import type { z } from "zod";
import { isAdmin } from "~/permissions";
import type { newCalendarEventActionSchema } from "./routes/calendar.new";
import type { TournamentSettings } from "~/db/tables";
import { BRACKET_NAMES } from "../tournament/tournament-constants";
import { nullFilledArray } from "~/utils/arrays";
import type { newCalendarEventActionSchema } from "./calendar-schemas.server";
const usersWithTournamentPerms =
process.env["TOURNAMENT_PERMS"]?.split(",").map(Number) ?? [];

View File

@@ -12,3 +12,10 @@ export function bracketProgressionToShortTournamentFormat(
return "RR_TO_SE";
}
export const calendarEventMinDate = () => new Date(Date.UTC(2015, 4, 28));
export const calendarEventMaxDate = () => {
const result = new Date();
result.setFullYear(result.getFullYear() + 1);
return result;
};

View File

@@ -5,8 +5,8 @@ import { Badge } from "~/components/Badge";
import { Button } from "~/components/Button";
import { CrossIcon } from "~/components/icons/Cross";
import type { CalendarEventTag } from "~/db/types";
import allTags from "../tags.json";
import type * as CalendarRepository from "../CalendarRepository.server";
import { tags as allTags } from "../calendar-constants";
export function Tags({
tags,

View File

@@ -21,17 +21,17 @@ import { Placement } from "~/components/Placement";
import { Section } from "~/components/Section";
import { useIsMounted } from "~/hooks/useIsMounted";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { requireUserId } from "~/features/auth/core/user.server";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { MapPool } from "~/features/map-list-generator/core/map-pool";
import {
canDeleteCalendarEvent,
canEditCalendarEvent,
canReportCalendarEventWinners,
} from "~/permissions";
import calendarStyles from "~/styles/calendar-event.css";
import mapsStyles from "~/styles/maps.css";
import calendarStyles from "~/styles/calendar-event.css?url";
import mapsStyles from "~/styles/maps.css?url";
import { databaseTimestampToDate } from "~/utils/dates";
import {
notFoundIfFalsy,

View File

@@ -1,23 +1,22 @@
import { json, redirect } from "@remix-run/node";
import type {
SerializeFrom,
ActionFunction,
LinksFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
import * as React from "react";
import { z } from "zod";
import { useTranslation } from "react-i18next";
import type { AlertVariation } from "~/components/Alert";
import { Alert } from "~/components/Alert";
import { Badge } from "~/components/Badge";
import { Button } from "~/components/Button";
import { DateInput } from "~/components/DateInput";
import { Divider } from "~/components/Divider";
import { FormMessage } from "~/components/FormMessage";
import { CrossIcon } from "~/components/icons/Cross";
import { TrashIcon } from "~/components/icons/Trash";
import { Input } from "~/components/Input";
import { Label } from "~/components/Label";
import { Main } from "~/components/Main";
@@ -25,16 +24,29 @@ import { MapPoolSelector } from "~/components/MapPoolSelector";
import { RequiredHiddenInput } from "~/components/RequiredHiddenInput";
import { SubmitButton } from "~/components/SubmitButton";
import { Toggle } from "~/components/Toggle";
import { CrossIcon } from "~/components/icons/Cross";
import { TrashIcon } from "~/components/icons/Trash";
import { CALENDAR_EVENT } from "~/constants";
import type { Tables } from "~/db/tables";
import type { Badge as BadgeType, CalendarEventTag } from "~/db/types";
import { useIsMounted } from "~/hooks/useIsMounted";
import { useTranslation } from "react-i18next";
import { requireUser } from "~/features/auth/core/user.server";
import { i18next } from "~/modules/i18n";
import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
import { MapPool } from "~/features/map-list-generator/core/map-pool";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
import {
BRACKET_NAMES,
TOURNAMENT,
type TournamentFormatShort,
} from "~/features/tournament/tournament-constants";
import { useIsMounted } from "~/hooks/useIsMounted";
import { i18next } from "~/modules/i18n/i18next.server";
import type { RankedModeShort } from "~/modules/in-game-lists";
import { rankedModesShort } from "~/modules/in-game-lists/modes";
import { canEditCalendarEvent } from "~/permissions";
import calendarNewStyles from "~/styles/calendar-new.css";
import mapsStyles from "~/styles/maps.css";
import calendarNewStyles from "~/styles/calendar-new.css?url";
import mapsStyles from "~/styles/maps.css?url";
import { isDefined } from "~/utils/arrays";
import {
databaseTimestampToDate,
@@ -50,45 +62,18 @@ import {
} from "~/utils/remix";
import { makeTitle, pathnameFromPotentialURL } from "~/utils/strings";
import { calendarEventPage, tournamentBracketsPage } from "~/utils/urls";
import {
actualNumber,
checkboxValueToBoolean,
date,
falsyToNull,
id,
processMany,
removeDuplicates,
safeJSONParse,
toArray,
} from "~/utils/zod";
import { Tags } from "../components/Tags";
import type { RankedModeShort } from "~/modules/in-game-lists";
import { rankedModesShort } from "~/modules/in-game-lists/modes";
import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
import { newCalendarEventActionSchema } from "../calendar-schemas.server";
import {
bracketProgressionToShortTournamentFormat,
calendarEventMaxDate,
calendarEventMinDate,
canAddNewEvent,
} from "../calendar-utils";
import {
canCreateTournament,
formValuesToBracketProgression,
} from "../calendar-utils.server";
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
import type { Tables } from "~/db/tables";
import { Divider } from "~/components/Divider";
import {
BRACKET_NAMES,
FORMATS_SHORT,
TOURNAMENT,
type TournamentFormatShort,
} from "~/features/tournament/tournament-constants";
const MIN_DATE = new Date(Date.UTC(2015, 4, 28));
const MAX_DATE = new Date();
MAX_DATE.setFullYear(MAX_DATE.getFullYear() + 1);
import { Tags } from "../components/Tags";
export const links: LinksFunction = () => {
return [
@@ -105,84 +90,6 @@ export const meta: MetaFunction = (args) => {
return [{ title: data.title }];
};
export const newCalendarEventActionSchema = z
.object({
eventToEditId: z.preprocess(actualNumber, id.nullish()),
name: z
.string()
.min(CALENDAR_EVENT.NAME_MIN_LENGTH)
.max(CALENDAR_EVENT.NAME_MAX_LENGTH),
description: z.preprocess(
falsyToNull,
z.string().max(CALENDAR_EVENT.DESCRIPTION_MAX_LENGTH).nullable(),
),
date: z.preprocess(
toArray,
z
.array(z.preprocess(date, z.date().min(MIN_DATE).max(MAX_DATE)))
.min(1)
.max(CALENDAR_EVENT.MAX_AMOUNT_OF_DATES),
),
bracketUrl: z
.string()
.url()
.max(CALENDAR_EVENT.BRACKET_URL_MAX_LENGTH)
.default("https://sendou.ink"),
discordInviteCode: z.preprocess(
falsyToNull,
z.string().max(CALENDAR_EVENT.DISCORD_INVITE_CODE_MAX_LENGTH).nullable(),
),
tags: z.preprocess(
processMany(safeJSONParse, removeDuplicates),
z
.array(
z
.string()
.refine((val) =>
CALENDAR_EVENT.TAGS.includes(val as CalendarEventTag),
),
)
.nullable(),
),
badges: z.preprocess(
processMany(safeJSONParse, removeDuplicates),
z.array(id).nullable(),
),
pool: z.string().optional(),
toToolsEnabled: z.preprocess(checkboxValueToBoolean, z.boolean()),
toToolsMode: z.enum(["ALL", "SZ", "TC", "RM", "CB"]).optional(),
//
// tournament format related fields
//
format: z.enum(FORMATS_SHORT).nullish(),
withUndergroundBracket: z.preprocess(checkboxValueToBoolean, z.boolean()),
teamsPerGroup: z.coerce
.number()
.min(TOURNAMENT.MIN_GROUP_SIZE)
.max(TOURNAMENT.MAX_GROUP_SIZE)
.nullish(),
advancingCount: z.coerce
.number()
.min(1)
.max(TOURNAMENT.MAX_GROUP_SIZE)
.nullish(),
})
.refine(
async (schema) => {
if (schema.eventToEditId) {
const eventToEdit = await CalendarRepository.findById({
id: schema.eventToEditId,
});
return schema.date.length === 1 || !eventToEdit?.tournamentId;
} else {
return schema.date.length === 1 || !schema.toToolsEnabled;
}
},
{
message: "Tournament must have exactly one date",
},
);
export const action: ActionFunction = async ({ request }) => {
const user = await requireUser(request);
const data = await parseRequestFormData({
@@ -501,8 +408,8 @@ function DatesInput({ allowMultiDate }: { allowMultiDate?: boolean }) {
id={`date-input-${key}`}
name="date"
defaultValue={date ?? undefined}
min={MIN_DATE}
max={MAX_DATE}
min={calendarEventMinDate()}
max={calendarEventMaxDate()}
required
onChange={(newDate: Date | null) => {
setDatesInputState((current) =>

View File

@@ -16,10 +16,10 @@ import { LinkButton } from "~/components/Button";
import { Main } from "~/components/Main";
import { useIsMounted } from "~/hooks/useIsMounted";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { getUserId } from "~/features/auth/core/user.server";
import { i18next } from "~/modules/i18n";
import styles from "~/styles/calendar.css";
import { i18next } from "~/modules/i18n/i18next.server";
import styles from "~/styles/calendar.css?url";
import { joinListToNaturalString } from "~/utils/arrays";
import {
databaseTimestampToDate,

View File

@@ -1,50 +0,0 @@
{
"BADGE": {
"color": "#000"
},
"SPECIAL": {
"color": "#CE93D8"
},
"ART": {
"color": "#C158F6"
},
"MONEY": {
"color": "#96F29D"
},
"REGION": {
"color": "#FF8C8C"
},
"LOW": {
"color": "#BBDEFB"
},
"COUNT": {
"color": "#62E8F5"
},
"LAN": {
"color": "#FFF"
},
"QUALIFIER": {
"color": "#FFC0CB"
},
"SZ": {
"color": "#F44336"
},
"TW": {
"color": "#D50000"
},
"S1": {
"color": "#E5E4E2"
},
"S2": {
"color": "#388E3C"
},
"SR": {
"color": "#FBCEB1"
},
"CARDS": {
"color": "#E4D00A"
},
"FULL_TOURNAMENT": {
"color": "#FFC0CB"
}
}

View File

@@ -2,7 +2,7 @@ import { Avatar } from "../../../components/Avatar";
import * as React from "react";
import { SubmitButton } from "../../../components/SubmitButton";
import type { User } from "~/db/types";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { nanoid } from "nanoid";
import clsx from "clsx";
import { Button } from "../../../components/Button";

View File

@@ -12,13 +12,11 @@ import {
} from "~/utils/urls";
import { useTranslation } from "react-i18next";
import type { LinksFunction } from "@remix-run/node";
import styles from "~/styles/front.css";
import styles from "~/styles/front.css?url";
import { Link } from "@remix-run/react";
import { GlobeIcon } from "~/components/icons/Globe";
import { LanguageChanger } from "~/components/layout/LanguageChanger";
import { Avatar } from "~/components/Avatar";
import { useUser } from "~/features/auth/core";
import { languages } from "~/modules/i18n";
import { Button } from "~/components/Button";
import { LogOutIcon } from "~/components/icons/LogOut";
import { LogInButtonContainer } from "~/components/layout/LogInButtonContainer";
@@ -28,6 +26,8 @@ import { ThemeChanger } from "~/components/layout/ThemeChanger";
import { SelectedThemeIcon } from "~/components/layout/SelectedThemeIcon";
import { useRootLoaderData } from "~/hooks/useRootLoaderData";
import { useTheme } from "~/features/theme/core/provider";
import { useUser } from "~/features/auth/core/user";
import { languages } from "~/modules/i18n/config";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];

View File

@@ -17,7 +17,7 @@ import Compressor from "compressorjs";
import invariant from "tiny-invariant";
import { Button } from "~/components/Button";
import { useTranslation } from "react-i18next";
import { requireUser } from "~/features/auth/core";
import { requireUser } from "~/features/auth/core/user.server";
import { dateToDatabaseTimestamp } from "~/utils/dates";
import { validate } from "~/utils/remix";
import { teamPage } from "~/utils/urls";

View File

@@ -2,7 +2,6 @@ import type { MetaFunction } from "@remix-run/node";
import { Trans } from "react-i18next";
import { Main } from "~/components/Main";
import { useSetTitle } from "~/hooks/useSetTitle";
import { languages } from "~/modules/i18n";
import { makeTitle } from "~/utils/strings";
import {
ANTARISKA_TWITTER,
@@ -18,6 +17,7 @@ import {
import { type SendouRouteHandle } from "~/utils/remix";
import { useTranslation } from "react-i18next";
import * as React from "react";
import { languages } from "~/modules/i18n/config";
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Contributions") }];

View File

@@ -2,7 +2,7 @@ import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { useTranslation } from "react-i18next";
import { Main } from "~/components/Main";
import { useSetTitle } from "~/hooks/useSetTitle";
import styles from "~/styles/faq.css";
import styles from "~/styles/faq.css?url";
import { makeTitle } from "~/utils/strings";
import { type SendouRouteHandle } from "~/utils/remix";

View File

@@ -1,6 +1,6 @@
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { Main } from "~/components/Main";
import styles from "../support.css";
import styles from "../support.css?url";
import * as React from "react";
import { CheckmarkIcon } from "~/components/icons/Checkmark";
import { useTranslation } from "react-i18next";

View File

@@ -6,7 +6,7 @@ import {
DEFAULT_LEADERBOARD_MAX_SIZE,
MATCHES_COUNT_NEEDED_FOR_LEADERBOARD,
} from "./leaderboards-constants";
import { ordinalToSp } from "../mmr";
import { ordinalToSp } from "../mmr/mmr-utils";
function addPowers<T extends { ordinal: number }>(entries: T[]) {
return entries.map((entry) => ({

View File

@@ -1,7 +1,7 @@
import { sql } from "~/db/sql";
import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "../leaderboards-constants";
import type { PlusTier, User } from "~/db/types";
import { ordinalToSp } from "~/features/mmr";
import { ordinalToSp } from "~/features/mmr/mmr-utils";
const stm = sql.prepare(/* sql */ `
select

View File

@@ -12,16 +12,15 @@ import { Avatar } from "~/components/Avatar";
import { TierImage, WeaponImage } from "~/components/Image";
import { Main } from "~/components/Main";
import { HALF_HOUR_IN_MS } from "~/constants";
import { getUser } from "~/features/auth/core";
import { getUser } from "~/features/auth/core/user.server";
import * as LeaderboardRepository from "~/features/leaderboards/LeaderboardRepository.server";
import { ordinalToSp } from "~/features/mmr";
import {
allSeasons,
currentOrPreviousSeason,
currentSeason,
} from "~/features/mmr/season";
import type { SkillTierInterval } from "~/features/mmr/tiered.server";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import {
weaponCategories,
type MainWeaponId,
@@ -40,7 +39,7 @@ import {
userSeasonsPage,
userSubmittedImage,
} from "~/utils/urls";
import styles from "../../top-search/top-search.css";
import styles from "../../top-search/top-search.css?url";
import { TopTenPlayer } from "../components/TopTenPlayer";
import {
cachedFullUserLeaderboard,
@@ -59,6 +58,7 @@ import {
weaponXPLeaderboard,
type XPLeaderboardItem,
} from "../queries/XPLeaderboard.server";
import { ordinalToSp } from "~/features/mmr/mmr-utils";
export const handle: SendouRouteHandle = {
i18n: ["vods"],

View File

@@ -18,9 +18,9 @@ import { Toggle } from "~/components/Toggle";
import type { CalendarEvent } from "~/db/types";
import { useTranslation } from "react-i18next";
import { getUserId } from "~/features/auth/core/user.server";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { stageIds, type ModeWithStage } from "~/modules/in-game-lists";
import styles from "~/styles/maps.css";
import styles from "~/styles/maps.css?url";
import { type SendouRouteHandle } from "~/utils/remix";
import { makeTitle } from "~/utils/strings";
import {

View File

@@ -4,7 +4,6 @@ import randomInt from "just-random-integer";
import * as React from "react";
import { usePlannerBg } from "~/hooks/usePlannerBg";
import { useTranslation } from "react-i18next";
import type { LanguageCode } from "~/modules/i18n";
import type { ModeShort, StageId } from "~/modules/in-game-lists";
import {
specialWeaponIds,
@@ -27,6 +26,7 @@ import { Button } from "../../../components/Button";
import { Image } from "../../../components/Image";
import type { StageBackgroundStyle } from "../plans-types";
import clsx from "clsx";
import type { LanguageCode } from "~/modules/i18n/config";
export default function Planner() {
const { t } = useTranslation(["common"]);

View File

@@ -1,6 +1,6 @@
import { lazy } from "react";
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import styles from "../plans.css";
import styles from "../plans.css?url";
import type { SendouRouteHandle } from "~/utils/remix";
import { useIsMounted } from "~/hooks/useIsMounted";
import { navIconUrl, PLANNER_URL } from "~/utils/urls";

View File

@@ -1,8 +0,0 @@
export {
queryCurrentUserRating,
queryCurrentTeamRating,
} from "./mmr-utils.server";
export { rate, userIdsToIdentifier, ordinalToSp } from "./mmr-utils";
export { currentSeason } from "./season";

View File

@@ -9,12 +9,12 @@ import {
specialFieldHp,
subStats,
hpDivided,
weaponParams,
type AbilityPoints,
type SpecialWeaponParams,
type SubWeaponParams,
} from "~/features/build-analyzer";
import type { HitPoints } from "../calculator-types";
import { weaponParams } from "~/features/build-analyzer/core/weapon-params";
const WAVE_BREAKER_HP = 400;
const SPRINKLER_HP = 120;

View File

@@ -35,7 +35,7 @@ import {
} from "~/utils/urls";
import { useObjectDamage } from "../calculator-hooks";
import type { DamageReceiver } from "../calculator-types";
import styles from "../calculator.css";
import styles from "../calculator.css?url";
export const CURRENT_PATCH = "6.1";

View File

@@ -10,7 +10,7 @@ import {
nextNonCompletedVoting,
rangeToMonthYear,
} from "~/features/plus-voting/core";
import { requireUser, useUser } from "~/features/auth/core";
import { requireUser } from "~/features/auth/core/user.server";
import {
canAddCommentToSuggestionBE,
canAddCommentToSuggestionFE,
@@ -22,6 +22,7 @@ import { actualNumber, trimmedString } from "~/utils/zod";
import type { PlusSuggestionsLoaderData } from "./plus.suggestions";
import { CommentTextarea } from "./plus.suggestions.new";
import * as PlusSuggestionRepository from "~/features/plus-suggestions/PlusSuggestionRepository.server";
import { useUser } from "~/features/auth/core/user";
const commentActionSchema = z.object({
comment: z.preprocess(

View File

@@ -32,11 +32,12 @@ import {
import type { UserWithPlusTier } from "~/db/types";
import { FormMessage } from "~/components/FormMessage";
import { atOrError } from "~/utils/arrays";
import { requireUser, useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { SubmitButton } from "~/components/SubmitButton";
import { UserSearch } from "~/components/UserSearch";
import * as PlusSuggestionRepository from "~/features/plus-suggestions/PlusSuggestionRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { requireUser } from "~/features/auth/core/user.server";
const commentActionSchema = z.object({
tier: z.preprocess(

View File

@@ -22,7 +22,7 @@ import {
} from "~/features/plus-voting/core";
import type { PlusSuggestion, User } from "~/db/types";
import * as PlusSuggestionRepository from "~/features/plus-suggestions/PlusSuggestionRepository.server";
import { requireUser, useUser } from "~/features/auth/core";
import { requireUser } from "~/features/auth/core/user.server";
import {
canAddCommentToSuggestionFE,
canDeleteComment,
@@ -35,6 +35,7 @@ import { makeTitle } from "~/utils/strings";
import { assertUnreachable } from "~/utils/types";
import { userPage } from "~/utils/urls";
import { _action, actualNumber } from "~/utils/zod";
import { useUser } from "~/features/auth/core/user";
export const meta: MetaFunction = () => {
return [

View File

@@ -2,7 +2,7 @@ import type { LinksFunction } from "@remix-run/node";
import { Outlet } from "@remix-run/react";
import { Main } from "~/components/Main";
import { SubNav, SubNavLink } from "~/components/SubNav";
import styles from "~/styles/plus.css";
import styles from "~/styles/plus.css?url";
import { type SendouRouteHandle } from "~/utils/remix";
import { navIconUrl, plusSuggestionPage } from "~/utils/urls";

View File

@@ -9,9 +9,9 @@ import clsx from "clsx";
import invariant from "tiny-invariant";
import type { UserWithPlusTier } from "~/db/types";
import * as PlusVotingRepository from "~/features/plus-voting/PlusVotingRepository.server";
import { getUser } from "~/features/auth/core";
import { getUser } from "~/features/auth/core/user.server";
import { lastCompletedVoting } from "~/features/plus-voting/core";
import styles from "~/styles/plus-history.css";
import styles from "~/styles/plus-history.css?url";
import { roundToNDecimalPlaces } from "~/utils/number";
import { makeTitle } from "~/utils/strings";
import { PLUS_SERVER_DISCORD_URL, userPage } from "~/utils/urls";

View File

@@ -13,7 +13,7 @@ import { Button } from "~/components/Button";
import { CheckmarkIcon } from "~/components/icons/Checkmark";
import { RelativeTime } from "~/components/RelativeTime";
import { PLUS_DOWNVOTE, PLUS_UPVOTE } from "~/constants";
import { getUser, requireUser } from "~/features/auth/core";
import { getUser, requireUser } from "~/features/auth/core/user.server";
import type { PlusVoteFromFE } from "~/features/plus-voting/core";
import {
rangeToMonthYear,

View File

@@ -48,7 +48,7 @@ import {
SENDOUQ_WEAPON_POOL_MAX_SIZE,
} from "../q-settings-constants";
import { settingsActionSchema } from "../q-settings-schemas.server";
import styles from "../q-settings.css";
import styles from "../q-settings.css?url";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];

View File

@@ -5,7 +5,7 @@ import { twitchThumbnailUrlToSrc } from "~/modules/twitch/utils";
import { FAQ_PAGE, sendouQMatchPage, twitchUrl, userPage } from "~/utils/urls";
import { cachedStreams } from "../core/streams.server";
import { Avatar } from "~/components/Avatar";
import styles from "~/features/sendouq/q.css";
import styles from "~/features/sendouq/q.css?url";
import type { LinksFunction } from "@remix-run/node";
import { useTranslation } from "react-i18next";
import { useIsMounted } from "~/hooks/useIsMounted";

View File

@@ -18,7 +18,7 @@ import { StarIcon } from "~/components/icons/Star";
import { StarFilledIcon } from "~/components/icons/StarFilled";
import { TrashIcon } from "~/components/icons/Trash";
import type { GroupMember as GroupMemberType, ParsedMemento } from "~/db/types";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "~/features/leaderboards/leaderboards-constants";
import { ordinalToRoundedSp } from "~/features/mmr/mmr-utils";
import type { TieredSkill } from "~/features/mmr/tiered.server";

View File

@@ -12,12 +12,14 @@ import type {
import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "~/features/leaderboards/leaderboards-constants";
import {
ordinalToSp,
queryCurrentTeamRating,
queryCurrentUserRating,
rate,
userIdsToIdentifier,
} from "~/features/mmr";
import { queryTeamPlayerRatingAverage } from "~/features/mmr/mmr-utils.server";
} from "~/features/mmr/mmr-utils";
import {
queryCurrentTeamRating,
queryCurrentUserRating,
queryTeamPlayerRatingAverage,
} from "~/features/mmr/mmr-utils.server";
import { currentOrPreviousSeason } from "~/features/mmr/season";
import { roundToNDecimalPlaces } from "~/utils/number";

View File

@@ -17,7 +17,7 @@ import { Image } from "~/components/Image";
import { Main } from "~/components/Main";
import { NewTabs } from "~/components/NewTabs";
import { SubmitButton } from "~/components/SubmitButton";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { getUser, requireUser } from "~/features/auth/core/user.server";
import * as NotificationService from "~/features/chat/NotificationService.server";
import { Chat, useChat } from "~/features/chat/components/Chat";
@@ -63,7 +63,7 @@ import { FULL_GROUP_SIZE } from "../q-constants";
import { lookingSchema } from "../q-schemas.server";
import type { LookingGroupWithInviteCode } from "../q-types";
import { groupRedirectLocationByCurrentLocation } from "../q-utils";
import styles from "../q.css";
import styles from "../q.css?url";
import { addLike } from "../queries/addLike.server";
import { addManagerRole } from "../queries/addManagerRole.server";
import { chatCodeByGroupId } from "../queries/chatCodeByGroupId.server";

View File

@@ -35,11 +35,10 @@ import type { GroupMember, ReportedWeapon } from "~/db/types";
import * as NotificationService from "~/features/chat/NotificationService.server";
import type { ChatMessage } from "~/features/chat/chat-types";
import { type ChatProps, Chat, useChat } from "~/features/chat/components/Chat";
import { currentSeason } from "~/features/mmr";
import { resolveRoomPass } from "~/features/tournament-bracket/tournament-bracket-utils";
import { useIsMounted } from "~/hooks/useIsMounted";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { getUserId, requireUser } from "~/features/auth/core/user.server";
import type { MainWeaponId } from "~/modules/in-game-lists";
import { isMod } from "~/permissions";
@@ -79,7 +78,7 @@ import {
import { FULL_GROUP_SIZE, USER_SKILLS_CACHE_KEY } from "../q-constants";
import { matchSchema } from "../q-schemas.server";
import { matchIdFromParams, winnersArrayToWinner } from "../q-utils";
import styles from "../q.css";
import styles from "../q.css?url";
import { addDummySkill } from "../queries/addDummySkill.server";
import { addMapResults } from "../queries/addMapResults.server";
import { addPlayerResults } from "../queries/addPlayerResults.server";
@@ -106,6 +105,7 @@ import cachified from "@epic-web/cachified";
import { refreshStreamsCache } from "~/features/sendouq-streams/core/streams.server";
import { CrossIcon } from "~/components/icons/Cross";
import { SPLATTERCOLOR_SCREEN_ID } from "~/modules/in-game-lists/weapon-ids";
import { currentSeason } from "~/features/mmr/season";
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;

View File

@@ -11,7 +11,7 @@ import invariant from "tiny-invariant";
import { Main } from "~/components/Main";
import { SubmitButton } from "~/components/SubmitButton";
import { getUser, requireUser } from "~/features/auth/core/user.server";
import { currentSeason } from "~/features/mmr";
import { currentSeason } from "~/features/mmr/season";
import * as QMatchRepository from "~/features/sendouq-match/QMatchRepository.server";
import { useAutoRefresh } from "~/hooks/useAutoRefresh";
import type { SendouRouteHandle } from "~/utils/remix";
@@ -30,7 +30,7 @@ import { hasGroupManagerPerms } from "../core/groups";
import { FULL_GROUP_SIZE } from "../q-constants";
import { preparingSchema } from "../q-schemas.server";
import { groupRedirectLocationByCurrentLocation } from "../q-utils";
import styles from "../q.css";
import styles from "../q.css?url";
import { addMember } from "../queries/addMember.server";
import { findCurrentGroupByUserId } from "../queries/findCurrentGroupByUserId.server";
import { findPreparingGroup } from "../queries/findPreparingGroup.server";

View File

@@ -24,9 +24,9 @@ import { UserIcon } from "~/components/icons/User";
import { UsersIcon } from "~/components/icons/Users";
import { sql } from "~/db/sql";
import type { GroupMember } from "~/db/types";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { getUserId, requireUserId } from "~/features/auth/core/user.server";
import { currentSeason } from "~/features/mmr";
import { currentSeason } from "~/features/mmr/season";
import type { RankingSeason } from "~/features/mmr/season";
import { nextSeason } from "~/features/mmr/season";
import * as QRepository from "~/features/sendouq/QRepository.server";
@@ -58,7 +58,7 @@ import {
import { FULL_GROUP_SIZE, JOIN_CODE_SEARCH_PARAM_KEY } from "../q-constants";
import { frontPageSchema } from "../q-schemas.server";
import { groupRedirectLocationByCurrentLocation } from "../q-utils";
import styles from "../q.css";
import styles from "../q.css?url";
import { addMember } from "../queries/addMember.server";
import { deleteLikesByGroupId } from "../queries/deleteLikesByGroupId.server";
import { findCurrentGroupByUserId } from "../queries/findCurrentGroupByUserId.server";

View File

@@ -1,7 +1,6 @@
import { useLoaderData } from "@remix-run/react";
import { TierImage } from "~/components/Image";
import { Main } from "~/components/Main";
import { ordinalToSp } from "~/features/mmr";
import {
TEAM_LEADERBOARD_MIN_ENTRIES_FOR_LEVIATHAN,
TIERS,
@@ -11,6 +10,7 @@ import { currentOrPreviousSeason } from "~/features/mmr/season";
import { userSkills } from "~/features/mmr/tiered.server";
import { useTranslation } from "react-i18next";
import type { SendouRouteHandle } from "~/utils/remix";
import { ordinalToSp } from "~/features/mmr/mmr-utils";
export const handle: SendouRouteHandle = {
i18n: ["q"],

View File

@@ -39,7 +39,7 @@ import { findByIdentifier } from "../queries/findByIdentifier.server";
import { TEAM } from "../team-constants";
import { editTeamSchema, teamParamsSchema } from "../team-schemas.server";
import { canAddCustomizedColors, isTeamOwner } from "../team-utils";
import styles from "../team.css";
import styles from "../team.css?url";
import { Input } from "~/components/Input";
export const links: LinksFunction = () => {

View File

@@ -9,7 +9,7 @@ import { Main } from "~/components/Main";
import { SubmitButton } from "~/components/SubmitButton";
import { INVITE_CODE_LENGTH } from "~/constants";
import { useTranslation } from "react-i18next";
import { requireUser } from "~/features/auth/core";
import { requireUser } from "~/features/auth/core/user.server";
import {
notFoundIfFalsy,
validate,
@@ -24,7 +24,7 @@ import type { DetailedTeam } from "../team-types";
import { isTeamFull, isTeamMember } from "../team-utils";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import styles from "../team.css";
import styles from "../team.css?url";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];

View File

@@ -17,7 +17,7 @@ import { Main } from "~/components/Main";
import { SubmitButton } from "~/components/SubmitButton";
import { useBaseUrl } from "~/hooks/useBaseUrl";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { requireUserId } from "~/features/auth/core/user.server";
import type { SendouRouteHandle } from "~/utils/remix";
import { notFoundIfFalsy, parseRequestFormData, validate } from "~/utils/remix";
@@ -39,7 +39,7 @@ import { TEAM_MEMBER_ROLES } from "../team-constants";
import { manageRosterSchema, teamParamsSchema } from "../team-schemas.server";
import type { DetailedTeamMember } from "../team-types";
import { isTeamFull, isTeamOwner } from "../team-utils";
import styles from "../team.css";
import styles from "../team.css?url";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];

View File

@@ -19,7 +19,7 @@ import { WeaponImage } from "~/components/Image";
import { Main } from "~/components/Main";
import { Placement } from "~/components/Placement";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { requireUserId } from "~/features/auth/core/user.server";
import {
notFoundIfFalsy,
@@ -46,7 +46,7 @@ import {
isTeamMember,
isTeamOwner,
} from "../team-utils";
import styles from "../team.css";
import styles from "../team.css?url";
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [];

View File

@@ -21,9 +21,9 @@ import { Input } from "~/components/Input";
import { Main } from "~/components/Main";
import { SubmitButton } from "~/components/SubmitButton";
import { useTranslation } from "react-i18next";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { getUserId, requireUserId } from "~/features/auth/core/user.server";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { joinListToNaturalString } from "~/utils/arrays";
import type { SendouRouteHandle } from "~/utils/remix";
import { parseRequestFormData, validate } from "~/utils/remix";
@@ -39,7 +39,7 @@ import { allTeams } from "../queries/allTeams.server";
import { createNewTeam } from "../queries/createNewTeam.server";
import { TEAM, TEAMS_PER_PAGE } from "../team-constants";
import { createTeamSchema } from "../team-schemas.server";
import styles from "../team.css";
import styles from "../team.css?url";
import { usePagination } from "~/hooks/usePagination";
import { Pagination } from "~/components/Pagination";

View File

@@ -9,7 +9,7 @@ import { Main } from "~/components/Main";
import { type SendouRouteHandle, notFoundIfFalsy } from "~/utils/remix";
import { PlacementsTable } from "../components/Placements";
import { findPlacementsByPlayerId } from "../queries/findPlacements.server";
import styles from "../top-search.css";
import styles from "../top-search.css?url";
import { removeDuplicates } from "~/utils/arrays";
import {
navIconUrl,
@@ -17,7 +17,7 @@ import {
topSearchPlayerPage,
userPage,
} from "~/utils/urls";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { makeTitle } from "~/utils/strings";
import { useTranslation } from "react-i18next";

View File

@@ -7,7 +7,7 @@ import type {
import { useLoaderData, useSearchParams } from "@remix-run/react";
import { Main } from "~/components/Main";
import { findPlacementsOfMonth } from "../queries/findPlacements.server";
import styles from "../top-search.css";
import styles from "../top-search.css?url";
import { PlacementsTable } from "../components/Placements";
import { rankedModesShort } from "~/modules/in-game-lists/modes";
import type { XRankPlacement } from "~/db/types";
@@ -16,7 +16,7 @@ import { nanoid } from "nanoid";
import { useTranslation } from "react-i18next";
import invariant from "tiny-invariant";
import type { MonthYear } from "../top-search-utils";
import { i18next } from "~/modules/i18n";
import { i18next } from "~/modules/i18n/i18next.server";
import { makeTitle } from "~/utils/strings";
import { monthYears } from "../queries/monthYears";
import type { SendouRouteHandle } from "~/utils/remix";

View File

@@ -7,7 +7,7 @@ import {
import { Link, useFetcher } from "@remix-run/react";
import { tournamentMatchPage, tournamentStreamsPage } from "~/utils/urls";
import clsx from "clsx";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import type { Bracket } from "../../core/Bracket";
import { Popover } from "~/components/Popover";
import * as React from "react";

View File

@@ -3,7 +3,7 @@ import { InfoPopover } from "~/components/InfoPopover";
import { SubmitButton } from "~/components/SubmitButton";
import { LockIcon } from "~/components/icons/Lock";
import { UnlockIcon } from "~/components/icons/Unlock";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
const lockingInfo =

View File

@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
import { Image } from "~/components/Image";
import { NewTabs } from "~/components/NewTabs";
import { SubmitButton } from "~/components/SubmitButton";
import { useUser } from "~/features/auth/core";
import { useUser } from "~/features/auth/core/user";
import { Chat, useChat } from "~/features/chat/components/Chat";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useIsMounted } from "~/hooks/useIsMounted";

View File

@@ -9,7 +9,7 @@ import { removeDuplicates } from "~/utils/arrays";
import { BRACKET_NAMES } from "~/features/tournament/tournament-constants";
import { logger } from "~/utils/logger";
import type { Round } from "~/modules/brackets-model";
import { getTournamentManager } from "..";
import { getTournamentManager } from "./brackets-manager";
interface CreateBracketArgs {
id: number;
@@ -93,7 +93,7 @@ export abstract class Bracket {
return;
try {
const manager = getTournamentManager("IN_MEMORY");
const manager = getTournamentManager();
manager.import(this.data);

View File

@@ -1,10 +1,10 @@
import { Tournament } from "./Tournament";
import { getTournamentManager } from "..";
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
import { notFoundIfFalsy } from "~/utils/remix";
import type { Unwrapped } from "~/utils/types";
import { getServerTournamentManager } from "./brackets-manager/manager.server";
const manager = getTournamentManager("SQL");
const manager = getServerTournamentManager();
export type TournamentData = Unwrapped<typeof tournamentData>;
export type TournamentDataTeam = TournamentData["ctx"]["teams"][number];

Some files were not shown because too many files have changed in this diff Show More