mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-21 03:22:11 +00:00
refactor(SideDrawer): simplify refs handing
This commit is contained in:
parent
00d89aec75
commit
a3c895dfc6
3 changed files with 21 additions and 29 deletions
|
|
@ -5,15 +5,15 @@ type Props = {
|
||||||
children: JSX.Element,
|
children: JSX.Element,
|
||||||
when: boolean,
|
when: boolean,
|
||||||
name: string,
|
name: string,
|
||||||
onTransitionEnd?: () => void
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Transition = ({ children, when, name, onTransitionEnd }: Props) => {
|
const Transition = ({ children, when, name }: Props) => {
|
||||||
const [element, setElement] = useState<HTMLElement | null>(null);
|
const [element, setElement] = useState<HTMLElement | null>(null);
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
|
|
||||||
const [state, setState] = useState('enter');
|
const [state, setState] = useState('enter');
|
||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
|
const [transitionEnded, setTransitionEnded] = useState(false);
|
||||||
|
|
||||||
const callbackRef = useCallback((element: HTMLElement | null) => {
|
const callbackRef = useCallback((element: HTMLElement | null) => {
|
||||||
setElement(element);
|
setElement(element);
|
||||||
|
|
@ -30,20 +30,15 @@ const Transition = ({ children, when, name, onTransitionEnd }: Props) => {
|
||||||
);
|
);
|
||||||
}, [name, state, active, children]);
|
}, [name, state, active, children]);
|
||||||
|
|
||||||
const handleTransitionEnd = useCallback(() => {
|
const onTransitionEnd = useCallback(() => {
|
||||||
switch (state) {
|
setTransitionEnded(true);
|
||||||
case 'enter':
|
state === 'exit' && setMounted(false);
|
||||||
onTransitionEnd?.();
|
|
||||||
break;
|
|
||||||
case 'exit':
|
|
||||||
setMounted(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, [state]);
|
}, [state]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setState(when ? 'enter' : 'exit');
|
setState(when ? 'enter' : 'exit');
|
||||||
when && setMounted(true);
|
when && setMounted(true);
|
||||||
|
setTransitionEnded(false);
|
||||||
}, [when]);
|
}, [when]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -53,14 +48,15 @@ const Transition = ({ children, when, name, onTransitionEnd }: Props) => {
|
||||||
}, [element]);
|
}, [element]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
element?.addEventListener('transitionend', handleTransitionEnd);
|
element?.addEventListener('transitionend', onTransitionEnd);
|
||||||
return () => element?.removeEventListener('transitionend', handleTransitionEnd);
|
return () => element?.removeEventListener('transitionend', onTransitionEnd);
|
||||||
}, [element, onTransitionEnd]);
|
}, [element, onTransitionEnd]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
mounted && cloneElement(children, {
|
mounted && cloneElement(children, {
|
||||||
ref: callbackRef,
|
ref: callbackRef,
|
||||||
className,
|
className,
|
||||||
|
transitionEnded
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
const routeFocused = useRouteFocused();
|
const routeFocused = useRouteFocused();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const [sideDrawerTransitionEnded, setSideDrawerTransitionEnded] = React.useState(false);
|
|
||||||
const [seeking, setSeeking] = React.useState(false);
|
const [seeking, setSeeking] = React.useState(false);
|
||||||
|
|
||||||
const [casting, setCasting] = React.useState(() => {
|
const [casting, setCasting] = React.useState(() => {
|
||||||
|
|
@ -511,10 +510,6 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
}
|
}
|
||||||
}, [settings.pauseOnMinimize, shell.windowClosed, shell.windowHidden]);
|
}, [settings.pauseOnMinimize, shell.windowClosed, shell.windowHidden]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!sideDrawerOpen) setSideDrawerTransitionEnded(false);
|
|
||||||
}, [sideDrawerOpen]);
|
|
||||||
|
|
||||||
React.useLayoutEffect(() => {
|
React.useLayoutEffect(() => {
|
||||||
const onKeyDown = (event) => {
|
const onKeyDown = (event) => {
|
||||||
switch (event.code) {
|
switch (event.code) {
|
||||||
|
|
@ -831,14 +826,13 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
<Transition when={sideDrawerOpen} name={'slide-left'} onTransitionEnd={() => setSideDrawerTransitionEnded(true)}>
|
<Transition when={sideDrawerOpen} name={'slide-left'}>
|
||||||
<SideDrawer
|
<SideDrawer
|
||||||
className={classnames(styles['layer'], styles['side-drawer-layer'])}
|
className={classnames(styles['layer'], styles['side-drawer-layer'])}
|
||||||
metaItem={player.metaItem?.content}
|
metaItem={player.metaItem?.content}
|
||||||
seriesInfo={player.seriesInfo}
|
seriesInfo={player.seriesInfo}
|
||||||
closeSideDrawer={closeSideDrawer}
|
closeSideDrawer={closeSideDrawer}
|
||||||
selectedVideoID={player.selected?.streamRequest.path.id}
|
selected={player.selected?.streamRequest.path.id}
|
||||||
transitionEnded={sideDrawerTransitionEnded}
|
|
||||||
/>
|
/>
|
||||||
</Transition>
|
</Transition>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,15 @@ type Props = {
|
||||||
className?: string;
|
className?: string;
|
||||||
seriesInfo: SeriesInfo;
|
seriesInfo: SeriesInfo;
|
||||||
metaItem: MetaItem;
|
metaItem: MetaItem;
|
||||||
selectedVideoID: string;
|
|
||||||
transitionEnded: boolean;
|
|
||||||
closeSideDrawer: () => void;
|
closeSideDrawer: () => void;
|
||||||
|
selected: string;
|
||||||
|
transitionEnded: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SideDrawer = memo(forwardRef<HTMLDivElement, Props>(({ seriesInfo, className, closeSideDrawer, ...props }: Props, ref) => {
|
const SideDrawer = memo(forwardRef<HTMLDivElement, Props>(({ seriesInfo, className, closeSideDrawer, selected, transitionEnded, ...props }: Props, ref) => {
|
||||||
const { core } = useServices();
|
const { core } = useServices();
|
||||||
const [season, setSeason] = useState<number>(seriesInfo?.season);
|
const [season, setSeason] = useState<number>(seriesInfo?.season);
|
||||||
|
const selectedVideoRef = useRef<HTMLDivElement>(null);
|
||||||
const metaItem = useMemo(() => {
|
const metaItem = useMemo(() => {
|
||||||
return seriesInfo ?
|
return seriesInfo ?
|
||||||
{
|
{
|
||||||
|
|
@ -77,12 +78,13 @@ const SideDrawer = memo(forwardRef<HTMLDivElement, Props>(({ seriesInfo, classNa
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedVideoRef = useRef<HTMLDivElement>(null);
|
const getSelectedRef = useCallback((video: Video) => {
|
||||||
|
return video.id === selected ? selectedVideoRef : null;
|
||||||
|
}, [selected]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
props.transitionEnded &&
|
transitionEnded && selectedVideoRef?.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
selectedVideoRef?.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
}, [transitionEnded]);
|
||||||
}, [props.transitionEnded]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className={classNames(styles['side-drawer'], className)} onMouseDown={onMouseDown}>
|
<div ref={ref} className={classNames(styles['side-drawer'], className)} onMouseDown={onMouseDown}>
|
||||||
|
|
@ -129,7 +131,7 @@ const SideDrawer = memo(forwardRef<HTMLDivElement, Props>(({ seriesInfo, classNa
|
||||||
scheduled={video.scheduled}
|
scheduled={video.scheduled}
|
||||||
onMarkVideoAsWatched={onMarkVideoAsWatched}
|
onMarkVideoAsWatched={onMarkVideoAsWatched}
|
||||||
onMarkSeasonAsWatched={onMarkSeasonAsWatched}
|
onMarkSeasonAsWatched={onMarkSeasonAsWatched}
|
||||||
ref={video.id === props.selectedVideoID ? selectedVideoRef : null}
|
ref={getSelectedRef(video)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue