mirror of
https://github.com/danog/telegram-tt.git
synced 2024-12-15 02:37:17 +01:00
1 line
49 KiB
Plaintext
1 line
49 KiB
Plaintext
{"version":3,"file":"2305.39f8bb954e6546753460.js","mappings":"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","sources":["webpack://telegram-t/./src/components/common/Avatar.tsx","webpack://telegram-t/./src/components/middle/message/hooks/useVideoAutoPause.ts","webpack://telegram-t/./src/components/right/DeleteMemberModal.tsx","webpack://telegram-t/./src/components/ui/InfiniteScroll.tsx","webpack://telegram-t/./src/components/ui/Modal.tsx","webpack://telegram-t/./src/util/trapFocus.ts","webpack://telegram-t/./src/components/ui/Portal.ts","webpack://telegram-t/./src/global/selectors/limits.ts","webpack://telegram-t/./src/hooks/useInfiniteScroll.ts","webpack://telegram-t/./src/hooks/useInterval.ts","webpack://telegram-t/./src/hooks/useVideoCleanup.ts","webpack://telegram-t/./src/util/resetScroll.ts"],"sourcesContent":["import type { MouseEvent as ReactMouseEvent } from 'react';\nimport React, {\n memo, useCallback, useEffect, useRef,\n} from '../../lib/teact/teact';\nimport { getActions } from '../../global';\n\nimport type { FC, TeactNode } from '../../lib/teact/teact';\nimport type {\n ApiChat, ApiPhoto, ApiUser, ApiUserStatus,\n} from '../../api/types';\nimport type { ObserveFn } from '../../hooks/useIntersectionObserver';\nimport type { AnimationLevel } from '../../types';\nimport { ApiMediaFormat } from '../../api/types';\n\nimport { ANIMATION_LEVEL_MAX, IS_TEST } from '../../config';\nimport { VIDEO_AVATARS_DISABLED } from '../../util/environment';\nimport {\n getChatAvatarHash,\n getChatTitle,\n getUserColorKey,\n getUserFullName,\n isUserId,\n isChatWithRepliesBot,\n isDeletedUser,\n isUserOnline,\n} from '../../global/helpers';\nimport { getFirstLetters } from '../../util/textFormat';\nimport buildClassName, { createClassNameBuilder } from '../../util/buildClassName';\nimport renderText from './helpers/renderText';\n\nimport useMedia from '../../hooks/useMedia';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useLang from '../../hooks/useLang';\nimport { useIsIntersecting } from '../../hooks/useIntersectionObserver';\nimport useVideoAutoPause from '../middle/message/hooks/useVideoAutoPause';\nimport useVideoCleanup from '../../hooks/useVideoCleanup';\n\nimport './Avatar.scss';\n\nconst LOOP_COUNT = 3;\n\nconst cn = createClassNameBuilder('Avatar');\ncn.media = cn('media');\ncn.icon = cn('icon');\n\ntype OwnProps = {\n className?: string;\n size?: 'micro' | 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';\n chat?: ApiChat;\n user?: ApiUser;\n photo?: ApiPhoto;\n userStatus?: ApiUserStatus;\n text?: string;\n isSavedMessages?: boolean;\n withVideo?: boolean;\n noLoop?: boolean;\n animationLevel?: AnimationLevel;\n lastSyncTime?: number;\n observeIntersection?: ObserveFn;\n onClick?: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasMedia: boolean) => void;\n};\n\nconst Avatar: FC<OwnProps> = ({\n className,\n size = 'large',\n chat,\n user,\n photo,\n userStatus,\n text,\n isSavedMessages,\n withVideo,\n noLoop,\n lastSyncTime,\n animationLevel,\n observeIntersection,\n onClick,\n}) => {\n const { loadFullUser } = getActions();\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n // eslint-disable-next-line no-null/no-null\n const videoRef = useRef<HTMLVideoElement>(null);\n const videoLoopCountRef = useRef(0);\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n const isDeleted = user && isDeletedUser(user);\n const isReplies = user && isChatWithRepliesBot(user.id);\n let imageHash: string | undefined;\n let videoHash: string | undefined;\n\n const shouldShowVideo = (\n !VIDEO_AVATARS_DISABLED && animationLevel === ANIMATION_LEVEL_MAX\n && isIntersecting && withVideo && user?.isPremium && user?.hasVideoAvatar\n );\n const profilePhoto = user?.fullInfo?.profilePhoto;\n const shouldLoadVideo = shouldShowVideo && profilePhoto?.isVideo;\n\n const shouldFetchBig = size === 'jumbo';\n if (!isSavedMessages && !isDeleted) {\n if (user) {\n imageHash = getChatAvatarHash(user, shouldFetchBig ? 'big' : undefined);\n } else if (chat) {\n imageHash = getChatAvatarHash(chat, shouldFetchBig ? 'big' : undefined);\n } else if (photo) {\n imageHash = `photo${photo.id}?size=m`;\n }\n\n if (shouldLoadVideo) {\n videoHash = getChatAvatarHash(user!, undefined, 'video');\n }\n }\n\n const imgBlobUrl = useMedia(imageHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);\n const videoBlobUrl = useMedia(videoHash, !shouldLoadVideo, ApiMediaFormat.BlobUrl, lastSyncTime);\n const hasBlobUrl = Boolean(imgBlobUrl || videoBlobUrl);\n const shouldPlayVideo = Boolean(isIntersecting && videoBlobUrl);\n\n const { transitionClassNames } = useShowTransition(hasBlobUrl, undefined, hasBlobUrl, 'slow');\n\n const { handlePlaying } = useVideoAutoPause(videoRef, shouldPlayVideo);\n useVideoCleanup(videoRef, [shouldPlayVideo]);\n\n useEffect(() => {\n const video = videoRef.current;\n if (!video || !videoBlobUrl) return undefined;\n\n const returnToStart = () => {\n videoLoopCountRef.current += 1;\n if (videoLoopCountRef.current >= LOOP_COUNT || noLoop) {\n video.style.display = 'none';\n } else {\n video.play();\n }\n };\n\n video.addEventListener('ended', returnToStart);\n return () => video.removeEventListener('ended', returnToStart);\n }, [noLoop, videoBlobUrl]);\n\n const userId = user?.id;\n useEffect(() => {\n if (shouldShowVideo && !profilePhoto) {\n loadFullUser({ userId });\n }\n }, [loadFullUser, profilePhoto, userId, shouldShowVideo]);\n\n const lang = useLang();\n\n let content: TeactNode | undefined;\n const author = user ? getUserFullName(user) : (chat ? getChatTitle(lang, chat) : text);\n\n if (isSavedMessages) {\n content = <i className={buildClassName(cn.icon, 'icon-avatar-saved-messages')} role=\"img\" aria-label={author} />;\n } else if (isDeleted) {\n content = <i className={buildClassName(cn.icon, 'icon-avatar-deleted-account')} role=\"img\" aria-label={author} />;\n } else if (isReplies) {\n content = <i className={buildClassName(cn.icon, 'icon-reply-filled')} role=\"img\" aria-label={author} />;\n } else if (hasBlobUrl) {\n content = (\n <>\n <img\n src={imgBlobUrl}\n className={buildClassName(cn.media, 'avatar-media', transitionClassNames, videoBlobUrl && 'poster')}\n alt={author}\n decoding=\"async\"\n />\n {shouldPlayVideo && (\n <video\n ref={videoRef}\n src={videoBlobUrl}\n className={buildClassName(cn.media, 'avatar-media')}\n muted\n autoPlay\n disablePictureInPicture\n playsInline\n onPlaying={handlePlaying}\n />\n )}\n </>\n );\n } else if (user) {\n const userFullName = getUserFullName(user);\n content = userFullName ? getFirstLetters(userFullName, 2) : undefined;\n } else if (chat) {\n const title = getChatTitle(lang, chat);\n content = title && getFirstLetters(title, isUserId(chat.id) ? 2 : 1);\n } else if (text) {\n content = getFirstLetters(text, 2);\n }\n\n const isOnline = !isSavedMessages && user && userStatus && isUserOnline(user, userStatus);\n const fullClassName = buildClassName(\n `Avatar size-${size}`,\n className,\n `color-bg-${getUserColorKey(user || chat)}`,\n isSavedMessages && 'saved-messages',\n isDeleted && 'deleted-account',\n isReplies && 'replies-bot-account',\n isOnline && 'online',\n onClick && 'interactive',\n (!isSavedMessages && !imgBlobUrl) && 'no-photo',\n );\n\n const hasMedia = Boolean(isSavedMessages || imgBlobUrl);\n const handleClick = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {\n if (onClick) {\n onClick(e, hasMedia);\n }\n }, [onClick, hasMedia]);\n\n const senderId = (user || chat) && (user || chat)!.id;\n\n return (\n <div\n ref={ref}\n className={fullClassName}\n onClick={handleClick}\n data-test-sender-id={IS_TEST ? senderId : undefined}\n aria-label={typeof content === 'string' ? author : undefined}\n >\n {typeof content === 'string' ? renderText(content, [size === 'jumbo' ? 'hq_emoji' : 'emoji']) : content}\n </div>\n );\n};\n\nexport default memo(Avatar);\n","import { useCallback, useRef } from '../../../../lib/teact/teact';\n\nimport { fastRaf } from '../../../../util/schedulers';\nimport safePlay from '../../../../util/safePlay';\nimport useBackgroundMode from '../../../../hooks/useBackgroundMode';\nimport useHeavyAnimationCheck from '../../../../hooks/useHeavyAnimationCheck';\n\nexport default function useVideoAutoPause(playerRef: { current: HTMLVideoElement | null }, canPlay: boolean) {\n const wasPlaying = useRef(playerRef.current?.paused);\n const canPlayRef = useRef();\n canPlayRef.current = canPlay;\n\n const isFrozenRef = useRef();\n\n const freezePlaying = useCallback(() => {\n isFrozenRef.current = true;\n\n if (!playerRef.current) {\n return;\n }\n\n wasPlaying.current = !playerRef.current.paused;\n\n if (wasPlaying.current) {\n playerRef.current.pause();\n }\n }, [playerRef]);\n\n const unfreezePlaying = useCallback(() => {\n isFrozenRef.current = false;\n\n if (\n playerRef.current && wasPlaying.current && canPlayRef.current\n // At this point HTMLVideoElement can be unmounted from the DOM\n && document.body.contains(playerRef.current)\n ) {\n safePlay(playerRef.current);\n }\n }, [playerRef]);\n\n const unfreezePlayingOnRaf = useCallback(() => {\n fastRaf(unfreezePlaying);\n }, [unfreezePlaying]);\n\n useBackgroundMode(freezePlaying, unfreezePlayingOnRaf);\n useHeavyAnimationCheck(freezePlaying, unfreezePlaying);\n\n const handlePlaying = useCallback(() => {\n if (isFrozenRef.current) {\n wasPlaying.current = true;\n playerRef.current!.pause();\n }\n }, [playerRef]);\n\n return { handlePlaying };\n}\n","import type { FC } from '../../lib/teact/teact';\nimport React, { useCallback, memo } from '../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../global';\n\nimport type { ApiChat } from '../../api/types';\n\nimport { selectCurrentChat, selectUser } from '../../global/selectors';\nimport { getUserFirstOrLastName } from '../../global/helpers';\nimport renderText from '../common/helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport Modal from '../ui/Modal';\nimport Button from '../ui/Button';\n\nexport type OwnProps = {\n isOpen: boolean;\n userId?: string;\n onClose: () => void;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n contactName?: string;\n};\n\nconst DeleteMemberModal: FC<OwnProps & StateProps> = ({\n isOpen,\n chat,\n userId,\n contactName,\n onClose,\n}) => {\n const { deleteChatMember } = getActions();\n\n const lang = useLang();\n\n const handleDeleteChatMember = useCallback(() => {\n deleteChatMember({ chatId: chat!.id, userId });\n onClose();\n }, [chat, deleteChatMember, onClose, userId]);\n\n if (!chat || !userId) {\n return undefined;\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n onEnter={handleDeleteChatMember}\n className=\"delete\"\n title={lang('GroupRemoved.Remove')}\n >\n <p>{renderText(lang('PeerInfo.Confirm.RemovePeer', contactName))}</p>\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteChatMember}>\n {lang('lng_box_remove')}\n </Button>\n <Button className=\"confirm-dialog-button\" isText onClick={onClose}>{lang('Cancel')}</Button>\n </Modal>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { userId }): StateProps => {\n const chat = selectCurrentChat(global);\n const user = userId && selectUser(global, userId);\n const contactName = user ? getUserFirstOrLastName(user) : undefined;\n\n return {\n chat,\n contactName,\n };\n },\n)(DeleteMemberModal));\n","import type { RefObject, UIEvent } from 'react';\nimport { LoadMoreDirection } from '../../types';\n\nimport type { FC } from '../../lib/teact/teact';\nimport React, {\n useCallback, useEffect, useLayoutEffect, useMemo, useRef,\n} from '../../lib/teact/teact';\n\nimport { debounce } from '../../util/schedulers';\nimport resetScroll from '../../util/resetScroll';\nimport { IS_ANDROID } from '../../util/environment';\nimport buildStyle from '../../util/buildStyle';\n\ntype OwnProps = {\n ref?: RefObject<HTMLDivElement>;\n className?: string;\n items?: any[];\n itemSelector?: string;\n preloadBackwards?: number;\n sensitiveArea?: number;\n withAbsolutePositioning?: boolean;\n maxHeight?: number;\n noScrollRestore?: boolean;\n noScrollRestoreOnTop?: boolean;\n noFastList?: boolean;\n cacheBuster?: any;\n children: React.ReactNode;\n onLoadMore?: ({ direction }: { direction: LoadMoreDirection; noScroll?: boolean }) => void;\n onScroll?: (e: UIEvent<HTMLDivElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent<any>) => void;\n onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;\n onDragLeave?: (e: React.DragEvent<HTMLDivElement>) => void;\n};\n\nconst DEFAULT_LIST_SELECTOR = '.ListItem';\nconst DEFAULT_PRELOAD_BACKWARDS = 20;\nconst DEFAULT_SENSITIVE_AREA = 800;\n\nconst InfiniteScroll: FC<OwnProps> = ({\n ref,\n className,\n items,\n itemSelector = DEFAULT_LIST_SELECTOR,\n preloadBackwards = DEFAULT_PRELOAD_BACKWARDS,\n sensitiveArea = DEFAULT_SENSITIVE_AREA,\n withAbsolutePositioning,\n maxHeight,\n // Used to turn off restoring scroll position (e.g. for frequently re-ordered chat or user lists)\n noScrollRestore = false,\n noScrollRestoreOnTop = false,\n noFastList,\n // Used to re-query `listItemElements` if rendering is delayed by transition\n cacheBuster,\n children,\n onLoadMore,\n onScroll,\n onKeyDown,\n onDragOver,\n onDragLeave,\n}: OwnProps) => {\n // eslint-disable-next-line no-null/no-null\n let containerRef = useRef<HTMLDivElement>(null);\n if (ref) {\n containerRef = ref;\n }\n\n const stateRef = useRef<{\n listItemElements?: NodeListOf<HTMLDivElement>;\n isScrollTopJustUpdated?: boolean;\n currentAnchor?: HTMLDivElement | undefined;\n currentAnchorTop?: number;\n }>({});\n\n const [loadMoreBackwards, loadMoreForwards] = useMemo(() => {\n if (!onLoadMore) {\n return [];\n }\n\n return [\n debounce((noScroll = false) => {\n onLoadMore({ direction: LoadMoreDirection.Backwards, noScroll });\n }, 1000, true, false),\n debounce(() => {\n onLoadMore({ direction: LoadMoreDirection.Forwards });\n }, 1000, true, false),\n ];\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [onLoadMore, items]);\n\n // Initial preload\n useEffect(() => {\n if (!loadMoreBackwards) {\n return;\n }\n\n if (preloadBackwards > 0 && (!items || items.length < preloadBackwards)) {\n loadMoreBackwards(true);\n return;\n }\n\n const { scrollHeight, clientHeight } = containerRef.current!;\n if (clientHeight && scrollHeight <= clientHeight) {\n loadMoreBackwards();\n }\n }, [items, loadMoreBackwards, preloadBackwards]);\n\n // Restore `scrollTop` after adding items\n useLayoutEffect(() => {\n const container = containerRef.current!;\n const state = stateRef.current;\n\n state.listItemElements = container.querySelectorAll<HTMLDivElement>(itemSelector);\n\n let newScrollTop;\n\n if (state.currentAnchor && Array.from(state.listItemElements).includes(state.currentAnchor)) {\n const { scrollTop } = container;\n const newAnchorTop = state.currentAnchor.getBoundingClientRect().top;\n newScrollTop = scrollTop + (newAnchorTop - state.currentAnchorTop!);\n } else {\n const nextAnchor = state.listItemElements[0];\n if (nextAnchor) {\n state.currentAnchor = nextAnchor;\n state.currentAnchorTop = nextAnchor.getBoundingClientRect().top;\n }\n }\n\n if (withAbsolutePositioning || noScrollRestore) {\n return;\n }\n\n if (noScrollRestoreOnTop && container.scrollTop === 0) {\n return;\n }\n\n resetScroll(container, newScrollTop);\n\n state.isScrollTopJustUpdated = true;\n }, [items, itemSelector, noScrollRestore, noScrollRestoreOnTop, cacheBuster, withAbsolutePositioning]);\n\n const handleScroll = useCallback((e: UIEvent<HTMLDivElement>) => {\n if (loadMoreForwards && loadMoreBackwards) {\n const {\n isScrollTopJustUpdated, currentAnchor, currentAnchorTop,\n } = stateRef.current;\n const listItemElements = stateRef.current.listItemElements!;\n\n if (isScrollTopJustUpdated) {\n stateRef.current.isScrollTopJustUpdated = false;\n return;\n }\n\n const listLength = listItemElements.length;\n const container = containerRef.current!;\n const { scrollTop, scrollHeight, offsetHeight } = container;\n const top = listLength ? listItemElements[0].offsetTop : 0;\n const isNearTop = scrollTop <= top + sensitiveArea;\n const bottom = listLength\n ? listItemElements[listLength - 1].offsetTop + listItemElements[listLength - 1].offsetHeight\n : scrollHeight;\n const isNearBottom = bottom - (scrollTop + offsetHeight) <= sensitiveArea;\n let isUpdated = false;\n\n if (isNearTop) {\n const nextAnchor = listItemElements[0];\n if (nextAnchor) {\n const nextAnchorTop = nextAnchor.getBoundingClientRect().top;\n const newAnchorTop = currentAnchor?.offsetParent && currentAnchor !== nextAnchor\n ? currentAnchor.getBoundingClientRect().top\n : nextAnchorTop;\n const isMovingUp = (\n currentAnchor && currentAnchorTop !== undefined && newAnchorTop > currentAnchorTop\n );\n\n if (isMovingUp) {\n stateRef.current.currentAnchor = nextAnchor;\n stateRef.current.currentAnchorTop = nextAnchorTop;\n isUpdated = true;\n loadMoreForwards();\n }\n }\n }\n\n if (isNearBottom) {\n const nextAnchor = listItemElements[listLength - 1];\n if (nextAnchor) {\n const nextAnchorTop = nextAnchor.getBoundingClientRect().top;\n const newAnchorTop = currentAnchor?.offsetParent && currentAnchor !== nextAnchor\n ? currentAnchor.getBoundingClientRect().top\n : nextAnchorTop;\n const isMovingDown = (\n currentAnchor && currentAnchorTop !== undefined && newAnchorTop < currentAnchorTop\n );\n\n if (isMovingDown) {\n stateRef.current.currentAnchor = nextAnchor;\n stateRef.current.currentAnchorTop = nextAnchorTop;\n isUpdated = true;\n loadMoreBackwards();\n }\n }\n }\n\n if (!isUpdated) {\n if (currentAnchor?.offsetParent) {\n stateRef.current.currentAnchorTop = currentAnchor.getBoundingClientRect().top;\n } else {\n const nextAnchor = listItemElements[0];\n\n if (nextAnchor) {\n stateRef.current.currentAnchor = nextAnchor;\n stateRef.current.currentAnchorTop = nextAnchor.getBoundingClientRect().top;\n }\n }\n }\n }\n\n if (onScroll) {\n onScroll(e);\n }\n }, [loadMoreBackwards, loadMoreForwards, onScroll, sensitiveArea]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n onScroll={handleScroll}\n teactFastList={!noFastList && !withAbsolutePositioning}\n onKeyDown={onKeyDown}\n onDragOver={onDragOver}\n onDragLeave={onDragLeave}\n >\n {withAbsolutePositioning && items?.length ? (\n <div\n teactFastList={!noFastList}\n style={buildStyle('position: relative', IS_ANDROID && `height: ${maxHeight}px`)}\n >\n {children}\n </div>\n ) : children}\n </div>\n );\n};\n\nexport default InfiniteScroll;\n","import type { RefObject } from 'react';\nimport type { FC, TeactNode } from '../../lib/teact/teact';\nimport React, { useEffect, useRef } from '../../lib/teact/teact';\n\nimport type { TextPart } from '../../types';\n\nimport captureKeyboardListeners from '../../util/captureKeyboardListeners';\nimport trapFocus from '../../util/trapFocus';\nimport buildClassName from '../../util/buildClassName';\nimport { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';\nimport useLang from '../../hooks/useLang';\nimport useHistoryBack from '../../hooks/useHistoryBack';\n\nimport Button from './Button';\nimport Portal from './Portal';\n\nimport './Modal.scss';\n\nconst ANIMATION_DURATION = 200;\n\ntype OwnProps = {\n title?: string | TextPart[];\n className?: string;\n isOpen?: boolean;\n header?: TeactNode;\n hasCloseButton?: boolean;\n noBackdrop?: boolean;\n children: React.ReactNode;\n style?: string;\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n onEnter?: () => void;\n dialogRef?: RefObject<HTMLDivElement>;\n};\n\ntype StateProps = {\n shouldSkipHistoryAnimations?: boolean;\n};\n\nconst Modal: FC<OwnProps & StateProps> = ({\n dialogRef,\n title,\n className,\n isOpen,\n header,\n hasCloseButton,\n noBackdrop,\n children,\n style,\n onClose,\n onCloseAnimationEnd,\n onEnter,\n shouldSkipHistoryAnimations,\n}) => {\n const {\n shouldRender,\n transitionClassNames,\n } = useShowTransition(\n isOpen, onCloseAnimationEnd, shouldSkipHistoryAnimations, undefined, shouldSkipHistoryAnimations,\n );\n // eslint-disable-next-line no-null/no-null\n const modalRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => (isOpen\n ? captureKeyboardListeners({ onEsc: onClose, onEnter })\n : undefined), [isOpen, onClose, onEnter]);\n useEffect(() => (isOpen && modalRef.current ? trapFocus(modalRef.current) : undefined), [isOpen]);\n\n useHistoryBack({\n isActive: isOpen,\n onBack: onClose,\n });\n\n useEffectWithPrevDeps(([prevIsOpen]) => {\n document.body.classList.toggle('has-open-dialog', Boolean(isOpen));\n\n if (isOpen || (!isOpen && prevIsOpen !== undefined)) {\n dispatchHeavyAnimationEvent(ANIMATION_DURATION);\n }\n\n return () => {\n document.body.classList.remove('has-open-dialog');\n };\n }, [isOpen]);\n\n const lang = useLang();\n\n if (!shouldRender) {\n return undefined;\n }\n\n function renderHeader() {\n if (header) {\n return header;\n }\n\n if (!title) {\n return undefined;\n }\n\n return (\n <div className=\"modal-header\">\n {hasCloseButton && (\n <Button\n round\n color=\"translucent\"\n size=\"smaller\"\n ariaLabel={lang('Close')}\n onClick={onClose}\n >\n <i className=\"icon-close\" />\n </Button>\n )}\n <div className=\"modal-title\">{title}</div>\n </div>\n );\n }\n\n const fullClassName = buildClassName(\n 'Modal',\n className,\n transitionClassNames,\n noBackdrop && 'transparent-backdrop',\n );\n\n return (\n <Portal>\n <div\n ref={modalRef}\n className={fullClassName}\n tabIndex={-1}\n role=\"dialog\"\n >\n <div className=\"modal-container\">\n <div className=\"modal-backdrop\" onClick={onClose} />\n <div className=\"modal-dialog\" ref={dialogRef}>\n {renderHeader()}\n <div className=\"modal-content custom-scroll\" style={style}>\n {children}\n </div>\n </div>\n </div>\n </div>\n </Portal>\n );\n};\n\nexport default Modal;\n","export default function trapFocus(element: HTMLElement) {\n function handleKeyDown(e: KeyboardEvent) {\n if (e.key !== 'Tab') {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n\n const focusableElements = Array.from(\n element.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'),\n ) as HTMLElement[];\n if (!focusableElements.length) {\n return;\n }\n\n const currentFocusedIndex = focusableElements.findIndex((em) => em.isSameNode(document.activeElement));\n let newFocusedIndex = 0;\n if (currentFocusedIndex >= 0) {\n if (e.shiftKey) {\n newFocusedIndex = currentFocusedIndex > 0\n ? currentFocusedIndex - 1\n : focusableElements.length - 1;\n } else {\n newFocusedIndex = currentFocusedIndex < focusableElements.length - 1\n ? currentFocusedIndex + 1\n : 0;\n }\n }\n\n focusableElements[newFocusedIndex].focus();\n }\n\n document.addEventListener('keydown', handleKeyDown, false);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown, false);\n };\n}\n","import type { FC, VirtualElement } from '../../lib/teact/teact';\nimport { useRef, useLayoutEffect } from '../../lib/teact/teact';\nimport TeactDOM from '../../lib/teact/teact-dom';\n\ntype OwnProps = {\n containerId?: string;\n className?: string;\n children: VirtualElement;\n};\n\nconst Portal: FC<OwnProps> = ({ containerId, className, children }) => {\n const elementRef = useRef<HTMLDivElement>();\n if (!elementRef.current) {\n elementRef.current = document.createElement('div');\n }\n\n useLayoutEffect(() => {\n const container = document.querySelector<HTMLDivElement>(containerId || '#portals');\n if (!container) {\n return undefined;\n }\n\n const element = elementRef.current!;\n if (className) {\n element.classList.add(className);\n }\n\n container.appendChild(element);\n\n return () => {\n TeactDOM.render(undefined, element);\n container.removeChild(element);\n };\n }, [className, containerId]);\n\n return TeactDOM.render(children, elementRef.current);\n};\n\nexport default Portal;\n","import type { ApiLimitType, GlobalState } from '../types';\nimport { selectIsCurrentUserPremium } from './users';\nimport { DEFAULT_LIMITS } from '../../config';\n\nexport function selectCurrentLimit(global: GlobalState, limit: ApiLimitType) {\n const { appConfig } = global;\n if (!appConfig) {\n return DEFAULT_LIMITS[limit][0];\n }\n\n const isPremium = selectIsCurrentUserPremium(global);\n const { limits } = appConfig;\n\n const value = limits[limit][isPremium ? 1 : 0] ?? DEFAULT_LIMITS[limit][isPremium ? 1 : 0];\n if (limit === 'dialogFilters') return value + 1; // Server does not count \"All\" as folder, but we need to\n return value;\n}\n\nexport function selectPremiumLimit(global: GlobalState, limit: ApiLimitType) {\n const { appConfig } = global;\n if (!appConfig) return DEFAULT_LIMITS[limit][1];\n\n const { limits } = appConfig;\n\n return limits[limit][1];\n}\n","import { useCallback, useRef } from '../lib/teact/teact';\nimport { LoadMoreDirection } from '../types';\n\nimport { areSortedArraysEqual } from '../util/iteratees';\nimport useForceUpdate from './useForceUpdate';\nimport usePrevious from './usePrevious';\n\ntype GetMore = (args: { direction: LoadMoreDirection }) => void;\ntype LoadMoreBackwards = (args: { offsetId?: string | number }) => void;\n\nconst DEFAULT_LIST_SLICE = 30;\n\nconst useInfiniteScroll = <ListId extends string | number>(\n loadMoreBackwards?: LoadMoreBackwards,\n listIds?: ListId[],\n isDisabled = false,\n listSlice = DEFAULT_LIST_SLICE,\n): [ListId[]?, GetMore?] => {\n const lastParamsRef = useRef<{\n direction?: LoadMoreDirection;\n offsetId?: ListId;\n }>();\n\n const viewportIdsRef = useRef<ListId[] | undefined>((() => {\n // Only run once to initialize\n if (!listIds || lastParamsRef.current) {\n return undefined;\n }\n\n const { newViewportIds } = getViewportSlice(listIds, LoadMoreDirection.Forwards, listSlice, listIds[0]);\n return newViewportIds;\n })());\n\n const forceUpdate = useForceUpdate();\n\n if (isDisabled) {\n lastParamsRef.current = {};\n }\n\n const prevListIds = usePrevious(listIds);\n const prevIsDisabled = usePrevious(isDisabled);\n if (listIds && !isDisabled && (listIds !== prevListIds || isDisabled !== prevIsDisabled)) {\n const { offsetId = listIds[0], direction = LoadMoreDirection.Forwards } = lastParamsRef.current || {};\n const { newViewportIds } = getViewportSlice(listIds, direction, listSlice, offsetId);\n\n if (!viewportIdsRef.current || !areSortedArraysEqual(viewportIdsRef.current, newViewportIds)) {\n viewportIdsRef.current = newViewportIds;\n }\n } else if (!listIds) {\n viewportIdsRef.current = undefined;\n }\n\n const getMore: GetMore = useCallback(({\n direction,\n noScroll,\n }: { direction: LoadMoreDirection; noScroll?: boolean }) => {\n const viewportIds = viewportIdsRef.current;\n\n const offsetId = viewportIds\n ? direction === LoadMoreDirection.Backwards ? viewportIds[viewportIds.length - 1] : viewportIds[0]\n : undefined;\n\n if (!listIds) {\n if (loadMoreBackwards) {\n loadMoreBackwards({ offsetId });\n }\n\n return;\n }\n\n if (!noScroll) {\n lastParamsRef.current = { ...lastParamsRef.current, direction, offsetId };\n }\n\n const {\n newViewportIds, areSomeLocal, areAllLocal,\n } = getViewportSlice(listIds, direction, listSlice, offsetId);\n\n if (areSomeLocal && !(viewportIds && areSortedArraysEqual(viewportIds, newViewportIds))) {\n viewportIdsRef.current = newViewportIds;\n forceUpdate();\n }\n\n if (!areAllLocal && loadMoreBackwards) {\n loadMoreBackwards({ offsetId });\n }\n }, [listIds, listSlice, loadMoreBackwards, forceUpdate]);\n\n return isDisabled ? [listIds] : [viewportIdsRef.current, getMore];\n};\n\nfunction getViewportSlice<ListId extends string | number>(\n sourceIds: ListId[],\n direction: LoadMoreDirection,\n listSlice: number,\n offsetId?: ListId,\n) {\n const { length } = sourceIds;\n const index = offsetId ? sourceIds.indexOf(offsetId) : 0;\n const isForwards = direction === LoadMoreDirection.Forwards;\n const indexForDirection = isForwards ? index : (index + 1) || length;\n const from = Math.max(0, indexForDirection - listSlice);\n const to = indexForDirection + listSlice - 1;\n const newViewportIds = sourceIds.slice(Math.max(0, from), to + 1);\n\n let areSomeLocal;\n let areAllLocal;\n switch (direction) {\n case LoadMoreDirection.Forwards:\n areSomeLocal = indexForDirection > 0;\n areAllLocal = from >= 0;\n break;\n case LoadMoreDirection.Backwards:\n areSomeLocal = indexForDirection < length;\n areAllLocal = to <= length - 1;\n break;\n }\n\n return { newViewportIds, areSomeLocal, areAllLocal };\n}\n\nexport default useInfiniteScroll;\n","import { useEffect, useLayoutEffect, useRef } from '../lib/teact/teact';\n\nfunction useInterval(callback: NoneToVoidFunction, delay?: number, noFirst = false) {\n const savedCallback = useRef(callback);\n\n useLayoutEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (delay === undefined) {\n return undefined;\n }\n\n const id = setInterval(() => savedCallback.current(), delay);\n if (!noFirst) savedCallback.current();\n\n return () => clearInterval(id);\n }, [delay, noFirst]);\n}\n\nexport default useInterval;\n","import type { RefObject } from 'react';\nimport { useEffect } from '../lib/teact/teact';\nimport { fastRaf } from '../util/schedulers';\n\n// Fix for memory leak when unmounting video element\nexport default function useVideoCleanup(videoRef: RefObject<HTMLVideoElement>, dependencies: any[]) {\n useEffect(() => {\n const videoEl = videoRef.current;\n\n return () => {\n if (videoEl) {\n fastRaf(() => {\n videoEl.pause();\n videoEl.src = '';\n videoEl.load();\n });\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies);\n}\n","import { IS_IOS } from './environment';\nimport forceReflow from './forceReflow';\n\nconst resetScroll = (container: HTMLDivElement, scrollTop?: number) => {\n if (IS_IOS) {\n container.style.overflow = 'hidden';\n }\n\n if (scrollTop !== undefined) {\n container.scrollTop = scrollTop;\n }\n\n if (IS_IOS) {\n container.style.overflow = '';\n }\n};\n\n// Workaround for https://bugs.chromium.org/p/chromium/issues/detail?id=1264266\nexport function patchChromiumScroll(element: HTMLElement) {\n element.style.display = 'none';\n forceReflow(element);\n element.style.display = '';\n}\n\nexport default resetScroll;\n"],"names":["cn","createClassNameBuilder","media","icon","memo","className","size","chat","user","photo","userStatus","text","isSavedMessages","withVideo","noLoop","lastSyncTime","animationLevel","observeIntersection","onClick","loadFullUser","getActions","ref","useRef","videoRef","videoLoopCountRef","isIntersecting","useIsIntersecting","isDeleted","isDeletedUser","isReplies","isChatWithRepliesBot","id","imageHash","videoHash","shouldShowVideo","VIDEO_AVATARS_DISABLED","ANIMATION_LEVEL_MAX","isPremium","hasVideoAvatar","profilePhoto","fullInfo","shouldLoadVideo","isVideo","shouldFetchBig","getChatAvatarHash","undefined","imgBlobUrl","useMedia","ApiMediaFormat","videoBlobUrl","hasBlobUrl","Boolean","shouldPlayVideo","transitionClassNames","useShowTransition","handlePlaying","useVideoAutoPause","useVideoCleanup","useEffect","video","current","returnToStart","style","display","play","addEventListener","removeEventListener","userId","lang","useLang","content","author","getUserFullName","getChatTitle","buildClassName","role","src","alt","decoding","muted","autoPlay","disablePictureInPicture","playsInline","onPlaying","userFullName","getFirstLetters","title","isUserId","isOnline","isUserOnline","fullClassName","getUserColorKey","hasMedia","handleClick","useCallback","e","senderId","IS_TEST","renderText","playerRef","canPlay","wasPlaying","paused","canPlayRef","isFrozenRef","freezePlaying","pause","unfreezePlaying","document","body","contains","safePlay","unfreezePlayingOnRaf","fastRaf","useBackgroundMode","useHeavyAnimationCheck","withGlobal","global","selectCurrentChat","selectUser","contactName","getUserFirstOrLastName","isOpen","onClose","deleteChatMember","handleDeleteChatMember","chatId","onEnter","color","isText","DEFAULT_LIST_SELECTOR","DEFAULT_PRELOAD_BACKWARDS","DEFAULT_SENSITIVE_AREA","items","itemSelector","preloadBackwards","sensitiveArea","withAbsolutePositioning","maxHeight","noScrollRestore","noScrollRestoreOnTop","noFastList","cacheBuster","children","onLoadMore","onScroll","onKeyDown","onDragOver","onDragLeave","containerRef","stateRef","loadMoreBackwards","loadMoreForwards","useMemo","debounce","noScroll","direction","LoadMoreDirection","length","scrollHeight","clientHeight","useLayoutEffect","container","state","newScrollTop","listItemElements","querySelectorAll","currentAnchor","Array","from","includes","scrollTop","getBoundingClientRect","top","currentAnchorTop","nextAnchor","resetScroll","isScrollTopJustUpdated","handleScroll","listLength","offsetHeight","isNearTop","offsetTop","isNearBottom","isUpdated","nextAnchorTop","newAnchorTop","offsetParent","teactFastList","buildStyle","IS_ANDROID","dialogRef","header","hasCloseButton","noBackdrop","onCloseAnimationEnd","shouldSkipHistoryAnimations","shouldRender","modalRef","captureKeyboardListeners","onEsc","element","handleKeyDown","key","preventDefault","stopPropagation","focusableElements","currentFocusedIndex","findIndex","em","isSameNode","activeElement","newFocusedIndex","shiftKey","focus","trapFocus","useHistoryBack","isActive","onBack","useEffectWithPrevDeps","prevIsOpen","classList","toggle","dispatchHeavyAnimationEvent","remove","Portal","tabIndex","Button","round","ariaLabel","containerId","elementRef","createElement","querySelector","add","appendChild","TeactDOM","removeChild","selectCurrentLimit","limit","appConfig","DEFAULT_LIMITS","selectIsCurrentUserPremium","limits","value","selectPremiumLimit","getViewportSlice","sourceIds","listSlice","offsetId","index","indexOf","indexForDirection","Math","max","to","newViewportIds","slice","areSomeLocal","areAllLocal","listIds","isDisabled","lastParamsRef","viewportIdsRef","forceUpdate","useForceUpdate","prevListIds","usePrevious","prevIsDisabled","areSortedArraysEqual","getMore","viewportIds","callback","delay","noFirst","savedCallback","setInterval","clearInterval","dependencies","videoEl","load","patchChromiumScroll","forceReflow","IS_IOS","overflow"],"sourceRoot":""} |