mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-22 19:16:09 -05:00
Inappropriate nickname report help
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
.instructions {
|
||||
margin: var(--s-1) 0 0;
|
||||
padding-inline-start: var(--s-4);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--s-1);
|
||||
}
|
||||
@@ -4,11 +4,19 @@ import { SendouDialog } from "~/components/elements/Dialog";
|
||||
import { toastQueue } from "~/components/elements/Toast";
|
||||
import { FormMessage } from "~/components/FormMessage";
|
||||
import { SendouForm } from "~/form";
|
||||
import type { FormRenderProps } from "~/form/SendouForm";
|
||||
import { useFormValue } from "~/form/SendouForm";
|
||||
import { userReportPage } from "~/utils/urls";
|
||||
import { INAPPROPRIATE_NICKNAME_CATEGORY } from "../user-report-constants";
|
||||
import { reportUserSchema } from "../user-report-schemas";
|
||||
import styles from "./ReportUserDialog.module.css";
|
||||
|
||||
const SENDOUQ_MATCH_ROUTE_ID = "features/sendouq-match/routes/q.match.$id";
|
||||
|
||||
type ReportFormFieldComponent = FormRenderProps<
|
||||
typeof reportUserSchema.entries
|
||||
>["FormField"];
|
||||
|
||||
/**
|
||||
* Modal for reporting a user to the staff, posting to the `/user-report/:id` resource
|
||||
* route. Re-reporting the same user overwrites the previous report. Rendered wherever
|
||||
@@ -35,6 +43,9 @@ export function ReportUserDialog({
|
||||
schema={reportUserSchema}
|
||||
action={userReportPage(userId)}
|
||||
defaultValues={{ matchId: prefilledMatchId }}
|
||||
hideSubmitButtonWhen={(values) =>
|
||||
values.category === INAPPROPRIATE_NICKNAME_CATEGORY
|
||||
}
|
||||
onSuccess={() => {
|
||||
toastQueue.add(
|
||||
{ message: "Report sent to the staff", variant: "success" },
|
||||
@@ -46,11 +57,7 @@ export function ReportUserDialog({
|
||||
{({ FormField }) => (
|
||||
<>
|
||||
<FormField name="category" />
|
||||
<FormField name="description" />
|
||||
<FormField name="matchId" />
|
||||
<FormMessage type="info">
|
||||
{t("user:card.report.falseReportsWarning")}
|
||||
</FormMessage>
|
||||
<ReportFields FormField={FormField} />
|
||||
</>
|
||||
)}
|
||||
</SendouForm>
|
||||
@@ -58,6 +65,46 @@ export function ReportUserDialog({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The report itself, replaced by instructions when the selected category is one the
|
||||
* staff can't act on.
|
||||
*/
|
||||
function ReportFields({ FormField }: { FormField: ReportFormFieldComponent }) {
|
||||
const { t } = useTranslation(["user"]);
|
||||
const category = useFormValue("category");
|
||||
|
||||
if (category === INAPPROPRIATE_NICKNAME_CATEGORY) {
|
||||
return <InappropriateNicknameInstructions />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormField name="description" />
|
||||
<FormField name="matchId" />
|
||||
<FormMessage type="info">
|
||||
{t("user:card.report.falseReportsWarning")}
|
||||
</FormMessage>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function InappropriateNicknameInstructions() {
|
||||
const { t } = useTranslation(["user"]);
|
||||
|
||||
return (
|
||||
<FormMessage type="info">
|
||||
{t("user:card.report.nickname.explanation")}
|
||||
<ul
|
||||
className={styles.instructions}
|
||||
data-testid="nickname-report-instructions"
|
||||
>
|
||||
<li>{t("user:card.report.nickname.inGame")}</li>
|
||||
<li>{t("user:card.report.nickname.discord")}</li>
|
||||
</ul>
|
||||
</FormMessage>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SendouQ match id from the current route so a report opened from a match page
|
||||
* prefills its "Match ID" field. Returns `undefined` on any other page.
|
||||
|
||||
@@ -3,6 +3,13 @@ export const USER_REPORT = {
|
||||
MATCH_ID_MAX_LENGTH: 10,
|
||||
};
|
||||
|
||||
/**
|
||||
* Category offered in the report dialog but never stored: nicknames are not set on
|
||||
* sendou.ink, so picking it points the user to Splatoon 3 / Discord instead of
|
||||
* letting them send a report.
|
||||
*/
|
||||
export const INAPPROPRIATE_NICKNAME_CATEGORY = "INAPPROPRIATE_NICKNAME";
|
||||
|
||||
export const USER_REPORT_CATEGORIES = [
|
||||
"INAPPROPRIATE_CONTENT",
|
||||
"ALTING",
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import * as v from "valibot";
|
||||
import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.server";
|
||||
import { USER_REPORT_CATEGORIES } from "./user-report-constants";
|
||||
import { reportUserSchema } from "./user-report-schemas";
|
||||
|
||||
export const reportUserSchemaServer = v.objectAsync({
|
||||
...reportUserSchema.entries,
|
||||
// the dialog also offers a category that only shows guidance, never a report
|
||||
category: v.picklist(USER_REPORT_CATEGORIES),
|
||||
// cast to the concrete value type: the field's nullability makes its inferred
|
||||
// type a union the async pipe can't resolve
|
||||
matchId: v.pipeAsync(
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import * as v from "valibot";
|
||||
import { select, textArea, textFieldOptional } from "~/form/fields";
|
||||
import { id } from "~/utils/schema";
|
||||
import { USER_REPORT } from "./user-report-constants";
|
||||
import {
|
||||
INAPPROPRIATE_NICKNAME_CATEGORY,
|
||||
USER_REPORT,
|
||||
} from "./user-report-constants";
|
||||
|
||||
export const reportUserSchema = v.object({
|
||||
category: select({
|
||||
@@ -11,6 +14,10 @@ export const reportUserSchema = v.object({
|
||||
label: "options.userReportCategory.INAPPROPRIATE_CONTENT",
|
||||
value: "INAPPROPRIATE_CONTENT",
|
||||
},
|
||||
{
|
||||
label: "options.userReportCategory.INAPPROPRIATE_NICKNAME",
|
||||
value: INAPPROPRIATE_NICKNAME_CATEGORY,
|
||||
},
|
||||
{ label: "options.userReportCategory.ALTING", value: "ALTING" },
|
||||
{ label: "options.userReportCategory.HARASSMENT", value: "HARASSMENT" },
|
||||
{ label: "options.userReportCategory.CHEATING", value: "CHEATING" },
|
||||
|
||||
@@ -79,6 +79,9 @@ const FormContext = React.createContext<FormFieldContextValue | null>(null);
|
||||
|
||||
export const EMPTY_FORM_STORE = createFormStore({}, {});
|
||||
|
||||
const SUBMIT_ROW_CLASS_NAME =
|
||||
"mt-4 stack horizontal md mx-auto justify-center items-center";
|
||||
|
||||
export interface FormRenderProps<T extends v.ObjectEntries> {
|
||||
FormField: TypedFormFieldComponent<T>;
|
||||
}
|
||||
@@ -113,6 +116,13 @@ type BaseFormProps<T extends v.ObjectEntries> = {
|
||||
*/
|
||||
readOnly?: boolean;
|
||||
secondarySubmit?: React.ReactNode;
|
||||
/**
|
||||
* Hides the submit button while the current values match, for forms with a
|
||||
* branch that has nothing to submit (e.g. a choice that only shows guidance).
|
||||
*/
|
||||
hideSubmitButtonWhen?: (
|
||||
values: Partial<v.InferInput<v.ObjectSchema<T, undefined>>>,
|
||||
) => boolean;
|
||||
/**
|
||||
* Called once after a server submission completes successfully (the action
|
||||
* returned without field errors). Useful for collapsing an inline edit form
|
||||
@@ -196,6 +206,7 @@ function SendouFormInner<T extends v.ObjectEntries>({
|
||||
mode = "submit",
|
||||
onApply,
|
||||
secondarySubmit,
|
||||
hideSubmitButtonWhen,
|
||||
onSuccess,
|
||||
}: SendouFormProps<T>) {
|
||||
const { t } = useTranslation(["forms"]);
|
||||
@@ -330,7 +341,11 @@ function SendouFormInner<T extends v.ObjectEntries>({
|
||||
{title ? <h2 className={styles.title}>{title}</h2> : null}
|
||||
{resolvedChildren}
|
||||
{mode !== "submit" || readOnly ? null : (
|
||||
<div className="mt-4 stack horizontal md mx-auto justify-center items-center">
|
||||
<SubmitRow
|
||||
hideWhen={
|
||||
hideSubmitButtonWhen as ((values: unknown) => boolean) | undefined
|
||||
}
|
||||
>
|
||||
<SubmitButton
|
||||
testId={submitButtonTestId}
|
||||
state={fetcher.state}
|
||||
@@ -340,7 +355,7 @@ function SendouFormInner<T extends v.ObjectEntries>({
|
||||
{submitButtonText ?? t("submit")}
|
||||
</SubmitButton>
|
||||
{secondarySubmit}
|
||||
</div>
|
||||
</SubmitRow>
|
||||
)}
|
||||
{fallbackError ? (
|
||||
<div className="mt-4 mx-auto" data-testid="fallback-form-error">
|
||||
@@ -372,6 +387,45 @@ function SendouFormInner<T extends v.ObjectEntries>({
|
||||
);
|
||||
}
|
||||
|
||||
function SubmitRow({
|
||||
hideWhen,
|
||||
children,
|
||||
}: {
|
||||
hideWhen: ((values: unknown) => boolean) | undefined;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return hideWhen ? (
|
||||
<ConditionalSubmitRow hideWhen={hideWhen}>{children}</ConditionalSubmitRow>
|
||||
) : (
|
||||
<div className={SUBMIT_ROW_CLASS_NAME}>{children}</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split out of {@link SubmitRow} so that only forms that opt in subscribe to the
|
||||
* form's values (and re-render on every edit).
|
||||
*/
|
||||
function ConditionalSubmitRow({
|
||||
hideWhen,
|
||||
children,
|
||||
}: {
|
||||
hideWhen: (values: unknown) => boolean;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const context = React.useContext(FormContext);
|
||||
const store = context?.store ?? EMPTY_FORM_STORE;
|
||||
const getValues = () => store.values;
|
||||
const values = React.useSyncExternalStore(
|
||||
store.subscribe,
|
||||
getValues,
|
||||
getValues,
|
||||
);
|
||||
|
||||
if (hideWhen(values)) return null;
|
||||
|
||||
return <div className={SUBMIT_ROW_CLASS_NAME}>{children}</div>;
|
||||
}
|
||||
|
||||
function createFormStore(
|
||||
initialValues: Record<string, unknown>,
|
||||
initialClientErrors: Partial<Record<string, string>>,
|
||||
|
||||
@@ -66,6 +66,8 @@ class ReportUserDialog {
|
||||
this.locators = {
|
||||
matchIdInput: page.getByLabel("Match ID"),
|
||||
sentToast: page.getByText("Report sent to the staff"),
|
||||
submitButton: page.getByTestId("submit-button"),
|
||||
nicknameInstructions: page.getByTestId("nickname-report-instructions"),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,28 @@ test.describe("User report", () => {
|
||||
await expect(adminPage.text(description)).toBeVisible();
|
||||
});
|
||||
|
||||
test("points elsewhere instead of reporting an inappropriate nickname", async ({
|
||||
page,
|
||||
factories,
|
||||
}) => {
|
||||
const reporter = await factories.UserFactory.create();
|
||||
await factories.LFGPostFactory.create({ authorId: NZAP_TEST_ID });
|
||||
|
||||
await impersonate(page, reporter.id);
|
||||
|
||||
const lfg = new LFGPage(page);
|
||||
await lfg.goto();
|
||||
const card = await lfg.openUserCard("N-ZAP");
|
||||
const reportDialog = await card.openReportDialog();
|
||||
|
||||
await expect(reportDialog.locators.submitButton).toBeVisible();
|
||||
|
||||
await reportDialog.form.select("category", "INAPPROPRIATE_NICKNAME");
|
||||
|
||||
await expect(reportDialog.locators.nicknameInstructions).toBeVisible();
|
||||
await expect(reportDialog.locators.submitButton).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("prefills the match id when reporting from a match page", async ({
|
||||
page,
|
||||
factories,
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -251,6 +251,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -251,6 +251,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "Category",
|
||||
"labels.reportMatchId": "Match ID",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "Inappropriate content",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "Inappropriate nickname (Splatoon/Discord)",
|
||||
"options.userReportCategory.ALTING": "Alting",
|
||||
"options.userReportCategory.HARASSMENT": "Harassment",
|
||||
"options.userReportCategory.CHEATING": "Cheating",
|
||||
|
||||
@@ -251,6 +251,9 @@
|
||||
"card.editPrivateNote": "Edit private note",
|
||||
"card.report.header": "Report {{name}}",
|
||||
"card.report.falseReportsWarning": "Abuse of the reporting system including making false reports can lead to the suspension of your account.",
|
||||
"card.report.nickname.explanation": "Please report them on the corresponding platform:",
|
||||
"card.report.nickname.inGame": "Splatoon 3 in-game name: report the player in-game using Splatoon 3's own reporting feature (Battle Logs).",
|
||||
"card.report.nickname.discord": "Discord username/avatar: report the account to Discord.",
|
||||
"card.privateNote": "Private note",
|
||||
"card.xp": "XP",
|
||||
"card.freeAgent": "FA",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "Categoría",
|
||||
"labels.reportMatchId": "ID de la partida",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "Contenido inapropiado",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "Multicuentas",
|
||||
"options.userReportCategory.HARASSMENT": "Acoso",
|
||||
"options.userReportCategory.CHEATING": "Trampas",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "Editar nota privada",
|
||||
"card.report.header": "Reportar a {{name}}",
|
||||
"card.report.falseReportsWarning": "Abusar del sistema de reportes, incluyendo hacer reportes falsos, puede llevar a la suspensión de tu cuenta.",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "Nota privada",
|
||||
"card.xp": "XP",
|
||||
"card.freeAgent": "FA",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "Categoría",
|
||||
"labels.reportMatchId": "ID de la partida",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "Contenido inapropiado",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "Multicuentas",
|
||||
"options.userReportCategory.HARASSMENT": "Acoso",
|
||||
"options.userReportCategory.CHEATING": "Trampas",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "Editar nota privada",
|
||||
"card.report.header": "Reportar a {{name}}",
|
||||
"card.report.falseReportsWarning": "Abusar del sistema de reportes, incluyendo hacer reportes falsos, puede llevar a la suspensión de tu cuenta.",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "Nota privada",
|
||||
"card.xp": "XP",
|
||||
"card.freeAgent": "FA",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -251,6 +251,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -257,6 +257,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -254,6 +254,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -257,6 +257,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
"labels.reportCategory": "",
|
||||
"labels.reportMatchId": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_CONTENT": "",
|
||||
"options.userReportCategory.INAPPROPRIATE_NICKNAME": "",
|
||||
"options.userReportCategory.ALTING": "",
|
||||
"options.userReportCategory.HARASSMENT": "",
|
||||
"options.userReportCategory.CHEATING": "",
|
||||
|
||||
@@ -246,6 +246,9 @@
|
||||
"card.editPrivateNote": "",
|
||||
"card.report.header": "",
|
||||
"card.report.falseReportsWarning": "",
|
||||
"card.report.nickname.explanation": "",
|
||||
"card.report.nickname.inGame": "",
|
||||
"card.report.nickname.discord": "",
|
||||
"card.privateNote": "",
|
||||
"card.xp": "",
|
||||
"card.freeAgent": "",
|
||||
|
||||
Reference in New Issue
Block a user