Skip to content
Snippets Groups Projects
Verified Commit a6fb936f authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Cleanup and adding preload

parent 939f5dec
No related branches found
No related tags found
No related merge requests found
......@@ -11415,6 +11415,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
......
......@@ -20,6 +20,7 @@
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3",
"react-sweet-state": "^2.3.1",
"resize-observer-polyfill": "^1.5.1",
"typescript": "^3.7.5"
},
"scripts": {
......
......@@ -7,9 +7,10 @@ interface Props {
previewTrack: HTMLTrackElement | null,
duration: number,
position: number,
hidden: boolean,
}
export function PreviewBar({previewTrack, duration, position}: Props) {
export function PreviewBar({previewTrack, duration, position, hidden}: Props) {
const classes = useStyles();
const [previewBarRef, previewHeadRef, offset] = useOffsetRef(position);
......@@ -23,7 +24,8 @@ export function PreviewBar({previewTrack, duration, position}: Props) {
ref={previewHeadRef}
className={classes.previewHead}
style={{
transform: `translate3d(${offset}px, 0, 0)`
transform: `translate3d(${offset}px, 0, 0)`,
opacity: hidden ? 0 : 1,
}}
>
<PreviewViewer
......@@ -32,22 +34,21 @@ export function PreviewBar({previewTrack, duration, position}: Props) {
/>
</div>
</div>
), [classes.previewHead, classes.previewBar, duration, offset, position, previewBarRef, previewHeadRef, previewTrack]);
), [previewBarRef, classes.previewBar, classes.previewHead, previewHeadRef, offset, hidden, previewTrack, position, duration]);
}
const useStyles = createUseStyles({
previewBar: {
position: "relative",
width: "40rem",
height: "6rem",
display: "flex",
flexDirection: "row",
alignContent: "stretch",
background: "#7c7",
},
previewHead: {
position: "absolute",
top: 0,
bottom: 0,
left: "-5rem",
width: "10rem",
maxWidth: "136rem",
maxHeight: "9rem",
display: "flex",
flexDirection: "column-reverse",
background: "#f00",
......
import React, {useMemo} from "react";
import {createUseStyles} from "react-jss";
import {HeadPortal} from "../../util/head/HeadPortal";
import {useImage} from "../../util/media/useImage";
import {useTextTrackCues} from "../../util/media/useTextTrackCues";
import {parseImageSprite} from "../../util/sprite/parseImageSprite";
......@@ -19,9 +20,21 @@ export function PreviewViewer({previewTrack, position}: Props) {
const imageSprite = useMemo(() => parseImageSprite(activeUrl), [activeUrl]);
const image = useImage(imageSprite?.src || null);
const sprite = useImageSprite(imageSprite, image);
const sources = useMemo(() => previewTrack === null ? null : Array.from(new Set(cues.map(it => {
const url = new URL(it.text, previewTrack.src);
url.hash = "";
return url.toString();
}))), [cues, previewTrack]);
return useMemo(() => (
<React.Fragment>
<HeadPortal>
{sources?.map(it => (
<link key={it} rel="preload" href={it} as="image" crossOrigin="anonymous"/>
))}
</HeadPortal>
<img alt="" className={classes.preview} src={sprite || undefined}/>
), [sprite]);
</React.Fragment>
), [classes.preview, sources, sprite]);
}
const useStyles = createUseStyles({
......
......@@ -60,11 +60,16 @@ export function SeekBar({video, previewTrack, duration, position}: Props) {
}}
/>
</div>
), [classes.seekBar, classes.seekHead, isVisible, offset, onClick, onMouseLeave, onMouseMove, seekBarRef, seekHeadRef]);
), [classes, isVisible, offset, onClick, onMouseLeave, onMouseMove, seekBarRef, seekHeadRef]);
return (
<React.Fragment>
<PreviewBar previewTrack={previewTrack} duration={duration} position={seekPosition || 0}/>
<PreviewBar
previewTrack={previewTrack}
duration={duration}
position={seekPosition || 0}
hidden={seekPosition === null}
/>
{seekBar}
</React.Fragment>
)
......@@ -74,14 +79,13 @@ const useStyles = createUseStyles({
seekBar: {
position: "relative",
width: "40rem",
display: "flex",
flexDirection: "row",
alignContent: "stretch",
height: "5rem",
background: "#77c",
},
seekHead: {
position: "absolute",
top: 0,
bottom: 0,
left: "-0.05rem",
width: "0.1rem",
background: "#f00",
}
......
import React from "react";
import ReactDOM from "react-dom";
export function HeadPortal({children}: React.PropsWithChildren<{}>) {
return ReactDOM.createPortal(children, document.head);
}
......@@ -4,8 +4,6 @@ export const useOffset = <T extends HTMLElement, U extends HTMLElement>(parent:
const parentWidth = useWidth(parent);
const childWidth = useWidth(child);
const offset = parentWidth * position;
const minOffset = childWidth / 2;
const maxOffset = parentWidth - minOffset;
return Math.max(minOffset, Math.min(offset, maxOffset));
const offset = parentWidth * position - childWidth / 2;
return Math.max(0, Math.min(offset, parentWidth - childWidth));
}
import {useEffect, useState} from "react";
import ResizeObserver from 'resize-observer-polyfill';
export const useWidth = <T extends HTMLElement>(it: T | null) => {
const [width, setWidth] = useState<number>(0);
useEffect(() => {
if (it !== null) {
let animationFrame: number | null = null;
const listener = () => {
};
listener();
const observer = new ResizeObserver(([element]) => {
animationFrame = window.requestAnimationFrame(() => {
animationFrame = null;
setWidth(it?.offsetWidth || 0);
setWidth(element.contentRect.width || 0);
});
};
listener();
window.addEventListener("resize", listener);
})
observer.observe(it);
return () => {
window.removeEventListener("resize", listener);
observer.unobserve(it);
if (animationFrame !== null) {
window.cancelAnimationFrame(animationFrame);
}
}
}
}, [it]);
return width;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment