From 8835fc640aa1fd21362465902a4dd74c12475c36 Mon Sep 17 00:00:00 2001 From: Kendall Garner <17521368+kgarner7@users.noreply.github.com> Date: Mon, 5 Jun 2023 09:00:12 -0700 Subject: [PATCH] Include lyric simplification, restore clear button - merges lyric simplification - restores metadata/clear --- src/renderer/api/types.ts | 12 +++++++ src/renderer/features/lyrics/lyric-skip.tsx | 6 ++-- src/renderer/features/lyrics/lyrics.tsx | 31 +++++++++++++------ .../features/lyrics/queries/lyric-query.ts | 15 +++++++-- .../features/lyrics/synchronized-lyrics.tsx | 14 ++++----- .../features/lyrics/unsynchronized-lyrics.tsx | 16 +++++----- 6 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/renderer/api/types.ts b/src/renderer/api/types.ts index e1086131..c6aa0c78 100644 --- a/src/renderer/api/types.ts +++ b/src/renderer/api/types.ts @@ -1036,6 +1036,18 @@ export type InternetProviderLyricResponse = { source: string; }; +export type SynchronizedLyricMetadata = { + lyrics: SynchronizedLyricsArray; + remote: boolean; +} & Omit; + +export type UnsyhchronizedLyricMetadata = { + lyrics: string; + remote: boolean; +} & Omit; + +export type FullLyricsMetadata = SynchronizedLyricMetadata | UnsyhchronizedLyricMetadata; + export type LyricOverride = Omit; export const instanceOfCancellationError = (error: any) => { diff --git a/src/renderer/features/lyrics/lyric-skip.tsx b/src/renderer/features/lyrics/lyric-skip.tsx index c1b43848..d9f6396a 100644 --- a/src/renderer/features/lyrics/lyric-skip.tsx +++ b/src/renderer/features/lyrics/lyric-skip.tsx @@ -6,10 +6,10 @@ const LyricClearButton = styled(Button)` position: absolute; right: 10px; z-index: 999; - top: 7vh; + bottom: 6vh; @media (max-width: 768px) { - top: 5vh; + bottom: 3vh; } `; @@ -22,7 +22,7 @@ export const LyricSkip = ({ onClick }: LyricSkipProps) => { } size="xl" - tooltip={{ label: 'Remove incorrect lyrics', position: 'bottom' }} + tooltip={{ label: 'Remove incorrect lyrics', position: 'top' }} variant="default" onClick={onClick} > diff --git a/src/renderer/features/lyrics/lyrics.tsx b/src/renderer/features/lyrics/lyrics.tsx index de60775c..1aa625c5 100644 --- a/src/renderer/features/lyrics/lyrics.tsx +++ b/src/renderer/features/lyrics/lyrics.tsx @@ -1,3 +1,4 @@ +import { useEffect, useState } from 'react'; import { Center, Group } from '@mantine/core'; import { AnimatePresence, motion } from 'framer-motion'; import { ErrorBoundary } from 'react-error-boundary'; @@ -9,6 +10,7 @@ import { ScrollArea, Spinner, TextTitle } from '/@/renderer/components'; import { ErrorFallback } from '/@/renderer/features/action-required'; import { UnsynchronizedLyrics } from '/@/renderer/features/lyrics/unsynchronized-lyrics'; import { getServerById, useCurrentSong } from '/@/renderer/store'; +import { FullLyricsMetadata, SynchronizedLyricMetadata } from '/@/renderer/api/types'; const LyricsScrollContainer = styled(motion(ScrollArea))` z-index: 1; @@ -36,10 +38,18 @@ const LyricsScrollContainer = styled(motion(ScrollArea))` } `; +function isSynchronized(data: FullLyricsMetadata): data is SynchronizedLyricMetadata { + // Type magic. The only difference between Synchronized and Unsynchhronized is + // the datatype of lyrics. This makes Typescript happier later... + return Array.isArray(data.lyrics); +} + export const Lyrics = () => { const currentSong = useCurrentSong(); const currentServer = getServerById(currentSong?.serverId); + const [clear, setClear] = useState(false); + const { data, isLoading } = useSongLyrics( { query: { songId: currentSong?.id || '' }, @@ -48,6 +58,11 @@ export const Lyrics = () => { currentSong, ); + useEffect(() => { + // We want to reset the clear flag whenever a song changes + setClear(false); + }, [currentSong]); + return ( {isLoading ? ( @@ -55,7 +70,7 @@ export const Lyrics = () => { container size={25} /> - ) : !data?.lyrics ? ( + ) : !data?.lyrics || clear ? (
@@ -74,19 +89,15 @@ export const Lyrics = () => { initial={{ opacity: 0 }} transition={{ duration: 0.5 }} > - {Array.isArray(data.lyrics) ? ( + {isSynchronized(data) ? ( {}} + {...data} + onRemoveLyric={() => setClear(true)} /> ) : ( {}} + {...data} + onRemoveLyric={() => setClear(true)} /> )} diff --git a/src/renderer/features/lyrics/queries/lyric-query.ts b/src/renderer/features/lyrics/queries/lyric-query.ts index ab859192..8cc8f2a2 100644 --- a/src/renderer/features/lyrics/queries/lyric-query.ts +++ b/src/renderer/features/lyrics/queries/lyric-query.ts @@ -1,9 +1,10 @@ -import { useQuery } from '@tanstack/react-query'; +import { UseQueryResult, useQuery } from '@tanstack/react-query'; import { LyricsQuery, QueueSong, SynchronizedLyricsArray, InternetProviderLyricResponse, + FullLyricsMetadata, } from '/@/renderer/api/types'; import { QueryHookArgs } from '/@/renderer/lib/react-query'; import { getServerById, useLyricsSettings } from '/@/renderer/store'; @@ -37,7 +38,9 @@ const formatLyrics = (lyrics: string) => { return formattedLyrics; }; -export const useServerLyrics = (args: QueryHookArgs) => { +export const useServerLyrics = ( + args: QueryHookArgs, +): UseQueryResult => { const { query, serverId } = args; const server = getServerById(serverId); @@ -55,7 +58,10 @@ export const useServerLyrics = (args: QueryHookArgs) => { }); }; -export const useSongLyrics = (args: QueryHookArgs, song: QueueSong | undefined) => { +export const useSongLyrics = ( + args: QueryHookArgs, + song: QueueSong | undefined, +): UseQueryResult => { const { query } = args; const { fetch } = useLyricsSettings(); const server = getServerById(song?.serverId); @@ -73,6 +79,7 @@ export const useSongLyrics = (args: QueryHookArgs, song: QueueSong artist: song.artists?.[0]?.name, lyrics: formatLyrics(song.lyrics), name: song.name, + remote: false, source: server?.name ?? 'music server', }; } @@ -88,6 +95,7 @@ export const useSongLyrics = (args: QueryHookArgs, song: QueueSong artist: song.artists?.[0]?.name, lyrics: jfLyrics, name: song.name, + remote: false, source: server?.name ?? 'music server', }; } @@ -101,6 +109,7 @@ export const useSongLyrics = (args: QueryHookArgs, song: QueueSong return { ...remoteLyricsResult, lyrics: formatLyrics(remoteLyricsResult.lyrics), + remote: true, }; } } diff --git a/src/renderer/features/lyrics/synchronized-lyrics.tsx b/src/renderer/features/lyrics/synchronized-lyrics.tsx index 8342b897..8fb2fd52 100644 --- a/src/renderer/features/lyrics/synchronized-lyrics.tsx +++ b/src/renderer/features/lyrics/synchronized-lyrics.tsx @@ -10,7 +10,7 @@ import { PlaybackType, PlayerStatus } from '/@/renderer/types'; import { LyricLine } from '/@/renderer/features/lyrics/lyric-line'; import isElectron from 'is-electron'; import { PlayersRef } from '/@/renderer/features/player/ref/players-ref'; -import { LyricOverride, SynchronizedLyricsArray } from '/@/renderer/api/types'; +import { FullLyricsMetadata, SynchronizedLyricsArray } from '/@/renderer/api/types'; import styled from 'styled-components'; import { LyricSkip } from '/@/renderer/features/lyrics/lyric-skip'; @@ -20,17 +20,17 @@ const SynchronizedLyricsContainer = styled.div` padding: 5rem 0; `; -interface SynchronizedLyricsProps { +interface SynchronizedLyricsProps extends Omit { lyrics: SynchronizedLyricsArray; onRemoveLyric: () => void; - override: LyricOverride | null; - source: string | null; } export const SynchronizedLyrics = ({ + artist, lyrics, + name, onRemoveLyric, - override, + remote, source, }: SynchronizedLyricsProps) => { const playersRef = PlayersRef; @@ -275,11 +275,11 @@ export const SynchronizedLyrics = ({ text={`Lyrics provided by ${source}`} /> )} - {override && ( + {remote && ( <> diff --git a/src/renderer/features/lyrics/unsynchronized-lyrics.tsx b/src/renderer/features/lyrics/unsynchronized-lyrics.tsx index 8a95b6b7..0b8cf6c2 100644 --- a/src/renderer/features/lyrics/unsynchronized-lyrics.tsx +++ b/src/renderer/features/lyrics/unsynchronized-lyrics.tsx @@ -1,14 +1,12 @@ import { useMemo } from 'react'; import styled from 'styled-components'; import { LyricLine } from '/@/renderer/features/lyrics/lyric-line'; -import { LyricOverride } from '/@/renderer/api/types'; +import { FullLyricsMetadata } from '/@/renderer/api/types'; import { LyricSkip } from '/@/renderer/features/lyrics/lyric-skip'; -interface UnsynchronizedLyricsProps { +interface UnsynchronizedLyricsProps extends Omit { lyrics: string; onRemoveLyric: () => void; - override: LyricOverride | null; - source: string | null; } const UnsynchronizedLyricsContainer = styled.div` @@ -16,9 +14,11 @@ const UnsynchronizedLyricsContainer = styled.div` `; export const UnsynchronizedLyrics = ({ - onRemoveLyric, + artist, lyrics, - override, + name, + onRemoveLyric, + remote, source, }: UnsynchronizedLyricsProps) => { const lines = useMemo(() => { @@ -33,11 +33,11 @@ export const UnsynchronizedLyrics = ({ text={`Lyrics provided by ${source}`} /> )} - {override && ( + {remote && ( <>