From d14bf345284afeff8a8baab27c639cd577ba2a5e Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Thu, 16 Apr 2026 16:26:21 -0700 Subject: lrc-type code creation screen --- src/app/create/page.tsx | 243 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 189 insertions(+), 54 deletions(-) (limited to 'src/app/create') diff --git a/src/app/create/page.tsx b/src/app/create/page.tsx index 5bcca2a..016c930 100644 --- a/src/app/create/page.tsx +++ b/src/app/create/page.tsx @@ -1,5 +1,5 @@ "use client"; -import { useState } from "react"; +import { useMemo, useState } from "react"; import { MdLibraryMusic } from "react-icons/md"; import { FaCopy, FaCheck, FaExternalLinkAlt } from "react-icons/fa"; import { Root, Navbar, Logo, LogoIcon, NavLink } from "../styles/shared"; @@ -21,7 +21,9 @@ import { OpenLink, } from "./page.styles"; -interface Payload { +type CreateMode = "karaoke" | "typing"; + +interface KaraokePayload { lrc?: string; srv3?: string; file1?: string; @@ -30,7 +32,20 @@ interface Payload { offset2?: number; } +interface TypingPayload { + file1?: string; + lrc?: string; + offset?: number; + title?: string; + artist?: string; + skip_backing?: boolean; + difficulty?: number; +} + export default function CreatePage() { + const [mode, setMode] = useState("karaoke"); + + // Karaoke fields const [lrc, setLrc] = useState(""); const [srv3, setSrv3] = useState(""); const [file1, setFile1] = useState(""); @@ -38,21 +53,47 @@ export default function CreatePage() { const [offset, setOffset] = useState(""); const [offset2, setOffset2] = useState(""); + // Typing fields + const [typingTitle, setTypingTitle] = useState(""); + const [typingArtist, setTypingArtist] = useState(""); + const [typingDifficulty, setTypingDifficulty] = useState(""); + const [skipBacking, setSkipBacking] = useState(true); + const [code, setCode] = useState(null); const [copiedCode, setCopiedCode] = useState(false); const [copiedUrl, setCopiedUrl] = useState(false); + const resetCopyStates = () => { + setCopiedCode(false); + setCopiedUrl(false); + }; + const generate = () => { - const payload: Payload = {}; - if (lrc.trim()) payload.lrc = lrc.trim(); - if (srv3.trim()) payload.srv3 = srv3.trim(); + if (mode === "karaoke") { + const payload: KaraokePayload = {}; + if (lrc.trim()) payload.lrc = lrc.trim(); + if (srv3.trim()) payload.srv3 = srv3.trim(); + if (file1.trim()) payload.file1 = file1.trim(); + if (file2.trim()) payload.file2 = file2.trim(); + if (offset.trim() !== "") payload.offset = Number(offset); + if (offset2.trim() !== "") payload.offset2 = Number(offset2); + + setCode(btoa(JSON.stringify(payload))); + resetCopyStates(); + return; + } + + const payload: TypingPayload = {}; if (file1.trim()) payload.file1 = file1.trim(); - if (file2.trim()) payload.file2 = file2.trim(); + if (lrc.trim()) payload.lrc = lrc.trim(); if (offset.trim() !== "") payload.offset = Number(offset); - if (offset2.trim() !== "") payload.offset2 = Number(offset2); + if (typingTitle.trim()) payload.title = typingTitle.trim(); + if (typingArtist.trim()) payload.artist = typingArtist.trim(); + payload.skip_backing = skipBacking; + if (typingDifficulty.trim() !== "") payload.difficulty = Number(typingDifficulty); + setCode(btoa(JSON.stringify(payload))); - setCopiedCode(false); - setCopiedUrl(false); + resetCopyStates(); }; const copy = (text: string, which: "code" | "url") => { @@ -66,9 +107,14 @@ export default function CreatePage() { } }; - const shareUrl = code - ? `${typeof window !== "undefined" ? window.location.origin : ""}/player?code=${code}` - : ""; + const playerPath = mode === "typing" ? "/typing" : "/player"; + const shareUrl = useMemo( + () => + code + ? `${typeof window !== "undefined" ? window.location.origin : ""}${playerPath}?code=${code}` + : "", + [code, playerPath] + ); return ( @@ -83,15 +129,45 @@ export default function CreatePage() { - Create a Karaoke Code + Create a Code - Fill in the URLs and offsets for your session, then generate a - shareable code. + Switch between Karaoke and Typing Game modes, then generate a shareable code for your session.
+ + { + setMode("karaoke"); + setCode(null); + resetCopyStates(); + }} + style={{ + backgroundColor: mode === "karaoke" ? "#1a1a1a" : "#e5e5e5", + color: mode === "karaoke" ? "#fff" : "#1a1a1a", + }} + > + MoekyunKaraoke + + { + setMode("typing"); + setCode(null); + resetCopyStates(); + }} + style={{ + backgroundColor: mode === "typing" ? "#1a1a1a" : "#e5e5e5", + color: mode === "typing" ? "#fff" : "#1a1a1a", + }} + > + LRC-Type + + + + + - + - + setSrv3(e.target.value)} + type="number" + placeholder="0" + value={offset} + onChange={(e) => setOffset(e.target.value)} + step="25" /> - + {mode === "karaoke" ? ( + <> + + + setSrv3(e.target.value)} + /> + - - - setFile2(e.target.value)} - /> - + - - - - setOffset(e.target.value)} - step="25" - /> - - - - setOffset2(e.target.value)} - step="25" - /> - - + + + setFile2(e.target.value)} + /> + + + + + setOffset2(e.target.value)} + step="25" + /> + + + ) : ( + <> + + + + + setTypingTitle(e.target.value)} + /> + + + + setTypingArtist(e.target.value)} + /> + + + + + + + setSkipBacking(e.target.checked)} + style={{ width: "18px", height: "18px", marginTop: "10px" }} + /> + + + + + setTypingDifficulty(e.target.value)} + /> + + + + )} Generate Code @@ -189,7 +324,7 @@ export default function CreatePage() { - Open in Player + Open in {mode === "typing" ? "Typing Game" : "Player"} )} -- cgit v1.2.3