mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 02:13:33 +00:00
Add additional lyrics customizability options (#146)
This commit is contained in:
parent
72b4a60c7b
commit
fca135ce2b
7 changed files with 230 additions and 64 deletions
26
src/renderer/features/lyrics/lyric-line.module.scss
Normal file
26
src/renderer/features/lyrics/lyric-line.module.scss
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.lyric-line {
|
||||
color: var(--main-fg);
|
||||
font-weight: 400;
|
||||
|
||||
font-size: 2.5vmax;
|
||||
transform: scale(0.95);
|
||||
opacity: 0.5;
|
||||
|
||||
.active {
|
||||
font-weight: 800 !important;
|
||||
transform: scale(1) !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.active.unsynchronized {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.lyric-line.active {
|
||||
font-weight: 800;
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -1,31 +1,41 @@
|
|||
import { ComponentPropsWithoutRef } from 'react';
|
||||
import { TextTitle } from '/@/renderer/components/text-title';
|
||||
import { TitleProps } from '@mantine/core';
|
||||
import styled from 'styled-components';
|
||||
|
||||
interface LyricLineProps extends ComponentPropsWithoutRef<'div'> {
|
||||
alignment: 'left' | 'center' | 'right';
|
||||
fontSize: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
const StyledText = styled(TextTitle)`
|
||||
const StyledText = styled(TextTitle)<TitleProps & { $alignment: string; $fontSize: number }>`
|
||||
color: var(--main-fg);
|
||||
font-weight: 400;
|
||||
font-size: 2.5vmax;
|
||||
transform: scale(0.95);
|
||||
text-align: ${(props) => props.$alignment};
|
||||
font-size: ${(props) => props.$fontSize}px;
|
||||
opacity: 0.5;
|
||||
|
||||
&.active {
|
||||
font-weight: 800;
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.active.unsynchronized {
|
||||
opacity: 0.8;
|
||||
&.unsynchronized {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
|
||||
`;
|
||||
|
||||
export const LyricLine = ({ text, ...props }: LyricLineProps) => {
|
||||
return <StyledText {...props}>{text}</StyledText>;
|
||||
export const LyricLine = ({ text, alignment, fontSize, ...props }: LyricLineProps) => {
|
||||
return (
|
||||
<StyledText
|
||||
$alignment={alignment}
|
||||
$fontSize={fontSize}
|
||||
{...props}
|
||||
>
|
||||
{text}
|
||||
</StyledText>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ import styled from 'styled-components';
|
|||
|
||||
const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null;
|
||||
|
||||
const SynchronizedLyricsContainer = styled.div`
|
||||
const SynchronizedLyricsContainer = styled.div<{ $gap: number }>`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
gap: ${(props) => props.$gap || 5}px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10vh 0 6vh;
|
||||
|
|
@ -146,7 +146,8 @@ export const SynchronizedLyrics = ({
|
|||
'sychronized-lyrics-scroll-container',
|
||||
) as HTMLElement;
|
||||
const currentLyric = document.querySelector(`#lyric-${index}`) as HTMLElement;
|
||||
const offsetTop = currentLyric.offsetTop - doc.clientHeight / 2 ?? 0;
|
||||
// eslint-disable-next-line no-unsafe-optional-chaining
|
||||
const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 ?? 0;
|
||||
|
||||
if (currentLyric === null) {
|
||||
lyricRef.current = undefined;
|
||||
|
|
@ -295,27 +296,34 @@ export const SynchronizedLyrics = ({
|
|||
|
||||
return (
|
||||
<SynchronizedLyricsContainer
|
||||
$gap={settings.gap}
|
||||
className="synchronized-lyrics overlay-scrollbar"
|
||||
id="sychronized-lyrics-scroll-container"
|
||||
onMouseEnter={showScrollbar}
|
||||
onMouseLeave={hideScrollbar}
|
||||
>
|
||||
{source && (
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{remote && (
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{lyrics.map(([, text], idx) => (
|
||||
<LyricLine
|
||||
key={idx}
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line synchronized"
|
||||
fontSize={settings.fontSize}
|
||||
id={`lyric-${idx}`}
|
||||
text={text}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@ import { useMemo } from 'react';
|
|||
import styled from 'styled-components';
|
||||
import { LyricLine } from '/@/renderer/features/lyrics/lyric-line';
|
||||
import { FullLyricsMetadata } from '/@/renderer/api/types';
|
||||
import { useLyricsSettings } from '/@/renderer/store';
|
||||
|
||||
interface UnsynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> {
|
||||
lyrics: string;
|
||||
}
|
||||
|
||||
const UnsynchronizedLyricsContainer = styled.div`
|
||||
const UnsynchronizedLyricsContainer = styled.div<{ $gap: number }>`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
gap: ${(props) => props.$gap || 5}px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10vh 0 6vh;
|
||||
|
|
@ -37,28 +38,38 @@ export const UnsynchronizedLyrics = ({
|
|||
remote,
|
||||
source,
|
||||
}: UnsynchronizedLyricsProps) => {
|
||||
const settings = useLyricsSettings();
|
||||
const lines = useMemo(() => {
|
||||
return lyrics.split('\n');
|
||||
}, [lyrics]);
|
||||
|
||||
return (
|
||||
<UnsynchronizedLyricsContainer className="unsynchronized-lyrics">
|
||||
<UnsynchronizedLyricsContainer
|
||||
$gap={settings.gapUnsync}
|
||||
className="unsynchronized-lyrics"
|
||||
>
|
||||
{source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{lines.map((text, idx) => (
|
||||
<LyricLine
|
||||
key={idx}
|
||||
className="lyric-line"
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line unsynchronized"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
id={`lyric-${idx}`}
|
||||
text={text}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue