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>0> によって管理されています",
"madeBy": "製作者: <0>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");
+ })();
+}