From 71b680fb9d29057b97748c54d1ad20229fe3394c Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Wed, 15 Nov 2023 00:28:35 -0800 Subject: feat: add custom upload for lrc and video/audio --- src/app/App.tsx | 151 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 50 deletions(-) (limited to 'src/app/App.tsx') diff --git a/src/app/App.tsx b/src/app/App.tsx index ebe2d33..871e387 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,7 +1,8 @@ -import { CSSProperties, useCallback, useRef, useEffect, useState } from "react"; -import styled, { css } from "styled-components"; -import { Lrc, LrcLine } from "react-lrc"; -import { LRC } from "./data"; +import React, { useEffect, useRef, useState } from 'react'; +import styled from 'styled-components'; +import KaraokePlayer from './components/KaraokePlayer'; +import { toast, ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; const Root = styled.div` position: absolute; @@ -9,79 +10,129 @@ const Root = styled.div` height: 100%; top: 0; left: 0; - display: flex; flex-direction: column; + align-items: center; + background-color: #f5f5f5; `; -const lrcStyle: CSSProperties = { - flex: 1, - minHeight: 0, - overflow: 'hidden !important' -}; -const Line = styled.div<{ $active: boolean; $next: boolean }>` - min-height: 10px; - padding: 14px 30px; - font-size: 40px; - font-family : "Roboto", sans-serif; - font-weight: 500; - text-align: center; - color: rgb(72,72,72); +const FileInputContainer = styled.div` + margin-bottom: 20px; + display: flex; + justify-content: center; + gap: 20px; + padding: 10px; + border-radius: 5px; + background-color: #ffffff; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +`; - background: linear-gradient(to right, rgba(0,0,0,0) 50%, rgb(200, 190, 190) 50%); - background-size: 200% 100%; - background-position: right bottom; +const FileInput = styled.input` + padding: 10px 15px; + border-radius: 5px; + border: 1px solid #ddd; + cursor: pointer; + display: none; + &:hover, &:focus { + background-color: #eaeaea; + outline: none; + } +`; - ${({ $active }) => $active && css` - color: black; - font-weight: 700; - background-position: left bottom; - color: rgb(50, 50, 50); - `} +const FileInputLabel = styled.label` + padding: 10px 15px; + border-radius: 5px; + border: 1px solid #ddd; + cursor: pointer; + &:hover, &:focus { + background-color: #eaeaea; + outline: none; + } `; + function App() { + const [currentMillisecond, setCurrentMillisecond] = useState(0); - + const [lrcContent, setLrcContent] = useState(''); + const [videoUrl, setVideoUrl] = useState(''); + const [showFileInputs, setShowFileInputs] = useState(true); const videoRef = useRef(null); + const [offset, setOffset] = useState('0'); + const handleLrcFileChange = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (file) { + const reader = new FileReader(); + reader.onload = (e) => { + setLrcContent(e.target?.result as string); + if (videoUrl) setShowFileInputs(false); + }; + reader.readAsText(file); + toast.success("LRC file loaded successfully", { autoClose: 2000 }); + } + }; + + const handleVideoFileChange = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (file) { + const url = URL.createObjectURL(file); + setVideoUrl(url); + setShowFileInputs(true); + toast.success("Video file loaded successfully", { autoClose: 2000 }); + } + }; useEffect(() => { const video = videoRef.current; if (!video) return; const syncLrcWithVideo = () => { - const offset = 400; - setCurrentMillisecond((video.currentTime * 1000)+offset); + console.log(offset); + setCurrentMillisecond((video.currentTime * 1000) + parseInt(offset)); }; - video.addEventListener('timeupdate', syncLrcWithVideo); return () => { video.removeEventListener('timeupdate', syncLrcWithVideo); }; - }, [setCurrentMillisecond]); - - const lineRenderer = useCallback( - ({ active, line: { content } }: { active: boolean; line: LrcLine }) => { - const next = active && content === ''; - return {content} - }, - [] - ); + }); return ( +
- -
-
-- cgit v1.2.3