Fix broken layout on lyrics scroll

- App layout would break when transitioning into the full-screen due to scrollIntoView
- Replace scroll action with scrollTop implementation
This commit is contained in:
jeffvli 2023-06-09 15:43:45 -07:00 committed by Jeff
parent 493e13ebc0
commit 72811dbedb
2 changed files with 37 additions and 7 deletions

View file

@ -6,7 +6,7 @@ import { RiInformationFill } from 'react-icons/ri';
import styled from 'styled-components'; import styled from 'styled-components';
import { useSongLyricsByRemoteId, useSongLyricsBySong } from './queries/lyric-query'; import { useSongLyricsByRemoteId, useSongLyricsBySong } from './queries/lyric-query';
import { SynchronizedLyrics } from './synchronized-lyrics'; import { SynchronizedLyrics } from './synchronized-lyrics';
import { ScrollArea, Spinner, TextTitle } from '/@/renderer/components'; import { Spinner, TextTitle } from '/@/renderer/components';
import { ErrorFallback } from '/@/renderer/features/action-required'; import { ErrorFallback } from '/@/renderer/features/action-required';
import { UnsynchronizedLyrics } from '/@/renderer/features/lyrics/unsynchronized-lyrics'; import { UnsynchronizedLyrics } from '/@/renderer/features/lyrics/unsynchronized-lyrics';
import { getServerById, useCurrentSong, usePlayerStore } from '/@/renderer/store'; import { getServerById, useCurrentSong, usePlayerStore } from '/@/renderer/store';
@ -53,11 +53,12 @@ const LyricsContainer = styled.div`
} }
`; `;
const ScrollContainer = styled(motion(ScrollArea))` const ScrollContainer = styled(motion.div)`
position: relative; position: relative;
z-index: 1; z-index: 1;
width: 100%;
height: 100%;
text-align: center; text-align: center;
transform: translateY(-2rem);
mask-image: linear-gradient( mask-image: linear-gradient(
180deg, 180deg,
@ -182,7 +183,6 @@ export const Lyrics = () => {
<ScrollContainer <ScrollContainer
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
scrollHideDelay={0}
transition={{ duration: 0.5 }} transition={{ duration: 0.5 }}
> >
{isSynchronizedLyrics ? ( {isSynchronizedLyrics ? (

View file

@ -16,7 +16,19 @@ import styled from 'styled-components';
const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null;
const SynchronizedLyricsContainer = styled.div` const SynchronizedLyricsContainer = styled.div`
width: 100%;
height: 100%;
padding: 5rem 0; padding: 5rem 0;
overflow: scroll;
transform: translateY(-2rem);
mask-image: linear-gradient(
180deg,
transparent 5%,
rgba(0, 0, 0, 100%) 20%,
rgba(0, 0, 0, 100%) 85%,
transparent 95%
);
`; `;
interface SynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> { interface SynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> {
@ -120,7 +132,10 @@ export const SynchronizedLyrics = ({
return; return;
} }
const currentLyric = document.querySelector(`#lyric-${index}`); const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement;
const currentLyric = document.querySelector(`#lyric-${index}`) as HTMLElement;
const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 ?? 0;
if (currentLyric === null) { if (currentLyric === null) {
lyricRef.current = undefined; lyricRef.current = undefined;
return; return;
@ -129,7 +144,7 @@ export const SynchronizedLyrics = ({
currentLyric.classList.add('active'); currentLyric.classList.add('active');
if (followRef.current) { if (followRef.current) {
currentLyric.scrollIntoView({ behavior: 'smooth', block: 'center' }); doc?.scroll({ behavior: 'smooth', top: offsetTop });
} }
if (index !== lyricRef.current!.length - 1) { if (index !== lyricRef.current!.length - 1) {
@ -254,8 +269,23 @@ export const SynchronizedLyrics = ({
timerEpoch.current += 1; timerEpoch.current += 1;
}, []); }, []);
const hideScrollbar = () => {
const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement;
doc.classList.add('hide-scrollbar');
};
const showScrollbar = () => {
const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement;
doc.classList.remove('hide-scrollbar');
};
return ( return (
<SynchronizedLyricsContainer className="synchronized-lyrics"> <SynchronizedLyricsContainer
className="synchronized-lyrics overlay-scrollbar"
id="sychronized-lyrics-scroll-container"
onMouseEnter={showScrollbar}
onMouseLeave={hideScrollbar}
>
{source && ( {source && (
<LyricLine <LyricLine
className="lyric-credit" className="lyric-credit"