From ca972ece84c5b993cb755eb4f1a5694fa9219efc Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Thu, 26 Dec 2024 11:37:14 +0200 Subject: [PATCH] Short link feature --- app/features/info/routes/support.tsx | 5 +++++ app/features/user-page/UserRepository.server.ts | 8 ++++++++ .../user-page/routes/short.$customUrl.tsx | 15 +++++++++++++++ .../user-page/routes/u.$identifier.edit.tsx | 1 + app/routes.ts | 2 ++ locales/en/common.json | 2 ++ locales/en/user.json | 1 + 7 files changed, 34 insertions(+) create mode 100644 app/features/user-page/routes/short.$customUrl.tsx diff --git a/app/features/info/routes/support.tsx b/app/features/info/routes/support.tsx index 17807febd..79ea1ca25 100644 --- a/app/features/info/routes/support.tsx +++ b/app/features/info/routes/support.tsx @@ -48,6 +48,11 @@ const PERKS = [ name: "prioritySupport", extraInfo: true, }, + { + tier: 2, + name: "userShortLink", + extraInfo: true, + }, { tier: 2, name: "customizedColorsUser", diff --git a/app/features/user-page/UserRepository.server.ts b/app/features/user-page/UserRepository.server.ts index c0037c605..01dce4d3a 100644 --- a/app/features/user-page/UserRepository.server.ts +++ b/app/features/user-page/UserRepository.server.ts @@ -255,6 +255,14 @@ export async function findProfileByIdentifier( }; } +export function findByCustomUrl(customUrl: string) { + return db + .selectFrom("User") + .select(["User.id", "User.discordId", "User.customUrl", "User.patronTier"]) + .where("customUrl", "=", customUrl) + .executeTakeFirst(); +} + export function findBannedStatusByUserId(userId: number) { return db .selectFrom("User") diff --git a/app/features/user-page/routes/short.$customUrl.tsx b/app/features/user-page/routes/short.$customUrl.tsx new file mode 100644 index 000000000..ac15d9285 --- /dev/null +++ b/app/features/user-page/routes/short.$customUrl.tsx @@ -0,0 +1,15 @@ +import type { LoaderFunction } from "@remix-run/node"; +import { redirect } from "react-router-dom"; +import * as UserRepository from "~/features/user-page/UserRepository.server"; +import { userPage } from "~/utils/urls"; +import { isAtLeastFiveDollarTierPatreon } from "~/utils/users"; + +export const loader: LoaderFunction = async ({ params }) => { + const user = await UserRepository.findByCustomUrl(params.customUrl!); + + if (!user || !isAtLeastFiveDollarTierPatreon(user)) { + return redirect("/"); + } + + return redirect(userPage(user)); +}; diff --git a/app/features/user-page/routes/u.$identifier.edit.tsx b/app/features/user-page/routes/u.$identifier.edit.tsx index f943e61d7..52ef6c4db 100644 --- a/app/features/user-page/routes/u.$identifier.edit.tsx +++ b/app/features/user-page/routes/u.$identifier.edit.tsx @@ -321,6 +321,7 @@ function CustomUrlInput({ maxLength={USER.CUSTOM_URL_MAX_LENGTH} defaultValue={parentRouteData.user.customUrl ?? undefined} /> + {t("user:forms.info.customUrl")} ); } diff --git a/app/routes.ts b/app/routes.ts index 09f410d0e..dc0195644 100644 --- a/app/routes.ts +++ b/app/routes.ts @@ -227,6 +227,8 @@ export default [ route("/org/:id", "features/api-public/routes/org.$id.ts"), ]), + route("/short/:customUrl", "features/user-page/routes/short.$customUrl.tsx"), + route("/theme", "features/theme/routes/theme.ts"), ...prefix("/auth", [ diff --git a/locales/en/common.json b/locales/en/common.json index 945f79202..cab9440d1 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -187,6 +187,8 @@ "support.perk.seePlusPercentage.extra": "Normally only failed suggests see their voting percentage. With this, you can always see your own percentage.", "support.perk.autoValidatePictures": "Auto validate uploaded pictures", "support.perk.autoValidatePictures.extra": "Any images you upload (e.g. team profile/banner picture) get automatically validated. Normally it needs a moderator's approval first. Note that this doesn't apply to images that were already submitted.", + "support.perk.userShortLink": "User page short link", + "support.perk.userShortLink.extra": "Instead of e.g. sendou.ink/u/sendou you can also use snd.ink/sendou when linking to your user profile.", "support.perk.customizedColorsUser": "Customize colors (user page)", "support.perk.customizedColorsTeam": "Customize colors (team page)", "support.perk.customizedColorsTeam.extra": "It is enough that one member of the team is a patron to get this perk.", diff --git a/locales/en/user.json b/locales/en/user.json index 41c24e407..0199bf0d0 100644 --- a/locales/en/user.json +++ b/locales/en/user.json @@ -40,6 +40,7 @@ "forms.errors.invalidCustomUrl.strangeCharacter": "Custom URL can't contain special characters", "forms.errors.invalidCustomUrl.duplicate": "Someone is already using this custom URL", "forms.errors.invalidSens": "Motion sens can't be set if R-stick sens isn't", + "forms.info.customUrl": "For patrons (Supporter & above) short link is available. E.g. instead of sendou.ink/u/sendou, snd.ink/sendou can be used.", "forms.info.favoriteBadge": "Your favorite badge is shown as big by default on your profile.", "forms.info.battlefy": "Battlefy account name is used for seeding and verification in some tournaments",