From 6fc1974145ed1418c445980749e1fed6427b4d3d Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 22 Dec 2025 22:53:29 +0100 Subject: [PATCH] Table About Modal: Redesign (#6523) --- src/assets/font-icons/closed-gift.svg | 2 +- src/assets/font-icons/frozen-time.svg | 2 +- src/assets/font-icons/hand-stop.svg | 2 +- src/assets/font-icons/lock.svg | 2 +- src/assets/font-icons/stars-refund.svg | 2 +- src/assets/font-icons/stealth-future.svg | 2 +- src/assets/font-icons/stealth-past.svg | 2 +- src/assets/font-icons/user-stars.svg | 2 +- src/assets/localization/fallback.strings | 1 + src/components/App.tsx | 11 +- src/components/common/CalendarModal.scss | 6 +- src/components/common/CalendarModal.tsx | 8 +- .../common/CountryPickerModal.module.scss | 3 +- src/components/common/CountryPickerModal.tsx | 8 +- .../PrivacySettingsNoticeModal.module.scss | 4 +- .../common/PrivacySettingsNoticeModal.tsx | 2 +- src/components/common/StickerSetModal.tsx | 2 +- .../common/pickers/ChatOrUserPicker.tsx | 4 +- .../common/pickers/PickerModal.module.scss | 5 +- src/components/common/pickers/PickerModal.tsx | 17 ++- .../common/pickers/PickerStyles.module.scss | 1 + .../profile/RadialPatternBackground.tsx | 14 ++- .../left/settings/SettingsActiveSession.tsx | 9 +- .../left/settings/SettingsActiveWebsite.tsx | 9 +- src/components/main/premium/GiveawayModal.tsx | 10 +- .../premium/PremiumFeatureModal.module.scss | 5 +- .../main/premium/PremiumFeatureModal.tsx | 2 +- .../main/premium/PremiumMainModal.module.scss | 4 +- .../main/premium/PremiumMainModal.tsx | 10 +- .../middle/ContactGreeting.module.scss | 4 +- src/components/middle/MessageList.scss | 2 - src/components/middle/MiddleColumn.scss | 11 +- src/components/middle/MiddleColumn.tsx | 6 +- src/components/middle/NoMessages.scss | 2 +- src/components/middle/ReactorListModal.scss | 22 ++-- src/components/middle/ReactorListModal.tsx | 17 ++- .../RequirementToContactMessage.module.scss | 6 +- .../middle/composer/AttachmentModal.tsx | 4 +- src/components/middle/composer/PollModal.tsx | 2 +- .../middle/composer/ToDoListModal.tsx | 4 +- .../middle/message/ActionMessage.tsx | 11 +- .../middle/message/InlineButtons.scss | 4 +- src/components/middle/message/Message.scss | 4 +- src/components/middle/message/Message.tsx | 2 - .../middle/message/MessageMeta.scss | 2 +- src/components/middle/message/RoundVideo.scss | 4 +- .../middle/message/SponsoredMessage.tsx | 2 - .../middle/message/_message-content.scss | 2 +- .../collectible/CollectibleInfoModal.tsx | 10 +- .../modals/common/TableAboutModal.module.scss | 61 +++++++++-- .../modals/common/TableAboutModal.tsx | 4 +- .../modals/common/TableInfoModal.module.scss | 2 +- .../FrozenAccountModal.module.scss | 8 +- .../frozenAccount/FrozenAccountModal.tsx | 7 +- .../modals/gift/GiftItemPremium.tsx | 2 +- .../modals/gift/GiftModal.module.scss | 13 ++- src/components/modals/gift/GiftModal.tsx | 28 ++++- .../gift/StarGiftCategoryList.module.scss | 11 +- .../modals/gift/StarGiftCategoryList.tsx | 16 ++- .../modals/gift/UniqueGiftHeader.module.scss | 25 +++-- .../modals/gift/UniqueGiftHeader.tsx | 13 ++- .../gift/UniqueGiftManageButtons.module.scss | 2 +- .../gift/info/GiftInfoModal.module.scss | 49 +++++++-- .../modals/gift/info/GiftInfoModal.tsx | 101 ++++++++---------- .../status/GiftStatusInfoModal.module.scss | 4 +- .../gift/status/GiftStatusInfoModal.tsx | 14 ++- .../ProfileRatingModal.module.scss | 36 +------ .../profileRating/ProfileRatingModal.tsx | 6 +- .../QuickPreviewModalHeader.module.scss | 4 +- .../quickPreview/QuickPreviewModalHeader.tsx | 2 +- .../modals/reportAd/ReportAdModal.tsx | 2 +- .../modals/reportModal/ReportModal.tsx | 4 +- .../stars/StarsBalanceModal.module.scss | 17 +-- .../modals/stars/StarsBalanceModal.tsx | 47 +++++--- .../stars/gift/StarsGiftModal.module.scss | 4 +- .../modals/stars/gift/StarsGiftModal.tsx | 11 +- .../modals/webApp/WebAppModal.module.scss | 2 +- src/components/story/StorySettings.tsx | 2 +- src/components/story/StoryViewer.tsx | 2 +- src/components/ui/Button.scss | 16 +-- src/components/ui/Modal.scss | 9 +- src/components/ui/Modal.tsx | 2 +- src/components/ui/TabList.tsx | 9 +- src/config.ts | 2 +- src/global/selectors/ui.ts | 5 + src/hooks/useScrollNotch.ts | 33 +++++- src/styles/_variables.scss | 4 +- src/styles/icons.css | 4 +- src/styles/icons.woff | Bin 38840 -> 38924 bytes src/styles/icons.woff2 | Bin 32396 -> 32428 bytes src/styles/index.scss | 9 ++ src/types/language.d.ts | 3 + src/util/colors.ts | 5 +- 93 files changed, 519 insertions(+), 353 deletions(-) diff --git a/src/assets/font-icons/closed-gift.svg b/src/assets/font-icons/closed-gift.svg index 2fefc3363..bd36be106 100644 --- a/src/assets/font-icons/closed-gift.svg +++ b/src/assets/font-icons/closed-gift.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/frozen-time.svg b/src/assets/font-icons/frozen-time.svg index 15a7c2b13..8f3eebc57 100644 --- a/src/assets/font-icons/frozen-time.svg +++ b/src/assets/font-icons/frozen-time.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/hand-stop.svg b/src/assets/font-icons/hand-stop.svg index 540546b9f..478e9198d 100644 --- a/src/assets/font-icons/hand-stop.svg +++ b/src/assets/font-icons/hand-stop.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/lock.svg b/src/assets/font-icons/lock.svg index ba83cc0a5..9a23a397c 100644 --- a/src/assets/font-icons/lock.svg +++ b/src/assets/font-icons/lock.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/stars-refund.svg b/src/assets/font-icons/stars-refund.svg index fc5ab8be0..4e3fb9d27 100644 --- a/src/assets/font-icons/stars-refund.svg +++ b/src/assets/font-icons/stars-refund.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/stealth-future.svg b/src/assets/font-icons/stealth-future.svg index 7f66ceae4..5b7b0fd35 100644 --- a/src/assets/font-icons/stealth-future.svg +++ b/src/assets/font-icons/stealth-future.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/stealth-past.svg b/src/assets/font-icons/stealth-past.svg index 4df90dfb3..e2d9cad54 100644 --- a/src/assets/font-icons/stealth-past.svg +++ b/src/assets/font-icons/stealth-past.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/font-icons/user-stars.svg b/src/assets/font-icons/user-stars.svg index 12e7ec236..08943452a 100644 --- a/src/assets/font-icons/user-stars.svg +++ b/src/assets/font-icons/user-stars.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings index d39dbb91e..b89002795 100644 --- a/src/assets/localization/fallback.strings +++ b/src/assets/localization/fallback.strings @@ -2108,6 +2108,7 @@ "StarGiftPurchaseTransaction" = "Gift Sale"; "GiftBuyConfirmDescription" = "Do you want to buy **{gift}** for **{stars}**?"; "GiftBuyForPeerConfirmDescription" = "Do you want to buy **{gift}** for **{stars}** and gift it to **{peer}**?"; +"GiftBuyEqualsTo" = "Equals to {stars}"; "ComposerTitleForwardFrom" = "From: **{users}**"; "ContextMenuItemMention" = "Mention"; "GiftRibbonResale" = "resale"; diff --git a/src/components/App.tsx b/src/components/App.tsx index df3066990..f6275a85c 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -8,7 +8,7 @@ import type { UiLoaderPage } from './common/UiLoader'; import { DARK_THEME_BG_COLOR, INACTIVE_MARKER, LIGHT_THEME_BG_COLOR, PAGE_TITLE, PAGE_TITLE_TAURI } from '../config'; import { forceMutation } from '../lib/fasterdom/stricterdom.ts'; -import { selectTabState, selectTheme } from '../global/selectors'; +import { selectActionMessageBg, selectTabState, selectTheme } from '../global/selectors'; import { IS_TAURI } from '../util/browser/globalEnvironment'; import { IS_INSTALL_PROMPT_SUPPORTED, PLATFORM_ENV } from '../util/browser/windowEnvironment'; import buildClassName from '../util/buildClassName'; @@ -43,6 +43,7 @@ type StateProps = { hasWebAuthTokenFailed?: boolean; isTestServer?: boolean; theme: ThemeKey; + actionMessageBg?: string; }; enum AppScreens { @@ -64,6 +65,7 @@ const App: FC = ({ hasWebAuthTokenFailed, isTestServer, theme, + actionMessageBg, }) => { const { isMobile } = useAppLayout(); const isMobileOs = PLATFORM_ENV === 'iOS' || PLATFORM_ENV === 'Android'; @@ -226,6 +228,12 @@ const App: FC = ({ ); }, [theme]); + useLayoutEffect(() => { + if (actionMessageBg) { + document.body.style.setProperty('--action-message-bg', actionMessageBg); + } + }, [actionMessageBg]); + const getIsInBackgroundLocal = getIsInBackground; useSignalEffect(() => { // Mutation forced to avoid RAF throttling in background @@ -263,6 +271,7 @@ export default withGlobal( hasWebAuthTokenFailed: global.hasWebAuthTokenFailed || global.hasWebAuthTokenPasswordRequired, theme: selectTheme(global), isTestServer: global.config?.isTestServer, + actionMessageBg: selectActionMessageBg(global), }; }, )(App); diff --git a/src/components/common/CalendarModal.scss b/src/components/common/CalendarModal.scss index 7f9725fe9..57df4ef90 100644 --- a/src/components/common/CalendarModal.scss +++ b/src/components/common/CalendarModal.scss @@ -70,13 +70,17 @@ } } + .container { + margin-top: 0.1875rem; + } + .month-selector { display: flex; align-items: center; h4 { flex: 1; - margin: 0 0 0 1.25rem; + margin: 0 0 0 2.25rem; font-size: 1.25rem; & ~ .Button { diff --git a/src/components/common/CalendarModal.tsx b/src/components/common/CalendarModal.tsx index f8d202895..2f7affb3a 100644 --- a/src/components/common/CalendarModal.tsx +++ b/src/components/common/CalendarModal.tsx @@ -370,16 +370,10 @@ const CalendarModal: FC = ({ className="CalendarModal" onEnter={handleSubmit} dialogRef={dialogRef} + hasAbsoluteCloseButton >
-
diff --git a/src/components/left/settings/SettingsActiveSession.tsx b/src/components/left/settings/SettingsActiveSession.tsx index 7104e83ad..5173f7ebc 100644 --- a/src/components/left/settings/SettingsActiveSession.tsx +++ b/src/components/left/settings/SettingsActiveSession.tsx @@ -62,7 +62,14 @@ const SettingsActiveSession: FC = ({ function renderHeader() { return (
-
@@ -123,7 +123,6 @@ const FrozenAccountModal = ({ header={header} listItemData={listItemData} footer={footer} - hasBackdrop onClose={handleClose} /> ); diff --git a/src/components/modals/gift/GiftItemPremium.tsx b/src/components/modals/gift/GiftItemPremium.tsx index e4550a8eb..dd0fee7de 100644 --- a/src/components/modals/gift/GiftItemPremium.tsx +++ b/src/components/modals/gift/GiftItemPremium.tsx @@ -83,7 +83,7 @@ function GiftItemPremium({
{lang('PremiumGiftDescription')}
- {optionByStars && ( diff --git a/src/components/modals/gift/GiftModal.module.scss b/src/components/modals/gift/GiftModal.module.scss index 73c2b75c7..04e19d692 100644 --- a/src/components/modals/gift/GiftModal.module.scss +++ b/src/components/modals/gift/GiftModal.module.scss @@ -119,7 +119,11 @@ background: var(--color-background); /* stylelint-disable-next-line plugin/no-low-performance-animation-properties */ - transition: height 0.25s ease-out, transform 0.25s ease-out; + transition: height 0.25s ease-out, transform 0.25s ease-out, border-color 0.2s ease; + + &.noBorder { + border-bottom-color: transparent; + } } .resaleHeader { @@ -174,8 +178,8 @@ .closeButton { position: absolute; z-index: 3; - top: 0.375rem; - left: 0.375rem; + top: 0.875rem; + left: 0.875rem; } .balance { @@ -209,9 +213,12 @@ } .logoBackground { + pointer-events: none; + position: absolute; left: 50%; transform: translateX(-50%); + height: 7rem; } diff --git a/src/components/modals/gift/GiftModal.tsx b/src/components/modals/gift/GiftModal.tsx index 80f16c52b..53c83af3b 100644 --- a/src/components/modals/gift/GiftModal.tsx +++ b/src/components/modals/gift/GiftModal.tsx @@ -1,7 +1,7 @@ import type { FC } from '@teact'; import { - memo, useEffect, useMemo, useRef, useState, -} from '@teact'; + memo, useEffect, + useMemo, useRef, useState } from '@teact'; import type React from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; @@ -24,8 +24,10 @@ import { selectTabState } from '../../../global/selectors'; import { selectPeer, selectUserFullInfo } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { throttle } from '../../../util/schedulers'; +import { REM } from '../../common/helpers/mediaDimensions'; import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev'; +import useFlag from '../../../hooks/useFlag'; import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; import useLang from '../../../hooks/useLang'; import useLastCallback from '../../../hooks/useLastCallback'; @@ -74,6 +76,7 @@ const AVATAR_SIZE = 100; const INTERSECTION_THROTTLE = 200; const SCROLL_THROTTLE = 200; const AVATAR_SPARKLES_CENTER_SHIFT = [0, -50] as const; +const CATEGORY_LIST_STICKY_TOP = 3.5 * REM; const runThrottledForScroll = throttle((cb) => cb(), SCROLL_THROTTLE, true); @@ -105,6 +108,7 @@ const GiftModal: FC = ({ const dialogRef = useRef(); const transitionRef = useRef(); const giftHeaderRef = useRef(); + const categoryListRef = useRef(); const scrollerRef = useRef(); @@ -118,8 +122,8 @@ const GiftModal: FC = ({ const [shouldShowMainScreenHeader, setShouldShowMainScreenHeader] = useState(false); const [isMainScreenHeaderForStarGifts, setIsMainScreenHeaderForStarGifts] = useState(false); const [isGiftScreenHeaderForStarGifts, setIsGiftScreenHeaderForStarGifts] = useState(false); - const [selectedCategory, setSelectedCategory] = useState('all'); + const [isCategoryListPinned, pinCategoryList, unpinCategoryList] = useFlag(false); const triggerSparklesRef = useRef<(() => void) | undefined>(); const areAllGiftsDisallowed = useMemo(() => { @@ -207,6 +211,17 @@ const GiftModal: FC = ({ const { top: transitionTop } = transitionRef.current.getBoundingClientRect(); setIsMainScreenHeaderForStarGifts(headerTop - transitionTop <= 0); } + + if (categoryListRef.current && scrollerRef.current) { + const { top: listTop } = categoryListRef.current.getBoundingClientRect(); + const { top: scrollerTop } = scrollerRef.current.getBoundingClientRect(); + const isPinned = listTop - scrollerTop <= CATEGORY_LIST_STICKY_TOP; + if (isPinned) { + pinCategoryList(); + } else { + unpinCategoryList(); + } + } }); }); @@ -463,10 +478,12 @@ const GiftModal: FC = ({ {renderStarGiftsHeader()} {renderStarGiftsDescription()} = ({ className={styles.closeButton} round color="translucent" - size="smaller" + size="tiny" onClick={handleCloseButtonClick} ariaLabel={isBackButton ? oldLang('Common.Back') : oldLang('Common.Close')} > @@ -547,7 +564,8 @@ const GiftModal: FC = ({
; areUniqueStarGiftsDisallowed?: boolean; areLimitedStarGiftsDisallowed?: boolean; isSelf?: boolean; hasMyUnique?: boolean; + isPinned?: boolean; onCategoryChanged: (category: StarGiftCategory) => void; }; @@ -25,14 +28,19 @@ type StateProps = { }; const StarGiftCategoryList = ({ + ref: externalRef, idsByCategory, onCategoryChanged, areUniqueStarGiftsDisallowed, areLimitedStarGiftsDisallowed, isSelf, hasMyUnique, + isPinned, }: StateProps & OwnProps) => { - const ref = useRef(); + let ref = useRef(); + if (externalRef) { + ref = externalRef; + } const lang = useLang(); @@ -42,9 +50,7 @@ const StarGiftCategoryList = ({ function handleItemClick(category: StarGiftCategory) { setSelectedCategory(category); - onCategoryChanged( - category, - ); + onCategoryChanged(category); } function renderCategoryName(category: StarGiftCategory) { @@ -71,7 +77,7 @@ const StarGiftCategoryList = ({ useHorizontalScroll(ref, undefined, true); return ( -
+
{renderCategoryItem('all')} {!areUniqueStarGiftsDisallowed && !isSelf && hasMyUnique && renderCategoryItem('myUnique')} {(!areUniqueStarGiftsDisallowed || !areLimitedStarGiftsDisallowed) diff --git a/src/components/modals/gift/UniqueGiftHeader.module.scss b/src/components/modals/gift/UniqueGiftHeader.module.scss index 0d40fd2a0..5e93e11f4 100644 --- a/src/components/modals/gift/UniqueGiftHeader.module.scss +++ b/src/components/modals/gift/UniqueGiftHeader.module.scss @@ -12,15 +12,22 @@ padding-bottom: 1rem; &.withManageButtons { - --_height: 18.5rem; + --_height: 19.25rem; .sticker { - margin-top: 2.5rem; + margin-top: 2.625rem; + } + + :global { + canvas { + transform-origin: center 32%; + } } } :global { canvas { + transform-origin: center 45%; transition: 250ms transform; } } @@ -48,7 +55,7 @@ .radialPattern { position: absolute; z-index: -1; - inset: 0; + inset: -5%; } .amount { @@ -65,7 +72,7 @@ } .sticker { - margin-top: 2rem; + margin-top: 2.875rem; } .transition { @@ -83,14 +90,16 @@ .title { margin-top: auto; - font-size: 1.25rem; + + font-size: 1.5rem; + font-weight: var(--font-weight-semibold); + line-height: 1.75rem; color: white; } .subtitle { - max-width: 85%; - - font-size: 0.875rem; + font-size: 1rem; + line-height: 1.375rem; text-align: center; text-wrap: balance; diff --git a/src/components/modals/gift/UniqueGiftHeader.tsx b/src/components/modals/gift/UniqueGiftHeader.tsx index 80b2974dd..298aafd65 100644 --- a/src/components/modals/gift/UniqueGiftHeader.tsx +++ b/src/components/modals/gift/UniqueGiftHeader.tsx @@ -17,6 +17,7 @@ import buildStyle from '../../../util/buildStyle'; import { REM } from '../../common/helpers/mediaDimensions.ts'; import { useTransitionActiveKey } from '../../../hooks/animations/useTransitionActiveKey'; +import useAppLayout from '../../../hooks/useAppLayout'; import useFlag from '../../../hooks/useFlag'; import useLang from '../../../hooks/useLang'; @@ -60,6 +61,8 @@ const UniqueGiftHeader = ({ openChat, } = getActions(); + const { isMobile } = useAppLayout(); + const lang = useLang(); const [isGiftHover, markGiftHover, unmarkGiftHover] = useFlag(false); const activeKey = useTransitionActiveKey([modelAttribute, backdropAttribute, patternAttribute]); @@ -71,16 +74,20 @@ const UniqueGiftHeader = ({ return ( ); - }, [backdropAttribute, patternAttribute]); + }, [backdropAttribute, patternAttribute, isMobile]); return (
diff --git a/src/components/modals/gift/UniqueGiftManageButtons.module.scss b/src/components/modals/gift/UniqueGiftManageButtons.module.scss index a8eee242f..71781b4a9 100644 --- a/src/components/modals/gift/UniqueGiftManageButtons.module.scss +++ b/src/components/modals/gift/UniqueGiftManageButtons.module.scss @@ -5,7 +5,7 @@ gap: 0.5rem; width: 100%; - margin-top: 1rem; + margin-top: 0.375rem; } .manageButton { diff --git a/src/components/modals/gift/info/GiftInfoModal.module.scss b/src/components/modals/gift/info/GiftInfoModal.module.scss index 7e96cb047..86ed1a108 100644 --- a/src/components/modals/gift/info/GiftInfoModal.module.scss +++ b/src/components/modals/gift/info/GiftInfoModal.module.scss @@ -63,31 +63,44 @@ backdrop-filter: blur(0.5rem); } -.headerButton, +.moreMenuButton { + position: absolute; + z-index: 1; + top: 0.875rem; + right: 0.875rem; +} + +.closeButton { + position: absolute; + z-index: 1; + top: 0.875rem; + left: 0.875rem; +} + .giftResalePriceContainer { pointer-events: auto; + position: absolute; + top: 0.875rem; + right: 3.25rem; + display: flex; align-items: center; justify-content: center; width: fit-content; - height: 1.75rem; + height: 1.875rem; padding: 0.25rem; padding-inline: 0.625rem; border-radius: 1rem; - font-size: 1rem; + font-size: 0.875rem; font-weight: var(--font-weight-medium); color: white; - background-color: rgba(0, 0, 0, 0.2); - outline: none !important; -} - -.giftResalePriceContainer { - font-size: 0.75rem; + background-color: rgba(255, 255, 255, 0.1); backdrop-filter: blur(25px); + outline: none !important; } .starAmountIcon, @@ -137,6 +150,24 @@ text-align: center; } +.footerHint { + display: flex; + align-items: center; + + font-size: 0.75rem; + line-height: 1.125rem; + color: var(--color-white); + text-align: center; + text-transform: none; + + opacity: 0.6; +} + +.buyButton { + display: flex; + flex-direction: column; +} + .unknown { margin-inline-start: 0.25rem; } diff --git a/src/components/modals/gift/info/GiftInfoModal.tsx b/src/components/modals/gift/info/GiftInfoModal.tsx index c2742f4db..019cca15a 100644 --- a/src/components/modals/gift/info/GiftInfoModal.tsx +++ b/src/components/modals/gift/info/GiftInfoModal.tsx @@ -108,7 +108,7 @@ const GiftInfoModal = ({ const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false); const [shouldPayInTon, setShouldPayInTon] = useState(false); - const splitButtonRef = useRef(); + const moreButtonRef = useRef(); const menuRef = useRef(); const uniqueGiftHeaderRef = useRef(); const { @@ -117,7 +117,7 @@ const GiftInfoModal = ({ handleContextMenu, handleContextMenuClose, handleContextMenuHide, - } = useContextMenuHandlers(splitButtonRef); + } = useContextMenuHandlers(moreButtonRef); const handleSymbolClick = useLastCallback(() => { if (!gift || !giftAttributes?.pattern) return; @@ -245,6 +245,9 @@ const GiftInfoModal = ({ const resellPrice = getResalePrice(); const confirmPrice = getResalePrice(shouldPayInTon); + const resellPriceInStars = resellPrice?.currency === TON_CURRENCY_CODE && isGiftUnique + ? gift.resellPrice?.find((amount) => amount.currency === STARS_CURRENCY_CODE) + : undefined; const canBuyGift = !isSelfUnique && gift?.type === 'starGiftUnique' && gift.ownerId !== currentUserId && Boolean(resellPrice); @@ -330,37 +333,24 @@ const GiftInfoModal = ({ return gift && getGiftAttributes(gift); }, [gift]); - const SettingsMenuButton = useMemo(() => { - return ( -
- -
- ); - }, [lang, handleContextMenu]); - const renderFooterButton = useLastCallback(() => { if (canBuyGift) { return ( - ); } @@ -536,6 +526,30 @@ const GiftInfoModal = ({
+ +
); @@ -883,13 +875,14 @@ const GiftInfoModal = ({ typeGift, savedGift, renderingTargetPeer, giftSticker, lang, canManage, hasConvertOption, isSender, oldLang, tonExplorerUrl, gift, giftAttributes, renderFooterButton, isTargetChat, - SettingsMenuButton, isGiftUnique, saleDateInfo, + isGiftUnique, saleDateInfo, canBuyGift, giftOwnerTitle, resellPrice, giftSubtitle, releasedByPeer, handleSymbolClick, handleBackdropClick, handleModelClick, + handleContextMenu, ]); const getRootElement = useLastCallback(() => uniqueGiftHeaderRef.current); - const getTriggerElement = useLastCallback(() => splitButtonRef.current); + const getTriggerElement = useLastCallback(() => moreButtonRef.current); const getMenuElement = useLastCallback(() => menuRef.current); const getLayout = useLastCallback(() => ({ withPortal: true })); diff --git a/src/components/modals/gift/status/GiftStatusInfoModal.module.scss b/src/components/modals/gift/status/GiftStatusInfoModal.module.scss index 29947073e..0bcd97599 100644 --- a/src/components/modals/gift/status/GiftStatusInfoModal.module.scss +++ b/src/components/modals/gift/status/GiftStatusInfoModal.module.scss @@ -28,7 +28,7 @@ } .avatar { - margin-top: 2rem; + margin-top: 2.375rem; } .userTitle { @@ -36,7 +36,7 @@ width: 100%; margin-top: auto; - padding-top: 1rem; + padding-top: 1.75rem; font-size: 1.25rem; color: white; diff --git a/src/components/modals/gift/status/GiftStatusInfoModal.tsx b/src/components/modals/gift/status/GiftStatusInfoModal.tsx index d70fd65dd..50feff433 100644 --- a/src/components/modals/gift/status/GiftStatusInfoModal.tsx +++ b/src/components/modals/gift/status/GiftStatusInfoModal.tsx @@ -11,6 +11,7 @@ import buildClassName from '../../../../util/buildClassName'; import buildStyle from '../../../../util/buildStyle'; import { REM } from '../../../common/helpers/mediaDimensions'; +import useAppLayout from '../../../../hooks/useAppLayout'; import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev'; import useLang from '../../../../hooks/useLang'; import useLastCallback from '../../../../hooks/useLastCallback'; @@ -34,6 +35,8 @@ type StateProps = { isCurrentUserPremium?: boolean; }; +const AVATAR_SIZE = 7 * REM; + const GiftStatusInfoModal = ({ modal, currentUser, @@ -44,6 +47,8 @@ const GiftStatusInfoModal = ({ setEmojiStatus, } = getActions(); const lang = useLang(); + const { isMobile } = useAppLayout(); + const isOpen = Boolean(modal); const renderingModal = useCurrentOrPrev(modal); @@ -74,10 +79,13 @@ const GiftStatusInfoModal = ({ className={styles.radialPattern} backgroundColors={backdropColors} patternIcon={patternIcon.customEmoji} - yPosition={6.5 * REM} + yPosition={6.875 * REM} + maxRadius={0.31} + patternSize={isMobile ? 13 : 15} + ovalFactor={1} /> ); - }, [emojiStatus, isOpen, patternIcon]); + }, [emojiStatus, isOpen, isMobile, patternIcon]); const mockPeerWithStatus = useMemo(() => { return { @@ -95,7 +103,7 @@ const GiftStatusInfoModal = ({ > {radialPatternBackdrop} - + + {renderBadge('added')} {lang('RatingGiftsFromTelegramDesc')} )], ['user-stars', lang('RatingGiftsAndPostsFromUsers'), ( - + {renderBadge('added')} {lang('RatingGiftsAndPostsFromUsersDesc')} )], ['stars-refund', lang('RatingRefundsAndConversions'), ( - + {renderBadge('deducted')} {lang('RatingRefundsAndConversionsDesc')} diff --git a/src/components/modals/quickPreview/QuickPreviewModalHeader.module.scss b/src/components/modals/quickPreview/QuickPreviewModalHeader.module.scss index d03656d6d..f445bdeb4 100644 --- a/src/components/modals/quickPreview/QuickPreviewModalHeader.module.scss +++ b/src/components/modals/quickPreview/QuickPreviewModalHeader.module.scss @@ -21,8 +21,8 @@ .closeButton { position: absolute !important; - top: 0.5rem; - right: 0.5rem; + top: 0.875rem; + right: 0.875rem; } .markAsReadButton { diff --git a/src/components/modals/quickPreview/QuickPreviewModalHeader.tsx b/src/components/modals/quickPreview/QuickPreviewModalHeader.tsx index a92f27542..81e6b4987 100644 --- a/src/components/modals/quickPreview/QuickPreviewModalHeader.tsx +++ b/src/components/modals/quickPreview/QuickPreviewModalHeader.tsx @@ -84,7 +84,7 @@ const QuickPreviewModalHeader: FC = ({ + + {currency === TON_CURRENCY_CODE && ( +
+ {lang('TonModalHint')} +
+ )} ); }; @@ -269,6 +281,17 @@ const StarsBalanceModal = ({ const { scrollTop } = e.currentTarget; setHeaderHidden(scrollTop <= 150); + + if (tabsRef.current) { + const { top: tabsTop } = tabsRef.current.getBoundingClientRect(); + const { top: scrollerTop } = e.currentTarget.getBoundingClientRect(); + const isPinned = tabsTop - scrollerTop <= HEADER_HEIGHT; + if (isPinned) { + pinTabs(); + } else { + unpinTabs(); + } + } } const handleLoadMoreTransactions = useLastCallback(() => { @@ -305,19 +328,15 @@ const StarsBalanceModal = ({ isOpen={isOpen} onClose={closeStarsBalanceModal} dialogStyle={`--modal-height: ${modalHeight}`} + hasAbsoluteCloseButton >
-