diff --git a/app/components/layout/ChatSidebar.tsx b/app/components/layout/ChatSidebar.tsx index 50eea44eb..a7cd53b78 100644 --- a/app/components/layout/ChatSidebar.tsx +++ b/app/components/layout/ChatSidebar.tsx @@ -2,12 +2,8 @@ import clsx from "clsx"; import { ArrowLeft, MessageSquare, X } from "lucide-react"; import { Button } from "react-aria-components"; import { useTranslation } from "react-i18next"; -import { Link, useFetcher } from "react-router"; +import { Link } from "react-router"; import { useCurrentRouteChatCode } from "~/features/chat/ChatProvider"; -import { - extractRoomLink, - isMatchRoomUrl, -} from "~/features/chat/chat-constants"; import { resolveDatePlaceholders } from "~/features/chat/chat-utils"; import { Chat } from "~/features/chat/components/Chat"; import { useChatContext } from "~/features/chat/useChatContext"; @@ -178,7 +174,6 @@ function ChatView({ onClose }: { onClose?: () => void }) { .filter(([code]) => code !== activeRoom) .reduce((sum, [, count]) => sum + count, 0); - const roomLinkFetcher = useFetcher(); const room = chatContext.rooms.find((r) => r.chatCode === activeRoom); const roomExpired = Boolean(room?.expiresAt && room.expiresAt < Date.now()); const messages = chatContext.messagesForRoom(activeRoom); @@ -194,26 +189,10 @@ function ChatView({ onClose }: { onClose?: () => void }) { } } - const isMatchRoom = room?.url ? isMatchRoomUrl(room.url) : false; - const chatAdapter = { messages, send: (contents: string) => { chatContext.send(activeRoom, contents); - - if (isMatchRoom) { - const link = extractRoomLink(contents); - if (link) { - roomLinkFetcher.submit( - { _action: "UPSERT", url: link }, - { - method: "post", - action: "/room", - encType: "application/json", - }, - ); - } - } }, currentRoom: activeRoom, setCurrentRoom: () => {}, diff --git a/app/components/match-page/MatchBanner.module.css b/app/components/match-page/MatchBanner.module.css index 76bd5ecbb..40359924f 100644 --- a/app/components/match-page/MatchBanner.module.css +++ b/app/components/match-page/MatchBanner.module.css @@ -18,12 +18,15 @@ width: 100%; height: var(--banner-height); border-radius: var(--radius-box); - padding: var(--s-2); + padding: var(--s-2-5); background-image: linear-gradient( to top, - rgba(255, 255, 255, 0), - rgba(255, 255, 255, 0), + rgba(0, 0, 0, 0.6), + rgba(0, 0, 0, 0.6), + rgba(0, 0, 0, 0.2), + rgba(0, 0, 0, 0.2), + rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6) ), var(--stage-img); @@ -50,32 +53,39 @@ bottom: var(--s-2); right: var(--s-2); display: flex; - gap: var(--s-0-5); + gap: var(--s-1); align-items: center; - color: var(--color-text-high); - background-color: var(--color-bg-high); - padding: var(--s-0-5) var(--s-1-5); - border-radius: var(--radius-field); - font-size: var(--font-3xs); - font-weight: normal; + color: inherit; + font-size: inherit; + font-weight: inherit; height: auto; } -.joinBadge { +.joinInfo { position: absolute; bottom: var(--s-2); left: var(--s-2); display: flex; - gap: var(--s-1); - align-items: center; - color: var(--color-text-high); - background-color: var(--color-bg-high); - padding: var(--s-0-5) var(--s-1-5); - border-radius: var(--radius-field); - font-size: var(--font-2xs); + gap: var(--s-4); +} + +.joinInfoItem { + display: flex; + flex-direction: column; + line-height: 1.1; +} + +.joinInfoLabel { + text-transform: uppercase; + font-size: var(--font-xs); font-weight: var(--weight-semi); - height: 32px; - width: 32px; + opacity: 0.7; +} + +.joinInfoValue { + font-size: var(--font-lg); + font-weight: var(--weight-bold); + letter-spacing: 1px; } .infoBadge { @@ -120,8 +130,11 @@ background-image: linear-gradient( to top, - rgba(255, 255, 255, 0), - rgba(255, 255, 255, 0), + rgba(0, 0, 0, 0.6), + rgba(0, 0, 0, 0.6), + rgba(0, 0, 0, 0.2), + rgba(0, 0, 0, 0.2), + rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6) ), var(--stage-img); @@ -149,7 +162,8 @@ flex-direction: column; align-items: center; justify-content: center; - gap: var(--s-1); + gap: var(--s-0-5); + line-height: 1.2; width: 100%; height: var(--banner-height); border-radius: var(--radius-box); diff --git a/app/components/match-page/MatchBanner.tsx b/app/components/match-page/MatchBanner.tsx index a5c08a52e..883fe7471 100644 --- a/app/components/match-page/MatchBanner.tsx +++ b/app/components/match-page/MatchBanner.tsx @@ -1,7 +1,6 @@ import clsx from "clsx"; -import { Check, QrCode, X } from "lucide-react"; +import { Check, X } from "lucide-react"; import { useTranslation } from "react-i18next"; -import { useSearchParams } from "react-router"; import { SendouButton } from "~/components/elements/Button"; import { SendouPopover } from "~/components/elements/Popover"; import type { ModeShort, StageId } from "~/modules/in-game-lists/types"; @@ -22,7 +21,7 @@ interface MatchBannerProps { mode: ModeShort; screenLegal?: boolean; joinPool?: string | null; - joinViaQr?: boolean; + joinPass?: string | null; children?: React.ReactNode; } @@ -31,7 +30,7 @@ export function MatchBanner({ mode, screenLegal, joinPool, - joinViaQr, + joinPass, children, }: MatchBannerProps) { const { t } = useTranslation(["game-misc"]); @@ -50,7 +49,7 @@ export function MatchBanner({
{children}
- {joinPool ? : null} + {joinPool ? : null} {screenLegal !== undefined ? ( ) : null} @@ -82,7 +81,7 @@ interface IconBannerProps { subtitle?: string; screenLegal?: boolean; joinPool?: string | null; - joinViaQr?: boolean; + joinPass?: string | null; topRight?: React.ReactNode; testId?: string; } @@ -93,7 +92,7 @@ export function IconBanner({ subtitle, screenLegal, joinPool, - joinViaQr, + joinPass, topRight, testId, }: IconBannerProps) { @@ -104,7 +103,7 @@ export function IconBanner({ {subtitle ? (
{subtitle}
) : null} - {joinPool ? : null} + {joinPool ? : null} {screenLegal !== undefined ? ( ) : null} @@ -115,35 +114,33 @@ export function IconBanner({ ); } -function JoinPoolBadge({ pool, viaQr }: { pool: string; viaQr?: boolean }) { +function JoinInfo({ pool, pass }: { pool: string; pass?: string | null }) { const { t } = useTranslation(["q"]); - const [, setSearchParams] = useSearchParams(); return ( - - setSearchParams( - { tab: "join" }, - { - preventScrollReset: true, - defaultShouldRevalidate: false, - }, - ) - } - aria-label={t("q:match.pool")} - testId="join-pool-badge" - > - {viaQr ? : pool} - +
+
+
{t("q:match.pool")}
+
{pool}
+
+ {pass ? ( +
+
+ {t("q:match.password.short")} +
+
+ {pass} +
+
+ ) : null} +
); } function ScreenNotice({ screenLegal }: { screenLegal: boolean }) { const { t } = useTranslation(["weapons", "q"]); - const imgSize = 18; + const imgSize = 24; const Icon = screenLegal ? Check : X; @@ -156,16 +153,16 @@ function ScreenNotice({ screenLegal }: { screenLegal: boolean }) { testId={screenLegal ? "screen-allowed" : "screen-banned"} aria-label={screenLegal ? "Screen allowed" : "Screen banned"} > - + } > diff --git a/app/components/match-page/MatchJoinTab.module.css b/app/components/match-page/MatchJoinTab.module.css deleted file mode 100644 index 46fa95e11..000000000 --- a/app/components/match-page/MatchJoinTab.module.css +++ /dev/null @@ -1,96 +0,0 @@ -.joinContent { - display: grid; - grid-template-areas: "time x" "qr join"; - grid-template-columns: auto minmax(0, max-content); - gap: var(--s-1) var(--s-4); - justify-content: center; - max-width: 100%; -} - -.joinInfo { - display: flex; - flex-direction: column; - grid-area: join; - gap: var(--s-2); - min-width: 0; -} - -.infoHeader { - text-transform: uppercase; - color: var(--color-text-high); - font-size: var(--font-2xs); - line-height: 1.1; -} - -.infoValue { - font-size: var(--font-lg); - font-weight: var(--weight-semi); - letter-spacing: 1px; -} - -.infoValueTruncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 400px; -} - -.qrCodeContainer { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--s-1); - grid-area: qr; -} - -.roomAge { - grid-area: time; - font-size: var(--font-2xs); - color: var(--color-text-high); - text-align: center; -} - -.qrCode { - background-color: white; - padding: var(--s-2); - border-radius: var(--radius-field); -} - -.joinLink { - font-size: var(--font-2xs); - text-overflow: ellipsis; - overflow-x: hidden; - text-wrap: nowrap; - max-width: 140px; -} - -.qrOverlay { - width: 172px; - height: 172px; - border-radius: var(--radius-field); - padding: var(--s-2); - background-color: var(--color-bg-higher); - grid-area: qr; -} - -.stalePrompt { - display: flex; - gap: var(--s-6); - flex-direction: column; - align-items: center; - justify-content: center; -} - -.staleText { - font-size: var(--font-sm); - color: var(--color-text-high); - text-align: center; -} - -.noRoomHint { - font-size: var(--font-sm); - color: var(--color-text-high); - display: grid; - place-items: center; - text-align: center; -} diff --git a/app/components/match-page/MatchJoinTab.tsx b/app/components/match-page/MatchJoinTab.tsx deleted file mode 100644 index 774252f20..000000000 --- a/app/components/match-page/MatchJoinTab.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import clsx from "clsx"; -import { QRCodeSVG } from "qrcode.react"; -import { useTranslation } from "react-i18next"; -import { Alert } from "~/components/Alert"; -import { useFormatDistanceToNow } from "~/hooks/intl/useFormatDistanceToNow"; -import { SendouButton } from "../elements/Button"; -import { SendouTabPanel } from "../elements/Tabs"; -import styles from "./MatchJoinTab.module.css"; -import { TAB_KEYS } from "./MatchTabs"; - -interface MatchJoinTabProps { - joinLink?: string; - hostedBy?: string; - pool: string; - pass: string; - showNoSplatnetAlert: boolean; - isStale?: boolean; - staleMinutesAgo?: number; - refreshedAt?: Date; - onConfirmRoom?: () => void; - isConfirming?: boolean; -} - -export function MatchJoinTab({ - joinLink, - hostedBy, - pool, - pass, - showNoSplatnetAlert, - isStale, - staleMinutesAgo, - refreshedAt, - onConfirmRoom, - isConfirming, -}: MatchJoinTabProps) { - const { t } = useTranslation(["q"]); - const formatDistanceToNow = useFormatDistanceToNow(); - - return ( - -
- {showNoSplatnetAlert ? ( - - {t("q:match.noSplatnetWarning")} - - ) : null} -
- {joinLink ? ( - isStale ? ( - - ) : ( - <> - {refreshedAt ? ( -
- {formatDistanceToNow(refreshedAt, { addSuffix: true })} -
- ) : null} - - - ) - ) : ( -
- {t("q:match.room.noRoomHint")} -
- )} -
- {hostedBy ? ( - - ) : null} - - -
-
-
-
- ); -} - -function StaleRoomPrompt({ - minutesAgo, - onConfirm, - isConfirming, -}: { - minutesAgo: number; - onConfirm?: () => void; - isConfirming?: boolean; -}) { - const { t } = useTranslation(["q"]); - - return ( -
-
- {t("q:match.room.stalePrompt", { minutes: minutesAgo })} -
- - {t("q:match.room.confirm")} - -
- ); -} - -function InfoWithHeader({ - header, - value, - testId, - truncate, -}: { - header: string; - value: string; - testId?: string; - truncate?: boolean; -}) { - return ( -
-
{header}
-
- {value} -
-
- ); -} diff --git a/app/components/match-page/MatchRosterTab.tsx b/app/components/match-page/MatchRosterTab.tsx index 4314554d7..b37f28807 100644 --- a/app/components/match-page/MatchRosterTab.tsx +++ b/app/components/match-page/MatchRosterTab.tsx @@ -50,6 +50,8 @@ interface RosterTabTeam { subbedOut?: Array; tier?: { name: TierName; isPlus: boolean }; seed?: number | null; + /** Whether this team is expected to host the room (tournament only). */ + isHost?: boolean; } interface MatchRosterTabProps { @@ -261,6 +263,8 @@ function TeamHeader({ label: string; dotClassName: string; }) { + const { t } = useTranslation(["common"]); + const tierText = team.tier ? `${team.tier.name.toLowerCase()}${team.tier.isPlus ? "+" : ""}` : undefined; @@ -282,6 +286,12 @@ function TeamHeader({ {seedText} ) : null} + {team.isHost ? ( + <> + + {t("common:host")} + + ) : null} ); diff --git a/app/components/match-page/MatchTabs.tsx b/app/components/match-page/MatchTabs.tsx index 9ca7205a0..3b72cd59b 100644 --- a/app/components/match-page/MatchTabs.tsx +++ b/app/components/match-page/MatchTabs.tsx @@ -1,15 +1,7 @@ -import { - BarChart3, - DoorOpen, - Key, - ScrollText, - Tally5, - Users, -} from "lucide-react"; +import { BarChart3, Key, ScrollText, Tally5, Users } from "lucide-react"; import type * as React from "react"; import { useTranslation } from "react-i18next"; import { useSearchParams } from "react-router"; -import { useUser } from "~/features/auth/core/user"; import invariant from "~/utils/invariant"; import { SendouTab, SendouTabList, SendouTabs } from "../elements/Tabs"; import styles from "./MatchTabs.module.css"; @@ -27,7 +19,6 @@ const TAB_KEY = "tab"; export const TAB_KEYS = { ROSTERS: "rosters", ACTION: "action", - JOIN: "join", RESULT: "result", STATS: "stats", ADMIN: "admin", @@ -36,7 +27,6 @@ export const TAB_KEYS = { const TAB_ICONS: Record = { rosters: , action: , - join: , result: , stats: , admin: , @@ -45,7 +35,6 @@ const TAB_ICONS: Record = { const TAB_TRANSLATION_KEYS = { rosters: "q:match.tabs.rosters", action: "q:match.tabs.action", - join: "common:actions.join", result: "q:match.tabs.result", stats: "q:match.tabs.stats", admin: "common:pages.admin", @@ -54,12 +43,9 @@ const TAB_TRANSLATION_KEYS = { export function MatchTabs({ children, tabs, alertTabs }: MatchTabsProps) { const { t } = useTranslation(["q", "common"]); const [searchParams, setSearchParams] = useSearchParams(); - const user = useUser(); - const preferredTab = user?.preferences.defaultMatchPageTab; const currentTab = - tabs.find((tab) => searchParams.get(TAB_KEY) === tab) ?? - (preferredTab && tabs.includes(preferredTab) ? preferredTab : tabs.at(0)); + tabs.find((tab) => searchParams.get(TAB_KEY) === tab) ?? tabs.at(0); invariant(currentTab); return ( diff --git a/app/db/seed/index.ts b/app/db/seed/index.ts index 1c0bf41dd..122a24638 100644 --- a/app/db/seed/index.ts +++ b/app/db/seed/index.ts @@ -2726,23 +2726,6 @@ async function groups(variation?: SeedVariation | null) { expiresAfter: { hours: 2 }, }); } - - const thirtyMinutesAgo = dateToDatabaseTimestamp( - sub(new Date(), { minutes: 30 }), - ); - sql - .prepare( - /* sql */ ` - insert into "RoomLink" ("userId", "url", "createdAt", "refreshedAt") - values (@userId, @url, @createdAt, @refreshedAt) - `, - ) - .run({ - userId: ADMIN_ID, - url: "https://example.com//private_battle/seed_room_123", - createdAt: thirtyMinutesAgo, - refreshedAt: thirtyMinutesAgo, - }); } } diff --git a/app/db/tables.ts b/app/db/tables.ts index 0e0a4bd57..805efb357 100644 --- a/app/db/tables.ts +++ b/app/db/tables.ts @@ -1070,8 +1070,6 @@ export interface UserPreferences { /** Is spoiler-free mode enabled? Hides recent tournament results and scores until the user chooses to reveal them. */ spoilerFreeMode?: boolean; weaponReportDefaultOpen?: boolean; - /** Which tab opens first on the match page. Unset = first available tab (Rosters). */ - defaultMatchPageTab?: "rosters" | "join" | "action"; } export const SUBJECT_PRONOUNS = ["he", "she", "they", "it", "any"] as const; @@ -1133,8 +1131,6 @@ export interface User { weaponPool: JSONColumnTypeNullable; plusSkippedForSeasonNth: number | null; noScreen: Generated; - /** User doesn't have access to SplatNet 3 to join rooms made by others */ - noSplatnet: Generated; buildSorting: JSONColumnTypeNullable; preferences: JSONColumnTypeNullable; /** User creation date. Can be null because we did not always save this. */ @@ -1435,13 +1431,6 @@ export interface NotificationUserSubscription { subscription: JSONColumnType; } -export interface RoomLink { - userId: number; - url: string; - createdAt: Generated; - refreshedAt: Generated; -} - export const SPLATOON_ROTATION_TYPES = ["SERIES", "OPEN", "X"] as const; export type SplatoonRotationType = (typeof SPLATOON_ROTATION_TYPES)[number]; @@ -1500,7 +1489,6 @@ export interface DB { PlusTier: PlusTier; PlusVote: PlusVote; PlusVotingResult: PlusVotingResult; - RoomLink: RoomLink; ReportedWeapon: ReportedWeapon; Skill: Skill; SkillTeamUser: SkillTeamUser; diff --git a/app/features/chat/RoomLinkRepository.server.ts b/app/features/chat/RoomLinkRepository.server.ts deleted file mode 100644 index aec58f5f8..000000000 --- a/app/features/chat/RoomLinkRepository.server.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { sub } from "date-fns"; -import { db } from "~/db/sql"; -import { actorId } from "~/features/auth/core/user.server"; -import { databaseTimestampNow, dateToDatabaseTimestamp } from "~/utils/dates"; - -export function upsertOwn(url: string) { - return db - .insertInto("RoomLink") - .values({ - userId: actorId(), - url, - }) - .onConflict((oc) => - oc.column("userId").doUpdateSet({ - url, - createdAt: databaseTimestampNow(), - refreshedAt: databaseTimestampNow(), - }), - ) - .execute(); -} - -export function findByUserIds(userIds: number[], maxAgeHours: number) { - return db - .selectFrom("RoomLink") - .select([ - "RoomLink.userId", - "RoomLink.url", - "RoomLink.createdAt", - "RoomLink.refreshedAt", - ]) - .where("RoomLink.userId", "in", userIds) - .where( - "RoomLink.createdAt", - ">=", - dateToDatabaseTimestamp(sub(new Date(), { hours: maxAgeHours })), - ) - .orderBy("RoomLink.refreshedAt", "asc") - .execute(); -} - -export function refreshOwnTimestamp() { - return db - .updateTable("RoomLink") - .set({ refreshedAt: databaseTimestampNow() }) - .where("userId", "=", actorId()) - .execute(); -} - -export function deleteOld() { - return db - .deleteFrom("RoomLink") - .where( - "refreshedAt", - "<", - dateToDatabaseTimestamp(sub(new Date(), { hours: 2 })), - ) - .executeTakeFirst(); -} diff --git a/app/features/chat/chat-constants.test.ts b/app/features/chat/chat-constants.test.ts index 35dbd414d..4a621cf0e 100644 --- a/app/features/chat/chat-constants.test.ts +++ b/app/features/chat/chat-constants.test.ts @@ -1,9 +1,5 @@ import { describe, expect, test } from "vitest"; -import { - extractRoomLink, - findRoomLinks, - isSplatnetRoomUrl, -} from "./chat-constants"; +import { findRoomLinks, isSplatnetRoomUrl } from "./chat-constants"; describe("isSplatnetRoomUrl", () => { test("accepts canonical SplatNet share path", () => { @@ -111,15 +107,3 @@ describe("findRoomLinks", () => { ]); }); }); - -describe("extractRoomLink", () => { - test("returns first valid link", () => { - expect(extractRoomLink("hi https://s.nintendo.com/abc see you")).toBe( - "https://s.nintendo.com/abc", - ); - }); - - test("returns null when no valid link present", () => { - expect(extractRoomLink("https://sanintendoacom.evil.tld/abc")).toBeNull(); - }); -}); diff --git a/app/features/chat/chat-constants.ts b/app/features/chat/chat-constants.ts index 0dda206ba..56c7d63ef 100644 --- a/app/features/chat/chat-constants.ts +++ b/app/features/chat/chat-constants.ts @@ -31,18 +31,6 @@ export function findRoomLinks( return results; } -export function extractRoomLink(text: string): string | null { - return findRoomLinks(text)[0]?.url ?? null; -} - -const MATCH_ROOM_URL_PATTERN = - /^\/q\/match\/\d+$|^\/to\/\d+\/matches\/\d+$|^\/scrims\/\d+$/; - -export function isMatchRoomUrl(url: string) { - const pathname = canParseUrl(url) ? new URL(url).pathname : url; - return MATCH_ROOM_URL_PATTERN.test(pathname); -} - function canParseUrl(url: string): boolean { try { new URL(url); diff --git a/app/features/chat/components/Chat.module.css b/app/features/chat/components/Chat.module.css index b562abf84..fbae6326c 100644 --- a/app/features/chat/components/Chat.module.css +++ b/app/features/chat/components/Chat.module.css @@ -107,6 +107,20 @@ opacity: 0.7; } +.roomLinkBlock { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--s-1); + margin-block: var(--s-1); +} + +.roomQrCode { + background-color: white; + padding: var(--s-2); + border-radius: var(--radius-field); +} + .roomLink { color: var(--color-text-accent); text-decoration: underline; diff --git a/app/features/chat/components/Chat.tsx b/app/features/chat/components/Chat.tsx index 83ee5be2a..b1a229c99 100644 --- a/app/features/chat/components/Chat.tsx +++ b/app/features/chat/components/Chat.tsx @@ -1,6 +1,7 @@ import clsx from "clsx"; import { sub } from "date-fns"; import { SendHorizontal } from "lucide-react"; +import { QRCodeSVG } from "qrcode.react"; import * as React from "react"; import { Button } from "react-aria-components"; import { useTranslation } from "react-i18next"; @@ -325,15 +326,17 @@ function MessageContents({ text }: { text: string }) { parts.push(text.slice(lastIndex, match.index)); } parts.push( - - {match.url} - , + + + + {match.url} + + , ); lastIndex = match.index + match.url.length; } diff --git a/app/features/chat/room-link-utils.ts b/app/features/chat/room-link-utils.ts deleted file mode 100644 index a494547c9..000000000 --- a/app/features/chat/room-link-utils.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { differenceInMinutes } from "date-fns"; -import { useFetcher } from "react-router"; -import { databaseTimestampToDate } from "~/utils/dates"; - -interface RoomLink { - userId: number; - url: string; - refreshedAt: number; -} - -interface ResolveActiveRoomLinkArgs { - /** Room links for all match participants, sorted by `refreshedAt` ascending. */ - roomLinks: ReadonlyArray; - /** Database timestamp before which a link is considered stale (e.g. match start time). */ - freshnessCutoff: number; - /** Viewer user id, used as fallback to surface the viewer's own stale link. */ - viewerUserId?: number; - /** Members shown to resolve `hostedBy`. */ - members: ReadonlyArray<{ id: number; username: string }>; -} - -interface ActiveRoomLink { - joinLink?: string; - hostedBy?: string; - isStale?: boolean; - staleMinutesAgo: number; - refreshedAt?: Date; -} - -/** - * Selects the room link to display for a match. Prefers the oldest link refreshed - * after the freshness cutoff (the host's confirmed room). Falls back to the - * viewer's own stale link so they can refresh it themselves. - */ -export function resolveActiveRoomLink({ - roomLinks, - freshnessCutoff, - viewerUserId, - members, -}: ResolveActiveRoomLinkArgs): ActiveRoomLink { - const validRoomLink = roomLinks.find( - (rl) => rl.refreshedAt >= freshnessCutoff, - ); - const ownStaleRoomLink = validRoomLink - ? undefined - : roomLinks.find((rl) => rl.userId === viewerUserId); - - const activeRoomLink = validRoomLink ?? ownStaleRoomLink; - - return { - joinLink: activeRoomLink?.url, - hostedBy: activeRoomLink - ? members.find((m) => m.id === activeRoomLink.userId)?.username - : undefined, - isStale: activeRoomLink ? !validRoomLink : undefined, - staleMinutesAgo: ownStaleRoomLink - ? differenceInMinutes( - new Date(), - databaseTimestampToDate(ownStaleRoomLink.refreshedAt), - ) - : 0, - refreshedAt: validRoomLink - ? databaseTimestampToDate(validRoomLink.refreshedAt) - : undefined, - }; -} - -/** Confirms the viewer's room link by refreshing its timestamp via the central `/room` action. */ -export function useConfirmRoom() { - const fetcher = useFetcher(); - - return { - onConfirmRoom: () => { - fetcher.submit( - { _action: "CONFIRM" }, - { method: "post", action: "/room", encType: "application/json" }, - ); - }, - isConfirming: fetcher.state !== "idle", - }; -} diff --git a/app/features/chat/routes/room.ts b/app/features/chat/routes/room.ts deleted file mode 100644 index 3c4a14c03..000000000 --- a/app/features/chat/routes/room.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { ActionFunctionArgs } from "react-router"; -import { z } from "zod"; -import { parseRequestPayload } from "~/utils/remix.server"; -import { isSplatnetRoomUrl } from "../chat-constants"; -import * as RoomLinkRepository from "../RoomLinkRepository.server"; - -const roomLinkSchema = z.discriminatedUnion("_action", [ - z.object({ - _action: z.literal("UPSERT"), - url: z.string().refine(isSplatnetRoomUrl, "Not a SplatNet room URL"), - }), - z.object({ - _action: z.literal("CONFIRM"), - }), -]); - -export const action = async ({ request }: ActionFunctionArgs) => { - const data = await parseRequestPayload({ - request, - schema: roomLinkSchema, - }); - - switch (data._action) { - case "UPSERT": { - await RoomLinkRepository.upsertOwn(data.url); - break; - } - case "CONFIRM": { - await RoomLinkRepository.refreshOwnTimestamp(); - break; - } - } - - return null; -}; diff --git a/app/features/match-page-test/routes/match-page-test.tsx b/app/features/match-page-test/routes/match-page-test.tsx index 53ced6dbc..7bfc98707 100644 --- a/app/features/match-page-test/routes/match-page-test.tsx +++ b/app/features/match-page-test/routes/match-page-test.tsx @@ -17,7 +17,6 @@ import { import { MatchBannerBottomRow } from "~/components/match-page/MatchBannerBottomRow"; import { MatchBannerTimer } from "~/components/match-page/MatchBannerTimer"; import { MatchBannerTopRow } from "~/components/match-page/MatchBannerTopRow"; -import { MatchJoinTab } from "~/components/match-page/MatchJoinTab"; import { MatchPage } from "~/components/match-page/MatchPage"; import { MatchPageHeader } from "~/components/match-page/MatchPageHeader"; import { MatchResultTab } from "~/components/match-page/MatchResultTab"; @@ -96,6 +95,8 @@ export default function MatchPageTestRoute() { teamName: "Chimera", })} screenLegal={false} + joinPool="SQ7" + joinPass="8430" /> - - + 0 ? languages.join(",") : null, noScreen, - noSplatnet, }) .where("id", "=", userId) .execute(); diff --git a/app/features/scrims/components/ScrimMatchBanner.tsx b/app/features/scrims/components/ScrimMatchBanner.tsx index d34e8253f..79d914311 100644 --- a/app/features/scrims/components/ScrimMatchBanner.tsx +++ b/app/features/scrims/components/ScrimMatchBanner.tsx @@ -1,4 +1,3 @@ -import { sub } from "date-fns"; import { Ban, Swords } from "lucide-react"; import { useTranslation } from "react-i18next"; import { useLoaderData } from "react-router"; @@ -9,20 +8,14 @@ import { } from "~/components/match-page/MatchBanner"; import { MatchBannerScheduledTime } from "~/components/match-page/MatchBannerScheduledTime"; import { MatchBannerTopRow } from "~/components/match-page/MatchBannerTopRow"; -import { useUser } from "~/features/auth/core/user"; -import { resolveActiveRoomLink } from "~/features/chat/room-link-utils"; -import { - databaseTimestampToDate, - dateToDatabaseTimestamp, -} from "~/utils/dates"; +import { resolveRoomPass } from "~/components/match-page/utils"; +import { databaseTimestampToDate } from "~/utils/dates"; import * as Scrim from "../core/Scrim"; import type { loader } from "../loaders/scrims.$id.server"; -import { SCRIM } from "../scrims-constants"; export function ScrimMatchBanner() { const { t } = useTranslation(["scrims"]); const data = useLoaderData(); - const user = useUser(); const screenLegal = !data.anyUserPrefersNoScreen; @@ -45,17 +38,8 @@ export function ScrimMatchBanner() { ); } - const acceptedRequest = data.post.requests[0]; - const activeRoomLink = resolveActiveRoomLink({ - roomLinks: data.roomLinks, - freshnessCutoff: dateToDatabaseTimestamp( - sub(new Date(), { minutes: SCRIM.ROOM_LINK_FRESHNESS_MINUTES }), - ), - viewerUserId: user?.id, - members: [...data.post.users, ...acceptedRequest.users], - }); - const joinViaQr = Boolean(activeRoomLink.joinLink) && !activeRoomLink.isStale; const joinPool = Scrim.resolvePoolCode(data.post.id); + const joinPass = resolveRoomPass(data.post.id); const currentMap = data.mapByMap.currentMap; @@ -68,7 +52,7 @@ export function ScrimMatchBanner() { mode={currentMap.mode} screenLegal={screenLegal} joinPool={joinPool} - joinViaQr={joinViaQr} + joinPass={joinPass} /> ); @@ -83,7 +67,7 @@ export function ScrimMatchBanner() { subtitle={t("scrims:banner.freeForm.subtitle")} screenLegal={screenLegal} joinPool={joinPool} - joinViaQr={joinViaQr} + joinPass={joinPass} /> ); diff --git a/app/features/scrims/components/ScrimMatchTabs.tsx b/app/features/scrims/components/ScrimMatchTabs.tsx index 42c3aab67..c1dd4de13 100644 --- a/app/features/scrims/components/ScrimMatchTabs.tsx +++ b/app/features/scrims/components/ScrimMatchTabs.tsx @@ -1,59 +1,27 @@ -import { sub } from "date-fns"; import { useTranslation } from "react-i18next"; import { useLoaderData } from "react-router"; -import { MatchJoinTab } from "~/components/match-page/MatchJoinTab"; import { MatchResultTab } from "~/components/match-page/MatchResultTab"; import { MatchRosterTab } from "~/components/match-page/MatchRosterTab"; import { MatchTabs, TAB_KEYS } from "~/components/match-page/MatchTabs"; import type { TimelineMap } from "~/components/match-page/MatchTimeline"; -import { resolveRoomPass } from "~/components/match-page/utils"; -import { useUser } from "~/features/auth/core/user"; -import { - resolveActiveRoomLink, - useConfirmRoom, -} from "~/features/chat/room-link-utils"; -import { - databaseTimestampToJavascriptTimestamp, - dateToDatabaseTimestamp, -} from "~/utils/dates"; +import { databaseTimestampToJavascriptTimestamp } from "~/utils/dates"; import { teamPage } from "~/utils/urls"; import * as Scrim from "../core/Scrim"; import type { loader } from "../loaders/scrims.$id.server"; -import { SCRIM } from "../scrims-constants"; import type { ScrimPost } from "../scrims-types"; import { ScrimMatchActionTab } from "./ScrimMatchActionTab"; import { ScrimMatchStatsTab } from "./ScrimMatchStatsTab"; export function ScrimMatchTabs() { const { t } = useTranslation(["q"]); - const user = useUser(); const data = useLoaderData(); - const { onConfirmRoom, isConfirming } = useConfirmRoom(); const acceptedRequest = data.post.requests[0]; - const allMembers = [...data.post.users, ...acceptedRequest.users]; - - const activeRoomLink = resolveActiveRoomLink({ - roomLinks: data.roomLinks, - freshnessCutoff: dateToDatabaseTimestamp( - sub(new Date(), { minutes: SCRIM.ROOM_LINK_FRESHNESS_MINUTES }), - ), - viewerUserId: user?.id, - members: allMembers, - }); const tabs = resolveTabs(data); return ( - >) { const tabs: Array<(typeof TAB_KEYS)[keyof typeof TAB_KEYS]> = [ TAB_KEYS.ROSTERS, - TAB_KEYS.JOIN, ]; if (!data.mapByMap?.locked) { diff --git a/app/features/scrims/loaders/scrims.$id.server.ts b/app/features/scrims/loaders/scrims.$id.server.ts index fb5d45bf0..653f369cf 100644 --- a/app/features/scrims/loaders/scrims.$id.server.ts +++ b/app/features/scrims/loaders/scrims.$id.server.ts @@ -1,6 +1,5 @@ import type { LoaderFunctionArgs } from "react-router"; import { chatAccessible } from "~/features/chat/chat-utils"; -import * as RoomLinkRepository from "~/features/chat/RoomLinkRepository.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { databaseTimestampToDate } from "~/utils/dates"; import { notFoundIfFalsy } from "../../../utils/remix.server"; @@ -31,12 +30,8 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { const participantIds = Scrim.participantIdsListFromAccepted(post); - const [anyUserPrefersNoScreen, anyUserPrefersNoSplatnet, roomLinks] = - await Promise.all([ - UserRepository.anyUserPrefersNoScreen(participantIds), - UserRepository.anyUserPrefersNoSplatnet(participantIds), - RoomLinkRepository.findByUserIds(participantIds, 3), - ]); + const anyUserPrefersNoScreen = + await UserRepository.anyUserPrefersNoScreen(participantIds); const mapByMap = await resolveMapByMap({ post, user }); @@ -52,8 +47,6 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { ? post.chatCode : undefined, anyUserPrefersNoScreen, - anyUserPrefersNoSplatnet, - roomLinks, mapByMap, }; }; diff --git a/app/features/scrims/scrims-constants.ts b/app/features/scrims/scrims-constants.ts index cad03fa89..5d4c0d0ef 100644 --- a/app/features/scrims/scrims-constants.ts +++ b/app/features/scrims/scrims-constants.ts @@ -19,7 +19,6 @@ export const SCRIM = { CANCEL_REASON_MAX_LENGTH: 500, REQUEST_MESSAGE_MAX_LENGTH: 200, MAX_TIME_RANGE_MS: 3 * 60 * 60 * 1000, // 3 hours - ROOM_LINK_FRESHNESS_MINUTES: 30, AUTO_CANCEL_WINDOW_HOURS: 1, }; diff --git a/app/features/sendouq-match/components/SendouQMatchBanner.tsx b/app/features/sendouq-match/components/SendouQMatchBanner.tsx index f9138506f..d18605ebc 100644 --- a/app/features/sendouq-match/components/SendouQMatchBanner.tsx +++ b/app/features/sendouq-match/components/SendouQMatchBanner.tsx @@ -15,8 +15,8 @@ import { MatchBannerBottomRow } from "~/components/match-page/MatchBannerBottomR import { MatchBannerStartedAt } from "~/components/match-page/MatchBannerStartedAt"; import { MatchBannerTimer } from "~/components/match-page/MatchBannerTimer"; import { MatchBannerTopRow } from "~/components/match-page/MatchBannerTopRow"; +import { resolveRoomPass } from "~/components/match-page/utils"; import { useUser } from "~/features/auth/core/user"; -import { resolveActiveRoomLink } from "~/features/chat/room-link-utils"; import { SENDOUQ_BEST_OF } from "~/features/sendouq/q-constants"; import { useAutoRerender } from "~/hooks/useAutoRerender"; import { databaseTimestampToDate } from "~/utils/dates"; @@ -90,16 +90,7 @@ export function SendouQMatchBanner({ data }: { data: SendouQMatchLoaderData }) { ); const joinPool = isParticipant ? `SQ${String(data.match.id).at(-1)}` : null; - const activeRoomLink = resolveActiveRoomLink({ - roomLinks: data.roomLinks, - freshnessCutoff: data.match.createdAt, - viewerUserId: user?.id, - members: [ - ...data.match.groupAlpha.members, - ...data.match.groupBravo.members, - ], - }); - const joinViaQr = Boolean(activeRoomLink.joinLink) && !activeRoomLink.isStale; + const joinPass = isParticipant ? resolveRoomPass(data.match.id) : null; return ( @@ -112,7 +103,7 @@ export function SendouQMatchBanner({ data }: { data: SendouQMatchLoaderData }) { teamName: cancelRequesterName, })} joinPool={joinPool} - joinViaQr={joinViaQr} + joinPass={joinPass} /> ) : ( diff --git a/app/features/sendouq-match/components/SendouQMatchTabs.tsx b/app/features/sendouq-match/components/SendouQMatchTabs.tsx index e9aa32c3a..b0a9a6ad6 100644 --- a/app/features/sendouq-match/components/SendouQMatchTabs.tsx +++ b/app/features/sendouq-match/components/SendouQMatchTabs.tsx @@ -1,15 +1,9 @@ import { useTranslation } from "react-i18next"; import { useNavigate, useSearchParams } from "react-router"; -import { MatchJoinTab } from "~/components/match-page/MatchJoinTab"; import { MatchResultTab } from "~/components/match-page/MatchResultTab"; import { MatchRosterTab } from "~/components/match-page/MatchRosterTab"; import { MatchTabs } from "~/components/match-page/MatchTabs"; -import { resolveRoomPass } from "~/components/match-page/utils"; import { useUser } from "~/features/auth/core/user"; -import { - resolveActiveRoomLink, - useConfirmRoom, -} from "~/features/chat/room-link-utils"; import { ACTION_TAB_AFTER_LOCKED_SECONDS } from "~/features/sendouq/q-constants"; import { useHasRole } from "~/modules/permissions/hooks"; import { databaseTimestampNow } from "~/utils/dates"; @@ -28,7 +22,6 @@ import { SendouQMatchActionTab } from "./SendouQMatchActionTab"; export function SendouQMatchTabs({ data }: { data: SendouQMatchLoaderData }) { const user = useUser(); const isStaff = useHasRole("STAFF"); - const { onConfirmRoom, isConfirming } = useConfirmRoom(); const [searchParams] = useSearchParams(); const navigate = useNavigate(); const { t } = useTranslation(["q"]); @@ -90,8 +83,7 @@ export function SendouQMatchTabs({ data }: { data: SendouQMatchLoaderData }) { reporterSide !== null && reporterSide !== userSide; - const tabs: Array<"join" | "rosters" | "action" | "result"> = ["rosters"]; - if (!isLocked && isParticipant) tabs.push("join"); + const tabs: Array<"rosters" | "action" | "result"> = ["rosters"]; if (showActionTab) tabs.push("action"); if (isLocked || hasReportedMaps) tabs.push("result"); @@ -99,18 +91,6 @@ export function SendouQMatchTabs({ data }: { data: SendouQMatchLoaderData }) { ? ["action"] : undefined; - const allMembers = [ - ...data.match.groupAlpha.members, - ...data.match.groupBravo.members, - ]; - - const activeRoomLink = resolveActiveRoomLink({ - roomLinks: data.roomLinks, - freshnessCutoff: data.match.createdAt, - viewerUserId: user?.id, - members: allMembers, - }); - const ownGroup = userSide === "ALPHA" ? data.match.groupAlpha @@ -146,16 +126,6 @@ export function SendouQMatchTabs({ data }: { data: SendouQMatchLoaderData }) { ) : null} ) : null} - {!isLocked && isParticipant ? ( - - ) : null} { const isStaff = user?.roles.includes("STAFF") ?? false; const isParticipant = Boolean(user && matchUsers.includes(user.id)); - const canSeeRoomLinks = isStaff || isParticipant; - const [privateNotes, roomLinks, anyUserPrefersNoSplatnet, reportedWeapons] = - await Promise.all([ - user ? PrivateUserNoteRepository.ownNotes(matchUsers) : undefined, - canSeeRoomLinks ? RoomLinkRepository.findByUserIds(matchUsers, 3) : [], - UserRepository.anyUserPrefersNoSplatnet(matchUsers), - ReportedWeaponRepository.findByMatchId(matchId), - ]); + const [privateNotes, reportedWeapons] = await Promise.all([ + user ? PrivateUserNoteRepository.ownNotes(matchUsers) : undefined, + ReportedWeaponRepository.findByMatchId(matchId), + ]); const match = SendouQ.mapMatch(matchUnmapped, user, privateNotes); return { match, - roomLinks, - anyUserPrefersNoSplatnet, reportedWeapons, isOffSeason: Seasons.current() === null, chatCode: (() => { diff --git a/app/features/settings/actions/settings.server.ts b/app/features/settings/actions/settings.server.ts index 8dfff3bcb..0ebd013d2 100644 --- a/app/features/settings/actions/settings.server.ts +++ b/app/features/settings/actions/settings.server.ts @@ -58,12 +58,6 @@ export const action = async ({ request }: ActionFunctionArgs) => { }); break; } - case "UPDATE_DEFAULT_MATCH_PAGE_TAB": { - await UserRepository.updateOwnPreferences({ - defaultMatchPageTab: data.newValue, - }); - break; - } case "UPDATE_MATCH_PROFILE": { await MatchProfileRepository.updateOwnMatchProfile({ mapModePreferences: data.mapModePreferences, @@ -71,7 +65,6 @@ export const action = async ({ request }: ActionFunctionArgs) => { languages: data.languages, weaponPool: data.weaponPool, noScreen: Number(data.noScreen), - noSplatnet: Number(data.noSplatnet), }); break; } diff --git a/app/features/settings/components/MatchProfileTab.tsx b/app/features/settings/components/MatchProfileTab.tsx index 4ac054cd2..5fe9eaf4d 100644 --- a/app/features/settings/components/MatchProfileTab.tsx +++ b/app/features/settings/components/MatchProfileTab.tsx @@ -30,7 +30,6 @@ export function MatchProfileTab() { vc: matchProfile.vc ?? "NO", languages: matchProfile.languages ?? [], noScreen: Boolean(matchProfile.noScreen), - noSplatnet: Boolean(matchProfile.noSplatnet), }} revalidateRoot > @@ -50,7 +49,6 @@ export function MatchProfileTab() { - )} diff --git a/app/features/settings/components/PreferencesTab.tsx b/app/features/settings/components/PreferencesTab.tsx index 0c46f2b01..9e76aa89c 100644 --- a/app/features/settings/components/PreferencesTab.tsx +++ b/app/features/settings/components/PreferencesTab.tsx @@ -9,7 +9,6 @@ import { Config } from "~/config"; import { useUser } from "~/features/auth/core/user"; import { SendouForm } from "~/form/SendouForm"; import { - defaultMatchPageTabSchema, disableBuildAbilitySortingSchema, disallowScrimPickupsFromUntrustedSchema, spoilerFreeModeSchema, @@ -58,18 +57,6 @@ export function PreferencesTab() { > {({ FormField }) => } - - {({ FormField }) => } - ); diff --git a/app/features/settings/match-profile-schemas.ts b/app/features/settings/match-profile-schemas.ts index c49c2dfcb..fd93fcf18 100644 --- a/app/features/settings/match-profile-schemas.ts +++ b/app/features/settings/match-profile-schemas.ts @@ -65,10 +65,6 @@ export const updateMatchProfileSchema = z.object({ label: "labels.languages", items: LANGUAGE_OPTIONS, }), - noSplatnet: toggle({ - label: "labels.noSplatnet", - bottomText: "bottomTexts.noScreen", - }), noScreen: toggle({ label: "labels.noScreen", bottomText: "bottomTexts.noScreen", diff --git a/app/features/settings/settings-schemas.ts b/app/features/settings/settings-schemas.ts index 2a0227740..538a8380a 100644 --- a/app/features/settings/settings-schemas.ts +++ b/app/features/settings/settings-schemas.ts @@ -1,11 +1,5 @@ import { z } from "zod"; -import { - customField, - radioGroup, - select, - stringConstant, - toggle, -} from "~/form/fields"; +import { customField, select, stringConstant, toggle } from "~/form/fields"; import { themeInputSchema } from "~/utils/zod"; const customThemeSchema = z.object({ @@ -54,18 +48,6 @@ const weaponReportDefaultOpenSchema = z.object({ newValue: z.boolean(), }); -export const defaultMatchPageTabSchema = z.object({ - _action: stringConstant("UPDATE_DEFAULT_MATCH_PAGE_TAB"), - newValue: radioGroup({ - label: "labels.defaultMatchPageTab", - items: [ - { value: "rosters", label: "options.defaultMatchPageTab.rosters" }, - { value: "join", label: "options.defaultMatchPageTab.join" }, - { value: "action", label: "options.defaultMatchPageTab.action" }, - ], - }), -}); - export const settingsEditSchema = z.union([ customThemeSchema, disableBuildAbilitySortingSchema, @@ -73,5 +55,4 @@ export const settingsEditSchema = z.union([ spoilerFreeModeSchema, clockFormatSchema, weaponReportDefaultOpenSchema, - defaultMatchPageTabSchema, ]); diff --git a/app/features/tournament-match/components/TournamentMatchBanner.tsx b/app/features/tournament-match/components/TournamentMatchBanner.tsx index f026c2d7b..eab4f8d17 100644 --- a/app/features/tournament-match/components/TournamentMatchBanner.tsx +++ b/app/features/tournament-match/components/TournamentMatchBanner.tsx @@ -55,10 +55,8 @@ export function TournamentMatchBanner({ teamsMissingActiveRoster, matchIsLocked, joinPool, - activeRoomLink, + joinPass, } = useMatch(); - const joinViaQr = - Boolean(activeRoomLink?.joinLink) && !activeRoomLink?.isStale; const opponentOne = data.match.opponentOne; const opponentTwo = data.match.opponentTwo; @@ -152,7 +150,7 @@ export function TournamentMatchBanner({ })} screenLegal={screenLegal} joinPool={joinPool} - joinViaQr={joinViaQr} + joinPass={joinPass} testId="active-roster-needed-text" /> ) : pickBanBanner ? ( @@ -162,7 +160,7 @@ export function TournamentMatchBanner({ subtitle={pickBanBanner.subtitle} screenLegal={screenLegal} joinPool={joinPool} - joinViaQr={joinViaQr} + joinPass={joinPass} /> ) : currentMap ? ( 0} /> ) : null} - {tabs.includes(TAB_KEYS.JOIN) ? ( - - ) : null} {tabs.includes(TAB_KEYS.ACTION) ? ( isPickBanStep && turnOfResult ? ( @@ -312,30 +306,6 @@ function slotOfEvent({ } } -function TournamentMatchJoinTab({ data }: { data: TournamentMatchLoaderData }) { - const { onConfirmRoom, isConfirming } = useConfirmRoom(); - const { - teams: [teamOne, teamTwo], - joinPool, - activeRoomLink, - } = useMatch(); - if (!teamOne || !teamTwo || !joinPool || !activeRoomLink) return null; - - const hostingTeam = resolveHostingTeam([teamOne, teamTwo]); - - return ( - - ); -} - function TournamentMatchRosterTab({ data, }: { @@ -351,6 +321,9 @@ function TournamentMatchRosterTab({ const tbdTeam = { defaultName: t("tournament:match.tbd"), members: [] }; + const hostingTeamId = + teamOne && teamTwo ? resolveHostingTeam([teamOne, teamTwo]).id : null; + return ( { (isParticipant || tournament.isOrganizerOrStreamer(user)) && !isLeagueRoundLocked(tournament, match.roundId); - const [roomLinks, anyUserPrefersNoSplatnet] = canJoin - ? await Promise.all([ - RoomLinkRepository.findByUserIds( - match.players.map((p) => p.id), - 3, - ), - UserRepository.anyUserPrefersNoSplatnet(match.players.map((p) => p.id)), - ]) - : ([[], false] as const); - return { match: hasPermsToSeeChat ? match : { ...match, chatCode: undefined }, results, @@ -238,8 +227,6 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { noScreen, chatCode: visibleChatCode, canJoin, - roomLinks, - anyUserPrefersNoSplatnet, pickBanEventCount: pickBanEvents.length, pickBanEvents: pickBanEvents.map((e) => ({ type: e.type, diff --git a/app/features/tournament-match/match-page-context.tsx b/app/features/tournament-match/match-page-context.tsx index 226ff6cb2..72e5c586e 100644 --- a/app/features/tournament-match/match-page-context.tsx +++ b/app/features/tournament-match/match-page-context.tsx @@ -1,7 +1,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 { resolveActiveRoomLink } from "~/features/chat/room-link-utils"; import { useTournament } from "~/features/tournament/routes/to.$id"; import { isLeagueRoundLocked } from "~/features/tournament/tournament-utils"; import * as PickBan from "~/features/tournament-bracket/core/PickBan"; @@ -13,8 +13,6 @@ import { import type { TournamentMatchLoaderData } from "./loaders/to.$id.matches.$mid.server"; import { matchIsLocked, resolveHostingTeam } from "./tournament-match-utils"; -type ActiveRoomLink = ReturnType; - export type MatchPageTeam = NonNullable>; export type MatchTabKey = (typeof TAB_KEYS)[keyof typeof TAB_KEYS]; @@ -35,7 +33,7 @@ type MatchPageContextValue = { isPickBanStep: boolean; matchIsLocked: boolean; joinPool: string | null; - activeRoomLink: ActiveRoomLink | null; + joinPass: string | null; }; const MatchPageContext = React.createContext( @@ -101,16 +99,7 @@ export function MatchPageProvider({ scores, }); - const joinPool = resolveJoinPool({ tournament, data, teams }); - - const activeRoomLink = data.canJoin - ? resolveActiveRoomLink({ - roomLinks: data.roomLinks, - freshnessCutoff: data.match.startedAt ?? 0, - viewerUserId: user?.id, - members: data.match.players, - }) - : null; + const joinInfo = resolveJoinInfo({ tournament, data, teams }); const tabs = resolveVisibleTabs({ canReportScore: tournament.canReportScore({ @@ -119,7 +108,6 @@ export function MatchPageProvider({ }), canReportWeapons: isParticipant && tournament.weaponReportingOpen && hasReportedMaps, - canJoin: data.canJoin, hasCurrentMap: Boolean(currentMap), hasMissingActiveRoster: teamsMissingActiveRoster.length > 0, hasReportedMaps, @@ -144,8 +132,8 @@ export function MatchPageProvider({ turnOfResult, isPickBanStep, matchIsLocked: lockedForCast, - joinPool, - activeRoomLink, + joinPool: joinInfo?.pool ?? null, + joinPass: joinInfo?.pass ?? null, }} > {children} @@ -164,7 +152,6 @@ export function useMatch() { function resolveVisibleTabs({ canReportScore, canReportWeapons, - canJoin, hasCurrentMap, hasMissingActiveRoster, hasReportedMaps, @@ -176,7 +163,6 @@ function resolveVisibleTabs({ }: { canReportScore: boolean; canReportWeapons: boolean; - canJoin: boolean; hasCurrentMap: boolean; hasMissingActiveRoster: boolean; hasReportedMaps: boolean; @@ -188,9 +174,6 @@ function resolveVisibleTabs({ }): MatchTabKey[] { const tabs: MatchTabKey[] = [TAB_KEYS.ROSTERS]; - if (canJoin) { - tabs.push(TAB_KEYS.JOIN); - } if ( !leagueRoundLocked && (isPickBanStep || @@ -214,7 +197,7 @@ function resolveVisibleTabs({ return tabs; } -function resolveJoinPool({ +function resolveJoinInfo({ tournament, data, teams, @@ -222,7 +205,7 @@ function resolveJoinPool({ tournament: ReturnType; data: TournamentMatchLoaderData; teams: [MatchPageTeam | null, MatchPageTeam | null]; -}): string | null { +}): { pool: string; pass: string } | null { if (!data.canJoin) return null; const [teamOne, teamTwo] = teams; @@ -254,7 +237,10 @@ function resolveJoinPool({ : undefined, }); - return `${poolCode.prefix}${poolCode.suffix}`; + return { + pool: `${poolCode.prefix}${poolCode.suffix}`, + pass: resolveRoomPass(hostingTeam.id), + }; } function resolveTeamsMissingActiveRoster( diff --git a/app/features/user-page/UserRepository.server.ts b/app/features/user-page/UserRepository.server.ts index f30d4a58b..a850da84c 100644 --- a/app/features/user-page/UserRepository.server.ts +++ b/app/features/user-page/UserRepository.server.ts @@ -1312,21 +1312,6 @@ export async function anyUserPrefersNoScreen( return Boolean(result); } -export async function anyUserPrefersNoSplatnet( - userIds: number[], -): Promise { - if (userIds.length === 0) return false; - - const result = await db - .selectFrom("User") - .select("User.noSplatnet") - .where("User.id", "in", userIds) - .where("User.noSplatnet", "=", 1) - .executeTakeFirst(); - - return Boolean(result); -} - export async function socialLinksByUserId(userId: number) { const user = await db .selectFrom("User") diff --git a/app/routes.ts b/app/routes.ts index d90b64654..0e3395c83 100644 --- a/app/routes.ts +++ b/app/routes.ts @@ -272,7 +272,6 @@ export default [ route("/admin", "features/admin/routes/admin.tsx"), route("/admin/streams", "features/admin/routes/admin.streams.tsx"), route("/api/chat-users", "features/chat/routes/api.chat-users.ts"), - route("/room", "features/chat/routes/room.ts"), route("/api", "features/api/routes/api.tsx"), ...prefix("/a", [ diff --git a/app/routines/deleteOldRoomLinks.ts b/app/routines/deleteOldRoomLinks.ts deleted file mode 100644 index e58f701c4..000000000 --- a/app/routines/deleteOldRoomLinks.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as RoomLinkRepository from "../features/chat/RoomLinkRepository.server"; -import { logger } from "../utils/logger"; -import { Routine } from "./routine.server"; - -export const DeleteOldRoomLinksRoutine = new Routine({ - name: "DeleteOldRoomLinks", - func: async () => { - const { numDeletedRows } = await RoomLinkRepository.deleteOld(); - logger.info(`Deleted ${numDeletedRows} old room links`); - }, -}); diff --git a/app/routines/list.server.ts b/app/routines/list.server.ts index 4ad57e7da..900e032ea 100644 --- a/app/routines/list.server.ts +++ b/app/routines/list.server.ts @@ -3,7 +3,6 @@ import { CloseExpiredContinueVotesRoutine } from "./closeExpiredContinueVotes"; import { DeleteObsoleteMatchVodsRoutine } from "./deleteObsoleteMatchVods"; import { DeleteOldExternalStreamsRoutine } from "./deleteOldExternalStreams"; import { DeleteOldNotificationsRoutine } from "./deleteOldNotifications"; -import { DeleteOldRoomLinksRoutine } from "./deleteOldRoomLinks"; import { DeleteOldTournamentAuditLogsRoutine } from "./deleteOldTournamentAuditLogs"; import { DeleteOrphanArtTagsRoutine } from "./deleteOrphanArtTags"; import { NotifyCheckInStartRoutine } from "./notifyCheckInStart"; @@ -32,7 +31,6 @@ export const everyHourAt30 = [ SetOldGroupsAsInactiveRoutine, UpdatePatreonDataRoutine, CloseExpiredContinueVotesRoutine, - DeleteOldRoomLinksRoutine, DeleteOldExternalStreamsRoutine, ]; diff --git a/db-test.sqlite3 b/db-test.sqlite3 index a892ccf06..418efb00b 100644 Binary files a/db-test.sqlite3 and b/db-test.sqlite3 differ diff --git a/e2e/helpers/tournament-match.ts b/e2e/helpers/tournament-match.ts index 2d036620c..67bc8ee18 100644 --- a/e2e/helpers/tournament-match.ts +++ b/e2e/helpers/tournament-match.ts @@ -33,12 +33,11 @@ const TAB_LABELS = { admin: "Admin", result: "Result", rosters: "Rosters", - join: "Join", } as const; export const goToTab = async ( page: Page, - tab: "action" | "admin" | "result" | "rosters" | "join", + tab: "action" | "admin" | "result" | "rosters", ) => { // When teams have more members than the minimum, the action tab is hidden // until each team's active roster is locked in via the rosters tab. Auto-set diff --git a/e2e/seeds/db-seed-AB_RR.sqlite3 b/e2e/seeds/db-seed-AB_RR.sqlite3 index f0308e405..b9a83bf95 100644 Binary files a/e2e/seeds/db-seed-AB_RR.sqlite3 and b/e2e/seeds/db-seed-AB_RR.sqlite3 differ diff --git a/e2e/seeds/db-seed-DEFAULT.sqlite3 b/e2e/seeds/db-seed-DEFAULT.sqlite3 index 50e1cb3e5..3548178d8 100644 Binary files a/e2e/seeds/db-seed-DEFAULT.sqlite3 and b/e2e/seeds/db-seed-DEFAULT.sqlite3 differ diff --git a/e2e/seeds/db-seed-FINALIZED_BRACKET.sqlite3 b/e2e/seeds/db-seed-FINALIZED_BRACKET.sqlite3 index 9389e6b4c..293218a1e 100644 Binary files a/e2e/seeds/db-seed-FINALIZED_BRACKET.sqlite3 and b/e2e/seeds/db-seed-FINALIZED_BRACKET.sqlite3 differ diff --git a/e2e/seeds/db-seed-IN_SQ_MATCH.sqlite3 b/e2e/seeds/db-seed-IN_SQ_MATCH.sqlite3 index 86f33e846..754722b81 100644 Binary files a/e2e/seeds/db-seed-IN_SQ_MATCH.sqlite3 and b/e2e/seeds/db-seed-IN_SQ_MATCH.sqlite3 differ diff --git a/e2e/seeds/db-seed-NO_SCRIMS.sqlite3 b/e2e/seeds/db-seed-NO_SCRIMS.sqlite3 index a546fa2ab..1a2cdfc4f 100644 Binary files a/e2e/seeds/db-seed-NO_SCRIMS.sqlite3 and b/e2e/seeds/db-seed-NO_SCRIMS.sqlite3 differ diff --git a/e2e/seeds/db-seed-NO_SQ_GROUPS.sqlite3 b/e2e/seeds/db-seed-NO_SQ_GROUPS.sqlite3 index f30434fc2..fb604254f 100644 Binary files a/e2e/seeds/db-seed-NO_SQ_GROUPS.sqlite3 and b/e2e/seeds/db-seed-NO_SQ_GROUPS.sqlite3 differ diff --git a/e2e/seeds/db-seed-NO_TOURNAMENT_TEAMS.sqlite3 b/e2e/seeds/db-seed-NO_TOURNAMENT_TEAMS.sqlite3 index 57da51081..8ee2b9734 100644 Binary files a/e2e/seeds/db-seed-NO_TOURNAMENT_TEAMS.sqlite3 and b/e2e/seeds/db-seed-NO_TOURNAMENT_TEAMS.sqlite3 differ diff --git a/e2e/seeds/db-seed-NZAP_IN_TEAM.sqlite3 b/e2e/seeds/db-seed-NZAP_IN_TEAM.sqlite3 index 8b4aac003..622b5ab61 100644 Binary files a/e2e/seeds/db-seed-NZAP_IN_TEAM.sqlite3 and b/e2e/seeds/db-seed-NZAP_IN_TEAM.sqlite3 differ diff --git a/e2e/seeds/db-seed-REG_OPEN.sqlite3 b/e2e/seeds/db-seed-REG_OPEN.sqlite3 index 15004ba87..e416d258a 100644 Binary files a/e2e/seeds/db-seed-REG_OPEN.sqlite3 and b/e2e/seeds/db-seed-REG_OPEN.sqlite3 differ diff --git a/e2e/seeds/db-seed-SMALL_SOS.sqlite3 b/e2e/seeds/db-seed-SMALL_SOS.sqlite3 index 38d3cdc10..e98a2cb1d 100644 Binary files a/e2e/seeds/db-seed-SMALL_SOS.sqlite3 and b/e2e/seeds/db-seed-SMALL_SOS.sqlite3 differ diff --git a/e2e/seeds/db-seed-TEAM_MAP_PREFS.sqlite3 b/e2e/seeds/db-seed-TEAM_MAP_PREFS.sqlite3 index 75dbe8d7d..ab0c9c3ad 100644 Binary files a/e2e/seeds/db-seed-TEAM_MAP_PREFS.sqlite3 and b/e2e/seeds/db-seed-TEAM_MAP_PREFS.sqlite3 differ diff --git a/e2e/tournament-staff.spec.ts b/e2e/tournament-staff.spec.ts index 095e6eca1..5f46843ac 100644 --- a/e2e/tournament-staff.spec.ts +++ b/e2e/tournament-staff.spec.ts @@ -12,7 +12,6 @@ import { startBracket, test, } from "./helpers/playwright"; -import { goToTab } from "./helpers/tournament-match"; const TOURNAMENT_ID = 2; @@ -146,8 +145,6 @@ test.describe("Tournament staff", () => { url: tournamentMatchPage({ tournamentId: TOURNAMENT_ID, matchId: 2 }), }); - await goToTab(page, "join"); - await expect(roomPassSelector).toBeVisible(); }); }); diff --git a/locales/da/common.json b/locales/da/common.json index e53cb14ba..9c59f19a4 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "Bliv medlem", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/da/forms.json b/locales/da/forms.json index e69f9028c..640b862c7 100644 --- a/locales/da/forms.json +++ b/locales/da/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Note: Hvis du ændrer dit holds navn, så kan andre hold overtage det tidligere holdnavn og URL-adresse.", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Kaptajn", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "Frontlinje", diff --git a/locales/da/q.json b/locales/da/q.json index 0e75faffc..2e81beef1 100644 --- a/locales/da/q.json +++ b/locales/da/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/de/common.json b/locales/de/common.json index cac577848..ce8b00696 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "Beitreten", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/de/forms.json b/locales/de/forms.json index 89220859c..ec36e3319 100644 --- a/locales/de/forms.json +++ b/locales/de/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Hinweis: Wenn du den Namen deines Teams änderst, können andere Teams den Namen und und die URL für sich beanspruchen.", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Kapitän", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "Frontline", diff --git a/locales/de/q.json b/locales/de/q.json index 6d01eb6e6..7a5d278aa 100644 --- a/locales/de/q.json +++ b/locales/de/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/en/common.json b/locales/en/common.json index c93bcf0df..3ee0a49c7 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -139,6 +139,7 @@ "actions.outlined": "Outlined", "actions.noOutline": "No outline", "actions.join": "Join", + "host": "Host", "actions.nevermind": "Nevermind", "actions.clickHere": "Click here", "actions.goBack": "Go back", diff --git a/locales/en/forms.json b/locales/en/forms.json index 5d613694f..315dd0378 100644 --- a/locales/en/forms.json +++ b/locales/en/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "Custom role", "labels.teamMemberRoleType": "Role type", "labels.clockFormat": "Clock format", - "labels.defaultMatchPageTab": "Default match page tab", "labels.disableBuildAbilitySorting": "Builds: Disable automatic ability sorting", "labels.disallowScrimPickupsFromUntrusted": "Disallow scrim pickups from non-friends", "labels.noScreen": "[Accessibility] Avoid Splattercolor Screen", - "labels.noSplatnet": "No SplatNet access", "labels.spoilerFreeMode": "Spoiler-free mode", "bottomTexts.imageModeration": "Unless you're a Supporter, newly uploaded images are shown publicly only after a moderator has checked them.", "bottomTexts.name": "Note that if you change your team's name then someone else can claim the name and URL for their team", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "Automatic", "options.clockFormat.24h": "24-hour", "options.clockFormat.12h": "12-hour", - "options.defaultMatchPageTab.rosters": "Rosters", - "options.defaultMatchPageTab.join": "Join", - "options.defaultMatchPageTab.action": "Action", "options.teamMemberRole.CAPTAIN": "Captain", "options.teamMemberRole.CO_CAPTAIN": "Co-Captain", "options.teamMemberRole.FRONTLINE": "Frontline", diff --git a/locales/en/q.json b/locales/en/q.json index 2bf6f9529..0c4fd6bcb 100644 --- a/locales/en/q.json +++ b/locales/en/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "Pool", "match.password.short": "Pass", - "match.hostedBy": "Hosted by", - "match.noSplatnetWarning": "One or more players don't have Splatnet, remember to use the pool and pass", - "match.room.noRoomHint": "Send the SplatNet room link to the chat or use the Share feature in the SplatNet3 app", - "match.room.stalePrompt": "Your room from {{minutes}} minutes ago still up?", - "match.room.confirm": "Confirm", "match.cancelMatch": "Cancel match", "match.canceled": "Match canceled", "match.canceled.detail": "Set was canceled as requested by {{requester}} and accepted by {{accepter}}", diff --git a/locales/es-ES/common.json b/locales/es-ES/common.json index 33b69ebdf..3f87f70b3 100644 --- a/locales/es-ES/common.json +++ b/locales/es-ES/common.json @@ -139,6 +139,7 @@ "actions.outlined": "Con borde", "actions.noOutline": "Sin borde", "actions.join": "Unirse", + "host": "", "actions.nevermind": "Olvídalo", "actions.clickHere": "Haz clic aquí", "actions.goBack": "Volver atrás", diff --git a/locales/es-ES/forms.json b/locales/es-ES/forms.json index fcba8079e..34f93f800 100644 --- a/locales/es-ES/forms.json +++ b/locales/es-ES/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "Formato de hora", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "Builds: Desactivar orden automático de potenciadores", "labels.disallowScrimPickupsFromUntrusted": "No permitir invitaciones de usuarios no verificados", "labels.noScreen": "[Accesibilidad] Evitar Pantintalla", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Nota que si cambias el nombre de tu equipo, el nombre y la URL estarán libres para que otro equipo los tome", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "Automático", "options.clockFormat.24h": "24 horas", "options.clockFormat.12h": "12 horas", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Capitán", "options.teamMemberRole.CO_CAPTAIN": "Co-Capitán", "options.teamMemberRole.FRONTLINE": "Delantero", diff --git a/locales/es-ES/q.json b/locales/es-ES/q.json index 6a836902a..f143d1ad9 100644 --- a/locales/es-ES/q.json +++ b/locales/es-ES/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "Grupo", "match.password.short": "Codigo", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "Cancelar partido", "match.canceled": "Partido cancelado", "match.canceled.detail": "", diff --git a/locales/es-US/common.json b/locales/es-US/common.json index 3feaea1b2..a139e3ec3 100644 --- a/locales/es-US/common.json +++ b/locales/es-US/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "Unirse", + "host": "", "actions.nevermind": "Cancelar", "actions.clickHere": "Haga click aquí", "actions.goBack": "Volver", diff --git a/locales/es-US/forms.json b/locales/es-US/forms.json index 3f7693d09..5c718f7e6 100644 --- a/locales/es-US/forms.json +++ b/locales/es-US/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Nota que si cambias el nombre de tu equipo, el nombre y la URL estarán libres para que otro equipo los tome", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Capitán", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "Delantero", diff --git a/locales/es-US/q.json b/locales/es-US/q.json index 6510854c8..b36fe2b9b 100644 --- a/locales/es-US/q.json +++ b/locales/es-US/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "Canal", "match.password.short": "Contraseña", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "Cancelar partido", "match.canceled": "Partido cancelado", "match.canceled.detail": "", diff --git a/locales/fr-CA/common.json b/locales/fr-CA/common.json index 904c3f02e..c9279702c 100644 --- a/locales/fr-CA/common.json +++ b/locales/fr-CA/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "Joindre", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/fr-CA/forms.json b/locales/fr-CA/forms.json index 8ae17aa56..98b6080f3 100644 --- a/locales/fr-CA/forms.json +++ b/locales/fr-CA/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Veuillez noter que si vous changer le nom de l'équipe, quelqu'un d'autre pourra s'emparer de l'ancien nom et URL", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Capitaine", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "Frontline", diff --git a/locales/fr-CA/q.json b/locales/fr-CA/q.json index c3ad7af21..20594e403 100644 --- a/locales/fr-CA/q.json +++ b/locales/fr-CA/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/fr-EU/common.json b/locales/fr-EU/common.json index d106db226..201a15049 100644 --- a/locales/fr-EU/common.json +++ b/locales/fr-EU/common.json @@ -139,6 +139,7 @@ "actions.outlined": "Outlined", "actions.noOutline": "No outline", "actions.join": "Joindre", + "host": "", "actions.nevermind": "Laisser tomber", "actions.clickHere": "Click ici", "actions.goBack": "Retourner en arrière", diff --git a/locales/fr-EU/forms.json b/locales/fr-EU/forms.json index 1c61bf359..c27d8ebb0 100644 --- a/locales/fr-EU/forms.json +++ b/locales/fr-EU/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Veuillez noter que si vous changer le nom de l'équipe, quelqu'un d'autre pourra s'emparer de l'ancien nom et URL", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Capitaine", "options.teamMemberRole.CO_CAPTAIN": "Co-capitaine", "options.teamMemberRole.FRONTLINE": "Frontline", diff --git a/locales/fr-EU/q.json b/locales/fr-EU/q.json index 5cd0057e0..d9ddc4631 100644 --- a/locales/fr-EU/q.json +++ b/locales/fr-EU/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "Canal", "match.password.short": "Mot de passe", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "Annuler match", "match.canceled": "Match annulé", "match.canceled.detail": "", diff --git a/locales/he/common.json b/locales/he/common.json index c39bdb5ef..39c01a2b9 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "הצטרפות", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/he/forms.json b/locales/he/forms.json index d19fc5536..43cafd36e 100644 --- a/locales/he/forms.json +++ b/locales/he/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "שימו לב שאם תשנו את שם הצוות שלכם, מישהו אחר יוכל לקחת בעלות על השם ועל כתובת האתר עבור הצוות שלו", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "קפטן", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "קו החזית", diff --git a/locales/he/q.json b/locales/he/q.json index f407e1637..08ac739b4 100644 --- a/locales/he/q.json +++ b/locales/he/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/it/common.json b/locales/it/common.json index ed3fd6142..21e7e38d5 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -139,6 +139,7 @@ "actions.outlined": "Contornato", "actions.noOutline": "Nessun contorno", "actions.join": "Entra", + "host": "", "actions.nevermind": "Non importa", "actions.clickHere": "Clicca qui", "actions.goBack": "Indietro", diff --git a/locales/it/forms.json b/locales/it/forms.json index 1097000b1..2d1879109 100644 --- a/locales/it/forms.json +++ b/locales/it/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Nota che se cambi il nome del team, qualcun altro può assumere nome e URL per il proprio team", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Capitano", "options.teamMemberRole.CO_CAPTAIN": "Co-Capitano", "options.teamMemberRole.FRONTLINE": "Frontline", diff --git a/locales/it/q.json b/locales/it/q.json index 4a5a092a2..eee424804 100644 --- a/locales/it/q.json +++ b/locales/it/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "Pool", "match.password.short": "Pass", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "Cancella match", "match.canceled": "Match cancellato", "match.canceled.detail": "", diff --git a/locales/ja/badges.json b/locales/ja/badges.json index 2f3806bf8..d237da1bd 100644 --- a/locales/ja/badges.json +++ b/locales/ja/badges.json @@ -2,8 +2,7 @@ "patreon": "Patreon での sendou.ink サポーター", "patreon+": "Patoreon での sendou.ink サポーター+", "xp": "{{xpText}} に到達したことで獲得", - "tournament_one": "{{tournament}}を勝利したことで獲得", - "tournament_other": "{{tournament}}を(×{{count}})回勝利したことで獲得", + "tournament": "{{tournament}}を勝利したことで獲得", "forYourEvent": "イベント専用のバッジ?", "managedBy": "<0> によって管理されています", "madeBy": "製作者: <0>", diff --git a/locales/ja/common.json b/locales/ja/common.json index 485cc4c9e..655b0b8a0 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -139,6 +139,7 @@ "actions.outlined": "アウトラインあり", "actions.noOutline": "アウトラインなし", "actions.join": "参加する", + "host": "", "actions.nevermind": "やーめた", "actions.clickHere": "ここをクリック", "actions.goBack": "戻る", diff --git a/locales/ja/forms.json b/locales/ja/forms.json index c3cc9328a..6af7634ea 100644 --- a/locales/ja/forms.json +++ b/locales/ja/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "注意: チーム名を変更した場合、他のプレイヤーが変更前の名前と URL を別のチームのために使用することができるようになります。", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "キャプテン", "options.teamMemberRole.CO_CAPTAIN": "キャプテン補佐", "options.teamMemberRole.FRONTLINE": "前衛", diff --git a/locales/ja/q.json b/locales/ja/q.json index eae413cba..1191714f3 100644 --- a/locales/ja/q.json +++ b/locales/ja/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "ヘルプデスク", "match.pool": "プール", "match.password.short": "通過", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "マッチをキャンセルする", "match.canceled": "マッチをキャンセルしました", "match.canceled.detail": "", diff --git a/locales/ko/common.json b/locales/ko/common.json index 61b58ceec..a6838abec 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "참여하기", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/ko/forms.json b/locales/ko/forms.json index a8be337a7..ce6d6c06b 100644 --- a/locales/ko/forms.json +++ b/locales/ko/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "", diff --git a/locales/ko/q.json b/locales/ko/q.json index 6d01eb6e6..7a5d278aa 100644 --- a/locales/ko/q.json +++ b/locales/ko/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/nl/common.json b/locales/nl/common.json index fcb2f2962..c608bcfb2 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/nl/forms.json b/locales/nl/forms.json index 99c48d06b..12e7bf49a 100644 --- a/locales/nl/forms.json +++ b/locales/nl/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "", diff --git a/locales/nl/q.json b/locales/nl/q.json index 6d01eb6e6..7a5d278aa 100644 --- a/locales/nl/q.json +++ b/locales/nl/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/pl/common.json b/locales/pl/common.json index 2bc704963..afdeb82e8 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "Dołącz", + "host": "", "actions.nevermind": "", "actions.clickHere": "", "actions.goBack": "", diff --git a/locales/pl/forms.json b/locales/pl/forms.json index 0904b9cf9..17721ebaa 100644 --- a/locales/pl/forms.json +++ b/locales/pl/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Uwaga: Jeśli zmienisz imię drużyny, ktoś inny może użyć twoje stare imię i URL", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Kapitan", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "Frontline", diff --git a/locales/pl/q.json b/locales/pl/q.json index 6d01eb6e6..7a5d278aa 100644 --- a/locales/pl/q.json +++ b/locales/pl/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "", "match.pool": "", "match.password.short": "", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "", "match.canceled": "", "match.canceled.detail": "", diff --git a/locales/pt-BR/common.json b/locales/pt-BR/common.json index 931eaf424..0f9a20b9b 100644 --- a/locales/pt-BR/common.json +++ b/locales/pt-BR/common.json @@ -139,6 +139,7 @@ "actions.outlined": "", "actions.noOutline": "", "actions.join": "Entrar", + "host": "", "actions.nevermind": "Deixa pra lá...", "actions.clickHere": "Clique aqui", "actions.goBack": "Voltar", diff --git a/locales/pt-BR/forms.json b/locales/pt-BR/forms.json index 8be814f3c..2135d211a 100644 --- a/locales/pt-BR/forms.json +++ b/locales/pt-BR/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Lembre-se que se você mudar o nome do seu time, alguém pode resgatar o nome e o URL para o time dele(a)", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Capitão(ã)", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "Linha de frente (frontline)", diff --git a/locales/pt-BR/q.json b/locales/pt-BR/q.json index ca978ae88..ad3d3436b 100644 --- a/locales/pt-BR/q.json +++ b/locales/pt-BR/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "Pool", "match.password.short": "Senha", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "Cancelar partida", "match.canceled": "Partida cancelada", "match.canceled.detail": "", diff --git a/locales/ru/common.json b/locales/ru/common.json index 9d7aa1e5a..6a31e703e 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -139,6 +139,7 @@ "actions.outlined": "Обводка", "actions.noOutline": "Без обводки", "actions.join": "Присоединиться", + "host": "", "actions.nevermind": "Отмена", "actions.clickHere": "Нажмите здесь", "actions.goBack": "Назад", diff --git a/locales/ru/forms.json b/locales/ru/forms.json index d49559d4f..22766854e 100644 --- a/locales/ru/forms.json +++ b/locales/ru/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "Обратите внимание, что если вы измените название команды, то кто-то другой может забрать себе URL и название для своей команды", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "Капитан", "options.teamMemberRole.CO_CAPTAIN": "Со-капитан", "options.teamMemberRole.FRONTLINE": "Фронтлайн", diff --git a/locales/ru/q.json b/locales/ru/q.json index a16a58207..4f2709758 100644 --- a/locales/ru/q.json +++ b/locales/ru/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Служба поддержки", "match.pool": "Канал", "match.password.short": "Пароль", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "Отменить матч", "match.canceled": "Матч был отменён", "match.canceled.detail": "", diff --git a/locales/zh/common.json b/locales/zh/common.json index a4ebe5bfe..9e29acac9 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -139,6 +139,7 @@ "actions.outlined": "描边", "actions.noOutline": "无描边", "actions.join": "加入", + "host": "", "actions.nevermind": "反悔", "actions.clickHere": "点击此处", "actions.goBack": "返回", diff --git a/locales/zh/forms.json b/locales/zh/forms.json index 1e9b20d29..6e8fb0360 100644 --- a/locales/zh/forms.json +++ b/locales/zh/forms.json @@ -12,11 +12,9 @@ "labels.teamMemberCustomRole": "", "labels.teamMemberRoleType": "", "labels.clockFormat": "", - "labels.defaultMatchPageTab": "", "labels.disableBuildAbilitySorting": "", "labels.disallowScrimPickupsFromUntrusted": "", "labels.noScreen": "", - "labels.noSplatnet": "", "labels.spoilerFreeMode": "", "bottomTexts.imageModeration": "", "bottomTexts.name": "请注意,如果您更改了队名,那么其他人便可以使用之前的队名和URL了。", @@ -29,9 +27,6 @@ "options.clockFormat.auto": "", "options.clockFormat.24h": "", "options.clockFormat.12h": "", - "options.defaultMatchPageTab.rosters": "", - "options.defaultMatchPageTab.join": "", - "options.defaultMatchPageTab.action": "", "options.teamMemberRole.CAPTAIN": "队长", "options.teamMemberRole.CO_CAPTAIN": "", "options.teamMemberRole.FRONTLINE": "前排", diff --git a/locales/zh/q.json b/locales/zh/q.json index 5a02f6950..09b11b354 100644 --- a/locales/zh/q.json +++ b/locales/zh/q.json @@ -124,11 +124,6 @@ "match.helpdesk": "Helpdesk", "match.pool": "频道", "match.password.short": "密码", - "match.hostedBy": "", - "match.noSplatnetWarning": "", - "match.room.noRoomHint": "", - "match.room.stalePrompt": "", - "match.room.confirm": "", "match.cancelMatch": "取消对战", "match.canceled": "对战已取消", "match.canceled.detail": "", diff --git a/migrations/153-match-page-simplification.js b/migrations/153-match-page-simplification.js new file mode 100644 index 000000000..71740b263 --- /dev/null +++ b/migrations/153-match-page-simplification.js @@ -0,0 +1,9 @@ +export function up(db) { + db.transaction(() => { + db.prepare(/* sql */ `drop table if exists "RoomLink"`).run(); + + db.prepare(/* sql */ `alter table "User" drop column "noSplatnet"`).run(); + + db.pragma("foreign_key_check"); + })(); +}