Fix panel animations when switching tabs
This commit is contained in:
parent
3339899684
commit
df0be46c3c
4 changed files with 81 additions and 60 deletions
|
@ -483,6 +483,7 @@ export type ConversationsStateType = Readonly<{
|
|||
targetedMessageSource: TargetedMessageSource | undefined;
|
||||
targetedConversationPanels: {
|
||||
isAnimating: boolean;
|
||||
wasAnimated: boolean;
|
||||
direction: 'push' | 'pop' | undefined;
|
||||
stack: ReadonlyArray<PanelRenderType>;
|
||||
watermark: number;
|
||||
|
@ -4156,6 +4157,7 @@ export function getEmptyState(): ConversationsStateType {
|
|||
showArchived: false,
|
||||
targetedConversationPanels: {
|
||||
isAnimating: false,
|
||||
wasAnimated: false,
|
||||
direction: undefined,
|
||||
stack: [],
|
||||
watermark: -1,
|
||||
|
@ -4710,6 +4712,7 @@ export function reducer(
|
|||
selectedConversationId,
|
||||
targetedConversationPanels: {
|
||||
isAnimating: false,
|
||||
wasAnimated: false,
|
||||
direction: undefined,
|
||||
stack: [],
|
||||
watermark: -1,
|
||||
|
@ -5651,6 +5654,7 @@ export function reducer(
|
|||
|
||||
const targetedConversationPanels = {
|
||||
isAnimating: false,
|
||||
wasAnimated: false,
|
||||
direction: 'push' as const,
|
||||
stack,
|
||||
watermark,
|
||||
|
@ -5691,6 +5695,7 @@ export function reducer(
|
|||
|
||||
const targetedConversationPanels = {
|
||||
isAnimating: false,
|
||||
wasAnimated: false,
|
||||
direction: 'pop' as const,
|
||||
stack: state.targetedConversationPanels.stack,
|
||||
watermark,
|
||||
|
@ -5726,6 +5731,7 @@ export function reducer(
|
|||
targetedConversationPanels: {
|
||||
...state.targetedConversationPanels,
|
||||
isAnimating: false,
|
||||
wasAnimated: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1201,6 +1201,13 @@ export const getIsPanelAnimating = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export const getWasPanelAnimated = createSelector(
|
||||
getConversations,
|
||||
(conversations): boolean => {
|
||||
return conversations.targetedConversationPanels.wasAnimated;
|
||||
}
|
||||
);
|
||||
|
||||
export const getConversationTitle = createSelector(
|
||||
getIntl,
|
||||
getActivePanel,
|
||||
|
|
|
@ -2,7 +2,14 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { MutableRefObject } from 'react';
|
||||
import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import React, {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import type { PanelRenderType } from '../../types/Panels';
|
||||
import * as log from '../../logging/log';
|
||||
|
@ -23,6 +30,7 @@ import { getIntl } from '../selectors/user';
|
|||
import {
|
||||
getIsPanelAnimating,
|
||||
getPanelInformation,
|
||||
getWasPanelAnimated,
|
||||
} from '../selectors/conversations';
|
||||
import { focusableSelectors } from '../../util/focusableSelectors';
|
||||
import { missingCaseError } from '../../util/missingCaseError';
|
||||
|
@ -92,37 +100,48 @@ export function ConversationPanel({
|
|||
const panelInformation = useSelector(getPanelInformation);
|
||||
const { panelAnimationDone, panelAnimationStarted } =
|
||||
useConversationsActions();
|
||||
const [shouldRenderPoppedPanel, setShouldRenderPoppedPanel] = useState(true);
|
||||
|
||||
const animateRef = useRef<HTMLDivElement | null>(null);
|
||||
const overlayRef = useRef<HTMLDivElement | null>(null);
|
||||
const prefersReducedMotion = useReducedMotion();
|
||||
|
||||
useEffect(() => {
|
||||
setShouldRenderPoppedPanel(true);
|
||||
}, [panelInformation?.prevPanel]);
|
||||
|
||||
const i18n = useSelector(getIntl);
|
||||
const isRTL = i18n.getLocaleDirection() === 'rtl';
|
||||
|
||||
const isAnimating = useSelector(getIsPanelAnimating);
|
||||
const wasAnimated = useSelector(getWasPanelAnimated);
|
||||
|
||||
const [lastPanelDoneAnimating, setLastPanelDoneAnimating] =
|
||||
useState<PanelRenderType | null>(null);
|
||||
|
||||
const wasAnimatedRef = useRef(wasAnimated);
|
||||
useEffect(() => {
|
||||
wasAnimatedRef.current = wasAnimated;
|
||||
}, [wasAnimated]);
|
||||
|
||||
useEffect(() => {
|
||||
if (prefersReducedMotion) {
|
||||
setLastPanelDoneAnimating(null);
|
||||
}, [panelInformation?.prevPanel]);
|
||||
|
||||
const onAnimationDone = useCallback(
|
||||
(panel: PanelRenderType | null) => {
|
||||
setLastPanelDoneAnimating(panel);
|
||||
panelAnimationDone();
|
||||
setShouldRenderPoppedPanel(false);
|
||||
},
|
||||
[panelAnimationDone]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (prefersReducedMotion || wasAnimatedRef.current) {
|
||||
onAnimationDone(panelInformation?.prevPanel ?? null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (panelInformation?.direction === 'pop') {
|
||||
if (!shouldRenderPoppedPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
return doAnimate({
|
||||
isRTL,
|
||||
onAnimationDone: () => {
|
||||
panelAnimationDone();
|
||||
setShouldRenderPoppedPanel(false);
|
||||
onAnimationDone(panelInformation?.prevPanel ?? null);
|
||||
},
|
||||
onAnimationStarted: panelAnimationStarted,
|
||||
overlay: {
|
||||
|
@ -143,13 +162,11 @@ export function ConversationPanel({
|
|||
}
|
||||
|
||||
if (panelInformation?.direction === 'push') {
|
||||
if (!panelInformation?.currPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
return doAnimate({
|
||||
isRTL,
|
||||
onAnimationDone: panelAnimationDone,
|
||||
onAnimationDone: () => {
|
||||
onAnimationDone(panelInformation?.prevPanel ?? null);
|
||||
},
|
||||
onAnimationStarted: panelAnimationStarted,
|
||||
overlay: {
|
||||
ref: overlayRef,
|
||||
|
@ -171,13 +188,12 @@ export function ConversationPanel({
|
|||
return undefined;
|
||||
}, [
|
||||
isRTL,
|
||||
panelAnimationDone,
|
||||
onAnimationDone,
|
||||
panelAnimationStarted,
|
||||
panelInformation?.currPanel,
|
||||
panelInformation?.direction,
|
||||
panelInformation?.prevPanel,
|
||||
prefersReducedMotion,
|
||||
shouldRenderPoppedPanel,
|
||||
]);
|
||||
|
||||
if (!panelInformation) {
|
||||
|
@ -200,10 +216,10 @@ export function ConversationPanel({
|
|||
panel={activePanel}
|
||||
/>
|
||||
)}
|
||||
{shouldRenderPoppedPanel && (
|
||||
{lastPanelDoneAnimating !== prevPanel && (
|
||||
<div className="ConversationPanel__overlay" ref={overlayRef} />
|
||||
)}
|
||||
{shouldRenderPoppedPanel && prevPanel && (
|
||||
{prevPanel && lastPanelDoneAnimating !== prevPanel && (
|
||||
<PanelContainer
|
||||
conversationId={conversationId}
|
||||
panel={prevPanel}
|
||||
|
|
|
@ -696,6 +696,13 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-04-20T16:43:40.643Z"
|
||||
},
|
||||
{
|
||||
"rule": "thenify-multiArgs",
|
||||
"path": "node_modules/make-dir/node_modules/pify/index.js",
|
||||
"line": "\t\tif (options.multiArgs) {",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-08-21T18:28:53.361Z"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-outerHTML",
|
||||
"path": "node_modules/domutils/node_modules/dom-serializer/lib/esm/index.js",
|
||||
|
@ -1126,13 +1133,6 @@
|
|||
"reasonCategory": "notExercisedByOurApp",
|
||||
"updated": "2023-06-29T17:01:25.145Z"
|
||||
},
|
||||
{
|
||||
"rule": "thenify-multiArgs",
|
||||
"path": "node_modules/make-dir/node_modules/pify/index.js",
|
||||
"line": "\t\tif (options.multiArgs) {",
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2023-08-18T19:09:30.283Z"
|
||||
},
|
||||
{
|
||||
"rule": "DOM-innerHTML",
|
||||
"path": "node_modules/min-document/serialize.js",
|
||||
|
@ -2355,8 +2355,7 @@
|
|||
"path": "ts/components/LeftPane.tsx",
|
||||
"line": " const measureRef = useRef<HTMLDivElement>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-08-09T21:48:42.602Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-08-09T21:48:42.602Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
|
@ -2427,16 +2426,14 @@
|
|||
"path": "ts/components/Modal.tsx",
|
||||
"line": " const bodyRef = useRef<HTMLDivElement>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/Modal.tsx",
|
||||
"line": " const bodyInnerRef = useRef<HTMLDivElement>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
|
@ -2529,24 +2526,21 @@
|
|||
"path": "ts/components/StoryViewer.tsx",
|
||||
"line": " const progressBarRef = useRef<HTMLDivElement>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2022-10-13T15:18:21.267Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2022-10-13T15:18:21.267Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/StoryViewer.tsx",
|
||||
"line": " const animationRef = useRef<Animation | null>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2022-10-13T15:18:21.267Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2022-10-13T15:18:21.267Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/StoryViewer.tsx",
|
||||
"line": " const onFinishRef = useRef<(() => void) | null>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2022-10-13T15:18:21.267Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2022-10-13T15:18:21.267Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
|
@ -2595,8 +2589,7 @@
|
|||
"path": "ts/components/TextAttachment.tsx",
|
||||
"line": " const ref = useRef<HTMLDivElement>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
|
@ -2617,8 +2610,7 @@
|
|||
"path": "ts/components/Tooltip.tsx",
|
||||
"line": " const timeoutRef = useRef<NodeJS.Timeout | undefined>();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-08-10T00:23:35.320Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-08-10T00:23:35.320Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
|
@ -2832,56 +2824,49 @@
|
|||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " const sizeRef = useRef<Size | null>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " const onSizeChangeRef = useRef<SizeChangeHandler | void>(onSizeChange);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " const ref = useRef<any>();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " * const scrollerRef = useRef()",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " * const scrollerInnerRef = useRef()",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " const scrollRef = useRef<Scroll | null>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/hooks/useSizeObserver.tsx",
|
||||
"line": " const onScrollChangeRef = useRef<ScrollChangeHandler>(onScrollChange);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-25T21:55:26.191Z",
|
||||
"reasonDetail": "<optional>"
|
||||
"updated": "2023-07-25T21:55:26.191Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
|
@ -2936,6 +2921,13 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-07-13T23:34:39.367Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/state/smart/ConversationPanel.tsx",
|
||||
"line": " const wasAnimatedRef = useRef(wasAnimated);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2023-08-20T22:14:52.008Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/state/smart/InstallScreen.tsx",
|
||||
|
|
Loading…
Reference in a new issue