feat: fancy internal links in mii descriptions
This commit is contained in:
parent
347fa4824e
commit
69cf02e018
2 changed files with 73 additions and 2 deletions
|
|
@ -13,6 +13,7 @@ import ImageViewer from "@/components/image-viewer";
|
||||||
import DeleteMiiButton from "@/components/delete-mii";
|
import DeleteMiiButton from "@/components/delete-mii";
|
||||||
import ShareMiiButton from "@/components/share-mii-button";
|
import ShareMiiButton from "@/components/share-mii-button";
|
||||||
import ScanTutorialButton from "@/components/tutorial/scan";
|
import ScanTutorialButton from "@/components/tutorial/scan";
|
||||||
|
import ProfilePicture from "@/components/profile-picture";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
params: Promise<{ id: string }>;
|
params: Promise<{ id: string }>;
|
||||||
|
|
@ -214,7 +215,77 @@ export default async function MiiPage({ params }: Props) {
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
{mii.description && (
|
{mii.description && (
|
||||||
<p className="text-sm mt-2 ml-2 bg-white/50 p-3 rounded-lg border border-orange-200 whitespace-break-spaces max-h-54 overflow-y-auto">
|
<p className="text-sm mt-2 ml-2 bg-white/50 p-3 rounded-lg border border-orange-200 whitespace-break-spaces max-h-54 overflow-y-auto">
|
||||||
{mii.description}
|
{/* Adds fancy formatting when linking to other pages on the site */}
|
||||||
|
{(() => {
|
||||||
|
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "https://tomodachishare.com";
|
||||||
|
|
||||||
|
// Match both mii and profile links
|
||||||
|
const regex = new RegExp(`(${baseUrl.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")}/(?:mii|profile)/\\d+)`, "g");
|
||||||
|
const parts = mii.description.split(regex);
|
||||||
|
|
||||||
|
return parts.map(async (part, index) => {
|
||||||
|
const miiMatch = part.match(new RegExp(`^${baseUrl}/mii/(\\d+)$`));
|
||||||
|
const profileMatch = part.match(new RegExp(`^${baseUrl}/profile/(\\d+)$`));
|
||||||
|
|
||||||
|
if (miiMatch) {
|
||||||
|
const id = Number(miiMatch[1]);
|
||||||
|
const linkedMii = await prisma.mii.findUnique({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!linkedMii) return;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
key={index}
|
||||||
|
href={`/mii/${id}`}
|
||||||
|
className="inline-flex items-center align-top gap-1.5 pr-2 bg-amber-100 border border-amber-400 rounded-lg mx-1 text-amber-800 text-sm -mt-2"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={`/mii/${id}/image?type=mii`}
|
||||||
|
alt="mii"
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
className="bg-white rounded-lg border-r border-amber-400"
|
||||||
|
/>
|
||||||
|
{linkedMii.name}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profileMatch) {
|
||||||
|
const id = Number(profileMatch[1]);
|
||||||
|
const linkedProfile = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!linkedProfile) return;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
key={index}
|
||||||
|
href={`/profile/${id}`}
|
||||||
|
className="inline-flex items-center align-top gap-1.5 pr-2 bg-orange-100 border border-orange-400 rounded-lg mx-1 text-orange-800 text-sm -mt-2"
|
||||||
|
>
|
||||||
|
<ProfilePicture
|
||||||
|
src={linkedProfile.image || "/guest.webp"}
|
||||||
|
width={32}
|
||||||
|
height={32}
|
||||||
|
className="bg-white rounded-lg border-r border-orange-400"
|
||||||
|
/>
|
||||||
|
{linkedProfile.name}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regular text
|
||||||
|
return <span key={index}>{part}</span>;
|
||||||
|
});
|
||||||
|
})()}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ export default function ProfilePicture(props: Partial<ImageProps>) {
|
||||||
const { src, ...rest } = props;
|
const { src, ...rest } = props;
|
||||||
const [imgSrc, setImgSrc] = useState(src);
|
const [imgSrc, setImgSrc] = useState(src);
|
||||||
|
|
||||||
return <Image {...rest} src={imgSrc || "/guest.webp"} alt={"profile picture"} width={128} height={128} onError={() => setImgSrc("/guest.webp")} />;
|
return <Image width={128} height={128} {...rest} src={imgSrc || "/guest.webp"} alt={"profile picture"} onError={() => setImgSrc("/guest.webp")} />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue