From d965b6c47905e4800bc47261287ea7d7805925d4 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Thu, 30 Mar 2023 18:26:14 -0500 Subject: [PATCH] Middle Column: Better pinned message animation (#2716) Co-authored-by: Alexander Zinchuk --- src/api/gramjs/apiBuilders/messages.ts | 3 +- src/api/types/messages.ts | 1 + src/assets/fonts/icomoon.woff | Bin 56468 -> 56612 bytes src/assets/fonts/icomoon.woff2 | Bin 26296 -> 26172 bytes src/components/common/AnimatedCounter.tsx | 40 +- src/components/mediaViewer/MediaViewer.tsx | 9 +- src/components/middle/ActionMessage.tsx | 12 + .../middle/HeaderPinnedMessage.module.scss | 269 ++++++++++++ src/components/middle/HeaderPinnedMessage.tsx | 95 +++-- src/components/middle/MessageList.tsx | 22 +- src/components/middle/MessageListContent.tsx | 7 +- src/components/middle/MiddleColumn.tsx | 17 + src/components/middle/MiddleHeader.scss | 291 +------------ src/components/middle/MiddleHeader.tsx | 56 +-- .../PinnedMessageNavigation.module.scss | 35 ++ .../middle/PinnedMessageNavigation.tsx | 19 +- .../middle/hooks/useMessageObservers.ts | 33 +- .../middle/hooks/usePinnedMessage.ts | 170 ++++++++ src/components/middle/message/Message.tsx | 18 + .../middle/message/MessageContextMenu.tsx | 2 +- .../middle/message/MessageMeta.scss | 7 +- src/components/middle/message/MessageMeta.tsx | 5 + .../middle/message/hooks/useFocusMessage.ts | 10 +- src/components/ui/Transition.scss | 160 +++++++ src/components/ui/Transition.tsx | 3 +- src/global/actions/api/messages.ts | 116 ++--- src/global/actions/apiUpdaters/messages.ts | 5 +- src/global/actions/ui/messages.ts | 15 +- src/global/cache.ts | 1 + src/global/reducers/messages.ts | 71 ++-- src/global/selectors/messages.ts | 28 +- src/global/types.ts | 7 +- src/lib/teact/teactn.tsx | 17 +- src/styles/Telegram T.json | 395 +++++++++--------- src/styles/_mixins.scss | 34 ++ src/styles/icons.scss | 3 + src/util/iteratees.ts | 37 ++ 37 files changed, 1304 insertions(+), 709 deletions(-) create mode 100644 src/components/middle/HeaderPinnedMessage.module.scss create mode 100644 src/components/middle/PinnedMessageNavigation.module.scss create mode 100644 src/components/middle/hooks/usePinnedMessage.ts diff --git a/src/api/gramjs/apiBuilders/messages.ts b/src/api/gramjs/apiBuilders/messages.ts index aeeffd0cf..8da7648db 100644 --- a/src/api/gramjs/apiBuilders/messages.ts +++ b/src/api/gramjs/apiBuilders/messages.ts @@ -162,7 +162,7 @@ type UniversalMessage = ( & Pick, ( 'out' | 'message' | 'entities' | 'fromId' | 'peerId' | 'fwdFrom' | 'replyTo' | 'replyMarkup' | 'post' | 'media' | 'action' | 'views' | 'editDate' | 'editHide' | 'mediaUnread' | 'groupedId' | 'mentioned' | 'viaBotId' | - 'replies' | 'fromScheduled' | 'postAuthor' | 'noforwards' | 'reactions' | 'forwards' | 'silent' + 'replies' | 'fromScheduled' | 'postAuthor' | 'noforwards' | 'reactions' | 'forwards' | 'silent' | 'pinned' )> ); @@ -213,6 +213,7 @@ export function buildApiMessageWithChatId( forwards: mtpMessage.forwards, isFromScheduled: mtpMessage.fromScheduled, isSilent: mtpMessage.silent, + isPinned: mtpMessage.pinned, reactions: mtpMessage.reactions && buildMessageReactions(mtpMessage.reactions), emojiOnlyCount, ...(replyToMsgId && { replyToMessageId: replyToMsgId }), diff --git a/src/api/types/messages.ts b/src/api/types/messages.ts index f93c16e7b..2b428fcfb 100644 --- a/src/api/types/messages.ts +++ b/src/api/types/messages.ts @@ -423,6 +423,7 @@ export interface ApiMessage { isHideKeyboardSelective?: boolean; isFromScheduled?: boolean; isSilent?: boolean; + isPinned?: boolean; seenByUserIds?: string[]; isProtected?: boolean; isForwardingAllowed?: boolean; diff --git a/src/assets/fonts/icomoon.woff b/src/assets/fonts/icomoon.woff index 478f2d1366d636de20287892fb3fc799017cf522..12494fc095b7d859771e8e22c6ccfe00c86660b4 100644 GIT binary patch delta 439 zcmbQTlX=N5X0dXAH#Y`G1|Ybr!oUrp@7!QuoZNUvc%r6Q{j=oU!~zBe#tfi%2ndUZ zU3N=PECz|~0rEMZSRg&8G7Ttpgn{A80uVkexocHMYGMil!!;mgFau%btn~g2pde6e z4v?<`!t6&_nlf@rDu7}K7#NrZK$!K0zf4YkGEkk}%?m(7yFj=g-ijwTu>xrE?HHg& z1u(wK_%$yvHx(#W160!n!ZW=%e;4EzmjM04GVzZ;nzrxeaV9MOV z?8=}4R5|&AyF$GjqdcRS2s?8JD>qv;kCh9*j=+TT{OSU1d`vtn7y1PR96DV2yd>ka z*tl8eC@V95WaVV`^6Yov=bvzakBOTVsFd}>1fVWQYYwI=EeS~$PS!a}iON9pfer-X zCsMZY@%%Pl8Ms-10t^ffR0Ze3=>PvFGhH)fJhIv18V@rIP`-P!%gqi(k*olq3XuLI UjGq~RAp!(Upa|Lg{?<}P0IzIry8r+H delta 319 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 = ({ text, }) => { const lang = useLang(); - const prevText = usePrevious(text); - const forceUpdate = useForceUpdate(); - - const isAnimatingRef = useRef(false); + const prevTextRef = useRef(); + const [isAnimating, markAnimating, unmarkAnimating] = useFlag(false); const shouldAnimate = getGlobal().settings.byKey.animationLevel === ANIMATION_LEVEL_MAX; const textElement = useMemo(() => { - if (!shouldAnimate) return text; + if (!shouldAnimate) { + return text; + } + if (!isAnimating) { + return prevTextRef.current || text; + } + + const prevText = prevTextRef.current; const elements = []; for (let i = 0; i < text.length; i++) { @@ -37,8 +40,8 @@ const AnimatedCounter: FC = ({ elements.push(
{text[i]}
-
{prevText[i]}
-
{text[i]}
+
{prevText[i]}
+
{text[i]}
, ); } else { @@ -46,15 +49,14 @@ const AnimatedCounter: FC = ({ } } - isAnimatingRef.current = true; + prevTextRef.current = text; return elements; - }, [prevText, shouldAnimate, text]); + }, [shouldAnimate, isAnimating, text]); - useTimeout(() => { - isAnimatingRef.current = false; - forceUpdate(); - }, isAnimatingRef.current ? ANIMATION_TIME : undefined); + useEffect(() => { + markAnimating(); + }, [text]); return ( diff --git a/src/components/mediaViewer/MediaViewer.tsx b/src/components/mediaViewer/MediaViewer.tsx index 77eae3033..b8c021a8f 100644 --- a/src/components/mediaViewer/MediaViewer.tsx +++ b/src/components/mediaViewer/MediaViewer.tsx @@ -17,9 +17,8 @@ import { selectCurrentMediaSearch, selectTabState, selectIsChatWithSelf, selectListedIds, - selectOutlyingIds, selectScheduledMessage, - selectUser, + selectUser, selectOutlyingListByMessageId, } from '../../global/selectors'; import { stopCurrentAudio } from '../../util/audioPlayer'; import captureEscKeyListener from '../../util/captureEscKeyListener'; @@ -462,9 +461,9 @@ export default memo(withGlobal( let collectionIds: number[] | undefined; if (origin === MediaViewerOrigin.Inline - || origin === MediaViewerOrigin.Album - || origin === MediaViewerOrigin.SuggestedAvatar) { - collectionIds = selectOutlyingIds(global, chatId, threadId) || selectListedIds(global, chatId, threadId); + || origin === MediaViewerOrigin.Album) { + collectionIds = selectOutlyingListByMessageId(global, chatId, threadId, message.id) + || selectListedIds(global, chatId, threadId); } else if (origin === MediaViewerOrigin.SharedMedia) { const currentSearch = selectCurrentMediaSearch(global); const { foundIds } = (currentSearch && currentSearch.resultsByType && currentSearch.resultsByType.media) || {}; diff --git a/src/components/middle/ActionMessage.tsx b/src/components/middle/ActionMessage.tsx index f4812b77a..d77035b74 100644 --- a/src/components/middle/ActionMessage.tsx +++ b/src/components/middle/ActionMessage.tsx @@ -8,6 +8,7 @@ import type { ApiUser, ApiMessage, ApiChat, ApiSticker, ApiTopic, } from '../../api/types'; import type { FocusDirection } from '../../types'; +import type { PinnedIntersectionChangedCallback } from './hooks/usePinnedMessage'; import { selectUser, @@ -45,6 +46,7 @@ type OwnProps = { isLastInList?: boolean; isInsideTopic?: boolean; memoFirstUnreadIdRef?: { current: number | undefined }; + onPinnedIntersectionChange?: PinnedIntersectionChangedCallback; }; type StateProps = { @@ -84,6 +86,7 @@ const ActionMessage: FC = ({ observeIntersectionForReading, observeIntersectionForLoading, observeIntersectionForPlaying, + onPinnedIntersectionChange, }) => { const { openPremiumModal, requestConfetti } = getActions(); @@ -96,6 +99,14 @@ const ActionMessage: FC = ({ useEnsureMessage(message.chatId, message.replyToMessageId, targetMessage); useFocusMessage(ref, message.chatId, isFocused, focusDirection, noFocusHighlight); + useEffect(() => { + if (!message.isPinned) return undefined; + + return () => { + onPinnedIntersectionChange?.({ viewportPinnedIdsToRemove: [message.id], isUnmount: true }); + }; + }, [onPinnedIntersectionChange, message.isPinned, message.id]); + const noAppearanceAnimation = appearanceOrder <= 0; const [isShown, markShown] = useFlag(noAppearanceAnimation); const isGift = Boolean(message.content.action?.text.startsWith('ActionGift')); @@ -209,6 +220,7 @@ const ActionMessage: FC = ({ id={getMessageHtmlId(message.id)} className={className} data-message-id={message.id} + data-is-pinned={message.isPinned || undefined} onMouseDown={handleMouseDown} onContextMenu={handleContextMenu} > diff --git a/src/components/middle/HeaderPinnedMessage.module.scss b/src/components/middle/HeaderPinnedMessage.module.scss new file mode 100644 index 000000000..8d4533b05 --- /dev/null +++ b/src/components/middle/HeaderPinnedMessage.module.scss @@ -0,0 +1,269 @@ +@import "../../styles/mixins"; + +.root { + display: flex; + align-items: center; + margin-left: auto; + cursor: default; + flex-direction: row-reverse; + background: var(--color-background); + + :global { + .Button { + margin-left: 0.25rem; + + &.tiny { + margin-right: 0.625rem; + } + } + } + + :global(body.animation-level-1) & { + :global(.ripple-container) { + display: none; + } + } + + :global(body.animation-level-0) & { + transition: none !important; + } + + @media (min-width: 1276px) { + transform: translate3d(0, 0, 0); + transition: opacity 0.15s ease, transform var(--layer-transition); + + :global(#Main.right-column-open) & { + transform: translate3d(calc(var(--right-column-width) * -1), 0, 0); + } + } + + > :global(.Button) { + flex-shrink: 0; + } +} + +.root:global(.full-width) { + position: absolute; + left: 0; + right: 0; + top: 100%; + background: var(--color-background); + padding: 0.25rem 0.8125rem 0.25rem 1rem; + box-shadow: 0 0.125rem 0.125rem var(--color-light-shadow); + transform: translate3d(0, 0, 0); + transition: opacity 0.15s ease, transform var(--layer-transition); + + &::before { + content: ""; + display: block; + position: absolute; + top: -0.1875rem; + left: 0; + right: 0; + height: 0.125rem; + box-shadow: 0 0.125rem 0.125rem var(--color-light-shadow); + } + + .pinnedMessage { + margin-top: 0; + margin-bottom: 0; + flex: 1; + } + + .messageText { + max-width: none; + } + + @media (min-width: 1276px) { + transform: translate3d(0, 0, 0); + transition: opacity 0.15s ease, transform var(--layer-transition); + + :global(#Main.right-column-open) & { + padding-left: calc(var(--right-column-width) + 1rem); + } + } +} + +.loading { + --spinner-size: 1.5rem; +} + +.pinListIcon { + position: absolute; + transition: 0.25s ease-in-out opacity, 0.25s ease-in-out transform; +} + +.pinListIconHidden { + opacity: 0; + transform: scale(0.6); +} + +.pinnedMessage { + display: flex; + flex-shrink: 1; + margin-top: -0.25rem; + margin-bottom: -0.25rem; + padding: 0.25rem; + padding-left: 0.375rem; + border-radius: var(--border-radius-messages-small); + position: relative; + overflow: hidden; + cursor: pointer; + align-items: center; + + &:hover:not(.no-hover) { + background-color: var(--color-interactive-element-hover); + } +} + + +.messageTextTransition { + height: 1.125rem; + width: 100%; + overflow: hidden; +} + +.messageText { + overflow: hidden; + margin-inline-start: 0.375rem; + margin-top: 0.125rem; + max-width: 15rem; + min-width: 15rem; + flex-grow: 1; + + transition: 0.25s ease-in-out transform; + + &.withMedia { + transform: translateX(2.625rem); + margin-right: 2.625rem; + max-width: calc(15rem - 2.625rem); + min-width: calc(15rem - 2.625rem); + } + + :global(.emoji-small) { + width: 1rem; + height: 1rem; + } + + @media (min-width: 1440px) and (max-width: 1500px) { + max-width: 14rem; + } +} + +.title { + font-weight: 500; + font-size: 0.875rem; + line-height: 1rem; + height: 1rem; + color: var(--color-primary); + margin-bottom: 0.125rem; + white-space: pre; + text-align: initial; + + :global(body.is-ios) & { + font-size: 0.9375rem; + } +} + +.summary { + font-size: 0.875rem; + line-height: 1.125rem; + height: 1.125rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin: 0; + + :global(body.is-ios) & { + font-size: 0.9375rem; + } +} + +.inlineButton { + display: block; + width: auto; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + border-radius: 1.5rem; + padding: 0 0.75rem; + font-weight: 500; + text-transform: none; + height: 2rem; + max-width: 10rem; + flex-shrink: 1; +} + +.pictogramTransition { + position: absolute; + width: 2.25rem !important; + height: 2.25rem; + margin-inline-start: 0.5rem; + margin-top: 0.125rem; + overflow: hidden; +} + +.pinnedThumb { + width: 100%; + height: 100%; + + flex-shrink: 0; + + border-radius: 0.25rem; + overflow: hidden; + + & + .messageText { + max-width: 12rem; + } +} + +.pinnedThumbImage { + width: 100%; + height: 100%; + object-fit: cover; +} + +@media (max-width: 600px) { + .pinnedMessage { + flex-grow: 1; + padding-top: 0; + padding-bottom: 0; + max-width: unset; + margin-top: -0.1875rem; + + &::before { + top: 0.125rem; + bottom: 0.125rem; + } + + .messageText { + max-width: none; + } + } + + .root:global(.full-width) { + display: none; + } + + .root { + @include header-mobile(); + } +} + +@media (min-width: 1276px) and (max-width: 1439px) { + :global(:not(.tools-stacked)) .root { + opacity: 1; + + :global(#Main.right-column-open) & { + opacity: 0; + } + } +} + +:global(.tools-stacked.animated) .root { + animation: fade-in var(--layer-transition) forwards; + + :global(body.animation-level-0) & { + animation: none; + } +} diff --git a/src/components/middle/HeaderPinnedMessage.tsx b/src/components/middle/HeaderPinnedMessage.tsx index b187c4ef9..736f228b7 100644 --- a/src/components/middle/HeaderPinnedMessage.tsx +++ b/src/components/middle/HeaderPinnedMessage.tsx @@ -17,6 +17,7 @@ import useMedia from '../../hooks/useMedia'; import useThumbnail from '../../hooks/useThumbnail'; import useFlag from '../../hooks/useFlag'; import useLang from '../../hooks/useLang'; +import useAsyncRendering from '../right/hooks/useAsyncRendering'; import RippleEffect from '../ui/RippleEffect'; import ConfirmDialog from '../ui/ConfirmDialog'; @@ -24,7 +25,13 @@ import Button from '../ui/Button'; import PinnedMessageNavigation from './PinnedMessageNavigation'; import MessageSummary from '../common/MessageSummary'; import MediaSpoiler from '../common/MediaSpoiler'; +import AnimatedCounter from '../common/AnimatedCounter'; +import Transition from '../ui/Transition'; +import Spinner from '../ui/Spinner'; +import styles from './HeaderPinnedMessage.module.scss'; + +const SHOW_LOADER_DELAY = 450; type OwnProps = { message: ApiMessage; index: number; @@ -34,17 +41,22 @@ type OwnProps = { onUnpinMessage?: (id: number) => void; onClick?: () => void; onAllPinnedClick?: () => void; + isLoading?: boolean; + isFullWidth?: boolean; }; const HeaderPinnedMessage: FC = ({ message, count, index, customTitle, className, onUnpinMessage, onClick, onAllPinnedClick, + isLoading, isFullWidth, }) => { const { clickBotInlineButton } = getActions(); const lang = useLang(); + const mediaThumbnail = useThumbnail(message); const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram')); - const isSpoiler = getMessageIsSpoiler(message); + const canRenderLoader = useAsyncRendering([isLoading], SHOW_LOADER_DELAY); + const shouldShowLoader = canRenderLoader && isLoading; const [isUnpinDialogOpen, openUnpinDialog, closeUnpinDialog] = useFlag(); @@ -66,18 +78,44 @@ const HeaderPinnedMessage: FC = ({ const [noHoverColor, markNoHoverColor, unmarkNoHoverColor] = useFlag(); + function renderPictogram(thumbDataUri?: string, blobUrl?: string, spoiler?: boolean) { + const { width, height } = getPictogramDimensions(); + const srcUrl = blobUrl || thumbDataUri; + + return ( +
+ {thumbDataUri && !spoiler + && } + {thumbDataUri + && } +
+ ); + } + return ( -
- {count > 1 && ( +
+ {(count > 1 || shouldShowLoader) && ( )} {onUnpinMessage && ( @@ -86,7 +124,6 @@ const HeaderPinnedMessage: FC = ({ size="smaller" color="translucent" ariaLabel={lang('UnpinMessageAlertTitle')} - className="unpin-button" onClick={openUnpinDialog} > @@ -100,7 +137,7 @@ const HeaderPinnedMessage: FC = ({ confirmHandler={handleUnpinMessage} />
@@ -108,20 +145,32 @@ const HeaderPinnedMessage: FC = ({ count={count} index={index} /> - {mediaThumbnail && renderPictogram(mediaThumbnail, mediaBlobUrl, isSpoiler)} -
-
- {customTitle ? renderText(customTitle) : `${lang('PinnedMessage')} ${index > 0 ? `#${count - index}` : ''}`} + + {renderPictogram( + mediaThumbnail, + mediaBlobUrl, + isSpoiler, + )} + +
+
+ {!customTitle && ( + 0 ? `#${count - index}` : ''}`} /> + )} + + {customTitle && renderText(customTitle)}
-

- -

- + +

+ +

+
+ {inlineButton && (