mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 13:23:28 +00:00
[ENG-1714] Fix black bars (#2289)
* fix black bars * Update Original.tsx
This commit is contained in:
parent
f168b5e45d
commit
7d0eee2e02
|
@ -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}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue