fix: resolve TypeScript and lint issues
- Fix proxy routes to use resolveImagerBase instead of removed resolveUpstreamBase - Fix avatarImageUrl type signature to use AvatarOptions - Run biome formatter
This commit is contained in:
1 parent
fc7e6ca248
commit
7a2c0fd4d4
19 files changed
+86
-164
No files matched your search
@@ -0,0 +1,27 @@
|
|||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { WebsiteSetting } from "@/db/schema";
|
||||||
|
import { db } from "./src/lib/db";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const result = await db
|
||||||
|
.select()
|
||||||
|
.from(WebsiteSetting)
|
||||||
|
.where(eq(WebsiteSetting.key, "habbo_imaging_url"));
|
||||||
|
console.log("Current:", result);
|
||||||
|
|
||||||
|
if (result[0]?.value !== "/imaging") {
|
||||||
|
await db
|
||||||
|
.update(WebsiteSetting)
|
||||||
|
.set({ value: "/imaging" })
|
||||||
|
.where(eq(WebsiteSetting.key, "habbo_imaging_url"));
|
||||||
|
console.log("Updated to /imaging");
|
||||||
|
} else {
|
||||||
|
console.log("Already correct");
|
||||||
|
}
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -8,7 +8,6 @@ import { ContentCard, EmptyState, OnlineBadge } from "@/components/public/ui";
|
|||||||
import { auth } from "@/lib/auth";
|
import { auth } from "@/lib/auth";
|
||||||
import { db, MessengerFriendships, User } from "@/lib/db";
|
import { db, MessengerFriendships, User } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
export const metadata = { title: "Friends" };
|
export const metadata = { title: "Friends" };
|
||||||
|
|
||||||
@@ -66,26 +65,20 @@ export default async function FriendsPage({
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [friends, imagerBase] = await Promise.all([
|
const friends = friendIds.length
|
||||||
friendIds.length
|
? await db
|
||||||
? db
|
.select({
|
||||||
.select({
|
id: User.id,
|
||||||
id: User.id,
|
username: User.username,
|
||||||
username: User.username,
|
look: User.look,
|
||||||
look: User.look,
|
motto: User.motto,
|
||||||
motto: User.motto,
|
online: User.online,
|
||||||
online: User.online,
|
})
|
||||||
})
|
.from(User)
|
||||||
.from(User)
|
.where(inArray(User.id, friendIds))
|
||||||
.where(inArray(User.id, friendIds))
|
.orderBy(asc(User.username))
|
||||||
.orderBy(asc(User.username))
|
.catch(() => [])
|
||||||
.catch(() => [])
|
: [];
|
||||||
: Promise.resolve([]),
|
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const errorMessage =
|
const errorMessage =
|
||||||
error === "not_found"
|
error === "not_found"
|
||||||
@@ -125,7 +118,7 @@ export default async function FriendsPage({
|
|||||||
) : (
|
) : (
|
||||||
<div className="card-grid sm-2 lg-3" style={{ padding: "1rem" }}>
|
<div className="card-grid sm-2 lg-3" style={{ padding: "1rem" }}>
|
||||||
{friends.map((friend) => {
|
{friends.map((friend) => {
|
||||||
const avatar = avatarImageUrl(imagerBase ?? "", friend.look, {
|
const avatar = avatarImageUrl(friend.look, {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { ContentCard, EmptyState, StatBlock } from "@/components/public/ui";
|
|||||||
import { db, Guilds, GuildsMembers, User } from "@/lib/db";
|
import { db, Guilds, GuildsMembers, User } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { formatDate } from "@/lib/format-date";
|
import { formatDate } from "@/lib/format-date";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
type GuildView = {
|
type GuildView = {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -98,11 +97,6 @@ export default async function GuildPage({
|
|||||||
users = [];
|
users = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const imagerBase = await siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
);
|
|
||||||
|
|
||||||
const usersById = new Map(users.map((u) => [u.id, u]));
|
const usersById = new Map(users.map((u) => [u.id, u]));
|
||||||
const sinceById = new Map(memberRows.map((m) => [m.userId, m.memberSince]));
|
const sinceById = new Map(memberRows.map((m) => [m.userId, m.memberSince]));
|
||||||
|
|
||||||
@@ -211,7 +205,7 @@ export default async function GuildPage({
|
|||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
<img
|
<img
|
||||||
className="avatar"
|
className="avatar"
|
||||||
src={avatarImageUrl(imagerBase ?? "", m.look, { size: "l" })}
|
src={avatarImageUrl(m.look, { size: "l" })}
|
||||||
alt={`${m.username} avatar`}
|
alt={`${m.username} avatar`}
|
||||||
width={50}
|
width={50}
|
||||||
height={75}
|
height={75}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { getTranslations } from "next-intl/server";
|
|||||||
import { ContentCard, EmptyState, RankBadge } from "@/components/public/ui";
|
import { ContentCard, EmptyState, RankBadge } from "@/components/public/ui";
|
||||||
import { db, User, UsersCurrency, UsersSettings } from "@/lib/db";
|
import { db, User, UsersCurrency, UsersSettings } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
export const metadata = { title: "Leaderboard" };
|
export const metadata = { title: "Leaderboard" };
|
||||||
|
|
||||||
@@ -158,20 +157,14 @@ export default async function LeaderboardPage({
|
|||||||
: "credits";
|
: "credits";
|
||||||
const activeTab = TABS.find((tab) => tab.key === active) ?? TABS[0];
|
const activeTab = TABS.find((tab) => tab.key === active) ?? TABS[0];
|
||||||
|
|
||||||
const [rows, imagerBase] = await Promise.all([
|
const rows = await (active === "credits"
|
||||||
active === "credits"
|
? loadCreditsRows()
|
||||||
? loadCreditsRows()
|
: active === "diamonds" || active === "duckets"
|
||||||
: active === "diamonds" || active === "duckets"
|
? // eslint-disable-next-line security/detect-object-injection -- active validated as "diamonds"|"duckets" in this branch
|
||||||
? // eslint-disable-next-line security/detect-object-injection -- active validated as "diamonds"|"duckets" in this branch
|
loadCurrencyRows(CURRENCY_TYPE[active])
|
||||||
loadCurrencyRows(CURRENCY_TYPE[active])
|
: loadSettingsRows(
|
||||||
: loadSettingsRows(
|
SETTINGS_FIELD[active as keyof typeof SETTINGS_FIELD],
|
||||||
SETTINGS_FIELD[active as keyof typeof SETTINGS_FIELD],
|
));
|
||||||
),
|
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const valueOnly =
|
const valueOnly =
|
||||||
active === "achievement" ||
|
active === "achievement" ||
|
||||||
@@ -213,7 +206,7 @@ export default async function LeaderboardPage({
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{rows.map((row, i) => {
|
{rows.map((row, i) => {
|
||||||
const avatar = avatarImageUrl(imagerBase ?? "", row.look, {
|
const avatar = avatarImageUrl(row.look, {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,17 +18,11 @@ import { siteSettings } from "@/lib/services/site-settings";
|
|||||||
export default async function LoginPage() {
|
export default async function LoginPage() {
|
||||||
const t = await getTranslations("pages.login");
|
const t = await getTranslations("pages.login");
|
||||||
const th = await getTranslations("header");
|
const th = await getTranslations("header");
|
||||||
const [hotelName, imagerRaw, cfg, logo] = await Promise.all([
|
const [hotelName, cfg, logo] = await Promise.all([
|
||||||
resolveHotelName(),
|
resolveHotelName(),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
captchaConfig(),
|
captchaConfig(),
|
||||||
siteSettings.get("radio_social_discord", ""),
|
|
||||||
siteSettings.get("cms_logo", ""),
|
siteSettings.get("cms_logo", ""),
|
||||||
]);
|
]);
|
||||||
const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage";
|
|
||||||
const nonce = (await headers()).get("x-nonce") ?? undefined;
|
const nonce = (await headers()).get("x-nonce") ?? undefined;
|
||||||
|
|
||||||
const [online, recentUsers, latestUsers] = await Promise.all([
|
const [online, recentUsers, latestUsers] = await Promise.all([
|
||||||
@@ -234,7 +228,7 @@ export default async function LoginPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
size: "s",
|
size: "s",
|
||||||
@@ -305,7 +299,7 @@ export default async function LoginPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
size: "s",
|
size: "s",
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import {
|
|||||||
WebsiteLoginLogs,
|
WebsiteLoginLogs,
|
||||||
WebsiteSetting,
|
WebsiteSetting,
|
||||||
} from "@/lib/db";
|
} from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
|
||||||
import { resolveHotelName } from "@/lib/hotel-name";
|
import { resolveHotelName } from "@/lib/hotel-name";
|
||||||
|
import { getAvatarUrl } from "@/lib/imager";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
import { siteSettings } from "@/lib/services/site-settings";
|
||||||
import CopyReferralButton from "./CopyReferralButton";
|
import CopyReferralButton from "./CopyReferralButton";
|
||||||
|
|
||||||
@@ -83,7 +83,6 @@ export default async function MePage({
|
|||||||
|
|
||||||
const [
|
const [
|
||||||
userRows,
|
userRows,
|
||||||
imagerBase,
|
|
||||||
hotelName,
|
hotelName,
|
||||||
neededRows,
|
neededRows,
|
||||||
amountRows,
|
amountRows,
|
||||||
@@ -111,10 +110,6 @@ export default async function MePage({
|
|||||||
.from(User)
|
.from(User)
|
||||||
.where(eq(User.id, userId))
|
.where(eq(User.id, userId))
|
||||||
.limit(1),
|
.limit(1),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
resolveHotelName(),
|
resolveHotelName(),
|
||||||
db
|
db
|
||||||
.select({ value: WebsiteSetting.value })
|
.select({ value: WebsiteSetting.value })
|
||||||
@@ -273,9 +268,7 @@ export default async function MePage({
|
|||||||
: "Never";
|
: "Never";
|
||||||
const referralLink = `/register?ref=${encodeURIComponent(user.username)}`;
|
const referralLink = `/register?ref=${encodeURIComponent(user.username)}`;
|
||||||
|
|
||||||
const imager =
|
const avatarFull = getAvatarUrl(user.look, {
|
||||||
imagerBase ?? "https://www.habbo.com/habbo-imaging/avatarimage";
|
|
||||||
const avatarFull = avatarImageUrl(imager, user.look, {
|
|
||||||
size: "l",
|
size: "l",
|
||||||
direction: 2,
|
direction: 2,
|
||||||
});
|
});
|
||||||
@@ -505,7 +498,7 @@ export default async function MePage({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, friend.look, {
|
src={getAvatarUrl(friend.look, {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import {
|
|||||||
} from "@/lib/db";
|
} from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { formatDate } from "@/lib/format-date";
|
import { formatDate } from "@/lib/format-date";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
type SearchParams = Promise<{
|
type SearchParams = Promise<{
|
||||||
accepted?: string;
|
accepted?: string;
|
||||||
@@ -65,10 +64,9 @@ export default async function MessagesPage({
|
|||||||
sendedOn: number;
|
sendedOn: number;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
let friendships: { userOneId: number; userTwoId: number }[] = [];
|
let friendships: { userOneId: number; userTwoId: number }[] = [];
|
||||||
let imagerBase = "https://www.habbo.com/habbo-imaging/avatarimage";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [reqRows, msgRows, friendRows, base] = await Promise.all([
|
const [reqRows, msgRows, friendRows] = await Promise.all([
|
||||||
db
|
db
|
||||||
.select({
|
.select({
|
||||||
id: MessengerFriendrequests.id,
|
id: MessengerFriendrequests.id,
|
||||||
@@ -101,15 +99,10 @@ export default async function MessagesPage({
|
|||||||
eq(MessengerFriendships.userTwoId, userId),
|
eq(MessengerFriendships.userTwoId, userId),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
]);
|
]);
|
||||||
requests = reqRows;
|
requests = reqRows;
|
||||||
messages = msgRows;
|
messages = msgRows;
|
||||||
friendships = friendRows;
|
friendships = friendRows;
|
||||||
if (base) imagerBase = base;
|
|
||||||
} catch {
|
} catch {
|
||||||
requests = [];
|
requests = [];
|
||||||
messages = [];
|
messages = [];
|
||||||
@@ -277,7 +270,7 @@ export default async function MessagesPage({
|
|||||||
<div className="grid" style={{ padding: "1rem", gap: "0.75rem" }}>
|
<div className="grid" style={{ padding: "1rem", gap: "0.75rem" }}>
|
||||||
{requests.map((req) => {
|
{requests.map((req) => {
|
||||||
const from = userById.get(req.userFromId);
|
const from = userById.get(req.userFromId);
|
||||||
const avatar = avatarImageUrl(imagerBase, from?.look ?? "", {
|
const avatar = avatarImageUrl(from?.look ?? "", {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
});
|
});
|
||||||
@@ -367,7 +360,7 @@ export default async function MessagesPage({
|
|||||||
<div className="grid" style={{ padding: "1rem", gap: "0.75rem" }}>
|
<div className="grid" style={{ padding: "1rem", gap: "0.75rem" }}>
|
||||||
{messages.map((msg) => {
|
{messages.map((msg) => {
|
||||||
const from = userById.get(msg.userFromId);
|
const from = userById.get(msg.userFromId);
|
||||||
const avatar = avatarImageUrl(imagerBase, from?.look ?? "", {
|
const avatar = avatarImageUrl(from?.look ?? "", {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
});
|
});
|
||||||
|
|||||||
+3
-10
@@ -22,15 +22,10 @@ import { captchaConfig } from "@/lib/services/captcha";
|
|||||||
import { siteSettings } from "@/lib/services/site-settings";
|
import { siteSettings } from "@/lib/services/site-settings";
|
||||||
|
|
||||||
async function getHotelData() {
|
async function getHotelData() {
|
||||||
const [hotelName, imagerRaw, logo] = await Promise.all([
|
const [hotelName, logo] = await Promise.all([
|
||||||
resolveHotelName(),
|
resolveHotelName(),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
siteSettings.get("cms_logo", ""),
|
siteSettings.get("cms_logo", ""),
|
||||||
]);
|
]);
|
||||||
const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage";
|
|
||||||
|
|
||||||
const [
|
const [
|
||||||
online,
|
online,
|
||||||
@@ -88,7 +83,6 @@ async function getHotelData() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
hotelName,
|
hotelName,
|
||||||
imager,
|
|
||||||
online,
|
online,
|
||||||
users,
|
users,
|
||||||
rooms,
|
rooms,
|
||||||
@@ -108,7 +102,6 @@ export default async function Home() {
|
|||||||
const th = await getTranslations("header");
|
const th = await getTranslations("header");
|
||||||
const {
|
const {
|
||||||
hotelName,
|
hotelName,
|
||||||
imager,
|
|
||||||
online,
|
online,
|
||||||
users,
|
users,
|
||||||
rooms,
|
rooms,
|
||||||
@@ -486,7 +479,7 @@ export default async function Home() {
|
|||||||
>
|
>
|
||||||
<div className="relative overflow-visible">
|
<div className="relative overflow-visible">
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 3,
|
direction: 3,
|
||||||
})}
|
})}
|
||||||
@@ -664,7 +657,7 @@ export default async function Home() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
size: "s",
|
size: "s",
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { getTranslations } from "next-intl/server";
|
|||||||
import { ContentCard, EmptyState, RankBadge } from "@/components/public/ui";
|
import { ContentCard, EmptyState, RankBadge } from "@/components/public/ui";
|
||||||
import { db } from "@/lib/db";
|
import { db } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
type LeaderRow = {
|
type LeaderRow = {
|
||||||
username: string;
|
username: string;
|
||||||
@@ -36,13 +35,7 @@ async function loadRows(): Promise<
|
|||||||
export default async function RadioLeaderboardPage() {
|
export default async function RadioLeaderboardPage() {
|
||||||
const t = await getTranslations("pages.radioLeaderboard");
|
const t = await getTranslations("pages.radioLeaderboard");
|
||||||
|
|
||||||
const [rows, imagerBase] = await Promise.all([
|
const rows = await loadRows();
|
||||||
loadRows(),
|
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main style={{ display: "grid", gap: "1.5rem" }}>
|
<main style={{ display: "grid", gap: "1.5rem" }}>
|
||||||
@@ -63,7 +56,7 @@ export default async function RadioLeaderboardPage() {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{rows.map((row, i) => {
|
{rows.map((row, i) => {
|
||||||
const avatar = avatarImageUrl(imagerBase ?? "", row.look, {
|
const avatar = avatarImageUrl(row.look, {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { auth } from "@/lib/auth";
|
|||||||
import { db, RadioShouts, User } from "@/lib/db";
|
import { db, RadioShouts, User } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { formatDate } from "@/lib/format-date";
|
import { formatDate } from "@/lib/format-date";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
type SearchParams = Promise<{ posted?: string; error?: string }>;
|
type SearchParams = Promise<{ posted?: string; error?: string }>;
|
||||||
|
|
||||||
@@ -35,17 +34,13 @@ export default async function RadioShoutsPage({
|
|||||||
const t = await getTranslations("pages.radioShouts");
|
const t = await getTranslations("pages.radioShouts");
|
||||||
const { posted, error } = await searchParams;
|
const { posted, error } = await searchParams;
|
||||||
|
|
||||||
const [shouts, imagerBase, session] = await Promise.all([
|
const [shouts, session] = await Promise.all([
|
||||||
db
|
db
|
||||||
.select()
|
.select()
|
||||||
.from(RadioShouts)
|
.from(RadioShouts)
|
||||||
.orderBy(desc(RadioShouts.createdAt))
|
.orderBy(desc(RadioShouts.createdAt))
|
||||||
.limit(50)
|
.limit(50)
|
||||||
.catch(() => []),
|
.catch(() => []),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
auth(),
|
auth(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -141,7 +136,7 @@ export default async function RadioShoutsPage({
|
|||||||
{shouts.map((s) => {
|
{shouts.map((s) => {
|
||||||
const author = authorById.get(Number(s.userId));
|
const author = authorById.get(Number(s.userId));
|
||||||
const authorAvatar = author
|
const authorAvatar = author
|
||||||
? avatarImageUrl(imagerBase ?? "", author.look, {
|
? avatarImageUrl(author.look, {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
} from "@/components/public/ui";
|
} from "@/components/public/ui";
|
||||||
import { db, User } from "@/lib/db";
|
import { db, User } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
export const metadata = { title: "Rankings" };
|
export const metadata = { title: "Rankings" };
|
||||||
|
|
||||||
@@ -41,11 +40,6 @@ export default async function RankingsPage() {
|
|||||||
users = [];
|
users = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const imagerBase = await siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main style={{ display: "grid", gap: "1.5rem" }}>
|
<main style={{ display: "grid", gap: "1.5rem" }}>
|
||||||
<ContentCard icon="🏆" title={t("title")} subtitle={t("subtitle")} />
|
<ContentCard icon="🏆" title={t("title")} subtitle={t("subtitle")} />
|
||||||
@@ -56,7 +50,7 @@ export default async function RankingsPage() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="card-grid sm-2 lg-3" style={{ padding: "1rem" }}>
|
<div className="card-grid sm-2 lg-3" style={{ padding: "1rem" }}>
|
||||||
{users.map((u, i) => {
|
{users.map((u, i) => {
|
||||||
const avatar = avatarImageUrl(imagerBase ?? "", u.look, {
|
const avatar = avatarImageUrl(u.look, {
|
||||||
size: "m",
|
size: "m",
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -18,17 +18,11 @@ import { siteSettings } from "@/lib/services/site-settings";
|
|||||||
export default async function RegisterPage() {
|
export default async function RegisterPage() {
|
||||||
const th = await getTranslations("header");
|
const th = await getTranslations("header");
|
||||||
const tpr = await getTranslations("pages.register");
|
const tpr = await getTranslations("pages.register");
|
||||||
const [hotelName, imagerRaw, cfg, logo] = await Promise.all([
|
const [hotelName, cfg, logo] = await Promise.all([
|
||||||
resolveHotelName(),
|
resolveHotelName(),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
captchaConfig(),
|
captchaConfig(),
|
||||||
siteSettings.get("radio_social_discord", ""),
|
|
||||||
siteSettings.get("cms_logo", ""),
|
siteSettings.get("cms_logo", ""),
|
||||||
]);
|
]);
|
||||||
const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage";
|
|
||||||
const nonce = (await headers()).get("x-nonce") ?? undefined;
|
const nonce = (await headers()).get("x-nonce") ?? undefined;
|
||||||
|
|
||||||
const [online, recentUsers, latestUsers] = await Promise.all([
|
const [online, recentUsers, latestUsers] = await Promise.all([
|
||||||
@@ -231,7 +225,7 @@ export default async function RegisterPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
size: "s",
|
size: "s",
|
||||||
@@ -302,7 +296,7 @@ export default async function RegisterPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import Image from "next/image";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { db, Rooms, User } from "@/lib/db";
|
import { db, Rooms, User } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
export const metadata: Metadata = { title: "Search" };
|
export const metadata: Metadata = { title: "Search" };
|
||||||
|
|
||||||
@@ -18,12 +17,6 @@ export default async function SearchPage({
|
|||||||
const { q } = await searchParams;
|
const { q } = await searchParams;
|
||||||
const query = q?.trim();
|
const query = q?.trim();
|
||||||
|
|
||||||
const imager =
|
|
||||||
(await siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
)) ?? "";
|
|
||||||
|
|
||||||
if (!query) {
|
if (!query) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -142,7 +135,7 @@ export default async function SearchPage({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { Reveal } from "@/components/motion-reveal";
|
|||||||
import { auth } from "@/lib/auth";
|
import { auth } from "@/lib/auth";
|
||||||
import { db, User } from "@/lib/db";
|
import { db, User } from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
export default async function SettingsPage() {
|
export default async function SettingsPage() {
|
||||||
const t = await getTranslations("pages.settings");
|
const t = await getTranslations("pages.settings");
|
||||||
@@ -41,15 +40,7 @@ export default async function SettingsPage() {
|
|||||||
|
|
||||||
if (!user) redirect("/login");
|
if (!user) redirect("/login");
|
||||||
|
|
||||||
let imagerBase = "https://www.habbo.com/habbo-imaging/avatarimage";
|
const avatar = avatarImageUrl(user.look, { size: "l" });
|
||||||
try {
|
|
||||||
imagerBase =
|
|
||||||
(await siteSettings.get("habbo_imaging_url", imagerBase)) ?? imagerBase;
|
|
||||||
} catch {
|
|
||||||
/* fall back to default */
|
|
||||||
}
|
|
||||||
|
|
||||||
const avatar = avatarImageUrl(imagerBase, user.look, { size: "l" });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-6 pb-14">
|
<div className="flex flex-col gap-6 pb-14">
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import {
|
|||||||
} from "@/lib/db";
|
} from "@/lib/db";
|
||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { formatDate } from "@/lib/format-date";
|
import { formatDate } from "@/lib/format-date";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
type SearchParams = Promise<{
|
type SearchParams = Promise<{
|
||||||
friend?: string;
|
friend?: string;
|
||||||
@@ -87,7 +86,7 @@ export default async function ProfilePage({
|
|||||||
const { username } = await params;
|
const { username } = await params;
|
||||||
const { friend, guestbook: guestbookStatus, error } = await searchParams;
|
const { friend, guestbook: guestbookStatus, error } = await searchParams;
|
||||||
|
|
||||||
const [userRows, imagerBase, session] = await Promise.all([
|
const [userRows, session] = await Promise.all([
|
||||||
db
|
db
|
||||||
.select({
|
.select({
|
||||||
id: User.id,
|
id: User.id,
|
||||||
@@ -102,17 +101,13 @@ export default async function ProfilePage({
|
|||||||
.from(User)
|
.from(User)
|
||||||
.where(eq(User.username, username))
|
.where(eq(User.username, username))
|
||||||
.limit(1),
|
.limit(1),
|
||||||
siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
),
|
|
||||||
auth(),
|
auth(),
|
||||||
]);
|
]);
|
||||||
const user = userRows[0] ?? null;
|
const user = userRows[0] ?? null;
|
||||||
|
|
||||||
if (!user) notFound();
|
if (!user) notFound();
|
||||||
|
|
||||||
const avatar = avatarImageUrl(imagerBase ?? "", user.look, { size: "l" });
|
const avatar = avatarImageUrl(user.look, { size: "l" });
|
||||||
const registered = formatDate(new Date(user.accountCreated * 1000), "date");
|
const registered = formatDate(new Date(user.accountCreated * 1000), "date");
|
||||||
const meId = Number(session?.user?.id);
|
const meId = Number(session?.user?.id);
|
||||||
const isLoggedIn = Number.isInteger(meId) && meId > 0;
|
const isLoggedIn = Number.isInteger(meId) && meId > 0;
|
||||||
@@ -484,7 +479,7 @@ export default async function ProfilePage({
|
|||||||
>
|
>
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
<img
|
<img
|
||||||
src={avatarImageUrl(imagerBase ?? "", f.look, {
|
src={avatarImageUrl(f.look, {
|
||||||
size: "m",
|
size: "m",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
})}
|
})}
|
||||||
@@ -686,7 +681,7 @@ export default async function ProfilePage({
|
|||||||
{guestbook.map((g) => {
|
{guestbook.map((g) => {
|
||||||
const author = authorById.get(g.userId);
|
const author = authorById.get(g.userId);
|
||||||
const authorAvatar = author
|
const authorAvatar = author
|
||||||
? avatarImageUrl(imagerBase ?? "", author.look, {
|
? avatarImageUrl(author.look, {
|
||||||
size: "s",
|
size: "s",
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type NextRequest, NextResponse } from "next/server";
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
import { resolveUpstreamBase } from "@/lib/imager";
|
import { resolveImagerBase } from "@/lib/imager";
|
||||||
|
|
||||||
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
|
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
|
||||||
const FIGURE_MAX_LEN = 512;
|
const FIGURE_MAX_LEN = 512;
|
||||||
@@ -66,7 +66,7 @@ export async function GET(request: NextRequest) {
|
|||||||
const imgFormat = searchParams.get("img_format");
|
const imgFormat = searchParams.get("img_format");
|
||||||
if (imgFormat) params.set("img_format", imgFormat);
|
if (imgFormat) params.set("img_format", imgFormat);
|
||||||
|
|
||||||
const upstream = resolveUpstreamBase();
|
const upstream = resolveImagerBase();
|
||||||
const upstreamUrl = `${upstream}?${params.toString()}`;
|
const upstreamUrl = `${upstream}?${params.toString()}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type NextRequest, NextResponse } from "next/server";
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
import { resolveUpstreamBase } from "@/lib/imager";
|
import { resolveImagerBase } from "@/lib/imager";
|
||||||
|
|
||||||
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
|
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
|
||||||
const FIGURE_MAX_LEN = 512;
|
const FIGURE_MAX_LEN = 512;
|
||||||
@@ -66,7 +66,7 @@ export async function GET(request: NextRequest) {
|
|||||||
const imgFormat = searchParams.get("img_format");
|
const imgFormat = searchParams.get("img_format");
|
||||||
if (imgFormat) params.set("img_format", imgFormat);
|
if (imgFormat) params.set("img_format", imgFormat);
|
||||||
|
|
||||||
const upstream = resolveUpstreamBase();
|
const upstream = resolveImagerBase();
|
||||||
const upstreamUrl = `${upstream}?${params.toString()}`;
|
const upstreamUrl = `${upstream}?${params.toString()}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
import { avatarImageUrl } from "@/lib/format";
|
import { avatarImageUrl } from "@/lib/format";
|
||||||
import { resolveHotelName } from "@/lib/hotel-name";
|
import { resolveHotelName } from "@/lib/hotel-name";
|
||||||
import { canAccess, getApiAdminContext, PERMS } from "@/lib/permissions";
|
import { canAccess, getApiAdminContext, PERMS } from "@/lib/permissions";
|
||||||
import { siteSettings } from "@/lib/services/site-settings";
|
|
||||||
|
|
||||||
function Currency({
|
function Currency({
|
||||||
icon,
|
icon,
|
||||||
@@ -78,12 +77,7 @@ export async function TopHeader({ session }: { session: Session | null }) {
|
|||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
const imager =
|
const avatar = avatarImageUrl(look, { headOnly: true, direction: 2 });
|
||||||
(await siteSettings.get(
|
|
||||||
"habbo_imaging_url",
|
|
||||||
"https://www.habbo.com/habbo-imaging/avatarimage",
|
|
||||||
)) ?? "";
|
|
||||||
const avatar = avatarImageUrl(imager, look, { headOnly: true, direction: 2 });
|
|
||||||
let showAdmin = false;
|
let showAdmin = false;
|
||||||
let showMod = false;
|
let showMod = false;
|
||||||
const ctx = await getApiAdminContext();
|
const ctx = await getApiAdminContext();
|
||||||
@@ -394,7 +388,7 @@ export async function TopHeader({ session }: { session: Session | null }) {
|
|||||||
className="flex items-center gap-2 rounded-lg px-2 py-1 text-xs transition-colors hover:bg-white/10"
|
className="flex items-center gap-2 rounded-lg px-2 py-1 text-xs transition-colors hover:bg-white/10"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatarImageUrl(imager, u.look, {
|
src={avatarImageUrl(u.look, {
|
||||||
headOnly: true,
|
headOnly: true,
|
||||||
direction: 2,
|
direction: 2,
|
||||||
size: "s",
|
size: "s",
|
||||||
|
|||||||
+2
-9
@@ -1,16 +1,9 @@
|
|||||||
import { getNewFormatFigure } from "@/lib/figure-convert";
|
import { getNewFormatFigure } from "@/lib/figure-convert";
|
||||||
import { getAvatarUrl } from "@/lib/imager";
|
import { getAvatarUrl } from "@/lib/imager";
|
||||||
|
import type { AvatarOptions } from "@/types/admin";
|
||||||
|
|
||||||
/** Build a Habbo avatar-imager URL for a figure string. */
|
/** Build a Habbo avatar-imager URL for a figure string. */
|
||||||
export function avatarImageUrl(
|
export function avatarImageUrl(look: string, opts: AvatarOptions = {}): string {
|
||||||
look: string,
|
|
||||||
opts: {
|
|
||||||
size?: "s" | "m" | "l";
|
|
||||||
headOnly?: boolean;
|
|
||||||
direction?: number;
|
|
||||||
headDirection?: number;
|
|
||||||
} = {},
|
|
||||||
): string {
|
|
||||||
const figure = getNewFormatFigure(look);
|
const figure = getNewFormatFigure(look);
|
||||||
return getAvatarUrl(figure, opts);
|
return getAvatarUrl(figure, opts);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user