"use client"; import { 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"; import { Content, Heading, Subheading, Form, FieldGroup, Label, Input, Divider, Row, GenerateButton, ModeButton, OutputSection, OutputLabel, CodeBox, CopyButton, OpenLink, } from "./page.styles"; type CreateMode = "karaoke" | "typing"; interface KaraokePayload { lrc?: string; srv3?: string; file1?: string; file2?: string; offset?: number; offset2?: number; } interface TypingPayload { file1?: string; lrc?: string; offset?: number; title?: string; artist?: string; skip_backing?: boolean; } export default function CreatePage() { const [mode, setMode] = useState("karaoke"); const [lrc, setLrc] = useState(""); const [srv3, setSrv3] = useState(""); const [file1, setFile1] = useState(""); const [file2, setFile2] = useState(""); const [offset, setOffset] = useState(""); const [offset2, setOffset2] = useState(""); const [typingTitle, setTypingTitle] = useState(""); const [typingArtist, setTypingArtist] = 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 = () => { 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 (lrc.trim()) payload.lrc = lrc.trim(); if (offset.trim() !== "") payload.offset = Number(offset); if (typingTitle.trim()) payload.title = typingTitle.trim(); if (typingArtist.trim()) payload.artist = typingArtist.trim(); payload.skip_backing = skipBacking; setCode(btoa(JSON.stringify(payload))); resetCopyStates(); }; const copy = (text: string, which: "code" | "url") => { navigator.clipboard.writeText(text); if (which === "code") { setCopiedCode(true); setTimeout(() => setCopiedCode(false), 2000); } else { setCopiedUrl(true); setTimeout(() => setCopiedUrl(false), 2000); } }; const playerPath = mode === "typing" ? "/game" : "/player"; const shareUrl = code ? `${window.location.origin}${playerPath}?code=${code}` : ""; return ( LRC-Karaoke-Player ← Back Create a Code Switch between Karaoke and Typing Game modes, then generate a shareable code for your session.
{ setMode("karaoke"); setCode(null); resetCopyStates(); }} > MoekyunKaraoke { setMode("typing"); setCode(null); resetCopyStates(); }} > LRC-Type setFile1(e.target.value)} /> setLrc(e.target.value)} /> setOffset(e.target.value)} step="25" /> {mode === "karaoke" ? ( <> setSrv3(e.target.value)} /> 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" }} /> )} Generate Code {code && (
Code {code} copy(code, "code")} aria-label="Copy code" > {copiedCode ? : }
Share URL {shareUrl} copy(shareUrl, "url")} aria-label="Copy URL" > {copiedUrl ? : }
Open in {mode === "typing" ? "Typing Game" : "Player"}
)}
); }