Fix panel animations when switching tabs

This commit is contained in:
Jamie Kyle 2023-08-21 13:18:22 -07:00 committed by GitHub
parent 3339899684
commit df0be46c3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 60 deletions

View file

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