mirror of
https://github.com/jeffvli/feishin.git
synced 2026-07-12 05:30:12 +02:00
add setting for lyrics container padding
This commit is contained in:
@@ -552,6 +552,8 @@
|
||||
"lyricOffset": "Lyrics offset (ms)",
|
||||
"lyricGap": "Lyric gap",
|
||||
"lyricLineLeadTime": "Line lead time (ms)",
|
||||
"lyricPaddingLeft": "Lyrics left padding (%)",
|
||||
"lyricPaddingRight": "Lyrics right padding (%)",
|
||||
"lyricSize": "Lyric size",
|
||||
"lyricOpacityNonActive": "Non-active lyric opacity",
|
||||
"lyricScaleNonActive": "Non-active lyric scale",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
@media screen and (orientation: portrait) {
|
||||
padding-top: 5vh !important;
|
||||
padding-right: var(--lyric-padding-right, 0%) !important;
|
||||
padding-bottom: 5vh !important;
|
||||
padding-left: var(--lyric-padding-left, 0%) !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import clsx from 'clsx';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import styles from './lyrics-scroll-content.module.css';
|
||||
|
||||
export interface LyricsScrollContentProps {
|
||||
bottomScrollPadding?: string;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
gap?: number;
|
||||
paddingLeft?: number;
|
||||
paddingRight?: number;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export const LyricsScrollContent = ({
|
||||
bottomScrollPadding = '50vh',
|
||||
children,
|
||||
className,
|
||||
gap,
|
||||
paddingLeft = 0,
|
||||
paddingRight = 0,
|
||||
style,
|
||||
}: LyricsScrollContentProps) => {
|
||||
const contentStyle = useMemo(
|
||||
() =>
|
||||
({
|
||||
'--lyric-padding-left': `${paddingLeft}%`,
|
||||
'--lyric-padding-right': `${paddingRight}%`,
|
||||
gap: gap !== undefined ? `${gap}px` : undefined,
|
||||
paddingBottom: bottomScrollPadding,
|
||||
paddingLeft: `${paddingLeft}%`,
|
||||
paddingRight: `${paddingRight}%`,
|
||||
paddingTop: '10vh',
|
||||
...style,
|
||||
}) as React.CSSProperties,
|
||||
[bottomScrollPadding, gap, paddingLeft, paddingRight, style],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.content, className)} style={contentStyle}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -147,6 +147,40 @@ export const LyricsSettingsForm = ({ settingsKey }: LyricsSettingsFormProps) =>
|
||||
`${t('page.fullscreenPlayer.config.lyricGap')} (${t('page.fullscreenPlayer.config.unsynchronized')})`,
|
||||
),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Slider
|
||||
defaultValue={displaySettings.paddingLeft ?? 0}
|
||||
label={(value) => `${value}%`}
|
||||
max={50}
|
||||
min={0}
|
||||
onChangeEnd={(value) => {
|
||||
updateDisplaySetting({ paddingLeft: value });
|
||||
}}
|
||||
step={1}
|
||||
w={100}
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t('page.fullscreenPlayer.config.lyricPaddingLeft'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Slider
|
||||
defaultValue={displaySettings.paddingRight ?? 0}
|
||||
label={(value) => `${value}%`}
|
||||
max={50}
|
||||
min={0}
|
||||
onChangeEnd={(value) => {
|
||||
updateDisplaySetting({ paddingRight: value });
|
||||
}}
|
||||
step={1}
|
||||
w={100}
|
||||
/>
|
||||
),
|
||||
description: '',
|
||||
title: t('page.fullscreenPlayer.config.lyricPaddingRight'),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<SegmentedControl
|
||||
|
||||
@@ -38,6 +38,8 @@ export const useSynchronizedLyricsBase = (settingsKey = 'default', offsetMs?: nu
|
||||
: 24,
|
||||
gap: displaySettings.gap && displaySettings.gap !== 0 ? displaySettings.gap : 24,
|
||||
opacityNonActive: displaySettings.opacityNonActive,
|
||||
paddingLeft: displaySettings.paddingLeft ?? 0,
|
||||
paddingRight: displaySettings.paddingRight ?? 0,
|
||||
scaleNonActive:
|
||||
displaySettings.scaleNonActive && displaySettings.scaleNonActive !== 0
|
||||
? displaySettings.scaleNonActive
|
||||
@@ -135,9 +137,8 @@ export const useSynchronizedLyricsBase = (settingsKey = 'default', offsetMs?: nu
|
||||
'--lyric-opacity': settings.opacityNonActive,
|
||||
'--lyric-scale': settings.scaleNonActive,
|
||||
'--lyric-scale-origin': settings.alignment,
|
||||
gap: `${settings.gap}px`,
|
||||
}) as React.CSSProperties,
|
||||
[settings.alignment, settings.gap, settings.opacityNonActive, settings.scaleNonActive],
|
||||
[settings.alignment, settings.opacityNonActive, settings.scaleNonActive],
|
||||
);
|
||||
|
||||
const hideScrollbar = useCallback(() => {
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
padding: 10vh 0 50vh;
|
||||
overflow: hidden auto;
|
||||
word-break: break-all;
|
||||
|
||||
@media screen and (orientation: portrait) {
|
||||
padding: 5vh 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
getLyricLineText,
|
||||
normalizeLyrics,
|
||||
} from '/@/renderer/features/lyrics/api/lyrics-utils';
|
||||
import { LyricsScrollContent } from '/@/renderer/features/lyrics/components/lyrics-scroll-content';
|
||||
import { SyncedRomajiLyrics } from '/@/renderer/features/lyrics/hooks/use-furigana-lyrics';
|
||||
import { useLyricsAnimationEngine } from '/@/renderer/features/lyrics/hooks/use-lyrics-animation-engine';
|
||||
import {
|
||||
@@ -290,68 +291,74 @@ export const SynchronizedKaraokeLyrics = ({
|
||||
ref={containerRef}
|
||||
style={{ ...containerStyle, ...style }}
|
||||
>
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{normalizedLyrics.map((rawLine, idx) => {
|
||||
const lineStartMs = getLyricLineStartMs(rawLine);
|
||||
const pronunciationText = getOverlayText(
|
||||
pronunciationLyrics,
|
||||
lineStartMs,
|
||||
romajiLyrics?.[idx] ? getLyricLineText(romajiLyrics[idx]) : undefined,
|
||||
);
|
||||
const translationText = getOverlayText(
|
||||
translationLyrics,
|
||||
lineStartMs,
|
||||
translatedLyrics?.split('\n')[idx],
|
||||
);
|
||||
<LyricsScrollContent
|
||||
gap={settings.gap}
|
||||
paddingLeft={settings.paddingLeft}
|
||||
paddingRight={settings.paddingRight}
|
||||
>
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{normalizedLyrics.map((rawLine, idx) => {
|
||||
const lineStartMs = getLyricLineStartMs(rawLine);
|
||||
const pronunciationText = getOverlayText(
|
||||
pronunciationLyrics,
|
||||
lineStartMs,
|
||||
romajiLyrics?.[idx] ? getLyricLineText(romajiLyrics[idx]) : undefined,
|
||||
);
|
||||
const translationText = getOverlayText(
|
||||
translationLyrics,
|
||||
lineStartMs,
|
||||
translatedLyrics?.split('\n')[idx],
|
||||
);
|
||||
|
||||
if (!rawLine.cueLines?.length) {
|
||||
return (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line synchronized"
|
||||
data-lyric-time={lineStartMs}
|
||||
fontSize={settings.fontSize}
|
||||
id={`karaoke-line-${idx}`}
|
||||
key={idx}
|
||||
romajiText={pronunciationText}
|
||||
text={getLyricLineText(rawLine)}
|
||||
translatedText={translationText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!rawLine.cueLines?.length) {
|
||||
return (
|
||||
<LyricLine
|
||||
<KaraokeLyricLine
|
||||
agents={agents}
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line synchronized"
|
||||
className="synchronized"
|
||||
cueLines={rawLine.cueLines}
|
||||
data-lyric-time={lineStartMs}
|
||||
fontSize={settings.fontSize}
|
||||
id={`karaoke-line-${idx}`}
|
||||
key={idx}
|
||||
lineIndex={idx}
|
||||
romajiCueLines={syncedRomajiLyrics?.[idx] ?? null}
|
||||
romajiText={pronunciationText}
|
||||
text={getLyricLineText(rawLine)}
|
||||
translatedText={translationText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<KaraokeLyricLine
|
||||
agents={agents}
|
||||
alignment={settings.alignment}
|
||||
className="synchronized"
|
||||
cueLines={rawLine.cueLines}
|
||||
data-lyric-time={lineStartMs}
|
||||
fontSize={settings.fontSize}
|
||||
id={`karaoke-line-${idx}`}
|
||||
key={idx}
|
||||
lineIndex={idx}
|
||||
romajiCueLines={syncedRomajiLyrics?.[idx] ?? null}
|
||||
romajiText={pronunciationText}
|
||||
translatedText={translationText}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
})}
|
||||
</LyricsScrollContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,12 +4,7 @@
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
padding: 10vh 0 50vh;
|
||||
overflow: hidden auto;
|
||||
word-break: break-all;
|
||||
transform: translateY(-2rem);
|
||||
|
||||
@media screen and (orientation: portrait) {
|
||||
padding: 5vh 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
getLyricLineText,
|
||||
normalizeLyrics,
|
||||
} from '/@/renderer/features/lyrics/api/lyrics-utils';
|
||||
import { LyricsScrollContent } from '/@/renderer/features/lyrics/components/lyrics-scroll-content';
|
||||
import { useLyricsAnimationEngine } from '/@/renderer/features/lyrics/hooks/use-lyrics-animation-engine';
|
||||
import {
|
||||
LYRICS_SCROLL_CONTAINER_ID,
|
||||
@@ -235,50 +236,56 @@ export const SynchronizedLyrics = ({
|
||||
ref={containerRef}
|
||||
style={{ ...containerStyle, ...style }}
|
||||
>
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{normalizedLyrics.map((rawLine, idx) => {
|
||||
const lineStartMs = getLyricLineStartMs(rawLine);
|
||||
const lineText = getLyricLineText(rawLine);
|
||||
const pronunciationText = getOverlayText(
|
||||
pronunciationLyrics,
|
||||
lineStartMs,
|
||||
romajiLyrics?.[idx] ? getLyricLineText(romajiLyrics[idx]) : undefined,
|
||||
);
|
||||
const translationText = getOverlayText(
|
||||
translationLyrics,
|
||||
lineStartMs,
|
||||
translatedLyrics?.split('\n')[idx],
|
||||
);
|
||||
|
||||
return (
|
||||
<LyricsScrollContent
|
||||
gap={settings.gap}
|
||||
paddingLeft={settings.paddingLeft}
|
||||
paddingRight={settings.paddingRight}
|
||||
>
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line synchronized"
|
||||
data-lyric-time={lineStartMs}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
id={`lyric-${idx}`}
|
||||
key={idx}
|
||||
romajiText={pronunciationText}
|
||||
text={lineText}
|
||||
translatedText={translationText}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
)}
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSize}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{normalizedLyrics.map((rawLine, idx) => {
|
||||
const lineStartMs = getLyricLineStartMs(rawLine);
|
||||
const lineText = getLyricLineText(rawLine);
|
||||
const pronunciationText = getOverlayText(
|
||||
pronunciationLyrics,
|
||||
lineStartMs,
|
||||
romajiLyrics?.[idx] ? getLyricLineText(romajiLyrics[idx]) : undefined,
|
||||
);
|
||||
const translationText = getOverlayText(
|
||||
translationLyrics,
|
||||
lineStartMs,
|
||||
translatedLyrics?.split('\n')[idx],
|
||||
);
|
||||
|
||||
return (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line synchronized"
|
||||
data-lyric-time={lineStartMs}
|
||||
fontSize={settings.fontSize}
|
||||
id={`lyric-${idx}`}
|
||||
key={idx}
|
||||
romajiText={pronunciationText}
|
||||
text={lineText}
|
||||
translatedText={translationText}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</LyricsScrollContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
padding: 10vh 0 6vh;
|
||||
overflow: hidden auto;
|
||||
transform: translateY(-2rem);
|
||||
|
||||
@media screen and (orientation: portrait) {
|
||||
padding: 5vh 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
|
||||
|
||||
import styles from './unsynchronized-lyrics.module.css';
|
||||
|
||||
import { LyricsScrollContent } from '/@/renderer/features/lyrics/components/lyrics-scroll-content';
|
||||
import { LyricLine } from '/@/renderer/features/lyrics/lyric-line';
|
||||
import { useLyricsDisplaySettings, useLyricsSettings } from '/@/renderer/store';
|
||||
import { FullLyricsMetadata } from '/@/shared/types/domain-types';
|
||||
@@ -49,35 +50,42 @@ export const UnsynchronizedLyrics = ({
|
||||
}, [romajiLyrics]);
|
||||
|
||||
return (
|
||||
<div className={styles.container} style={{ gap: `${settings.gapUnsync}px` }}>
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{lines.map((text, idx) => (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line unsynchronized"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
id={`lyric-${idx}`}
|
||||
key={idx}
|
||||
romajiText={romajiLines[idx]}
|
||||
text={text}
|
||||
translatedText={translatedLines[idx]}
|
||||
/>
|
||||
))}
|
||||
<div className={styles.container}>
|
||||
<LyricsScrollContent
|
||||
bottomScrollPadding="6vh"
|
||||
gap={settings.gapUnsync}
|
||||
paddingLeft={displaySettings.paddingLeft ?? 0}
|
||||
paddingRight={displaySettings.paddingRight ?? 0}
|
||||
>
|
||||
{settings.showProvider && source && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
text={`Provided by ${source}`}
|
||||
/>
|
||||
)}
|
||||
{settings.showMatch && remote && (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-credit"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
text={`"${name} by ${artist}"`}
|
||||
/>
|
||||
)}
|
||||
{lines.map((text, idx) => (
|
||||
<LyricLine
|
||||
alignment={settings.alignment}
|
||||
className="lyric-line unsynchronized"
|
||||
fontSize={settings.fontSizeUnsync}
|
||||
id={`lyric-${idx}`}
|
||||
key={idx}
|
||||
romajiText={romajiLines[idx]}
|
||||
text={text}
|
||||
translatedText={translatedLines[idx]}
|
||||
/>
|
||||
))}
|
||||
</LyricsScrollContent>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -248,7 +248,14 @@ const Controls = () => {
|
||||
};
|
||||
|
||||
const handleLyricsSettings = (property: string, value: any) => {
|
||||
const displayProperties = ['fontSize', 'fontSizeUnsync', 'gap', 'gapUnsync'];
|
||||
const displayProperties = [
|
||||
'fontSize',
|
||||
'fontSizeUnsync',
|
||||
'gap',
|
||||
'gapUnsync',
|
||||
'paddingLeft',
|
||||
'paddingRight',
|
||||
];
|
||||
if (displayProperties.includes(property)) {
|
||||
const currentDisplay = useSettingsStore.getState().lyricsDisplay;
|
||||
setSettings({
|
||||
@@ -475,6 +482,38 @@ const Controls = () => {
|
||||
</Group>
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricPaddingLeft')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
defaultValue={lyricConfig.paddingLeft ?? 0}
|
||||
label={(value) => `${value}%`}
|
||||
max={20}
|
||||
min={0}
|
||||
onChangeEnd={(value) => handleLyricsSettings('paddingLeft', value)}
|
||||
step={1}
|
||||
w="100%"
|
||||
/>
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricPaddingRight')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
defaultValue={lyricConfig.paddingRight ?? 0}
|
||||
label={(value) => `${value}%`}
|
||||
max={20}
|
||||
min={0}
|
||||
onChangeEnd={(value) => handleLyricsSettings('paddingRight', value)}
|
||||
step={1}
|
||||
w="100%"
|
||||
/>
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricAlignment')}
|
||||
|
||||
@@ -51,7 +51,14 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
const lyricConfig = { ...lyricsSettings, ...displaySettings };
|
||||
|
||||
const handleLyricsSettings = (property: string, value: any) => {
|
||||
const displayProperties = ['fontSize', 'fontSizeUnsync', 'gap', 'gapUnsync'];
|
||||
const displayProperties = [
|
||||
'fontSize',
|
||||
'fontSizeUnsync',
|
||||
'gap',
|
||||
'gapUnsync',
|
||||
'paddingLeft',
|
||||
'paddingRight',
|
||||
];
|
||||
if (displayProperties.includes(property)) {
|
||||
const currentDisplay = useSettingsStore.getState().lyricsDisplay;
|
||||
setSettings({
|
||||
@@ -284,6 +291,42 @@ export const MobileFullscreenPlayerHeader = memo(
|
||||
</Group>
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricPaddingLeft')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
defaultValue={lyricConfig.paddingLeft ?? 0}
|
||||
label={(value) => `${value}%`}
|
||||
max={20}
|
||||
min={0}
|
||||
onChangeEnd={(value) =>
|
||||
handleLyricsSettings('paddingLeft', value)
|
||||
}
|
||||
step={1}
|
||||
w="100%"
|
||||
/>
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricPaddingRight')}
|
||||
</Option.Label>
|
||||
<Option.Control>
|
||||
<Slider
|
||||
defaultValue={lyricConfig.paddingRight ?? 0}
|
||||
label={(value) => `${value}%`}
|
||||
max={20}
|
||||
min={0}
|
||||
onChangeEnd={(value) =>
|
||||
handleLyricsSettings('paddingRight', value)
|
||||
}
|
||||
step={1}
|
||||
w="100%"
|
||||
/>
|
||||
</Option.Control>
|
||||
</Option>
|
||||
<Option>
|
||||
<Option.Label>
|
||||
{t('page.fullscreenPlayer.config.lyricAlignment')}
|
||||
|
||||
@@ -570,6 +570,8 @@ const LyricsDisplaySettingsSchema = z.object({
|
||||
gap: z.number(),
|
||||
gapUnsync: z.number(),
|
||||
opacityNonActive: z.number(),
|
||||
paddingLeft: z.number(),
|
||||
paddingRight: z.number(),
|
||||
scaleNonActive: z.number(),
|
||||
});
|
||||
|
||||
@@ -1872,6 +1874,8 @@ const initialState: SettingsState = {
|
||||
gap: 24,
|
||||
gapUnsync: 24,
|
||||
opacityNonActive: 0.2,
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
scaleNonActive: 0.95,
|
||||
},
|
||||
},
|
||||
@@ -2539,10 +2543,25 @@ export const useSettingsStore = createWithEqualityFn<SettingsSlice>()(
|
||||
);
|
||||
}
|
||||
|
||||
if (version < 30) {
|
||||
for (const [key, displaySettings] of Object.entries(state.lyricsDisplay)) {
|
||||
const legacySettings = displaySettings as typeof displaySettings & {
|
||||
paddingX?: number;
|
||||
};
|
||||
const legacyPaddingX = legacySettings.paddingX ?? 0;
|
||||
|
||||
state.lyricsDisplay[key] = {
|
||||
...displaySettings,
|
||||
paddingLeft: displaySettings.paddingLeft ?? legacyPaddingX,
|
||||
paddingRight: displaySettings.paddingRight ?? legacyPaddingX,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return persistedState;
|
||||
},
|
||||
name: 'store_settings',
|
||||
version: 28,
|
||||
version: 30,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user