Story Ribbon: Fix animation on iOS, refactoring

This commit is contained in:
Alexander Zinchuk 2023-08-16 15:27:46 +02:00
parent 52189af778
commit 5c14ed4e83
7 changed files with 34 additions and 60 deletions

View File

@ -44,22 +44,11 @@
}
.chat-list-wrapper {
--story-ribbon-height: 5.5rem;
height: calc(100% - var(--header-height));
position: relative;
height: calc(100% - var(--header-height));
&.shown {
transform: translateY(calc(var(--story-ribbon-height) * -1));
height: calc(100% - var(--header-height) + var(--story-ribbon-height));
transition: none;
}
&.open, &.closing {
transition: transform 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
&.open {
transform: translateY(0);
&.with-story-ribbon {
--extra-height: var(--header-height);
}
}
}

View File

@ -1,7 +1,6 @@
import type { FC } from '../../lib/teact/teact';
import React, { memo } from '../../lib/teact/teact';
import { getActions } from '../../global';
import type { FC } from '../../lib/teact/teact';
import type { LeftColumnContent, SettingsScreens } from '../../types';
import type { FolderEditDispatch } from '../../hooks/reducers/useFoldersReducer';
import type { GlobalState } from '../../global/types';
@ -117,7 +116,13 @@ const ArchivedChats: FC<OwnProps> = ({
</DropdownMenu>
)}
</div>
<div className={buildClassName('chat-list-wrapper', storyRibbonClassNames)}>
<div
className={buildClassName(
'chat-list-wrapper',
shouldRenderStoryRibbon && 'with-story-ribbon',
storyRibbonClassNames,
)}
>
{shouldRenderStoryRibbon && (
<StoryRibbon isArchived className="left-header-shadow" isClosing={isStoryRibbonClosing} />
)}

View File

@ -1,16 +1,17 @@
import type { FC } from '../../../lib/teact/teact';
import React, {
memo, useEffect, useLayoutEffect, useMemo, useRef, useState,
memo, useEffect, useMemo, useRef,
} from '../../../lib/teact/teact';
import { getActions, getGlobal, withGlobal } from '../../../global';
import type { ApiChatFolder, ApiChatlistExportedInvite } from '../../../api/types';
import type { SettingsScreens, LeftColumnContent } from '../../../types';
import type { LeftColumnContent, SettingsScreens } from '../../../types';
import type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
import type { GlobalState } from '../../../global/types';
import type { TabWithProperties } from '../../ui/TabList';
import TabList from '../../ui/TabList';
import { ALL_FOLDER_ID, ANIMATION_END_DELAY } from '../../../config';
import { ALL_FOLDER_ID } from '../../../config';
import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
@ -26,9 +27,8 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import { useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
import Transition from '../../ui/Transition';
import TabList from '../../ui/TabList';
import ChatList from './ChatList';
import StoryRibbon from '../../story/StoryRibbon';
import ChatList from './ChatList';
type OwnProps = {
onSettingsScreenSelect: (screen: SettingsScreens) => void;
@ -56,7 +56,6 @@ type StateProps = {
const SAVED_MESSAGES_HOTKEY = '0';
const FIRST_FOLDER_INDEX = 0;
const STORY_RIBBON_APPEARANCE_DURATION_MS = 200 + ANIMATION_END_DELAY;
const ChatFolders: FC<OwnProps & StateProps> = ({
foldersDispatch,
@ -92,28 +91,11 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
const transitionRef = useRef<HTMLDivElement>(null);
const lang = useLang();
const [isStoryRibbonAnimated, setIsStoryRibbonAnimated] = useState(false);
useEffect(() => {
loadChatFolders();
}, []);
useLayoutEffect(() => {
let timeoutId: number;
if (isStoryRibbonShown) {
timeoutId = window.setTimeout(() => {
setIsStoryRibbonAnimated(true);
}, STORY_RIBBON_APPEARANCE_DURATION_MS);
} else {
setIsStoryRibbonAnimated(false);
}
return () => {
window.clearTimeout(timeoutId);
};
}, [isStoryRibbonShown]);
const {
shouldRender: shouldRenderStoryRibbon,
transitionClassNames: storyRibbonClassNames,
@ -327,7 +309,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
className={buildClassName(
'ChatFolders',
shouldRenderFolders && shouldHideFolderTabs && 'ChatFolders--tabs-hidden',
shouldRenderStoryRibbon && !isStoryRibbonAnimated && 'withStoryRibbon',
shouldRenderStoryRibbon && 'with-story-ribbon',
storyRibbonClassNames,
)}
>

View File

@ -43,7 +43,6 @@ type OwnProps = {
canDisplayArchive?: boolean;
archiveSettings: GlobalState['archiveSettings'];
isForumPanelOpen?: boolean;
isStoryRibbonShown?: boolean;
className?: string;
foldersDispatch: FolderEditDispatch;
onSettingsScreenSelect: (screen: SettingsScreens) => void;

View File

@ -16,23 +16,6 @@
flex-direction: column;
overflow: hidden;
&.withStoryRibbon {
--story-ribbon-height: 5.5rem;
&.shown {
transform: translateY(calc(var(--story-ribbon-height) * -1));
height: calc(100% + var(--story-ribbon-height));
transition: none;
}
&.open, &.closing {
transition: transform 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
&.open {
transform: translateY(0);
}
}
.tabs-placeholder {
height: 2.625rem;
/* stylelint-disable-next-line plugin/no-low-performance-animation-properties */

View File

@ -54,7 +54,8 @@ function StoryToggler({
}, [orderedUserIds]);
useStoryPreloader(preloadUserIds);
const { shouldRender, transitionClassNames } = useShowTransition(canShow && isShown);
// For some reason, setting 'slow' here also fixes scroll freezes on iOS when collapsing Story Ribbon
const { shouldRender, transitionClassNames } = useShowTransition(canShow && isShown, undefined, undefined, 'slow');
if (!shouldRender) {
return undefined;

View File

@ -216,3 +216,18 @@
.fab-padding-bottom {
padding-bottom: 5rem !important;
}
.with-story-ribbon {
--story-ribbon-height: 5.5rem;
height: calc(100% - var(--extra-height, 0px) + var(--story-ribbon-height)) !important;
transform: translateY(calc(var(--story-ribbon-height) * -1));
&.open, &.closing {
transition: transform 250ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
&.open {
transform: translateY(0);
}
}