Swap tournament-context location to fix HMR crash

This commit is contained in:
Kalle 2026-08-06 17:34:15 +03:00
parent 0c50b45cdb
commit 81cb406f1e
44 changed files with 94 additions and 82 deletions

View File

@ -6,7 +6,7 @@ import { Input } from "~/components/Input";
import { Label } from "~/components/Label";
import { Main } from "~/components/Main";
import type { Tables } from "~/db/tables";
import { TournamentOverrideProvider } from "~/features/tournament/routes/to.$id";
import { TournamentProvider } from "~/features/tournament/tournament-context";
import type { Bracket as BracketType } from "~/features/tournament-bracket/core/Bracket";
import * as Engine from "~/features/tournament-bracket/core/engine";
import type { BracketData } from "~/features/tournament-bracket/core/engine/types";
@ -181,7 +181,7 @@ export default function BracketTestLayout() {
</SendouSwitch>
</div>
</div>
<TournamentOverrideProvider
<TournamentProvider
tournament={mockTournament as unknown as TournamentClass}
>
<Outlet
@ -194,7 +194,7 @@ export default function BracketTestLayout() {
bracket: mockBracket,
}}
/>
</TournamentOverrideProvider>
</TournamentProvider>
</Main>
);
}

View File

@ -5,7 +5,7 @@ import {
SendouChipRadioGroup,
} from "~/components/elements/ChipRadio";
import { SendouDialog } from "~/components/elements/Dialog";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import type { TournamentTeamFull } from "~/features/tournament-bracket/core/Tournament.server";
import * as CSV from "~/modules/csv";
import { databaseTimestampToDate } from "~/utils/dates";

View File

@ -26,7 +26,7 @@ import {
type SortState,
} from "~/components/SortableTableHeader";
import { Table } from "~/components/Table";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import type {
BracketMeta,
Tournament,

View File

@ -5,11 +5,11 @@ import { LocaleTime } from "~/components/LocaleTime";
import { Pagination } from "~/components/Pagination";
import { Table } from "~/components/Table";
import { UserLink } from "~/components/UserLink";
import { useTournament } from "~/features/tournament/routes/to.$id";
import {
TOURNAMENT_AUDIT_LOG_TYPES,
type TournamentAuditLogType,
} from "~/features/tournament/tournament-constants";
import { useTournament } from "~/features/tournament/tournament-context";
import { useSearchParamPagination } from "~/hooks/useSearchParamPagination";
import { useSearchParamsTyped } from "~/modules/search-params/hooks";
import type { CommonUser } from "~/utils/kysely.server";

View File

@ -8,7 +8,7 @@ import { Redirect } from "~/components/Redirect";
import { SubmitButton } from "~/components/SubmitButton";
import { DANGEROUS_CAN_ACCESS_DEV_CONTROLS } from "~/features/admin/core/dev-controls";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import * as Progression from "~/features/tournament-bracket/core/Progression";
import { SendouForm } from "~/form/SendouForm";
import { useActionSubmit } from "~/hooks/useActionSubmit";

View File

@ -28,7 +28,7 @@ vi.mock("react-router", async () => {
};
});
vi.mock("~/features/tournament/routes/to.$id", () => ({
vi.mock("~/features/tournament/tournament-context", () => ({
useTournament: () => mockTournament,
}));

View File

@ -19,7 +19,7 @@ vi.mock("react-router", async () => {
};
});
vi.mock("~/features/tournament/routes/to.$id", () => ({
vi.mock("~/features/tournament/tournament-context", () => ({
useTournament: () => mockTournament,
}));

View File

@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next";
import { useFetcher, useLoaderData } from "react-router";
import { LinkButton, SendouButton } from "~/components/elements/Button";
import { SendouDialog } from "~/components/elements/Dialog";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import type { TournamentTeamFull } from "~/features/tournament-bracket/core/Tournament.server";
import { FormField } from "~/form/FormField";
import { SendouForm, useFormFieldContext } from "~/form/SendouForm";

View File

@ -31,8 +31,8 @@ import { SendouDialog } from "~/components/elements/Dialog";
import { InfoPopover } from "~/components/InfoPopover";
import { Table } from "~/components/Table";
import type { SeedingSnapshot } from "~/db/tables-json";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { TOURNAMENT } from "~/features/tournament/tournament-constants";
import { useTournament } from "~/features/tournament/tournament-context";
import * as AbDivisions from "~/features/tournament-bracket/core/AbDivisions";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
import type { TournamentTeamFull } from "~/features/tournament-bracket/core/Tournament.server";

View File

@ -5,7 +5,7 @@ import { Avatar } from "~/components/Avatar";
import { Divider } from "~/components/Divider";
import { LinkButton, SendouButton } from "~/components/elements/Button";
import type { Tables } from "~/db/tables";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { TOURNAMENT_ORGANIZATION_ROLES } from "~/features/tournament-organization/tournament-organization-constants";
import { SendouForm } from "~/form/SendouForm";
import { tournamentOrganizationEditPage } from "~/utils/urls";

View File

@ -1,5 +1,5 @@
import { Redirect } from "~/components/Redirect";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { SendouForm } from "~/form/SendouForm";
import { tournamentAdminPage } from "~/utils/urls";
import { adminStreamFormSchema } from "../tournament-admin-staff-schemas";

View File

@ -22,7 +22,7 @@ import { containerClassName } from "~/components/Main";
import { Redirect } from "~/components/Redirect";
import { DANGEROUS_CAN_ACCESS_DEV_CONTROLS } from "~/features/admin/core/dev-controls";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { useHasRole } from "~/modules/permissions/hooks";
import {
calendarEventPage,

View File

@ -101,8 +101,11 @@ vi.mock("~/features/auth/core/user", () => ({
useUser: () => null,
}));
vi.mock("~/features/tournament/routes/to.$id", () => ({
vi.mock("~/features/tournament/tournament-context", () => ({
useTournament: () => mockTournament,
}));
vi.mock("~/features/tournament/routes/to.$id", () => ({
useTournamentVods: () => [],
useBracketExpanded: () => ({
bracketExpanded: true,

View File

@ -7,10 +7,8 @@ import { SendouButton } from "~/components/elements/Button";
import { SendouPopover } from "~/components/elements/Popover";
import { useUser } from "~/features/auth/core/user";
import { TournamentStream } from "~/features/tournament/components/TournamentStream";
import {
useTournament,
useTournamentVods,
} from "~/features/tournament/routes/to.$id";
import { useTournamentVods } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { matchEndedEarly } from "~/features/tournament-bracket/core/engine";
import { useAutoRerender } from "~/hooks/useAutoRerender";
import { databaseTimestampToDate } from "~/utils/dates";

View File

@ -2,7 +2,7 @@ import clsx from "clsx";
import { differenceInMinutes } from "date-fns";
import { LocaleTime } from "~/components/LocaleTime";
import type { TournamentRoundMaps } from "~/db/tables-json";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { resolveLeagueRoundStartDate } from "~/features/tournament/tournament-utils";
import { useAutoRerender } from "~/hooks/useAutoRerender";
import { databaseTimestampToDate } from "~/utils/dates";

View File

@ -2,10 +2,8 @@ import clsx from "clsx";
import { ActionButton } from "~/components/ActionButton";
import { SendouButton } from "~/components/elements/Button";
import { useUser } from "~/features/auth/core/user";
import {
useBracketExpanded,
useTournament,
} from "~/features/tournament/routes/to.$id";
import { useBracketExpanded } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import * as Engine from "~/features/tournament-bracket/core/engine";
import type { MatchData as MatchType } from "~/features/tournament-bracket/core/engine/types";
import { useSearchParam } from "~/modules/search-params/hooks";

View File

@ -1,6 +1,6 @@
import { differenceInDays } from "date-fns";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { TOURNAMENT } from "~/features/tournament/tournament-constants";
import { useTournament } from "~/features/tournament/tournament-context";
import { useSpoilerFree } from "~/hooks/useSpoilerFree";
export type SpoilerCensor = "full" | "score-only" | undefined;

View File

@ -24,11 +24,9 @@ import { Label } from "~/components/Label";
import { LocaleTime } from "~/components/LocaleTime";
import { SubmitButton } from "~/components/SubmitButton";
import type { CustomPickBanFlow, TournamentRoundMaps } from "~/db/tables-json";
import {
useTournament,
useTournamentPreparedMaps,
} from "~/features/tournament/routes/to.$id";
import { useTournamentPreparedMaps } from "~/features/tournament/routes/to.$id";
import { TOURNAMENT } from "~/features/tournament/tournament-constants";
import { useTournament } from "~/features/tournament/tournament-context";
import type { BracketData } from "~/features/tournament-bracket/core/engine/types";
import * as PickBan from "~/features/tournament-bracket/core/PickBan";
import { modesShort } from "~/modules/in-game-lists/modes";

View File

@ -8,7 +8,7 @@ import { SendouPopover } from "~/components/elements/Popover";
import { LocaleTimeRange } from "~/components/LocaleTimeRange";
import { useUser } from "~/features/auth/core/user";
import { soundEnabled, soundVolume } from "~/features/chat/chat-utils";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { checkInSchema } from "~/features/tournament/tournament-schemas";
import type { TournamentTeamMemberProgressStatus } from "~/features/tournament-bracket/core/Tournament";
import { bracketSchema } from "~/features/tournament-bracket/tournament-bracket-schemas";

View File

@ -9,7 +9,7 @@ import { SendouDialog } from "~/components/elements/Dialog";
import { SendouSwitch } from "~/components/elements/Switch";
import { FormMessage } from "~/components/FormMessage";
import { Placement } from "~/components/Placement";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import {
finalizeTournamentActionSchema,
type TournamentBadgeReceivers,

View File

@ -35,6 +35,10 @@ import { Placeholder } from "~/components/Placeholder";
import { useUser } from "~/features/auth/core/user";
import { useWebsocketRevalidation } from "~/features/chat/chat-hooks";
import { TOURNAMENT } from "~/features/tournament/tournament-constants";
import {
TournamentProvider,
useTournament,
} from "~/features/tournament/tournament-context";
import { useCopyToClipboard } from "~/hooks/useCopyToClipboard";
import { useHydrated } from "~/hooks/useHydrated";
import { useIsomorphicLayoutEffect } from "~/hooks/useIsomorphicLayoutEffect";
@ -42,9 +46,7 @@ import { useSearchParam } from "~/modules/search-params/hooks";
import type { SendouRouteHandle } from "~/utils/remix.server";
import { SENDOU_INK_BASE_URL, tournamentJoinPage } from "~/utils/urls";
import {
TournamentOverrideProvider,
useBracketExpanded,
useTournament,
useTournamentPreparedMaps,
} from "../../tournament/routes/to.$id";
import { action } from "../actions/to.$id.brackets.server";
@ -88,9 +90,9 @@ export default function TournamentBracketsPage() {
);
return (
<TournamentOverrideProvider tournament={tournament}>
<TournamentProvider tournament={tournament}>
<TournamentBracketsView />
</TournamentOverrideProvider>
</TournamentProvider>
);
}

View File

@ -13,7 +13,7 @@ import { Image, WeaponImage } from "~/components/Image";
import { NoteAvatar } from "~/components/NoteAvatar";
import { useUser } from "~/features/auth/core/user";
import { IS_Q_LOOKING_MOBILE_BREAKPOINT } from "~/features/sendouq/q-constants";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import {
UserCard,
useUserCardData,

View File

@ -21,7 +21,7 @@ import { NoteAvatar } from "~/components/NoteAvatar";
import { Placeholder } from "~/components/Placeholder";
import { useUser } from "~/features/auth/core/user";
import { IS_Q_LOOKING_MOBILE_BREAKPOINT } from "~/features/sendouq/q-constants";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import {
UserCard,
useUserCardData,

View File

@ -4,7 +4,7 @@ import * as React from "react";
import { useTranslation } from "react-i18next";
import { SendouButton } from "~/components/elements/Button";
import { SendouDialog } from "~/components/elements/Dialog";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { nullFilledArray } from "~/utils/arrays";
import type { TournamentMatchLoaderData } from "../loaders/to.$id.matches.$mid.server";
import { useMatch } from "../match-page-context";

View File

@ -3,7 +3,7 @@ import {
type PickBanMapOption,
} from "~/components/match-page/MatchActionPickBanTab";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import * as PickBan from "~/features/tournament-bracket/core/PickBan";
import { matchSchema } from "~/features/tournament-bracket/tournament-bracket-schemas";
import { useActionSubmit } from "~/hooks/useActionSubmit";

View File

@ -7,7 +7,7 @@ import { TAB_KEYS } from "~/components/match-page/MatchTabs";
import { useMatchWeaponReport } from "~/components/match-page/useMatchWeaponReport";
import { WeaponReporter } from "~/components/match-page/WeaponReporter";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import { isSetOverByScore } from "~/features/tournament-bracket/core/engine";
import { matchSchema } from "~/features/tournament-bracket/tournament-bracket-schemas";
import { tournamentTeamToActiveRosterUserIds } from "~/features/tournament-bracket/tournament-bracket-utils";

View File

@ -16,7 +16,7 @@ import { Label } from "~/components/Label";
import { TAB_KEYS } from "~/components/match-page/MatchTabs";
import { SubmitButton } from "~/components/SubmitButton";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import type { MatchStatus } from "~/features/tournament-bracket/core/engine";
import { matchSchema } from "~/features/tournament-bracket/tournament-bracket-schemas";
import { useActionSubmit } from "~/hooks/useActionSubmit";

View File

@ -24,7 +24,7 @@ import { MatchBannerStartedAt } from "~/components/match-page/MatchBannerStarted
import { MatchBannerTimer } from "~/components/match-page/MatchBannerTimer";
import { MatchBannerTopRow } from "~/components/match-page/MatchBannerTopRow";
import type { TournamentRoundMaps } from "~/db/tables-json";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import * as PickBan from "~/features/tournament-bracket/core/PickBan";
import { useDateTimeFormat } from "~/hooks/intl/useDateTimeFormat";
import { useAutoRerender } from "~/hooks/useAutoRerender";

View File

@ -1,7 +1,7 @@
import { ArrowLeft } from "lucide-react";
import { LinkButton } from "~/components/elements/Button";
import { MatchPageHeader } from "~/components/match-page/MatchPageHeader";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import type { BracketsPageState } from "~/features/tournament-bracket/routes/to.$id.brackets";
import { tournamentBracketsPage } from "~/utils/urls";
import type { TournamentMatchLoaderData } from "../loaders/to.$id.matches.$mid.server";

View File

@ -7,7 +7,7 @@ import type {
TimelinePickBanEvent,
} from "~/components/match-page/MatchTimeline";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import * as PickBan from "~/features/tournament-bracket/core/PickBan";
import { matchSchema } from "~/features/tournament-bracket/tournament-bracket-schemas";
import { tournamentTeamToActiveRosterUserIds } from "~/features/tournament-bracket/tournament-bracket-utils";

View File

@ -2,7 +2,7 @@ import * as React from "react";
import { TAB_KEYS } from "~/components/match-page/MatchTabs";
import { resolveRoomPass } from "~/components/match-page/utils";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import * as PickBan from "~/features/tournament-bracket/core/PickBan";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
import {

View File

@ -2,7 +2,7 @@ import { useLoaderData } from "react-router";
import { containerClassName } from "~/components/Main";
import { MatchPage } from "~/components/match-page/MatchPage";
import { useWebsocketRevalidation } from "~/features/chat/chat-hooks";
import { useTournament } from "~/features/tournament/routes/to.$id";
import { useTournament } from "~/features/tournament/tournament-context";
import type { SendouRouteHandle } from "~/utils/remix.server";
import { action } from "../actions/to.$id.matches.$mid.server";
import { TournamentMatchBanner } from "../components/TournamentMatchBanner";

View File

@ -4,10 +4,11 @@ import { Avatar } from "~/components/Avatar";
import { ModeImage, StageImage } from "~/components/Image";
import type { Tables } from "~/db/tables";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/tournament-context";
import type { TournamentTeamFull } from "~/features/tournament-bracket/core/Tournament.server";
import { userPage } from "~/utils/urls";
import { accountCreatedInTheLastSixMonths } from "~/utils/users";
import { useTournament, useTournamentFriendCodes } from "../routes/to.$id";
import { useTournamentFriendCodes } from "../routes/to.$id";
import styles from "../tournament.module.css";
export function TeamWithRoster({

View File

@ -1,10 +1,10 @@
import clsx from "clsx";
import { User } from "lucide-react";
import { Avatar } from "~/components/Avatar";
import { useTournament } from "~/features/tournament/tournament-context";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
import { twitchThumbnailUrlToSrc } from "~/modules/twitch/utils";
import { twitchUrl } from "~/utils/urls";
import { useTournament } from "../routes/to.$id";
import styles from "../tournament.module.css";
export function TournamentStream({

View File

@ -7,6 +7,7 @@ import { containerClassName } from "~/components/Main";
import { Markdown } from "~/components/Markdown";
import { TierPill } from "~/components/TierPill";
import * as Seasons from "~/features/mmr/core/Seasons";
import { useTournament } from "~/features/tournament/tournament-context";
import { metaTags } from "~/utils/remix";
import type { SendouRouteHandle } from "~/utils/remix.server";
import { removeMarkdown } from "~/utils/strings";
@ -21,7 +22,6 @@ import {
import { parseTournamentLoaderData } from "../core/layout-payload";
import { loader } from "../loaders/to.$id.info.server";
import { bracketProgressionLabel } from "../tournament-utils";
import { useTournament } from "./to.$id";
import styles from "./to.$id.info.module.css";
export { action, loader };

View File

@ -6,6 +6,7 @@ import { LinkButton } from "~/components/elements/Button";
import { FriendCodeInput } from "~/components/FriendCodeInput";
import { SubmitButton } from "~/components/SubmitButton";
import { useUser } from "~/features/auth/core/user";
import { useTournament } from "~/features/tournament/tournament-context";
import invariant from "~/utils/invariant";
import { assertUnreachable } from "~/utils/types";
import {
@ -17,7 +18,6 @@ import { action } from "../actions/to.$id.join.server";
import { loader } from "../loaders/to.$id.join.server";
import styles from "../tournament.module.css";
import { validateCanJoinTeam } from "../tournament-utils";
import { useTournament } from "./to.$id";
export { action, loader };

View File

@ -18,6 +18,7 @@ import { Config } from "~/config";
import { useUser } from "~/features/auth/core/user";
import { MapPool } from "~/features/map-list-generator/core/map-pool";
import { ModeMapPoolPicker } from "~/features/settings/components/ModeMapPoolPicker";
import { useTournament } from "~/features/tournament/tournament-context";
import type { TournamentTeamFull } from "~/features/tournament-bracket/core/Tournament.server";
import { FormField } from "~/form/FormField";
import { SendouForm, useFormFieldContext } from "~/form/SendouForm";
@ -51,7 +52,6 @@ import {
type CounterPickValidationStatus,
validateCounterPickMapPool,
} from "../tournament-utils";
import { useTournament } from "./to.$id";
export { action, loader };

View File

@ -16,6 +16,7 @@ import { Flag } from "~/components/Flag";
import { InfoPopover } from "~/components/InfoPopover";
import { Placement } from "~/components/Placement";
import { Table } from "~/components/Table";
import { useTournament } from "~/features/tournament/tournament-context";
import { useSpoilerFree } from "~/hooks/useSpoilerFree";
import {
SPR_INFO_URL,
@ -25,7 +26,6 @@ import {
import type { TournamentResultsLoaderData } from "../loaders/to.$id.results.server";
import styles from "../tournament.module.css";
import { TOURNAMENT } from "../tournament-constants";
import { useTournament } from "./to.$id";
export { loader } from "../loaders/to.$id.results.server";

View File

@ -8,11 +8,11 @@ import { MapPoolStages } from "~/components/MapPoolSelector";
import { Markdown } from "~/components/Markdown";
import { Section } from "~/components/Section";
import { MapPool } from "~/features/map-list-generator/core/map-pool";
import { useTournament } from "~/features/tournament/tournament-context";
import { modesShort } from "~/modules/in-game-lists/modes";
import type { SendouRouteHandle } from "~/utils/remix.server";
import { mapsPageWithMapPool, navIconUrl } from "~/utils/urls";
import { loader } from "../loaders/to.$id.rules.server";
import { useTournament } from "./to.$id";
import styles from "./to.$id.info.module.css";
export { loader };

View File

@ -1,11 +1,11 @@
import { useTranslation } from "react-i18next";
import { useLoaderData } from "react-router";
import { Redirect } from "~/components/Redirect";
import { useTournament } from "~/features/tournament/tournament-context";
import { tournamentRegisterPage } from "~/utils/urls";
import { TournamentStream } from "../components/TournamentStream";
import type { TournamentStreamsLoaderData } from "../loaders/to.$id.streams.server";
import styles from "../tournament.module.css";
import { useTournament } from "./to.$id";
export { loader } from "../loaders/to.$id.streams.server";

View File

@ -7,6 +7,7 @@ import { SendouPopover } from "~/components/elements/Popover";
import { ModeImage, StageImage } from "~/components/Image";
import { Placement } from "~/components/Placement";
import { UserLink } from "~/components/UserLink";
import { useTournament } from "~/features/tournament/tournament-context";
import type { TournamentTeamFull } from "~/features/tournament-bracket/core/Tournament.server";
import type { TournamentMaplistSource } from "~/modules/tournament-map-list-generator/types";
import { metaTags } from "~/utils/remix";
@ -21,7 +22,6 @@ import {
type TournamentTeamLoaderData,
} from "../loaders/to.$id.teams.$tid.server";
import styles from "../tournament.module.css";
import { useTournament } from "./to.$id";
export { loader };

View File

@ -1,13 +1,14 @@
import { useLoaderData } from "react-router";
import { Pagination } from "~/components/Pagination";
import { Redirect } from "~/components/Redirect";
import { useTournament } from "~/features/tournament/tournament-context";
import { useSearchParamPagination } from "~/hooks/useSearchParamPagination";
import { tournamentDivisionsPage, tournamentTeamPage } from "~/utils/urls";
import { TeamWithRoster } from "../components/TeamWithRoster";
import type { TournamentTeamsLoaderData } from "../loaders/to.$id.teams.server";
import { tournamentTeamsSearchParams } from "../tournament-search-params";
import { getBracketProgressionLabel } from "../tournament-utils";
import { useHasChildTournaments, useTournament } from "./to.$id";
import { useHasChildTournaments } from "./to.$id";
export { loader } from "../loaders/to.$id.teams.server";

View File

@ -10,6 +10,7 @@ import { containerClassName, Main } from "~/components/Main";
import { Placeholder } from "~/components/Placeholder";
import { isMatchResultsScopedRevalidation } from "~/features/chat/revalidation-scope";
import { useChatContext } from "~/features/chat/useChatContext";
import { TournamentProvider } from "~/features/tournament/tournament-context";
import { Tournament } from "~/features/tournament-bracket/core/Tournament";
import { useHydrated } from "~/hooks/useHydrated";
import type { SendouRouteHandle } from "~/utils/remix.server";
@ -71,26 +72,6 @@ export const handle: SendouRouteHandle = {
},
};
const TournamentContext = React.createContext<Tournament>(null!);
/**
* Overrides the tournament of the subtree, used by the views that load bracket match data
* of their own on top of what the layout ships.
*/
export function TournamentOverrideProvider({
tournament,
children,
}: {
tournament: Tournament;
children: React.ReactNode;
}) {
return (
<TournamentContext.Provider value={tournament}>
{children}
</TournamentContext.Provider>
);
}
export default function TournamentLayoutShell() {
const isHydrated = useHydrated();
@ -135,7 +116,7 @@ export function TournamentLayout() {
streamsCount={data.streamsCount}
hasChildTournaments={data.hasChildTournaments}
/>
<TournamentContext.Provider value={tournament}>
<TournamentProvider tournament={tournament}>
<Outlet
context={
{
@ -149,7 +130,7 @@ export function TournamentLayout() {
} satisfies TournamentContext
}
/>
</TournamentContext.Provider>
</TournamentProvider>
</>
);
@ -173,10 +154,6 @@ type TournamentContext = {
vods: NonNullable<TournamentLoaderData["vods"]>;
};
export function useTournament() {
return React.useContext(TournamentContext);
}
export function useBracketExpanded() {
const { bracketExpanded, setBracketExpanded } =
useOutletContext<TournamentContext>();

View File

@ -0,0 +1,34 @@
import * as React from "react";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
// Lives outside the to.$id route module on purpose: a context created inside a
// route module gets a new identity when HMR re-executes that module, leaving
// consumers in sibling route modules reading the stale context (null).
const TournamentContext = React.createContext<Tournament | null>(null);
/**
* Provides the tournament of the subtree. Rendered by the tournament layout,
* and rendered again by views that load bracket match data of their own to
* override the layout's tournament.
*/
export function TournamentProvider({
tournament,
children,
}: {
tournament: Tournament;
children: React.ReactNode;
}) {
return (
<TournamentContext.Provider value={tournament}>
{children}
</TournamentContext.Provider>
);
}
export function useTournament() {
const tournament = React.useContext(TournamentContext);
if (!tournament) {
throw new Error("useTournament must be used within TournamentProvider");
}
return tournament;
}