From baff4367094ca2415e947b46141d8511b2e4e381 Mon Sep 17 00:00:00 2001 From: zubiden <19638254+zubiden@users.noreply.github.com> Date: Sun, 22 Feb 2026 23:43:03 +0100 Subject: [PATCH] Translation: Add Cocoon info (#6646) --- src/@types/global.d.ts | 6 + src/assets/cocoon.webp | Bin 0 -> 47846 bytes src/assets/localization/fallback.strings | 17 +++ src/bundles/extra.ts | 1 + src/components/common/InteractiveSparkles.tsx | 8 ++ src/components/middle/HeaderActions.tsx | 66 ++++++++--- .../middle/message/_message-content.scss | 8 +- src/components/modals/ModalContainer.tsx | 5 +- .../modals/cocoon/CocoonModal.async.tsx | 14 +++ .../modals/cocoon/CocoonModal.module.scss | 26 +++++ src/components/modals/cocoon/CocoonModal.tsx | 108 ++++++++++++++++++ .../modals/common/ParticlesHeader.module.scss | 30 +++++ .../modals/common/ParticlesHeader.tsx | 23 +++- .../modals/common/SpeedingDiamond.tsx | 6 +- src/components/modals/common/SwayingStar.tsx | 4 +- .../modals/common/TableAboutModal.module.scss | 8 +- .../modals/common/TableAboutModal.tsx | 2 +- src/components/ui/Link.tsx | 7 +- src/components/ui/MenuItem.scss | 9 ++ src/components/ui/MenuItem.tsx | 1 + src/config.ts | 1 + src/global/actions/ui/misc.ts | 9 ++ src/global/types/actions.ts | 3 + src/global/types/tabState.ts | 2 + src/lib/gramjs/tl/apiTl.ts | 1 + src/lib/gramjs/tl/static/api.json | 1 + src/types/language.d.ts | 25 ++++ src/util/stopEvent.ts | 2 - webpack.config.ts | 2 +- 29 files changed, 352 insertions(+), 43 deletions(-) create mode 100644 src/assets/cocoon.webp create mode 100644 src/components/modals/cocoon/CocoonModal.async.tsx create mode 100644 src/components/modals/cocoon/CocoonModal.module.scss create mode 100644 src/components/modals/cocoon/CocoonModal.tsx diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 5dd1ab7a0..fa8a8af93 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -84,6 +84,12 @@ declare module '*.jpg' { const url: string; export default url; } + +declare module '*.webp' { + const url: string; + export default url; +} + declare module '*.svg' { const url: string; export default url; diff --git a/src/assets/cocoon.webp b/src/assets/cocoon.webp new file mode 100644 index 0000000000000000000000000000000000000000..100c20ade8a786a453eb9009c382757209224831 GIT binary patch literal 47846 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 af`<&}2Y+a;7Q@Mu* { const canvasRef = useRef(); + const lastBurstTimeRef = useRef(0); useLayoutEffect(() => { if (isDisabled) return undefined; @@ -41,6 +44,11 @@ const InteractiveSparkles = ({ const animate = () => { if (isDisabled) return; + const now = Date.now(); + if (now - lastBurstTimeRef.current < MIN_BURST_INTERVAL) return; + + lastBurstTimeRef.current = now; + setupParticles(canvasRef.current!, { color: PARTICLE_COLORS[`${color}Gradient`], centerShift, diff --git a/src/components/middle/HeaderActions.tsx b/src/components/middle/HeaderActions.tsx index bb5974842..6a27a3f6e 100644 --- a/src/components/middle/HeaderActions.tsx +++ b/src/components/middle/HeaderActions.tsx @@ -8,6 +8,7 @@ import type { IAnchorPosition, MessageListType, ThreadId } from '../../types'; import { MAIN_THREAD_ID } from '../../api/types'; import { ManagementScreens } from '../../types'; +import { COCOON_EMOJI_ID } from '../../config'; import { requestMeasure, requestNextMutation } from '../../lib/fasterdom/fasterdom'; import { getHasAdminRight, @@ -38,11 +39,14 @@ import { isUserId } from '../../util/entities/ids'; import focusNoScroll from '../../util/focusNoScroll'; import { useHotkeys } from '../../hooks/useHotkeys'; +import useLang from '../../hooks/useLang'; import useLastCallback from '../../hooks/useLastCallback'; import useOldLang from '../../hooks/useOldLang'; +import CustomEmoji from '../common/CustomEmoji'; import Button from '../ui/Button'; import DropdownMenu from '../ui/DropdownMenu'; +import Link from '../ui/Link'; import MenuItem from '../ui/MenuItem'; import MenuSeparator from '../ui/MenuSeparator'; import HeaderMenuContainer from './HeaderMenuContainer.async'; @@ -142,9 +146,12 @@ const HeaderActions: FC = ({ unblockUser, setViewForumAsMessages, openFrozenAccountModal, + openCocoonModal, } = getActions(); const menuButtonRef = useRef(); - const lang = useOldLang(); + const oldLang = useOldLang(); + const lang = useLang(); + const [isMenuOpen, setIsMenuOpen] = useState(false); const [menuAnchor, setMenuAnchor] = useState(undefined); @@ -166,7 +173,8 @@ const HeaderActions: FC = ({ joinChannel({ chatId }); if (shouldSendJoinRequest) { showNotification({ - message: isChannel ? lang('RequestToJoinChannelSentDescription') : lang('RequestToJoinGroupSentDescription'), + message: isChannel ? oldLang('RequestToJoinChannelSentDescription') + : oldLang('RequestToJoinGroupSentDescription'), }); } }); @@ -239,21 +247,21 @@ const HeaderActions: FC = ({ const getTextWithLanguage = useCallback((langKey: string, langCode: string) => { const simplified = langCode.split('-')[0]; const translationKey = `TranslateLanguage${simplified.toUpperCase()}`; - const name = lang(translationKey); + const name = oldLang(translationKey); if (name !== translationKey) { - return lang(langKey, name); + return oldLang(langKey, name); } const translatedNames = new Intl.DisplayNames([language], { type: 'language' }); const translatedName = translatedNames.of(langCode)!; - return lang(`${langKey}Other`, translatedName); - }, [language, lang]); + return oldLang(`${langKey}Other`, translatedName); + }, [language, oldLang]); const buttonText = useMemo(() => { - if (isTranslating) return lang('ShowOriginalButton'); + if (isTranslating) return oldLang('ShowOriginalButton'); return getTextWithLanguage('TranslateToButton', translationLanguage); - }, [translationLanguage, getTextWithLanguage, isTranslating, lang]); + }, [translationLanguage, getTextWithLanguage, isTranslating, oldLang]); const doNotTranslateText = useMemo(() => { if (!detectedChatLanguage) return undefined; @@ -270,6 +278,10 @@ const HeaderActions: FC = ({ openChatLanguageModal({ chatId }); }); + const handleCocoonClick = useLastCallback(() => { + openCocoonModal(); + }); + const handleDoNotTranslate = useLastCallback(() => { if (!detectedChatLanguage) return; @@ -294,11 +306,11 @@ const HeaderActions: FC = ({ size="smaller" className={isOpen ? 'active' : ''} onClick={onTrigger} - ariaLabel={lang('TranslateMessage')} + ariaLabel={oldLang('TranslateMessage')} iconName="language" /> ); - }, [isRightColumnShown, lang]); + }, [isRightColumnShown, oldLang]); return (
@@ -312,12 +324,28 @@ const HeaderActions: FC = ({ {buttonText} - {lang('Chat.Translate.Menu.To')} + {oldLang('Chat.Translate.Menu.To')} {detectedChatLanguage && {doNotTranslateText}} - {lang('Hide')} + {oldLang('Hide')} + + + {lang('TranslateMenuCocoon', { + link: ( + e.preventDefault()}> + {lang('TranslateMenuCocoonLinkText')} + + ), + }, { + withNodes: true, + withMarkdown: true, + specialReplacement: { + '🥚': , + }, + })} + )} {!isMobile && ( @@ -329,7 +357,7 @@ const HeaderActions: FC = ({ fluid onClick={handleSubscribeClick} > - {lang(isChannel ? 'ProfileJoinChannel' : 'ProfileJoinGroup')} + {oldLang(isChannel ? 'ProfileJoinChannel' : 'ProfileJoinGroup')} )} {canExpandActions && shouldSendJoinRequest && ( @@ -339,7 +367,7 @@ const HeaderActions: FC = ({ fluid onClick={handleSubscribeClick} > - {lang('ChannelJoinRequest')} + {oldLang('ChannelJoinRequest')} )} {canExpandActions && canStartBot && ( @@ -349,7 +377,7 @@ const HeaderActions: FC = ({ fluid onClick={handleStartBot} > - {lang('BotStart')} + {oldLang('BotStart')} )} {canExpandActions && canRestartBot && ( @@ -359,7 +387,7 @@ const HeaderActions: FC = ({ fluid onClick={handleRestartBot} > - {lang('BotRestart')} + {oldLang('BotRestart')} )} {canExpandActions && canUnblock && ( @@ -369,7 +397,7 @@ const HeaderActions: FC = ({ fluid onClick={handleUnblock} > - {lang('Unblock')} + {oldLang('Unblock')} )} {canSearch && ( @@ -379,7 +407,7 @@ const HeaderActions: FC = ({ color="translucent" size="smaller" onClick={handleSearchClick} - ariaLabel={lang('Conversation.SearchPlaceholder')} + ariaLabel={oldLang('Conversation.SearchPlaceholder')} iconName="search" /> )} @@ -404,7 +432,7 @@ const HeaderActions: FC = ({ size="smaller" iconName="user" onClick={handleJoinRequestsClick} - ariaLabel={isChannel ? lang('SubscribeRequests') : lang('MemberRequests')} + ariaLabel={isChannel ? oldLang('SubscribeRequests') : oldLang('MemberRequests')} >
{pendingJoinRequests}
diff --git a/src/components/middle/message/_message-content.scss b/src/components/middle/message/_message-content.scss index cc289c437..baca3d26f 100644 --- a/src/components/middle/message/_message-content.scss +++ b/src/components/middle/message/_message-content.scss @@ -583,13 +583,13 @@ &:not(.custom-shape) .text-content { .emoji { - width: calc(1.25 * var(--message-text-size, 1rem)); - height: calc(1.25 * var(--message-text-size, 1rem)); - background-size: calc(1.25 * var(--message-text-size, 1rem)); + width: 1.25em; + height: 1.25em; + background-size: 1.25em; } .custom-emoji { - --custom-emoji-size: max(calc(1.25 * var(--message-text-size, 1rem)), 20px); + --custom-emoji-size: max(1.25em, 20px); width: var(--custom-emoji-size); height: var(--custom-emoji-size); diff --git a/src/components/modals/ModalContainer.tsx b/src/components/modals/ModalContainer.tsx index c3d68981b..2c784e4b8 100644 --- a/src/components/modals/ModalContainer.tsx +++ b/src/components/modals/ModalContainer.tsx @@ -15,6 +15,7 @@ import BirthdaySetupModal from './birthday/BirthdaySetupModal.async'; import BoostModal from './boost/BoostModal.async'; import ChatInviteModal from './chatInvite/ChatInviteModal.async'; import ChatlistModal from './chatlist/ChatlistModal.async'; +import CocoonModal from './cocoon/CocoonModal.async'; import CollectibleInfoModal from './collectible/CollectibleInfoModal.async'; import DeleteAccountModal from './deleteAccount/DeleteAccountModal.async'; import EmojiStatusAccessModal from './emojiStatusAccess/EmojiStatusAccessModal.async'; @@ -130,7 +131,8 @@ type ModalKey = keyof Pick; type StateProps = { @@ -207,6 +209,7 @@ const MODALS: ModalRegistry = { isPasskeyModalOpen: PasskeyModal, birthdaySetupModal: BirthdaySetupModal, isQuickChatPickerOpen: QuickChatPickerModal, + isCocoonModalOpen: CocoonModal, }; const MODAL_KEYS = Object.keys(MODALS) as ModalKey[]; const MODAL_ENTRIES = Object.entries(MODALS) as Entries; diff --git a/src/components/modals/cocoon/CocoonModal.async.tsx b/src/components/modals/cocoon/CocoonModal.async.tsx new file mode 100644 index 000000000..a959c720b --- /dev/null +++ b/src/components/modals/cocoon/CocoonModal.async.tsx @@ -0,0 +1,14 @@ +import type { OwnProps } from './CocoonModal'; + +import { Bundles } from '../../../util/moduleLoader'; + +import useModuleLoader from '../../../hooks/useModuleLoader'; + +const CocoonModalAsync = (props: OwnProps) => { + const { modal } = props; + const CocoonModal = useModuleLoader(Bundles.Extra, 'CocoonModal', !modal); + + return CocoonModal ? : undefined; +}; + +export default CocoonModalAsync; diff --git a/src/components/modals/cocoon/CocoonModal.module.scss b/src/components/modals/cocoon/CocoonModal.module.scss new file mode 100644 index 000000000..907caed32 --- /dev/null +++ b/src/components/modals/cocoon/CocoonModal.module.scss @@ -0,0 +1,26 @@ +.header { + position: relative; + margin-top: -1rem; + margin-inline: -1rem; +} + +.footer { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.footerText { + font-size: 0.9375rem; + color: var(--color-text-secondary); + text-align: center; + text-wrap: balance; +} + +.egg { + transition: transform 0.25s ease-out; + + &:hover { + transform: scale(1.1); + } +} diff --git a/src/components/modals/cocoon/CocoonModal.tsx b/src/components/modals/cocoon/CocoonModal.tsx new file mode 100644 index 000000000..8014c90eb --- /dev/null +++ b/src/components/modals/cocoon/CocoonModal.tsx @@ -0,0 +1,108 @@ +import { memo, useMemo } from '@teact'; +import { getActions } from '../../../global'; + +import type { TabState } from '../../../global/types'; + +import useLang from '../../../hooks/useLang'; +import useLastCallback from '../../../hooks/useLastCallback'; + +import SafeLink from '../../common/SafeLink'; +import Button from '../../ui/Button'; +import Link from '../../ui/Link'; +import ParticlesHeader from '../common/ParticlesHeader'; +import TableAboutModal, { type TableAboutData } from '../common/TableAboutModal'; + +import styles from './CocoonModal.module.scss'; + +export type OwnProps = { + modal: TabState['isCocoonModalOpen']; +}; + +const CocoonModal = ({ modal }: OwnProps) => { + const { closeCocoonModal, openTelegramLink } = getActions(); + const isOpen = Boolean(modal); + + const lang = useLang(); + + const handleClose = useLastCallback(() => { + closeCocoonModal(); + }); + + const openLinkAndClose = useLastCallback((url: string) => { + openTelegramLink({ url }); + handleClose(); + }); + + const listItemData = useMemo(() => { + const feature1Description = lang('CocoonFeature1Text', { + username: ( + { + openLinkAndClose(lang('CocoonFeature1UsernameLink')); + }} + > + {lang('CocoonFeature1Username')} + + ), + }, { withNodes: true, withMarkdown: true }); + + const feature3Description = lang('CocoonFeature3Text', { + link: , + }, { + withNodes: true, + withMarkdown: true, + }); + + return [ + ['lock', lang('CocoonFeature1Title'), feature1Description], + ['stats', lang('CocoonFeature2Title'), lang('CocoonFeature2Text')], + ['gift', lang('CocoonFeature3Title'), feature3Description], + ] satisfies TableAboutData; + }, [lang]); + + const header = useMemo(() => { + return ( + + ); + }, [lang]); + + const footer = useMemo(() => { + return ( +
+ + {lang('CocoonFooterText', { + link: ( + openLinkAndClose(lang('CocoonFooterLink'))}> + {lang('CocoonFooterLinkText')} + + ), + }, { withNodes: true, withMarkdown: true })} + + +
+ ); + }, [lang]); + + return ( + + ); +}; + +export default memo(CocoonModal); diff --git a/src/components/modals/common/ParticlesHeader.module.scss b/src/components/modals/common/ParticlesHeader.module.scss index 3b940028c..a13343ad8 100644 --- a/src/components/modals/common/ParticlesHeader.module.scss +++ b/src/components/modals/common/ParticlesHeader.module.scss @@ -5,6 +5,29 @@ padding-top: 9rem; } +.ai-egg { + padding-top: 10rem; + background-color: #061029; + background-image: radial-gradient(circle at center, #FFFFFF08 0%, #00000000 50%); + + .title { + margin-bottom: 0; + + font-size: 2.5rem; + color: transparent; + + background-image: linear-gradient(90deg, #67c9ff 0%, #cb56ff 100%); + background-clip: text; + } + + .description { + color: #b8c9ef; + :global(b) { + color: white; + } + } +} + .particles { position: absolute; top: 0; @@ -41,3 +64,10 @@ transform: scale(1.1); } } + +.cocoon { + position: absolute; + z-index: 1; + top: 1.75rem; + height: 8.125rem; +} diff --git a/src/components/modals/common/ParticlesHeader.tsx b/src/components/modals/common/ParticlesHeader.tsx index e8b683e53..525d7d13c 100644 --- a/src/components/modals/common/ParticlesHeader.tsx +++ b/src/components/modals/common/ParticlesHeader.tsx @@ -15,14 +15,17 @@ import SwayingStar from './SwayingStar.tsx'; import styles from './ParticlesHeader.module.scss'; +import Cocoon from '../../../assets/cocoon.webp'; + interface OwnProps { - model: 'swaying-star' | 'speeding-diamond' | 'sticker'; + model: 'swaying-star' | 'speeding-diamond' | 'ai-egg' | 'sticker'; sticker?: ApiSticker; color: 'purple' | 'gold' | 'blue'; title: TeactNode; description: TeactNode; isDisabled?: boolean; className?: string; + modelClassName?: string; } const GIFT_STICKER_SIZE = 8 * REM; @@ -39,6 +42,7 @@ function ParticlesHeader({ description, isDisabled, className, + modelClassName, }: OwnProps) { const stickerRef = useRef(); const triggerSparklesRef = useRef<(() => void) | undefined>(); @@ -52,7 +56,7 @@ function ParticlesHeader({ }); return ( -
+
+ ) : model === 'ai-egg' ? ( + ) : model === 'speeding-diamond' ? ( - + ) : model === 'sticker' && sticker && (
diff --git a/src/components/modals/common/SpeedingDiamond.tsx b/src/components/modals/common/SpeedingDiamond.tsx index 16f951310..a2eaf4642 100644 --- a/src/components/modals/common/SpeedingDiamond.tsx +++ b/src/components/modals/common/SpeedingDiamond.tsx @@ -2,6 +2,7 @@ import { memo, useState } from '@teact'; import { requestMutation } from '../../../lib/fasterdom/fasterdom.ts'; import { animateSingle } from '../../../util/animation.ts'; +import buildClassName from '../../../util/buildClassName'; import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets.ts'; import useLastCallback from '../../../hooks/useLastCallback.ts'; @@ -13,6 +14,7 @@ import styles from './SpeedingDiamond.module.scss'; import diamondPreviewUrl from '../../../assets/diamond.png'; interface OwnProps { + className?: string; onMouseMove: NoneToVoidFunction; } @@ -24,7 +26,7 @@ const SLOWDOWN_DURATION = 1500; let slowdownTimeout: number | undefined; let isAnimating = true; -function SpeedingDiamond({ onMouseMove }: OwnProps) { +function SpeedingDiamond({ className, onMouseMove }: OwnProps) { const [speed, setSpeed] = useState(MIN_SPEED); const handleMouseMove = useLastCallback(() => { @@ -58,7 +60,7 @@ function SpeedingDiamond({ onMouseMove }: OwnProps) { }); return ( -
+
diff --git a/src/components/modals/common/TableAboutModal.module.scss b/src/components/modals/common/TableAboutModal.module.scss index 103fcbbc6..a5cd55935 100644 --- a/src/components/modals/common/TableAboutModal.module.scss +++ b/src/components/modals/common/TableAboutModal.module.scss @@ -75,8 +75,10 @@ align-items: center; } -.listItem { - padding-bottom: 0.5rem; +.listItems { + display: flex; + flex-direction: column; + gap: 0.5rem; } .listItemTitle { @@ -86,5 +88,5 @@ .separator { width: calc(100% + 2rem); // Hack to cover modal paddings - margin-block: 1rem; + margin-bottom: 0.5rem; } diff --git a/src/components/modals/common/TableAboutModal.tsx b/src/components/modals/common/TableAboutModal.tsx index 65567c6c8..16ad61b4a 100644 --- a/src/components/modals/common/TableAboutModal.tsx +++ b/src/components/modals/common/TableAboutModal.tsx @@ -63,7 +63,7 @@ const TableAboutModal = ({
)} {header} -
+
{listItemData?.map(([icon, title, subtitle]) => { return ( ) => void; }; -const Link: FC = ({ +const Link = ({ children, isPrimary, className, isRtl, withMultilineFix, onClick, -}) => { +}: OwnProps) => { const handleClick = useLastCallback((e: React.MouseEvent) => { e.preventDefault(); onClick!(e); diff --git a/src/components/ui/MenuItem.scss b/src/components/ui/MenuItem.scss index f4e5fc284..f09b01d4d 100644 --- a/src/components/ui/MenuItem.scss +++ b/src/components/ui/MenuItem.scss @@ -161,11 +161,20 @@ font-weight: var(--font-weight-semibold); } + a:hover { + text-decoration: none; + } + &.wrap { display: block; white-space: normal; } + &.text-only { + padding-inline: 0.5rem; + line-height: 1.375; + } + &.menu-custom-emoji-sets { margin: 0 0.25rem; padding: 0.5rem 0.75rem; diff --git a/src/components/ui/MenuItem.tsx b/src/components/ui/MenuItem.tsx index ea323171c..eee9a59d0 100644 --- a/src/components/ui/MenuItem.tsx +++ b/src/components/ui/MenuItem.tsx @@ -91,6 +91,7 @@ const MenuItem = (props: MenuItemProps) => { destructive && 'destructive', !isTouchScreen && 'compact', withWrap && 'wrap', + !icon && !customIcon && 'text-only', ); const content = ( diff --git a/src/config.ts b/src/config.ts index 5aa0cf844..811f0bea7 100644 --- a/src/config.ts +++ b/src/config.ts @@ -345,6 +345,7 @@ export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must export const VERIFICATION_CODES_USER_ID = '489000'; export const ANONYMOUS_USER_ID = '2666000'; export const RESTRICTED_EMOJI_SET_ID = '7173162320003080'; +export const COCOON_EMOJI_ID = '5197252827247841976'; export const LOCAL_MESSAGES_LIMIT = 1e6; // 1M export const CHANNEL_ID_BASE = 10n ** 12n; export const DEFAULT_GIF_SEARCH_BOT_USERNAME = 'gif'; diff --git a/src/global/actions/ui/misc.ts b/src/global/actions/ui/misc.ts index c9d5ca961..459426d43 100644 --- a/src/global/actions/ui/misc.ts +++ b/src/global/actions/ui/misc.ts @@ -961,3 +961,12 @@ addActionHandler('openQuickChatPicker', (global, actions, payload): ActionReturn }); addTabStateResetterAction('closeQuickChatPicker', 'isQuickChatPickerOpen'); + +addActionHandler('openCocoonModal', (global, actions, payload): ActionReturnType => { + const { tabId = getCurrentTabId() } = payload || {}; + return updateTabState(global, { + isCocoonModalOpen: true, + }, tabId); +}); + +addTabStateResetterAction('closeCocoonModal', 'isCocoonModalOpen'); diff --git a/src/global/types/actions.ts b/src/global/types/actions.ts index 45def6392..c1c76364f 100644 --- a/src/global/types/actions.ts +++ b/src/global/types/actions.ts @@ -2996,6 +2996,9 @@ export interface ActionPayloads { chatId: string; messageId: number; }; + + openCocoonModal: WithTabId | undefined; + closeCocoonModal: WithTabId | undefined; } export interface RequiredActionPayloads { diff --git a/src/global/types/tabState.ts b/src/global/types/tabState.ts index c0bc50547..ca74ef599 100644 --- a/src/global/types/tabState.ts +++ b/src/global/types/tabState.ts @@ -975,4 +975,6 @@ export type TabState = { isWaitingForStarGiftTransfer?: true; insertingPeerIdMention?: string; shouldSaveAttachmentsCompression?: boolean; + + isCocoonModalOpen?: boolean; }; diff --git a/src/lib/gramjs/tl/apiTl.ts b/src/lib/gramjs/tl/apiTl.ts index dcbebb4be..15e749cd7 100644 --- a/src/lib/gramjs/tl/apiTl.ts +++ b/src/lib/gramjs/tl/apiTl.ts @@ -1872,6 +1872,7 @@ payments.getStarsStatus#4ea9b3bf flags:# ton:flags.0?true peer:InputPeer = payme payments.getStarsTransactions#69da4557 flags:# inbound:flags.0?true outbound:flags.1?true ascending:flags.2?true ton:flags.4?true subscription_id:flags.3?string peer:InputPeer offset:string limit:int = payments.StarsStatus; payments.sendStarsForm#7998c914 form_id:long invoice:InputInvoice = payments.PaymentResult; payments.refundStarsCharge#25ae8f4a user_id:InputUser charge_id:string = Updates; +payments.getStarsRevenueStats#d91ffad6 flags:# dark:flags.0?true ton:flags.1?true peer:InputPeer = payments.StarsRevenueStats; payments.getStarsTransactionsByID#2dca16b8 flags:# ton:flags.0?true peer:InputPeer id:Vector = payments.StarsStatus; payments.getStarsGiftOptions#d3c96bc8 flags:# user_id:flags.0?InputUser = Vector; payments.getStarsSubscriptions#32512c5 flags:# missing_balance:flags.0?true peer:InputPeer offset:string = payments.StarsStatus; diff --git a/src/lib/gramjs/tl/static/api.json b/src/lib/gramjs/tl/static/api.json index b707c67eb..d598c6599 100644 --- a/src/lib/gramjs/tl/static/api.json +++ b/src/lib/gramjs/tl/static/api.json @@ -331,6 +331,7 @@ "payments.getStarsTransactions", "payments.getStarsTransactionsByID", "payments.getStarsSubscriptions", + "payments.getStarsRevenueStats", "payments.changeStarsSubscription", "payments.fulfillStarsSubscription", "payments.sendStarsForm", diff --git a/src/types/language.d.ts b/src/types/language.d.ts index d4bf564ab..7a51922b2 100644 --- a/src/types/language.d.ts +++ b/src/types/language.d.ts @@ -1916,6 +1916,19 @@ export interface LangPair { 'SettingsDataClearMediaCache': undefined; 'SettingsDataClearMediaCacheDescription': undefined; 'SettingsDataClearMediaDone': undefined; + 'TranslateMenuCocoonLinkText': undefined; + 'CocoonTitle': undefined; + 'CocoonDescription': undefined; + 'CocoonFeature1Title': undefined; + 'CocoonFeature1Username': undefined; + 'CocoonFeature1UsernameLink': undefined; + 'CocoonFeature2Title': undefined; + 'CocoonFeature2Text': undefined; + 'CocoonFeature3Title': undefined; + 'CocoonFeature3LinkText': undefined; + 'CocoonFeature3Link': undefined; + 'CocoonFooterLinkText': undefined; + 'CocoonFooterLink': undefined; 'ChatListAuctionWinning': undefined; 'ChatListAuctionOutbid': undefined; 'ChatListAuctionView': undefined; @@ -3360,6 +3373,18 @@ export interface LangPairWithVariables { 'status': V; 'onlineCount': V; }; + 'TranslateMenuCocoon': { + 'link': V; + }; + 'CocoonFeature1Text': { + 'username': V; + }; + 'CocoonFeature3Text': { + 'link': V; + }; + 'CocoonFooterText': { + 'link': V; + }; 'ChatListAuctionMixed': { 'winCount': V; 'outbidCount': V; diff --git a/src/util/stopEvent.ts b/src/util/stopEvent.ts index 65e03f0fb..801591078 100644 --- a/src/util/stopEvent.ts +++ b/src/util/stopEvent.ts @@ -1,5 +1,3 @@ -import type React from '../lib/teact/teact'; - const stopEvent = (e: React.UIEvent | Event | React.FormEvent) => { e.stopPropagation(); e.preventDefault(); diff --git a/webpack.config.ts b/webpack.config.ts index 3f2580cba..873109e6a 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -164,7 +164,7 @@ export default function createConfig( ], }, { - test: /\.(woff(2)?|ttf|eot|svg|png|jpg|tgs)(\?v=\d+\.\d+\.\d+)?$/, + test: /\.(woff(2)?|ttf|eot|svg|png|jpg|tgs|webp)(\?v=\d+\.\d+\.\d+)?$/, type: 'asset/resource', }, {