Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 19x 19x | import { ReactElement, useEffect, useRef } from "react"; import { useAuth, useLyricsContext, useSpotify } from "hooks"; import { LineType } from "types/lyrics"; import { IFormatLyricsResponse } from "utils"; interface ILyricLineProps { line: IFormatLyricsResponse["lines"][0]; type: LineType; } export function LyricLine({ line, type }: ILyricLineProps): ReactElement { const { player } = useSpotify(); const { isPremium } = useAuth(); const lineRef = useRef<HTMLButtonElement>(null); const { lyricsProgressMs, lyricTextColor, lyricLineColor, lyrics } = useLyricsContext(); const lineColors = { current: "#fff", previous: lyricLineColor + "80", next: lyricTextColor, }; useEffect(() => { const line = lineRef.current; Iif (!line) return; const currentLine = line.classList.contains("current"); Iif (currentLine) { line.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest", }); } }, [lyricsProgressMs]); return ( <button onClick={(e) => { e.stopPropagation(); Iif ( isPremium && line?.startTimeMs && player && lyrics?.syncType === "LINE_SYNCED" ) { player.seek(Number(line.startTimeMs)); } }} className={`line ${type}`} dir="auto" ref={lineRef} > {line.words} <style jsx>{` .line { display: block; color: ${lyricTextColor}; background-color: transparent; border: none; width: 100%; text-align: left; padding-left: 144px; font-size: 32px; font-weight: 700; letter-spacing: -0.04em; line-height: 54px; cursor: pointer; transition: all 0.1s ease-out 0s; } .line.current { color: ${lineColors.current}; } .line.previous { color: ${lineColors.previous}; } .line.next { color: ${lineColors.next}; } .line:hover { color: ${lyrics?.colors ? lyricLineColor : "#fff"}; opacity: 1; } @media (max-width: 768px) { .line { padding-left: 0; font-size: 18px; line-height: 32px; } } @media (max-width: 658px) { .line { padding-left: 0; } } `}</style> </button> ); } |