[ENG-1714] Fix black bars (#2289)

* fix black bars

* Update Original.tsx
This commit is contained in:
nikec 2024-04-05 19:11:47 +02:00 committed by GitHub
parent f168b5e45d
commit 7d0eee2e02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 103 additions and 50 deletions

View file

@ -184,11 +184,17 @@ interface VideoProps extends VideoHTMLAttributes<HTMLVideoElement> {
}
const Video = ({ paused, blackBars, blackBarsSize, className, ...props }: VideoProps) => {
const ref = useRef<HTMLVideoElement>(null);
const size = useSize(ref);
const { style: blackBarsStyle } = useBlackBars(size, blackBarsSize);
const { t } = useLocale();
const ref = useRef<HTMLVideoElement>(null);
const size = useSize(ref);
const { style: blackBarsStyle } = useBlackBars(ref, size, {
size: blackBarsSize,
disabled: !blackBars
});
useEffect(() => {
if (!ref.current) return;
paused ? ref.current.pause() : ref.current.play();
@ -214,7 +220,7 @@ const Video = ({ paused, blackBars, blackBarsSize, className, ...props }: VideoP
}}
playsInline
draggable={false}
style={{ ...(blackBars ? blackBarsStyle : {}) }}
style={{ ...blackBarsStyle }}
className={clsx(blackBars && size.width === 0 && 'invisible', className)}
{...props}
key={props.src}

View file

@ -240,10 +240,7 @@ interface ThumbnailProps extends Omit<ImageProps, 'blackBarsStyle' | 'size'> {
}
const Thumbnail = forwardRef<HTMLImageElement, ThumbnailProps>(
(
{ crossOrigin, blackBars, blackBarsSize, extension, cover, className, style, ...props },
_ref
) => {
({ blackBars, blackBarsSize, extension, cover, className, style, ...props }, _ref) => {
const ref = useRef<HTMLImageElement>(null);
useImperativeHandle<HTMLImageElement | null, HTMLImageElement | null>(
_ref,
@ -252,27 +249,28 @@ const Thumbnail = forwardRef<HTMLImageElement, ThumbnailProps>(
const size = useSize(ref);
const { style: blackBarsStyle } = useBlackBars(size, blackBarsSize);
const { style: blackBarsStyle } = useBlackBars(ref, size, {
size: blackBarsSize,
disabled: !blackBars
});
return (
<>
<Image
{...props}
{...{
className: clsx(className, blackBars && size.width === 0 && 'invisible'),
style: { ...style, ...(blackBars ? blackBarsStyle : undefined) },
size,
ref
}}
className={clsx(className, blackBars && size.width === 0 && 'invisible')}
style={{ ...style, ...blackBarsStyle }}
size={size}
ref={ref}
/>
{(cover || (size && size.width > 80)) && extension && (
{(cover || size.width > 80) && extension && (
<div
style={{
...(!cover &&
size && {
marginTop: Math.floor(size.height / 2) - 2,
marginLeft: Math.floor(size.width / 2) - 2
})
...(!cover && {
marginTop: Math.floor(size.height / 2) - 2,
marginLeft: Math.floor(size.width / 2) - 2
})
}}
className={clsx(
'pointer-events-none absolute rounded bg-black/60 px-1 py-0.5 text-[9px] font-semibold uppercase text-white opacity-70',

View file

@ -1,44 +1,93 @@
import { useEffect, useMemo, useRef, useState, type CSSProperties, type RefObject } from 'react';
import { useMemo, useRef, useState, type CSSProperties, type RefObject } from 'react';
import { useCallbackToWatchResize } from '~/hooks';
import { useExplorerContext } from '../Context';
export function useSize(ref: RefObject<Element>) {
const explorerSettings = useExplorerContext({ suspense: false })?.useSettingsSnapshot();
const initialized = useRef(false);
const [size, setSize] = useState({ width: 0, height: 0 });
useEffect(() => {
initialized.current = false;
}, [explorerSettings?.gridItemSize, explorerSettings?.listViewIconSize]);
useCallbackToWatchResize(
({ width, height }) => {
if (initialized.current || (!width && !height)) return;
setSize({ width, height });
initialized.current = true;
},
[],
ref
);
useCallbackToWatchResize(({ width, height }) => setSize({ width, height }), [], ref);
return size;
}
export function useBlackBars(videoSize: { width: number; height: number }, blackBarsSize?: number) {
export function useBlackBars(
node: RefObject<HTMLElement>,
size: ReturnType<typeof useSize>,
options: { size?: number; disabled?: boolean } = {}
) {
const previousNodeSize = useRef<typeof size>();
const previousParentSize = useRef<typeof size>();
const previousBarSize = useRef<{ x?: number; y?: number }>();
return useMemo(() => {
const { width, height } = videoSize;
if (options.disabled) return {};
const orientation = height > width ? 'vertical' : 'horizontal';
const orientation = size.height > size.width ? 'vertical' : 'horizontal';
const barSize =
blackBarsSize ||
Math.floor(Math.ceil(orientation === 'vertical' ? height : width) / 10);
const getBarSize = () => {
return Math.floor(
Math.ceil(orientation === 'vertical' ? size.height : size.width) / 10
);
};
const xBarSize = orientation === 'vertical' ? barSize : 0;
const yBarSize = orientation === 'horizontal' ? barSize : 0;
let barSize = options.size;
if (barSize === undefined) {
let parentSize = { width: 0, height: 0 };
const parent = node.current?.parentElement;
if (parent) {
const style = getComputedStyle(parent);
const paddingX = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
const paddingY = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
parentSize = {
width: parent.clientWidth - paddingX,
height: parent.clientHeight - paddingY
};
}
if (
parentSize.width !== previousParentSize.current?.width ||
parentSize.height !== previousParentSize.current?.height
) {
barSize = getBarSize();
} else if (previousNodeSize.current && previousBarSize.current) {
const previousNodeWidth =
previousNodeSize.current.width + (previousBarSize.current.x ?? 0) * 2;
const previousNodeHeight =
previousNodeSize.current.height + (previousBarSize.current.y ?? 0) * 2;
const nodeWidth =
previousNodeSize.current.width -
Math.max(0, previousNodeWidth - parentSize.width);
const nodeHeight =
previousNodeSize.current.height -
Math.max(0, previousNodeHeight - parentSize.height);
if (
(orientation === 'vertical' && nodeWidth === size.width) ||
(orientation === 'horizontal' && nodeHeight === size.height)
) {
barSize = previousBarSize.current.x ?? previousBarSize.current.y;
} else {
barSize = getBarSize();
}
} else {
barSize = getBarSize();
}
previousParentSize.current = parentSize;
}
const xBarSize = orientation === 'vertical' ? barSize : undefined;
const yBarSize = orientation === 'horizontal' ? barSize : undefined;
previousNodeSize.current = { width: size.width, height: size.height };
previousBarSize.current = { x: xBarSize, y: yBarSize };
return {
size: {
@ -54,5 +103,5 @@ export function useBlackBars(videoSize: { width: number; height: number }, black
borderRadius: 4
} satisfies CSSProperties
};
}, [videoSize, blackBarsSize]);
}, [options.disabled, options.size, size.height, size.width, node]);
}