mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-03-29 03:29:13 +00:00
fix: optimize images (again)
This commit is contained in:
parent
0396ad5b0d
commit
2055f61527
5 changed files with 48 additions and 9 deletions
|
|
@ -4,7 +4,34 @@ import type { NextConfig } from "next";
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
images: {
|
images: {
|
||||||
unoptimized: true,
|
localPatterns: [
|
||||||
|
{
|
||||||
|
pathname: "/mii/*/image",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathname: "/profile/*/picture",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathname: "/tutorial/**",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathname: "/guest.webp",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
hostname: "avatars.githubusercontent.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "cdn.discordapp.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "studio.mii.nintendo.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "*.googleusercontent.com",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ export default async function MiiPage({ params }: Props) {
|
||||||
alt="mii qr code"
|
alt="mii qr code"
|
||||||
width={128}
|
width={128}
|
||||||
height={128}
|
height={128}
|
||||||
|
unoptimized
|
||||||
className="border-2 border-amber-300 rounded-lg hover:brightness-90 transition-all"
|
className="border-2 border-amber-300 rounded-lg hover:brightness-90 transition-all"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,12 @@ interface Props {
|
||||||
alt: string;
|
alt: string;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
unoptimized?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
images?: string[];
|
images?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ImageViewer({ src, alt, width, height, className, images = [] }: Props) {
|
export default function ImageViewer({ src, alt, width, height, unoptimized = false, className, images = [] }: Props) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
|
|
@ -73,7 +74,16 @@ export default function ImageViewer({ src, alt, width, height, className, images
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* not inserting pixelated image-rendering here because i thought it looked a bit weird */}
|
{/* not inserting pixelated image-rendering here because i thought it looked a bit weird */}
|
||||||
<Image src={src} alt={alt} width={width} height={height} onClick={() => setIsOpen(true)} className={`cursor-pointer ${className}`} />
|
<Image
|
||||||
|
src={src}
|
||||||
|
alt={alt}
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
unoptimized={unoptimized}
|
||||||
|
loading="lazy"
|
||||||
|
onClick={() => setIsOpen(true)}
|
||||||
|
className={`cursor-pointer ${className}`}
|
||||||
|
/>
|
||||||
|
|
||||||
{isOpen &&
|
{isOpen &&
|
||||||
createPortal(
|
createPortal(
|
||||||
|
|
@ -104,6 +114,7 @@ export default function ImageViewer({ src, alt, width, height, className, images
|
||||||
alt={alt}
|
alt={alt}
|
||||||
width={896}
|
width={896}
|
||||||
height={896}
|
height={896}
|
||||||
|
unoptimized
|
||||||
priority={index === selectedIndex}
|
priority={index === selectedIndex}
|
||||||
loading={Math.abs(index - selectedIndex) <= 1 ? "eager" : "lazy"}
|
loading={Math.abs(index - selectedIndex) <= 1 ? "eager" : "lazy"}
|
||||||
className="max-w-full max-h-full object-contain drop-shadow-lg"
|
className="max-w-full max-h-full object-contain drop-shadow-lg"
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ import { ChangeEvent } from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: SwitchMiiInstructions["voice"];
|
data: SwitchMiiInstructions["voice"];
|
||||||
onClick?: (e: ChangeEvent<HTMLInputElement, HTMLInputElement>, label: string) => void;
|
onChange?: (e: ChangeEvent<HTMLInputElement, HTMLInputElement>, label: string) => void;
|
||||||
onClickTone?: (i: number) => void;
|
onClickTone?: (i: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VOICE_SETTINGS: string[] = ["Speed", "Pitch", "Depth", "Delivery"];
|
const VOICE_SETTINGS: string[] = ["Speed", "Pitch", "Depth", "Delivery"];
|
||||||
|
|
||||||
export default function VoiceViewer({ data, onClick, onClickTone }: Props) {
|
export default function VoiceViewer({ data, onChange, onClickTone }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
{VOICE_SETTINGS.map((label) => (
|
{VOICE_SETTINGS.map((label) => (
|
||||||
|
|
@ -28,9 +28,9 @@ export default function VoiceViewer({ data, onClick, onClickTone }: Props) {
|
||||||
max={50}
|
max={50}
|
||||||
step={1}
|
step={1}
|
||||||
value={data[label as keyof typeof data] ?? 25}
|
value={data[label as keyof typeof data] ?? 25}
|
||||||
disabled={!onClick}
|
disabled={!onChange}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (onClick) onClick(e, label);
|
if (onChange) onChange(e, label);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="absolute h-4 w-1.5 rounded bg-orange-400 z-0"></div>
|
<div className="absolute h-4 w-1.5 rounded bg-orange-400 z-0"></div>
|
||||||
|
|
@ -50,7 +50,7 @@ export default function VoiceViewer({ data, onClick, onClickTone }: Props) {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (onClickTone) onClickTone(i);
|
if (onClickTone) onClickTone(i);
|
||||||
}}
|
}}
|
||||||
className={`transition-colors duration-100 rounded-xl ${data.tone === i ? "bg-orange-400!" : ""} ${onClick ? "hover:bg-orange-300 cursor-pointer" : ""}`}
|
className={`transition-colors duration-100 rounded-xl ${data.tone === i ? "bg-orange-400!" : ""} ${onClickTone ? "hover:bg-orange-300 cursor-pointer" : ""}`}
|
||||||
>
|
>
|
||||||
{i + 1}
|
{i + 1}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ export default function HeadTab({ instructions }: Props) {
|
||||||
|
|
||||||
<VoiceViewer
|
<VoiceViewer
|
||||||
data={voice}
|
data={voice}
|
||||||
onClick={(e, label) => {
|
onChange={(e, label) => {
|
||||||
setVoice((p) => ({ ...p, [label]: e.target.valueAsNumber }));
|
setVoice((p) => ({ ...p, [label]: e.target.valueAsNumber }));
|
||||||
instructions.current.voice[label as keyof typeof voice] = e.target.valueAsNumber;
|
instructions.current.voice[label as keyof typeof voice] = e.target.valueAsNumber;
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue