diff --git a/app/features/bracket-test/routes/bracket-test.tsx b/app/features/bracket-test/routes/bracket-test.tsx index cd5a0c952..750fbbfec 100644 --- a/app/features/bracket-test/routes/bracket-test.tsx +++ b/app/features/bracket-test/routes/bracket-test.tsx @@ -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() { - - + ); } diff --git a/app/features/tournament-admin/components/ExportDialog.tsx b/app/features/tournament-admin/components/ExportDialog.tsx index ff7862f20..f7073e65e 100644 --- a/app/features/tournament-admin/components/ExportDialog.tsx +++ b/app/features/tournament-admin/components/ExportDialog.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin._index.tsx b/app/features/tournament-admin/routes/to.$id.admin._index.tsx index 56abf44fa..e26c97da7 100644 --- a/app/features/tournament-admin/routes/to.$id.admin._index.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin._index.tsx @@ -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, diff --git a/app/features/tournament-admin/routes/to.$id.admin.audit.tsx b/app/features/tournament-admin/routes/to.$id.admin.audit.tsx index 09ce61a9b..3048550d4 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.audit.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.audit.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin.brackets.tsx b/app/features/tournament-admin/routes/to.$id.admin.brackets.tsx index c4b5c7f67..240ddaf20 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.brackets.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.brackets.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.browser.test.tsx b/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.browser.test.tsx index d614fc78c..b0b6032a2 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.browser.test.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.browser.test.tsx @@ -28,7 +28,7 @@ vi.mock("react-router", async () => { }; }); -vi.mock("~/features/tournament/routes/to.$id", () => ({ +vi.mock("~/features/tournament/tournament-context", () => ({ useTournament: () => mockTournament, })); diff --git a/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.captain-label.browser.test.tsx b/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.captain-label.browser.test.tsx index a38077c91..8ec1599b6 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.captain-label.browser.test.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.captain-label.browser.test.tsx @@ -19,7 +19,7 @@ vi.mock("react-router", async () => { }; }); -vi.mock("~/features/tournament/routes/to.$id", () => ({ +vi.mock("~/features/tournament/tournament-context", () => ({ useTournament: () => mockTournament, })); diff --git a/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.tsx b/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.tsx index e396db427..1b932a5ec 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.registration.$tid.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin.seeds.tsx b/app/features/tournament-admin/routes/to.$id.admin.seeds.tsx index 00b575b9c..6f2cf402a 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.seeds.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.seeds.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin.staff.tsx b/app/features/tournament-admin/routes/to.$id.admin.staff.tsx index f015670f5..12d745de3 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.staff.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.staff.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin.stream.tsx b/app/features/tournament-admin/routes/to.$id.admin.stream.tsx index 98338ce81..c01271a46 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.stream.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.stream.tsx @@ -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"; diff --git a/app/features/tournament-admin/routes/to.$id.admin.tsx b/app/features/tournament-admin/routes/to.$id.admin.tsx index 11f9934e9..96af0e4a8 100644 --- a/app/features/tournament-admin/routes/to.$id.admin.tsx +++ b/app/features/tournament-admin/routes/to.$id.admin.tsx @@ -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, diff --git a/app/features/tournament-bracket/components/Bracket/Bracket.browser.test.tsx b/app/features/tournament-bracket/components/Bracket/Bracket.browser.test.tsx index fea605fca..3257dbe50 100644 --- a/app/features/tournament-bracket/components/Bracket/Bracket.browser.test.tsx +++ b/app/features/tournament-bracket/components/Bracket/Bracket.browser.test.tsx @@ -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, diff --git a/app/features/tournament-bracket/components/Bracket/Match.tsx b/app/features/tournament-bracket/components/Bracket/Match.tsx index 391d5f327..28c006e73 100644 --- a/app/features/tournament-bracket/components/Bracket/Match.tsx +++ b/app/features/tournament-bracket/components/Bracket/Match.tsx @@ -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"; diff --git a/app/features/tournament-bracket/components/Bracket/RoundHeader.tsx b/app/features/tournament-bracket/components/Bracket/RoundHeader.tsx index 561966615..944169f54 100644 --- a/app/features/tournament-bracket/components/Bracket/RoundHeader.tsx +++ b/app/features/tournament-bracket/components/Bracket/RoundHeader.tsx @@ -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"; diff --git a/app/features/tournament-bracket/components/Bracket/Swiss.tsx b/app/features/tournament-bracket/components/Bracket/Swiss.tsx index fc35e89f7..d8338266b 100644 --- a/app/features/tournament-bracket/components/Bracket/Swiss.tsx +++ b/app/features/tournament-bracket/components/Bracket/Swiss.tsx @@ -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"; diff --git a/app/features/tournament-bracket/components/Bracket/useBracketSpoilerCensor.ts b/app/features/tournament-bracket/components/Bracket/useBracketSpoilerCensor.ts index 8130ecaa2..f2e99996c 100644 --- a/app/features/tournament-bracket/components/Bracket/useBracketSpoilerCensor.ts +++ b/app/features/tournament-bracket/components/Bracket/useBracketSpoilerCensor.ts @@ -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; diff --git a/app/features/tournament-bracket/components/BracketMapListDialog.tsx b/app/features/tournament-bracket/components/BracketMapListDialog.tsx index 7c168b76a..56846addf 100644 --- a/app/features/tournament-bracket/components/BracketMapListDialog.tsx +++ b/app/features/tournament-bracket/components/BracketMapListDialog.tsx @@ -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"; diff --git a/app/features/tournament-bracket/components/TournamentTeamActions.tsx b/app/features/tournament-bracket/components/TournamentTeamActions.tsx index 1f3c292e3..3d628e419 100644 --- a/app/features/tournament-bracket/components/TournamentTeamActions.tsx +++ b/app/features/tournament-bracket/components/TournamentTeamActions.tsx @@ -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"; diff --git a/app/features/tournament-bracket/routes/to.$id.brackets.finalize.tsx b/app/features/tournament-bracket/routes/to.$id.brackets.finalize.tsx index a1b9398a9..4bd128d38 100644 --- a/app/features/tournament-bracket/routes/to.$id.brackets.finalize.tsx +++ b/app/features/tournament-bracket/routes/to.$id.brackets.finalize.tsx @@ -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, diff --git a/app/features/tournament-bracket/routes/to.$id.brackets.tsx b/app/features/tournament-bracket/routes/to.$id.brackets.tsx index 0a22cc505..ccfe4077c 100644 --- a/app/features/tournament-bracket/routes/to.$id.brackets.tsx +++ b/app/features/tournament-bracket/routes/to.$id.brackets.tsx @@ -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 ( - + - + ); } diff --git a/app/features/tournament-lfg/components/LFGGroupCard.tsx b/app/features/tournament-lfg/components/LFGGroupCard.tsx index 05baef808..0dec0a556 100644 --- a/app/features/tournament-lfg/components/LFGGroupCard.tsx +++ b/app/features/tournament-lfg/components/LFGGroupCard.tsx @@ -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, diff --git a/app/features/tournament-lfg/routes/to.$id.looking.tsx b/app/features/tournament-lfg/routes/to.$id.looking.tsx index 4b51b44d0..45ce44804 100644 --- a/app/features/tournament-lfg/routes/to.$id.looking.tsx +++ b/app/features/tournament-lfg/routes/to.$id.looking.tsx @@ -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, diff --git a/app/features/tournament-match/components/OrganizerMatchMapListDialog.tsx b/app/features/tournament-match/components/OrganizerMatchMapListDialog.tsx index c5b7e3ffe..d8c313ff4 100644 --- a/app/features/tournament-match/components/OrganizerMatchMapListDialog.tsx +++ b/app/features/tournament-match/components/OrganizerMatchMapListDialog.tsx @@ -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"; diff --git a/app/features/tournament-match/components/TournamentMatchActionPickBanTab.tsx b/app/features/tournament-match/components/TournamentMatchActionPickBanTab.tsx index 06a876c14..2738a0f41 100644 --- a/app/features/tournament-match/components/TournamentMatchActionPickBanTab.tsx +++ b/app/features/tournament-match/components/TournamentMatchActionPickBanTab.tsx @@ -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"; diff --git a/app/features/tournament-match/components/TournamentMatchActionTab.tsx b/app/features/tournament-match/components/TournamentMatchActionTab.tsx index 5b9297121..bedcbafc9 100644 --- a/app/features/tournament-match/components/TournamentMatchActionTab.tsx +++ b/app/features/tournament-match/components/TournamentMatchActionTab.tsx @@ -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"; diff --git a/app/features/tournament-match/components/TournamentMatchAdminTab.tsx b/app/features/tournament-match/components/TournamentMatchAdminTab.tsx index a5b41e190..e727eb680 100644 --- a/app/features/tournament-match/components/TournamentMatchAdminTab.tsx +++ b/app/features/tournament-match/components/TournamentMatchAdminTab.tsx @@ -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"; diff --git a/app/features/tournament-match/components/TournamentMatchBanner.tsx b/app/features/tournament-match/components/TournamentMatchBanner.tsx index f42bf05e6..0cffed821 100644 --- a/app/features/tournament-match/components/TournamentMatchBanner.tsx +++ b/app/features/tournament-match/components/TournamentMatchBanner.tsx @@ -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"; diff --git a/app/features/tournament-match/components/TournamentMatchHeader.tsx b/app/features/tournament-match/components/TournamentMatchHeader.tsx index f88b5ea0b..00a9d3e80 100644 --- a/app/features/tournament-match/components/TournamentMatchHeader.tsx +++ b/app/features/tournament-match/components/TournamentMatchHeader.tsx @@ -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"; diff --git a/app/features/tournament-match/components/TournamentMatchTabs.tsx b/app/features/tournament-match/components/TournamentMatchTabs.tsx index 62da64b10..0aa16e60a 100644 --- a/app/features/tournament-match/components/TournamentMatchTabs.tsx +++ b/app/features/tournament-match/components/TournamentMatchTabs.tsx @@ -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"; diff --git a/app/features/tournament-match/match-page-context.tsx b/app/features/tournament-match/match-page-context.tsx index 194e62afd..96e8f0241 100644 --- a/app/features/tournament-match/match-page-context.tsx +++ b/app/features/tournament-match/match-page-context.tsx @@ -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 { diff --git a/app/features/tournament-match/routes/to.$id.matches.$mid.tsx b/app/features/tournament-match/routes/to.$id.matches.$mid.tsx index b3ade903b..1549bec24 100644 --- a/app/features/tournament-match/routes/to.$id.matches.$mid.tsx +++ b/app/features/tournament-match/routes/to.$id.matches.$mid.tsx @@ -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"; diff --git a/app/features/tournament/components/TeamWithRoster.tsx b/app/features/tournament/components/TeamWithRoster.tsx index ca6faadb8..c9227fc9e 100644 --- a/app/features/tournament/components/TeamWithRoster.tsx +++ b/app/features/tournament/components/TeamWithRoster.tsx @@ -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({ diff --git a/app/features/tournament/components/TournamentStream.tsx b/app/features/tournament/components/TournamentStream.tsx index 357c36099..c178269da 100644 --- a/app/features/tournament/components/TournamentStream.tsx +++ b/app/features/tournament/components/TournamentStream.tsx @@ -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({ diff --git a/app/features/tournament/routes/to.$id.info.tsx b/app/features/tournament/routes/to.$id.info.tsx index 385aab5fa..118b7b5e8 100644 --- a/app/features/tournament/routes/to.$id.info.tsx +++ b/app/features/tournament/routes/to.$id.info.tsx @@ -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 }; diff --git a/app/features/tournament/routes/to.$id.join.tsx b/app/features/tournament/routes/to.$id.join.tsx index 4133271cb..d05730250 100644 --- a/app/features/tournament/routes/to.$id.join.tsx +++ b/app/features/tournament/routes/to.$id.join.tsx @@ -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 }; diff --git a/app/features/tournament/routes/to.$id.register.tsx b/app/features/tournament/routes/to.$id.register.tsx index 4f75452a1..d1df10b9e 100644 --- a/app/features/tournament/routes/to.$id.register.tsx +++ b/app/features/tournament/routes/to.$id.register.tsx @@ -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 }; diff --git a/app/features/tournament/routes/to.$id.results.tsx b/app/features/tournament/routes/to.$id.results.tsx index e5cd17319..c7f89f82f 100644 --- a/app/features/tournament/routes/to.$id.results.tsx +++ b/app/features/tournament/routes/to.$id.results.tsx @@ -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"; diff --git a/app/features/tournament/routes/to.$id.rules.tsx b/app/features/tournament/routes/to.$id.rules.tsx index 75f1da183..dc5d821e9 100644 --- a/app/features/tournament/routes/to.$id.rules.tsx +++ b/app/features/tournament/routes/to.$id.rules.tsx @@ -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 }; diff --git a/app/features/tournament/routes/to.$id.streams.tsx b/app/features/tournament/routes/to.$id.streams.tsx index 8cec7d009..4f857265a 100644 --- a/app/features/tournament/routes/to.$id.streams.tsx +++ b/app/features/tournament/routes/to.$id.streams.tsx @@ -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"; diff --git a/app/features/tournament/routes/to.$id.teams.$tid.tsx b/app/features/tournament/routes/to.$id.teams.$tid.tsx index eb5e01b39..575c6a67f 100644 --- a/app/features/tournament/routes/to.$id.teams.$tid.tsx +++ b/app/features/tournament/routes/to.$id.teams.$tid.tsx @@ -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 }; diff --git a/app/features/tournament/routes/to.$id.teams.tsx b/app/features/tournament/routes/to.$id.teams.tsx index 7b987d79f..4a15da028 100644 --- a/app/features/tournament/routes/to.$id.teams.tsx +++ b/app/features/tournament/routes/to.$id.teams.tsx @@ -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"; diff --git a/app/features/tournament/routes/to.$id.tsx b/app/features/tournament/routes/to.$id.tsx index 1c5631e08..b381fcde4 100644 --- a/app/features/tournament/routes/to.$id.tsx +++ b/app/features/tournament/routes/to.$id.tsx @@ -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(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 ( - - {children} - - ); -} - export default function TournamentLayoutShell() { const isHydrated = useHydrated(); @@ -135,7 +116,7 @@ export function TournamentLayout() { streamsCount={data.streamsCount} hasChildTournaments={data.hasChildTournaments} /> - + - + ); @@ -173,10 +154,6 @@ type TournamentContext = { vods: NonNullable; }; -export function useTournament() { - return React.useContext(TournamentContext); -} - export function useBracketExpanded() { const { bracketExpanded, setBracketExpanded } = useOutletContext(); diff --git a/app/features/tournament/tournament-context.tsx b/app/features/tournament/tournament-context.tsx new file mode 100644 index 000000000..b2fc00a2d --- /dev/null +++ b/app/features/tournament/tournament-context.tsx @@ -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(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 ( + + {children} + + ); +} + +export function useTournament() { + const tournament = React.useContext(TournamentContext); + if (!tournament) { + throw new Error("useTournament must be used within TournamentProvider"); + } + return tournament; +}