diff --git a/src/components/mii/instructions.tsx b/src/components/mii/instructions.tsx index 22ccaeb..3b2bf1f 100644 --- a/src/components/mii/instructions.tsx +++ b/src/components/mii/instructions.tsx @@ -40,16 +40,18 @@ function ColorPosition({ color }: { color: number }) { if (!color) return null; if (color <= 7) { return ( - <> + +
Color menu on left, - +
); } if (color >= 108) { return ( - <> + +
Outside color menu, - +
); } diff --git a/src/components/submit-form/index.tsx b/src/components/submit-form/index.tsx index a26d766..009e2a1 100644 --- a/src/components/submit-form/index.tsx +++ b/src/components/submit-form/index.tsx @@ -372,6 +372,8 @@ export default function SubmitForm() { + +

You must upload a screenshot of the features, check tutorial on how.

{/* (3DS only) QR code scanning */} diff --git a/src/components/submit-form/mii-editor/color-picker.tsx b/src/components/submit-form/mii-editor/color-picker.tsx index c0f009c..6d853fc 100644 --- a/src/components/submit-form/mii-editor/color-picker.tsx +++ b/src/components/submit-form/mii-editor/color-picker.tsx @@ -6,12 +6,30 @@ interface Props { disabled?: boolean; color: number; setColor: (color: number) => void; + tab?: "hair" | "eyes" | "lips" | "glasses" | "eyeliner"; } -export default function ColorPicker({ disabled, color, setColor }: Props) { +export default function ColorPicker({ disabled, color, setColor, tab = "hair" }: Props) { const [isOpen, setIsOpen] = useState(false); const [isVisible, setIsVisible] = useState(false); + const getExtraSlice = () => { + switch (tab) { + case "hair": + return { start: 0, end: 8 }; + case "eyes": + return { start: 122, end: 128 }; + case "lips": + return { start: 128, end: 133 }; + case "glasses": + return { start: 133, end: 139 }; + case "eyeliner": + return { start: 139, end: 152 }; + default: + return { start: 108, end: 122 }; + } + }; + const close = () => { setIsVisible(false); setTimeout(() => { @@ -38,7 +56,7 @@ export default function ColorPicker({ disabled, color, setColor }: Props) { } }} disabled={disabled} - className={`w-full flex gap-1.5 mb-2 p-2 rounded-xl shadow ${disabled ? "bg-zinc-300 opacity-50 cursor-not-allowed" : "bg-zinc-100 cursor-pointer"}`} + className={`w-20 flex gap-1.5 mb-2 p-2 rounded-xl shadow ${disabled ? "bg-zinc-300 opacity-50 cursor-not-allowed" : "bg-zinc-100 cursor-pointer"}`} >
@@ -46,7 +64,7 @@ export default function ColorPicker({ disabled, color, setColor }: Props) { {isOpen && (
- {COLORS.slice(0, 8).map((c, i) => ( - - ))} + {COLORS.slice(getExtraSlice().start, getExtraSlice().end).map((c, i) => { + const actualIndex = i + getExtraSlice().start; + return ( + + ); + })}
-
+
{COLORS.slice(8, 108).map((c, i) => ( - ))} -
-
-
- - -
-
- -
- +
+
+ {TABS.map((_, i) => ( + + ))}
-
+ +
+ + +
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/glasses.tsx b/src/components/submit-form/mii-editor/tabs/glasses.tsx index 94a43c0..9e2640c 100644 --- a/src/components/submit-form/mii-editor/tabs/glasses.tsx +++ b/src/components/submit-form/mii-editor/tabs/glasses.tsx @@ -12,32 +12,28 @@ export default function GlassesTab({ instructions }: Props) { const [shadesColor, setShadesColor] = useState(0); return ( -
-
-
-
-

Glasses

-
-
+ <> +

Glasses

-
- { - setRingColor(i); - instructions.current.glasses.ringColor = i; - }} - /> - { - setShadesColor(i); - instructions.current.glasses.shadesColor = i; - }} - /> - -
+
+ { + setRingColor(i); + instructions.current.glasses.ringColor = i; + }} + tab="glasses" + /> + { + setShadesColor(i); + instructions.current.glasses.shadesColor = i; + }} + tab="glasses" + /> +
-
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/hair.tsx b/src/components/submit-form/mii-editor/tabs/hair.tsx index 63b2479..7aec88a 100644 --- a/src/components/submit-form/mii-editor/tabs/hair.tsx +++ b/src/components/submit-form/mii-editor/tabs/hair.tsx @@ -16,122 +16,114 @@ export default function HairTab({ instructions }: Props) { const [style, setStyle] = useState(null); const [isFlipped, setIsFlipped] = useState(false); - const length = tab === "sets" ? 245 : tab === "bangs" ? 83 : 111; - return ( -
-
-
-
-

Hair

+ <> +

Hair

-
- +
+ -
- - -
-
-
+
+ +
+
-
- { - setColor(i); - instructions.current.hair.color = i; - }} - /> +
+ { + setColor(i); + instructions.current.hair.color = i; + }} + /> -
- { - if (tab === "back") { - setSubColor2(e.target.checked ? 0 : null); - instructions.current.hair.subColor2 = e.target.checked ? 0 : null; - } else { - setSubColor(e.target.checked ? 0 : null); - instructions.current.hair.subColor = e.target.checked ? 0 : null; - } - }} - /> - -
- - { +
+ { if (tab === "back") { - setSubColor2(i); - instructions.current.hair.subColor2 = i; + setSubColor2(e.target.checked ? 0 : null); + instructions.current.hair.subColor2 = e.target.checked ? 0 : null; } else { - setSubColor(i); - instructions.current.hair.subColor = i; + setSubColor(e.target.checked ? 0 : null); + instructions.current.hair.subColor = e.target.checked ? 0 : null; } }} /> + +
-

Tying style

-
- {Array.from({ length: 3 }).map((_, i) => ( - - ))} -
+ { + if (tab === "back") { + setSubColor2(i); + instructions.current.hair.subColor2 = i; + } else { + setSubColor(i); + instructions.current.hair.subColor = i; + } + }} + /> -
- { - setIsFlipped(e.target.checked); - instructions.current.hair.isFlipped = e.target.checked; +

Tying style

+
+ {Array.from({ length: 3 }).map((_, i) => ( +
+ className={`size-full aspect-square cursor-pointer hover:bg-orange-300 transition-colors duration-100 rounded-lg ${style === i ? "bg-orange-400!" : ""}`} + > + {i + 1} + + ))} +
+ +
+ { + setIsFlipped(e.target.checked); + instructions.current.hair.isFlipped = e.target.checked; + }} + /> +
-
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/head.tsx b/src/components/submit-form/mii-editor/tabs/head.tsx index 53aabc0..6b95d49 100644 --- a/src/components/submit-form/mii-editor/tabs/head.tsx +++ b/src/components/submit-form/mii-editor/tabs/head.tsx @@ -10,39 +10,32 @@ const COLORS = ["FFD8BA", "FFD5AC", "FEC1A4", "FEC68F", "FEB089", "FEBA6B", "F39 export default function HeadTab({ instructions }: Props) { const [color, setColor] = useState(109); - const [type, setType] = useState(1); return ( -
-
-
-
-

Head

-
-
+ <> +

Head

-
- { - setColor(i); - instructions.current.head.skinColor = i; - }} - /> +
+ { + setColor(i); + instructions.current.head.skinColor = i; + }} + /> -
- {COLORS.map((hex, i) => ( - - ))} -
+
+ {COLORS.map((hex, i) => ( + + ))}
-
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/lips.tsx b/src/components/submit-form/mii-editor/tabs/lips.tsx index bb53589..49795f4 100644 --- a/src/components/submit-form/mii-editor/tabs/lips.tsx +++ b/src/components/submit-form/mii-editor/tabs/lips.tsx @@ -12,41 +12,36 @@ export default function LipsTab({ instructions }: Props) { const [hasLipstick, setHasLipstick] = useState(false); return ( -
-
-
-
-

Lips

-
-
+ <> +

Lips

-
- { - setColor(i); - instructions.current.lips.color = i; +
+ { + setColor(i); + instructions.current.lips.color = i; + }} + tab="lips" + /> + + +
+ { + setHasLipstick(e.target.checked); + instructions.current.lips.hasLipstick = e.target.checked; }} /> - - -
- { - setHasLipstick(e.target.checked); - instructions.current.lips.hasLipstick = e.target.checked; - }} - /> - -
+
-
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/misc.tsx b/src/components/submit-form/mii-editor/tabs/misc.tsx index 655091c..e7b8ded 100644 --- a/src/components/submit-form/mii-editor/tabs/misc.tsx +++ b/src/components/submit-form/mii-editor/tabs/misc.tsx @@ -31,119 +31,113 @@ export default function HeadTab({ instructions }: Props) { }); return ( -
-
-
-
-

Misc

+ <> +

Misc

+ +
+
+
+
+
+ Body +
+
+ +
+ + { + setHeight(e.target.valueAsNumber); + instructions.current.height = e.target.valueAsNumber; + }} + /> +
+ +
+ + { + setWeight(e.target.valueAsNumber); + instructions.current.weight = e.target.valueAsNumber; + }} + /> +
+ +
+
+ Dating Preferences +
+
+ +
+ { + setDatingPreferences((prev) => { + const updated = e.target.checked ? (prev.includes(gender) ? prev : [...prev, gender]) : prev.filter((p) => p !== gender); + instructions.current.datingPreferences = updated; + return updated; + }); + }} + /> +
-
-
-
-
-
- Body -
-
- -
- - { - setHeight(e.target.valueAsNumber); - instructions.current.height = e.target.valueAsNumber; - }} - /> -
- -
- - { - setWeight(e.target.valueAsNumber); - instructions.current.weight = e.target.valueAsNumber; - }} - /> -
- -
-
- Dating Preferences -
-
- -
- { - setDatingPreferences((prev) => { - const updated = e.target.checked ? (prev.includes(gender) ? prev : [...prev, gender]) : prev.filter((p) => p !== gender); - instructions.current.datingPreferences = updated; - return updated; - }); - }} - /> -
-
- -
-
-
- Voice -
-
- - { - setVoice((p) => ({ ...p, [label]: e.target.valueAsNumber })); - instructions.current.voice[label as keyof typeof voice] = e.target.valueAsNumber; - }} - onClickTone={(i) => { - setVoice((p) => ({ ...p, tone: i })); - instructions.current.voice.tone = i; - }} - /> -
-
- -
+
+

