[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:
diondiondion 2026-06-24 10:54:58 +02:00 committed by Claire
parent 695371f591
commit 5109b00bc0

View File

@ -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