mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-06-28 14:44:15 +00:00
fix: move mii images to new uploads directory and add route to access it
This commit is contained in:
parent
594309d22d
commit
eea3df283c
12 changed files with 73 additions and 33 deletions
|
|
@ -20,7 +20,6 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
|
|||
|
||||
const { id: slugId } = await params;
|
||||
const parsed = idSchema.safeParse(slugId);
|
||||
|
||||
if (!parsed.success) return rateLimit.sendResponse({ error: parsed.error.errors[0].message }, 400);
|
||||
const miiId = parsed.data;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
|||
// Get Mii ID
|
||||
const { id: slugId } = await params;
|
||||
const parsedId = idSchema.safeParse(slugId);
|
||||
|
||||
if (!parsedId.success) return rateLimit.sendResponse({ error: parsedId.error.errors[0].message }, 400);
|
||||
const miiId = parsedId.data;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
|||
|
||||
const { id: slugId } = await params;
|
||||
const parsed = idSchema.safeParse(slugId);
|
||||
|
||||
if (!parsed.success) return rateLimit.sendResponse({ error: parsed.error.errors[0].message }, 400);
|
||||
const miiId = parsed.data;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { convertQrCode } from "@/lib/qr-codes";
|
|||
import Mii from "@/lib/mii.js/mii";
|
||||
import TomodachiLifeMii from "@/lib/tomodachi-life-mii";
|
||||
|
||||
const uploadsDirectory = path.join(process.cwd(), "public", "mii");
|
||||
const uploadsDirectory = path.join(process.cwd(), "uploads");
|
||||
|
||||
const submitSchema = z.object({
|
||||
name: nameSchema,
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ import { prisma } from "@/lib/prisma";
|
|||
import EditForm from "@/components/submit-form/edit-form";
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>;
|
||||
params: Promise<{ id: string }>;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const { id } = await params;
|
||||
|
||||
const mii = await prisma.mii.findUnique({
|
||||
where: {
|
||||
id: Number(slug),
|
||||
id: Number(id),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -29,12 +29,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||
}
|
||||
|
||||
export default async function MiiPage({ params }: Props) {
|
||||
const { slug } = await params;
|
||||
const { id } = await params;
|
||||
const session = await auth();
|
||||
|
||||
const mii = await prisma.mii.findUnique({
|
||||
where: {
|
||||
id: Number(slug),
|
||||
id: Number(id),
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
40
src/app/mii/[id]/image/route.ts
Normal file
40
src/app/mii/[id]/image/route.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
|
||||
import { idSchema } from "@/lib/schemas";
|
||||
import { RateLimit } from "@/lib/rate-limit";
|
||||
|
||||
const searchParamsSchema = z.object({
|
||||
type: z
|
||||
.enum(["mii", "qr-code", "image0", "image1", "image2"], {
|
||||
message: "Image type must be either 'mii', 'qr-code' or 'image[number from 0 to 2]'",
|
||||
})
|
||||
.default("mii"),
|
||||
});
|
||||
|
||||
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||
const rateLimit = new RateLimit(request, 200);
|
||||
const check = await rateLimit.handle();
|
||||
if (check) return check;
|
||||
|
||||
const { id: slugId } = await params;
|
||||
const parsed = idSchema.safeParse(slugId);
|
||||
if (!parsed.success) return rateLimit.sendResponse({ error: parsed.error.errors[0].message }, 400);
|
||||
const miiId = parsed.data;
|
||||
|
||||
const searchParamsParsed = searchParamsSchema.safeParse(Object.fromEntries(request.nextUrl.searchParams));
|
||||
if (!searchParamsParsed.success) return rateLimit.sendResponse({ error: searchParamsParsed.error.errors[0].message }, 400);
|
||||
const { type: imageType } = searchParamsParsed.data;
|
||||
|
||||
const filePath = path.join(process.cwd(), "uploads", miiId.toString(), `${imageType}.webp`);
|
||||
|
||||
try {
|
||||
const buffer = await fs.readFile(filePath);
|
||||
return new NextResponse(buffer);
|
||||
} catch {
|
||||
return rateLimit.sendResponse({ success: false, error: "Image not found" }, 404);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,15 +14,15 @@ import DeleteMiiButton from "@/components/delete-mii";
|
|||
import ScanTutorialButton from "@/components/tutorial/scan";
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>;
|
||||
params: Promise<{ id: string }>;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const { id } = await params;
|
||||
|
||||
const mii = await prisma.mii.findUnique({
|
||||
where: {
|
||||
id: Number(slug),
|
||||
id: Number(id),
|
||||
},
|
||||
include: {
|
||||
user: {
|
||||
|
|
@ -39,8 +39,8 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||
// Bots get redirected anyways
|
||||
if (!mii) return {};
|
||||
|
||||
const miiImageUrl = `/mii/${mii.id}/mii.webp`;
|
||||
const qrCodeUrl = `/mii/${mii.id}/qrcode.webp`;
|
||||
const miiImageUrl = `/mii/${mii.id}/image?type=mii`;
|
||||
const qrCodeUrl = `/mii/${mii.id}/image?type=qr-code`;
|
||||
|
||||
const username = `@${mii.user.username}`;
|
||||
|
||||
|
|
@ -73,12 +73,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||
}
|
||||
|
||||
export default async function MiiPage({ params }: Props) {
|
||||
const { slug } = await params;
|
||||
const { id } = await params;
|
||||
const session = await auth();
|
||||
|
||||
const mii = await prisma.mii.findUnique({
|
||||
where: {
|
||||
id: Number(slug),
|
||||
id: Number(id),
|
||||
},
|
||||
include: {
|
||||
user: {
|
||||
|
|
@ -103,9 +103,9 @@ export default async function MiiPage({ params }: Props) {
|
|||
if (!mii) redirect("/404");
|
||||
|
||||
const images = [
|
||||
`/mii/${mii.id}/mii.webp`,
|
||||
`/mii/${mii.id}/qr-code.webp`,
|
||||
...Array.from({ length: mii.imageCount }, (_, index) => `/mii/${mii.id}/image${index}.webp`),
|
||||
`/mii/${mii.id}/image?type=mii`,
|
||||
`/mii/${mii.id}/image?type=qr-code`,
|
||||
...Array.from({ length: mii.imageCount }, (_, index) => `/mii/${mii.id}/image?type=image${index}`),
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
@ -11,15 +11,15 @@ import { prisma } from "@/lib/prisma";
|
|||
import MiiList from "@/components/mii-list";
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>;
|
||||
params: Promise<{ id: string }>;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const { id } = await params;
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: Number(slug),
|
||||
id: Number(id),
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
|
|
@ -68,17 +68,17 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||
|
||||
export default async function ProfilePage({ params }: Props) {
|
||||
const session = await auth();
|
||||
const { slug } = await params;
|
||||
const { id } = await params;
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: Number(slug),
|
||||
id: Number(id),
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) redirect("/404");
|
||||
|
||||
const likedMiis = await prisma.like.count({ where: { userId: Number(slug) } });
|
||||
const likedMiis = await prisma.like.count({ where: { userId: Number(id) } });
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
@ -102,7 +102,7 @@ export default async function ProfilePage({ params }: Props) {
|
|||
Created: {user?.createdAt.toLocaleDateString("en-GB", { month: "long", day: "2-digit", year: "numeric" })}
|
||||
</h4>
|
||||
|
||||
{session?.user.id == slug && (
|
||||
{session?.user.id == id && (
|
||||
<Link href="/profile/settings" className="pill button absolute right-0 bottom-0 !px-4">
|
||||
<Icon icon="material-symbols:settings-rounded" className="text-2xl mr-2" />
|
||||
<span>Settings</span>
|
||||
Loading…
Add table
Add a link
Reference in a new issue