mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-06-28 14:44:15 +00:00
feat: youtube video instructions
also the repo is public again
This commit is contained in:
parent
94389ddc8f
commit
d947f09112
11 changed files with 893 additions and 15 deletions
|
|
@ -120,12 +120,7 @@ export default function MiiInstructions({ instructions }: Props) {
|
|||
const { head, hair, eyebrows, eyes, nose, lips, ears, glasses, other, height, weight, birthday, datingPreferences, voice, personality } = instructions;
|
||||
|
||||
return (
|
||||
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl shadow-lg p-4 flex flex-col gap-3 max-h-96 overflow-y-auto">
|
||||
<h2 className="text-xl font-semibold text-amber-700 flex items-center gap-2">
|
||||
<Icon icon="fa7-solid:list" />
|
||||
Instructions
|
||||
</h2>
|
||||
|
||||
<>
|
||||
{head && (
|
||||
<Section name="Head" instructions={head}>
|
||||
{not(head.skinColor) && (
|
||||
|
|
@ -264,6 +259,6 @@ export default function MiiInstructions({ instructions }: Props) {
|
|||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export default function EditForm({ mii, likes }: Props) {
|
|||
const [makeup, setMakeup] = useState<MiiMakeup>(mii.makeup ?? "PARTIAL");
|
||||
const [miiPortraitUri, setMiiPortraitUri] = useState<string | undefined>(`/mii/${mii.id}/image?type=mii`);
|
||||
const [miiFeaturesUri, setMiiFeaturesUri] = useState<string | undefined>(`/mii/${mii.id}/image?type=features`);
|
||||
const [youtubeId, setYouTubeId] = useState(mii.youtubeId ?? "");
|
||||
const instructions = useRef<SwitchMiiInstructions>(deepMerge(defaultInstructions, (mii.instructions as object) ?? {}));
|
||||
|
||||
const [quarantined, setQuarantined] = useState(mii.quarantined);
|
||||
|
|
@ -98,6 +99,7 @@ export default function EditForm({ mii, likes }: Props) {
|
|||
if (makeup != mii.makeup) formData.append("makeup", makeup);
|
||||
if (miiPortraitUri) formData.append("miiPortraitUri", miiPortraitUri);
|
||||
if (quarantined != mii.quarantined) formData.append("quarantined", JSON.stringify(quarantined));
|
||||
if (youtubeId != mii.youtubeId) formData.append("youtubeId", youtubeId);
|
||||
if (minifyInstructions(structuredClone(instructions.current)) !== (mii.instructions as object))
|
||||
formData.append("instructions", JSON.stringify(instructions.current));
|
||||
|
||||
|
|
@ -394,6 +396,27 @@ export default function EditForm({ mii, likes }: Props) {
|
|||
<hr className="grow border-zinc-300" />
|
||||
</div>
|
||||
|
||||
{/* YouTube */}
|
||||
<div className="w-full grid grid-cols-3 items-center">
|
||||
<label htmlFor="youtube" className="font-semibold">
|
||||
YouTube Video
|
||||
</label>
|
||||
<input
|
||||
id="youtube"
|
||||
type="text"
|
||||
className="pill input w-full col-span-2"
|
||||
minLength={2}
|
||||
maxLength={64}
|
||||
placeholder="Paste a URL or video ID..."
|
||||
value={youtubeId}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
const match = val.match(/(?:youtube\.com\/(?:watch\?v=|shorts\/|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
|
||||
setYouTubeId(match ? match[1] : val);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MiiEditor instructions={instructions} />
|
||||
<SwitchSubmitTutorialButton />
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ export default function SubmitForm({ inQueueMiisCount }: Props) {
|
|||
const [platform, setPlatform] = useState<MiiPlatform>("SWITCH");
|
||||
const [gender, setGender] = useState<MiiGender>("MALE");
|
||||
const [makeup, setMakeup] = useState<MiiMakeup>("PARTIAL");
|
||||
const [youtubeId, setYouTubeId] = useState("");
|
||||
const instructions = useRef<SwitchMiiInstructions>(defaultInstructions);
|
||||
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
|
|
@ -108,6 +109,7 @@ export default function SubmitForm({ inQueueMiisCount }: Props) {
|
|||
formData.append("makeup", makeup);
|
||||
formData.append("miiPortraitImage", portraitBlob);
|
||||
formData.append("miiFeaturesImage", featuresBlob);
|
||||
formData.append("youtubeId", youtubeId);
|
||||
formData.append("instructions", JSON.stringify(instructions.current));
|
||||
}
|
||||
|
||||
|
|
@ -299,7 +301,7 @@ export default function SubmitForm({ inQueueMiisCount }: Props) {
|
|||
</div>
|
||||
|
||||
{/* Gender (switch only) */}
|
||||
<div className={`w-full grid grid-cols-3 items-start z-10 ${platform === "SWITCH" ? "" : "hidden"}`}>
|
||||
<div className={`w-full grid grid-cols-3 items-start z-20 ${platform === "SWITCH" ? "" : "hidden"}`}>
|
||||
<label htmlFor="gender" className="font-semibold py-2">
|
||||
Gender
|
||||
</label>
|
||||
|
|
@ -354,7 +356,7 @@ export default function SubmitForm({ inQueueMiisCount }: Props) {
|
|||
type="button"
|
||||
onClick={() => setMakeup("FULL")}
|
||||
aria-label="Full Face Paint"
|
||||
data-tooltip="Full Face Paint"
|
||||
data-tooltip="Face covered more than 80%"
|
||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-pink-400! after:border-pink-400! before:border-b-pink-400! ${
|
||||
makeup === "FULL" ? "bg-pink-100 border-pink-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||
}`}
|
||||
|
|
@ -367,7 +369,7 @@ export default function SubmitForm({ inQueueMiisCount }: Props) {
|
|||
type="button"
|
||||
onClick={() => setMakeup("PARTIAL")}
|
||||
aria-label="Partial Face Paint"
|
||||
data-tooltip="Partial Face Paint"
|
||||
data-tooltip="For at least any face paint"
|
||||
className={`cursor-pointer rounded-xl flex justify-center items-center size-11 text-4xl border-2 transition-all after:bg-purple-400! after:border-purple-400! before:border-b-purple-400! ${
|
||||
makeup === "PARTIAL" ? "bg-purple-100 border-purple-400 shadow-md" : "bg-white border-gray-300 hover:border-gray-400"
|
||||
}`}
|
||||
|
|
@ -481,6 +483,27 @@ export default function SubmitForm({ inQueueMiisCount }: Props) {
|
|||
</div>
|
||||
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
{/* YouTube */}
|
||||
<div className="w-full grid grid-cols-3 items-center">
|
||||
<label htmlFor="youtube" className="font-semibold">
|
||||
YouTube Video
|
||||
</label>
|
||||
<input
|
||||
id="youtube"
|
||||
type="text"
|
||||
className="pill input w-full col-span-2"
|
||||
minLength={2}
|
||||
maxLength={64}
|
||||
placeholder="Paste a URL or video ID..."
|
||||
value={youtubeId}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
const match = val.match(/(?:youtube\.com\/(?:watch\?v=|shorts\/|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
|
||||
setYouTubeId(match ? match[1] : val);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MiiEditor instructions={instructions} />
|
||||
<SwitchSubmitTutorialButton />
|
||||
<span className="text-xs text-zinc-400 text-center px-32 max-sm:px-8">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue