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 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 { t } = useLocale();
|
||||||
|
|
||||||
|
const ref = useRef<HTMLVideoElement>(null);
|
||||||
|
|
||||||
|
const size = useSize(ref);
|
||||||
|
|
||||||
|
const { style: blackBarsStyle } = useBlackBars(ref, size, {
|
||||||
|
size: blackBarsSize,
|
||||||
|
disabled: !blackBars
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ref.current) return;
|
if (!ref.current) return;
|
||||||
paused ? ref.current.pause() : ref.current.play();
|
paused ? ref.current.pause() : ref.current.play();
|
||||||
|
@ -214,7 +220,7 @@ const Video = ({ paused, blackBars, blackBarsSize, className, ...props }: VideoP
|
||||||
}}
|
}}
|
||||||
playsInline
|
playsInline
|
||||||
draggable={false}
|
draggable={false}
|
||||||
style={{ ...(blackBars ? blackBarsStyle : {}) }}
|
style={{ ...blackBarsStyle }}
|
||||||
className={clsx(blackBars && size.width === 0 && 'invisible', className)}
|
className={clsx(blackBars && size.width === 0 && 'invisible', className)}
|
||||||
{...props}
|
{...props}
|
||||||
key={props.src}
|
key={props.src}
|
||||||
|
|
|
@ -240,10 +240,7 @@ interface ThumbnailProps extends Omit<ImageProps, 'blackBarsStyle' | 'size'> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Thumbnail = forwardRef<HTMLImageElement, ThumbnailProps>(
|
const Thumbnail = forwardRef<HTMLImageElement, ThumbnailProps>(
|
||||||
(
|
({ blackBars, blackBarsSize, extension, cover, className, style, ...props }, _ref) => {
|
||||||
{ crossOrigin, blackBars, blackBarsSize, extension, cover, className, style, ...props },
|
|
||||||
_ref
|
|
||||||
) => {
|
|
||||||
const ref = useRef<HTMLImageElement>(null);
|
const ref = useRef<HTMLImageElement>(null);
|
||||||
useImperativeHandle<HTMLImageElement | null, HTMLImageElement | null>(
|
useImperativeHandle<HTMLImageElement | null, HTMLImageElement | null>(
|
||||||
_ref,
|
_ref,
|
||||||
|
@ -252,27 +249,28 @@ const Thumbnail = forwardRef<HTMLImageElement, ThumbnailProps>(
|
||||||
|
|
||||||
const size = useSize(ref);
|
const size = useSize(ref);
|
||||||
|
|
||||||
const { style: blackBarsStyle } = useBlackBars(size, blackBarsSize);
|
const { style: blackBarsStyle } = useBlackBars(ref, size, {
|
||||||
|
size: blackBarsSize,
|
||||||
|
disabled: !blackBars
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Image
|
<Image
|
||||||
{...props}
|
{...props}
|
||||||
{...{
|
className={clsx(className, blackBars && size.width === 0 && 'invisible')}
|
||||||
className: clsx(className, blackBars && size.width === 0 && 'invisible'),
|
style={{ ...style, ...blackBarsStyle }}
|
||||||
style: { ...style, ...(blackBars ? blackBarsStyle : undefined) },
|
size={size}
|
||||||
size,
|
ref={ref}
|
||||||
ref
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{(cover || (size && size.width > 80)) && extension && (
|
|
||||||
|
{(cover || size.width > 80) && extension && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
...(!cover &&
|
...(!cover && {
|
||||||
size && {
|
marginTop: Math.floor(size.height / 2) - 2,
|
||||||
marginTop: Math.floor(size.height / 2) - 2,
|
marginLeft: Math.floor(size.width / 2) - 2
|
||||||
marginLeft: Math.floor(size.width / 2) - 2
|
})
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'pointer-events-none absolute rounded bg-black/60 px-1 py-0.5 text-[9px] font-semibold uppercase text-white opacity-70',
|
'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 { useCallbackToWatchResize } from '~/hooks';
|
||||||
|
|
||||||
import { useExplorerContext } from '../Context';
|
|
||||||
|
|
||||||
export function useSize(ref: RefObject<Element>) {
|
export function useSize(ref: RefObject<Element>) {
|
||||||
const explorerSettings = useExplorerContext({ suspense: false })?.useSettingsSnapshot();
|
|
||||||
|
|
||||||
const initialized = useRef(false);
|
|
||||||
|
|
||||||
const [size, setSize] = useState({ width: 0, height: 0 });
|
const [size, setSize] = useState({ width: 0, height: 0 });
|
||||||
|
|
||||||
useEffect(() => {
|
useCallbackToWatchResize(({ width, height }) => setSize({ width, height }), [], ref);
|
||||||
initialized.current = false;
|
|
||||||
}, [explorerSettings?.gridItemSize, explorerSettings?.listViewIconSize]);
|
|
||||||
|
|
||||||
useCallbackToWatchResize(
|
|
||||||
({ width, height }) => {
|
|
||||||
if (initialized.current || (!width && !height)) return;
|
|
||||||
setSize({ width, height });
|
|
||||||
initialized.current = true;
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
ref
|
|
||||||
);
|
|
||||||
|
|
||||||
return size;
|
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(() => {
|
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 =
|
const getBarSize = () => {
|
||||||
blackBarsSize ||
|
return Math.floor(
|
||||||
Math.floor(Math.ceil(orientation === 'vertical' ? height : width) / 10);
|
Math.ceil(orientation === 'vertical' ? size.height : size.width) / 10
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const xBarSize = orientation === 'vertical' ? barSize : 0;
|
let barSize = options.size;
|
||||||
const yBarSize = orientation === 'horizontal' ? barSize : 0;
|
|
||||||
|
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 {
|
return {
|
||||||
size: {
|
size: {
|
||||||
|
@ -54,5 +103,5 @@ export function useBlackBars(videoSize: { width: number; height: number }, black
|
||||||
borderRadius: 4
|
borderRadius: 4
|
||||||
} satisfies CSSProperties
|
} satisfies CSSProperties
|
||||||
};
|
};
|
||||||
}, [videoSize, blackBarsSize]);
|
}, [options.disabled, options.size, size.height, size.width, node]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue