diff --git a/app/components/BuildCard.tsx b/app/components/BuildCard.tsx index 2b0aa5b23..ace1cc552 100644 --- a/app/components/BuildCard.tsx +++ b/app/components/BuildCard.tsx @@ -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; 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}
diff --git a/app/components/UserSearch.tsx b/app/components/UserSearch.tsx index 63f469dc0..1ce6fc1e9 100644 --- a/app/components/UserSearch.tsx +++ b/app/components/UserSearch.tsx @@ -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({
- - {user.discordName} - {" "} + {user.username}{" "} {user.plusTier ? ( +{user.plusTier} ) : null} diff --git a/app/components/layout/Footer.tsx b/app/components/layout/Footer.tsx index ace106bd8..8b4b3ef89 100644 --- a/app/components/layout/Footer.tsx +++ b/app/components/layout/Footer.tsx @@ -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} ))} diff --git a/app/components/layout/UserItem.tsx b/app/components/layout/UserItem.tsx index 606fa4e07..bbfe2a35e 100644 --- a/app/components/layout/UserItem.tsx +++ b/app/components/layout/UserItem.tsx @@ -18,7 +18,7 @@ export function UserItem() { ) { return () => ({ discordAvatar: null, - discordDiscriminator: String(faker.string.numeric(4)), discordId: String(faker.string.numeric(17)), discordName: uniqueDiscordName(usedNames), twitch: null, diff --git a/app/db/tables.ts b/app/db/tables.ts index ec7dbd83a..45d70b275 100644 --- a/app/db/tables.ts +++ b/app/db/tables.ts @@ -667,9 +667,11 @@ export interface User { css: ColumnType | 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; discordUniqueName: string | null; favoriteBadgeId: number | null; id: GeneratedAlways; diff --git a/app/db/types.ts b/app/db/types.ts index 1bd208e65..ea5fbf778 100644 --- a/app/db/types.ts +++ b/app/db/types.ts @@ -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; diff --git a/app/features/api-public/routes/tournament.$id.teams.ts b/app/features/api-public/routes/tournament.$id.teams.ts index 1d60d8bd6..00b6bc478 100644 --- a/app/features/api-public/routes/tournament.$id.teams.ts +++ b/app/features/api-public/routes/tournament.$id.teams.ts @@ -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` diff --git a/app/features/art/art-types.ts b/app/features/art/art-types.ts index d728e1b89..29255af99 100644 --- a/app/features/art/art-types.ts +++ b/app/features/art/art-types.ts @@ -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"]; }; diff --git a/app/features/art/components/ArtGrid.tsx b/app/features/art/components/ArtGrid.tsx index 2526dc8c6..e1b1849dc 100644 --- a/app/features/art/components/ArtGrid.tsx +++ b/app/features/art/components/ArtGrid.tsx @@ -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} ))} {art.tags?.map((tag) => ( @@ -205,7 +204,7 @@ function ImagePreview({ })} > - {t("art:madeBy")} {discordFullName(art.author)} + {t("art:madeBy")} {art.author.username}
); @@ -220,7 +219,7 @@ function ImagePreview({ })} > - {discordFullName(art.author)} + {art.author.username}
); diff --git a/app/features/art/queries/artsByUserId.server.ts b/app/features/art/queries/artsByUserId.server.ts index 7b8e98f3e..dd6684a29 100644 --- a/app/features/art/queries/artsByUserId.server.ts +++ b/app/features/art/queries/artsByUserId.server.ts @@ -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, }; diff --git a/app/features/art/queries/showcaseArts.server.ts b/app/features/art/queries/showcaseArts.server.ts index 5f5c16268..46dd60ca8 100644 --- a/app/features/art/queries/showcaseArts.server.ts +++ b/app/features/art/queries/showcaseArts.server.ts @@ -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, }, })); } diff --git a/app/features/auth/core/DiscordStrategy.server.ts b/app/features/auth/core/DiscordStrategy.server.ts index 99d38147b..e4bcb2346 100644 --- a/app/features/auth/core/DiscordStrategy.server.ts +++ b/app/features/auth/core/DiscordStrategy.server.ts @@ -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, diff --git a/app/features/auth/core/routes.server.ts b/app/features/auth/core/routes.server.ts index a65b5a8dd..264235d73 100644 --- a/app/features/auth/core/routes.server.ts +++ b/app/features/auth/core/routes.server.ts @@ -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, diff --git a/app/features/badges/BadgeRepository.server.ts b/app/features/badges/BadgeRepository.server.ts index a9e02d03e..d7509ffca 100644 --- a/app/features/badges/BadgeRepository.server.ts +++ b/app/features/badges/BadgeRepository.server.ts @@ -90,7 +90,7 @@ export function findOwnersByBadgeId(badgeId: number) { fn.count("BadgeOwner.badgeId").as("count"), "User.id", "User.discordId", - "User.discordName", + "User.username", ]) .where("BadgeOwner.badgeId", "=", badgeId) .groupBy("User.id") diff --git a/app/features/badges/routes/badges.$id.edit.tsx b/app/features/badges/routes/badges.$id.edit.tsx index bfdb32146..de713edec 100644 --- a/app/features/badges/routes/badges.$id.edit.tsx +++ b/app/features/badges/routes/badges.$id.edit.tsx @@ -126,7 +126,7 @@ function Managers({ data }: { data: BadgeDetailsLoaderData }) {
    {managers.map((manager) => (
  • - {manager.discordName} + {manager.username}
  • @@ -353,7 +353,7 @@ function Description() {
    - {discordFullName(data.event)} + {data.event.username}
    {data.event.description && (
    {data.event.description}
    diff --git a/app/features/calendar/routes/calendar.tsx b/app/features/calendar/routes/calendar.tsx index 8eee6e6b0..b8f3c594a 100644 --- a/app/features/calendar/routes/calendar.tsx +++ b/app/features/calendar/routes/calendar.tsx @@ -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({
    {t("from", { - author: discordFullName(calendarEvent), + author: calendarEvent.username, })}
    {sectionWeekday !== eventWeekday ? ( diff --git a/app/features/chat/components/Chat.tsx b/app/features/chat/components/Chat.tsx index 90ea24c88..603b2135f 100644 --- a/app/features/chat/components/Chat.tsx +++ b/app/features/chat/components/Chat.tsx @@ -17,7 +17,7 @@ import { soundPath } from "~/utils/urls"; import { useTranslation } from "react-i18next"; import { logger } from "~/utils/logger"; -type ChatUser = Pick & { +type ChatUser = Pick & { chatNameColor: string | null; title?: string; }; @@ -239,7 +239,7 @@ function Message({ : undefined } > - {user?.discordName ?? missingUserName} + {user?.username ?? missingUserName}
    {user?.title ? (
    diff --git a/app/features/front-page/routes/index.tsx b/app/features/front-page/routes/index.tsx index 7c78677d9..d42d2d607 100644 --- a/app/features/front-page/routes/index.tsx +++ b/app/features/front-page/routes/index.tsx @@ -202,7 +202,7 @@ function TournamentCard({
      {tournament.firstPlacers.map((p) => ( -
    • {p.discordName}
    • +
    • {p.username}
    • ))}
    @@ -228,7 +228,7 @@ function LogInButton() { "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; diff --git a/app/features/leaderboards/queries/userSPLeaderboard.server.ts b/app/features/leaderboards/queries/userSPLeaderboard.server.ts index b8fbf12db..6fb31a44e 100644 --- a/app/features/leaderboards/queries/userSPLeaderboard.server.ts +++ b/app/features/leaderboards/queries/userSPLeaderboard.server.ts @@ -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"]; diff --git a/app/features/leaderboards/routes/leaderboards.tsx b/app/features/leaderboards/routes/leaderboards.tsx index 08ac6b675..e693f9cc4 100644 --- a/app/features/leaderboards/routes/leaderboards.tsx +++ b/app/features/leaderboards/routes/leaderboards.tsx @@ -372,7 +372,7 @@ function OwnEntryPeek({ height={32} /> ) : null} -
    {entry.discordName}
    +
    {entry.username}
    {entry.power}
    @@ -435,7 +435,7 @@ function PlayersTable({ /> ) : null}
    - {entry.discordName} + {entry.username}
    {entry.pendingPlusTier ? (
    @@ -493,7 +493,7 @@ function TeamTable({ {entry.members.map((member, i) => { return ( - {member.discordName} + {member.username} {i !== entry.members.length - 1 ? ", " : null} ); diff --git a/app/features/lfg/components/LFGPost.tsx b/app/features/lfg/components/LFGPost.tsx index 51b09b46f..c95ac67a4 100644 --- a/app/features/lfg/components/LFGPost.tsx +++ b/app/features/lfg/components/LFGPost.tsx @@ -210,7 +210,7 @@ function PostTeamMember({
    - {member.discordName} + {member.username} {tier ? : null}
    @@ -232,7 +232,7 @@ function PostUserHeader({
    - {author.discordName} + {author.username} {" "} {author.country ? : null}
    diff --git a/app/features/plus-suggestions/PlusSuggestionRepository.server.ts b/app/features/plus-suggestions/PlusSuggestionRepository.server.ts index cac3451a2..7293d5950 100644 --- a/app/features/plus-suggestions/PlusSuggestionRepository.server.ts +++ b/app/features/plus-suggestions/PlusSuggestionRepository.server.ts @@ -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; diff --git a/app/features/plus-suggestions/routes/plus.suggestions.comment.$tier.$userId.tsx b/app/features/plus-suggestions/routes/plus.suggestions.comment.$tier.$userId.tsx index c1cb379cc..e5bbce72b 100644 --- a/app/features/plus-suggestions/routes/plus.suggestions.comment.$tier.$userId.tsx +++ b/app/features/plus-suggestions/routes/plus.suggestions.comment.$tier.$userId.tsx @@ -106,7 +106,7 @@ export default function PlusCommentModalPage() {

    - {userBeingCommented.suggested.discordName}'s +{tierSuggestedTo}{" "} + {userBeingCommented.suggested.username}'s +{tierSuggestedTo}{" "} suggestion

    diff --git a/app/features/plus-suggestions/routes/plus.suggestions.tsx b/app/features/plus-suggestions/routes/plus.suggestions.tsx index b5c9de700..f335d8e7a 100644 --- a/app/features/plus-suggestions/routes/plus.suggestions.tsx +++ b/app/features/plus-suggestions/routes/plus.suggestions.tsx @@ -309,7 +309,7 @@ function SuggestedUser({

    - {suggestion.suggested.discordName} + {suggestion.suggested.username}

    {canAddCommentToSuggestionFE({ @@ -366,7 +366,7 @@ export function PlusSuggestionComments({ {suggestion.suggestions.map((suggestion) => { return (
    - {suggestion.author.discordName} + {suggestion.author.username} {suggestion.text}
    @@ -388,9 +388,7 @@ export function PlusSuggestionComments({
    diff --git a/app/features/plus-voting/routes/plus.voting.tsx b/app/features/plus-voting/routes/plus.voting.tsx index f8fac70a6..ab7468bbe 100644 --- a/app/features/plus-voting/routes/plus.voting.tsx +++ b/app/features/plus-voting/routes/plus.voting.tsx @@ -275,7 +275,7 @@ function Voting(data: Extract) { {previous.score > 0 ? "+" : ""} {previous.score} {" "} - on {previous.user.discordName}. + on {previous.user.username}. @@ -286,7 +286,7 @@ function Voting(data: Extract) { {currentUser ? (
    -

    {currentUser.user.discordName}

    +

    {currentUser.user.username}

    @@ -296,7 +296,7 @@ function GroupMember({ {inGameNameWithoutDiscriminator(member.inGameName)} ) : ( - member.discordName + member.username )}
    diff --git a/app/features/sendouq/components/MemberAdder.tsx b/app/features/sendouq/components/MemberAdder.tsx index fdd296dde..22a9c3464 100644 --- a/app/features/sendouq/components/MemberAdder.tsx +++ b/app/features/sendouq/components/MemberAdder.tsx @@ -127,7 +127,7 @@ function TrusterDropdown({ {trustersNotInGroup.map((player) => { return ( ); })} diff --git a/app/features/sendouq/q-types.ts b/app/features/sendouq/q-types.ts index 0222fb28f..939ff9b60 100644 --- a/app/features/sendouq/q-types.ts +++ b/app/features/sendouq/q-types.ts @@ -27,7 +27,7 @@ export type LookingGroup = { members?: { id: number; discordId: string; - discordName: string; + username: string; discordAvatar: string | null; noScreen?: number; customUrl?: User["customUrl"]; diff --git a/app/features/sendouq/queries/findGroupByInviteCode.server.ts b/app/features/sendouq/queries/findGroupByInviteCode.server.ts index dbd366801..03b5bca9e 100644 --- a/app/features/sendouq/queries/findGroupByInviteCode.server.ts +++ b/app/features/sendouq/queries/findGroupByInviteCode.server.ts @@ -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; diff --git a/app/features/sendouq/queries/findPreparingGroup.server.ts b/app/features/sendouq/queries/findPreparingGroup.server.ts index c303deeae..ffaaaf230 100644 --- a/app/features/sendouq/queries/findPreparingGroup.server.ts +++ b/app/features/sendouq/queries/findPreparingGroup.server.ts @@ -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", diff --git a/app/features/sendouq/queries/seasonMatchesByUserId.server.ts b/app/features/sendouq/queries/seasonMatchesByUserId.server.ts index 5180f7bfc..114a7678a 100644 --- a/app/features/sendouq/queries/seasonMatchesByUserId.server.ts +++ b/app/features/sendouq/queries/seasonMatchesByUserId.server.ts @@ -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; diff --git a/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts b/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts index ec09e7001..20e45aca0 100644 --- a/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts +++ b/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts @@ -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" >; }>; } diff --git a/app/features/sendouq/routes/q.looking.tsx b/app/features/sendouq/routes/q.looking.tsx index bc15e103d..8aeeaeb7b 100644 --- a/app/features/sendouq/routes/q.looking.tsx +++ b/app/features/sendouq/routes/q.looking.tsx @@ -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 }, }); } diff --git a/app/features/sendouq/routes/q.match.$id.tsx b/app/features/sendouq/routes/q.match.$id.tsx index 419335d4d..65c455bfc 100644 --- a/app/features/sendouq/routes/q.match.$id.tsx +++ b/app/features/sendouq/routes/q.match.$id.tsx @@ -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({
    - {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 )}
    @@ -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" > - {user?.discordName} + {user?.username}
    ); })} @@ -1825,7 +1825,7 @@ function MapListMapPickInfo({ className="q-settings__radio__emoji" width={18} /> - {userIdToUser(userId)?.discordName} + {userIdToUser(userId)?.username}
    ); }) diff --git a/app/features/sendouq/routes/q.tsx b/app/features/sendouq/routes/q.tsx index 44fcaaa80..37c82a62c 100644 --- a/app/features/sendouq/routes/q.tsx +++ b/app/features/sendouq/routes/q.tsx @@ -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)), })} {t("q:front.join.joinWithTrustAction", { - inviterName: owner.discordName, + inviterName: owner.username, })}
    {selectedTeam.members.map((member) => ( ))} @@ -682,7 +682,7 @@ function StaffList() { > {" "}
    -
    {staff.discordName}
    +
    {staff.username}
    {t(`tournament:staff.role.${staff.role}`)}
    @@ -703,7 +703,7 @@ function RemoveStaffButton({ return ( !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"); diff --git a/app/features/tournament/routes/to.$id.join.tsx b/app/features/tournament/routes/to.$id.join.tsx index 6eb302c4c..7a012d29d 100644 --- a/app/features/tournament/routes/to.$id.join.tsx +++ b/app/features/tournament/routes/to.$id.join.tsx @@ -171,7 +171,7 @@ export default function JoinTeamPage() { {" "}
    diff --git a/app/features/tournament/routes/to.$id.register.tsx b/app/features/tournament/routes/to.$id.register.tsx index 4cc499830..55a4226e3 100644 --- a/app/features/tournament/routes/to.$id.register.tsx +++ b/app/features/tournament/routes/to.$id.register.tsx @@ -328,7 +328,7 @@ export default function TournamentRegisterPage() { className="stack horizontal xs items-center text-lighter" > {" "} - {tournament.ctx.author.discordName} + {tournament.ctx.author.username}
    {" "} @@ -979,7 +979,7 @@ function FillRoster({ data-testid={`member-num-${i + 1}`} > - {member.discordName} + {member.username}
    ); })} @@ -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 ( ); })} @@ -1078,7 +1078,7 @@ function DeleteMember({ members }: { members: TournamentDataTeam["members"] }) { .filter((member) => !member.isOwner) .map((member) => ( ))} diff --git a/app/features/tournament/routes/to.$id.seeds.tsx b/app/features/tournament/routes/to.$id.seeds.tsx index bb69c95fb..d1560cf7b 100644 --- a/app/features/tournament/routes/to.$id.seeds.tsx +++ b/app/features/tournament/routes/to.$id.seeds.tsx @@ -314,7 +314,7 @@ function RowContents({ target="_blank" className="tournament__seeds__team-member__name" > - {member.discordName} + {member.username} {member.plusTier ? (
    - {user.discordName} + {user.username} ); })} diff --git a/app/features/user-page/UserRepository.server.ts b/app/features/user-page/UserRepository.server.ts index 30a1f9359..1ee4d78d4 100644 --- a/app/features/user-page/UserRepository.server.ts +++ b/app/features/user-page/UserRepository.server.ts @@ -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, diff --git a/app/features/user-page/components/UserResultsTable.tsx b/app/features/user-page/components/UserResultsTable.tsx index 5fbc3529a..04890c27e 100644 --- a/app/features/user-page/components/UserResultsTable.tsx +++ b/app/features/user-page/components/UserResultsTable.tsx @@ -135,7 +135,7 @@ export function UserResultsTable({ className="stack horizontal xs items-center" > - {player.discordName} + {player.username} )} diff --git a/app/features/user-page/routes/u.$identifier.edit.tsx b/app/features/user-page/routes/u.$identifier.edit.tsx index b6054b9f0..1303e14e9 100644 --- a/app/features/user-page/routes/u.$identifier.edit.tsx +++ b/app/features/user-page/routes/u.$identifier.edit.tsx @@ -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) ? ( ) : null} + @@ -290,6 +295,31 @@ function CustomUrlInput({ ); } +function CustomNameInput({ + parentRouteData, +}: { + parentRouteData: UserPageLoaderData; +}) { + const { t } = useTranslation(["user"]); + + return ( +
    + + + + {t("user:forms.customName.info", { + discordName: parentRouteData.discordName, + })} + +
    + ); +} + function InGameNameInputs({ parentRouteData, }: { diff --git a/app/features/user-page/routes/u.$identifier.index.tsx b/app/features/user-page/routes/u.$identifier.index.tsx index 3c571bec1..8681662a4 100644 --- a/app/features/user-page/routes/u.$identifier.index.tsx +++ b/app/features/user-page/routes/u.$identifier.index.tsx @@ -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() {

    -
    {data.discordName}
    +
    {data.username}
    - - {!isNewDiscordUniqueName(data.discordDiscriminator) ? ( - <> - #{data.discordDiscriminator} - - - ) : null} - {data.country ? : null}

    diff --git a/app/features/user-page/routes/u.$identifier.seasons.tsx b/app/features/user-page/routes/u.$identifier.seasons.tsx index 8b1622b34..e7c43d9ee 100644 --- a/app/features/user-page/routes/u.$identifier.seasons.tsx +++ b/app/features/user-page/routes/u.$identifier.seasons.tsx @@ -579,7 +579,7 @@ function Players({ className="u__season__player-name" > - {player.user.discordName} + {player.user.username}
    - {member.discordName} + {member.username} {typeof member.weaponSplId === "number" ? ( = ({ 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", }, diff --git a/app/features/user-search/routes/u.tsx b/app/features/user-search/routes/u.tsx index 3e4170698..8c4fed2dd 100644 --- a/app/features/user-search/routes/u.tsx +++ b/app/features/user-search/routes/u.tsx @@ -102,7 +102,7 @@ function UsersList() {
    -
    {user.discordName}
    +
    {user.username}
    {user.inGameName ? (
    {t("user:ign.short")}: {user.inGameName} diff --git a/app/features/vods/components/VodPov.tsx b/app/features/vods/components/VodPov.tsx index ac17677e6..0b984bf5b 100644 --- a/app/features/vods/components/VodPov.tsx +++ b/app/features/vods/components/VodPov.tsx @@ -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 ( - {discordFullName(pov)} + {pov.username} ); } diff --git a/app/features/vods/queries/findVodById.server.ts b/app/features/vods/queries/findVodById.server.ts index 525b6082d..13d002e96 100644 --- a/app/features/vods/queries/findVodById.server.ts +++ b/app/features/vods/queries/findVodById.server.ts @@ -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', diff --git a/app/features/vods/queries/findVods.server.ts b/app/features/vods/queries/findVods.server.ts index 2574c5caf..cd7c668f3 100644 --- a/app/features/vods/queries/findVods.server.ts +++ b/app/features/vods/queries/findVods.server.ts @@ -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" ) diff --git a/app/features/vods/vods-types.ts b/app/features/vods/vods-types.ts index 4c13fe29c..6c7e5a1b2 100644 --- a/app/features/vods/vods-types.ts +++ b/app/features/vods/vods-types.ts @@ -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"]; diff --git a/app/root.tsx b/app/root.tsx index 19f435efa..b258a2c55 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -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, diff --git a/app/styles/u.css b/app/styles/u.css index a680d80ed..2facf7c13 100644 --- a/app/styles/u.css +++ b/app/styles/u.css @@ -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 { diff --git a/app/utils/Test.ts b/app/utils/Test.ts index ea545a20b..b74ec8704 100644 --- a/app/utils/Test.ts +++ b/app/utils/Test.ts @@ -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), })), ) diff --git a/app/utils/kysely.server.ts b/app/utils/kysely.server.ts index 59ab04eb1..9e82c1c46 100644 --- a/app/utils/kysely.server.ts +++ b/app/utils/kysely.server.ts @@ -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< diff --git a/app/utils/strings.ts b/app/utils/strings.ts index 095f7908f..950662e63 100644 --- a/app/utils/strings.ts +++ b/app/utils/strings.ts @@ -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, -) { - if (isNewDiscordUniqueName(user.discordDiscriminator)) { - return user.discordName; - } - return `${user.discordName}#${user.discordDiscriminator}`; -} - export function inGameNameWithoutDiscriminator(inGameName: string) { return inGameName.split("#")[0]; } diff --git a/db-test.sqlite3 b/db-test.sqlite3 index 176a7d9b5..06bcf1e0e 100644 Binary files a/db-test.sqlite3 and b/db-test.sqlite3 differ diff --git a/e2e/tournament.spec.ts b/e2e/tournament.spec.ts index eba59e2be..b79ea6186 100644 --- a/e2e/tournament.spec.ts +++ b/e2e/tournament.spec.ts @@ -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); diff --git a/locales/en/user.json b/locales/en/user.json index 714e8f46a..f42579b5e 100644 --- a/locales/en/user.json +++ b/locales/en/user.json @@ -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", diff --git a/migrations/059-user-name.js b/migrations/059-user-name.js new file mode 100644 index 000000000..75275bc89 --- /dev/null +++ b/migrations/059-user-name.js @@ -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(); +}