- Personality + Voice
- { - setPersonality((p) => { - const updated = { ...p, [key]: i }; - instructions.current.personality = updated; - return updated; - }); - instructions.current.personality = personality; + { + setVoice((p) => ({ ...p, [label]: e.target.valueAsNumber })); + instructions.current.voice[label as keyof typeof voice] = e.target.valueAsNumber; + }} + onClickTone={(i) => { + setVoice((p) => ({ ...p, tone: i })); + instructions.current.voice.tone = i; }} />
+ +
+
+ Personality +
+
+ + { + setPersonality((p) => { + const updated = { ...p, [key]: i }; + instructions.current.personality = updated; + return updated; + }); + instructions.current.personality = personality; + }} + />
-
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/nose.tsx b/src/components/submit-form/mii-editor/tabs/nose.tsx index de2b93d..19a22cb 100644 --- a/src/components/submit-form/mii-editor/tabs/nose.tsx +++ b/src/components/submit-form/mii-editor/tabs/nose.tsx @@ -7,18 +7,12 @@ interface Props { export default function NoseTab({ instructions }: Props) { return ( -
-
-
-
-

Nose

-
-
+ <> +

Nose

-
- -
+
+
-
+ ); } diff --git a/src/components/submit-form/mii-editor/tabs/other.tsx b/src/components/submit-form/mii-editor/tabs/other.tsx index 4e7fd31..e06ef93 100644 --- a/src/components/submit-form/mii-editor/tabs/other.tsx +++ b/src/components/submit-form/mii-editor/tabs/other.tsx @@ -38,52 +38,46 @@ export default function OtherTab({ instructions }: Props) { }; return ( -
-
-
-
-

Other

+ <> +

Other

-
-
- {TABS.map((_, i) => ( - - ))} -
-
-
-
- -
- - - - {tab === 3 && ( -
- { - setIsFlipped(e.target.checked); - instructions.current.other.moustache.isFlipped = e.target.checked; - }} - /> - -
- )} +
+
+ {TABS.map((_, i) => ( + + ))}
-
+ +
+ + + + {tab === 3 && ( +
+ { + setIsFlipped(e.target.checked); + instructions.current.other.moustache.isFlipped = e.target.checked; + }} + /> + +
+ )} +
+ ); } diff --git a/src/components/submit-form/portrait-upload.tsx b/src/components/submit-form/portrait-upload.tsx index 81cd65e..0a6db2b 100644 --- a/src/components/submit-form/portrait-upload.tsx +++ b/src/components/submit-form/portrait-upload.tsx @@ -31,7 +31,7 @@ export default function PortraitUpload({ setImage }: Props) {

{!hasImage ? ( <> - Drag and drop a screenshot of your Mii's parts here + Drag and drop a screenshot of your Mii's features here
or click to open diff --git a/src/components/tutorial/index.tsx b/src/components/tutorial/index.tsx index 6bc0a3f..19fa3d8 100644 --- a/src/components/tutorial/index.tsx +++ b/src/components/tutorial/index.tsx @@ -105,7 +105,7 @@ export default function Tutorial({ tutorials, isOpen, setIsOpen }: Props) { />

diff --git a/src/components/tutorial/switch-submit.tsx b/src/components/tutorial/switch-submit.tsx index 7f0d863..1e7fbff 100644 --- a/src/components/tutorial/switch-submit.tsx +++ b/src/components/tutorial/switch-submit.tsx @@ -29,11 +29,11 @@ export default function SubmitTutorialButton() { imageSrc: "/tutorial/switch/submitting/step2.jpg", }, { - text: "3. Press Y to open the parts list, take a screenshot then upload to this submit form", + text: "3. Press Y to open the features list, then take a screenshot and upload to this submit form", imageSrc: "/tutorial/switch/submitting/step3.jpg", }, { - text: "4. Adding Mii colors and settings is recommended. All instructions are optional; for values like height or distance, use the number of button clicks (positive for up/left, negative for down/right)", + text: "4. Adding Mii colors and settings is recommended. All instructions are optional; for values like height or distance, use the number of button clicks (positive for buttons on right, negative for buttons on left)", imageSrc: "/tutorial/switch/step4.jpg", }, { type: "finish" }, diff --git a/src/lib/images.tsx b/src/lib/images.tsx index 55fcca1..c14938f 100644 --- a/src/lib/images.tsx +++ b/src/lib/images.tsx @@ -181,7 +181,7 @@ export async function generateMetadataImage(mii: Mii, author: string): Promise<{ ) : (
Switch Guide -

You need to manually create the Mii, visit site for instructions.

+

To fully create the Mii, visit the site for instructions.

View Steps
diff --git a/src/lib/schemas.ts b/src/lib/schemas.ts index 26d20cd..c65a20c 100644 --- a/src/lib/schemas.ts +++ b/src/lib/schemas.ts @@ -83,17 +83,14 @@ export const userNameSchema = z error: "Name can only contain letters, numbers, dashes, underscores, apostrophes, and spaces.", }); -const colorSchema = z.number().int().min(0).max(107).optional(); +const colorSchema = z.number().int().min(0).max(152).optional(); const geometrySchema = z.number().int().min(-10).max(10).optional(); export const switchMiiInstructionsSchema = z .object({ - head: z.object({ type: z.number().int().min(0).max(15).optional(), skinColor: z.number().int().min(0).max(121).optional() }).optional(), + head: z.object({ skinColor: colorSchema }).optional(), hair: z .object({ - setType: z.number().int().min(0).max(244).optional(), - bangsType: z.number().int().min(0).max(82).optional(), - backType: z.number().int().min(0).max(110).optional(), color: colorSchema, subColor: colorSchema, style: z.number().int().min(1).max(3).optional(), @@ -102,7 +99,6 @@ export const switchMiiInstructionsSchema = z .optional(), eyebrows: z .object({ - type: z.number().int().min(0).max(42).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -115,7 +111,6 @@ export const switchMiiInstructionsSchema = z .object({ main: z .object({ - type: z.number().int().min(0).max(120).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -126,7 +121,6 @@ export const switchMiiInstructionsSchema = z .optional(), eyelashesTop: z .object({ - type: z.number().int().min(0).max(5).optional(), height: geometrySchema, distance: geometrySchema, rotation: geometrySchema, @@ -136,7 +130,6 @@ export const switchMiiInstructionsSchema = z .optional(), eyelashesBottom: z .object({ - type: z.number().int().min(0).max(1).optional(), height: geometrySchema, distance: geometrySchema, rotation: geometrySchema, @@ -146,7 +139,6 @@ export const switchMiiInstructionsSchema = z .optional(), eyelidTop: z .object({ - type: z.number().int().min(0).max(2).optional(), height: geometrySchema, distance: geometrySchema, rotation: geometrySchema, @@ -156,7 +148,6 @@ export const switchMiiInstructionsSchema = z .optional(), eyelidBottom: z .object({ - type: z.number().int().min(0).max(2).optional(), height: geometrySchema, distance: geometrySchema, rotation: geometrySchema, @@ -166,13 +157,11 @@ export const switchMiiInstructionsSchema = z .optional(), eyeliner: z .object({ - type: z.number().int().min(0).max(1).optional(), color: colorSchema, }) .optional(), pupil: z .object({ - type: z.number().int().min(0).max(9).optional(), height: geometrySchema, distance: geometrySchema, rotation: geometrySchema, @@ -184,14 +173,12 @@ export const switchMiiInstructionsSchema = z .optional(), nose: z .object({ - type: z.number().int().min(0).max(31).optional(), height: geometrySchema, size: geometrySchema, }) .optional(), lips: z .object({ - type: z.number().int().min(0).max(52).optional(), color: colorSchema, height: geometrySchema, rotation: geometrySchema, @@ -202,14 +189,12 @@ export const switchMiiInstructionsSchema = z .optional(), ears: z .object({ - type: z.number().int().min(0).max(4).optional(), height: geometrySchema, size: geometrySchema, }) .optional(), glasses: z .object({ - type: z.number().int().min(0).max(57).optional(), ringColor: colorSchema, shadesColor: colorSchema, height: geometrySchema, @@ -221,7 +206,6 @@ export const switchMiiInstructionsSchema = z .object({ wrinkles1: z .object({ - type: z.number().int().min(0).max(8).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -231,7 +215,6 @@ export const switchMiiInstructionsSchema = z .optional(), wrinkles2: z .object({ - type: z.number().int().min(0).max(14).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -241,7 +224,6 @@ export const switchMiiInstructionsSchema = z .optional(), beard: z .object({ - type: z.number().int().min(0).max(14).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -251,17 +233,16 @@ export const switchMiiInstructionsSchema = z .optional(), moustache: z .object({ - type: z.number().int().min(0).max(15).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, size: geometrySchema, stretch: geometrySchema, + isFlipped: z.boolean().optional(), }) .optional(), goatee: z .object({ - type: z.number().int().min(0).max(13).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -271,7 +252,6 @@ export const switchMiiInstructionsSchema = z .optional(), mole: z .object({ - type: z.number().int().min(0).max(1).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -281,7 +261,6 @@ export const switchMiiInstructionsSchema = z .optional(), eyeShadow: z .object({ - type: z.number().int().min(0).max(3).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, @@ -291,7 +270,6 @@ export const switchMiiInstructionsSchema = z .optional(), blush: z .object({ - type: z.number().int().min(0).max(7).optional(), color: colorSchema, height: geometrySchema, distance: geometrySchema, diff --git a/src/lib/switch.ts b/src/lib/switch.ts index 647fadf..81210cc 100644 --- a/src/lib/switch.ts +++ b/src/lib/switch.ts @@ -118,7 +118,7 @@ export const COLORS: string[] = [ "2B1B3F", "7B2D2D", "8B3A0E", - // Head tab extra colors + // Hair tab extra colors "FFD8BA", "FFD5AC", "FEC1A4", @@ -133,4 +133,33 @@ export const COLORS: string[] = [ "59371F", "662D16", "392D1E", + // Eye tab extra colors + "000100", + "6B6F6E", + "663F2D", + "605F34", + "3B6F59", + "4856A6", + // Lips tab extra colors + "D65413", + "F21415", + "F54A4A", + "EE9670", + "8A4E40", + // Glasses tab extra colors + "000000", + "776F66", + "603915", + "A65F00", + "A61615", + "273465", + // Eye shade extra colors + "A54E21", + "653E2C", + "EC946F", + "FC9414", + "F97595", + "F54A4A", + "86E1B0", + "6E44B0", ];