mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-02 00:23:57 -05:00
Custom name (#1754)
* Migration and edit * Migrate from discordName * discordDiscriminator
This commit is contained in:
parent
764fd8ba7b
commit
bfce8d9646
|
|
@ -15,7 +15,7 @@ import type {
|
|||
} from "~/modules/in-game-lists";
|
||||
import type { BuildAbilitiesTuple } from "~/modules/in-game-lists/types";
|
||||
import { databaseTimestampToDate } from "~/utils/dates";
|
||||
import { discordFullName, gearTypeToInitial } from "~/utils/strings";
|
||||
import { gearTypeToInitial } from "~/utils/strings";
|
||||
import {
|
||||
analyzerPage,
|
||||
gearImageUrl,
|
||||
|
|
@ -58,10 +58,7 @@ interface BuildProps {
|
|||
maxPower: number | null;
|
||||
}>;
|
||||
};
|
||||
owner?: Pick<
|
||||
UserWithPlusTier,
|
||||
"discordId" | "discordName" | "discordDiscriminator" | "plusTier"
|
||||
>;
|
||||
owner?: Pick<UserWithPlusTier, "discordId" | "username" | "plusTier">;
|
||||
canEdit?: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +114,7 @@ export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
|||
to={userBuildsPage(owner)}
|
||||
className="build__date-author-row__owner"
|
||||
>
|
||||
{discordFullName(owner)}
|
||||
{owner.username}
|
||||
</Link>
|
||||
<div>•</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ export function UserSearch({
|
|||
: "Search via name or ID..."
|
||||
}
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
displayValue={(user: UserSearchUserItem) => user?.discordName ?? ""}
|
||||
displayValue={(user: UserSearchUserItem) => user?.username ?? ""}
|
||||
className={clsx("combobox-input", className)}
|
||||
data-1p-ignore
|
||||
data-testid={`${inputName}-combobox-input`}
|
||||
|
|
@ -118,9 +118,7 @@ export function UserSearch({
|
|||
<Avatar user={user} size="xs" />
|
||||
<div>
|
||||
<div className="stack xs horizontal items-center">
|
||||
<span className="combobox-username">
|
||||
{user.discordName}
|
||||
</span>{" "}
|
||||
<span className="combobox-username">{user.username}</span>{" "}
|
||||
{user.plusTier ? (
|
||||
<span className="text-xxs">+{user.plusTier}</span>
|
||||
) : null}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { Link } from "@remix-run/react";
|
|||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { usePatrons } from "~/hooks/swr";
|
||||
import { discordFullName } from "~/utils/strings";
|
||||
import {
|
||||
CONTRIBUTIONS_PAGE,
|
||||
FAQ_PAGE,
|
||||
|
|
@ -105,7 +104,7 @@ function PatronsList() {
|
|||
to={userPage(patron)}
|
||||
className="layout__footer__patron-list__patron"
|
||||
>
|
||||
{discordFullName(patron)}
|
||||
{patron.username}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export function UserItem() {
|
|||
<Avatar
|
||||
user={user}
|
||||
alt={t("header.loggedInAs", {
|
||||
userName: `${user.discordName}`,
|
||||
userName: `${user.username}`,
|
||||
})}
|
||||
className="layout__avatar"
|
||||
size="sm"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export const DISCORD_MESSAGE_MAX_LENGTH = 2000;
|
|||
export const USER = {
|
||||
BIO_MAX_LENGTH: DISCORD_MESSAGE_MAX_LENGTH,
|
||||
CUSTOM_URL_MAX_LENGTH: 32,
|
||||
CUSTOM_NAME_MAX_LENGTH: 32,
|
||||
IN_GAME_NAME_TEXT_MAX_LENGTH: 20,
|
||||
IN_GAME_NAME_DISCRIMINATOR_MAX_LENGTH: 5,
|
||||
WEAPON_POOL_MAX_SIZE: 5,
|
||||
|
|
|
|||
|
|
@ -223,7 +223,6 @@ function wipeDB() {
|
|||
|
||||
async function adminUser() {
|
||||
await UserRepository.upsert({
|
||||
discordDiscriminator: "0",
|
||||
discordId: ADMIN_DISCORD_ID,
|
||||
discordName: "Sendou",
|
||||
twitch: "Sendou",
|
||||
|
|
@ -267,7 +266,6 @@ function adminUserWeaponPool() {
|
|||
|
||||
function nzapUser() {
|
||||
return UserRepository.upsert({
|
||||
discordDiscriminator: "6227",
|
||||
discordId: NZAP_TEST_DISCORD_ID,
|
||||
discordName: "N-ZAP",
|
||||
twitch: null,
|
||||
|
|
@ -450,7 +448,6 @@ async function userQWeaponPool() {
|
|||
function fakeUser(usedNames: Set<string>) {
|
||||
return () => ({
|
||||
discordAvatar: null,
|
||||
discordDiscriminator: String(faker.string.numeric(4)),
|
||||
discordId: String(faker.string.numeric(17)),
|
||||
discordName: uniqueDiscordName(usedNames),
|
||||
twitch: null,
|
||||
|
|
|
|||
|
|
@ -667,9 +667,11 @@ export interface User {
|
|||
css: ColumnType<Record<string, string> | null, string | null, string | null>;
|
||||
customUrl: string | null;
|
||||
discordAvatar: string | null;
|
||||
discordDiscriminator: string;
|
||||
discordId: string;
|
||||
discordName: string;
|
||||
customName: string | null;
|
||||
/** coalesce(customName, discordName) */
|
||||
username: ColumnType<string, never, never>;
|
||||
discordUniqueName: string | null;
|
||||
favoriteBadgeId: number | null;
|
||||
id: GeneratedAlways<number>;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export interface User {
|
|||
discordId: string;
|
||||
/** Discord display name aka global name (non-unique) */
|
||||
discordName: string;
|
||||
discordDiscriminator: string;
|
||||
username: string;
|
||||
discordAvatar: string | null;
|
||||
/** Discord username (unique) */
|
||||
discordUniqueName: string | null;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
|||
.innerJoin("User", "User.id", "TournamentTeamMember.userId")
|
||||
.select([
|
||||
"User.id as userId",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
"User.discordId",
|
||||
"User.discordAvatar",
|
||||
"TournamentTeamMember.isOwner",
|
||||
|
|
@ -85,7 +85,7 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
|||
members: team.members.map((member) => {
|
||||
return {
|
||||
userId: member.userId,
|
||||
name: member.discordName,
|
||||
name: member.username,
|
||||
discordId: member.discordId,
|
||||
avatarUrl: member.discordAvatar
|
||||
? `https://cdn.discordapp.com/avatars/${member.discordId}/${member.discordAvatar}.png`
|
||||
|
|
|
|||
|
|
@ -7,14 +7,12 @@ export interface ListedArt {
|
|||
tags?: string[];
|
||||
linkedUsers?: Array<{
|
||||
discordId: User["discordId"];
|
||||
discordName: User["discordName"];
|
||||
discordDiscriminator: User["discordDiscriminator"];
|
||||
username: User["username"];
|
||||
customUrl: User["customUrl"];
|
||||
}>;
|
||||
author?: {
|
||||
discordId: User["discordId"];
|
||||
discordName: User["discordName"];
|
||||
discordDiscriminator: User["discordDiscriminator"];
|
||||
username: User["username"];
|
||||
discordAvatar: User["discordAvatar"];
|
||||
commissionsOpen?: User["commissionsOpen"];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { Link } from "@remix-run/react";
|
|||
import Masonry, { ResponsiveMasonry } from "react-responsive-masonry";
|
||||
import { Avatar } from "~/components/Avatar";
|
||||
import { useIsMounted } from "~/hooks/useIsMounted";
|
||||
import { discordFullName } from "~/utils/strings";
|
||||
import {
|
||||
artPage,
|
||||
conditionalUserSubmittedImage,
|
||||
|
|
@ -116,7 +115,7 @@ function BigImageDialog({ close, art }: { close: () => void; art: ListedArt }) {
|
|||
key={user.discordId}
|
||||
className="art__dialog__tag art__dialog__tag__user"
|
||||
>
|
||||
{discordFullName(user)}
|
||||
{user.username}
|
||||
</Link>
|
||||
))}
|
||||
{art.tags?.map((tag) => (
|
||||
|
|
@ -205,7 +204,7 @@ function ImagePreview({
|
|||
})}
|
||||
>
|
||||
<Avatar user={art.author} size="xxs" />
|
||||
{t("art:madeBy")} {discordFullName(art.author)}
|
||||
{t("art:madeBy")} {art.author.username}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -220,7 +219,7 @@ function ImagePreview({
|
|||
})}
|
||||
>
|
||||
<Avatar user={art.author} size="xxs" />
|
||||
{discordFullName(art.author)}
|
||||
{art.author.username}
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
"Art"."description",
|
||||
"Art"."createdAt",
|
||||
"User"."discordId",
|
||||
"User"."discordName",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"UserSubmittedImage"."url"
|
||||
from
|
||||
|
|
@ -28,8 +27,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
"Art"."description",
|
||||
"Art"."createdAt",
|
||||
null, -- discordId
|
||||
null, -- discordName
|
||||
null, -- discordDiscriminator
|
||||
null, -- username
|
||||
null, -- discordAvatar
|
||||
"UserSubmittedImage"."url"
|
||||
from
|
||||
|
|
@ -55,8 +53,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_group_array(
|
||||
json_object(
|
||||
'discordId', "LinkedUser"."discordId",
|
||||
'discordName', "LinkedUser"."discordName",
|
||||
'discordDiscriminator', "LinkedUser"."discordDiscriminator",
|
||||
'username', "LinkedUser"."username",
|
||||
'customUrl', "LinkedUser"."customUrl"
|
||||
)
|
||||
) as "linkedUsers"
|
||||
|
|
@ -83,9 +80,8 @@ export function artsByUserId(userId: number): ListedArt[] {
|
|||
? {
|
||||
commissionsOpen: a.commissionsOpen,
|
||||
discordAvatar: a.discordAvatar,
|
||||
discordDiscriminator: a.discordDiscriminator,
|
||||
discordId: a.discordId,
|
||||
discordName: a.discordName,
|
||||
username: a.username,
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ const showcaseArtsStm = sql.prepare(/* sql */ `
|
|||
"Art"."id",
|
||||
"User"."id" as "userId",
|
||||
"User"."discordId",
|
||||
"User"."discordName",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."commissionsOpen",
|
||||
"UserSubmittedImage"."url"
|
||||
|
|
@ -28,9 +27,8 @@ export function showcaseArts(): ListedArt[] {
|
|||
author: {
|
||||
commissionsOpen: a.commissionsOpen,
|
||||
discordAvatar: a.discordAvatar,
|
||||
discordDiscriminator: a.discordDiscriminator,
|
||||
discordId: a.discordId,
|
||||
discordName: a.discordName,
|
||||
username: a.username,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
|
@ -40,8 +38,7 @@ const showcaseArtsByTagStm = sql.prepare(/* sql */ `
|
|||
"Art"."id",
|
||||
"User"."id" as "userId",
|
||||
"User"."discordId",
|
||||
"User"."discordName",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."commissionsOpen",
|
||||
"UserSubmittedImage"."url"
|
||||
|
|
@ -76,9 +73,8 @@ export function showcaseArtsByTag(tagId: ArtTag["id"]): ListedArt[] {
|
|||
author: {
|
||||
commissionsOpen: a.commissionsOpen,
|
||||
discordAvatar: a.discordAvatar,
|
||||
discordDiscriminator: a.discordDiscriminator,
|
||||
discordId: a.discordId,
|
||||
discordName: a.discordName,
|
||||
username: a.username,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ export class DiscordStrategy extends OAuth2Strategy<
|
|||
|
||||
const userFromDb = await UserRepository.upsert({
|
||||
discordAvatar: user.avatar ?? null,
|
||||
discordDiscriminator: user.discriminator,
|
||||
discordId: user.id,
|
||||
discordName: user.global_name ?? user.username,
|
||||
discordUniqueName: user.global_name ? user.username : null,
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ export const createLogInLinkAction: ActionFunction = async ({ request }) => {
|
|||
|
||||
const user = await UserRepository.upsert({
|
||||
discordAvatar: data.discordAvatar ?? null,
|
||||
discordDiscriminator: "0",
|
||||
discordId: data.discordId,
|
||||
discordName: data.discordName,
|
||||
discordUniqueName: data.discordUniqueName,
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ export function findOwnersByBadgeId(badgeId: number) {
|
|||
fn.count<number>("BadgeOwner.badgeId").as("count"),
|
||||
"User.id",
|
||||
"User.discordId",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
])
|
||||
.where("BadgeOwner.badgeId", "=", badgeId)
|
||||
.groupBy("User.id")
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ function Managers({ data }: { data: BadgeDetailsLoaderData }) {
|
|||
<ul className="badges-edit__users-list">
|
||||
{managers.map((manager) => (
|
||||
<li key={manager.id}>
|
||||
{manager.discordName}
|
||||
{manager.username}
|
||||
<Button
|
||||
icon={<TrashIcon />}
|
||||
variant="minimal-destructive"
|
||||
|
|
@ -201,7 +201,7 @@ function Owners({ data }: { data: BadgeDetailsLoaderData }) {
|
|||
<ul className="badges-edit__users-list">
|
||||
{owners.map((owner) => (
|
||||
<li key={owner.id}>
|
||||
{owner.discordName}
|
||||
{owner.username}
|
||||
<input
|
||||
className="badges-edit__number-input"
|
||||
id="number"
|
||||
|
|
@ -230,13 +230,13 @@ function Owners({ data }: { data: BadgeDetailsLoaderData }) {
|
|||
<>
|
||||
{o.difference}{" "}
|
||||
<span className="text-success font-semi-bold">added</span> to{" "}
|
||||
{o.discordFullName}
|
||||
{o.username}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{o.difference}{" "}
|
||||
<span className="text-error font-semi-bold">removed</span>{" "}
|
||||
from {o.discordFullName}
|
||||
from {o.username}
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
|
|
@ -270,7 +270,7 @@ function getOwnerDifferences(
|
|||
id: User["id"];
|
||||
type: "added" | "removed";
|
||||
difference: number;
|
||||
discordFullName: string;
|
||||
username: string;
|
||||
}> = [];
|
||||
|
||||
for (const owner of newOwners) {
|
||||
|
|
@ -280,7 +280,7 @@ function getOwnerDifferences(
|
|||
id: owner.id,
|
||||
type: "added",
|
||||
difference: owner.count,
|
||||
discordFullName: owner.discordName,
|
||||
username: owner.username,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
|
@ -290,7 +290,7 @@ function getOwnerDifferences(
|
|||
id: owner.id,
|
||||
type: owner.count > oldOwner.count ? "added" : "removed",
|
||||
difference: Math.abs(owner.count - oldOwner.count),
|
||||
discordFullName: owner.discordName,
|
||||
username: owner.username,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export default function BadgeDetailsPage() {
|
|||
})}
|
||||
>
|
||||
{t("managedBy", {
|
||||
users: data.managers.map((m) => m.discordName).join(", "),
|
||||
users: data.managers.map((m) => m.username).join(", "),
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -78,7 +78,7 @@ export default function BadgeDetailsPage() {
|
|||
>
|
||||
×{owner.count}
|
||||
</span>
|
||||
<span>{owner.discordName}</span>
|
||||
<span>{owner.username}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -82,8 +82,7 @@ with "Top500Weapon" as (
|
|||
select
|
||||
"BuildWithWeapon".*,
|
||||
"User"."discordId",
|
||||
"User"."discordName",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."username",
|
||||
"PlusTier"."tier" as "plusTier",
|
||||
json_group_array(
|
||||
json_object(
|
||||
|
|
@ -184,10 +183,7 @@ order by
|
|||
`);
|
||||
|
||||
type BuildsByWeaponIdRow = BuildsByUserRow &
|
||||
Pick<
|
||||
UserWithPlusTier,
|
||||
"discordId" | "discordName" | "discordDiscriminator" | "plusTier"
|
||||
>;
|
||||
Pick<UserWithPlusTier, "discordId" | "username" | "plusTier">;
|
||||
|
||||
export function buildsByWeaponId({
|
||||
weaponId,
|
||||
|
|
|
|||
|
|
@ -95,8 +95,7 @@ export async function findById({
|
|||
"User.id as authorId",
|
||||
"CalendarEventDate.startTime",
|
||||
"CalendarEventDate.eventId",
|
||||
"User.discordName",
|
||||
"User.discordDiscriminator",
|
||||
"User.username",
|
||||
"User.discordId",
|
||||
"User.discordAvatar",
|
||||
hasBadge,
|
||||
|
|
@ -157,8 +156,7 @@ export async function findAllBetweenTwoTimestamps({
|
|||
"CalendarEventDate.id as eventDateId",
|
||||
"CalendarEventDate.eventId",
|
||||
"CalendarEventDate.startTime",
|
||||
"User.discordName",
|
||||
"User.discordDiscriminator",
|
||||
"User.username",
|
||||
"CalendarEventRanks.nthAppearance",
|
||||
eb
|
||||
.selectFrom("UserSubmittedImage")
|
||||
|
|
@ -364,7 +362,7 @@ export async function findResultsByEventId(eventId: number) {
|
|||
.select([
|
||||
"CalendarEventResultPlayer.userId as id",
|
||||
"CalendarEventResultPlayer.name",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
"User.discordId",
|
||||
"User.discordAvatar",
|
||||
])
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import {
|
|||
validate,
|
||||
type SendouRouteHandle,
|
||||
} from "~/utils/remix";
|
||||
import { discordFullName, makeTitle } from "~/utils/strings";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import {
|
||||
CALENDAR_PAGE,
|
||||
calendarEditPage,
|
||||
|
|
@ -304,7 +304,7 @@ function Results() {
|
|||
className="stack horizontal xs items-center"
|
||||
>
|
||||
<Avatar user={player as any} size="xxs" />{" "}
|
||||
{player.discordName}
|
||||
{player.username}
|
||||
</Link>
|
||||
)}
|
||||
</li>
|
||||
|
|
@ -353,7 +353,7 @@ function Description() {
|
|||
<div className="stack sm">
|
||||
<div className="event__author">
|
||||
<Avatar user={data.event} size="xs" />
|
||||
{discordFullName(data.event)}
|
||||
{data.event.username}
|
||||
</div>
|
||||
{data.event.description && (
|
||||
<div className="whitespace-pre-wrap">{data.event.description}</div>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
weekNumberToDate,
|
||||
} from "~/utils/dates";
|
||||
import { type SendouRouteHandle } from "~/utils/remix";
|
||||
import { discordFullName, makeTitle } from "~/utils/strings";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import type { Unpacked } from "~/utils/types";
|
||||
import {
|
||||
CALENDAR_PAGE,
|
||||
|
|
@ -451,7 +451,7 @@ function EventsList({
|
|||
</time>
|
||||
<div className="calendar__event__author">
|
||||
{t("from", {
|
||||
author: discordFullName(calendarEvent),
|
||||
author: calendarEvent.username,
|
||||
})}
|
||||
</div>
|
||||
{sectionWeekday !== eventWeekday ? (
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { soundPath } from "~/utils/urls";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { logger } from "~/utils/logger";
|
||||
|
||||
type ChatUser = Pick<User, "discordName" | "discordId" | "discordAvatar"> & {
|
||||
type ChatUser = Pick<User, "username" | "discordId" | "discordAvatar"> & {
|
||||
chatNameColor: string | null;
|
||||
title?: string;
|
||||
};
|
||||
|
|
@ -239,7 +239,7 @@ function Message({
|
|||
: undefined
|
||||
}
|
||||
>
|
||||
{user?.discordName ?? missingUserName}
|
||||
{user?.username ?? missingUserName}
|
||||
</div>
|
||||
{user?.title ? (
|
||||
<div className="text-xs text-theme-secondary font-semi-bold">
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ function TournamentCard({
|
|||
</div>
|
||||
<ul className="front__tournament-card__first-placers">
|
||||
{tournament.firstPlacers.map((p) => (
|
||||
<li key={p.id}>{p.discordName}</li>
|
||||
<li key={p.id}>{p.username}</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
|
|
@ -228,7 +228,7 @@ function LogInButton() {
|
|||
<Avatar
|
||||
user={user}
|
||||
alt={t("common:header.loggedInAs", {
|
||||
userName: `${user.discordName}`,
|
||||
userName: `${user.username}`,
|
||||
})}
|
||||
className="front__avatar"
|
||||
size="sm"
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@ const getStm = (where = "") =>
|
|||
"XRankPlacement"."weaponSplId",
|
||||
"XRankPlacement"."name",
|
||||
"User"."id",
|
||||
"User"."discordName",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."discordId",
|
||||
"User"."customUrl",
|
||||
max("XRankPlacement"."power") as "power",
|
||||
|
|
@ -45,9 +44,8 @@ export interface XPLeaderboardItem {
|
|||
id: User["id"];
|
||||
name: XRankPlacement["name"];
|
||||
playerId: XRankPlacement["playerId"];
|
||||
discordName: User["discordName"] | null;
|
||||
username: User["username"] | null;
|
||||
discordAvatar: User["discordAvatar"] | null;
|
||||
discordDiscriminator: User["discordDiscriminator"] | null;
|
||||
discordId: User["discordId"] | null;
|
||||
customUrl: User["customUrl"] | null;
|
||||
placementRank: number;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
"Skill"."id" as "entryId",
|
||||
"Skill"."ordinal",
|
||||
"User"."id",
|
||||
"User"."discordName",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."discordId",
|
||||
"User"."customUrl",
|
||||
|
|
@ -39,7 +39,7 @@ export interface UserSPLeaderboardItem {
|
|||
entryId: number;
|
||||
power: number;
|
||||
id: User["id"];
|
||||
discordName: User["discordName"];
|
||||
username: User["username"];
|
||||
discordAvatar: User["discordAvatar"];
|
||||
discordId: User["discordId"];
|
||||
customUrl: User["customUrl"];
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ function OwnEntryPeek({
|
|||
height={32}
|
||||
/>
|
||||
) : null}
|
||||
<div className="placements__table__name">{entry.discordName}</div>
|
||||
<div className="placements__table__name">{entry.username}</div>
|
||||
<div className="placements__table__power">{entry.power}</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
|
@ -435,7 +435,7 @@ function PlayersTable({
|
|||
/>
|
||||
) : null}
|
||||
<div className="placements__table__name">
|
||||
{entry.discordName}
|
||||
{entry.username}
|
||||
</div>
|
||||
{entry.pendingPlusTier ? (
|
||||
<div className="text-xs text-theme whitespace-nowrap">
|
||||
|
|
@ -493,7 +493,7 @@ function TeamTable({
|
|||
{entry.members.map((member, i) => {
|
||||
return (
|
||||
<React.Fragment key={member.id}>
|
||||
<Link to={userPage(member)}>{member.discordName}</Link>
|
||||
<Link to={userPage(member)}>{member.username}</Link>
|
||||
{i !== entry.members.length - 1 ? ", " : null}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ function PostTeamMember({
|
|||
<div className="stack sm items-center">
|
||||
<Avatar size="xs" user={member} />
|
||||
<Link to={userPage(member)} className="lfg__post-team-member-name">
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</Link>
|
||||
{tier ? <TierImage tier={tier} width={32} /> : null}
|
||||
</div>
|
||||
|
|
@ -232,7 +232,7 @@ function PostUserHeader({
|
|||
<div>
|
||||
<div className="stack horizontal sm items-center text-md font-bold">
|
||||
<Link to={userPage(author)} className="lfg__post-user-name">
|
||||
{author.discordName}
|
||||
{author.username}
|
||||
</Link>{" "}
|
||||
{author.country ? <Flag countryCode={author.country} tiny /> : null}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ type FindAllByMonthRow = {
|
|||
createdAt: number;
|
||||
author: {
|
||||
id: number;
|
||||
discordName: string;
|
||||
username: string;
|
||||
discordId: string;
|
||||
discordAvatar: string | null;
|
||||
};
|
||||
suggested: {
|
||||
id: number;
|
||||
discordName: string;
|
||||
username: string;
|
||||
discordId: string;
|
||||
discordAvatar: string | null;
|
||||
bio: string | null;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ export default function PlusCommentModalPage() {
|
|||
<input type="hidden" name="tier" value={tierSuggestedTo} />
|
||||
<input type="hidden" name="suggestedId" value={targetUserId} />
|
||||
<h2 className="plus__modal-title">
|
||||
{userBeingCommented.suggested.discordName}'s +{tierSuggestedTo}{" "}
|
||||
{userBeingCommented.suggested.username}'s +{tierSuggestedTo}{" "}
|
||||
suggestion
|
||||
</h2>
|
||||
<CommentTextarea maxLength={PlUS_SUGGESTION_COMMENT_MAX_LENGTH} />
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ function SuggestedUser({
|
|||
<Avatar user={suggestion.suggested} size="md" />
|
||||
<h2>
|
||||
<Link className="all-unset" to={userPage(suggestion.suggested)}>
|
||||
{suggestion.suggested.discordName}
|
||||
{suggestion.suggested.username}
|
||||
</Link>
|
||||
</h2>
|
||||
{canAddCommentToSuggestionFE({
|
||||
|
|
@ -366,7 +366,7 @@ export function PlusSuggestionComments({
|
|||
{suggestion.suggestions.map((suggestion) => {
|
||||
return (
|
||||
<fieldset key={suggestion.id} className="plus__comment">
|
||||
<legend>{suggestion.author.discordName}</legend>
|
||||
<legend>{suggestion.author.username}</legend>
|
||||
{suggestion.text}
|
||||
<div className="stack horizontal xs items-center">
|
||||
<span className="plus__comment-time">
|
||||
|
|
@ -388,9 +388,7 @@ export function PlusSuggestionComments({
|
|||
<CommentDeleteButton
|
||||
suggestionId={suggestion.id}
|
||||
tier={deleteButtonArgs.tier}
|
||||
suggestedDiscordName={
|
||||
deleteButtonArgs.suggested.discordName
|
||||
}
|
||||
suggestedUsername={deleteButtonArgs.suggested.username}
|
||||
isFirstSuggestion={
|
||||
deleteButtonArgs.suggestions.length === 1
|
||||
}
|
||||
|
|
@ -408,12 +406,12 @@ export function PlusSuggestionComments({
|
|||
function CommentDeleteButton({
|
||||
suggestionId,
|
||||
tier,
|
||||
suggestedDiscordName,
|
||||
suggestedUsername,
|
||||
isFirstSuggestion = false,
|
||||
}: {
|
||||
suggestionId: PlusSuggestion["id"];
|
||||
tier: string;
|
||||
suggestedDiscordName: string;
|
||||
suggestedUsername: string;
|
||||
isFirstSuggestion?: boolean;
|
||||
}) {
|
||||
return (
|
||||
|
|
@ -424,8 +422,8 @@ function CommentDeleteButton({
|
|||
]}
|
||||
dialogHeading={
|
||||
isFirstSuggestion
|
||||
? `Delete your suggestion of ${suggestedDiscordName} to +${tier}?`
|
||||
: `Delete your comment to ${suggestedDiscordName}'s +${tier} suggestion?`
|
||||
? `Delete your suggestion of ${suggestedUsername} to +${tier}?`
|
||||
: `Delete your comment to ${suggestedUsername}'s +${tier} suggestion?`
|
||||
}
|
||||
>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const resultsByMonthYearQuery = (args: MonthYear) =>
|
|||
])
|
||||
.where("PlusVotingResult.month", "=", args.month)
|
||||
.where("PlusVotingResult.year", "=", args.year)
|
||||
.orderBy(sql`"User"."discordName" collate nocase`, "asc");
|
||||
.orderBy(sql`"User"."username" collate nocase`, "asc");
|
||||
type ResultsByMonthYearQueryReturnType = InferResult<
|
||||
ReturnType<typeof resultsByMonthYearQuery>
|
||||
>;
|
||||
|
|
@ -67,7 +67,7 @@ function groupPlusVotingResults(rows: ResultsByMonthYearQueryReturnType) {
|
|||
export type UsersForVoting = {
|
||||
user: Pick<
|
||||
Tables["User"],
|
||||
"id" | "discordId" | "discordName" | "discordAvatar" | "bio"
|
||||
"id" | "discordId" | "username" | "discordAvatar" | "bio"
|
||||
>;
|
||||
suggestion?: PlusSuggestionRepository.FindAllByMonthItem;
|
||||
}[];
|
||||
|
|
@ -96,7 +96,7 @@ export async function usersForVoting(loggedInUser: {
|
|||
user: {
|
||||
id: member.id,
|
||||
discordId: member.discordId,
|
||||
discordName: member.discordName,
|
||||
username: member.username,
|
||||
discordAvatar: member.discordAvatar,
|
||||
bio: member.bio,
|
||||
},
|
||||
|
|
@ -108,7 +108,7 @@ export async function usersForVoting(loggedInUser: {
|
|||
user: {
|
||||
id: suggestion.suggested.id,
|
||||
discordId: suggestion.suggested.discordId,
|
||||
discordName: suggestion.suggested.discordName,
|
||||
username: suggestion.suggested.username,
|
||||
discordAvatar: suggestion.suggested.discordAvatar,
|
||||
bio: suggestion.suggested.bio,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ function Results({
|
|||
{user.wasSuggested ? (
|
||||
<span className="plus-history__suggestion-s">S</span>
|
||||
) : null}
|
||||
{user.discordName}
|
||||
{user.username}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ function Voting(data: Extract<PlusVotingLoaderData, { type: "voting" }>) {
|
|||
{previous.score > 0 ? "+" : ""}
|
||||
{previous.score}
|
||||
</span>{" "}
|
||||
on {previous.user.discordName}.
|
||||
on {previous.user.username}.
|
||||
<Button className="ml-auto" variant="minimal" onClick={undoLast}>
|
||||
Undo?
|
||||
</Button>
|
||||
|
|
@ -286,7 +286,7 @@ function Voting(data: Extract<PlusVotingLoaderData, { type: "voting" }>) {
|
|||
{currentUser ? (
|
||||
<div className="stack md items-center">
|
||||
<Avatar user={currentUser.user} size="lg" />
|
||||
<h2>{currentUser.user.discordName}</h2>
|
||||
<h2>{currentUser.user.username}</h2>
|
||||
<div className="stack horizontal lg">
|
||||
<Button
|
||||
className="plus-voting__vote-button downvote"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export interface GroupForMatch {
|
|||
members: Array<{
|
||||
id: Tables["GroupMember"]["userId"];
|
||||
discordId: Tables["User"]["discordId"];
|
||||
discordName: Tables["User"]["discordName"];
|
||||
username: Tables["User"]["username"];
|
||||
discordAvatar: Tables["User"]["discordAvatar"];
|
||||
role: Tables["GroupMember"]["role"];
|
||||
customUrl: Tables["User"]["customUrl"];
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export function AddPrivateNoteDialog({
|
|||
}: {
|
||||
aboutUser?: Pick<
|
||||
GroupForMatch["members"][number],
|
||||
"id" | "discordName" | "privateNote"
|
||||
"id" | "username" | "privateNote"
|
||||
>;
|
||||
close: () => void;
|
||||
}) {
|
||||
|
|
@ -33,7 +33,7 @@ export function AddPrivateNoteDialog({
|
|||
<input type="hidden" name="targetId" value={aboutUser.id} />
|
||||
<div className="stack horizontal items-center justify-between">
|
||||
<h2 className="text-md">
|
||||
{t("q:privateNote.header", { name: aboutUser.discordName })}
|
||||
{t("q:privateNote.header", { name: aboutUser.username })}
|
||||
</h2>
|
||||
<Button
|
||||
variant="minimal-destructive"
|
||||
|
|
|
|||
|
|
@ -727,11 +727,11 @@ function TrustedUsers() {
|
|||
>
|
||||
<Avatar user={trustedUser} size="xxs" />
|
||||
<div className="text-sm font-semi-bold">
|
||||
{trustedUser.discordName}
|
||||
{trustedUser.username}
|
||||
</div>
|
||||
<FormWithConfirm
|
||||
dialogHeading={t("q:settings.trusted.confirm", {
|
||||
name: trustedUser.discordName,
|
||||
name: trustedUser.username,
|
||||
})}
|
||||
fields={[
|
||||
["_action", "REMOVE_TRUST"],
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export default function SendouQStreamsPage() {
|
|||
className="q-stream__stream__user-container"
|
||||
>
|
||||
<Avatar size="xxs" user={streamedMatch.user} />{" "}
|
||||
{streamedMatch.user.discordName}
|
||||
{streamedMatch.user.username}
|
||||
</Link>
|
||||
<div className="stack horizontal sm">
|
||||
{streamedMatch.weaponSplId ? (
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ export async function usersThatTrusted(userId: number) {
|
|||
.select(COMMON_USER_FIELDS)
|
||||
.where("TrustRelationship.trustReceiverUserId", "=", userId),
|
||||
)
|
||||
.orderBy("User.discordName asc")
|
||||
.orderBy("User.username asc")
|
||||
.execute();
|
||||
|
||||
const rowsWithoutBanned = rows.filter((row) => !userIsBanned(row.id));
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ function GroupMember({
|
|||
})}
|
||||
</div>
|
||||
<DeletePrivateNoteForm
|
||||
name={member.discordName}
|
||||
name={member.username}
|
||||
targetId={member.id}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -296,7 +296,7 @@ function GroupMember({
|
|||
{inGameNameWithoutDiscriminator(member.inGameName)}
|
||||
</>
|
||||
) : (
|
||||
member.discordName
|
||||
member.username
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ function TrusterDropdown({
|
|||
{trustersNotInGroup.map((player) => {
|
||||
return (
|
||||
<option key={player.id} value={player.id}>
|
||||
{player.discordName}
|
||||
{player.username}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export type LookingGroup = {
|
|||
members?: {
|
||||
id: number;
|
||||
discordId: string;
|
||||
discordName: string;
|
||||
username: string;
|
||||
discordAvatar: string | null;
|
||||
noScreen?: number;
|
||||
customUrl?: User["customUrl"];
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_group_array(
|
||||
json_object(
|
||||
'id', "User"."id",
|
||||
'discordName', "User"."discordName",
|
||||
'username', "User"."username",
|
||||
'role', "GroupMember"."role"
|
||||
)
|
||||
) as "members"
|
||||
|
|
@ -26,7 +26,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
export function findGroupByInviteCode(inviteCode: string): {
|
||||
id: number;
|
||||
status: Group["status"];
|
||||
members: { id: number; discordName: string; role: GroupMember["role"] }[];
|
||||
members: { id: number; username: string; role: GroupMember["role"] }[];
|
||||
} | null {
|
||||
const row = stm.get({ inviteCode }) as any;
|
||||
if (!row) return null;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
"Group"."inviteCode",
|
||||
"User"."id" as "userId",
|
||||
"User"."discordId",
|
||||
"User"."discordName",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."qWeaponPool",
|
||||
"GroupMember"."role",
|
||||
|
|
@ -33,7 +33,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_object(
|
||||
'id', "q1"."userId",
|
||||
'discordId', "q1"."discordId",
|
||||
'discordName', "q1"."discordName",
|
||||
'username', "q1"."username",
|
||||
'discordAvatar', "q1"."discordAvatar",
|
||||
'role', "q1"."role",
|
||||
'note', "q1"."note",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_group_array(
|
||||
json_object(
|
||||
'id', "User"."id",
|
||||
'discordName', "User"."discordName",
|
||||
'username', "User"."username",
|
||||
'discordId', "User"."discordId",
|
||||
'discordAvatar', "User"."discordAvatar"
|
||||
)
|
||||
|
|
@ -63,7 +63,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_group_array(
|
||||
json_object(
|
||||
'id', "User"."id",
|
||||
'discordName', "User"."discordName",
|
||||
'username', "User"."username",
|
||||
'discordId', "User"."discordId",
|
||||
'discordAvatar', "User"."discordAvatar"
|
||||
)
|
||||
|
|
@ -107,14 +107,14 @@ interface SeasonMatchByUserId {
|
|||
spDiff: number | null;
|
||||
groupAlphaMembers: Array<{
|
||||
id: User["id"];
|
||||
discordName: User["discordName"];
|
||||
username: User["username"];
|
||||
discordId: User["discordId"];
|
||||
discordAvatar: User["discordAvatar"];
|
||||
weaponSplId?: MainWeaponId;
|
||||
}>;
|
||||
groupBravoMembers: Array<{
|
||||
id: User["id"];
|
||||
discordName: User["discordName"];
|
||||
username: User["username"];
|
||||
discordId: User["discordId"];
|
||||
discordAvatar: User["discordAvatar"];
|
||||
weaponSplId?: MainWeaponId;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
"setLosses",
|
||||
json_object(
|
||||
'id', "User"."id",
|
||||
'discordName', "User"."discordName",
|
||||
'username', "User"."username",
|
||||
'discordAvatar', "User"."discordAvatar",
|
||||
'discordId', "User"."discordId",
|
||||
'customUrl', "User"."customUrl"
|
||||
|
|
@ -44,7 +44,7 @@ export function seasonsMatesEnemiesByUserId({
|
|||
setLosses: number;
|
||||
user: Pick<
|
||||
User,
|
||||
"id" | "discordName" | "discordAvatar" | "discordId" | "customUrl"
|
||||
"id" | "username" | "discordAvatar" | "discordId" | "customUrl"
|
||||
>;
|
||||
}>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
NotificationService.notify({
|
||||
room: targetChatCode,
|
||||
type: "USER_LEFT",
|
||||
context: { name: user.discordName },
|
||||
context: { name: user.username },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ export const meta: MetaFunction = (args) => {
|
|||
{
|
||||
name: "description",
|
||||
content: `${joinListToNaturalString(
|
||||
data.groupAlpha.members.map((m) => m.discordName),
|
||||
data.groupAlpha.members.map((m) => m.username),
|
||||
)} vs. ${joinListToNaturalString(
|
||||
data.groupBravo.members.map((m) => m.discordName),
|
||||
data.groupBravo.members.map((m) => m.username),
|
||||
)}`,
|
||||
},
|
||||
];
|
||||
|
|
@ -325,7 +325,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
|
|||
room: match.chatCode,
|
||||
type: type(),
|
||||
context: {
|
||||
name: user.discordName,
|
||||
name: user.username,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -689,7 +689,7 @@ function Score({
|
|||
<div
|
||||
className={clsx("text-xs text-lighter", { invisible: !isMounted })}
|
||||
>
|
||||
{t("q:match.reportedBy", { name: reporter?.discordName ?? "admin" })}{" "}
|
||||
{t("q:match.reportedBy", { name: reporter?.username ?? "admin" })}{" "}
|
||||
{isMounted
|
||||
? databaseTimestampToDate(reportedAt).toLocaleString(
|
||||
i18n.language,
|
||||
|
|
@ -955,7 +955,7 @@ function ReportWeaponsForm() {
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
member.discordName
|
||||
member.username
|
||||
)}
|
||||
</div>
|
||||
<div className="stack horizontal sm items-center">
|
||||
|
|
@ -1522,7 +1522,7 @@ function MapListMap({
|
|||
...data.groupBravo.members,
|
||||
].find((m) => m.id === userId);
|
||||
|
||||
return member?.discordName ?? "";
|
||||
return member?.username ?? "";
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -1811,7 +1811,7 @@ function MapListMapPickInfo({
|
|||
className="stack sm horizontal items-center xs"
|
||||
>
|
||||
<Avatar user={user} size="xxs" />
|
||||
{user?.discordName}
|
||||
{user?.username}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
|
@ -1825,7 +1825,7 @@ function MapListMapPickInfo({
|
|||
className="q-settings__radio__emoji"
|
||||
width={18}
|
||||
/>
|
||||
{userIdToUser(userId)?.discordName}
|
||||
{userIdToUser(userId)?.username}
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ function JoinTeamDialog({
|
|||
open: boolean;
|
||||
close: () => void;
|
||||
members: {
|
||||
discordName: string;
|
||||
username: string;
|
||||
role: GroupMember["role"];
|
||||
}[];
|
||||
}) {
|
||||
|
|
@ -412,7 +412,7 @@ function JoinTeamDialog({
|
|||
className="text-center"
|
||||
>
|
||||
{t("q:front.join.header", {
|
||||
members: joinListToNaturalString(members.map((m) => m.discordName)),
|
||||
members: joinListToNaturalString(members.map((m) => m.username)),
|
||||
})}
|
||||
<fetcher.Form
|
||||
className="stack horizontal justify-center sm mt-4 flex-wrap"
|
||||
|
|
@ -427,7 +427,7 @@ function JoinTeamDialog({
|
|||
variant="outlined"
|
||||
>
|
||||
{t("q:front.join.joinWithTrustAction", {
|
||||
inviterName: owner.discordName,
|
||||
inviterName: owner.username,
|
||||
})}
|
||||
</SubmitButton>
|
||||
<Button onClick={close} variant="destructive">
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_object(
|
||||
'id',
|
||||
"User"."id",
|
||||
'discordName',
|
||||
"User"."discordName",
|
||||
'username',
|
||||
"User"."username",
|
||||
'plusTier',
|
||||
"PlusTier"."tier"
|
||||
)
|
||||
|
|
@ -28,7 +28,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
export type AllTeams = Array<
|
||||
Pick<Team, "customUrl" | "name"> & {
|
||||
avatarSrc?: string;
|
||||
members: Pick<UserWithPlusTier, "id" | "plusTier" | "discordName">[];
|
||||
members: Pick<UserWithPlusTier, "id" | "plusTier" | "username">[];
|
||||
}
|
||||
>;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,9 @@ const teamStm = sql.prepare(/*sql*/ `
|
|||
const membersStm = sql.prepare(/*sql*/ `
|
||||
select
|
||||
"User"."id",
|
||||
"User"."discordName",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."discordId",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."patronTier",
|
||||
"TeamMember"."role",
|
||||
"TeamMember"."isOwner",
|
||||
|
|
@ -57,15 +56,7 @@ type TeamRow =
|
|||
| null;
|
||||
|
||||
type MemberRows = Array<
|
||||
Pick<
|
||||
User,
|
||||
| "id"
|
||||
| "discordName"
|
||||
| "discordAvatar"
|
||||
| "discordId"
|
||||
| "discordDiscriminator"
|
||||
| "patronTier"
|
||||
> &
|
||||
Pick<User, "id" | "username" | "discordAvatar" | "discordId" | "patronTier"> &
|
||||
Pick<TeamMember, "role" | "isOwner"> & { weapons: string }
|
||||
>;
|
||||
|
||||
|
|
@ -93,8 +84,7 @@ export function findByIdentifier(
|
|||
id: member.id,
|
||||
discordAvatar: member.discordAvatar,
|
||||
discordId: member.discordId,
|
||||
discordName: member.discordName,
|
||||
discordDiscriminator: member.discordDiscriminator,
|
||||
username: member.username,
|
||||
patronTier: member.patronTier,
|
||||
role: member.role ?? undefined,
|
||||
isOwner: Boolean(member.isOwner),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { useUser } from "~/features/auth/core/user";
|
|||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import type { SendouRouteHandle } from "~/utils/remix";
|
||||
import { notFoundIfFalsy, parseRequestFormData, validate } from "~/utils/remix";
|
||||
import { discordFullName, makeTitle } from "~/utils/strings";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import {
|
||||
joinTeamPage,
|
||||
|
|
@ -223,7 +223,7 @@ function MemberRow({
|
|||
className="team__roster__members__member"
|
||||
data-testid={`member-row-${number}`}
|
||||
>
|
||||
{discordFullName(member)}
|
||||
{member.username}
|
||||
</div>
|
||||
<div>
|
||||
<select
|
||||
|
|
@ -255,7 +255,7 @@ function MemberRow({
|
|||
<FormWithConfirm
|
||||
dialogHeading={t("team:kick.header", {
|
||||
teamName: team.name,
|
||||
user: discordFullName(member),
|
||||
user: member.username,
|
||||
})}
|
||||
deleteButtonText={t("team:actionButtons.kick")}
|
||||
fields={[
|
||||
|
|
@ -276,7 +276,7 @@ function MemberRow({
|
|||
<FormWithConfirm
|
||||
dialogHeading={t("team:transferOwnership.header", {
|
||||
teamName: team.name,
|
||||
user: discordFullName(member),
|
||||
user: member.username,
|
||||
})}
|
||||
deleteButtonText={t("team:actionButtons.transferOwnership.confirm")}
|
||||
fields={[
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ function MemberRow({
|
|||
<div className="team__member__avatar">
|
||||
<Avatar user={member} size="md" />
|
||||
</div>
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</Link>
|
||||
<div className="stack horizontal md">
|
||||
{member.weapons.map(({ weaponSplId, isFavorite }) => (
|
||||
|
|
@ -323,7 +323,7 @@ function MobileMemberCard({ member }: { member: DetailedTeamMember }) {
|
|||
<div className="team__member-card">
|
||||
<Link to={userPage(member)} className="stack items-center">
|
||||
<Avatar user={member} size="md" />
|
||||
<div className="team__member-card__name">{member.discordName}</div>
|
||||
<div className="team__member-card__name">{member.username}</div>
|
||||
</Link>
|
||||
{member.weapons.length > 0 ? (
|
||||
<div className="stack horizontal md">
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export default function TeamSearchPage() {
|
|||
if (team.name.toLowerCase().includes(lowerCaseInput)) return true;
|
||||
if (
|
||||
team.members.some((m) =>
|
||||
m.discordName.toLowerCase().includes(lowerCaseInput),
|
||||
m.username.toLowerCase().includes(lowerCaseInput),
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
|
|
@ -136,9 +136,9 @@ export default function TeamSearchPage() {
|
|||
</div>
|
||||
<div className="team-search__team__members">
|
||||
{team.members.length === 1
|
||||
? team.members[0].discordName
|
||||
? team.members[0].username
|
||||
: joinListToNaturalString(
|
||||
team.members.map((member) => member.discordName),
|
||||
team.members.map((member) => member.username),
|
||||
"&",
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,10 +15,9 @@ export interface DetailedTeam {
|
|||
|
||||
export interface DetailedTeamMember {
|
||||
id: number;
|
||||
discordName: string;
|
||||
username: string;
|
||||
discordId: string;
|
||||
discordAvatar: string | null;
|
||||
discordDiscriminator: string;
|
||||
isOwner: boolean;
|
||||
weapons: Array<Pick<UserWeapon, "weaponSplId" | "isFavorite">>;
|
||||
role?: MemberRole;
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ function MatchRow({
|
|||
<div
|
||||
className={clsx("stack horizontal", { "text-lighter": isLoser })}
|
||||
data-participant-id={team?.id}
|
||||
title={team?.members.map((m) => m.discordName).join(", ")}
|
||||
title={team?.members.map((m) => m.username).join(", ")}
|
||||
>
|
||||
<div
|
||||
className={clsx("bracket__match__seed", {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export function MatchRosters({
|
|||
})}
|
||||
>
|
||||
<Avatar user={p} size="xxs" />
|
||||
{p.discordName}
|
||||
{p.username}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
|
|
@ -132,7 +132,7 @@ export function MatchRosters({
|
|||
})}
|
||||
>
|
||||
<Avatar user={p} size="xxs" />
|
||||
{p.discordName}
|
||||
{p.username}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ function TeamRosterInputsCheckboxes({
|
|||
<span className="tournament-bracket__during-match-actions__player-name__inner">
|
||||
{member.inGameName
|
||||
? inGameNameWithoutDiscriminator(member.inGameName)
|
||||
: member.discordName}
|
||||
: member.username}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const createTeam = (teamId: number, userIds: number[]): TournamentDataTeam => ({
|
|||
customUrl: null,
|
||||
discordAvatar: null,
|
||||
discordId: "123",
|
||||
discordName: "test",
|
||||
username: "test",
|
||||
inGameName: "test",
|
||||
isOwner: 0,
|
||||
plusTier: null,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -78,7 +78,7 @@ export const testTournament = (
|
|||
customUrl: null,
|
||||
discordAvatar: null,
|
||||
discordId: "123",
|
||||
discordName: "test",
|
||||
username: "test",
|
||||
id: 1,
|
||||
},
|
||||
...partialCtx,
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_object(
|
||||
'id',
|
||||
"User"."id",
|
||||
'discordName',
|
||||
"User"."discordName",
|
||||
'username',
|
||||
"User"."username",
|
||||
'tournamentTeamId',
|
||||
"TournamentTeamMember"."tournamentTeamId",
|
||||
'inGameName',
|
||||
|
|
@ -78,7 +78,7 @@ export const findMatchById = (id: number) => {
|
|||
opponentTwo: JSON.parse(row.opponentTwo) as Match["opponent2"],
|
||||
players: parseDBArray(row.players) as Array<{
|
||||
id: User["id"];
|
||||
discordName: User["discordName"];
|
||||
username: User["username"];
|
||||
tournamentTeamId: TournamentTeamMember["tournamentTeamId"];
|
||||
inGameName: User["inGameName"];
|
||||
discordId: User["discordId"];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import type { User } from "~/db/types";
|
|||
const stm = sql.prepare(/* sql */ `
|
||||
select
|
||||
"User"."id",
|
||||
"User"."discordName",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."discordId",
|
||||
"User"."customUrl",
|
||||
|
|
@ -27,7 +27,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
|
||||
export type PlayerThatPlayedByTeamId = Pick<
|
||||
User,
|
||||
"id" | "discordName" | "discordAvatar" | "discordId" | "customUrl" | "country"
|
||||
"id" | "username" | "discordAvatar" | "discordId" | "customUrl" | "country"
|
||||
> & { tournamentTeamId: number };
|
||||
|
||||
export function playersThatPlayedByTournamentId(tournamentId: number) {
|
||||
|
|
|
|||
|
|
@ -721,7 +721,7 @@ function FinalStandings() {
|
|||
to={userPage(player)}
|
||||
className="stack items-center text-xs mt-auto"
|
||||
>
|
||||
{player.discordName}
|
||||
{player.username}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -781,7 +781,7 @@ function FinalStandings() {
|
|||
to={userPage(player)}
|
||||
className="stack items-center text-xs mt-auto"
|
||||
>
|
||||
{player.discordName}
|
||||
{player.username}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ const stm = sql.prepare(/* sql */ `
|
|||
"TournamentSub"."visibility",
|
||||
"TournamentSub"."createdAt",
|
||||
"TournamentSub"."userId",
|
||||
"User"."discordName",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."username",
|
||||
"User"."discordAvatar",
|
||||
"User"."country",
|
||||
"User"."discordId",
|
||||
|
|
@ -39,8 +38,7 @@ export interface SubByTournamentId {
|
|||
visibility: TournamentSub["visibility"];
|
||||
createdAt: TournamentSub["createdAt"];
|
||||
userId: TournamentSub["userId"];
|
||||
discordName: UserWithPlusTier["discordName"];
|
||||
discordDiscriminator: UserWithPlusTier["discordDiscriminator"];
|
||||
username: UserWithPlusTier["username"];
|
||||
discordAvatar: UserWithPlusTier["discordAvatar"];
|
||||
discordId: UserWithPlusTier["discordId"];
|
||||
customUrl: UserWithPlusTier["customUrl"];
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import { getUser, requireUser } from "~/features/auth/core/user.server";
|
|||
import { tournamentIdFromParams } from "~/features/tournament";
|
||||
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
|
||||
import { useTournament } from "~/features/tournament/routes/to.$id";
|
||||
import { discordFullName } from "~/utils/strings";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import { tournamentRegisterPage, userPage } from "~/utils/urls";
|
||||
import { deleteSub } from "../queries/deleteSub.server";
|
||||
|
|
@ -170,7 +169,7 @@ function SubInfoSection({ sub }: { sub: SubByTournamentId }) {
|
|||
<section className="sub__section">
|
||||
<Avatar user={sub} size="sm" className="sub__section__avatar" />
|
||||
<Link to={userPage(sub)} className="sub__section__name">
|
||||
{discordFullName(sub)}
|
||||
{sub.username}
|
||||
</Link>
|
||||
<div className="sub__section__spacer" />
|
||||
<div className="sub__section__info">{infos}</div>
|
||||
|
|
@ -214,7 +213,7 @@ function SubInfoSection({ sub }: { sub: SubByTournamentId }) {
|
|||
dialogHeading={
|
||||
user?.id === sub.userId
|
||||
? "Delete your sub post?"
|
||||
: `Delete sub post by ${sub.discordName}?`
|
||||
: `Delete sub post by ${sub.username}?`
|
||||
}
|
||||
fields={[["userId", sub.userId]]}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ export async function findById(id: number) {
|
|||
.leftJoin("PlusTier", "User.id", "PlusTier.userId")
|
||||
.select([
|
||||
"User.id as userId",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
"User.discordId",
|
||||
"User.discordAvatar",
|
||||
"User.customUrl",
|
||||
|
|
@ -250,7 +250,7 @@ export async function forShowcase() {
|
|||
.where("TournamentResult.placement", "=", 1)
|
||||
.select([
|
||||
"User.id",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
"TournamentTeam.name as teamName",
|
||||
]),
|
||||
).as("firstPlacers"),
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ export function TeamWithRoster({
|
|||
to={userPage(member)}
|
||||
className="tournament__team-member-name"
|
||||
>
|
||||
{member.discordName}{" "}
|
||||
{member.username}{" "}
|
||||
</Link>
|
||||
</div>
|
||||
{friendCode ? (
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export function TournamentStream({
|
|||
<div className="stack md horizontal justify-between">
|
||||
{user && team ? (
|
||||
<div className="tournament__stream__user-container">
|
||||
<Avatar size="xxs" user={user} /> {user.discordName}
|
||||
<Avatar size="xxs" user={user} /> {user.username}
|
||||
<span className="text-theme-secondary">{team.name}</span>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export interface PlayedSet {
|
|||
roster: Array<
|
||||
Pick<
|
||||
User,
|
||||
"id" | "discordName" | "discordAvatar" | "discordId" | "customUrl"
|
||||
"id" | "username" | "discordAvatar" | "discordId" | "customUrl"
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ select
|
|||
"CalendarEvent"."bracketUrl",
|
||||
"CalendarEvent"."authorId",
|
||||
"CalendarEventDate"."startTime",
|
||||
"User"."discordName",
|
||||
"User"."discordDiscriminator",
|
||||
"User"."username",
|
||||
"User"."discordId"
|
||||
from "Tournament"
|
||||
left join "CalendarEvent" on "Tournament"."id" = "CalendarEvent"."tournamentId"
|
||||
|
|
@ -35,7 +34,7 @@ type FindByIdentifierRow = (Pick<
|
|||
"bracketUrl" | "name" | "description" | "authorId"
|
||||
> &
|
||||
Pick<Tournament, "id" | "mapPickingStyle" | "showMapListGenerator"> &
|
||||
Pick<User, "discordId" | "discordName" | "discordDiscriminator"> &
|
||||
Pick<User, "discordId" | "username"> &
|
||||
Pick<CalendarEventDate, "startTime">) & {
|
||||
eventId: CalendarEvent["id"];
|
||||
} & { settings: string };
|
||||
|
|
@ -46,7 +45,7 @@ export function findByIdentifier(identifier: string | number) {
|
|||
|
||||
const tournament = { ...rows[0], startTime: resolveEarliestStartTime(rows) };
|
||||
|
||||
const { discordId, discordName, discordDiscriminator, ...rest } = tournament;
|
||||
const { discordId, username, ...rest } = tournament;
|
||||
|
||||
return {
|
||||
...rest,
|
||||
|
|
@ -55,8 +54,7 @@ export function findByIdentifier(identifier: string | number) {
|
|||
) as Tables["Tournament"]["settings"],
|
||||
author: {
|
||||
discordId,
|
||||
discordName,
|
||||
discordDiscriminator,
|
||||
username,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ const stm = sql.prepare(/* sql */ `
|
|||
json_object(
|
||||
'id',
|
||||
"u"."id",
|
||||
'discordName',
|
||||
"u"."discordName",
|
||||
'username',
|
||||
"u"."username",
|
||||
'discordAvatar',
|
||||
"u"."discordAvatar",
|
||||
'discordId',
|
||||
|
|
@ -94,10 +94,7 @@ export interface SetHistoryByTeamIdItem {
|
|||
wasWinner: number;
|
||||
}[];
|
||||
players: Array<
|
||||
Pick<
|
||||
User,
|
||||
"id" | "discordName" | "discordAvatar" | "discordId" | "customUrl"
|
||||
>
|
||||
Pick<User, "id" | "username" | "discordAvatar" | "discordId" | "customUrl">
|
||||
>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ function TeamActions() {
|
|||
<select id="memberId" name="memberId">
|
||||
{selectedTeam.members.map((member) => (
|
||||
<option key={member.userId} value={member.userId}>
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
|
@ -682,7 +682,7 @@ function StaffList() {
|
|||
>
|
||||
<Avatar size="xs" user={staff} />{" "}
|
||||
<div className="mr-4">
|
||||
<div>{staff.discordName}</div>
|
||||
<div>{staff.username}</div>
|
||||
<div className="text-lighter text-xs text-capitalize">
|
||||
{t(`tournament:staff.role.${staff.role}`)}
|
||||
</div>
|
||||
|
|
@ -703,7 +703,7 @@ function RemoveStaffButton({
|
|||
|
||||
return (
|
||||
<FormWithConfirm
|
||||
dialogHeading={`Remove ${staff.discordName} as ${t(
|
||||
dialogHeading={`Remove ${staff.username} as ${t(
|
||||
`tournament:staff.role.${staff.role}`,
|
||||
)}?`}
|
||||
fields={[
|
||||
|
|
@ -760,12 +760,12 @@ function DownloadParticipants() {
|
|||
|
||||
const nonOwners = team.members.filter((user) => !user.isOwner);
|
||||
|
||||
let result = `-- ${team.name} --\n(C) ${owner.discordName} (IGN: ${owner.inGameName ?? ""}) - <@${owner.discordId}>`;
|
||||
let result = `-- ${team.name} --\n(C) ${owner.username} (IGN: ${owner.inGameName ?? ""}) - <@${owner.discordId}>`;
|
||||
|
||||
result += nonOwners
|
||||
.map(
|
||||
(user) =>
|
||||
`\n${user.discordName} (IGN: ${user.inGameName ?? ""}) - <@${user.discordId}>`,
|
||||
`\n${user.username} (IGN: ${user.inGameName ?? ""}) - <@${user.discordId}>`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
|
|
@ -789,7 +789,7 @@ function DownloadParticipants() {
|
|||
return `${i + 1}) ${team.name} - ${databaseTimestampToDate(
|
||||
team.createdAt,
|
||||
).toISOString()} - ${team.members
|
||||
.map((member) => `${member.discordName} - <@${member.discordId}>`)
|
||||
.map((member) => `${member.username} - <@${member.discordId}>`)
|
||||
.join(" / ")}`;
|
||||
})
|
||||
.join("\n")
|
||||
|
|
@ -803,7 +803,7 @@ function DownloadParticipants() {
|
|||
.filter((team) => team.checkIns.length === 0)
|
||||
.map((team) => {
|
||||
return `${team.name} - ${team.members
|
||||
.map((member) => `${member.discordName} - <@${member.discordId}>`)
|
||||
.map((member) => `${member.username} - <@${member.discordId}>`)
|
||||
.join(" / ")}`;
|
||||
})
|
||||
.join("\n");
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ export default function JoinTeamPage() {
|
|||
<input id={id} type="checkbox" name="trust" />{" "}
|
||||
<label htmlFor={id} className="mb-0">
|
||||
{t("tournament:join.giveTrust", {
|
||||
name: captain ? captain.discordName : "",
|
||||
name: captain ? captain.username : "",
|
||||
})}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ export default function TournamentRegisterPage() {
|
|||
className="stack horizontal xs items-center text-lighter"
|
||||
>
|
||||
<UserIcon className="tournament__info__icon" />{" "}
|
||||
{tournament.ctx.author.discordName}
|
||||
{tournament.ctx.author.username}
|
||||
</Link>
|
||||
<div className="stack horizontal xs items-center">
|
||||
<ClockIcon className="tournament__info__icon" />{" "}
|
||||
|
|
@ -979,7 +979,7 @@ function FillRoster({
|
|||
data-testid={`member-num-${i + 1}`}
|
||||
>
|
||||
<Avatar size="xsm" user={member} />
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
|
@ -1018,7 +1018,7 @@ function FillRoster({
|
|||
function DirectlyAddPlayerSelect({
|
||||
players,
|
||||
}: {
|
||||
players: { id: number; discordName: string }[];
|
||||
players: { id: number; username: string }[];
|
||||
}) {
|
||||
const { t } = useTranslation(["tournament", "common"]);
|
||||
const fetcher = useFetcher();
|
||||
|
|
@ -1034,7 +1034,7 @@ function DirectlyAddPlayerSelect({
|
|||
{players.map((player) => {
|
||||
return (
|
||||
<option key={player.id} value={player.id}>
|
||||
{player.discordName}
|
||||
{player.username}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
|
|
@ -1078,7 +1078,7 @@ function DeleteMember({ members }: { members: TournamentDataTeam["members"] }) {
|
|||
.filter((member) => !member.isOwner)
|
||||
.map((member) => (
|
||||
<option key={member.userId} value={member.userId}>
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ function RowContents({
|
|||
target="_blank"
|
||||
className="tournament__seeds__team-member__name"
|
||||
>
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</Link>
|
||||
{member.plusTier ? (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ function SetInfo({ set, team }: { set: PlayedSet; team: TournamentDataTeam }) {
|
|||
className="tournament__team__set__opponent__member"
|
||||
>
|
||||
<Avatar user={user} size="xxs" />
|
||||
{user.discordName}
|
||||
{user.username}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ export function findByIdentifier(identifier: string) {
|
|||
.leftJoin("PlusTier", "PlusTier.userId", "User.id")
|
||||
.select(({ eb }) => [
|
||||
"User.discordAvatar",
|
||||
"User.discordDiscriminator",
|
||||
"User.discordId",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
"User.customName",
|
||||
"User.showDiscordUniqueName",
|
||||
"User.discordUniqueName",
|
||||
"User.customUrl",
|
||||
|
|
@ -107,13 +108,7 @@ export function findLeanById(id: number) {
|
|||
export function findAllPatrons() {
|
||||
return db
|
||||
.selectFrom("User")
|
||||
.select([
|
||||
"User.id",
|
||||
"User.discordId",
|
||||
"User.discordName",
|
||||
"User.discordDiscriminator",
|
||||
"User.patronTier",
|
||||
])
|
||||
.select(["User.id", "User.discordId", "User.username", "User.patronTier"])
|
||||
.where("User.patronTier", "is not", null)
|
||||
.orderBy("User.patronTier", "desc")
|
||||
.orderBy("User.patronSince", "asc")
|
||||
|
|
@ -264,7 +259,7 @@ export async function search({
|
|||
.select(searchSelectedFields)
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb("User.discordName", "like", query),
|
||||
eb("User.username", "like", query),
|
||||
eb("User.inGameName", "like", query),
|
||||
eb("User.discordUniqueName", "like", query),
|
||||
eb("User.twitter", "like", query),
|
||||
|
|
@ -293,7 +288,7 @@ export async function search({
|
|||
.where((eb) =>
|
||||
eb
|
||||
.or([
|
||||
eb("User.discordName", "like", fuzzyQuery),
|
||||
eb("User.username", "like", fuzzyQuery),
|
||||
eb("User.inGameName", "like", fuzzyQuery),
|
||||
eb("User.discordUniqueName", "like", fuzzyQuery),
|
||||
eb("User.twitter", "like", fuzzyQuery),
|
||||
|
|
@ -368,7 +363,6 @@ export function upsert(
|
|||
TablesInsertable["User"],
|
||||
| "discordId"
|
||||
| "discordName"
|
||||
| "discordDiscriminator"
|
||||
| "discordAvatar"
|
||||
| "discordUniqueName"
|
||||
| "twitch"
|
||||
|
|
@ -393,6 +387,7 @@ type UpdateProfileArgs = Pick<
|
|||
| "country"
|
||||
| "bio"
|
||||
| "customUrl"
|
||||
| "customName"
|
||||
| "motionSens"
|
||||
| "stickSens"
|
||||
| "inGameName"
|
||||
|
|
@ -432,6 +427,7 @@ export function updateProfile(args: UpdateProfileArgs) {
|
|||
country: args.country,
|
||||
bio: args.bio,
|
||||
customUrl: args.customUrl,
|
||||
customName: args.customName,
|
||||
motionSens: args.motionSens,
|
||||
stickSens: args.stickSens,
|
||||
inGameName: args.inGameName,
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ export function UserResultsTable({
|
|||
className="stack horizontal xs items-center"
|
||||
>
|
||||
<Avatar user={player as any} size="xxs" />
|
||||
{player.discordName}
|
||||
{player.username}
|
||||
</Link>
|
||||
)}
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ const userEditActionSchema = z
|
|||
.transform((val) => val?.toLowerCase())
|
||||
.nullable(),
|
||||
),
|
||||
customName: z.preprocess(
|
||||
falsyToNull,
|
||||
z.string().trim().max(USER.CUSTOM_NAME_MAX_LENGTH).nullable(),
|
||||
),
|
||||
stickSens: z.preprocess(
|
||||
processMany(actualNumber, undefinedToNull),
|
||||
z
|
||||
|
|
@ -232,6 +236,7 @@ export default function UserEditPage() {
|
|||
{canAddCustomizedColorsToUserProfile(user) ? (
|
||||
<CustomizedColorsInput initialColors={parentRouteData.css} />
|
||||
) : null}
|
||||
<CustomNameInput parentRouteData={parentRouteData} />
|
||||
<CustomUrlInput parentRouteData={parentRouteData} />
|
||||
<InGameNameInputs parentRouteData={parentRouteData} />
|
||||
<SensSelects parentRouteData={parentRouteData} />
|
||||
|
|
@ -290,6 +295,31 @@ function CustomUrlInput({
|
|||
);
|
||||
}
|
||||
|
||||
function CustomNameInput({
|
||||
parentRouteData,
|
||||
}: {
|
||||
parentRouteData: UserPageLoaderData;
|
||||
}) {
|
||||
const { t } = useTranslation(["user"]);
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<Label htmlFor="customName">{t("user:customName")}</Label>
|
||||
<Input
|
||||
name="customName"
|
||||
id="customName"
|
||||
maxLength={USER.CUSTOM_NAME_MAX_LENGTH}
|
||||
defaultValue={parentRouteData.customName ?? undefined}
|
||||
/>
|
||||
<FormMessage type="info">
|
||||
{t("user:forms.customName.info", {
|
||||
discordName: parentRouteData.discordName,
|
||||
})}
|
||||
</FormMessage>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function InGameNameInputs({
|
||||
parentRouteData,
|
||||
}: {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { YouTubeIcon } from "~/components/icons/YouTube";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { modesShort } from "~/modules/in-game-lists";
|
||||
import { type SendouRouteHandle } from "~/utils/remix";
|
||||
import { isNewDiscordUniqueName, rawSensToString } from "~/utils/strings";
|
||||
import { rawSensToString } from "~/utils/strings";
|
||||
import type { Unpacked } from "~/utils/types";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import {
|
||||
|
|
@ -41,16 +41,8 @@ export default function UserInfoPage() {
|
|||
<Avatar user={data} size="lg" className="u__avatar" />
|
||||
<div>
|
||||
<h2 className="u__name">
|
||||
<div>{data.discordName}</div>
|
||||
<div>{data.username}</div>
|
||||
<div>
|
||||
<span className="u__discriminator">
|
||||
{!isNewDiscordUniqueName(data.discordDiscriminator) ? (
|
||||
<>
|
||||
#{data.discordDiscriminator}
|
||||
<wbr />
|
||||
</>
|
||||
) : null}
|
||||
</span>
|
||||
{data.country ? <Flag countryCode={data.country} tiny /> : null}
|
||||
</div>
|
||||
</h2>
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ function Players({
|
|||
className="u__season__player-name"
|
||||
>
|
||||
<Avatar user={player.user} size="xs" className="mx-auto" />
|
||||
{player.user.discordName}
|
||||
{player.user.username}
|
||||
</Link>
|
||||
<div
|
||||
className={clsx("text-xs font-bold", {
|
||||
|
|
@ -803,7 +803,7 @@ function MatchMembersRow({
|
|||
<div key={member.discordId} className="u__season__match__user">
|
||||
<Avatar user={member} size="xxs" />
|
||||
<span className="u__season__match__user__name">
|
||||
{member.discordName}
|
||||
{member.username}
|
||||
</span>
|
||||
{typeof member.weaponSplId === "number" ? (
|
||||
<WeaponImage
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { useUser } from "~/features/auth/core/user";
|
|||
import { getUserId } from "~/features/auth/core/user.server";
|
||||
import { canAddCustomizedColorsToUserProfile, isAdmin } from "~/permissions";
|
||||
import { notFoundIfFalsy, type SendouRouteHandle } from "~/utils/remix";
|
||||
import { discordFullName, makeTitle } from "~/utils/strings";
|
||||
import { makeTitle } from "~/utils/strings";
|
||||
import {
|
||||
isCustomUrl,
|
||||
navIconUrl,
|
||||
|
|
@ -41,7 +41,7 @@ import "~/styles/u.css";
|
|||
export const meta: MetaFunction<typeof loader> = ({ data }) => {
|
||||
if (!data) return [];
|
||||
|
||||
return [{ title: makeTitle(discordFullName(data)) }];
|
||||
return [{ title: makeTitle(data.username) }];
|
||||
};
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
|
|
@ -58,7 +58,7 @@ export const handle: SendouRouteHandle = {
|
|||
type: "IMAGE",
|
||||
},
|
||||
{
|
||||
text: data.discordName,
|
||||
text: data.username,
|
||||
href: userPage(data),
|
||||
type: "TEXT",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ function UsersList() {
|
|||
<div className="u-search__user">
|
||||
<Avatar size="sm" user={user} />
|
||||
<div>
|
||||
<div>{user.discordName}</div>
|
||||
<div>{user.username}</div>
|
||||
{user.inGameName ? (
|
||||
<div className="u-search__ign">
|
||||
{t("user:ign.short")}: {user.inGameName}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { Link } from "@remix-run/react";
|
||||
import { Avatar } from "~/components/Avatar";
|
||||
import { discordFullName } from "~/utils/strings";
|
||||
import { userVodsPage } from "~/utils/urls";
|
||||
import type { Vod } from "../vods-types";
|
||||
|
||||
|
|
@ -14,7 +13,7 @@ export function PovUser({ pov }: { pov: Vod["pov"] }) {
|
|||
return (
|
||||
<Link to={userVodsPage(pov)} className="stack horizontal xs">
|
||||
<Avatar user={pov} size="xxs" />
|
||||
<span className="text-sm font-semi-bold">{discordFullName(pov)}</span>
|
||||
<span className="text-sm font-semi-bold">{pov.username}</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,14 +24,12 @@ const videoMatchesStm = sql.prepare(/* sql */ `
|
|||
json_group_array("vp"."playerName") as "playerNames",
|
||||
json_group_array(
|
||||
json_object(
|
||||
'discordName',
|
||||
"u"."discordName",
|
||||
'username',
|
||||
"u"."username",
|
||||
'discordId',
|
||||
"u"."discordId",
|
||||
'discordAvatar',
|
||||
"u"."discordAvatar",
|
||||
'discordDiscriminator',
|
||||
"u"."discordDiscriminator",
|
||||
'customUrl',
|
||||
"u"."customUrl",
|
||||
'id',
|
||||
|
|
|
|||
|
|
@ -16,14 +16,12 @@ const query = (byUser?: true) => /* sql */ `
|
|||
json_group_array("vp"."playerName") as "playerNames",
|
||||
json_group_array(
|
||||
json_object(
|
||||
'discordName',
|
||||
"u"."discordName",
|
||||
'username',
|
||||
"u"."username",
|
||||
'discordId',
|
||||
"u"."discordId",
|
||||
'discordAvatar',
|
||||
"u"."discordAvatar",
|
||||
'discordDiscriminator',
|
||||
"u"."discordDiscriminator",
|
||||
'customUrl',
|
||||
"u"."customUrl"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,12 +14,7 @@ export interface Vod {
|
|||
pov?:
|
||||
| Pick<
|
||||
User,
|
||||
| "discordName"
|
||||
| "discordId"
|
||||
| "discordAvatar"
|
||||
| "discordDiscriminator"
|
||||
| "customUrl"
|
||||
| "id"
|
||||
"username" | "discordId" | "discordAvatar" | "customUrl" | "id"
|
||||
>
|
||||
| string;
|
||||
title: Video["title"];
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
|
|||
loginDisabled: process.env["LOGIN_DISABLED"] === "true",
|
||||
user: user
|
||||
? {
|
||||
discordName: user.discordName,
|
||||
username: user.username,
|
||||
discordAvatar: user.discordAvatar,
|
||||
discordId: user.discordId,
|
||||
id: user.id,
|
||||
|
|
|
|||
|
|
@ -30,11 +30,7 @@
|
|||
align-items: center;
|
||||
grid-area: name;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.u__discriminator {
|
||||
color: var(--text-lighter);
|
||||
margin-inline-end: var(--s-2);
|
||||
gap: var(--s-2-5);
|
||||
}
|
||||
|
||||
.u__country-name {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ export const database = {
|
|||
Array.from({ length: count }).map((_, i) => ({
|
||||
id: i + 1,
|
||||
discordName: `user${i + 1}`,
|
||||
discordDiscriminator: "0",
|
||||
discordId: String(i),
|
||||
})),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Tables } from "~/db/tables";
|
|||
|
||||
export const COMMON_USER_FIELDS = [
|
||||
"User.id",
|
||||
"User.discordName",
|
||||
"User.username",
|
||||
"User.discordId",
|
||||
"User.discordAvatar",
|
||||
"User.customUrl",
|
||||
|
|
@ -11,7 +11,7 @@ export const COMMON_USER_FIELDS = [
|
|||
|
||||
export type CommonUser = Pick<
|
||||
Tables["User"],
|
||||
"id" | "discordName" | "discordId" | "discordAvatar" | "customUrl"
|
||||
"id" | "username" | "discordId" | "discordAvatar" | "customUrl"
|
||||
>;
|
||||
|
||||
export const userChatNameColor = sql<
|
||||
|
|
|
|||
|
|
@ -1,18 +1,6 @@
|
|||
import type { GearType, User } from "~/db/types";
|
||||
import type { GearType } from "~/db/types";
|
||||
import { assertUnreachable } from "./types";
|
||||
|
||||
export const isNewDiscordUniqueName = (discordDiscriminator: string) =>
|
||||
discordDiscriminator === "0";
|
||||
|
||||
export function discordFullName(
|
||||
user: Pick<User, "discordName" | "discordDiscriminator">,
|
||||
) {
|
||||
if (isNewDiscordUniqueName(user.discordDiscriminator)) {
|
||||
return user.discordName;
|
||||
}
|
||||
return `${user.discordName}#${user.discordDiscriminator}`;
|
||||
}
|
||||
|
||||
export function inGameNameWithoutDiscriminator(inGameName: string) {
|
||||
return inGameName.split("#")[0];
|
||||
}
|
||||
|
|
|
|||
BIN
db-test.sqlite3
BIN
db-test.sqlite3
Binary file not shown.
|
|
@ -190,7 +190,7 @@ test.describe("Tournament", () => {
|
|||
await teamSelect.selectOption(String(teamWithSpace.id));
|
||||
await selectUser({
|
||||
labelName: "User",
|
||||
userName: firstNonOwnerMember.discordName,
|
||||
userName: firstNonOwnerMember.username,
|
||||
page,
|
||||
});
|
||||
await submit(page);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"customUrl": "Custom URL",
|
||||
"customName": "Custom name",
|
||||
"ign": "In-game name",
|
||||
"ign.short": "IGN",
|
||||
"country": "Country",
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
"forms.commissionsOpen": "Commissions open",
|
||||
"forms.commissionText": "Commission info",
|
||||
"forms.commissionText.info": "Price, slots open or other info related to commissioning you",
|
||||
"forms.customName.info": "If missing, your Discord display name is used: \"{{discordName}}\"",
|
||||
|
||||
"results.title": "Results",
|
||||
"results.placing": "Placing",
|
||||
|
|
|
|||
13
migrations/059-user-name.js
Normal file
13
migrations/059-user-name.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
export function up(db) {
|
||||
db.transaction(() => {
|
||||
db.prepare(/* sql */ `alter table "User" add "customName" text`).run();
|
||||
})();
|
||||
|
||||
db.prepare(
|
||||
/* sql */ `alter table "User" add "username" text generated always as (coalesce("customName", "discordName")) virtual`,
|
||||
).run();
|
||||
|
||||
db.prepare(
|
||||
/* sql */ `alter table "User" drop column "discordDiscriminator"`,
|
||||
).run();
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user