Remove screen banning

This commit is contained in:
Kalle 2023-12-30 11:28:22 +02:00
parent 80228a3bcc
commit 076cabfbfa
13 changed files with 3 additions and 245 deletions

View File

@ -547,7 +547,8 @@ export interface User {
>;
qWeaponPool: ColumnType<MainWeaponId[] | null, string | null, string | null>;
plusSkippedForSeasonNth: number | null;
noScreen: Generated<number>;
// TODO: remove with migration
// noScreen: Generated<number>;
}
export interface UserResultHighlight {

View File

@ -159,15 +159,3 @@ export async function findGroupById({
})),
} as GroupForMatch;
}
export function groupMembersNoScreenSettings(groups: GroupForMatch[]) {
return db
.selectFrom("User")
.select("User.noScreen")
.where(
"User.id",
"in",
groups.flatMap((group) => group.members.map((member) => member.id)),
)
.execute();
}

View File

@ -10,7 +10,6 @@ export async function settingsByUserId(userId: number) {
"User.vc",
"User.languages",
"User.qWeaponPool",
"User.noScreen",
])
.where("id", "=", userId)
.executeTakeFirstOrThrow();
@ -63,19 +62,3 @@ export function updateSendouQWeaponPool(args: {
.where("User.id", "=", args.userId)
.execute();
}
export function updateNoScreen({
noScreen,
userId,
}: {
noScreen: number;
userId: number;
}) {
return db
.updateTable("User")
.set({
noScreen,
})
.where("User.id", "=", userId)
.execute();
}

View File

@ -2,7 +2,6 @@ import { z } from "zod";
import { languagesUnified } from "~/modules/i18n/config";
import {
_action,
checkboxValueToBoolean,
modeShort,
noDuplicates,
safeJSONParse,
@ -43,8 +42,4 @@ export const settingsActionSchema = z.union([
z.array(weaponSplId).max(SENDOUQ_WEAPON_POOL_MAX_SIZE),
),
}),
z.object({
_action: _action("UPDATE_NO_SCREEN"),
noScreen: z.preprocess(checkboxValueToBoolean, z.boolean()),
}),
]);

View File

@ -33,7 +33,6 @@ import { assertUnreachable } from "~/utils/types";
import {
SENDOUQ_PAGE,
SENDOUQ_SETTINGS_PAGE,
SPLATTERCOLOR_SCREEN_TWITTER_URL,
navIconUrl,
preferenceEmojiUrl,
} from "~/utils/urls";
@ -42,8 +41,6 @@ import { settingsActionSchema } from "../q-settings-schemas.server";
import styles from "../q-settings.css";
import { BANNED_MAPS } from "../banned-maps";
import { Divider } from "~/components/Divider";
import { Toggle } from "~/components/Toggle";
import { FormMessage } from "~/components/FormMessage";
export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
@ -95,13 +92,6 @@ export const action = async ({ request }: ActionFunctionArgs) => {
});
break;
}
case "UPDATE_NO_SCREEN": {
await QSettingsRepository.updateNoScreen({
userId: user.id,
noScreen: Number(data.noScreen),
});
break;
}
default: {
assertUnreachable(data);
}
@ -126,7 +116,6 @@ export default function SendouQSettingsPage() {
<WeaponPool />
<VoiceChat />
<Sounds />
<Misc />
</div>
</Main>
);
@ -670,53 +659,3 @@ function SoundCheckboxes() {
</div>
);
}
function Misc() {
const data = useLoaderData<typeof loader>();
const [checked, setChecked] = React.useState(Boolean(data.settings.noScreen));
const { t } = useTranslation(["common", "q", "weapons"]);
const fetcher = useFetcher();
return (
<details>
<summary className="q-settings__summary">
<div>{t("q:settings.misc.header")}</div>
</summary>
<fetcher.Form method="post" className="mb-4 ml-2-5 stack sm">
<div className="stack horizontal xs items-center">
<Toggle
checked={checked}
setChecked={setChecked}
id="noScreen"
name="noScreen"
/>
<label className="mb-0" htmlFor="noScreen">
{t("q:settings.avoid.label", {
special: t("weapons:SPECIAL_19"),
})}
</label>
</div>
<FormMessage type="info">
{t("q:settings.avoid.explanation")}{" "}
<a
href={SPLATTERCOLOR_SCREEN_TWITTER_URL}
target="_blank"
rel="noopener noreferrer"
>
{t("q:settings.avoid.readMore")}
</a>
</FormMessage>
<div className="mt-6">
<SubmitButton
size="big"
className="mx-auto"
_action="UPDATE_NO_SCREEN"
state={fetcher.state}
>
{t("common:actions.save")}
</SubmitButton>
</div>
</fetcher.Form>
</details>
);
}

View File

@ -434,23 +434,6 @@
letter-spacing: 1px;
}
.q-match__screen-legality svg {
width: 24px;
}
.q-match__screen-legality .alert {
padding-block: var(--s-1);
padding-inline: var(--s-2-5);
}
.q-match__screen-legality__button:focus-visible {
outline: none !important;
}
.q-match__screen-legality__button:focus-visible .alert {
background-color: var(--bg-lighter);
}
@media screen and (min-width: 640px) {
.q-match__teams-container {
grid-template-columns: 1fr 1fr;

View File

@ -100,8 +100,6 @@ import { DiscordIcon } from "~/components/icons/Discord";
import { useWindowSize } from "~/hooks/useWindowSize";
import { joinListToNaturalString } from "~/utils/arrays";
import { NewTabs } from "~/components/NewTabs";
import { Alert } from "~/components/Alert";
import cachified from "@epic-web/cachified";
import { refreshStreamsCache } from "~/features/sendouq-streams/core/streams.server";
export const meta: MetaFunction = (args) => {
@ -432,22 +430,6 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
? reportedWeaponsByMatchId(matchId)
: null;
const banScreen = !match.isLocked
? await cachified({
key: `matches-screen-ban-${match.id}`,
cache,
async getFreshValue() {
const noScreenSettings =
await QMatchRepository.groupMembersNoScreenSettings([
groupAlpha,
groupBravo,
]);
return noScreenSettings.some((user) => user.noScreen);
},
})
: null;
return {
match: censoredMatch,
matchChatCode: canAccessMatchChat ? match.chatCode : null,
@ -455,7 +437,6 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
groupChatCode: groupChatCode(),
groupAlpha: censoredGroupAlpha,
groupBravo: censoredGroupBravo,
banScreen,
groupMemberOf: isTeamAlphaMember
? ("ALPHA" as const)
: isTeamBravoMember
@ -1144,11 +1125,6 @@ function BottomSection({
</FormWithConfirm>
) : null;
const screenLegalityInfoElement =
data.banScreen !== null ? (
<ScreenLegalityInfo ban={data.banScreen} />
) : null;
const chatHidden = chatRooms.length === 0;
if (!showMid && chatHidden) {
@ -1161,7 +1137,6 @@ function BottomSection({
<div className="stack horizontal lg items-center justify-center">
{roomJoiningInfoElement}
<div className="stack md">
{screenLegalityInfoElement}
{rulesButtonElement}
{helpdeskButtonElement}
{cancelMatchElement}
@ -1211,7 +1186,6 @@ function BottomSection({
>
<div className="stack md">
{roomJoiningInfoElement}
{screenLegalityInfoElement}
{rulesButtonElement}
{helpdeskButtonElement}
{cancelMatchElement}
@ -1235,34 +1209,6 @@ function BottomSection({
);
}
function ScreenLegalityInfo({ ban }: { ban: boolean }) {
const { t } = useTranslation(["q", "weapons"]);
return (
<div className="q-match__screen-legality">
<Popover
triggerClassName="minimal tiny q-match__screen-legality__button"
buttonChildren={
<Alert variation={ban ? "ERROR" : "SUCCESS"}>
<div className="stack xs horizontal items-center">
<WeaponImage weaponSplId={401} width={30} variant="build" />
<WeaponImage weaponSplId={6021} width={30} variant="build" />
</div>
</Alert>
}
>
{ban
? t("q:match.screen.ban", {
special: t("weapons:SPECIAL_19"),
})
: t("q:match.screen.allowed", {
special: t("weapons:SPECIAL_19"),
})}
</Popover>
</div>
);
}
function InfoWithHeader({ header, value }: { header: string; value: string }) {
return (
<div>

View File

@ -37,15 +37,6 @@ export default function SendouqRules() {
should be played out.
</div>
<h2 className="text-lg mt-4">Unallowed weapons</h2>
<div>
If someone picks an unallowed weapon game can be canceled within 1
minute by any player. For the replay everyone has to use the same
weapons and gear except the player with unallowed weapon who should
switch to the allowed variant of the weapon. For example had a player
picked Foil Squeezer they need to play regular Squeezer in the replay.
</div>
<h2 className="text-lg mt-4">Subs</h2>
<div>
There are no subs. If a player is unavailable to play from either team

View File

@ -5,7 +5,7 @@ import {
useOutletContext,
} from "@remix-run/react";
import clsx from "clsx";
import { Image, WeaponImage } from "~/components/Image";
import { Image } from "~/components/Image";
import { SubmitButton } from "~/components/SubmitButton";
import { useTranslation } from "react-i18next";
import type { ModeShort, StageId } from "~/modules/in-game-lists";
@ -32,8 +32,6 @@ import { NewTabs } from "~/components/NewTabs";
import { ScoreReporterRosters } from "./ScoreReporterRosters";
import { Chat, useChat } from "~/features/chat/components/Chat";
import * as React from "react";
import { CrossIcon } from "~/components/icons/Cross";
import { CheckmarkIcon } from "~/components/icons/Checkmark";
export type Result = Unpacked<
SerializeFrom<TournamentMatchLoaderData>["results"]
@ -116,7 +114,6 @@ export function ScoreReporter({
bestOf: data.match.bestOf,
})}
</>,
data.banScreen !== null ? <ScreenBanIcons banned={data.banScreen} /> : null,
];
const matchIsLockedError = actionData?.error === "locked";
@ -203,20 +200,6 @@ export function ScoreReporter({
);
}
function ScreenBanIcons({ banned }: { banned: boolean }) {
return (
<div
className={clsx("tournament-bracket__no-screen", {
"tournament-bracket__no-screen__banned": banned,
})}
>
{banned ? <CrossIcon /> : <CheckmarkIcon />}
<WeaponImage weaponSplId={401} width={24} variant="build" />
<WeaponImage weaponSplId={6021} width={24} variant="build" />
</div>
);
}
function FancyStageBanner({
stage,
infos,

View File

@ -54,8 +54,6 @@ import {
import bracketStyles from "../tournament-bracket.css";
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
import { logger } from "~/utils/logger";
import cachified from "@epic-web/cachified";
import { cache } from "~/utils/cache.server";
export const links: LinksFunction = () => [
{
@ -325,23 +323,6 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const matchIsOver =
match.opponentOne?.result === "win" || match.opponentTwo?.result === "win";
// not cache as performance optimization but instead
// so that people don't change their setting mid-set
const banScreen = !matchIsOver
? await cachified({
key: `tournament-screen-ban-${match.id}`,
cache,
async getFreshValue() {
const noScreenSettings =
await TournamentRepository.matchPlayersNoScreenSettings(
match.players,
);
return noScreenSettings.some((user) => user.noScreen);
},
})
: null;
return {
match: {
...match,
@ -351,7 +332,6 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
seeds: resolveSeeds(),
currentMap,
modes: mapList?.map((map) => map.mode),
banScreen,
matchIsOver,
};

View File

@ -103,20 +103,6 @@
}
}
.tournament-bracket__no-screen {
display: flex;
gap: var(--s-0-5);
}
.tournament-bracket__no-screen > svg {
width: 24px;
fill: var(--theme-success);
}
.tournament-bracket__no-screen__banned > svg {
fill: var(--theme-error);
}
.tournament-bracket__during-match-actions {
display: grid;
grid-template-areas:

View File

@ -53,15 +53,3 @@ export async function findById(id: number) {
return { ...row, author };
}
export function matchPlayersNoScreenSettings(players: { id: number }[]) {
return db
.selectFrom("User")
.select("User.noScreen")
.where(
"User.id",
"in",
players.map((player) => player.id),
)
.execute();
}

View File

@ -65,11 +65,6 @@
"settings.sounds.likeReceived": "Like received",
"settings.sounds.groupNewMember": "Group new member",
"settings.sounds.matchStarted": "Match started",
"settings.misc.header": "Misc",
"settings.banned": "Banned",
"settings.avoid.label": "Avoid {{special}}",
"settings.avoid.explanation": "Accessibility concerns related to the new special have been raised. Enabling this setting will make the special banned in SendouQ lobbies and tournament matches you play via sendou.ink.",
"settings.avoid.readMore": "Read more about the issues here",
"looking.joiningGroupError": "Before joining another group, leave the current one",
"looking.goToSettingsPrompt": "To help group finding set your weapon pool and voice chat status on the settings page",