[Glitch] Fix media modal navigation in RTL languages
Port f1b0832bfb08dc2d8ccb410be917095f0fcac62e to glitch-soc Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
695371f591
commit
5109b00bc0
@ -47,11 +47,9 @@ interface MediaModalProps {
|
||||
}
|
||||
|
||||
const MIN_SWIPE_DISTANCE = 400;
|
||||
const isLtrDir = getComputedStyle(document.body).direction !== 'rtl';
|
||||
|
||||
export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
HTMLDivElement,
|
||||
MediaModalProps
|
||||
>(
|
||||
export const MediaModal = forwardRef<HTMLDivElement, MediaModalProps>(
|
||||
(
|
||||
{
|
||||
media,
|
||||
@ -64,15 +62,16 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
statusId,
|
||||
onChangeBackgroundColor,
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- _ref is required to keep the ref forwarding working
|
||||
_ref,
|
||||
) => {
|
||||
const [index, setIndex] = useState(startIndex);
|
||||
const [zoomedIn, setZoomedIn] = useState(false);
|
||||
const currentMedia = media.get(index);
|
||||
|
||||
const sign = isLtrDir ? '-' : '';
|
||||
|
||||
const [wrapperStyles, api] = useSpring(() => ({
|
||||
x: `-${index * 100}%`,
|
||||
x: `${sign}${index * 100}%`,
|
||||
}));
|
||||
|
||||
const handleChangeIndex = useCallback(
|
||||
@ -85,10 +84,12 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
setIndex(newIndex);
|
||||
setZoomedIn(false);
|
||||
if (animate) {
|
||||
void api.start({ x: `calc(-${newIndex * 100}% + 0px)` });
|
||||
void api.start({
|
||||
x: `calc(${sign}${newIndex * 100}% + 0px)`,
|
||||
});
|
||||
}
|
||||
},
|
||||
[api, media.size],
|
||||
[api, media.size, sign],
|
||||
);
|
||||
const handlePrevClick = useCallback(() => {
|
||||
handleChangeIndex(index - 1, true);
|
||||
@ -99,11 +100,14 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (event.key === 'ArrowLeft') {
|
||||
const prevKey = isLtrDir ? 'ArrowLeft' : 'ArrowRight';
|
||||
const nextKey = isLtrDir ? 'ArrowRight' : 'ArrowLeft';
|
||||
|
||||
if (event.key === prevKey) {
|
||||
handlePrevClick();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
} else if (event.key === 'ArrowRight') {
|
||||
} else if (event.key === nextKey) {
|
||||
handleNextClick();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@ -124,13 +128,14 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
active &&
|
||||
Math.abs(mx) > Math.min(window.innerWidth / 4, MIN_SWIPE_DISTANCE)
|
||||
) {
|
||||
handleChangeIndex(index - xDir);
|
||||
handleChangeIndex(isLtrDir ? index - xDir : index + xDir);
|
||||
cancel();
|
||||
}
|
||||
// Set the x position via calc to ensure proper centering regardless of screen size.
|
||||
const x = active ? mx : 0;
|
||||
const operator = isLtrDir ? '+' : '-';
|
||||
void api.start({
|
||||
x: `calc(-${index * 100}% + ${x}px)`,
|
||||
x: `calc(${sign}${index * 100}% ${operator} ${x}px)`,
|
||||
});
|
||||
},
|
||||
{ pointer: { capture: false } },
|
||||
@ -161,14 +166,23 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
width: number;
|
||||
height: number;
|
||||
}>({ width: 0, height: 0 });
|
||||
const handleRef: RefCallback<HTMLDivElement> = useCallback((ele) => {
|
||||
if (ele?.clientWidth && ele.clientHeight) {
|
||||
setViewportDimensions({
|
||||
width: ele.clientWidth,
|
||||
height: ele.clientHeight,
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
const handleRef: RefCallback<HTMLDivElement> = useCallback(
|
||||
(ele) => {
|
||||
if (typeof _ref === 'function') {
|
||||
_ref(ele);
|
||||
} else if (_ref) {
|
||||
_ref.current = ele;
|
||||
}
|
||||
|
||||
if (ele?.clientWidth && ele.clientHeight) {
|
||||
setViewportDimensions({
|
||||
width: ele.clientWidth,
|
||||
height: ele.clientHeight,
|
||||
});
|
||||
}
|
||||
},
|
||||
[_ref],
|
||||
);
|
||||
|
||||
const zoomable =
|
||||
currentMedia?.get('type') === 'image' &&
|
||||
@ -268,9 +282,8 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
const leftNav = media.size > 1 && (
|
||||
const prevNav = media.size > 1 && (
|
||||
<button
|
||||
tabIndex={0}
|
||||
className='media-modal__nav media-modal__nav--prev'
|
||||
onClick={handlePrevClick}
|
||||
aria-label={intl.formatMessage(messages.previous)}
|
||||
@ -279,9 +292,8 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
<Icon id='chevron-left' icon={ChevronLeftIcon} />
|
||||
</button>
|
||||
);
|
||||
const rightNav = media.size > 1 && (
|
||||
const nextNav = media.size > 1 && (
|
||||
<button
|
||||
tabIndex={0}
|
||||
className='media-modal__nav media-modal__nav--next'
|
||||
onClick={handleNextClick}
|
||||
aria-label={intl.formatMessage(messages.next)}
|
||||
@ -330,8 +342,8 @@ export const MediaModal: FC<MediaModalProps> = forwardRef<
|
||||
/>
|
||||
</div>
|
||||
|
||||
{leftNav}
|
||||
{rightNav}
|
||||
{prevNav}
|
||||
{nextNav}
|
||||
|
||||
<div className='media-modal__overlay'>
|
||||
<MediaPagination
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user