Media Viewer: Fix navigating back in history (#2056)
This commit is contained in:
parent
e55b78a2dc
commit
15527f925d
@ -37,7 +37,6 @@ import { renderMessageText } from '../common/helpers/renderMessageText';
|
|||||||
import useFlag from '../../hooks/useFlag';
|
import useFlag from '../../hooks/useFlag';
|
||||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import { useMediaProps } from './hooks/useMediaProps';
|
import { useMediaProps } from './hooks/useMediaProps';
|
||||||
@ -64,6 +63,7 @@ type StateProps = {
|
|||||||
chatMessages?: Record<number, ApiMessage>;
|
chatMessages?: Record<number, ApiMessage>;
|
||||||
collectionIds?: number[];
|
collectionIds?: number[];
|
||||||
animationLevel: AnimationLevel;
|
animationLevel: AnimationLevel;
|
||||||
|
shouldSkipHistoryAnimations?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ANIMATION_DURATION = 350;
|
const ANIMATION_DURATION = 350;
|
||||||
@ -80,6 +80,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
chatMessages,
|
chatMessages,
|
||||||
collectionIds,
|
collectionIds,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
|
shouldSkipHistoryAnimations,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
openMediaViewer,
|
openMediaViewer,
|
||||||
@ -95,7 +96,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
const animationKey = useRef<number>();
|
const animationKey = useRef<number>();
|
||||||
const prevSenderId = usePrevious<string | undefined>(senderId);
|
const prevSenderId = usePrevious<string | undefined>(senderId);
|
||||||
const headerAnimation = animationLevel === 2 ? 'slide-fade' : 'none';
|
const headerAnimation = animationLevel === 2 ? 'slide-fade' : 'none';
|
||||||
const isGhostAnimation = animationLevel === 2;
|
const isGhostAnimation = animationLevel === 2 && !shouldSkipHistoryAnimations;
|
||||||
|
|
||||||
/* Controls */
|
/* Controls */
|
||||||
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
|
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
|
||||||
@ -184,12 +185,10 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
bestImageData, prevBestImageData, dimensions, isVideo, hasFooter,
|
bestImageData, prevBestImageData, dimensions, isVideo, hasFooter,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const close = useCallback(() => {
|
const handleClose = useCallback(() => closeMediaViewer(), [closeMediaViewer]);
|
||||||
closeMediaViewer();
|
|
||||||
}, [closeMediaViewer]);
|
|
||||||
|
|
||||||
const handleFooterClick = useCallback(() => {
|
const handleFooterClick = useCallback(() => {
|
||||||
close();
|
handleClose();
|
||||||
|
|
||||||
if (IS_SINGLE_COLUMN_LAYOUT) {
|
if (IS_SINGLE_COLUMN_LAYOUT) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -199,7 +198,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
} else {
|
} else {
|
||||||
focusMessage({ chatId, threadId, mediaId });
|
focusMessage({ chatId, threadId, mediaId });
|
||||||
}
|
}
|
||||||
}, [close, chatId, threadId, focusMessage, toggleChatInfo, mediaId]);
|
}, [handleClose, chatId, threadId, focusMessage, toggleChatInfo, mediaId]);
|
||||||
|
|
||||||
const handleForward = useCallback(() => {
|
const handleForward = useCallback(() => {
|
||||||
openForwardMenu({
|
openForwardMenu({
|
||||||
@ -221,8 +220,8 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
}, [avatarOwner?.id, chatId, openMediaViewer, origin, threadId]);
|
}, [avatarOwner?.id, chatId, openMediaViewer, origin, threadId]);
|
||||||
|
|
||||||
useEffect(() => (isOpen ? captureEscKeyListener(() => {
|
useEffect(() => (isOpen ? captureEscKeyListener(() => {
|
||||||
close();
|
handleClose();
|
||||||
}) : undefined), [close, isOpen]);
|
}) : undefined), [handleClose, isOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isVideo && !isGif) {
|
if (isVideo && !isGif) {
|
||||||
@ -235,7 +234,6 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
windowSize.disableRefresh();
|
windowSize.disableRefresh();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@ -254,11 +252,6 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
useHistoryBack({
|
|
||||||
isActive: isOpen,
|
|
||||||
onBack: closeMediaViewer,
|
|
||||||
});
|
|
||||||
|
|
||||||
function renderSenderInfo() {
|
function renderSenderInfo() {
|
||||||
return avatarOwner ? (
|
return avatarOwner ? (
|
||||||
<SenderInfo
|
<SenderInfo
|
||||||
@ -276,7 +269,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ShowTransition id="MediaViewer" isOpen={isOpen}>
|
<ShowTransition id="MediaViewer" isOpen={isOpen} noCloseTransition={shouldSkipHistoryAnimations}>
|
||||||
<div className="media-viewer-head" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="media-viewer-head" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||||
{IS_SINGLE_COLUMN_LAYOUT && (
|
{IS_SINGLE_COLUMN_LAYOUT && (
|
||||||
<Button
|
<Button
|
||||||
@ -285,7 +278,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
size="smaller"
|
size="smaller"
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
onClick={close}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
<i className="icon-close" />
|
<i className="icon-close" />
|
||||||
</Button>
|
</Button>
|
||||||
@ -300,7 +293,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
fileName={fileName}
|
fileName={fileName}
|
||||||
canReport={canReport}
|
canReport={canReport}
|
||||||
onReport={openReportModal}
|
onReport={openReportModal}
|
||||||
onCloseMediaViewer={close}
|
onCloseMediaViewer={handleClose}
|
||||||
onForward={handleForward}
|
onForward={handleForward}
|
||||||
zoomLevelChange={zoomLevelChange}
|
zoomLevelChange={zoomLevelChange}
|
||||||
setZoomLevelChange={setZoomLevelChange}
|
setZoomLevelChange={setZoomLevelChange}
|
||||||
@ -328,7 +321,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
zoomLevelChange={zoomLevelChange}
|
zoomLevelChange={zoomLevelChange}
|
||||||
isVideo={isVideo}
|
isVideo={isVideo}
|
||||||
animationLevel={animationLevel}
|
animationLevel={animationLevel}
|
||||||
onClose={close}
|
onClose={handleClose}
|
||||||
selectMedia={selectMedia}
|
selectMedia={selectMedia}
|
||||||
onFooterClick={handleFooterClick}
|
onFooterClick={handleFooterClick}
|
||||||
/>
|
/>
|
||||||
@ -349,16 +342,18 @@ export default memo(withGlobal(
|
|||||||
animationLevel,
|
animationLevel,
|
||||||
} = global.settings.byKey;
|
} = global.settings.byKey;
|
||||||
|
|
||||||
|
const { shouldSkipHistoryAnimations } = global;
|
||||||
|
|
||||||
let isChatWithSelf = !!chatId && selectIsChatWithSelf(global, chatId);
|
let isChatWithSelf = !!chatId && selectIsChatWithSelf(global, chatId);
|
||||||
|
|
||||||
if (origin === MediaViewerOrigin.SearchResult) {
|
if (origin === MediaViewerOrigin.SearchResult) {
|
||||||
if (!(chatId && mediaId)) {
|
if (!(chatId && mediaId)) {
|
||||||
return { animationLevel };
|
return { animationLevel, shouldSkipHistoryAnimations };
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = selectChatMessage(global, chatId, mediaId);
|
const message = selectChatMessage(global, chatId, mediaId);
|
||||||
if (!message) {
|
if (!message) {
|
||||||
return { animationLevel };
|
return { animationLevel, shouldSkipHistoryAnimations };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -369,6 +364,7 @@ export default memo(withGlobal(
|
|||||||
origin,
|
origin,
|
||||||
message,
|
message,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
|
shouldSkipHistoryAnimations,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,11 +379,12 @@ export default memo(withGlobal(
|
|||||||
isChatWithSelf,
|
isChatWithSelf,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
origin,
|
origin,
|
||||||
|
shouldSkipHistoryAnimations,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(chatId && threadId && mediaId)) {
|
if (!(chatId && threadId && mediaId)) {
|
||||||
return { animationLevel };
|
return { animationLevel, shouldSkipHistoryAnimations };
|
||||||
}
|
}
|
||||||
|
|
||||||
let message: ApiMessage | undefined;
|
let message: ApiMessage | undefined;
|
||||||
@ -398,7 +395,7 @@ export default memo(withGlobal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!message) {
|
if (!message) {
|
||||||
return { animationLevel };
|
return { animationLevel, shouldSkipHistoryAnimations };
|
||||||
}
|
}
|
||||||
|
|
||||||
let chatMessages: Record<number, ApiMessage> | undefined;
|
let chatMessages: Record<number, ApiMessage> | undefined;
|
||||||
@ -429,6 +426,7 @@ export default memo(withGlobal(
|
|||||||
chatMessages,
|
chatMessages,
|
||||||
collectionIds,
|
collectionIds,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
|
shouldSkipHistoryAnimations,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(MediaViewer));
|
)(MediaViewer));
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import useLang from '../../hooks/useLang';
|
|||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import useTimeout from '../../hooks/useTimeout';
|
import useTimeout from '../../hooks/useTimeout';
|
||||||
import useWindowSize from '../../hooks/useWindowSize';
|
import useWindowSize from '../../hooks/useWindowSize';
|
||||||
|
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||||
|
|
||||||
import MediaViewerContent from './MediaViewerContent';
|
import MediaViewerContent from './MediaViewerContent';
|
||||||
|
|
||||||
@ -104,6 +105,12 @@ const MediaViewerSlides: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
|
useHistoryBack({
|
||||||
|
isActive: isOpen,
|
||||||
|
onBack: onClose,
|
||||||
|
shouldBeReplaced: true,
|
||||||
|
});
|
||||||
|
|
||||||
const setTransform = useCallback((value: Transform) => {
|
const setTransform = useCallback((value: Transform) => {
|
||||||
transformRef.current = value;
|
transformRef.current = value;
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
@ -370,7 +377,7 @@ const MediaViewerSlides: FC<OwnProps> = ({
|
|||||||
onUpdate: (value) => setTransform({
|
onUpdate: (value) => setTransform({
|
||||||
y: 0,
|
y: 0,
|
||||||
x: value,
|
x: value,
|
||||||
scale: transformRef.current.scale,
|
scale: transformRef.current?.scale ?? 1,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,14 +11,24 @@ type OwnProps = {
|
|||||||
id?: string;
|
id?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||||
|
noCloseTransition?: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ShowTransition: FC<OwnProps> = ({
|
const ShowTransition: FC<OwnProps> = ({
|
||||||
isOpen, isCustom, id, className, onClick, children,
|
isOpen,
|
||||||
|
isCustom,
|
||||||
|
id,
|
||||||
|
className,
|
||||||
|
onClick,
|
||||||
|
noCloseTransition,
|
||||||
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const { shouldRender, transitionClassNames } = useShowTransition(
|
const {
|
||||||
isOpen, undefined, undefined, isCustom ? false : undefined,
|
shouldRender,
|
||||||
|
transitionClassNames,
|
||||||
|
} = useShowTransition(
|
||||||
|
isOpen, undefined, undefined, isCustom ? false : undefined, noCloseTransition,
|
||||||
);
|
);
|
||||||
const prevIsOpen = usePrevious(isOpen);
|
const prevIsOpen = usePrevious(isOpen);
|
||||||
const prevChildren = usePrevious(children);
|
const prevChildren = usePrevious(children);
|
||||||
|
|||||||
@ -142,12 +142,15 @@ function cleanupClosed(alreadyClosedCount = 1) {
|
|||||||
|
|
||||||
function cleanupTrashedState() {
|
function cleanupTrashedState() {
|
||||||
// Navigation to previous page reload, state of which was trashed by reload
|
// Navigation to previous page reload, state of which was trashed by reload
|
||||||
|
let isAnimationDisabled = false;
|
||||||
for (let i = historyState.length - 1; i > 0; i--) {
|
for (let i = historyState.length - 1; i > 0; i--) {
|
||||||
if (historyState[i].isClosed) {
|
if (historyState[i].isClosed) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isSafariGestureAnimation) {
|
// TODO[history]: probably we should not call this inside the loop
|
||||||
|
if (!isAnimationDisabled && isSafariGestureAnimation) {
|
||||||
getActions().disableHistoryAnimations();
|
getActions().disableHistoryAnimations();
|
||||||
|
isAnimationDisabled = true;
|
||||||
}
|
}
|
||||||
historyState[i].onBack?.();
|
historyState[i].onBack?.();
|
||||||
}
|
}
|
||||||
@ -188,13 +191,16 @@ window.addEventListener('popstate', ({ state }: PopStateEvent) => {
|
|||||||
if (index < historyCursor) {
|
if (index < historyCursor) {
|
||||||
// Navigating back
|
// Navigating back
|
||||||
let alreadyClosedCount = 0;
|
let alreadyClosedCount = 0;
|
||||||
|
let isAnimationDisabled = false;
|
||||||
for (let i = historyCursor; i > index - alreadyClosedCount; i--) {
|
for (let i = historyCursor; i > index - alreadyClosedCount; i--) {
|
||||||
if (historyState[i].isClosed) {
|
if (historyState[i].isClosed) {
|
||||||
alreadyClosedCount++;
|
alreadyClosedCount++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isSafariGestureAnimation) {
|
// TODO[history]: probably we should not call this inside the loop
|
||||||
|
if (!isAnimationDisabled && isSafariGestureAnimation) {
|
||||||
getActions().disableHistoryAnimations();
|
getActions().disableHistoryAnimations();
|
||||||
|
isAnimationDisabled = true;
|
||||||
}
|
}
|
||||||
historyState[i].onBack?.();
|
historyState[i].onBack?.();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user