mirror of
https://github.com/danog/telegram-tt.git
synced 2024-12-12 09:09:45 +01:00
1 line
458 KiB
Plaintext
1 line
458 KiB
Plaintext
{"version":3,"file":"484.c0ed9d4b856019215efb.js","mappings":"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AI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,EAAG,GAAI,IAAK,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,GAE5qCC,EAAY,CAAC,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI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","sources":["webpack://telegram-t/./src/components/common/AnimatedEmoji.tsx","webpack://telegram-t/./src/components/common/AnimatedSticker.tsx","webpack://telegram-t/./src/components/common/Audio.tsx","webpack://telegram-t/./src/util/waveform.ts","webpack://telegram-t/./src/components/common/helpers/waveform.ts","webpack://telegram-t/./src/components/common/Avatar.tsx","webpack://telegram-t/./src/components/common/ChatExtra.tsx","webpack://telegram-t/./src/components/common/DeleteChatModal.tsx","webpack://telegram-t/./src/components/common/Document.tsx","webpack://telegram-t/./src/components/common/File.tsx","webpack://telegram-t/./src/components/common/GroupChatInfo.tsx","webpack://telegram-t/./src/components/common/LastMessageMeta.tsx","webpack://telegram-t/./src/components/common/Media.tsx","webpack://telegram-t/./src/components/common/MessageOutgoingStatus.tsx","webpack://telegram-t/./src/components/common/NothingFound.tsx","webpack://telegram-t/./src/components/common/Picker.tsx","webpack://telegram-t/./src/components/common/PickerSelectedItem.tsx","webpack://telegram-t/./src/components/common/PrivateChatInfo.tsx","webpack://telegram-t/./src/components/common/ProfilePhoto.tsx","webpack://telegram-t/./src/components/common/ProfileInfo.tsx","webpack://telegram-t/./src/components/common/hooks/usePhotosPreload.ts","webpack://telegram-t/./src/components/common/StickerButton.tsx","webpack://telegram-t/./src/components/common/StickerSetModal.async.tsx","webpack://telegram-t/./src/components/common/TypingStatus.tsx","webpack://telegram-t/./src/components/common/VerifiedIcon.tsx","webpack://telegram-t/./src/components/common/WebLink.tsx","webpack://telegram-t/./src/components/common/helpers/mediaDimensions.ts","webpack://telegram-t/./src/components/common/helpers/renderMessageText.tsx","webpack://telegram-t/./src/components/left/main/hooks/useChatAnimationType.ts","webpack://telegram-t/./src/components/left/main/Badge.tsx","webpack://telegram-t/./src/components/left/main/Chat.tsx","webpack://telegram-t/./src/components/left/main/EmptyFolder.tsx","webpack://telegram-t/./src/components/left/main/ChatList.tsx","webpack://telegram-t/./src/components/middle/composer/DropTarget.tsx","webpack://telegram-t/./src/components/middle/composer/DropArea.tsx","webpack://telegram-t/./src/components/middle/composer/EmojiTooltip.async.tsx","webpack://telegram-t/./src/components/middle/composer/MessageInput.tsx","webpack://telegram-t/./src/components/middle/composer/TextFormatter.tsx","webpack://telegram-t/./src/components/middle/composer/helpers/parseMessageInput.ts","webpack://telegram-t/./src/components/middle/composer/helpers/selection.ts","webpack://telegram-t/./src/components/middle/composer/hooks/useEmojiTooltip.ts","webpack://telegram-t/./src/components/middle/composer/helpers/searchUserName.ts","webpack://telegram-t/./src/components/middle/composer/hooks/useMentionTooltip.ts","webpack://telegram-t/./src/components/right/hooks/useAsyncRendering.ts","webpack://telegram-t/./src/components/ui/ConfirmDialog.tsx","webpack://telegram-t/./src/components/ui/FloatingActionButton.tsx","webpack://telegram-t/./src/components/ui/InfiniteScroll.tsx","webpack://telegram-t/./src/components/ui/ListItem.tsx","webpack://telegram-t/./src/components/ui/Modal.tsx","webpack://telegram-t/./src/util/trapFocus.ts","webpack://telegram-t/./src/components/ui/Notification.tsx","webpack://telegram-t/./src/components/ui/Portal.ts","webpack://telegram-t/./src/components/ui/ProgressSpinner.tsx","webpack://telegram-t/./src/components/ui/Radio.tsx","webpack://telegram-t/./src/components/ui/RadioGroup.tsx","webpack://telegram-t/./src/components/ui/SearchInput.tsx","webpack://telegram-t/./src/components/ui/ShowTransition.tsx","webpack://telegram-t/./src/components/ui/Switcher.tsx","webpack://telegram-t/./src/components/ui/Tab.tsx","webpack://telegram-t/./src/components/ui/TabList.tsx","webpack://telegram-t/./src/components/ui/Transition.tsx","webpack://telegram-t/./src/hooks/reducers/useFoldersReducer.ts","webpack://telegram-t/./src/hooks/useAudioPlayer.ts","webpack://telegram-t/./src/hooks/useBackgroundMode.ts","webpack://telegram-t/./src/hooks/useBlur.ts","webpack://telegram-t/./src/hooks/useBlurSync.ts","webpack://telegram-t/./src/hooks/useBuffering.ts","webpack://telegram-t/./src/hooks/useCanvasBlur.ts","webpack://telegram-t/./src/hooks/useChatContextActions.ts","webpack://telegram-t/./src/hooks/useContextMenuHandlers.ts","webpack://telegram-t/./src/hooks/useContextMenuPosition.ts","webpack://telegram-t/./src/hooks/useCurrentOrPrev.ts","webpack://telegram-t/./src/hooks/useEnsureMessage.ts","webpack://telegram-t/./src/hooks/useHorizontalScroll.ts","webpack://telegram-t/./src/hooks/useInfiniteScroll.ts","webpack://telegram-t/./src/hooks/useIntersectionObserver.ts","webpack://telegram-t/./src/hooks/useLayoutEffectWithPrevDeps.ts","webpack://telegram-t/./src/hooks/useMedia.ts","webpack://telegram-t/./src/hooks/useMediaDownload.ts","webpack://telegram-t/./src/hooks/useMediaWithDownloadProgress.ts","webpack://telegram-t/./src/hooks/useMouseInside.ts","webpack://telegram-t/./src/hooks/usePrevDuringAnimation.ts","webpack://telegram-t/./src/hooks/useReducer.ts","webpack://telegram-t/./src/hooks/useTransitionForMedia.ts","webpack://telegram-t/./src/hooks/useVideoCleanup.ts","webpack://telegram-t/./src/lib/fastBlur.js","webpack://telegram-t/./src/util/audioPlayer.ts","webpack://telegram-t/./src/util/captureEvents.ts","webpack://telegram-t/./src/util/clipboard.ts","webpack://telegram-t/./src/util/cssAnimationEndListeners.ts","webpack://telegram-t/./src/util/cycleRestrict.ts","webpack://telegram-t/./src/util/download.ts","webpack://telegram-t/./src/util/fastSmoothScroll.ts","webpack://telegram-t/./src/util/fastSmoothScrollHorizontal.ts","webpack://telegram-t/./src/util/focusEditableElement.ts","webpack://telegram-t/./src/util/patchSafariProgressiveAudio.ts","webpack://telegram-t/./src/util/resetScroll.ts","webpack://telegram-t/./src/util/safePlay.ts"],"sourcesContent":["import React, {\n FC, useCallback, useRef, useState,\n} from '../../lib/teact/teact';\n\nimport { ApiMediaFormat, ApiSticker } from '../../api/types';\n\nimport { LIKE_STICKER_ID } from './helpers/mediaDimensions';\nimport { ObserveFn, useIsIntersecting } from '../../hooks/useIntersectionObserver';\nimport useMedia from '../../hooks/useMedia';\nimport useTransitionForMedia from '../../hooks/useTransitionForMedia';\nimport useFlag from '../../hooks/useFlag';\n\nimport AnimatedSticker from './AnimatedSticker';\n\nimport './AnimatedEmoji.scss';\n\ntype OwnProps = {\n sticker: ApiSticker;\n observeIntersection?: ObserveFn;\n size?: 'large' | 'medium' | 'small';\n lastSyncTime?: number;\n forceLoadPreview?: boolean;\n};\n\nconst QUALITY = 1;\nconst WIDTH = {\n large: 160,\n medium: 128,\n small: 104,\n};\n\nconst AnimatedEmoji: FC<OwnProps> = ({\n sticker,\n size = 'medium',\n observeIntersection,\n lastSyncTime,\n forceLoadPreview,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const [isAnimationLoaded, markAnimationLoaded] = useFlag();\n const localMediaHash = `sticker${sticker.id}`;\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n\n const thumbDataUri = sticker.thumbnail && sticker.thumbnail.dataUri;\n const previewBlobUrl = useMedia(\n `${localMediaHash}?size=m`,\n !isIntersecting && !forceLoadPreview,\n ApiMediaFormat.BlobUrl,\n lastSyncTime,\n );\n const { transitionClassNames } = useTransitionForMedia(previewBlobUrl, 'slow');\n\n const mediaData = useMedia(localMediaHash, !isIntersecting, ApiMediaFormat.Lottie, lastSyncTime);\n const isMediaLoaded = Boolean(mediaData);\n\n const [playKey, setPlayKey] = useState(String(Math.random()));\n const handleClick = useCallback(() => {\n setPlayKey(String(Math.random()));\n }, []);\n\n const width = WIDTH[size];\n const style = `width: ${width}px; height: ${width}px;`;\n\n return (\n <div\n ref={ref}\n className=\"AnimatedEmoji media-inner\"\n // @ts-ignore\n style={style}\n onClick={handleClick}\n >\n {!isAnimationLoaded && thumbDataUri && (\n <img src={thumbDataUri} className={sticker.id === LIKE_STICKER_ID ? 'like-sticker-thumb' : undefined} alt=\"\" />\n )}\n {!isAnimationLoaded && previewBlobUrl && (\n <img src={previewBlobUrl} className={transitionClassNames} alt=\"\" />\n )}\n {isMediaLoaded && (\n <AnimatedSticker\n key={localMediaHash}\n id={localMediaHash}\n animationData={mediaData as AnyLiteral}\n size={width}\n quality={QUALITY}\n play={isIntersecting && playKey}\n noLoop\n onLoad={markAnimationLoaded}\n />\n )}\n </div>\n );\n};\n\nexport default AnimatedEmoji;\n","import React, {\n FC, useEffect, useRef, memo, useCallback, useState,\n} from '../../lib/teact/teact';\n\nimport { fastRaf } from '../../util/schedulers';\nimport buildClassName from '../../util/buildClassName';\nimport useHeavyAnimationCheck from '../../hooks/useHeavyAnimationCheck';\nimport useBackgroundMode from '../../hooks/useBackgroundMode';\n\ntype OwnProps = {\n className?: string;\n id: string;\n animationData: AnyLiteral;\n play?: boolean | string;\n playSegment?: [number, number];\n speed?: number;\n noLoop?: boolean;\n size: number;\n quality?: number;\n isLowPriority?: boolean;\n onLoad?: NoneToVoidFunction;\n};\n\ntype RLottieClass = typeof import('../../lib/rlottie/RLottie').default;\ntype RLottieInstance = import('../../lib/rlottie/RLottie').default;\nlet lottiePromise: Promise<RLottieClass>;\nlet RLottie: RLottieClass;\n\n// Time supposed for judges to measure \"Transferred Size\" in Dev Tools\nconst LOTTIE_LOAD_DELAY = 5000;\n\nasync function ensureLottie() {\n if (!lottiePromise) {\n lottiePromise = import('../../lib/rlottie/RLottie') as unknown as Promise<RLottieClass>;\n RLottie = (await lottiePromise as any).default;\n }\n\n return lottiePromise;\n}\n\nsetTimeout(ensureLottie, LOTTIE_LOAD_DELAY);\n\nconst AnimatedSticker: FC<OwnProps> = ({\n className,\n id,\n animationData,\n play,\n playSegment,\n speed,\n noLoop,\n size,\n quality,\n isLowPriority,\n onLoad,\n}) => {\n const [animation, setAnimation] = useState<RLottieInstance>();\n // eslint-disable-next-line no-null/no-null\n const container = useRef<HTMLDivElement>(null);\n const wasPlaying = useRef(false);\n const isFrozen = useRef(false);\n\n const playRef = useRef();\n playRef.current = play;\n const playSegmentRef = useRef<[number, number]>();\n playSegmentRef.current = playSegment;\n\n useEffect(() => {\n if (animation || !animationData) {\n return;\n }\n\n const exec = () => {\n if (!container.current) {\n return;\n }\n\n const newAnimation = new RLottie(\n id,\n container.current,\n animationData,\n {\n noLoop,\n size,\n quality,\n isLowPriority,\n },\n onLoad,\n );\n\n if (speed) {\n newAnimation.setSpeed(speed);\n }\n\n setAnimation(newAnimation);\n };\n\n if (RLottie) {\n exec();\n } else {\n ensureLottie().then(() => {\n fastRaf(() => {\n if (container.current) {\n exec();\n }\n });\n });\n }\n }, [animation, animationData, id, isLowPriority, noLoop, onLoad, quality, size, speed]);\n\n useEffect(() => {\n return () => {\n if (animation) {\n animation.destroy();\n }\n };\n }, [animation]);\n\n const playAnimation = useCallback((shouldRestart = false) => {\n if (animation && (playRef.current || playSegmentRef.current)) {\n if (playSegmentRef.current) {\n animation.playSegment(playSegmentRef.current);\n } else if (shouldRestart) {\n animation.goToAndPlay(0);\n } else {\n animation.play();\n }\n }\n }, [animation]);\n\n const pauseAnimation = useCallback(() => {\n if (!animation) {\n return;\n }\n\n animation.pause();\n }, [animation]);\n\n const freezeAnimation = useCallback(() => {\n isFrozen.current = true;\n\n if (!animation) {\n return;\n }\n\n if (!wasPlaying.current) {\n wasPlaying.current = animation.isPlaying();\n }\n\n pauseAnimation();\n }, [animation, pauseAnimation]);\n\n const unfreezeAnimation = useCallback(() => {\n if (wasPlaying.current) {\n playAnimation();\n }\n\n wasPlaying.current = false;\n isFrozen.current = false;\n }, [playAnimation]);\n\n const unfreezeAnimationOnRaf = useCallback(() => {\n fastRaf(unfreezeAnimation);\n }, [unfreezeAnimation]);\n\n useEffect(() => {\n if (!animation) {\n return;\n }\n\n if (play || playSegment) {\n if (isFrozen.current) {\n wasPlaying.current = true;\n } else {\n playAnimation(noLoop);\n }\n } else {\n // eslint-disable-next-line no-lonely-if\n if (isFrozen.current) {\n wasPlaying.current = false;\n } else {\n pauseAnimation();\n }\n }\n }, [animation, play, playSegment, noLoop, playAnimation, pauseAnimation]);\n\n useHeavyAnimationCheck(freezeAnimation, unfreezeAnimation);\n // Pausing frame may not happen in background\n // so we need to make sure it happens right after focusing,\n // then we can play again.\n useBackgroundMode(freezeAnimation, unfreezeAnimationOnRaf);\n\n const fullClassName = buildClassName('AnimatedSticker', className);\n\n const style = size ? `width: ${size}px; height: ${size}px;` : undefined;\n\n return (\n <div\n ref={container}\n className={fullClassName}\n // @ts-ignore\n style={style}\n />\n );\n};\n\nexport default memo(AnimatedSticker);\n","import React, {\n FC, memo, useCallback, useEffect, useMemo, useRef, useState,\n} from '../../lib/teact/teact';\n\nimport {\n ApiAudio, ApiMessage, ApiVoice,\n} from '../../api/types';\nimport { ISettings } from '../../types';\n\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';\nimport { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';\nimport {\n getMediaDuration,\n getMediaTransferState,\n getMessageAudioCaption,\n getMessageKey,\n getMessageMediaFormat,\n getMessageMediaHash,\n isMessageLocal,\n isOwnMessage,\n} from '../../modules/helpers';\nimport { renderWaveformToDataUri } from './helpers/waveform';\nimport buildClassName from '../../util/buildClassName';\nimport renderText from './helpers/renderText';\nimport { decodeWaveform, interpolateArray } from '../../util/waveform';\nimport useMediaWithDownloadProgress from '../../hooks/useMediaWithDownloadProgress';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useBuffering from '../../hooks/useBuffering';\nimport useAudioPlayer from '../../hooks/useAudioPlayer';\nimport useMediaDownload from '../../hooks/useMediaDownload';\nimport useLang, { LangFn } from '../../hooks/useLang';\n\nimport Button from '../ui/Button';\nimport ProgressSpinner from '../ui/ProgressSpinner';\nimport Link from '../ui/Link';\n\nimport './Audio.scss';\n\ntype OwnProps = {\n theme: ISettings['theme'];\n message: ApiMessage;\n senderTitle?: string;\n uploadProgress?: number;\n target?: 'searchResult' | 'sharedMedia';\n date?: number;\n lastSyncTime?: number;\n className?: string;\n isSelectable?: boolean;\n isSelected?: boolean;\n onPlay: (messageId: number, chatId: number) => void;\n onReadMedia?: () => void;\n onCancelUpload?: () => void;\n onDateClick?: (messageId: number, chatId: number) => void;\n};\n\ninterface ISeekMethods {\n handleStartSeek: (e: React.MouseEvent<HTMLElement>) => void;\n handleSeek: (e: React.MouseEvent<HTMLElement>) => void;\n handleStopSeek: () => void;\n}\n\nconst AVG_VOICE_DURATION = 30;\nconst MIN_SPIKES = IS_SINGLE_COLUMN_LAYOUT ? 20 : 25;\nconst MAX_SPIKES = IS_SINGLE_COLUMN_LAYOUT ? 50 : 75;\n// This is needed for browsers requiring user interaction before playing.\nconst PRELOAD = true;\n\nconst Audio: FC<OwnProps> = ({\n theme,\n message,\n senderTitle,\n uploadProgress,\n target,\n date,\n lastSyncTime,\n className,\n isSelectable,\n isSelected,\n onPlay,\n onReadMedia,\n onCancelUpload,\n onDateClick,\n}) => {\n const { content: { audio, voice }, isMediaUnread } = message;\n const isVoice = Boolean(voice);\n const isSeeking = useRef<boolean>(false);\n const lang = useLang();\n\n const [isActivated, setIsActivated] = useState(false);\n const shouldDownload = (isActivated || PRELOAD) && lastSyncTime;\n\n const { mediaData, downloadProgress } = useMediaWithDownloadProgress(\n getMessageMediaHash(message, 'inline'),\n !shouldDownload,\n getMessageMediaFormat(message, 'inline'),\n );\n\n function handleForcePlay() {\n setIsActivated(true);\n onPlay(message.id, message.chatId);\n }\n\n const {\n isBuffered, bufferedProgress, bufferingHandlers, checkBuffering,\n } = useBuffering();\n\n const {\n isPlaying, playProgress, playPause, setCurrentTime, duration,\n } = useAudioPlayer(\n getMessageKey(message),\n getMediaDuration(message)!,\n mediaData,\n bufferingHandlers,\n checkBuffering,\n isActivated,\n handleForcePlay,\n isMessageLocal(message),\n );\n\n useEffect(() => {\n setIsActivated(isPlaying);\n }, [isPlaying]);\n\n const {\n isDownloadStarted,\n downloadProgress: directDownloadProgress,\n handleDownloadClick,\n } = useMediaDownload(getMessageMediaHash(message, 'download'), getMessageAudioCaption(message));\n\n const isLoadingForPlaying = isActivated && !isBuffered;\n\n const {\n isUploading, isTransferring, transferProgress,\n } = getMediaTransferState(\n message,\n isDownloadStarted ? directDownloadProgress : (uploadProgress || downloadProgress),\n isLoadingForPlaying || isDownloadStarted,\n );\n\n const {\n shouldRender: shouldRenderSpinner,\n transitionClassNames: spinnerClassNames,\n } = useShowTransition(isTransferring);\n\n const handleButtonClick = useCallback(() => {\n if (isUploading) {\n if (onCancelUpload) {\n onCancelUpload();\n }\n\n return;\n }\n\n if (!isPlaying) {\n onPlay(message.id, message.chatId);\n }\n\n setIsActivated(!isActivated);\n playPause();\n }, [isPlaying, isUploading, message.id, message.chatId, onCancelUpload, onPlay, playPause, isActivated]);\n\n useEffect(() => {\n if (isPlaying && onReadMedia && isMediaUnread) {\n onReadMedia();\n }\n }, [isPlaying, isMediaUnread, onReadMedia]);\n\n const handleSeek = useCallback((e: React.MouseEvent<HTMLElement>) => {\n if (isSeeking.current) {\n const seekBar = e.currentTarget.closest('.seekline,.waveform');\n if (seekBar) {\n const { width, left } = seekBar.getBoundingClientRect();\n setCurrentTime(duration * ((e.clientX - left) / width));\n }\n }\n }, [duration, setCurrentTime]);\n\n const handleStartSeek = useCallback((e: React.MouseEvent<HTMLElement>) => {\n isSeeking.current = true;\n handleSeek(e);\n }, [handleSeek]);\n\n const handleStopSeek = useCallback(() => {\n isSeeking.current = false;\n }, []);\n\n const handleDateClick = useCallback(() => {\n onDateClick!(message.id, message.chatId);\n }, [onDateClick, message.id, message.chatId]);\n\n function getFirstLine() {\n if (isVoice) {\n return senderTitle || 'Voice';\n }\n\n const { title, fileName } = audio!;\n\n return title || fileName;\n }\n\n function getSecondLine() {\n if (isVoice) {\n return formatMediaDuration(voice!.duration);\n }\n\n const { performer } = audio!;\n\n return (\n <>\n {performer && renderText(performer)}\n {performer && senderTitle && <span>•</span>}\n {senderTitle && renderText(senderTitle)}\n </>\n );\n }\n\n const seekHandlers = { handleStartSeek, handleSeek, handleStopSeek };\n const isOwn = isOwnMessage(message);\n const renderedWaveform = useMemo(\n () => voice && renderWaveform(voice, playProgress, isOwn, { handleStartSeek, handleSeek, handleStopSeek }, theme),\n [voice, playProgress, isOwn, handleStartSeek, handleSeek, handleStopSeek, theme],\n );\n\n const fullClassName = buildClassName(\n 'Audio media-inner',\n className,\n isOwn && !target && 'own',\n target && 'bigger',\n isSelected && 'audio-is-selected',\n );\n\n const buttonClassNames = ['toggle-play'];\n if (isLoadingForPlaying) {\n buttonClassNames.push('loading');\n } else if (isPlaying) {\n buttonClassNames.push('pause');\n } else if (!isPlaying) {\n buttonClassNames.push('play');\n }\n\n const showSeekline = isPlaying || (playProgress > 0 && playProgress < 1);\n const contentClassName = buildClassName('content', showSeekline && 'with-seekline');\n\n function renderSearchResult() {\n return (\n <>\n <div className={contentClassName}>\n <div className=\"content-row\">\n <p className=\"title\" dir=\"auto\">{renderText(getFirstLine())}</p>\n\n <div className=\"message-date\">\n {date && (\n <Link\n className=\"date\"\n onClick={handleDateClick}\n >\n {formatPastTimeShort(lang, date * 1000)}\n </Link>\n )}\n </div>\n </div>\n\n {showSeekline && renderSeekline(playProgress, bufferedProgress, seekHandlers)}\n {!showSeekline && (\n <p className=\"duration\" dir=\"auto\">\n {playProgress > 0 ? `${formatMediaDuration(duration * playProgress)} / ` : undefined}\n {getSecondLine()}\n </p>\n )}\n </div>\n </>\n );\n }\n\n return (\n <div className={fullClassName} dir={lang.isRtl ? 'rtl' : undefined}>\n {isSelectable && (\n <div className=\"message-select-control\">\n {isSelected && <i className=\"icon-select\" />}\n </div>\n )}\n <Button\n round\n ripple={!IS_SINGLE_COLUMN_LAYOUT}\n size={target ? 'smaller' : 'tiny'}\n className={buttonClassNames.join(' ')}\n ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}\n onClick={handleButtonClick}\n isRtl={lang.isRtl}\n >\n <i className=\"icon-play\" />\n <i className=\"icon-pause\" />\n </Button>\n {shouldRenderSpinner && (\n <div className={buildClassName('media-loading', spinnerClassNames, isLoadingForPlaying && 'interactive')}>\n <ProgressSpinner\n progress={transferProgress}\n transparent\n size={target ? 'm' : 's'}\n onClick={isLoadingForPlaying ? handleButtonClick : undefined}\n noCross={!isLoadingForPlaying}\n />\n </div>\n )}\n {audio && (\n <Button\n round\n size=\"tiny\"\n className=\"download-button\"\n ariaLabel={isDownloadStarted ? 'Cancel download' : 'Download'}\n onClick={handleDownloadClick}\n >\n <i className={isDownloadStarted ? 'icon-close' : 'icon-arrow-down'} />\n </Button>\n )}\n {target === 'searchResult' && renderSearchResult()}\n {target !== 'searchResult' && audio && renderAudio(\n lang, audio, isPlaying, playProgress, bufferedProgress, seekHandlers, date,\n onDateClick ? handleDateClick : undefined,\n )}\n {target !== 'searchResult' && voice && renderVoice(voice, renderedWaveform, isMediaUnread)}\n </div>\n );\n};\n\nfunction renderAudio(\n lang: LangFn,\n audio: ApiAudio,\n isPlaying: boolean,\n playProgress: number,\n bufferedProgress: number,\n seekHandlers: ISeekMethods,\n date?: number,\n handleDateClick?: NoneToVoidFunction,\n) {\n const {\n title, performer, duration, fileName,\n } = audio;\n const showSeekline = isPlaying || (playProgress > 0 && playProgress < 1);\n\n return (\n <div className=\"content\">\n <p className=\"title\" dir=\"auto\">{renderText(title || fileName)}</p>\n {showSeekline && renderSeekline(playProgress, bufferedProgress, seekHandlers)}\n {!showSeekline && (\n <div className=\"meta\" dir=\"auto\">\n <span className=\"performer\">{renderText(performer || 'Unknown')}</span>\n {date && (\n <>\n {' '}\n •\n {' '}\n <Link className=\"date\" onClick={handleDateClick}>{formatMediaDateTime(lang, date * 1000)}</Link>\n </>\n )}\n </div>\n )}\n <p className=\"duration\" dir=\"auto\">\n {playProgress > 0 ? `${formatMediaDuration(duration * playProgress)} / ` : undefined}\n {formatMediaDuration(duration)}\n </p>\n </div>\n );\n}\n\nfunction renderVoice(voice: ApiVoice, renderedWaveform: any, isMediaUnread?: boolean) {\n return (\n <div className=\"content\">\n {renderedWaveform}\n <p className=\"voice-duration\" dir=\"auto\">\n {formatMediaDuration(voice.duration)}\n {isMediaUnread && <span>•</span>}\n </p>\n </div>\n );\n}\n\nfunction renderWaveform(\n voice: ApiVoice,\n playProgress = 0,\n isOwn = false,\n { handleStartSeek, handleSeek, handleStopSeek }: ISeekMethods,\n theme: ISettings['theme'],\n) {\n const { waveform, duration } = voice;\n\n if (!waveform) {\n return undefined;\n }\n\n const fillColor = theme === 'dark' ? '#494B75' : '#CBCBCB';\n const fillOwnColor = theme === 'dark' ? '#C0BBED' : '#B0DEA6';\n const progressFillColor = theme === 'dark' ? '#868DF5' : '#54a3e6';\n const progressFillOwnColor = theme === 'dark' ? '#FFFFFF' : '#53ad53';\n const durationFactor = Math.min(duration / AVG_VOICE_DURATION, 1);\n const spikesCount = Math.round(MIN_SPIKES + (MAX_SPIKES - MIN_SPIKES) * durationFactor);\n const decodedWaveform = decodeWaveform(new Uint8Array(waveform));\n const { data: spikes, peak } = interpolateArray(decodedWaveform, spikesCount);\n const { src, width, height } = renderWaveformToDataUri(spikes, playProgress, {\n peak,\n fillStyle: isOwn ? fillOwnColor : fillColor,\n progressFillStyle: isOwn ? progressFillOwnColor : progressFillColor,\n });\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <img\n src={src}\n alt=\"\"\n width={width}\n height={height}\n className=\"waveform\"\n draggable={false}\n onMouseDown={handleStartSeek}\n onMouseMove={handleSeek}\n onMouseUp={handleStopSeek}\n />\n );\n}\n\nfunction renderSeekline(\n playProgress: number,\n bufferedProgress: number,\n { handleStartSeek, handleSeek, handleStopSeek }: ISeekMethods,\n) {\n return (\n <div\n className=\"seekline no-selection\"\n onMouseDown={handleStartSeek}\n onMouseMove={handleSeek}\n onMouseUp={handleStopSeek}\n >\n <span className=\"seekline-buffered-progress\">\n <i\n // @ts-ignore\n style={`transform: translateX(${bufferedProgress * 100}%)`}\n />\n </span>\n <span className=\"seekline-play-progress\">\n <i\n // @ts-ignore\n style={`transform: translateX(${playProgress * 100}%)`}\n />\n </span>\n <span className=\"seekline-thumb\">\n <i\n // @ts-ignore\n style={`transform: translateX(${playProgress * 100}%)`}\n />\n </span>\n </div>\n );\n}\n\nexport default memo(Audio);\n","/* eslint-disable no-bitwise */\n\n// eslint-disable-next-line max-len\n// Ref: https://github.com/telegramdesktop/tdesktop/blob/0743e71ab6b928d2ee5bae1aed991849b1e2b291/Telegram/SourceFiles/data/data_document.cpp#L1018\nexport function decodeWaveform(encoded5bit: Uint8Array) {\n const bitsCount = encoded5bit.length * 8;\n const valuesCount = Math.floor(bitsCount / 5);\n if (!valuesCount) {\n return [];\n }\n\n // Read each 5 bit of encoded5bit as 0-31 unsigned char.\n // We count the index of the byte in which the desired 5-bit sequence starts.\n // And then we read a uint16 starting from that byte to guarantee to get all of those 5 bits.\n //\n // BUT! if it is the last byte we have, we're not allowed to read a uint16 starting with it.\n // Because it will be an overflow (we'll access one byte after the available memory).\n // We see, that only the last 5 bits could start in the last available byte and be problematic.\n // So we read in a general way all the entries in a general way except the last one.\n const result = Array(valuesCount);\n const bitsData = encoded5bit;\n for (let i = 0, l = valuesCount - 1; i !== l; ++i) {\n const byteIndex = Math.floor((i * 5) / 8);\n const bitShift = Math.floor((i * 5) % 8);\n const value = bitsData[byteIndex] + (bitsData[byteIndex + 1] << 8);\n result[i] = ((value >> bitShift) & 0x1F);\n }\n const lastByteIndex = Math.floor(((valuesCount - 1) * 5) / 8);\n const lastBitShift = Math.floor(((valuesCount - 1) * 5) % 8);\n const lastValue = bitsData[lastByteIndex] + (bitsData[lastByteIndex + 1] << 8);\n result[valuesCount - 1] = (lastValue >> lastBitShift) & 0x1F;\n\n return result;\n}\n\nexport function interpolateArray(data: number[], fitCount: number) {\n let peak = 0;\n const newData = new Array(fitCount);\n const springFactor = data.length / fitCount;\n const leftFiller = data[0];\n const rightFiller = data[data.length - 1];\n for (let i = 0; i < fitCount; i++) {\n const idx = Math.floor(i * springFactor);\n const val = ((data[idx - 1] ?? leftFiller) + (data[idx] ?? leftFiller) + (data[idx + 1] ?? rightFiller)) / 3;\n newData[i] = val;\n if (peak < val) {\n peak = val;\n }\n }\n return { data: newData, peak };\n}\n","type IWaveformProps = {\n peak: number;\n fillStyle: string;\n progressFillStyle: string;\n};\n\nconst SPIKE_WIDTH = 2;\nconst SPIKE_STEP = 4;\nconst SPIKE_RADIUS = 1;\nconst HEIGHT = 23;\n\nexport function renderWaveformToDataUri(\n spikes: number[],\n progress: number,\n {\n peak, fillStyle, progressFillStyle,\n }: IWaveformProps,\n) {\n const width = spikes.length * SPIKE_STEP;\n const height = HEIGHT;\n\n const canvas = document.createElement('canvas');\n canvas.width = width * 2;\n canvas.height = height * 2;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n\n const ctx = canvas.getContext('2d')!;\n ctx.scale(2, 2);\n\n spikes.forEach((item, i) => {\n ctx.globalAlpha = (i / spikes.length >= progress) ? 0.5 : 1;\n ctx.fillStyle = progress > i / spikes.length ? progressFillStyle : fillStyle;\n const spikeHeight = Math.max(2, HEIGHT * (item / Math.max(1, peak)));\n roundedRectangle(ctx, i * SPIKE_STEP, height, SPIKE_WIDTH, spikeHeight, SPIKE_RADIUS);\n ctx.fill();\n });\n\n return {\n src: canvas.toDataURL(),\n width,\n height,\n };\n}\n\nfunction roundedRectangle(\n ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number,\n) {\n if (width < 2 * radius) {\n radius = width / 2;\n }\n if (height < 2 * radius) {\n radius = height / 2;\n }\n\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.arcTo(x + width, y, x + width, y - height, radius);\n ctx.arcTo(x + width, y - height, x, y - height, radius);\n ctx.arcTo(x, y - height, x, y, radius);\n ctx.arcTo(x, y, x + width, y, radius);\n ctx.closePath();\n}\n","import { MouseEvent as ReactMouseEvent } from 'react';\nimport React, { FC, useCallback, memo } from '../../lib/teact/teact';\n\nimport { ApiUser, ApiChat, ApiMediaFormat } from '../../api/types';\n\nimport { IS_TEST } from '../../config';\nimport {\n getChatAvatarHash, getChatTitle, isChatPrivate,\n getUserFullName, isUserOnline, isDeletedUser, getUserColorKey,\n} from '../../modules/helpers';\nimport { getFirstLetters } from '../../util/textFormat';\nimport buildClassName from '../../util/buildClassName';\nimport renderText from './helpers/renderText';\nimport useMedia from '../../hooks/useMedia';\nimport useTransitionForMedia from '../../hooks/useTransitionForMedia';\nimport useLang from '../../hooks/useLang';\n\nimport './Avatar.scss';\n\ntype OwnProps = {\n className?: string;\n size?: 'micro' | 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';\n withOnlineStatus?: boolean;\n chat?: ApiChat;\n user?: ApiUser;\n text?: string;\n isSavedMessages?: boolean;\n lastSyncTime?: number;\n onClick?: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasPhoto: boolean) => void;\n};\n\nconst Avatar: FC<OwnProps> = ({\n className,\n size = 'large',\n chat,\n user,\n text,\n withOnlineStatus,\n isSavedMessages,\n lastSyncTime,\n onClick,\n}) => {\n const isDeleted = user && isDeletedUser(user);\n let imageHash: string | undefined;\n\n if (!isSavedMessages && !isDeleted) {\n if (user) {\n imageHash = getChatAvatarHash(user);\n } else if (chat) {\n imageHash = getChatAvatarHash(chat);\n }\n }\n\n const dataUri = useMedia(imageHash, false, ApiMediaFormat.DataUri, lastSyncTime);\n const { shouldRenderFullMedia, transitionClassNames } = useTransitionForMedia(dataUri, 'slow');\n\n const lang = useLang();\n\n let content: string | undefined = '';\n\n if (isSavedMessages) {\n content = <i className=\"icon-avatar-saved-messages\" />;\n } else if (isDeleted) {\n content = <i className=\"icon-avatar-deleted-account\" />;\n } else if (shouldRenderFullMedia) {\n content = <img src={dataUri} className={`${transitionClassNames} avatar-media`} alt=\"\" decoding=\"async\" />;\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, isChatPrivate(chat.id) ? 2 : 1);\n } else if (text) {\n content = getFirstLetters(text, 2);\n }\n\n const isOnline = !isSavedMessages && user && isUserOnline(user);\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 withOnlineStatus && isOnline && 'online',\n onClick && 'interactive',\n (!isSavedMessages && !shouldRenderFullMedia) && 'no-photo',\n );\n\n const handleClick = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {\n if (onClick) {\n onClick(e, isSavedMessages || shouldRenderFullMedia);\n }\n }, [onClick, isSavedMessages, shouldRenderFullMedia]);\n\n const senderId = (user || chat) && (user || chat)!.id;\n\n return (\n <div className={fullClassName} onClick={handleClick} data-test-sender-id={IS_TEST ? senderId : undefined}>\n {typeof content === 'string' ? renderText(content, [size === 'jumbo' ? 'hq_emoji' : 'emoji']) : content}\n </div>\n );\n};\n\nexport default memo(Avatar);\n","import React, {\n FC, memo, useCallback, useEffect,\n} from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { GlobalActions, GlobalState } from '../../global/types';\nimport { ApiChat, ApiUser } from '../../api/types';\n\nimport {\n selectChat, selectNotifyExceptions, selectNotifySettings, selectUser,\n} from '../../modules/selectors';\nimport {\n getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isChatPrivate, isUserRightBanned, selectIsChatMuted,\n} from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport { pick } from '../../util/iteratees';\nimport { copyTextToClipboard } from '../../util/clipboard';\nimport { formatPhoneNumberWithCode } from '../../util/phoneNumber';\nimport useLang from '../../hooks/useLang';\n\nimport ListItem from '../ui/ListItem';\nimport Switcher from '../ui/Switcher';\n\ntype OwnProps = {\n chatOrUserId: number;\n forceShowSelf?: boolean;\n};\n\ntype StateProps = {\n user?: ApiUser;\n chat?: ApiChat;\n canInviteUsers?: boolean;\n isMuted?: boolean;\n} & Pick<GlobalState, 'lastSyncTime'>;\n\ntype DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'updateChatMutedState' | 'showNotification'>;\n\nconst ChatExtra: FC<OwnProps & StateProps & DispatchProps> = ({\n lastSyncTime,\n user,\n chat,\n forceShowSelf,\n canInviteUsers,\n isMuted,\n loadFullUser,\n showNotification,\n updateChatMutedState,\n}) => {\n const {\n id: userId,\n fullInfo,\n username,\n phoneNumber,\n isSelf,\n } = user || {};\n const { id: chatId } = chat || {};\n const lang = useLang();\n\n useEffect(() => {\n if (lastSyncTime && userId) {\n loadFullUser({ userId });\n }\n }, [loadFullUser, userId, lastSyncTime]);\n\n const handleNotificationChange = useCallback(() => {\n updateChatMutedState({ chatId, isMuted: !isMuted });\n }, [chatId, isMuted, updateChatMutedState]);\n\n if (!chat || chat.isRestricted || (isSelf && !forceShowSelf)) {\n return undefined;\n }\n\n function copy(text: string, entity: string) {\n copyTextToClipboard(text);\n showNotification({ message: `${entity} was copied` });\n }\n\n const formattedNumber = phoneNumber && formatPhoneNumberWithCode(phoneNumber);\n const link = getChatLink(chat);\n const description = (fullInfo && fullInfo.bio) || getChatDescription(chat);\n\n return (\n <div className=\"ChatExtra\">\n {formattedNumber && !!formattedNumber.length && (\n <ListItem icon=\"phone\" multiline narrow ripple onClick={() => copy(formattedNumber, lang('Phone'))}>\n <span className=\"title\" dir=\"auto\">{formattedNumber}</span>\n <span className=\"subtitle\">{lang('Phone')}</span>\n </ListItem>\n )}\n {username && (\n <ListItem\n icon=\"mention\"\n multiline\n narrow\n ripple\n onClick={() => copy(`@${username}`, lang('Username'))}\n >\n <span className=\"title\" dir=\"auto\">{renderText(username)}</span>\n <span className=\"subtitle\">{lang('Username')}</span>\n </ListItem>\n )}\n {description && !!description.length && (\n <ListItem\n icon=\"info\"\n multiline\n narrow\n isStatic\n >\n <span className=\"title\" dir=\"auto\">\n {renderText(description, ['br', 'links', 'emoji'])}\n </span>\n <span className=\"subtitle\">{lang(userId ? 'UserBio' : 'Info')}</span>\n </ListItem>\n )}\n {(canInviteUsers || !username) && link && (\n <ListItem icon=\"mention\" multiline narrow ripple onClick={() => copy(link, lang('SetUrlPlaceholder'))}>\n <div className=\"title\">{link}</div>\n <span className=\"subtitle\">{lang('SetUrlPlaceholder')}</span>\n </ListItem>\n )}\n {!forceShowSelf && (\n <ListItem icon=\"unmute\" ripple onClick={handleNotificationChange}>\n <span>{lang('Notifications')}</span>\n <Switcher\n id=\"group-notifications\"\n label={userId ? 'Toggle User Notifications' : 'Toggle Chat Notifications'}\n checked={!isMuted}\n inactive\n />\n </ListItem>\n )}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatOrUserId }): StateProps => {\n const { lastSyncTime } = global;\n\n const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;\n const user = isChatPrivate(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;\n const isMuted = chat && selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global));\n\n const canInviteUsers = chat && !user && (\n (!isChatChannel(chat) && !isUserRightBanned(chat, 'inviteUsers'))\n || getHasAdminRight(chat, 'inviteUsers')\n );\n\n return {\n lastSyncTime, chat, user, canInviteUsers, isMuted,\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, [\n 'loadFullUser', 'updateChatMutedState', 'showNotification',\n ]),\n)(ChatExtra));\n","import React, { FC, useCallback, memo } from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiChat } from '../../api/types';\nimport { GlobalActions } from '../../global/types';\n\nimport { selectIsChatWithSelf, selectUser } from '../../modules/selectors';\nimport {\n isChatPrivate,\n isUserBot,\n getUserFirstOrLastName,\n getPrivateChatUserId,\n isChatBasicGroup,\n isChatSuperGroup,\n isChatChannel,\n getChatTitle,\n} from '../../modules/helpers';\nimport { pick } from '../../util/iteratees';\nimport useLang from '../../hooks/useLang';\nimport renderText from './helpers/renderText';\n\nimport Avatar from './Avatar';\nimport Modal from '../ui/Modal';\nimport Button from '../ui/Button';\n\nimport './DeleteChatModal.scss';\n\nexport type OwnProps = {\n isOpen: boolean;\n chat: ApiChat;\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n};\n\ntype StateProps = {\n isChannel: boolean;\n isChatWithSelf?: boolean;\n isBot?: boolean;\n isPrivateChat: boolean;\n isBasicGroup: boolean;\n isSuperGroup: boolean;\n currentUserId: number | undefined;\n canDeleteForAll?: boolean;\n contactName?: string;\n};\n\ntype DispatchProps = Pick<GlobalActions, (\n 'leaveChannel' | 'deleteHistory' | 'deleteChannel' | 'deleteChatUser' | 'blockContact'\n)>;\n\nconst DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({\n isOpen,\n chat,\n isChannel,\n isPrivateChat,\n isChatWithSelf,\n isBot,\n isBasicGroup,\n isSuperGroup,\n currentUserId,\n canDeleteForAll,\n contactName,\n onClose,\n onCloseAnimationEnd,\n leaveChannel,\n deleteHistory,\n deleteChannel,\n deleteChatUser,\n blockContact,\n}) => {\n const lang = useLang();\n const chatTitle = getChatTitle(lang, chat);\n\n const handleDeleteMessageForAll = useCallback(() => {\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: true });\n\n onClose();\n }, [deleteHistory, chat.id, onClose]);\n\n const handleDeleteAndStop = useCallback(() => {\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: true });\n blockContact({ contactId: chat.id, accessHash: chat.accessHash });\n\n onClose();\n }, [deleteHistory, chat.id, chat.accessHash, blockContact, onClose]);\n\n const handleDeleteChat = useCallback(() => {\n if (isPrivateChat) {\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: false });\n } else if (isBasicGroup) {\n deleteChatUser({ chatId: chat.id, userId: currentUserId });\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: false });\n } else if ((isChannel || isSuperGroup) && !chat.isCreator) {\n leaveChannel({ chatId: chat.id });\n } else if ((isChannel || isSuperGroup) && chat.isCreator) {\n deleteChannel({ chatId: chat.id });\n }\n onClose();\n }, [\n isPrivateChat,\n isBasicGroup,\n isChannel,\n isSuperGroup,\n currentUserId,\n chat.isCreator,\n chat.id,\n onClose,\n deleteHistory,\n deleteChatUser,\n leaveChannel,\n deleteChannel,\n ]);\n\n function renderHeader() {\n return (\n <div className=\"modal-header\" dir={lang.isRtl ? 'rtl' : undefined}>\n <Avatar\n size=\"tiny\"\n chat={chat}\n isSavedMessages={isChatWithSelf}\n />\n <h3 className=\"modal-title\">{lang(renderTitle())}</h3>\n </div>\n );\n }\n\n function renderTitle() {\n if (isChannel && !chat.isCreator) {\n return 'LeaveChannel';\n }\n\n if (isChannel && chat.isCreator) {\n return 'ChannelDelete';\n }\n\n if (isBasicGroup || isSuperGroup) {\n return 'Group.LeaveGroup';\n }\n\n return 'DeleteChatUser';\n }\n\n function renderMessage() {\n if (isChannel && chat.isCreator) {\n return <p>{renderText(lang('ChatList.DeleteAndLeaveGroupConfirmation', chatTitle), ['simple_markdown'])}</p>;\n }\n\n if ((isChannel && !chat.isCreator) || isBasicGroup || isSuperGroup) {\n return <p>{renderText(lang('ChannelLeaveAlertWithName', chatTitle), ['simple_markdown'])}</p>;\n }\n\n return <p>{renderText(lang('ChatList.DeleteChatConfirmation', contactName), ['simple_markdown'])}</p>;\n }\n\n function renderActionText() {\n if (isChannel && !chat.isCreator) {\n return 'LeaveChannel';\n }\n if (isChannel && chat.isCreator) {\n return 'Chat.Input.Delete';\n }\n\n if (isBasicGroup || isSuperGroup) {\n return 'Group.LeaveGroup';\n }\n\n return canDeleteForAll ? 'ChatList.DeleteForCurrentUser' : 'Delete';\n }\n\n return (\n <Modal\n isOpen={isOpen}\n className=\"DeleteChatModal\"\n header={renderHeader()}\n onClose={onClose}\n onCloseAnimationEnd={onCloseAnimationEnd}\n >\n {renderMessage()}\n {isBot && (\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteAndStop}>\n {lang('DeleteAndStop')}\n </Button>\n )}\n {canDeleteForAll && (\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteMessageForAll}>\n {contactName ? renderText(lang('ChatList.DeleteForEveryone', contactName)) : lang('DeleteForAll')}\n </Button>\n )}\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteChat}>\n {lang(renderActionText())}\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, { chat }): StateProps => {\n const isPrivateChat = isChatPrivate(chat.id);\n const isChatWithSelf = selectIsChatWithSelf(global, chat.id);\n const user = isPrivateChat && selectUser(global, getPrivateChatUserId(chat)!);\n const isBot = user && isUserBot(user) && !chat.isSupport;\n const canDeleteForAll = (isPrivateChat && !isChatWithSelf && !isBot);\n const contactName = isPrivateChat\n ? getUserFirstOrLastName(selectUser(global, getPrivateChatUserId(chat)!))\n : undefined;\n\n return {\n isPrivateChat,\n isChatWithSelf,\n isBot,\n isChannel: isChatChannel(chat),\n isBasicGroup: isChatBasicGroup(chat),\n isSuperGroup: isChatSuperGroup(chat),\n currentUserId: global.currentUserId,\n canDeleteForAll,\n contactName,\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions,\n ['leaveChannel', 'deleteHistory', 'deleteChannel', 'deleteChatUser', 'blockContact']),\n)(DeleteChatModal));\n","import React, {\n FC, useCallback, useEffect, useState, memo, useRef,\n} from '../../lib/teact/teact';\n\nimport { ApiMediaFormat, ApiMessage } from '../../api/types';\n\nimport { getDocumentExtension, getDocumentHasPreview } from './helpers/documentInfo';\nimport {\n getMediaTransferState,\n getMessageMediaHash,\n getMessageMediaThumbDataUri,\n isMessageDocumentVideo,\n} from '../../modules/helpers';\nimport { ObserveFn, useIsIntersecting } from '../../hooks/useIntersectionObserver';\nimport useMediaWithDownloadProgress from '../../hooks/useMediaWithDownloadProgress';\nimport useMedia from '../../hooks/useMedia';\nimport download from '../../util/download';\n\nimport File from './File';\n\ntype OwnProps = {\n message: ApiMessage;\n observeIntersection?: ObserveFn;\n smaller?: boolean;\n isSelected?: boolean;\n isSelectable?: boolean;\n uploadProgress?: number;\n withDate?: boolean;\n datetime?: number;\n className?: string;\n sender?: string;\n onCancelUpload?: () => void;\n onMediaClick?: () => void;\n onDateClick?: (messageId: number, chatId: number) => void;\n};\n\nconst Document: FC<OwnProps> = ({\n message,\n observeIntersection,\n smaller,\n uploadProgress,\n withDate,\n datetime,\n className,\n sender,\n isSelected,\n isSelectable,\n onCancelUpload,\n onMediaClick,\n onDateClick,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const document = message.content.document!;\n const extension = getDocumentExtension(document) || '';\n const { fileName, size, timestamp } = document;\n const withMediaViewer = onMediaClick && Boolean(document.mediaType);\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n\n const [isDownloadAllowed, setIsDownloadAllowed] = useState(false);\n const {\n mediaData, downloadProgress,\n } = useMediaWithDownloadProgress<ApiMediaFormat.BlobUrl>(\n getMessageMediaHash(message, 'download'), !isDownloadAllowed, undefined, undefined, undefined, true,\n );\n const {\n isUploading, isTransferring, transferProgress,\n } = getMediaTransferState(message, uploadProgress || downloadProgress, isDownloadAllowed);\n\n const hasPreview = getDocumentHasPreview(document);\n const thumbDataUri = hasPreview ? getMessageMediaThumbDataUri(message) : undefined;\n const localBlobUrl = hasPreview ? document.previewBlobUrl : undefined;\n const previewData = useMedia(getMessageMediaHash(message, 'pictogram'), !isIntersecting);\n\n const handleClick = useCallback(() => {\n if (withMediaViewer) {\n onMediaClick!();\n } else if (isUploading) {\n if (onCancelUpload) {\n onCancelUpload();\n }\n } else {\n setIsDownloadAllowed((isAllowed) => !isAllowed);\n }\n }, [withMediaViewer, isUploading, onCancelUpload, onMediaClick]);\n\n const handleDateClick = useCallback(() => {\n onDateClick!(message.id, message.chatId);\n }, [onDateClick, message.id, message.chatId]);\n\n useEffect(() => {\n if (isDownloadAllowed && mediaData) {\n download(mediaData, fileName);\n setIsDownloadAllowed(false);\n }\n }, [fileName, mediaData, isDownloadAllowed]);\n\n return (\n <File\n ref={ref}\n name={fileName}\n extension={extension}\n size={size}\n timestamp={withDate ? datetime || timestamp : undefined}\n thumbnailDataUri={thumbDataUri}\n previewData={localBlobUrl || previewData}\n smaller={smaller}\n isTransferring={isTransferring}\n isUploading={isUploading}\n transferProgress={transferProgress}\n className={className}\n sender={sender}\n isSelectable={isSelectable}\n isSelected={isSelected}\n actionIcon={withMediaViewer ? (isMessageDocumentVideo(message) ? 'icon-play' : 'icon-eye') : 'icon-download'}\n onClick={handleClick}\n onDateClick={onDateClick ? handleDateClick : undefined}\n />\n );\n};\n\nexport default memo(Document);\n","import { RefObject } from 'react';\nimport React, { FC, memo, useRef } from '../../lib/teact/teact';\n\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useTransitionForMedia from '../../hooks/useTransitionForMedia';\nimport buildClassName from '../../util/buildClassName';\nimport { formatMediaDateTime, formatPastTimeShort } from '../../util/dateFormat';\nimport { getColorFromExtension, getFileSizeString } from './helpers/documentInfo';\nimport { getDocumentThumbnailDimensions } from './helpers/mediaDimensions';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport ProgressSpinner from '../ui/ProgressSpinner';\nimport Link from '../ui/Link';\n\nimport './File.scss';\n\ntype OwnProps = {\n ref?: RefObject<HTMLDivElement>;\n name: string;\n extension?: string;\n size: number;\n timestamp?: number;\n sender?: string;\n thumbnailDataUri?: string;\n previewData?: string;\n className?: string;\n smaller?: boolean;\n isTransferring?: boolean;\n isUploading?: boolean;\n isSelectable?: boolean;\n isSelected?: boolean;\n transferProgress?: number;\n actionIcon?: string;\n onClick?: () => void;\n onDateClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;\n};\n\nconst File: FC<OwnProps> = ({\n ref,\n name,\n size,\n extension = '',\n timestamp,\n sender,\n thumbnailDataUri,\n previewData,\n className,\n smaller,\n isTransferring,\n isUploading,\n isSelectable,\n isSelected,\n transferProgress,\n actionIcon,\n onClick,\n onDateClick,\n}) => {\n const lang = useLang();\n // eslint-disable-next-line no-null/no-null\n let elementRef = useRef<HTMLDivElement>(null);\n if (ref) {\n elementRef = ref;\n }\n\n const {\n shouldRender: shouldSpinnerRender,\n transitionClassNames: spinnerClassNames,\n } = useShowTransition(isTransferring, undefined, true);\n const color = getColorFromExtension(extension);\n const sizeString = getFileSizeString(size);\n\n const {\n shouldRenderThumb, shouldRenderFullMedia, transitionClassNames,\n } = useTransitionForMedia(previewData, 'slow');\n const { width, height } = getDocumentThumbnailDimensions(smaller);\n\n const fullClassName = buildClassName(\n 'File',\n className,\n smaller && 'smaller',\n onClick && !isUploading && 'interactive',\n isSelected && 'file-is-selected',\n );\n\n return (\n <div ref={elementRef} className={fullClassName} dir={lang.isRtl ? 'rtl' : undefined}>\n {isSelectable && (\n <div className=\"message-select-control\">\n {isSelected && <i className=\"icon-select\" />}\n </div>\n )}\n <div className=\"file-icon-container\" onClick={isUploading ? undefined : onClick}>\n {thumbnailDataUri || previewData ? (\n <div className=\"file-preview media-inner\">\n {shouldRenderThumb && (\n <img\n src={thumbnailDataUri}\n width={width}\n height={height}\n className=\"thumbnail\"\n alt=\"\"\n />\n )}\n {shouldRenderFullMedia && (\n <img\n src={previewData}\n className={`full-media ${transitionClassNames}`}\n width={width}\n height={height}\n alt=\"\"\n />\n )}\n </div>\n ) : (\n <div className={`file-icon ${color}`}>\n {extension.length <= 4 && (\n <span className=\"file-ext\" dir=\"auto\">{extension}</span>\n )}\n </div>\n )}\n {shouldSpinnerRender && (\n <div className={buildClassName('file-progress', color, spinnerClassNames)}>\n <ProgressSpinner\n progress={transferProgress}\n size={smaller ? 's' : 'm'}\n onClick={isUploading ? onClick : undefined}\n />\n </div>\n )}\n {onClick && (\n <i\n className={buildClassName(\n 'action-icon',\n actionIcon || 'icon-download',\n shouldSpinnerRender && 'hidden',\n )}\n />\n )}\n </div>\n <div className=\"file-info\">\n <div className=\"file-title\" dir=\"auto\">{renderText(name)}</div>\n <div className=\"file-subtitle\" dir=\"auto\">\n <span>\n {isTransferring && transferProgress ? `${Math.round(transferProgress * 100)}%` : sizeString}\n </span>\n {sender && <span className=\"file-sender\">{renderText(sender)}</span>}\n {!sender && timestamp && (\n <>\n {' '}\n <Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000)}</Link>\n </>\n )}\n </div>\n </div>\n {sender && timestamp && (\n <Link onClick={onDateClick}>{formatPastTimeShort(lang, timestamp * 1000)}</Link>\n )}\n </div>\n );\n};\n\nexport default memo(File);\n","import { MouseEvent as ReactMouseEvent } from 'react';\nimport React, {\n FC, useEffect, useCallback, memo,\n} from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiChat, ApiTypingStatus } from '../../api/types';\nimport { GlobalActions, GlobalState } from '../../global/types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport {\n getChatTypeString,\n getChatTitle,\n isChatSuperGroup,\n} from '../../modules/helpers';\nimport { selectChat, selectChatMessages, selectChatOnlineCount } from '../../modules/selectors';\nimport renderText from './helpers/renderText';\nimport { pick } from '../../util/iteratees';\nimport useLang, { LangFn } from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\nimport VerifiedIcon from './VerifiedIcon';\nimport TypingStatus from './TypingStatus';\n\ntype OwnProps = {\n chatId: number;\n typingStatus?: ApiTypingStatus;\n avatarSize?: 'small' | 'medium' | 'large' | 'jumbo';\n withMediaViewer?: boolean;\n withUsername?: boolean;\n withFullInfo?: boolean;\n withUpdatingStatus?: boolean;\n withChatType?: boolean;\n noRtl?: boolean;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n onlineCount?: number;\n areMessagesLoaded: boolean;\n} & Pick<GlobalState, 'lastSyncTime'>;\n\ntype DispatchProps = Pick<GlobalActions, 'loadFullChat' | 'openMediaViewer'>;\n\nconst GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({\n typingStatus,\n avatarSize = 'medium',\n withMediaViewer,\n withUsername,\n withFullInfo,\n withUpdatingStatus,\n withChatType,\n noRtl,\n chat,\n onlineCount,\n areMessagesLoaded,\n lastSyncTime,\n loadFullChat,\n openMediaViewer,\n}) => {\n const isSuperGroup = chat && isChatSuperGroup(chat);\n const { id: chatId, isMin, isRestricted } = chat || {};\n\n useEffect(() => {\n if (chatId && !isMin && withFullInfo && lastSyncTime) {\n loadFullChat({ chatId });\n }\n }, [chatId, isMin, lastSyncTime, withFullInfo, loadFullChat, isSuperGroup]);\n\n const handleAvatarViewerOpen = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasPhoto: boolean) => {\n if (chat && hasPhoto) {\n e.stopPropagation();\n openMediaViewer({\n avatarOwnerId: chat.id,\n origin: avatarSize === 'jumbo' ? MediaViewerOrigin.ProfileAvatar : MediaViewerOrigin.MiddleHeaderAvatar,\n });\n }\n }, [chat, avatarSize, openMediaViewer]);\n\n const lang = useLang();\n\n if (!chat) {\n return undefined;\n }\n\n function renderStatusOrTyping() {\n if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {\n return (\n <span className=\"status\" dir=\"auto\">{lang('Updating')}</span>\n );\n }\n\n if (!chat) {\n return undefined;\n }\n\n if (typingStatus) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n if (withChatType) {\n return (\n <div className=\"status\" dir=\"auto\">{lang(getChatTypeString(chat))}</div>\n );\n }\n\n const handle = withUsername ? chat.username : undefined;\n const groupStatus = getGroupStatus(lang, chat);\n const onlineStatus = onlineCount ? `, ${lang('OnlineCount', onlineCount, 'i')}` : undefined;\n\n return (\n <div className=\"status\">\n {handle && <span className=\"handle\">{handle}</span>}\n <span className=\"group-status\">{groupStatus}</span>\n {onlineStatus && <span className=\"online-status\">{onlineStatus}</span>}\n </div>\n );\n }\n\n return (\n <div className=\"ChatInfo\" dir={!noRtl && lang.isRtl ? 'rtl' : undefined}>\n <Avatar\n key={chat.id}\n size={avatarSize}\n chat={chat}\n onClick={withMediaViewer ? handleAvatarViewerOpen : undefined}\n />\n <div className=\"info\">\n <div className=\"title\">\n <h3 dir=\"auto\">{renderText(getChatTitle(lang, chat))}</h3>\n {chat.isVerified && <VerifiedIcon />}\n </div>\n {renderStatusOrTyping()}\n </div>\n </div>\n );\n};\n\nfunction getGroupStatus(lang: LangFn, chat: ApiChat) {\n const chatTypeString = lang(getChatTypeString(chat));\n const { membersCount } = chat;\n\n if (chat.isRestricted) {\n return chatTypeString === 'Channel' ? 'channel is inaccessible' : 'group is inaccessible';\n }\n\n if (!membersCount) {\n return chatTypeString;\n }\n\n return chatTypeString === 'Channel'\n ? lang('Subscribers', membersCount, 'i')\n : lang('Members', membersCount, 'i');\n}\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatId }): StateProps => {\n const { lastSyncTime } = global;\n const chat = selectChat(global, chatId);\n const onlineCount = chat ? selectChatOnlineCount(global, chat) : undefined;\n const areMessagesLoaded = Boolean(selectChatMessages(global, chatId));\n\n return {\n lastSyncTime, chat, onlineCount, areMessagesLoaded,\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, ['loadFullChat', 'openMediaViewer']),\n)(GroupChatInfo));\n","import React, { FC, memo } from '../../lib/teact/teact';\n\nimport { ApiMessage, ApiMessageOutgoingStatus } from '../../api/types';\n\nimport { formatPastTimeShort } from '../../util/dateFormat';\nimport useLang from '../../hooks/useLang';\n\nimport MessageOutgoingStatus from './MessageOutgoingStatus';\n\nimport './LastMessageMeta.scss';\n\ntype OwnProps = {\n message: ApiMessage;\n outgoingStatus?: ApiMessageOutgoingStatus;\n};\n\nconst LastMessageMeta: FC<OwnProps> = ({ message, outgoingStatus }) => {\n const lang = useLang();\n return (\n <div className=\"LastMessageMeta\">\n {outgoingStatus && (\n <MessageOutgoingStatus status={outgoingStatus} />\n )}\n <span className=\"time\">{formatPastTimeShort(lang, message.date * 1000)}</span>\n </div>\n );\n};\n\nexport default memo(LastMessageMeta);\n","import React, { FC, memo, useCallback } from '../../lib/teact/teact';\n\nimport { ApiMessage } from '../../api/types';\n\nimport { formatMediaDuration } from '../../util/dateFormat';\nimport {\n getMessageMediaHash,\n getMessageMediaThumbDataUri,\n getMessageVideo,\n} from '../../modules/helpers';\nimport useMedia from '../../hooks/useMedia';\nimport useTransitionForMedia from '../../hooks/useTransitionForMedia';\n\nimport './Media.scss';\n\ntype OwnProps = {\n message: ApiMessage;\n idPrefix?: string;\n onClick?: (messageId: number, chatId: number) => void;\n};\n\nconst Media: FC<OwnProps> = ({ message, idPrefix = 'shared-media', onClick }) => {\n const handleClick = useCallback(() => {\n onClick!(message.id, message.chatId);\n }, [message.id, message.chatId, onClick]);\n\n const thumbDataUri = getMessageMediaThumbDataUri(message);\n const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram'));\n const {\n shouldRenderThumb, shouldRenderFullMedia, transitionClassNames,\n } = useTransitionForMedia(mediaBlobUrl, 'slow');\n\n const video = getMessageVideo(message);\n\n return (\n <div id={`${idPrefix}${message.id}`} className=\"Media scroll-item\" onClick={onClick ? handleClick : undefined}>\n {shouldRenderThumb && (\n <img src={thumbDataUri} alt=\"\" />\n )}\n {shouldRenderFullMedia && (\n <img src={mediaBlobUrl} className={`${transitionClassNames} full-media`} alt=\"\" />\n )}\n {video && <span className=\"video-duration\">{video.isGif ? 'GIF' : formatMediaDuration(video.duration)}</span>}\n </div>\n );\n};\n\nexport default memo(Media);\n","import React, { FC, memo } from '../../lib/teact/teact';\n\nimport { ApiMessageOutgoingStatus } from '../../api/types';\n\nimport Transition from '../ui/Transition';\n\nimport './MessageOutgoingStatus.scss';\n\ntype OwnProps = {\n status: ApiMessageOutgoingStatus;\n};\n\nenum Keys {\n failed, pending, succeeded, read,\n}\n\nconst MessageOutgoingStatus: FC<OwnProps> = ({ status }) => {\n return (\n <div className=\"MessageOutgoingStatus\">\n <Transition name=\"reveal\" activeKey={Keys[status]}>\n {() => (\n <i className={`icon-message-${status}`} />\n )}\n </Transition>\n </div>\n );\n};\n\nexport default memo(MessageOutgoingStatus);\n","import React, { FC, memo } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport './NothingFound.scss';\n\ninterface OwnProps {\n text?: string;\n description?: string;\n}\n\nconst DEFAULT_TEXT = 'Nothing found.';\n\nconst NothingFound: FC<OwnProps> = ({ text = DEFAULT_TEXT, description }) => {\n const lang = useLang();\n const { transitionClassNames } = useShowTransition(true);\n\n return (\n <div className={buildClassName('NothingFound', transitionClassNames, description && 'with-description')}>\n {text}\n {description && <p className=\"description\">{renderText(lang(description), ['br'])}</p>}\n </div>\n );\n};\n\nexport default memo(NothingFound);\n","import React, {\n FC, useCallback, useRef, useEffect, memo,\n} from '../../lib/teact/teact';\n\nimport { isChatPrivate } from '../../modules/helpers';\n\nimport InfiniteScroll from '../ui/InfiniteScroll';\nimport Checkbox from '../ui/Checkbox';\nimport InputText from '../ui/InputText';\nimport ListItem from '../ui/ListItem';\nimport PrivateChatInfo from './PrivateChatInfo';\nimport GroupChatInfo from './GroupChatInfo';\nimport PickerSelectedItem from './PickerSelectedItem';\nimport useInfiniteScroll from '../../hooks/useInfiniteScroll';\nimport useLang from '../../hooks/useLang';\n\nimport Loading from '../ui/Loading';\n\nimport './Picker.scss';\n\ntype OwnProps = {\n itemIds: number[];\n selectedIds: number[];\n filterValue?: string;\n filterPlaceholder?: string;\n notFoundText?: string;\n searchInputId?: string;\n isLoading?: boolean;\n noScrollRestore?: boolean;\n onSelectedIdsChange: (ids: number[]) => void;\n onFilterChange: (value: string) => void;\n onLoadMore?: () => void;\n};\n\n// Focus slows down animation, also it breaks transition layout in Chrome\nconst FOCUS_DELAY_MS = 500;\n\nconst MAX_FULL_ITEMS = 10;\nconst ALWAYS_FULL_ITEMS_COUNT = 5;\n\nconst Picker: FC<OwnProps> = ({\n itemIds,\n selectedIds,\n filterValue,\n filterPlaceholder,\n notFoundText,\n searchInputId,\n isLoading,\n noScrollRestore,\n onSelectedIdsChange,\n onFilterChange,\n onLoadMore,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const inputRef = useRef<HTMLInputElement>(null);\n const shouldMinimize = selectedIds.length > MAX_FULL_ITEMS;\n\n useEffect(() => {\n setTimeout(() => {\n requestAnimationFrame(() => {\n inputRef.current!.focus();\n });\n }, FOCUS_DELAY_MS);\n }, []);\n\n const handleItemClick = useCallback((id: number) => {\n const newSelectedIds = [...selectedIds];\n if (newSelectedIds.includes(id)) {\n newSelectedIds.splice(newSelectedIds.indexOf(id), 1);\n } else {\n newSelectedIds.push(id);\n }\n onSelectedIdsChange(newSelectedIds);\n onFilterChange('');\n }, [selectedIds, onSelectedIdsChange, onFilterChange]);\n\n const handleFilterChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const { value } = e.currentTarget;\n onFilterChange(value);\n }, [onFilterChange]);\n\n const [viewportIds, getMore] = useInfiniteScroll(onLoadMore, itemIds, Boolean(filterValue));\n\n const lang = useLang();\n\n return (\n <div className=\"Picker\">\n <div className=\"picker-header custom-scroll\" dir={lang.isRtl ? 'rtl' : undefined}>\n {selectedIds.map((id, i) => (\n <PickerSelectedItem\n chatOrUserId={id}\n isMinimized={shouldMinimize && i < selectedIds.length - ALWAYS_FULL_ITEMS_COUNT}\n canClose\n onClick={handleItemClick}\n clickArg={id}\n />\n ))}\n <InputText\n id={searchInputId}\n ref={inputRef}\n value={filterValue}\n onChange={handleFilterChange}\n placeholder={filterPlaceholder || lang('SelectChat')}\n />\n </div>\n\n {viewportIds && viewportIds.length ? (\n <InfiniteScroll\n className=\"picker-list custom-scroll\"\n items={viewportIds}\n onLoadMore={getMore}\n noScrollRestore={noScrollRestore}\n >\n {viewportIds.map((id) => (\n <ListItem\n key={id}\n className=\"chat-item-clickable picker-list-item\"\n onClick={() => handleItemClick(id)}\n ripple\n >\n <Checkbox label=\"\" checked={selectedIds.includes(id)} />\n {isChatPrivate(id) ? (\n <PrivateChatInfo userId={id} />\n ) : (\n <GroupChatInfo chatId={id} />\n )}\n </ListItem>\n ))}\n </InfiniteScroll>\n ) : !isLoading && viewportIds && !viewportIds.length ? (\n <p className=\"no-results\">{notFoundText || 'Sorry, nothing found.'}</p>\n ) : (\n <Loading />\n )}\n </div>\n );\n};\n\nexport default memo(Picker);\n","import React, { FC, memo } from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiChat, ApiUser } from '../../api/types';\n\nimport { selectChat, selectUser } from '../../modules/selectors';\nimport { getChatTitle, getUserFirstOrLastName, isChatPrivate } from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\n\nimport './PickerSelectedItem.scss';\n\ntype OwnProps = {\n chatOrUserId?: number;\n icon?: string;\n title?: string;\n isMinimized?: boolean;\n canClose?: boolean;\n onClick: (arg: any) => void;\n clickArg: any;\n className?: string;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n user?: ApiUser;\n};\n\nconst PickerSelectedItem: FC<OwnProps & StateProps> = ({\n icon,\n title,\n isMinimized,\n canClose,\n onClick,\n clickArg,\n chat,\n user,\n className,\n}) => {\n const lang = useLang();\n\n let iconElement: any;\n let titleText: any;\n\n if (icon && title) {\n iconElement = (\n <div className=\"item-icon\">\n <i className={`icon-${icon}`} />\n </div>\n );\n\n titleText = title;\n } else if (chat || user) {\n iconElement = (\n <Avatar\n chat={chat}\n user={user}\n size=\"small\"\n isSavedMessages={user && user.isSelf}\n />\n );\n\n const name = !chat || (user && !user.isSelf)\n ? getUserFirstOrLastName(user)\n : getChatTitle(lang, chat, user);\n\n titleText = name ? renderText(name) : undefined;\n }\n\n const fullClassName = buildClassName(\n 'PickerSelectedItem',\n className,\n isMinimized && 'minimized',\n canClose && 'closeable',\n );\n\n return (\n <div\n className={fullClassName}\n onClick={() => onClick(clickArg)}\n title={isMinimized ? titleText : undefined}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {iconElement}\n {!isMinimized && (\n <div className=\"item-name\" dir=\"auto\">\n {titleText}\n </div>\n )}\n {canClose && (\n <div className=\"item-remove\">\n <i className=\"icon-close\" />\n </div>\n )}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatOrUserId }): StateProps => {\n if (!chatOrUserId) {\n return {};\n }\n\n const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;\n const user = isChatPrivate(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;\n\n return {\n chat,\n user,\n };\n },\n)(PickerSelectedItem));\n","import { MouseEvent as ReactMouseEvent } from 'react';\nimport React, {\n FC, useEffect, useCallback, memo,\n} from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiUser, ApiTypingStatus } from '../../api/types';\nimport { GlobalActions, GlobalState } from '../../global/types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport { selectChatMessages, selectUser } from '../../modules/selectors';\nimport { getUserFullName, getUserStatus, isUserOnline } from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport { pick } from '../../util/iteratees';\nimport useLang from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\nimport VerifiedIcon from './VerifiedIcon';\nimport TypingStatus from './TypingStatus';\n\ntype OwnProps = {\n userId: number;\n typingStatus?: ApiTypingStatus;\n avatarSize?: 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';\n forceShowSelf?: boolean;\n status?: string;\n withMediaViewer?: boolean;\n withUsername?: boolean;\n withFullInfo?: boolean;\n withUpdatingStatus?: boolean;\n noStatusOrTyping?: boolean;\n noRtl?: boolean;\n};\n\ntype StateProps = {\n user?: ApiUser;\n isSavedMessages?: boolean;\n areMessagesLoaded: boolean;\n serverTimeOffset: number;\n} & Pick<GlobalState, 'lastSyncTime'>;\n\ntype DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'openMediaViewer'>;\n\nconst PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({\n typingStatus,\n avatarSize = 'medium',\n status,\n withMediaViewer,\n withUsername,\n withFullInfo,\n withUpdatingStatus,\n noStatusOrTyping,\n noRtl,\n user,\n isSavedMessages,\n areMessagesLoaded,\n lastSyncTime,\n loadFullUser,\n openMediaViewer,\n serverTimeOffset,\n}) => {\n const { id: userId } = user || {};\n const fullName = getUserFullName(user);\n\n useEffect(() => {\n if (withFullInfo && lastSyncTime && userId) {\n loadFullUser({ userId });\n }\n }, [userId, loadFullUser, lastSyncTime, withFullInfo]);\n\n const handleAvatarViewerOpen = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasPhoto: boolean) => {\n if (user && hasPhoto) {\n e.stopPropagation();\n openMediaViewer({\n avatarOwnerId: user.id,\n origin: avatarSize === 'jumbo' ? MediaViewerOrigin.ProfileAvatar : MediaViewerOrigin.MiddleHeaderAvatar,\n });\n }\n }, [user, avatarSize, openMediaViewer]);\n\n const lang = useLang();\n\n if (!user) {\n return undefined;\n }\n\n function renderStatusOrTyping() {\n if (status) {\n return (\n <span className=\"status\" dir=\"auto\">{status}</span>\n );\n }\n\n if (withUpdatingStatus && !areMessagesLoaded) {\n return (\n <span className=\"status\" dir=\"auto\">{lang('Updating')}</span>\n );\n }\n\n if (!user) {\n return undefined;\n }\n\n if (typingStatus) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n return (\n <div className={`status ${isUserOnline(user) ? 'online' : ''}`}>\n {withUsername && user.username && <span className=\"handle\">{user.username}</span>}\n <span className=\"user-status\" dir=\"auto\">{getUserStatus(lang, user, serverTimeOffset)}</span>\n </div>\n );\n }\n\n return (\n <div className=\"ChatInfo\" dir={!noRtl && lang.isRtl ? 'rtl' : undefined}>\n <Avatar\n key={user.id}\n size={avatarSize}\n user={user}\n isSavedMessages={isSavedMessages}\n onClick={withMediaViewer ? handleAvatarViewerOpen : undefined}\n />\n <div className=\"info\">\n {isSavedMessages ? (\n <div className=\"title\">\n <h3>{lang('SavedMessages')}</h3>\n </div>\n ) : (\n <div className=\"title\">\n <h3 dir=\"auto\">{fullName && renderText(fullName)}</h3>\n {user && user.isVerified && <VerifiedIcon />}\n </div>\n )}\n {(status || (!isSavedMessages && !noStatusOrTyping)) && renderStatusOrTyping()}\n </div>\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { userId, forceShowSelf }): StateProps => {\n const { lastSyncTime, serverTimeOffset } = global;\n const user = selectUser(global, userId);\n const isSavedMessages = !forceShowSelf && user && user.isSelf;\n const areMessagesLoaded = Boolean(selectChatMessages(global, userId));\n\n return {\n lastSyncTime, user, isSavedMessages, areMessagesLoaded, serverTimeOffset,\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, ['loadFullUser', 'openMediaViewer']),\n)(PrivateChatInfo));\n","import React, { FC, memo } from '../../lib/teact/teact';\n\nimport {\n ApiUser, ApiChat, ApiMediaFormat, ApiPhoto,\n} from '../../api/types';\n\nimport {\n getChatAvatarHash, isDeletedUser, getUserColorKey, getChatTitle, isChatPrivate, getUserFullName,\n} from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport buildClassName from '../../util/buildClassName';\nimport { getFirstLetters } from '../../util/textFormat';\nimport useMedia from '../../hooks/useMedia';\nimport useBlurSync from '../../hooks/useBlurSync';\nimport usePrevious from '../../hooks/usePrevious';\nimport useLang from '../../hooks/useLang';\n\nimport Spinner from '../ui/Spinner';\n\nimport './ProfilePhoto.scss';\n\ntype OwnProps = {\n chat?: ApiChat;\n user?: ApiUser;\n isFirstPhoto?: boolean;\n isSavedMessages?: boolean;\n photo?: ApiPhoto;\n lastSyncTime?: number;\n onClick: NoneToVoidFunction;\n};\n\nconst ProfilePhoto: FC<OwnProps> = ({\n chat,\n user,\n photo,\n isFirstPhoto,\n isSavedMessages,\n lastSyncTime,\n onClick,\n}) => {\n const lang = useLang();\n const isDeleted = user && isDeletedUser(user);\n\n function getMediaHash(size: 'normal' | 'big' = 'big', forceAvatar?: boolean) {\n if (photo && !forceAvatar) {\n return `photo${photo.id}?size=c`;\n }\n\n let hash: string | undefined;\n if (!isSavedMessages && !isDeleted) {\n if (user) {\n hash = getChatAvatarHash(user, size);\n } else if (chat) {\n hash = getChatAvatarHash(chat, size);\n }\n }\n\n return hash;\n }\n\n const imageHash = getMediaHash();\n const fullMediaData = useMedia(\n imageHash,\n false,\n imageHash?.startsWith('avatar') ? ApiMediaFormat.DataUri : ApiMediaFormat.BlobUrl,\n lastSyncTime,\n );\n const avatarThumbnailData = useMedia(\n !fullMediaData && isFirstPhoto ? getMediaHash('normal', true) : undefined,\n false,\n ApiMediaFormat.DataUri,\n lastSyncTime,\n );\n const thumbDataUri = useBlurSync(!fullMediaData && photo && photo.thumbnail && photo.thumbnail.dataUri);\n const imageSrc = fullMediaData || avatarThumbnailData || thumbDataUri;\n const prevImageSrc = usePrevious(imageSrc);\n\n let content: string | undefined = '';\n\n if (isSavedMessages) {\n content = <i className=\"icon-avatar-saved-messages\" />;\n } else if (isDeleted) {\n content = <i className=\"icon-avatar-deleted-account\" />;\n } else if (imageSrc) {\n content = <img src={imageSrc} className=\"avatar-media\" alt=\"\" decoding=\"async\" />;\n } else if (!imageSrc && user) {\n const userFullName = getUserFullName(user);\n content = userFullName ? getFirstLetters(userFullName, 2) : undefined;\n } else if (!imageSrc && chat) {\n const title = getChatTitle(lang, chat);\n content = title && getFirstLetters(title, isChatPrivate(chat.id) ? 2 : 1);\n } else {\n content = (\n <div className=\"spinner-wrapper\">\n <Spinner color=\"white\" />\n </div>\n );\n }\n\n const fullClassName = buildClassName(\n 'ProfilePhoto',\n `color-bg-${getUserColorKey(user || chat)}`,\n isSavedMessages && 'saved-messages',\n isDeleted && 'deleted-account',\n (!isSavedMessages && !(imageSrc)) && 'no-photo',\n );\n\n return (\n <div className={fullClassName} onClick={imageSrc ? onClick : undefined}>\n {prevImageSrc && imageSrc && prevImageSrc !== imageSrc && (\n <img src={prevImageSrc} className=\"prev-avatar-media\" alt=\"\" decoding=\"async\" />\n )}\n {typeof content === 'string' ? renderText(content, ['hq_emoji']) : content}\n </div>\n );\n};\n\nexport default memo(ProfilePhoto);\n","import React, {\n FC, useEffect, useCallback, memo, useState,\n} from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiUser, ApiChat } from '../../api/types';\nimport { GlobalActions, GlobalState } from '../../global/types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport { IS_TOUCH_ENV } from '../../util/environment';\nimport { selectChat, selectUser } from '../../modules/selectors';\nimport {\n getUserFullName, getUserStatus, isChatChannel, isUserOnline,\n} from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport { pick } from '../../util/iteratees';\nimport { captureEvents, SwipeDirection } from '../../util/captureEvents';\nimport buildClassName from '../../util/buildClassName';\nimport usePhotosPreload from './hooks/usePhotosPreload';\nimport useLang from '../../hooks/useLang';\n\nimport VerifiedIcon from './VerifiedIcon';\nimport ProfilePhoto from './ProfilePhoto';\nimport Transition from '../ui/Transition';\n\nimport './ProfileInfo.scss';\n\ntype OwnProps = {\n userId: number;\n forceShowSelf?: boolean;\n};\n\ntype StateProps = {\n user?: ApiUser;\n chat?: ApiChat;\n isSavedMessages?: boolean;\n animationLevel: 0 | 1 | 2;\n serverTimeOffset: number;\n} & Pick<GlobalState, 'connectionState'>;\n\ntype DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'openMediaViewer'>;\n\nconst ProfileInfo: FC<OwnProps & StateProps & DispatchProps> = ({\n forceShowSelf,\n user,\n chat,\n isSavedMessages,\n connectionState,\n animationLevel,\n loadFullUser,\n openMediaViewer,\n serverTimeOffset,\n}) => {\n const { id: userId } = user || {};\n const { id: chatId } = chat || {};\n const fullName = user ? getUserFullName(user) : (chat ? chat.title : '');\n const photos = (user ? user.photos : (chat ? chat.photos : undefined)) || [];\n const slideAnimation = animationLevel >= 1 ? 'slide' : 'none';\n\n const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);\n const isFirst = isSavedMessages || photos.length <= 1 || currentPhotoIndex === 0;\n const isLast = isSavedMessages || photos.length <= 1 || currentPhotoIndex === photos.length - 1;\n\n // Deleting the last profile photo may result in an error\n useEffect(() => {\n if (currentPhotoIndex > photos.length) {\n setCurrentPhotoIndex(Math.max(0, photos.length - 1));\n }\n }, [currentPhotoIndex, photos.length]);\n\n const lang = useLang();\n\n useEffect(() => {\n if (connectionState === 'connectionStateReady' && userId && !forceShowSelf) {\n loadFullUser({ userId });\n }\n }, [userId, loadFullUser, connectionState, forceShowSelf]);\n\n usePhotosPreload(user || chat, photos, currentPhotoIndex);\n\n const handleProfilePhotoClick = useCallback(() => {\n openMediaViewer({\n avatarOwnerId: userId || chatId,\n profilePhotoIndex: currentPhotoIndex,\n origin: forceShowSelf ? MediaViewerOrigin.SettingsAvatar : MediaViewerOrigin.ProfileAvatar,\n });\n }, [openMediaViewer, userId, chatId, currentPhotoIndex, forceShowSelf]);\n\n const selectPreviousMedia = useCallback(() => {\n if (isFirst) {\n return;\n }\n\n setCurrentPhotoIndex(currentPhotoIndex - 1);\n }, [currentPhotoIndex, isFirst]);\n\n const selectNextMedia = useCallback(() => {\n if (isLast) {\n return;\n }\n\n setCurrentPhotoIndex(currentPhotoIndex + 1);\n }, [currentPhotoIndex, isLast]);\n\n // Support for swipe gestures and closing on click\n useEffect(() => {\n const element = document.querySelector<HTMLDivElement>('.photo-wrapper');\n if (!element) {\n return undefined;\n }\n\n return captureEvents(element, {\n selectorToPreventScroll: '.Profile, .settings-content',\n onSwipe: IS_TOUCH_ENV ? (e, direction) => {\n if (direction === SwipeDirection.Right) {\n selectPreviousMedia();\n return true;\n } else if (direction === SwipeDirection.Left) {\n selectNextMedia();\n return true;\n }\n\n return false;\n } : undefined,\n });\n }, [selectNextMedia, selectPreviousMedia]);\n\n if (!user && !chat) {\n return undefined;\n }\n\n function renderPhotoTabs() {\n if (isSavedMessages || !photos || photos.length <= 1) {\n return undefined;\n }\n\n return (\n <div className=\"photo-dashes\">\n {photos.map((_, i) => (\n <span className={`photo-dash ${i === currentPhotoIndex ? 'current' : ''}`} />\n ))}\n </div>\n );\n }\n\n function renderPhoto() {\n const photo = !isSavedMessages && photos && photos.length > 0 ? photos[currentPhotoIndex] : undefined;\n\n return (\n <ProfilePhoto\n key={currentPhotoIndex}\n user={user}\n chat={chat}\n photo={photo}\n isSavedMessages={isSavedMessages}\n isFirstPhoto={isFirst}\n onClick={handleProfilePhotoClick}\n />\n );\n }\n\n function renderStatus() {\n if (user) {\n return (\n <div className={`status ${isUserOnline(user) ? 'online' : ''}`}>\n <span className=\"user-status\" dir=\"auto\">{getUserStatus(lang, user, serverTimeOffset)}</span>\n </div>\n );\n }\n\n return (\n <span className=\"status\" dir=\"auto\">{\n isChatChannel(chat!)\n ? lang('Subscribers', chat!.membersCount, 'i')\n : lang('Members', chat!.membersCount, 'i')\n }\n </span>\n );\n }\n\n const isVerifiedIconShown = (user && user.isVerified) || (chat && chat.isVerified);\n\n return (\n <div className={buildClassName('ProfileInfo', forceShowSelf && 'self')} dir={lang.isRtl ? 'rtl' : undefined}>\n <div className=\"photo-wrapper\">\n {renderPhotoTabs()}\n <Transition activeKey={currentPhotoIndex} name={slideAnimation} className=\"profile-slide-container\">\n {renderPhoto}\n </Transition>\n\n {!isFirst && (\n <button\n type=\"button\"\n className=\"navigation prev\"\n aria-label={lang('AccDescrPrevious')}\n onClick={selectPreviousMedia}\n />\n )}\n {!isLast && (\n <button\n type=\"button\"\n className=\"navigation next\"\n aria-label={lang('Next')}\n onClick={selectNextMedia}\n />\n )}\n </div>\n\n <div className=\"info\" dir={lang.isRtl ? 'rtl' : 'auto'}>\n {isSavedMessages ? (\n <div className=\"title\">\n <h3 dir=\"auto\">{lang('SavedMessages')}</h3>\n </div>\n ) : (\n <div className=\"title\">\n <h3 dir=\"auto\">{fullName && renderText(fullName)}</h3>\n {isVerifiedIconShown && <VerifiedIcon />}\n </div>\n )}\n {!isSavedMessages && renderStatus()}\n </div>\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { userId, forceShowSelf }): StateProps => {\n const { connectionState, serverTimeOffset } = global;\n const user = selectUser(global, userId);\n const chat = selectChat(global, userId);\n const isSavedMessages = !forceShowSelf && user && user.isSelf;\n const { animationLevel } = global.settings.byKey;\n\n return {\n connectionState, user, chat, isSavedMessages, animationLevel, serverTimeOffset,\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, ['loadFullUser', 'openMediaViewer']),\n)(ProfileInfo));\n","import {\n ApiChat, ApiMediaFormat, ApiPhoto, ApiUser,\n} from '../../../api/types';\nimport { useEffect } from '../../../lib/teact/teact';\nimport * as mediaLoader from '../../../util/mediaLoader';\n\nconst PHOTOS_TO_PRELOAD = 4;\n\nexport default function usePhotosPreload(\n profile: ApiUser | ApiChat | undefined,\n photos: ApiPhoto[],\n currentIndex: number,\n) {\n useEffect(() => {\n photos.slice(currentIndex, currentIndex + PHOTOS_TO_PRELOAD).forEach((photo) => {\n const mediaData = mediaLoader.getFromMemory(`photo${photo.id}?size=c`);\n if (!mediaData) {\n mediaLoader.fetch(`photo${photo.id}?size=c`, ApiMediaFormat.BlobUrl);\n }\n });\n }, [currentIndex, photos]);\n}\n","import { MouseEvent as ReactMouseEvent } from 'react';\nimport React, {\n FC, memo, useEffect, useRef,\n} from '../../lib/teact/teact';\n\nimport { ApiMediaFormat, ApiSticker } from '../../api/types';\n\nimport { useIsIntersecting, ObserveFn } from '../../hooks/useIntersectionObserver';\nimport useMedia from '../../hooks/useMedia';\nimport useTransitionForMedia from '../../hooks/useTransitionForMedia';\nimport useFlag from '../../hooks/useFlag';\nimport buildClassName from '../../util/buildClassName';\n\nimport AnimatedSticker from './AnimatedSticker';\nimport Button from '../ui/Button';\n\nimport './StickerButton.scss';\n\ntype OwnProps = {\n sticker: ApiSticker;\n size: number;\n observeIntersection: ObserveFn;\n noAnimate?: boolean;\n title?: string;\n className?: string;\n onClick?: (arg: any) => void;\n clickArg?: any;\n onUnfaveClick?: (sticker: ApiSticker) => void;\n};\n\nconst StickerButton: FC<OwnProps> = ({\n sticker, size, observeIntersection, noAnimate, title, className, onClick, clickArg, onUnfaveClick,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const localMediaHash = `sticker${sticker.id}`;\n const stickerSelector = `sticker-button-${sticker.id}`;\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n\n const thumbDataUri = sticker.thumbnail ? sticker.thumbnail.dataUri : undefined;\n const previewBlobUrl = useMedia(`${localMediaHash}?size=m`, !isIntersecting, ApiMediaFormat.BlobUrl);\n\n const shouldPlay = isIntersecting && !noAnimate;\n const lottieData = useMedia(sticker.isAnimated && localMediaHash, !shouldPlay, ApiMediaFormat.Lottie);\n const [isAnimationLoaded, markLoaded, unmarkLoaded] = useFlag(Boolean(lottieData));\n const canAnimatedPlay = isAnimationLoaded && shouldPlay;\n\n const {\n shouldRenderThumb,\n shouldRenderFullMedia: shouldRenderPreview,\n transitionClassNames: previewTransitionClassNames,\n } = useTransitionForMedia(previewBlobUrl || canAnimatedPlay, 'slow');\n\n // To avoid flickering\n useEffect(() => {\n if (!shouldPlay) {\n unmarkLoaded();\n }\n }, [unmarkLoaded, shouldPlay]);\n\n function handleClick() {\n if (onClick) {\n onClick(clickArg);\n }\n }\n\n function handleUnfaveClick(e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) {\n e.stopPropagation();\n e.preventDefault();\n\n onUnfaveClick!(sticker);\n }\n\n const fullClassName = buildClassName(\n 'StickerButton',\n sticker.isAnimated && 'animated',\n stickerSelector,\n className,\n );\n\n const style = shouldRenderThumb && thumbDataUri ? `background-image: url('${thumbDataUri}');` : '';\n\n return (\n <div\n ref={ref}\n className={fullClassName}\n title={title || (sticker && sticker.emoji)}\n // @ts-ignore\n style={style}\n data-sticker-id={sticker.id}\n onClick={handleClick}\n >\n {shouldRenderPreview && !canAnimatedPlay && (\n // eslint-disable-next-line jsx-a11y/alt-text\n <img src={previewBlobUrl} className={previewTransitionClassNames} />\n )}\n {shouldPlay && lottieData && (\n <AnimatedSticker\n id={localMediaHash}\n animationData={lottieData}\n play\n size={size}\n isLowPriority\n onLoad={markLoaded}\n />\n )}\n {onUnfaveClick && (\n <Button\n className=\"sticker-unfave-button\"\n color=\"dark\"\n round\n onClick={handleUnfaveClick}\n >\n <i className=\"icon-close\" />\n </Button>\n )}\n </div>\n );\n};\n\nexport default memo(StickerButton);\n","import React, { FC, memo } from '../../lib/teact/teact';\nimport { OwnProps } from './StickerSetModal';\nimport { Bundles } from '../../util/moduleLoader';\n\nimport useModuleLoader from '../../hooks/useModuleLoader';\n\nconst StickerSetModalAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const StickerSetModal = useModuleLoader(Bundles.Extra, 'StickerSetModal', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return StickerSetModal ? <StickerSetModal {...props} /> : undefined;\n};\n\nexport default memo(StickerSetModalAsync);\n","import React, { FC, memo } from '../../lib/teact/teact';\nimport { withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiUser, ApiTypingStatus } from '../../api/types';\n\nimport { selectUser } from '../../modules/selectors';\nimport { getUserFirstOrLastName } from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport './TypingStatus.scss';\n\ntype OwnProps = {\n typingStatus: ApiTypingStatus;\n};\n\ntype StateProps = {\n typingUser?: ApiUser;\n};\n\nconst TypingStatus: FC<OwnProps & StateProps> = ({ typingStatus, typingUser }) => {\n const lang = useLang();\n const typingUserName = typingUser && !typingUser.isSelf && getUserFirstOrLastName(typingUser);\n\n return (\n <p className=\"typing-status\" dir={lang.isRtl ? 'rtl' : 'auto'}>\n {typingUserName && (\n <span className=\"sender-name\" dir=\"auto\">{renderText(typingUserName)}</span>\n )}\n {/* fix for translation \"username _is_ typing\" */}\n {lang(typingStatus.action).replace('{user}', '').trim()}\n <span className=\"ellipsis\" />\n </p>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { typingStatus }): StateProps => {\n if (!typingStatus.userId) {\n return {};\n }\n\n const typingUser = selectUser(global, typingStatus.userId);\n\n return { typingUser };\n },\n)(TypingStatus));\n","import React, { FC } from '../../lib/teact/teact';\n\nimport './VerifiedIcon.scss';\n\nconst VerifiedIcon: FC = () => {\n return (\n <span className=\"VerifiedIcon\" />\n );\n};\n\nexport default VerifiedIcon;\n","import React, { FC, memo, useCallback } from '../../lib/teact/teact';\n\nimport { ApiMessage, ApiWebPage } from '../../api/types';\n\nimport { getFirstLinkInMessage, getMessageSummaryText, getMessageWebPage } from '../../modules/helpers';\nimport buildClassName from '../../util/buildClassName';\nimport trimText from '../../util/trimText';\nimport renderText from './helpers/renderText';\nimport { formatPastTimeShort } from '../../util/dateFormat';\nimport useLang from '../../hooks/useLang';\n\nimport Media from './Media';\nimport Link from '../ui/Link';\nimport SafeLink from './SafeLink';\n\nimport './WebLink.scss';\n\nconst MAX_TEXT_LENGTH = 170; // symbols\n\ntype OwnProps = {\n message: ApiMessage;\n senderTitle?: string;\n onMessageClick: (messageId: number, chatId: number) => void;\n};\n\nconst WebLink: FC<OwnProps> = ({ message, senderTitle, onMessageClick }) => {\n const lang = useLang();\n\n let linkData: ApiWebPage | undefined = getMessageWebPage(message);\n\n if (!linkData) {\n const link = getFirstLinkInMessage(message);\n if (link) {\n const { url, domain } = link;\n const messageText = getMessageSummaryText(lang, message);\n\n linkData = {\n siteName: domain.replace(/^www./, ''),\n url: url.includes('://') ? url : url.includes('@') ? `mailto:${url}` : `http://${url}`,\n description: messageText !== url ? messageText : undefined,\n } as ApiWebPage;\n }\n }\n\n const handleMessageClick = useCallback(() => {\n onMessageClick(message.id, message.chatId);\n }, [onMessageClick, message.id, message.chatId]);\n\n if (!linkData) {\n return undefined;\n }\n\n const {\n siteName,\n url,\n displayUrl,\n title,\n description,\n photo,\n video,\n } = linkData;\n\n const truncatedDescription = !senderTitle && trimText(description, MAX_TEXT_LENGTH);\n\n const className = buildClassName(\n 'WebLink scroll-item',\n (!photo && !video) && 'without-media',\n );\n\n return (\n <div\n className={className}\n data-initial={(siteName || displayUrl)[0]}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {photo && (\n <Media message={message} />\n )}\n <div className=\"content\">\n <Link isRtl={lang.isRtl} className=\"site-title\" onClick={handleMessageClick}>\n {renderText(title || siteName || displayUrl)}\n </Link>\n {truncatedDescription && (\n <Link isRtl={lang.isRtl} className=\"site-description\" onClick={handleMessageClick}>\n {renderText(truncatedDescription)}\n </Link>\n )}\n <SafeLink\n url={url}\n className=\"site-name\"\n text=\"\"\n isRtl={lang.isRtl}\n >\n {url.replace('mailto:', '') || displayUrl}\n </SafeLink>\n {senderTitle && <div className=\"sender-name\">{renderText(senderTitle)}</div>}\n </div>\n {senderTitle && (\n <div className=\"message-date\">\n <Link\n className=\"date\"\n onClick={handleMessageClick}\n isRtl={lang.isRtl}\n >\n {formatPastTimeShort(lang, message.date * 1000)}\n </Link>\n </div>\n )}\n </div>\n );\n};\n\nexport default memo(WebLink);\n","import {\n ApiPhoto, ApiVideo, ApiSticker, ApiDimensions,\n} from '../../../api/types';\n\nimport { STICKER_SIZE_INLINE_DESKTOP_FACTOR, STICKER_SIZE_INLINE_MOBILE_FACTOR } from '../../../config';\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\nimport windowSize from '../../../util/windowSize';\nimport { getPhotoInlineDimensions, getVideoDimensions } from '../../../modules/helpers';\n\nexport const MEDIA_VIEWER_MEDIA_QUERY = '(max-height: 640px)';\nexport const REM = parseInt(getComputedStyle(document.documentElement).fontSize, 10);\nexport const ROUND_VIDEO_DIMENSIONS = 200;\nexport const AVATAR_FULL_DIMENSIONS = { width: 640, height: 640 };\nexport const LIKE_STICKER_ID = '1258816259753933';\n\nconst DEFAULT_MEDIA_DIMENSIONS: ApiDimensions = { width: 100, height: 100 };\nconst MOBILE_SCREEN_NO_AVATARS_MESSAGE_EXTRA_WIDTH_REM = 4.5;\nconst MOBILE_SCREEN_MESSAGE_EXTRA_WIDTH_REM = 7;\nconst MESSAGE_MAX_WIDTH_REM = 29;\nconst MESSAGE_OWN_MAX_WIDTH_REM = 30;\n\nlet cachedMaxWidthOwn: number | undefined;\nlet cachedMaxWidth: number | undefined;\nlet cachedMaxWidthNoAvatar: number | undefined;\n\nfunction getMaxMessageWidthRem(fromOwnMessage: boolean, noAvatars?: boolean) {\n const regularMaxWidth = fromOwnMessage ? MESSAGE_OWN_MAX_WIDTH_REM : MESSAGE_MAX_WIDTH_REM;\n if (!IS_SINGLE_COLUMN_LAYOUT) {\n return regularMaxWidth;\n }\n\n const { width: windowWidth } = windowSize.get();\n\n // @optimization Limitation: changing device screen width not supported\n if (!cachedMaxWidthOwn) {\n cachedMaxWidthOwn = Math.min(\n MESSAGE_OWN_MAX_WIDTH_REM,\n windowWidth / REM - MOBILE_SCREEN_NO_AVATARS_MESSAGE_EXTRA_WIDTH_REM,\n );\n }\n if (!cachedMaxWidth) {\n cachedMaxWidth = Math.min(\n MESSAGE_MAX_WIDTH_REM,\n windowWidth / REM - MOBILE_SCREEN_MESSAGE_EXTRA_WIDTH_REM,\n );\n }\n if (!cachedMaxWidthNoAvatar) {\n cachedMaxWidthNoAvatar = Math.min(\n MESSAGE_MAX_WIDTH_REM,\n windowWidth / REM - MOBILE_SCREEN_NO_AVATARS_MESSAGE_EXTRA_WIDTH_REM,\n );\n }\n\n return fromOwnMessage\n ? cachedMaxWidthOwn\n : (noAvatars ? cachedMaxWidthNoAvatar : cachedMaxWidth);\n}\n\nexport function getAvailableWidth(\n fromOwnMessage: boolean,\n isForwarded?: boolean,\n isWebPagePhoto?: boolean,\n noAvatars?: boolean,\n) {\n const extraPaddingRem = isForwarded || isWebPagePhoto ? 1.625 : 0;\n const availableWidthRem = getMaxMessageWidthRem(fromOwnMessage, noAvatars) - extraPaddingRem;\n\n return availableWidthRem * REM;\n}\n\nfunction getAvailableHeight(isGif?: boolean, aspectRatio?: number) {\n if (\n isGif && aspectRatio\n && aspectRatio >= 0.75 && aspectRatio <= 1.25\n ) {\n return 20 * REM;\n }\n\n return 27 * REM;\n}\n\nfunction calculateDimensionsForMessageMedia({\n width,\n height,\n fromOwnMessage,\n isForwarded,\n isWebPagePhoto,\n isGif,\n noAvatars,\n}: {\n width: number;\n height: number;\n fromOwnMessage: boolean;\n isForwarded?: boolean;\n isWebPagePhoto?: boolean;\n isGif?: boolean;\n noAvatars?: boolean;\n}): ApiDimensions {\n const aspectRatio = height / width;\n const availableWidth = getAvailableWidth(fromOwnMessage, isForwarded, isWebPagePhoto, noAvatars);\n const availableHeight = getAvailableHeight(isGif, aspectRatio);\n\n return calculateDimensions(availableWidth, availableHeight, width, height);\n}\n\nexport function getMediaViewerAvailableDimensions(withFooter: boolean, isVideo: boolean): ApiDimensions {\n const mql = window.matchMedia(MEDIA_VIEWER_MEDIA_QUERY);\n const { width: windowWidth, height: windowHeight } = windowSize.get();\n let occupiedHeightRem = isVideo && mql.matches ? 10 : 8.25;\n if (withFooter) {\n occupiedHeightRem = mql.matches ? 10 : 15;\n }\n\n return {\n width: windowWidth,\n height: windowHeight - occupiedHeightRem * REM,\n };\n}\n\nexport function calculateInlineImageDimensions(\n photo: ApiPhoto,\n fromOwnMessage: boolean,\n isForwarded?: boolean,\n isWebPagePhoto?: boolean,\n noAvatars?: boolean,\n) {\n const { width, height } = getPhotoInlineDimensions(photo) || DEFAULT_MEDIA_DIMENSIONS;\n\n return calculateDimensionsForMessageMedia({\n width,\n height,\n fromOwnMessage,\n isForwarded,\n isWebPagePhoto,\n noAvatars,\n });\n}\n\nexport function calculateVideoDimensions(\n video: ApiVideo,\n fromOwnMessage: boolean,\n isForwarded?: boolean,\n noAvatars?: boolean,\n) {\n const { width, height } = getVideoDimensions(video) || DEFAULT_MEDIA_DIMENSIONS;\n\n return calculateDimensionsForMessageMedia({\n width,\n height,\n fromOwnMessage,\n isForwarded,\n isGif: video.isGif,\n noAvatars,\n });\n}\n\nexport function getPictogramDimensions(): ApiDimensions {\n return {\n width: 2 * REM,\n height: 2 * REM,\n };\n}\n\nexport function getDocumentThumbnailDimensions(smaller?: boolean): ApiDimensions {\n if (smaller) {\n return {\n width: 3 * REM,\n height: 3 * REM,\n };\n }\n\n return {\n width: 3.375 * REM,\n height: 3.375 * REM,\n };\n}\n\nexport function getStickerDimensions(sticker: ApiSticker): ApiDimensions {\n const { width } = sticker;\n let { height } = sticker;\n\n // For some reason this sticker has some weird `height` value\n if (sticker.id === LIKE_STICKER_ID) {\n height = width;\n }\n\n const aspectRatio = (height && width) && height / width;\n const baseWidth = REM * (\n IS_SINGLE_COLUMN_LAYOUT\n ? STICKER_SIZE_INLINE_MOBILE_FACTOR\n : STICKER_SIZE_INLINE_DESKTOP_FACTOR\n );\n const calculatedHeight = aspectRatio ? baseWidth * aspectRatio : baseWidth;\n\n if (aspectRatio && calculatedHeight > baseWidth) {\n return {\n width: Math.round(baseWidth / aspectRatio),\n height: baseWidth,\n };\n }\n\n return {\n width: baseWidth,\n height: calculatedHeight,\n };\n}\n\nexport function calculateMediaViewerDimensions(\n { width, height }: ApiDimensions, withFooter: boolean, isVideo: boolean = false,\n): ApiDimensions {\n const { width: availableWidth, height: availableHeight } = getMediaViewerAvailableDimensions(withFooter, isVideo);\n\n return calculateDimensions(availableWidth, availableHeight, width, height);\n}\n\nexport function calculateDimensions(\n availableWidth: number,\n availableHeight: number,\n mediaWidth: number,\n mediaHeight: number,\n): ApiDimensions {\n const aspectRatio = mediaHeight / mediaWidth;\n const calculatedWidth = Math.min(mediaWidth, availableWidth);\n const calculatedHeight = Math.round(calculatedWidth * aspectRatio);\n\n if (calculatedHeight > availableHeight) {\n return {\n width: Math.round(availableHeight / aspectRatio),\n height: availableHeight,\n };\n }\n\n return {\n width: calculatedWidth,\n height: Math.round(calculatedWidth * aspectRatio),\n };\n}\n","import { MouseEvent } from 'react';\nimport React from '../../../lib/teact/teact';\nimport { getDispatch } from '../../../lib/teact/teactn';\n\nimport { ApiMessageEntity, ApiMessageEntityTypes, ApiMessage } from '../../../api/types';\n\nimport { getMessageText } from '../../../modules/helpers';\nimport renderText from './renderText';\n\nimport MentionLink from '../../middle/message/MentionLink';\nimport SafeLink from '../SafeLink';\n\nexport type TextPart = string | Element;\n\nexport function renderMessageText(message: ApiMessage, highlight?: string, shouldRenderHqEmoji?: boolean) {\n const formattedText = message.content.text;\n\n if (!formattedText || !formattedText.text) {\n const rawText = getMessageText(message);\n return rawText ? [rawText] : undefined;\n }\n const { text, entities } = formattedText;\n\n return renderTextWithEntities(text, entities, highlight, shouldRenderHqEmoji);\n}\n\ninterface IOrganizedEntity {\n entity: ApiMessageEntity;\n organizedIndexes: Set<number>;\n nestedEntities: IOrganizedEntity[];\n}\n\nfunction organizeEntity(\n entity: ApiMessageEntity,\n index: number,\n entities: ApiMessageEntity[],\n organizedEntityIndexes: Set<number>,\n): IOrganizedEntity | undefined {\n const { offset, length } = entity;\n const organizedIndexes = new Set([index]);\n\n if (organizedEntityIndexes.has(index)) {\n return undefined;\n }\n\n // Determine any nested entities inside current entity\n const nestedEntities: IOrganizedEntity[] = [];\n const parsedNestedEntities = entities\n .filter((e, i) => i > index && e.offset >= offset && e.offset < offset + length)\n .map((e) => organizeEntity(e, entities.indexOf(e), entities, organizedEntityIndexes))\n .filter<IOrganizedEntity>(Boolean as any);\n\n parsedNestedEntities.forEach((parsedEntity) => {\n let isChanged = false;\n\n parsedEntity.organizedIndexes.forEach((organizedIndex) => {\n if (!isChanged && !organizedIndexes.has(organizedIndex)) {\n isChanged = true;\n }\n\n organizedIndexes.add(organizedIndex);\n });\n\n if (isChanged) {\n nestedEntities.push(parsedEntity);\n }\n });\n\n return {\n entity,\n organizedIndexes,\n nestedEntities,\n };\n}\n\n// Organize entities in a tree-like structure to better represent how the text will be displayed\nfunction organizeEntities(entities: ApiMessageEntity[]) {\n const organizedEntityIndexes: Set<number> = new Set();\n const organizedEntities: IOrganizedEntity[] = [];\n\n entities.forEach((entity, index) => {\n if (organizedEntityIndexes.has(index)) {\n return;\n }\n\n const organizedEntity = organizeEntity(entity, index, entities, organizedEntityIndexes);\n if (organizedEntity) {\n organizedEntity.organizedIndexes.forEach((organizedIndex) => {\n organizedEntityIndexes.add(organizedIndex);\n });\n\n organizedEntities.push(organizedEntity);\n }\n });\n\n return organizedEntities;\n}\n\nexport function renderTextWithEntities(\n text: string,\n entities?: ApiMessageEntity[],\n highlight?: string,\n shouldRenderHqEmoji?: boolean,\n shouldRenderAsHtml?: boolean,\n) {\n if (!entities || !entities.length) {\n return renderMessagePart(text, highlight, shouldRenderHqEmoji, shouldRenderAsHtml);\n }\n\n const result: TextPart[] = [];\n let deleteLineBreakAfterPre = false;\n\n const organizedEntities = organizeEntities(entities);\n\n // Recursive function to render regular and nested entities\n function renderEntity(\n textPartStart: number,\n textPartEnd: number,\n organizedEntity: IOrganizedEntity,\n isLastEntity: boolean,\n ) {\n const renderResult: TextPart[] = [];\n const { entity, nestedEntities } = organizedEntity;\n const { offset, length, type } = entity;\n\n // Render text before the entity\n let textBefore = text.substring(textPartStart, offset);\n const textBeforeLength = textBefore.length;\n if (textBefore) {\n if (deleteLineBreakAfterPre && textBefore.length > 0 && textBefore[0] === '\\n') {\n textBefore = textBefore.substr(1);\n deleteLineBreakAfterPre = false;\n }\n if (textBefore) {\n renderResult.push(...renderMessagePart(\n textBefore, highlight, shouldRenderHqEmoji, shouldRenderAsHtml,\n ) as TextPart[]);\n }\n }\n\n const entityStartIndex = textPartStart + textBeforeLength;\n const entityEndIndex = entityStartIndex + length;\n\n let entityContent: TextPart = text.substring(offset, offset + length);\n const nestedEntityContent: TextPart[] = [];\n\n if (deleteLineBreakAfterPre && entityContent.length > 0 && entityContent[0] === '\\n') {\n entityContent = entityContent.substr(1);\n deleteLineBreakAfterPre = false;\n }\n\n if (type === ApiMessageEntityTypes.Pre) {\n deleteLineBreakAfterPre = true;\n }\n\n // Render nested entities, if any\n if (nestedEntities.length) {\n let nestedIndex = entityStartIndex;\n\n nestedEntities.forEach((nestedEntity, nestedEntityIndex) => {\n const {\n renderResult: nestedResult,\n entityEndIndex: nestedEntityEndIndex,\n } = renderEntity(\n nestedIndex,\n entityEndIndex,\n nestedEntity,\n nestedEntityIndex === nestedEntities.length - 1,\n );\n\n nestedEntityContent.push(...nestedResult);\n nestedIndex = nestedEntityEndIndex;\n });\n }\n\n // Render the entity itself\n const newEntity = shouldRenderAsHtml\n ? processEntityAsHtml(entity, entityContent, nestedEntityContent)\n : processEntity(entity, entityContent, nestedEntityContent);\n\n if (Array.isArray(newEntity)) {\n renderResult.push(...newEntity);\n } else {\n renderResult.push(newEntity);\n }\n\n // Render text after the entity, if it is the last entity in the text,\n // or the last nested entity inside of another entity\n if (isLastEntity && entityEndIndex < textPartEnd) {\n let textAfter = text.substring(entityEndIndex, textPartEnd);\n if (deleteLineBreakAfterPre && textAfter.length > 0 && textAfter[0] === '\\n') {\n textAfter = textAfter.substring(1);\n }\n if (textAfter) {\n renderResult.push(...renderMessagePart(\n textAfter, highlight, shouldRenderHqEmoji, shouldRenderAsHtml,\n ) as TextPart[]);\n }\n }\n\n return {\n renderResult,\n entityEndIndex,\n };\n }\n\n // Process highest-level entities\n let index = 0;\n\n organizedEntities.forEach((entity, arrayIndex) => {\n const { renderResult, entityEndIndex } = renderEntity(\n index,\n text.length,\n entity,\n arrayIndex === organizedEntities.length - 1,\n );\n\n result.push(...renderResult);\n index = entityEndIndex;\n });\n\n return result;\n}\n\nfunction processEntity(\n entity: ApiMessageEntity,\n entityContent: TextPart,\n nestedEntityContent: TextPart[],\n) {\n const entityText = typeof entityContent === 'string' && entityContent;\n const renderedContent = nestedEntityContent.length ? nestedEntityContent : entityContent;\n\n if (!entityText) {\n return renderMessagePart(renderedContent);\n }\n\n switch (entity.type) {\n case ApiMessageEntityTypes.Bold:\n return <strong>{renderMessagePart(renderedContent)}</strong>;\n case ApiMessageEntityTypes.Blockquote:\n return <blockquote>{renderMessagePart(renderedContent)}</blockquote>;\n case ApiMessageEntityTypes.BotCommand:\n return (\n <a\n onClick={handleBotCommandClick}\n className=\"text-entity-link\"\n dir=\"auto\"\n >\n {renderMessagePart(renderedContent)}\n </a>\n );\n case ApiMessageEntityTypes.Hashtag:\n return (\n <a\n onClick={handleHashtagClick}\n className=\"text-entity-link\"\n dir=\"auto\"\n >\n {renderMessagePart(renderedContent)}\n </a>\n );\n case ApiMessageEntityTypes.Cashtag:\n return (\n <a\n onClick={handleHashtagClick}\n className=\"text-entity-link\"\n dir=\"auto\"\n >\n {renderMessagePart(renderedContent)}\n </a>\n );\n case ApiMessageEntityTypes.Code:\n return <code className=\"text-entity-code\">{renderMessagePart(renderedContent)}</code>;\n case ApiMessageEntityTypes.Email:\n return (\n <a\n href={`mailto:${entityText}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-entity-link\"\n dir=\"auto\"\n >\n {renderMessagePart(renderedContent)}\n </a>\n );\n case ApiMessageEntityTypes.Italic:\n return <em>{renderMessagePart(renderedContent)}</em>;\n case ApiMessageEntityTypes.MentionName:\n return (\n <MentionLink userId={entity.userId}>\n {renderMessagePart(renderedContent)}\n </MentionLink>\n );\n case ApiMessageEntityTypes.Mention:\n return (\n <MentionLink username={entityText}>\n {renderMessagePart(renderedContent)}\n </MentionLink>\n );\n case ApiMessageEntityTypes.Phone:\n return (\n <a\n href={`tel:${entityText}`}\n className=\"text-entity-link\"\n dir=\"auto\"\n >\n {renderMessagePart(renderedContent)}\n </a>\n );\n case ApiMessageEntityTypes.Pre:\n return <pre className=\"text-entity-pre\">{renderMessagePart(renderedContent)}</pre>;\n case ApiMessageEntityTypes.Strike:\n return <del>{renderMessagePart(renderedContent)}</del>;\n case ApiMessageEntityTypes.TextUrl:\n case ApiMessageEntityTypes.Url:\n return (\n <SafeLink\n url={getLinkUrl(entityText, entity)}\n text={entityText}\n >\n {renderMessagePart(renderedContent)}\n </SafeLink>\n );\n case ApiMessageEntityTypes.Underline:\n return <ins>{renderMessagePart(renderedContent)}</ins>;\n default:\n return renderMessagePart(renderedContent);\n }\n}\n\nfunction renderMessagePart(\n content: TextPart | TextPart[],\n highlight?: string,\n shouldRenderHqEmoji?: boolean,\n shouldRenderAsHtml?: boolean,\n) {\n if (Array.isArray(content)) {\n const result: TextPart[] = [];\n\n content.forEach((c) => {\n result.push(...renderMessagePart(c, highlight, shouldRenderHqEmoji, shouldRenderAsHtml));\n });\n\n return result;\n }\n\n if (shouldRenderAsHtml) {\n return renderText(content, ['escape_html', 'emoji_html', 'br_html']);\n }\n\n const emojiFilter = shouldRenderHqEmoji ? 'hq_emoji' : 'emoji';\n\n if (highlight) {\n return renderText(content, [emojiFilter, 'br', 'highlight'], { highlight });\n } else {\n return renderText(content, [emojiFilter, 'br']);\n }\n}\n\nfunction getLinkUrl(entityContent: string, entity: ApiMessageEntity) {\n const { type, url } = entity;\n return type === ApiMessageEntityTypes.TextUrl && url ? url : entityContent;\n}\n\nfunction handleBotCommandClick(e: MouseEvent<HTMLAnchorElement>) {\n getDispatch().sendBotCommand({ command: e.currentTarget.innerText });\n}\n\nfunction handleHashtagClick(e: MouseEvent<HTMLAnchorElement>) {\n getDispatch().setLocalTextSearchQuery({ query: e.currentTarget.innerText });\n getDispatch().searchTextMessagesLocal();\n}\n\nfunction processEntityAsHtml(\n entity: ApiMessageEntity,\n entityContent: TextPart,\n nestedEntityContent: TextPart[],\n) {\n const rawEntityText = typeof entityContent === 'string' && entityContent;\n\n const renderedContent = nestedEntityContent.length\n ? nestedEntityContent.join('')\n : renderText(entityContent, ['escape_html', 'emoji_html', 'br_html']).join('');\n\n if (!rawEntityText) {\n return renderedContent;\n }\n\n switch (entity.type) {\n case ApiMessageEntityTypes.Bold:\n return `<b>${renderedContent}</b>`;\n case ApiMessageEntityTypes.Italic:\n return `<i>${renderedContent}</i>`;\n case ApiMessageEntityTypes.Underline:\n return `<u>${renderedContent}</u>`;\n case ApiMessageEntityTypes.Code:\n return `<code class=\"text-entity-code\">${renderedContent}</code>`;\n case ApiMessageEntityTypes.Pre:\n return `\\`\\`\\`<br/>${renderedContent}<br/>\\`\\`\\``;\n case ApiMessageEntityTypes.Strike:\n return `<del>${renderedContent}</del>`;\n case ApiMessageEntityTypes.MentionName:\n return `<a\n class=\"text-entity-link\"\n data-entity-type=\"${ApiMessageEntityTypes.MentionName}\"\n data-user-id=\"${entity.userId}\"\n contenteditable=\"false\"\n dir=\"auto\"\n >${renderedContent}</a>`;\n case ApiMessageEntityTypes.Url:\n case ApiMessageEntityTypes.TextUrl:\n return `<a\n class=\"text-entity-link\"\n href=${getLinkUrl(rawEntityText, entity)}\n data-entity-type=\"${entity.type}\"\n dir=\"auto\"\n >${renderedContent}</a>`;\n default:\n return renderedContent;\n }\n}\n","import { useCallback } from '../../../../lib/teact/teact';\n\nexport enum ChatAnimationTypes {\n Move,\n Opacity,\n None,\n}\n\nexport function useChatAnimationType(orderDiffById: Record<number, number>) {\n const movesUp = useCallback((id: number) => orderDiffById[id] < 0, [orderDiffById]);\n const movesDown = useCallback((id: number) => orderDiffById[id] > 0, [orderDiffById]);\n\n const orderDiffIds = Object.keys(orderDiffById).map(Number);\n const numberOfUp = orderDiffIds.filter(movesUp).length;\n const numberOfDown = orderDiffIds.filter(movesDown).length;\n\n return useCallback((chatId: number): ChatAnimationTypes => {\n const orderDiff = orderDiffById[chatId];\n\n if (orderDiff === 0) {\n return ChatAnimationTypes.None;\n }\n\n if (\n orderDiff === Infinity\n || orderDiff === -Infinity\n || (movesUp(chatId) && numberOfUp <= numberOfDown)\n || (movesDown(chatId) && numberOfDown < numberOfUp)\n ) {\n return ChatAnimationTypes.Opacity;\n }\n\n return ChatAnimationTypes.Move;\n }, [movesDown, movesUp, numberOfDown, numberOfUp, orderDiffById]);\n}\n","import React, { FC, memo } from '../../../lib/teact/teact';\n\nimport { ApiChat } from '../../../api/types';\n\nimport { formatIntegerCompact } from '../../../util/textFormat';\nimport buildClassName from '../../../util/buildClassName';\n\nimport ShowTransition from '../../ui/ShowTransition';\n\nimport './Badge.scss';\n\ntype OwnProps = {\n chat: ApiChat;\n isPinned?: boolean;\n isMuted?: boolean;\n};\n\nconst Badge: FC<OwnProps> = ({ chat, isPinned, isMuted }) => {\n const isShown = Boolean(chat.unreadCount || chat.hasUnreadMark || isPinned);\n const className = buildClassName(\n 'Badge',\n isMuted && 'muted',\n isPinned && 'pinned',\n Boolean(chat.unreadCount || chat.hasUnreadMark) && 'unread',\n );\n\n function renderContent() {\n if (chat.unreadCount) {\n if (chat.unreadMentionsCount) {\n return (\n <div className=\"Badge-wrapper\">\n <div className=\"Badge mention\">\n <i className=\"icon-mention\" />\n </div>\n <div className={className}>\n {formatIntegerCompact(chat.unreadCount)}\n </div>\n </div>\n );\n }\n\n return (\n <div className={className}>\n {formatIntegerCompact(chat.unreadCount)}\n </div>\n );\n } else if (chat.hasUnreadMark) {\n return (\n <div className={className} />\n );\n } else if (isPinned) {\n return (\n <div className={className}>\n <i className=\"icon-pinned-chat\" />\n </div>\n );\n }\n\n return undefined;\n }\n\n return (\n <ShowTransition isCustom className=\"Badge-transition\" isOpen={isShown}>\n {renderContent}\n </ShowTransition>\n );\n};\n\nexport default memo(Badge);\n","import React, {\n FC, memo, useCallback, useLayoutEffect, useMemo, useRef,\n} from '../../../lib/teact/teact';\nimport { withGlobal } from '../../../lib/teact/teactn';\n\nimport useLang, { LangFn } from '../../../hooks/useLang';\n\nimport { GlobalActions } from '../../../global/types';\nimport {\n ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus, ApiFormattedText, MAIN_THREAD_ID,\n} from '../../../api/types';\n\nimport { ANIMATION_END_DELAY } from '../../../config';\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\nimport {\n getChatTitle,\n isChatPrivate,\n isActionMessage,\n getPrivateChatUserId,\n getMessageAction,\n getMessageSenderName,\n isChatChannel,\n getMessageMediaHash,\n getMessageSummaryText,\n getMessageMediaThumbDataUri,\n getMessageVideo,\n getMessageSticker,\n selectIsChatMuted,\n getMessageRoundVideo,\n} from '../../../modules/helpers';\nimport {\n selectChat, selectUser, selectChatMessage, selectOutgoingStatus, selectDraft, selectCurrentMessageList,\n selectNotifySettings, selectNotifyExceptions,\n} from '../../../modules/selectors';\nimport { renderActionMessageText } from '../../common/helpers/renderActionMessageText';\nimport renderText from '../../common/helpers/renderText';\nimport { fastRaf } from '../../../util/schedulers';\nimport buildClassName from '../../../util/buildClassName';\nimport { pick } from '../../../util/iteratees';\nimport useEnsureMessage from '../../../hooks/useEnsureMessage';\nimport useChatContextActions from '../../../hooks/useChatContextActions';\nimport useFlag from '../../../hooks/useFlag';\nimport useMedia from '../../../hooks/useMedia';\nimport { ChatAnimationTypes } from './hooks';\n\nimport Avatar from '../../common/Avatar';\nimport VerifiedIcon from '../../common/VerifiedIcon';\nimport TypingStatus from '../../common/TypingStatus';\nimport LastMessageMeta from '../../common/LastMessageMeta';\nimport DeleteChatModal from '../../common/DeleteChatModal';\nimport ListItem from '../../ui/ListItem';\nimport Badge from './Badge';\n\nimport './Chat.scss';\n\ntype OwnProps = {\n style?: string;\n chatId: number;\n folderId?: number;\n orderDiff: number;\n animationType: ChatAnimationTypes;\n isPinned?: boolean;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n isMuted?: boolean;\n privateChatUser?: ApiUser;\n actionTargetUserIds?: number[];\n usersById?: Record<number, ApiUser>;\n actionTargetMessage?: ApiMessage;\n actionTargetChatId?: number;\n lastMessageSender?: ApiUser;\n lastMessageOutgoingStatus?: ApiMessageOutgoingStatus;\n draft?: ApiFormattedText;\n animationLevel?: number;\n isSelected?: boolean;\n canScrollDown?: boolean;\n lastSyncTime?: number;\n};\n\ntype DispatchProps = Pick<GlobalActions, 'openChat' | 'focusLastMessage'>;\n\nconst ANIMATION_DURATION = 200;\n\nconst Chat: FC<OwnProps & StateProps & DispatchProps> = ({\n style,\n chatId,\n folderId,\n orderDiff,\n animationType,\n isPinned,\n chat,\n isMuted,\n privateChatUser,\n actionTargetUserIds,\n usersById,\n lastMessageSender,\n lastMessageOutgoingStatus,\n actionTargetMessage,\n actionTargetChatId,\n draft,\n animationLevel,\n isSelected,\n canScrollDown,\n lastSyncTime,\n openChat,\n focusLastMessage,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();\n const [shouldRenderDeleteModal, markRenderDeleteModal, unmarkRenderDeleteModal] = useFlag();\n\n const { lastMessage, typingStatus } = chat || {};\n const isAction = lastMessage && isActionMessage(lastMessage);\n\n useEnsureMessage(chatId, isAction ? lastMessage!.replyToMessageId : undefined, actionTargetMessage);\n\n const mediaThumbnail = lastMessage && !getMessageSticker(lastMessage)\n ? getMessageMediaThumbDataUri(lastMessage)\n : undefined;\n const mediaBlobUrl = useMedia(lastMessage ? getMessageMediaHash(lastMessage, 'micro') : undefined);\n const isRoundVideo = Boolean(lastMessage && getMessageRoundVideo(lastMessage));\n\n const actionTargetUsers = useMemo(() => {\n return actionTargetUserIds\n ? actionTargetUserIds.map((userId) => usersById && usersById[userId]).filter<ApiUser>(Boolean as any)\n : undefined;\n }, [actionTargetUserIds, usersById]);\n\n // Sets animation excess values when `orderDiff` changes and then resets excess values to animate.\n useLayoutEffect(() => {\n const element = ref.current;\n\n if (animationLevel === 0 || !element) {\n return;\n }\n\n // TODO Refactor animation: create `useListAnimation` that owns `orderDiff` and `animationType`\n if (animationType === ChatAnimationTypes.Opacity) {\n element.style.opacity = '0';\n\n fastRaf(() => {\n element.classList.add('animate-opacity');\n element.style.opacity = '1';\n });\n } else if (animationType === ChatAnimationTypes.Move) {\n element.style.transform = `translate3d(0, ${-orderDiff * 100}%, 0)`;\n\n fastRaf(() => {\n element.classList.add('animate-transform');\n element.style.transform = '';\n });\n } else {\n return;\n }\n\n setTimeout(() => {\n fastRaf(() => {\n element.classList.remove('animate-opacity', 'animate-transform');\n element.style.opacity = '';\n element.style.transform = '';\n });\n }, ANIMATION_DURATION + ANIMATION_END_DELAY);\n }, [animationLevel, orderDiff, animationType]);\n\n const handleClick = useCallback(() => {\n openChat({ id: chatId, shouldReplaceHistory: true });\n\n if (isSelected && canScrollDown) {\n focusLastMessage();\n }\n }, [\n isSelected,\n canScrollDown,\n openChat,\n chatId,\n focusLastMessage,\n ]);\n\n function handleDelete() {\n markRenderDeleteModal();\n openDeleteModal();\n }\n\n const contextActions = useChatContextActions({\n chat,\n privateChatUser,\n handleDelete,\n folderId,\n isPinned,\n isMuted,\n });\n\n const lang = useLang();\n\n if (!chat) {\n return undefined;\n }\n\n function renderLastMessageOrTyping() {\n if (typingStatus && lastMessage && typingStatus.timestamp > lastMessage.date * 1000) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n if (draft && draft.text.length) {\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n <span className=\"draft\">{lang('Draft')}</span>\n {renderText(draft.text)}\n </p>\n );\n }\n\n if (!lastMessage) {\n return undefined;\n }\n\n if (isAction) {\n const actionOrigin = chat && (isChatChannel(chat) || lastMessage.senderId === lastMessage.chatId)\n ? chat\n : lastMessageSender;\n\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n {renderText(renderActionMessageText(\n lang,\n lastMessage,\n actionOrigin,\n actionTargetUsers,\n actionTargetMessage,\n actionTargetChatId,\n { asPlain: true },\n ) as string)}\n </p>\n );\n }\n\n const senderName = getMessageSenderName(lang, chatId, lastMessageSender);\n\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n {senderName && (\n <>\n <span className=\"sender-name\">{renderText(senderName)}</span>\n <span className=\"colon\">:</span>\n </>\n )}\n {renderMessageSummary(lang, lastMessage!, mediaBlobUrl || mediaThumbnail, isRoundVideo)}\n </p>\n );\n }\n\n const className = buildClassName(\n 'Chat chat-item-clickable',\n isChatPrivate(chatId) ? 'private' : 'group',\n isSelected && 'selected',\n );\n\n return (\n <ListItem\n ref={ref}\n className={className}\n style={style}\n ripple={!IS_SINGLE_COLUMN_LAYOUT}\n contextActions={contextActions}\n onClick={handleClick}\n >\n <div className=\"status\">\n <Avatar\n chat={chat}\n user={privateChatUser}\n withOnlineStatus\n isSavedMessages={privateChatUser && privateChatUser.isSelf}\n lastSyncTime={lastSyncTime}\n />\n </div>\n <div className=\"info\">\n <div className=\"title\">\n <h3>{renderText(getChatTitle(lang, chat, privateChatUser))}</h3>\n {chat.isVerified && <VerifiedIcon />}\n {isMuted && <i className=\"icon-muted-chat\" />}\n {chat.lastMessage && (\n <LastMessageMeta message={chat.lastMessage} outgoingStatus={lastMessageOutgoingStatus} />\n )}\n </div>\n <div className=\"subtitle\">\n {renderLastMessageOrTyping()}\n <Badge chat={chat} isPinned={isPinned} isMuted={isMuted} />\n </div>\n </div>\n {shouldRenderDeleteModal && (\n <DeleteChatModal\n isOpen={isDeleteModalOpen}\n onClose={closeDeleteModal}\n onCloseAnimationEnd={unmarkRenderDeleteModal}\n chat={chat}\n />\n )}\n </ListItem>\n );\n};\n\nfunction renderMessageSummary(lang: LangFn, message: ApiMessage, blobUrl?: string, isRoundVideo?: boolean) {\n if (!blobUrl) {\n return renderText(getMessageSummaryText(lang, message));\n }\n\n return (\n <span className=\"media-preview\">\n <img src={blobUrl} alt=\"\" className={isRoundVideo ? 'round' : undefined} />\n {getMessageVideo(message) && <i className=\"icon-play\" />}\n {renderText(getMessageSummaryText(lang, message, true))}\n </span>\n );\n}\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatId }): StateProps => {\n const chat = selectChat(global, chatId);\n if (!chat || !chat.lastMessage) {\n return {};\n }\n\n const { senderId, replyToMessageId, isOutgoing } = chat.lastMessage;\n const lastMessageSender = senderId ? selectUser(global, senderId) : undefined;\n const lastMessageAction = getMessageAction(chat.lastMessage);\n const actionTargetMessage = lastMessageAction && replyToMessageId\n ? selectChatMessage(global, chat.id, replyToMessageId)\n : undefined;\n const { targetUserIds: actionTargetUserIds, targetChatId: actionTargetChatId } = lastMessageAction || {};\n const privateChatUserId = getPrivateChatUserId(chat);\n const { byId: usersById } = global.users;\n const {\n chatId: currentChatId,\n threadId: currentThreadId,\n type: messageListType,\n } = selectCurrentMessageList(global) || {};\n const isSelected = chatId === currentChatId && currentThreadId === MAIN_THREAD_ID;\n\n return {\n chat,\n isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),\n lastMessageSender,\n actionTargetUserIds,\n actionTargetChatId,\n actionTargetMessage,\n draft: selectDraft(global, chatId, MAIN_THREAD_ID),\n animationLevel: global.settings.byKey.animationLevel,\n isSelected,\n canScrollDown: isSelected && messageListType === 'thread',\n lastSyncTime: global.lastSyncTime,\n ...(isOutgoing && { lastMessageOutgoingStatus: selectOutgoingStatus(global, chat.lastMessage) }),\n ...(privateChatUserId && { privateChatUser: selectUser(global, privateChatUserId) }),\n ...(actionTargetUserIds && { usersById }),\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, [\n 'openChat',\n 'focusLastMessage',\n ]),\n)(Chat));\n","import React, { FC, memo, useCallback } from '../../../lib/teact/teact';\nimport { withGlobal } from '../../../lib/teact/teactn';\n\nimport { ApiChatFolder, ApiSticker } from '../../../api/types';\nimport { SettingsScreens } from '../../../types';\nimport { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';\n\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\nimport { selectAnimatedEmoji, selectChatFolder } from '../../../modules/selectors';\nimport useLang from '../../../hooks/useLang';\n\nimport Button from '../../ui/Button';\nimport AnimatedEmoji from '../../common/AnimatedEmoji';\n\nimport './EmptyFolder.scss';\n\ntype OwnProps = {\n folderId?: number;\n folderType: 'all' | 'archived' | 'folder';\n foldersDispatch?: FolderEditDispatch;\n onScreenSelect?: (screen: SettingsScreens) => void;\n};\n\ntype StateProps = {\n chatFolder?: ApiChatFolder;\n animatedEmoji?: ApiSticker;\n};\n\nconst EmptyFolder: FC<OwnProps & StateProps> = ({\n chatFolder, animatedEmoji, foldersDispatch, onScreenSelect,\n}) => {\n const lang = useLang();\n\n const handleEditFolder = useCallback(() => {\n foldersDispatch!({ type: 'editFolder', payload: chatFolder });\n onScreenSelect!(SettingsScreens.FoldersEditFolderFromChatList);\n }, [chatFolder, foldersDispatch, onScreenSelect]);\n\n return (\n <div className=\"EmptyFolder\">\n <div className=\"sticker\">{animatedEmoji && <AnimatedEmoji sticker={animatedEmoji} />}</div>\n <h3 className=\"title\" dir=\"auto\">{lang('FilterNoChatsToDisplay')}</h3>\n <p className=\"description\" dir=\"auto\">\n {lang(chatFolder ? 'ChatList.EmptyChatListFilterText' : 'Chat.EmptyChat')}\n </p>\n {chatFolder && foldersDispatch && onScreenSelect && (\n <Button\n ripple={!IS_SINGLE_COLUMN_LAYOUT}\n fluid\n pill\n onClick={handleEditFolder}\n size=\"smaller\"\n isRtl={lang.isRtl}\n >\n <i className=\"icon-settings\" />\n {lang('ChatList.EmptyChatListEditFilter')}\n </Button>\n )}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>((global, { folderId, folderType }): StateProps => {\n const chatFolder = folderId && folderType === 'folder' ? selectChatFolder(global, folderId) : undefined;\n\n return {\n chatFolder,\n animatedEmoji: selectAnimatedEmoji(global, '📂'),\n };\n})(EmptyFolder));\n","import React, {\n FC, memo, useMemo, useCallback, useEffect,\n} from '../../../lib/teact/teact';\nimport { withGlobal } from '../../../lib/teact/teactn';\n\nimport { GlobalActions } from '../../../global/types';\nimport {\n ApiChat, ApiChatFolder, ApiUser,\n} from '../../../api/types';\nimport { NotifyException, NotifySettings, SettingsScreens } from '../../../types';\nimport { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';\n\nimport { ALL_CHATS_PRELOAD_DISABLED, CHAT_HEIGHT_PX, CHAT_LIST_SLICE } from '../../../config';\nimport { IS_ANDROID, IS_MAC_OS, IS_PWA } from '../../../util/environment';\nimport usePrevious from '../../../hooks/usePrevious';\nimport { mapValues, pick } from '../../../util/iteratees';\nimport { getChatOrder, prepareChatList, prepareFolderListIds } from '../../../modules/helpers';\nimport {\n selectChatFolder, selectNotifyExceptions, selectNotifySettings,\n} from '../../../modules/selectors';\nimport useInfiniteScroll from '../../../hooks/useInfiniteScroll';\nimport { useChatAnimationType } from './hooks';\n\nimport InfiniteScroll from '../../ui/InfiniteScroll';\nimport Loading from '../../ui/Loading';\nimport Chat from './Chat';\nimport EmptyFolder from './EmptyFolder';\n\ntype OwnProps = {\n folderType: 'all' | 'archived' | 'folder';\n folderId?: number;\n isActive: boolean;\n onScreenSelect?: (screen: SettingsScreens) => void;\n foldersDispatch?: FolderEditDispatch;\n};\n\ntype StateProps = {\n chatsById: Record<number, ApiChat>;\n usersById: Record<number, ApiUser>;\n chatFolder?: ApiChatFolder;\n listIds?: number[];\n orderedPinnedIds?: number[];\n lastSyncTime?: number;\n notifySettings: NotifySettings;\n notifyExceptions?: Record<number, NotifyException>;\n};\n\ntype DispatchProps = Pick<GlobalActions, 'loadMoreChats' | 'preloadTopChatMessages' | 'openChat' | 'openNextChat'>;\n\nenum FolderTypeToListType {\n 'all' = 'active',\n 'archived' = 'archived',\n}\n\nconst ChatList: FC<OwnProps & StateProps & DispatchProps> = ({\n folderType,\n folderId,\n isActive,\n chatFolder,\n chatsById,\n usersById,\n listIds,\n orderedPinnedIds,\n lastSyncTime,\n foldersDispatch,\n notifySettings,\n notifyExceptions,\n onScreenSelect,\n loadMoreChats,\n preloadTopChatMessages,\n openChat,\n openNextChat,\n}) => {\n const [currentListIds, currentPinnedIds] = useMemo(() => {\n return folderType === 'folder' && chatFolder\n ? prepareFolderListIds(chatsById, usersById, chatFolder, notifySettings, notifyExceptions)\n : [listIds, orderedPinnedIds];\n }, [folderType, chatFolder, chatsById, usersById, notifySettings, notifyExceptions, listIds, orderedPinnedIds]);\n\n const [orderById, orderedIds] = useMemo(() => {\n if (!currentListIds || (folderType === 'folder' && !chatFolder)) {\n return [];\n }\n const newChatArrays = prepareChatList(chatsById, currentListIds, currentPinnedIds, folderType);\n const singleList = [...newChatArrays.pinnedChats, ...newChatArrays.otherChats];\n const newOrderedIds = singleList.map(({ id }) => id);\n const newOrderById = singleList.reduce((acc, chat, i) => {\n acc[chat.id] = i;\n return acc;\n }, {} as Record<string, number>);\n\n return [newOrderById, newOrderedIds];\n }, [currentListIds, currentPinnedIds, folderType, chatFolder, chatsById]);\n\n const prevOrderById = usePrevious(orderById);\n\n const orderDiffById = useMemo(() => {\n if (!orderById || !prevOrderById) {\n return {};\n }\n\n return mapValues(orderById, (order, id) => {\n return order - (prevOrderById[id] !== undefined ? prevOrderById[id] : Infinity);\n });\n }, [orderById, prevOrderById]);\n\n const loadMoreOfType = useCallback(() => {\n loadMoreChats({ listType: folderType === 'archived' ? 'archived' : 'active' });\n }, [loadMoreChats, folderType]);\n\n const [viewportIds, getMore] = useInfiniteScroll(\n lastSyncTime ? loadMoreOfType : undefined,\n orderedIds,\n undefined,\n CHAT_LIST_SLICE,\n folderType === 'all' && !ALL_CHATS_PRELOAD_DISABLED,\n );\n\n // TODO Refactor to not call `prepareChatList` twice\n const chatArrays = viewportIds && prepareChatList(chatsById, viewportIds, currentPinnedIds, folderType);\n\n useEffect(() => {\n if (lastSyncTime && folderType === 'all') {\n preloadTopChatMessages();\n }\n }, [lastSyncTime, folderType, preloadTopChatMessages]);\n\n const getAnimationType = useChatAnimationType(orderDiffById);\n\n function renderChats() {\n const viewportOffset = orderedIds!.indexOf(viewportIds![0]);\n const pinnedOffset = viewportOffset + chatArrays!.pinnedChats.length;\n\n return (\n <div\n className=\"scroll-container\"\n // @ts-ignore\n style={IS_ANDROID ? `height: ${orderedIds!.length * CHAT_HEIGHT_PX}px` : undefined}\n teactFastList\n >\n {chatArrays!.pinnedChats.map(({ id }, i) => (\n <Chat\n key={id}\n teactOrderKey={i}\n chatId={id}\n isPinned\n folderId={folderId}\n animationType={getAnimationType(id)}\n orderDiff={orderDiffById[id]}\n // @ts-ignore\n style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}\n />\n ))}\n {chatArrays!.otherChats.map((chat, i) => (\n <Chat\n key={chat.id}\n teactOrderKey={getChatOrder(chat)}\n chatId={chat.id}\n folderId={folderId}\n animationType={getAnimationType(chat.id)}\n orderDiff={orderDiffById[chat.id]}\n // @ts-ignore\n style={`top: ${(pinnedOffset + i) * CHAT_HEIGHT_PX}px;`}\n />\n ))}\n </div>\n );\n }\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (isActive && orderedIds) {\n if (IS_PWA && ((IS_MAC_OS && e.metaKey) || (!IS_MAC_OS && e.ctrlKey)) && e.code.startsWith('Digit')) {\n const [, digit] = e.code.match(/Digit(\\d)/) || [];\n if (!digit) return;\n\n const position = Number(digit) - 1;\n if (position > orderedIds.length - 1) return;\n\n openChat({ id: orderedIds[position], shouldReplaceHistory: true });\n }\n\n if (e.altKey) {\n const targetIndexDelta = e.key === 'ArrowDown' ? 1 : e.key === 'ArrowUp' ? -1 : undefined;\n if (!targetIndexDelta) return;\n\n e.preventDefault();\n openNextChat({ targetIndexDelta, orderedIds });\n }\n }\n };\n\n document.addEventListener('keydown', handleKeyDown, false);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown, false);\n };\n });\n\n return (\n <InfiniteScroll\n className=\"chat-list custom-scroll\"\n items={viewportIds}\n onLoadMore={getMore}\n preloadBackwards={CHAT_LIST_SLICE}\n noFastList\n noScrollRestore\n >\n {viewportIds && viewportIds.length && chatArrays ? (\n renderChats()\n ) : viewportIds && !viewportIds.length ? (\n (\n <EmptyFolder\n folderId={folderId}\n folderType={folderType}\n foldersDispatch={foldersDispatch}\n onScreenSelect={onScreenSelect}\n />\n )\n ) : (\n <Loading key=\"loading\" />\n )}\n </InfiniteScroll>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { folderType, folderId }): StateProps => {\n const {\n chats: {\n listIds,\n byId: chatsById,\n orderedPinnedIds,\n },\n users: { byId: usersById },\n lastSyncTime,\n } = global;\n const listType = folderType !== 'folder' ? FolderTypeToListType[folderType] : undefined;\n const chatFolder = folderId ? selectChatFolder(global, folderId) : undefined;\n\n return {\n chatsById,\n usersById,\n lastSyncTime,\n notifySettings: selectNotifySettings(global),\n notifyExceptions: selectNotifyExceptions(global),\n ...(listType ? {\n listIds: listIds[listType],\n orderedPinnedIds: orderedPinnedIds[listType],\n } : {\n chatFolder,\n }),\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, [\n 'loadMoreChats',\n 'preloadTopChatMessages',\n 'openChat',\n 'openNextChat',\n ]),\n)(ChatList));\n","import React, { FC, memo } from '../../../lib/teact/teact';\n\nimport useFlag from '../../../hooks/useFlag';\nimport buildClassName from '../../../util/buildClassName';\n\nimport './DropTarget.scss';\n\nexport type OwnProps = {\n isQuick?: boolean;\n onFileSelect: (e: React.DragEvent<HTMLDivElement>) => void;\n};\n\nconst DropTarget: FC<OwnProps> = ({ isQuick, onFileSelect }) => {\n const [isHovered, markHovered, unmarkHovered] = useFlag();\n\n const handleDragEnter = () => { markHovered(); };\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {\n const { relatedTarget: toTarget } = e;\n\n if (toTarget) {\n e.stopPropagation();\n }\n\n unmarkHovered();\n };\n\n const className = buildClassName(\n 'DropTarget',\n isHovered && 'hovered',\n );\n\n return (\n <div\n className={className}\n onDrop={onFileSelect}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n >\n <div className=\"target-content\">\n <div className={`icon icon-${isQuick ? 'photo' : 'document'}`} />\n <div className=\"title\">Drop files here to send them</div>\n <div className=\"description\">{isQuick ? 'in a quick way' : 'without compression'}</div>\n </div>\n </div>\n );\n};\n\nexport default memo(DropTarget);\n","import React, {\n FC, memo, useCallback, useEffect, useRef,\n} from '../../../lib/teact/teact';\n\nimport useShowTransition from '../../../hooks/useShowTransition';\nimport buildClassName from '../../../util/buildClassName';\n\nimport captureEscKeyListener from '../../../util/captureEscKeyListener';\nimport usePrevious from '../../../hooks/usePrevious';\n\nimport DropTarget from './DropTarget';\n\nimport './DropArea.scss';\n\nexport type OwnProps = {\n isOpen: boolean;\n withQuick?: boolean;\n onHide: NoneToVoidFunction;\n onFileSelect: (files: File[], isQuick: boolean) => void;\n};\n\nexport enum DropAreaState {\n None = 'none',\n Document = 'document',\n QuickFile = 'quick_file',\n}\n\nconst DROP_LEAVE_TIMEOUT_MS = 150;\n\nconst DropArea: FC<OwnProps> = ({\n isOpen, withQuick, onHide, onFileSelect,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const hideTimeoutRef = useRef<number>(null);\n const prevWithQuick = usePrevious(withQuick);\n const { shouldRender, transitionClassNames } = useShowTransition(isOpen);\n\n useEffect(() => (isOpen ? captureEscKeyListener(onHide) : undefined), [isOpen, onHide]);\n\n const handleFilesDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n const { dataTransfer: dt } = e;\n\n if (dt.files && dt.files.length > 0) {\n onHide();\n onFileSelect(Array.from(dt.files), false);\n }\n }, [onFileSelect, onHide]);\n\n const handleQuickFilesDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n const { dataTransfer: dt } = e;\n\n if (dt.files && dt.files.length > 0) {\n onHide();\n onFileSelect(Array.from(dt.files), true);\n }\n }, [onFileSelect, onHide]);\n\n const handleDragLeave = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.stopPropagation();\n\n const { target: fromTarget, relatedTarget: toTarget } = e;\n\n // Esc button pressed during drag event\n if ((fromTarget as HTMLDivElement).matches('.DropTarget, .DropArea') && !toTarget) {\n hideTimeoutRef.current = window.setTimeout(() => {\n onHide();\n }, DROP_LEAVE_TIMEOUT_MS);\n }\n }, [onHide]);\n\n const handleDragOver = () => {\n if (hideTimeoutRef.current) {\n window.clearTimeout(hideTimeoutRef.current);\n }\n };\n\n if (!shouldRender) {\n return undefined;\n }\n\n const className = buildClassName(\n 'DropArea',\n transitionClassNames,\n );\n\n return (\n <div className={className} onDragLeave={handleDragLeave} onDragOver={handleDragOver} onDrop={onHide}>\n <DropTarget onFileSelect={handleFilesDrop} />\n {(withQuick || prevWithQuick) && <DropTarget onFileSelect={handleQuickFilesDrop} isQuick />}\n </div>\n );\n};\n\nexport default memo(DropArea);\n","import React, { FC, memo } from '../../../lib/teact/teact';\nimport { OwnProps } from './EmojiTooltip';\nimport { Bundles } from '../../../util/moduleLoader';\n\nimport useModuleLoader from '../../../hooks/useModuleLoader';\n\nconst EmojiTooltipAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const EmojiTooltip = useModuleLoader(Bundles.Extra, 'EmojiTooltip', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return EmojiTooltip ? <EmojiTooltip {...props} /> : undefined;\n};\n\nexport default memo(EmojiTooltipAsync);\n","import { ChangeEvent } from 'react';\nimport React, {\n FC, useEffect, useRef, memo, useState, useCallback,\n} from '../../../lib/teact/teact';\nimport { withGlobal } from '../../../lib/teact/teactn';\n\nimport { GlobalActions } from '../../../global/types';\nimport { IAnchorPosition, ISettings } from '../../../types';\n\nimport { EDITABLE_INPUT_ID } from '../../../config';\nimport { selectCurrentMessageList, selectReplyingToId } from '../../../modules/selectors';\nimport { debounce } from '../../../util/schedulers';\nimport focusEditableElement from '../../../util/focusEditableElement';\nimport buildClassName from '../../../util/buildClassName';\nimport { pick } from '../../../util/iteratees';\nimport {\n IS_ANDROID, IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV,\n} from '../../../util/environment';\nimport captureKeyboardListeners from '../../../util/captureKeyboardListeners';\nimport useLayoutEffectWithPrevDeps from '../../../hooks/useLayoutEffectWithPrevDeps';\nimport useFlag from '../../../hooks/useFlag';\nimport parseEmojiOnlyString from '../../common/helpers/parseEmojiOnlyString';\nimport { isSelectionInsideInput } from './helpers/selection';\nimport useLang from '../../../hooks/useLang';\nimport renderText from '../../common/helpers/renderText';\n\nimport TextFormatter from './TextFormatter';\n\nconst CONTEXT_MENU_CLOSE_DELAY_MS = 100;\n// Focus slows down animation, also it breaks transition layout in Chrome\nconst FOCUS_DELAY_MS = 350;\nconst TRANSITION_DURATION_FACTOR = 50;\n\ntype OwnProps = {\n id: string;\n isAttachmentModalInput?: boolean;\n editableInputId?: string;\n html: string;\n placeholder: string;\n forcedPlaceholder?: string;\n shouldSetFocus: boolean;\n shouldSuppressFocus?: boolean;\n shouldSuppressTextFormatter?: boolean;\n onUpdate: (html: string) => void;\n onSuppressedFocus?: () => void;\n onSend: () => void;\n};\n\ntype StateProps = {\n currentChatId?: number;\n replyingToId?: number;\n noTabCapture?: boolean;\n messageSendKeyCombo?: ISettings['messageSendKeyCombo'];\n};\n\ntype DispatchProps = Pick<GlobalActions, 'editLastMessage' | 'replyToNextMessage'>;\n\nconst MAX_INPUT_HEIGHT = IS_SINGLE_COLUMN_LAYOUT ? 256 : 416;\nconst TAB_INDEX_PRIORITY_TIMEOUT = 2000;\nconst TEXT_FORMATTER_SAFE_AREA_PX = 90;\n// For some reason Safari inserts `<br>` after user removes text from input\nconst SAFARI_BR = '<br>';\n\nfunction clearSelection() {\n const selection = window.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.removeAllRanges) {\n selection.removeAllRanges();\n } else if (selection.empty) {\n selection.empty();\n }\n}\n\nconst MessageInput: FC<OwnProps & StateProps & DispatchProps> = ({\n id,\n isAttachmentModalInput,\n editableInputId,\n html,\n placeholder,\n forcedPlaceholder,\n shouldSetFocus,\n shouldSuppressFocus,\n shouldSuppressTextFormatter,\n onUpdate,\n onSuppressedFocus,\n onSend,\n currentChatId,\n replyingToId,\n noTabCapture,\n messageSendKeyCombo,\n editLastMessage,\n replyToNextMessage,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const inputRef = useRef<HTMLDivElement>(null);\n // eslint-disable-next-line no-null/no-null\n const cloneRef = useRef<HTMLDivElement>(null);\n\n const lang = useLang();\n const isContextMenuOpenRef = useRef(false);\n const [isTextFormatterOpen, openTextFormatter, closeTextFormatter] = useFlag();\n const [textFormatterAnchorPosition, setTextFormatterAnchorPosition] = useState<IAnchorPosition>();\n const [selectedRange, setSelectedRange] = useState<Range>();\n\n useEffect(() => {\n if (!isAttachmentModalInput) return;\n updateInputHeight(false);\n }, [isAttachmentModalInput]);\n\n useLayoutEffectWithPrevDeps(([prevHtml]) => {\n if (html !== inputRef.current!.innerHTML) {\n inputRef.current!.innerHTML = html;\n }\n\n if (html !== cloneRef.current!.innerHTML) {\n cloneRef.current!.innerHTML = html;\n }\n\n if (prevHtml !== undefined && prevHtml !== html) {\n updateInputHeight(!html.length);\n }\n }, [html]);\n\n const focusInput = useCallback(() => {\n // Avoid focusing during animation\n if (inputRef.current!.closest('.from, .to')) {\n setTimeout(focusInput, FOCUS_DELAY_MS);\n return;\n }\n\n focusEditableElement(inputRef.current!);\n }, []);\n\n const handleCloseTextFormatter = useCallback(() => {\n closeTextFormatter();\n clearSelection();\n }, [closeTextFormatter]);\n\n function checkSelection() {\n // Disable the formatter on iOS devices for now.\n if (IS_IOS) {\n return;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount || isContextMenuOpenRef.current) {\n closeTextFormatter();\n return;\n }\n\n const selectionRange = selection.getRangeAt(0);\n const selectedText = selectionRange.toString().trim();\n if (\n shouldSuppressTextFormatter\n || !isSelectionInsideInput(selectionRange, editableInputId || EDITABLE_INPUT_ID)\n || !selectedText\n || parseEmojiOnlyString(selectedText)\n || !selectionRange.START_TO_END\n ) {\n closeTextFormatter();\n return;\n }\n\n const selectionRect = selectionRange.getBoundingClientRect();\n const inputRect = inputRef.current!.getBoundingClientRect();\n\n let x = (selectionRect.left + selectionRect.width / 2) - inputRect.left;\n\n if (x < TEXT_FORMATTER_SAFE_AREA_PX) {\n x = TEXT_FORMATTER_SAFE_AREA_PX;\n } else if (x > inputRect.width - TEXT_FORMATTER_SAFE_AREA_PX) {\n x = inputRect.width - TEXT_FORMATTER_SAFE_AREA_PX;\n }\n\n setTextFormatterAnchorPosition({\n x,\n y: selectionRect.top - inputRect.top,\n });\n\n setSelectedRange(selectionRange);\n openTextFormatter();\n }\n\n function handleMouseDown(event: React.MouseEvent<HTMLDivElement, MouseEvent>) {\n function handleMouseUp() {\n checkSelection();\n\n event.target.removeEventListener('mouseup', handleMouseUp);\n }\n\n if (event.button !== 2) {\n event.target.addEventListener('mouseup', handleMouseUp);\n return;\n }\n\n if (isContextMenuOpenRef.current === true) {\n return;\n }\n\n isContextMenuOpenRef.current = true;\n\n function closeContextMenuMouseListener() {\n setTimeout(() => {\n isContextMenuOpenRef.current = false;\n }, CONTEXT_MENU_CLOSE_DELAY_MS);\n\n window.removeEventListener('mouseup', closeContextMenuMouseListener);\n }\n\n function closeContextMenuKeyListener(e: KeyboardEvent) {\n if (e.key !== 'Esc' && e.key !== 'Escape') {\n return;\n }\n\n setTimeout(() => {\n isContextMenuOpenRef.current = false;\n }, CONTEXT_MENU_CLOSE_DELAY_MS);\n\n window.removeEventListener('keydown', closeContextMenuKeyListener);\n }\n\n document.addEventListener('mousedown', closeContextMenuMouseListener);\n document.addEventListener('keydown', closeContextMenuKeyListener);\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {\n function handleKeyUp() {\n checkSelection();\n\n e.target.removeEventListener('keyup', handleKeyUp);\n }\n\n if (e.metaKey && !html.length) {\n const targetIndexDelta = e.key === 'ArrowDown' ? 1 : e.key === 'ArrowUp' ? -1 : undefined;\n if (targetIndexDelta) {\n e.preventDefault();\n\n replyToNextMessage({ targetIndexDelta });\n return;\n }\n }\n\n if (e.key === 'Enter' && !e.shiftKey) {\n if (\n !(IS_IOS || IS_ANDROID)\n && (\n (messageSendKeyCombo === 'enter' && !e.shiftKey)\n || (messageSendKeyCombo === 'ctrl-enter' && (e.ctrlKey || e.metaKey))\n )\n ) {\n e.preventDefault();\n\n closeTextFormatter();\n onSend();\n }\n } else if (e.key === 'ArrowUp' && !html.length && !e.metaKey && !e.altKey) {\n e.preventDefault();\n editLastMessage();\n } else {\n e.target.addEventListener('keyup', handleKeyUp);\n }\n }\n\n function handleTouchSelection() {\n if (!IS_ANDROID) {\n return;\n }\n\n checkSelection();\n }\n\n function handleChange(e: ChangeEvent<HTMLDivElement>) {\n const { innerHTML, textContent } = e.currentTarget;\n\n onUpdate(innerHTML === SAFARI_BR ? '' : innerHTML);\n\n // Reset focus on the input to remove any active styling when input is cleared\n if (!IS_TOUCH_ENV && (!textContent || !textContent.length)) {\n const selection = window.getSelection()!;\n if (selection) {\n inputRef.current!.blur();\n selection.removeAllRanges();\n focusEditableElement(inputRef.current!, true);\n }\n }\n }\n\n function stopEvent(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {\n if (!IS_ANDROID) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n }\n\n function updateInputHeight(willSend = false) {\n const input = inputRef.current!;\n const clone = cloneRef.current!;\n const currentHeight = Number(input.style.height.replace('px', ''));\n const newHeight = Math.min(clone.scrollHeight, MAX_INPUT_HEIGHT);\n if (newHeight === currentHeight) {\n return;\n }\n\n const transitionDuration = Math.round(\n TRANSITION_DURATION_FACTOR * Math.log(Math.abs(newHeight - currentHeight)),\n );\n\n const exec = () => {\n input.style.height = `${newHeight}px`;\n input.style.transitionDuration = `${transitionDuration}ms`;\n input.classList.toggle('overflown', clone.scrollHeight > MAX_INPUT_HEIGHT);\n };\n\n if (willSend) {\n // Sync with sending animation\n requestAnimationFrame(exec);\n } else {\n exec();\n }\n }\n\n useEffect(() => {\n if (IS_TOUCH_ENV) {\n return;\n }\n\n if (shouldSetFocus) {\n focusInput();\n }\n }, [currentChatId, focusInput, replyingToId, shouldSetFocus]);\n\n useEffect(() => {\n if (noTabCapture) {\n return undefined;\n }\n\n const captureFirstTab = debounce((e: KeyboardEvent) => {\n if (e.key === 'Tab') {\n e.preventDefault();\n requestAnimationFrame(focusInput);\n }\n }, TAB_INDEX_PRIORITY_TIMEOUT, true, false);\n\n return captureKeyboardListeners({ onTab: captureFirstTab });\n }, [focusInput, noTabCapture]);\n\n useEffect(() => {\n const input = inputRef.current!;\n\n function suppressFocus() {\n input.blur();\n }\n\n if (shouldSuppressFocus) {\n input.addEventListener('focus', suppressFocus);\n }\n\n return () => {\n input.removeEventListener('focus', suppressFocus);\n };\n }, [shouldSuppressFocus]);\n\n const className = buildClassName(\n 'form-control custom-scroll',\n html.length > 0 && 'touched',\n shouldSuppressFocus && 'focus-disabled',\n );\n\n return (\n <div id={id} onClick={shouldSuppressFocus ? onSuppressedFocus : undefined} dir={lang.isRtl ? 'rtl' : undefined}>\n <div\n ref={inputRef}\n id={editableInputId || EDITABLE_INPUT_ID}\n className={className}\n contentEditable\n dir=\"auto\"\n onClick={focusInput}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onMouseDown={handleMouseDown}\n onContextMenu={stopEvent}\n onTouchCancel={handleTouchSelection}\n />\n <div ref={cloneRef} className={buildClassName(className, 'clone')} dir=\"auto\" />\n {!forcedPlaceholder && <span className=\"placeholder-text\" dir=\"auto\">{placeholder}</span>}\n <TextFormatter\n isOpen={isTextFormatterOpen}\n anchorPosition={textFormatterAnchorPosition}\n selectedRange={selectedRange}\n onClose={handleCloseTextFormatter}\n />\n {forcedPlaceholder && <span className=\"forced-placeholder\">{renderText(forcedPlaceholder!)}</span>}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global): StateProps => {\n const { chatId: currentChatId, threadId } = selectCurrentMessageList(global) || {};\n const { messageSendKeyCombo } = global.settings.byKey;\n\n return {\n currentChatId,\n messageSendKeyCombo,\n replyingToId: currentChatId && threadId ? selectReplyingToId(global, currentChatId, threadId) : undefined,\n noTabCapture: global.isPollModalOpen || global.payment.isPaymentModalOpen,\n };\n },\n (setGlobal, actions): DispatchProps => pick(actions, ['editLastMessage', 'replyToNextMessage']),\n)(MessageInput));\n","import React, {\n FC, memo, useCallback, useEffect, useRef, useState,\n} from '../../../lib/teact/teact';\n\nimport { IAnchorPosition } from '../../../types';\n\nimport { EDITABLE_INPUT_ID } from '../../../config';\nimport buildClassName from '../../../util/buildClassName';\nimport captureEscKeyListener from '../../../util/captureEscKeyListener';\nimport useShowTransition from '../../../hooks/useShowTransition';\nimport useVirtualBackdrop from '../../../hooks/useVirtualBackdrop';\nimport useFlag from '../../../hooks/useFlag';\nimport useLang from '../../../hooks/useLang';\n\nimport Button from '../../ui/Button';\n\nimport './TextFormatter.scss';\n\nexport type OwnProps = {\n isOpen: boolean;\n anchorPosition?: IAnchorPosition;\n selectedRange?: Range;\n onClose: () => void;\n};\n\ninterface ISelectedTextFormats {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n monospace?: boolean;\n}\n\nconst TEXT_FORMAT_BY_TAG_NAME: Record<string, keyof ISelectedTextFormats> = {\n B: 'bold',\n STRONG: 'bold',\n I: 'italic',\n EM: 'italic',\n U: 'underline',\n DEL: 'strikethrough',\n CODE: 'monospace',\n};\nconst fragmentEl = document.createElement('div');\n\nconst TextFormatter: FC<OwnProps> = ({\n isOpen,\n anchorPosition,\n selectedRange,\n onClose,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const containerRef = useRef<HTMLDivElement>(null);\n // eslint-disable-next-line no-null/no-null\n const linkUrlInputRef = useRef<HTMLInputElement>(null);\n const { shouldRender, transitionClassNames } = useShowTransition(isOpen);\n const [isLinkControlOpen, openLinkControl, closeLinkControl] = useFlag();\n const [linkUrl, setLinkUrl] = useState('');\n const [isEditingLink, setIsEditingLink] = useState(false);\n const [inputClassName, setInputClassName] = useState<string | undefined>();\n const [selectedTextFormats, setSelectedTextFormats] = useState<ISelectedTextFormats>({});\n\n useEffect(() => (isOpen ? captureEscKeyListener(onClose) : undefined), [isOpen, onClose]);\n useVirtualBackdrop(\n isOpen,\n containerRef,\n onClose,\n );\n\n useEffect(() => {\n if (isLinkControlOpen) {\n linkUrlInputRef.current!.focus();\n } else {\n setLinkUrl('');\n setIsEditingLink(false);\n }\n }, [isLinkControlOpen]);\n\n useEffect(() => {\n if (!shouldRender) {\n closeLinkControl();\n setSelectedTextFormats({});\n setInputClassName(undefined);\n }\n }, [closeLinkControl, shouldRender]);\n\n useEffect(() => {\n if (!isOpen || !selectedRange) {\n return;\n }\n\n const selectedFormats: ISelectedTextFormats = {};\n let { parentElement } = selectedRange.commonAncestorContainer;\n while (parentElement && parentElement.id !== EDITABLE_INPUT_ID) {\n const textFormat = TEXT_FORMAT_BY_TAG_NAME[parentElement.tagName];\n if (textFormat) {\n selectedFormats[textFormat] = true;\n }\n\n parentElement = parentElement.parentElement;\n }\n\n setSelectedTextFormats(selectedFormats);\n }, [isOpen, selectedRange, openLinkControl]);\n\n function restoreSelection() {\n if (!selectedRange) {\n return;\n }\n\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(selectedRange);\n }\n }\n\n const getSelectedText = useCallback(() => {\n if (!selectedRange) {\n return undefined;\n }\n fragmentEl.innerText = selectedRange.toString();\n\n return fragmentEl.innerHTML;\n }, [selectedRange]);\n\n const getSelectedElement = useCallback(() => {\n if (!selectedRange) {\n return undefined;\n }\n\n return selectedRange.commonAncestorContainer.parentElement;\n }, [selectedRange]);\n\n function updateInputStyles() {\n const input = linkUrlInputRef.current;\n if (!input) {\n return;\n }\n\n const { offsetWidth, scrollWidth, scrollLeft } = input;\n if (scrollWidth <= offsetWidth) {\n setInputClassName(undefined);\n return;\n }\n\n let className = '';\n if (scrollLeft < scrollWidth - offsetWidth) {\n className = 'mask-right';\n }\n if (scrollLeft > 0) {\n className += ' mask-left';\n }\n\n setInputClassName(className);\n }\n\n function handleLinkUrlChange(e: React.ChangeEvent<HTMLInputElement>) {\n setLinkUrl(e.target.value);\n updateInputStyles();\n }\n\n function getFormatButtonClassName(key: keyof ISelectedTextFormats) {\n if (selectedTextFormats[key]) {\n return 'active';\n }\n\n if (key === 'monospace' || key === 'strikethrough') {\n if (Object.keys(selectedTextFormats).some(\n (fKey) => fKey !== key && !!selectedTextFormats[fKey as keyof ISelectedTextFormats],\n )) {\n return 'disabled';\n }\n } else if (selectedTextFormats.monospace || selectedTextFormats.strikethrough) {\n return 'disabled';\n }\n\n return undefined;\n }\n\n const handleBoldText = useCallback(() => {\n setSelectedTextFormats((selectedFormats) => {\n // Somehow re-applying 'bold' command to already bold text doesn't work\n document.execCommand(selectedFormats.bold ? 'removeFormat' : 'bold');\n Object.keys(selectedFormats).forEach((key) => {\n if ((key === 'italic' || key === 'underline') && !!selectedFormats[key]) {\n document.execCommand(key);\n }\n });\n\n return {\n ...selectedFormats,\n bold: !selectedFormats.bold,\n };\n });\n }, []);\n\n const handleItalicText = useCallback(() => {\n document.execCommand('italic');\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n italic: !selectedFormats.italic,\n }));\n }, []);\n\n const handleUnderlineText = useCallback(() => {\n document.execCommand('underline');\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n underline: !selectedFormats.underline,\n }));\n }, []);\n\n const handleStrikethroughText = useCallback(() => {\n if (selectedTextFormats.strikethrough) {\n const element = getSelectedElement();\n if (\n !selectedRange\n || !element\n || element.tagName !== 'DEL'\n || !element.textContent\n ) {\n return;\n }\n\n element.replaceWith(element.textContent);\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n strikethrough: false,\n }));\n\n return;\n }\n\n const text = getSelectedText();\n document.execCommand('insertHTML', false, `<del>${text}</del>`);\n onClose();\n }, [\n getSelectedElement, getSelectedText, onClose,\n selectedRange, selectedTextFormats.strikethrough,\n ]);\n\n const handleMonospaceText = useCallback(() => {\n if (selectedTextFormats.monospace) {\n const element = getSelectedElement();\n if (\n !selectedRange\n || !element\n || element.tagName !== 'CODE'\n || !element.textContent\n ) {\n return;\n }\n\n element.replaceWith(element.textContent);\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n monospace: false,\n }));\n return;\n }\n\n const text = getSelectedText();\n document.execCommand('insertHTML', false, `<code class=\"text-entity-code\" dir=\"auto\">${text}</code>`);\n onClose();\n }, [\n getSelectedElement, getSelectedText, onClose,\n selectedRange, selectedTextFormats.monospace,\n ]);\n\n function handleLinkUrlConfirm() {\n const formattedLinkUrl = encodeURI(linkUrl.includes('://') ? linkUrl : `http://${linkUrl}`);\n\n if (isEditingLink) {\n const element = getSelectedElement();\n if (!element || element.tagName !== 'A') {\n return;\n }\n\n (element as HTMLAnchorElement).href = formattedLinkUrl;\n\n onClose();\n return;\n }\n\n const text = getSelectedText();\n restoreSelection();\n document.execCommand(\n 'insertHTML',\n false,\n `<a href=${formattedLinkUrl} class=\"text-entity-link\" dir=\"auto\">${text}</a>`,\n );\n onClose();\n }\n\n const handleKeyDown = useCallback((e: KeyboardEvent) => {\n const HANDLERS_BY_KEY_CODE: Record<string, AnyToVoidFunction> = {\n KeyK: openLinkControl,\n KeyB: handleBoldText,\n KeyU: handleUnderlineText,\n KeyI: handleItalicText,\n KeyM: handleMonospaceText,\n KeyS: handleStrikethroughText,\n };\n\n const handler = HANDLERS_BY_KEY_CODE[e.code];\n\n if (\n e.altKey\n || !(e.ctrlKey || e.metaKey)\n || !handler\n ) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n handler();\n }, [\n handleBoldText, handleItalicText, handleUnderlineText,\n handleMonospaceText, handleStrikethroughText,\n openLinkControl,\n ]);\n\n useEffect(() => {\n if (isOpen) {\n document.addEventListener('keydown', handleKeyDown);\n }\n\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, handleKeyDown]);\n\n const lang = useLang();\n\n function handleContainerKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {\n if (e.key === 'Enter' && isLinkControlOpen) {\n handleLinkUrlConfirm();\n e.preventDefault();\n }\n }\n\n if (!shouldRender) {\n return undefined;\n }\n\n const className = buildClassName(\n 'TextFormatter',\n transitionClassNames,\n isLinkControlOpen && 'link-control-shown',\n );\n\n const linkUrlConfirmClassName = buildClassName(\n 'TextFormatter-link-url-confirm',\n !!linkUrl.length && 'shown',\n );\n\n const style = anchorPosition\n ? `left: ${anchorPosition.x}px; top: ${anchorPosition.y}px;--text-formatter-left: ${anchorPosition.x}px;`\n : '';\n\n return (\n <div\n ref={containerRef}\n className={className}\n // @ts-ignore Teact feature\n style={style}\n onKeyDown={handleContainerKeyDown}\n >\n <div className=\"TextFormatter-buttons\">\n <Button\n color=\"translucent\"\n ariaLabel=\"Bold text\"\n className={getFormatButtonClassName('bold')}\n onClick={handleBoldText}\n >\n <i className=\"icon-bold\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Italic text\"\n className={getFormatButtonClassName('italic')}\n onClick={handleItalicText}\n >\n <i className=\"icon-italic\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Underlined text\"\n className={getFormatButtonClassName('underline')}\n onClick={handleUnderlineText}\n >\n <i className=\"icon-underlined\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Strikethrough text\"\n className={getFormatButtonClassName('strikethrough')}\n onClick={handleStrikethroughText}\n >\n <i className=\"icon-strikethrough\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Monospace text\"\n className={getFormatButtonClassName('monospace')}\n onClick={handleMonospaceText}\n >\n <i className=\"icon-monospace\" />\n </Button>\n <div className=\"TextFormatter-divider\" />\n <Button color=\"translucent\" ariaLabel={lang('TextFormat.AddLinkTitle')} onClick={openLinkControl}>\n <i className=\"icon-link\" />\n </Button>\n </div>\n\n <div className=\"TextFormatter-link-control\">\n <div className=\"TextFormatter-buttons\">\n <Button color=\"translucent\" ariaLabel={lang('Cancel')} onClick={closeLinkControl}>\n <i className=\"icon-arrow-left\" />\n </Button>\n <div className=\"TextFormatter-divider\" />\n\n <div\n className={buildClassName('TextFormatter-link-url-input-wrapper', inputClassName)}\n >\n <input\n ref={linkUrlInputRef}\n className=\"TextFormatter-link-url-input\"\n type=\"text\"\n value={linkUrl}\n placeholder=\"Enter URL...\"\n autoComplete=\"off\"\n inputMode=\"url\"\n dir=\"auto\"\n onChange={handleLinkUrlChange}\n onScroll={updateInputStyles}\n />\n </div>\n\n <div className={linkUrlConfirmClassName}>\n <div className=\"TextFormatter-divider\" />\n <Button\n color=\"translucent\"\n ariaLabel={lang('Save')}\n className=\"color-primary\"\n onClick={handleLinkUrlConfirm}\n >\n <i className=\"icon-check\" />\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default memo(TextFormatter);\n","import { ApiMessageEntity, ApiMessageEntityTypes, ApiFormattedText } from '../../../../api/types';\nimport { IS_EMOJI_SUPPORTED } from '../../../../util/environment';\n\nconst ENTITY_CLASS_BY_NODE_NAME: Record<string, string> = {\n B: ApiMessageEntityTypes.Bold,\n STRONG: ApiMessageEntityTypes.Bold,\n I: ApiMessageEntityTypes.Italic,\n EM: ApiMessageEntityTypes.Italic,\n U: ApiMessageEntityTypes.Underline,\n S: ApiMessageEntityTypes.Strike,\n STRIKE: ApiMessageEntityTypes.Strike,\n DEL: ApiMessageEntityTypes.Strike,\n CODE: ApiMessageEntityTypes.Code,\n PRE: ApiMessageEntityTypes.Pre,\n BLOCKQUOTE: ApiMessageEntityTypes.Blockquote,\n};\n\nconst MAX_TAG_DEEPNESS = 3;\n\nexport default function parseMessageInput(html: string): ApiFormattedText {\n const fragment = document.createElement('div');\n fragment.innerHTML = parseMarkdown(html);\n const text = fragment.innerText.trim().replace(/\\u200b+/g, '');\n let textIndex = 0;\n let recursionDeepness = 0;\n const entities: ApiMessageEntity[] = [];\n\n function addEntity(node: ChildNode) {\n const { index, entity } = getEntityDataFromNode(node, text, textIndex);\n\n if (entity) {\n textIndex = index;\n entities.push(entity);\n } else if (node.textContent) {\n textIndex += node.textContent.length;\n }\n\n if (node.hasChildNodes() && recursionDeepness <= MAX_TAG_DEEPNESS) {\n recursionDeepness += 1;\n Array.from(node.childNodes).forEach(addEntity);\n }\n }\n\n Array.from(fragment.childNodes).forEach((node) => {\n recursionDeepness = 1;\n addEntity(node);\n });\n\n return {\n text,\n entities: entities.length ? entities : undefined,\n };\n}\n\nfunction parseMarkdown(html: string) {\n let parsedHtml = html.slice(0);\n\n if (!IS_EMOJI_SUPPORTED) {\n // Emojis\n parsedHtml = parsedHtml.replace(/<img[^>]+alt=\"([^\"]+)\"[^>]*>/gm, '$1');\n }\n\n // Strip redundant <span> tags\n parsedHtml = parsedHtml.replace(/<\\/?span([^>]*)?>/g, '');\n\n // Strip redundant nbsp's\n parsedHtml = parsedHtml.replace(/ /g, ' ');\n\n // Replace <div><br></div> with newline (new line in Safari)\n parsedHtml = parsedHtml.replace(/<div><br([^>]*)?><\\/div>/g, '\\n');\n // Replace <br> with newline\n parsedHtml = parsedHtml.replace(/<br([^>]*)?>/g, '\\n');\n\n // Strip redundant <div> tags\n parsedHtml = parsedHtml.replace(/<\\/div>(\\s*)<div>/g, '\\n');\n parsedHtml = parsedHtml.replace(/<div>/g, '\\n');\n parsedHtml = parsedHtml.replace(/<\\/div>/g, '');\n\n // Pre\n parsedHtml = parsedHtml.replace(/^`{3}(.*[\\n\\r][^]*?^)`{3}/gm, '<pre>$1</pre>');\n parsedHtml = parsedHtml.replace(/[`]{3}([^`]+)[`]{3}/g, '<pre>$1</pre>');\n\n // Code\n parsedHtml = parsedHtml.replace(/[`]{1}([^`\\n]+)[`]{1}/g, '<code>$1</code>');\n\n // Other simple markdown\n parsedHtml = parsedHtml.replace(/[*]{2}([^*\\n]+)[*]{2}/g, '<b>$1</b>');\n parsedHtml = parsedHtml.replace(/[_]{2}([^*\\n]+)[_]{2}/g, '<i>$1</i>');\n parsedHtml = parsedHtml.replace(/[~]{2}([^~\\n]+)[~]{2}/g, '<s>$1</s>');\n\n return parsedHtml;\n}\n\nfunction getEntityDataFromNode(\n node: ChildNode,\n rawText: string,\n textIndex: number,\n): { index: number; entity?: ApiMessageEntity } {\n const type = getEntityTypeFromNode(node);\n if (!type || !node.textContent) {\n return {\n index: textIndex,\n entity: undefined,\n };\n }\n\n const rawIndex = rawText.indexOf(node.textContent, textIndex);\n // In some cases, last text entity ends with a newline (which gets trimmed from `rawText`).\n // In this case, `rawIndex` would return `-1`, so we use `textIndex` instead.\n const index = rawIndex >= 0 ? rawIndex : textIndex;\n const offset = rawText.substring(0, index).length;\n const { length } = rawText.substring(index, index + node.textContent.length);\n\n let url: string | undefined;\n let userId: number | undefined;\n if (type === ApiMessageEntityTypes.TextUrl) {\n url = (node as HTMLAnchorElement).href;\n }\n if (type === ApiMessageEntityTypes.MentionName) {\n userId = Number((node as HTMLAnchorElement).dataset.userId);\n }\n\n return {\n index,\n entity: {\n type,\n offset,\n length,\n ...(url && { url }),\n ...(userId && { userId }),\n },\n };\n}\n\nfunction getEntityTypeFromNode(node: ChildNode) {\n if (ENTITY_CLASS_BY_NODE_NAME[node.nodeName]) {\n return ENTITY_CLASS_BY_NODE_NAME[node.nodeName];\n }\n\n if (node.nodeName === 'A') {\n const anchor = node as HTMLAnchorElement;\n if (anchor.dataset.entityType === ApiMessageEntityTypes.MentionName) {\n return ApiMessageEntityTypes.MentionName;\n }\n if (anchor.dataset.entityType === ApiMessageEntityTypes.Url) {\n return ApiMessageEntityTypes.Url;\n }\n if (anchor.href.startsWith('mailto:')) {\n return ApiMessageEntityTypes.Email;\n }\n if (anchor.href.startsWith('tel:')) {\n return ApiMessageEntityTypes.Phone;\n }\n if (anchor.href !== anchor.textContent) {\n return ApiMessageEntityTypes.TextUrl;\n }\n\n return ApiMessageEntityTypes.Url;\n }\n\n if (node.nodeName === 'SPAN') {\n return (node as HTMLElement).dataset.entityType;\n }\n\n return undefined;\n}\n","const MAX_NESTING_PARENTS = 5;\n\nexport function isSelectionInsideInput(selectionRange: Range, inputId: string) {\n const { commonAncestorContainer } = selectionRange;\n let parentNode: HTMLElement | null = commonAncestorContainer as HTMLElement;\n let iterations = 1;\n while (parentNode && parentNode.id !== inputId && iterations < MAX_NESTING_PARENTS) {\n parentNode = parentNode.parentElement;\n iterations++;\n }\n\n return Boolean(parentNode && parentNode.id === inputId);\n}\n","import {\n useCallback, useEffect, useMemo, useState,\n} from '../../../../lib/teact/teact';\n\nimport { EDITABLE_INPUT_ID } from '../../../../config';\nimport { MEMO_EMPTY_ARRAY } from '../../../../util/memo';\nimport {\n EmojiData, EmojiModule, EmojiRawData, uncompressEmoji,\n} from '../../../../util/emoji';\nimport focusEditableElement from '../../../../util/focusEditableElement';\nimport {\n buildCollectionByKey, flatten, mapValues, pickTruthy, unique,\n} from '../../../../util/iteratees';\nimport useFlag from '../../../../hooks/useFlag';\n\nlet emojiDataPromise: Promise<EmojiModule>;\nlet emojiRawData: EmojiRawData;\nlet emojiData: EmojiData;\n\nlet RE_EMOJI_SEARCH: RegExp;\nconst EMOJIS_LIMIT = 36;\nconst FILTER_MIN_LENGTH = 2;\nconst RE_BR = /(<br>|<br\\s?\\/>)/g;\nconst RE_SPACE = / /g;\nconst RE_CLEAN_HTML = /(<div>|<\\/div>)/gi;\n\ntry {\n RE_EMOJI_SEARCH = new RegExp('(^|\\\\s):[-+_:\\\\p{L}\\\\p{N}]*$', 'gui');\n} catch (e) {\n // Support for older versions of firefox\n RE_EMOJI_SEARCH = new RegExp('(^|\\\\s):[-+_:\\\\d\\\\wа-яё]*$', 'gi');\n}\n\nexport default function useEmojiTooltip(\n isAllowed: boolean,\n html: string,\n recentEmojiIds: string[],\n inputId = EDITABLE_INPUT_ID,\n onUpdateHtml: (html: string) => void,\n baseEmojiKeywords?: Record<string, string[]>,\n emojiKeywords?: Record<string, string[]>,\n isDisabled = false,\n) {\n const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();\n\n const [byId, setById] = useState<Record<string, Emoji> | undefined>();\n const [keywords, setKeywords] = useState<string[]>();\n const [byKeyword, setByKeyword] = useState<Record<string, Emoji[]>>({});\n const [names, setNames] = useState<string[]>();\n const [byName, setByName] = useState<Record<string, Emoji[]>>({});\n const [shouldForceInsertEmoji, setShouldForceInsertEmoji] = useState(false);\n\n const [filteredEmojis, setFilteredEmojis] = useState<Emoji[]>(MEMO_EMPTY_ARRAY);\n\n const recentEmojis = useMemo(\n () => {\n if (!byId || !recentEmojiIds.length) {\n return [];\n }\n\n return Object.values(pickTruthy(byId, recentEmojiIds));\n },\n [byId, recentEmojiIds],\n );\n\n // Initialize data on first render.\n useEffect(() => {\n if (isDisabled) return;\n const exec = () => {\n setById(emojiData.emojis);\n };\n\n if (emojiData) {\n exec();\n } else {\n ensureEmojiData()\n .then(exec);\n }\n }, [isDisabled]);\n\n useEffect(() => {\n if (!byId || isDisabled) {\n return;\n }\n\n const emojis = Object.values(byId);\n\n const byNative = buildCollectionByKey(emojis, 'native');\n const baseEmojisByKeyword = baseEmojiKeywords\n ? mapValues(baseEmojiKeywords, (natives) => {\n return Object.values(pickTruthy(byNative, natives));\n })\n : {};\n const emojisByKeyword = emojiKeywords\n ? mapValues(emojiKeywords, (natives) => {\n return Object.values(pickTruthy(byNative, natives));\n })\n : {};\n\n setByKeyword({ ...baseEmojisByKeyword, ...emojisByKeyword });\n setKeywords([...Object.keys(baseEmojisByKeyword), ...Object.keys(emojisByKeyword)]);\n\n const emojisByName = emojis.reduce((result, emoji) => {\n emoji.names.forEach((name) => {\n if (!result[name]) {\n result[name] = [];\n }\n\n result[name].push(emoji);\n });\n\n return result;\n }, {} as Record<string, Emoji[]>);\n setByName(emojisByName);\n setNames(Object.keys(emojisByName));\n }, [isDisabled, baseEmojiKeywords, byId, emojiKeywords]);\n\n useEffect(() => {\n if (!isAllowed || !html || !byId || !keywords || !keywords.length) {\n unmarkIsOpen();\n return;\n }\n\n const code = html.includes(':') && getEmojiCode(html);\n if (!code) {\n setFilteredEmojis(MEMO_EMPTY_ARRAY);\n unmarkIsOpen();\n return;\n }\n\n const forceSend = code.length > 2 && code.endsWith(':');\n const filter = code.substr(1, forceSend ? code.length - 2 : undefined);\n let matched: Emoji[] = [];\n\n setShouldForceInsertEmoji(forceSend);\n\n if (!filter) {\n matched = recentEmojis;\n } else if (filter.length >= FILTER_MIN_LENGTH) {\n const matchedKeywords = keywords.filter((keyword) => keyword.startsWith(filter)).sort();\n matched = matched.concat(flatten(Object.values(pickTruthy(byKeyword, matchedKeywords))));\n\n // Also search by names, which is useful for non-English languages\n const matchedNames = names.filter((name) => name.startsWith(filter));\n matched = matched.concat(flatten(Object.values(pickTruthy(byName, matchedNames))));\n\n matched = unique(matched);\n }\n\n if (matched.length) {\n if (!forceSend) {\n markIsOpen();\n }\n setFilteredEmojis(matched.slice(0, EMOJIS_LIMIT));\n } else {\n unmarkIsOpen();\n }\n }, [\n byId, byKeyword, keywords, byName, names, html, isAllowed, markIsOpen,\n recentEmojis, unmarkIsOpen, setShouldForceInsertEmoji,\n ]);\n\n const insertEmoji = useCallback((textEmoji: string, isForce?: boolean) => {\n const atIndex = html.lastIndexOf(':', isForce ? html.lastIndexOf(':') - 1 : undefined);\n if (atIndex !== -1) {\n onUpdateHtml(`${html.substr(0, atIndex)}${textEmoji}`);\n const messageInput = document.getElementById(inputId)!;\n requestAnimationFrame(() => {\n focusEditableElement(messageInput, true);\n });\n }\n\n unmarkIsOpen();\n }, [html, inputId, onUpdateHtml, unmarkIsOpen]);\n\n useEffect(() => {\n if (isOpen && shouldForceInsertEmoji && filteredEmojis.length) {\n insertEmoji(filteredEmojis[0].native, true);\n }\n }, [filteredEmojis, insertEmoji, isOpen, shouldForceInsertEmoji]);\n\n return {\n isEmojiTooltipOpen: isOpen,\n closeEmojiTooltip: unmarkIsOpen,\n filteredEmojis,\n insertEmoji,\n };\n}\n\nfunction getEmojiCode(html: string) {\n const emojis = html\n .replace(RE_SPACE, ' ')\n .replace(RE_BR, '\\n')\n .replace(/\\n$/i, '')\n .replace(RE_CLEAN_HTML, '')\n .match(RE_EMOJI_SEARCH);\n\n return emojis ? emojis[0].trim() : undefined;\n}\n\nasync function ensureEmojiData() {\n if (!emojiDataPromise) {\n emojiDataPromise = import('emoji-data-ios/emoji-data.json') as unknown as Promise<EmojiModule>;\n emojiRawData = (await emojiDataPromise).default;\n\n emojiData = uncompressEmoji(emojiRawData);\n }\n\n return emojiDataPromise;\n}\n","import { ApiUser } from '../../../../api/types';\nimport { getUserFullName } from '../../../../modules/helpers';\nimport searchWords from '../../../../util/searchWords';\n\n// TODO: Support cyrillic translit search\nexport default function searchUserName(filter: string, user: ApiUser) {\n const usernameLowered = user.username.toLowerCase();\n const fullName = getUserFullName(user);\n const fullNameLowered = fullName && fullName.toLowerCase();\n const filterLowered = filter.toLowerCase();\n\n return usernameLowered.startsWith(filterLowered) || (\n fullNameLowered && searchWords(fullNameLowered, filterLowered)\n );\n}\n","import {\n useCallback, useEffect, useState, useMemo,\n} from '../../../../lib/teact/teact';\n\nimport { ApiMessageEntityTypes, ApiChatMember, ApiUser } from '../../../../api/types';\nimport { EDITABLE_INPUT_ID } from '../../../../config';\nimport { getUserFirstOrLastName } from '../../../../modules/helpers';\nimport searchUserName from '../helpers/searchUserName';\nimport focusEditableElement from '../../../../util/focusEditableElement';\nimport useFlag from '../../../../hooks/useFlag';\nimport { unique } from '../../../../util/iteratees';\nimport { throttle } from '../../../../util/schedulers';\n\nconst runThrottled = throttle((cb) => cb(), 500, true);\nconst RE_BR = /(<br>|<br\\s?\\/>)/g;\nconst RE_SPACE = / /g;\nconst RE_CLEAN_HTML = /(<div>|<\\/div>)/gi;\nlet RE_USERNAME_SEARCH: RegExp;\n\ntry {\n RE_USERNAME_SEARCH = new RegExp('(^|\\\\s)@[-_\\\\p{L}\\\\p{M}\\\\p{N}]*$', 'gui');\n} catch (e) {\n // Support for older versions of firefox\n RE_USERNAME_SEARCH = new RegExp('(^|\\\\s)@[-_\\\\d\\\\wа-яё]*$', 'gi');\n}\n\nexport default function useMentionTooltip(\n canSuggestMembers: boolean | undefined,\n html: string,\n onUpdateHtml: (html: string) => void,\n inputId: string = EDITABLE_INPUT_ID,\n groupChatMembers?: ApiChatMember[],\n topInlineBotIds?: number[],\n currentUserId?: number,\n usersById?: Record<number, ApiUser>,\n) {\n const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();\n const [usersToMention, setUsersToMention] = useState<ApiUser[] | undefined>();\n\n const topInlineBots = useMemo(() => {\n return (topInlineBotIds || []).map((id) => usersById && usersById[id]).filter<ApiUser>(Boolean as any);\n }, [topInlineBotIds, usersById]);\n\n const getFilteredUsers = useCallback((filter, withInlineBots: boolean) => {\n if (!(groupChatMembers || topInlineBotIds) || !usersById) {\n setUsersToMention(undefined);\n\n return;\n }\n runThrottled(() => {\n const inlineBots = (withInlineBots ? topInlineBots : []).filter((inlineBot) => {\n return !filter || searchUserName(filter, inlineBot);\n });\n\n const chatMembers = (groupChatMembers || [])\n .map(({ userId }) => usersById[userId])\n .filter((user) => {\n if (!user || user.id === currentUserId) {\n return false;\n }\n\n return !filter || searchUserName(filter, user);\n });\n\n setUsersToMention(unique(inlineBots.concat(chatMembers)));\n });\n }, [currentUserId, groupChatMembers, topInlineBotIds, topInlineBots, usersById]);\n\n useEffect(() => {\n if (!canSuggestMembers || !html.length) {\n unmarkIsOpen();\n return;\n }\n\n const usernameFilter = html.includes('@') && getUsernameFilter(html);\n\n if (usernameFilter) {\n const filter = usernameFilter ? usernameFilter.substr(1) : '';\n getFilteredUsers(filter, canSuggestInlineBots(html));\n } else {\n unmarkIsOpen();\n }\n }, [canSuggestMembers, html, getFilteredUsers, markIsOpen, unmarkIsOpen]);\n\n useEffect(() => {\n if (usersToMention && usersToMention.length) {\n markIsOpen();\n } else {\n unmarkIsOpen();\n }\n }, [markIsOpen, unmarkIsOpen, usersToMention]);\n\n const insertMention = useCallback((user: ApiUser, forceFocus = false) => {\n if (!user.username && !getUserFirstOrLastName(user)) {\n return;\n }\n\n const insertedHtml = user.username\n ? `@${user.username}`\n : `<a\n class=\"text-entity-link\"\n data-entity-type=\"${ApiMessageEntityTypes.MentionName}\"\n data-user-id=\"${user.id}\"\n contenteditable=\"false\"\n dir=\"auto\"\n >${getUserFirstOrLastName(user)}</a>`;\n\n const atIndex = html.lastIndexOf('@');\n if (atIndex !== -1) {\n onUpdateHtml(`${html.substr(0, atIndex)}${insertedHtml} `);\n const messageInput = document.getElementById(inputId)!;\n requestAnimationFrame(() => {\n focusEditableElement(messageInput, forceFocus);\n });\n }\n\n unmarkIsOpen();\n }, [html, inputId, onUpdateHtml, unmarkIsOpen]);\n\n return {\n isMentionTooltipOpen: isOpen,\n closeMentionTooltip: unmarkIsOpen,\n insertMention,\n mentionFilteredUsers: usersToMention,\n };\n}\n\nfunction getUsernameFilter(html: string) {\n const username = html\n .replace(RE_SPACE, ' ')\n .replace(RE_BR, '\\n')\n .replace(RE_CLEAN_HTML, '')\n .replace(/\\n$/i, '')\n .match(RE_USERNAME_SEARCH);\n\n return username ? username[0].trim() : undefined;\n}\n\nfunction canSuggestInlineBots(html: string) {\n return html.startsWith('@');\n}\n","import { useEffect, useRef } from '../../../lib/teact/teact';\n\nimport useOnChange from '../../../hooks/useOnChange';\nimport useForceUpdate from '../../../hooks/useForceUpdate';\n\nexport default function useAsyncRendering<T extends any[]>(dependencies: T, delay?: number) {\n const isDisabled = delay === undefined;\n const shouldRenderRef = useRef(isDisabled);\n const timeoutRef = useRef<number>();\n const forceUpdate = useForceUpdate();\n\n useOnChange(() => {\n if (isDisabled) {\n return;\n }\n\n shouldRenderRef.current = false;\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n }, dependencies);\n\n useEffect(() => {\n if (isDisabled || shouldRenderRef.current) {\n return;\n }\n\n const exec = () => {\n shouldRenderRef.current = true;\n forceUpdate();\n };\n\n if (delay! > 0) {\n timeoutRef.current = window.setTimeout(exec, delay);\n } else {\n exec();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies);\n\n return shouldRenderRef.current;\n}\n","import React, { FC, memo } from '../../lib/teact/teact';\n\nimport useLang from '../../hooks/useLang';\nimport { TextPart } from '../common/helpers/renderMessageText';\n\nimport Modal from './Modal';\nimport Button from './Button';\n\ntype OwnProps = {\n isOpen: boolean;\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n title?: string;\n header?: FC;\n textParts?: TextPart[];\n text?: string;\n confirmLabel?: string;\n confirmHandler: () => void;\n confirmIsDestructive?: boolean;\n isButtonsInOneRow?: boolean;\n};\n\nconst ConfirmDialog: FC<OwnProps> = ({\n isOpen,\n onClose,\n onCloseAnimationEnd,\n title,\n header,\n text,\n textParts,\n confirmLabel = 'Confirm',\n confirmHandler,\n confirmIsDestructive,\n isButtonsInOneRow,\n}) => {\n const lang = useLang();\n\n return (\n <Modal\n className=\"confirm\"\n title={title}\n header={header}\n isOpen={isOpen}\n onClose={onClose}\n onCloseAnimationEnd={onCloseAnimationEnd}\n onEnter={confirmHandler}\n >\n {text && text.split('\\\\n').map((textPart) => (\n <p>{textPart}</p>\n ))}\n {textParts}\n <div className={isButtonsInOneRow ? 'dialog-buttons mt-2' : ''}>\n <Button\n className=\"confirm-dialog-button\"\n isText\n onClick={confirmHandler}\n color={confirmIsDestructive ? 'danger' : 'primary'}\n >\n {confirmLabel}\n </Button>\n <Button className=\"confirm-dialog-button\" isText onClick={onClose}>{lang('Cancel')}</Button>\n </div>\n </Modal>\n );\n};\n\nexport default memo(ConfirmDialog);\n","import React, { FC } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport Button, { OwnProps as ButtonProps } from './Button';\n\nimport './FloatingActionButton.scss';\n\ntype OwnProps = {\n isShown: boolean;\n className?: string;\n color?: ButtonProps['color'];\n ariaLabel?: ButtonProps['ariaLabel'];\n disabled?: boolean;\n onClick: () => void;\n children: any;\n};\n\nconst FloatingActionButton: FC<OwnProps> = ({\n isShown,\n className,\n color = 'primary',\n ariaLabel,\n disabled,\n onClick,\n children,\n}) => {\n const buttonClassName = buildClassName(\n 'FloatingActionButton',\n isShown && 'revealed',\n className,\n );\n\n return (\n <Button\n className={buttonClassName}\n color={color}\n round\n disabled={disabled}\n onClick={isShown && !disabled ? onClick : undefined}\n ariaLabel={ariaLabel}\n tabIndex={-1}\n >\n {children}\n </Button>\n );\n};\n\nexport default FloatingActionButton;\n","import { RefObject, UIEvent } from 'react';\nimport { LoadMoreDirection } from '../../types';\n\nimport React, {\n FC, useCallback, useEffect, useLayoutEffect, useMemo, useRef,\n} from '../../lib/teact/teact';\n\nimport { debounce } from '../../util/schedulers';\nimport resetScroll from '../../util/resetScroll';\n\ntype OwnProps = {\n ref?: RefObject<HTMLDivElement>;\n className?: string;\n onLoadMore?: ({ direction }: { direction: LoadMoreDirection; noScroll?: boolean }) => void;\n onScroll?: (e: UIEvent<HTMLDivElement>) => void;\n onKeyDown?: (e: React.KeyboardEvent<any>) => void;\n items?: any[];\n itemSelector?: string;\n preloadBackwards?: number;\n sensitiveArea?: number;\n noScrollRestore?: boolean;\n noScrollRestoreOnTop?: boolean;\n noFastList?: boolean;\n cacheBuster?: any;\n children: any;\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 onLoadMore,\n onScroll,\n onKeyDown,\n items,\n itemSelector = DEFAULT_LIST_SELECTOR,\n preloadBackwards = DEFAULT_PRELOAD_BACKWARDS,\n sensitiveArea = DEFAULT_SENSITIVE_AREA,\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}: 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 (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]);\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 && 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 resetScroll(container);\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 && 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 resetScroll(container);\n loadMoreBackwards();\n }\n }\n }\n\n if (!isUpdated) {\n if (currentAnchor && 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}\n onKeyDown={onKeyDown}\n >\n {children}\n </div>\n );\n};\n\nexport default InfiniteScroll;\n","import { RefObject } from 'react';\nimport React, { FC, useRef, useCallback } from '../../lib/teact/teact';\n\nimport { IS_TOUCH_ENV } from '../../util/environment';\nimport { fastRaf } from '../../util/schedulers';\nimport buildClassName from '../../util/buildClassName';\nimport useContextMenuHandlers from '../../hooks/useContextMenuHandlers';\nimport useContextMenuPosition from '../../hooks/useContextMenuPosition';\nimport useFlag from '../../hooks/useFlag';\nimport useLang from '../../hooks/useLang';\n\nimport RippleEffect from './RippleEffect';\nimport Menu from './Menu';\nimport MenuItem from './MenuItem';\n\nimport './ListItem.scss';\n\ntype OnClickHandler = (e: React.MouseEvent<HTMLDivElement>) => void;\n\ntype MenuItemContextAction = {\n title: string;\n icon: string;\n destructive?: boolean;\n handler?: () => void;\n};\n\ntype OwnProps = {\n ref?: RefObject<HTMLDivElement>;\n buttonRef?: RefObject<HTMLDivElement>;\n icon?: string;\n className?: string;\n style?: string;\n children: any;\n disabled?: boolean;\n ripple?: boolean;\n narrow?: boolean;\n inactive?: boolean;\n focus?: boolean;\n destructive?: boolean;\n multiline?: boolean;\n isStatic?: boolean;\n contextActions?: MenuItemContextAction[];\n onClick?: OnClickHandler;\n};\n\nconst ListItem: FC<OwnProps> = (props) => {\n const {\n ref,\n buttonRef,\n icon,\n className,\n style,\n children,\n disabled,\n ripple,\n narrow,\n inactive,\n focus,\n destructive,\n multiline,\n isStatic,\n contextActions,\n onClick,\n } = props;\n\n // eslint-disable-next-line no-null/no-null\n let containerRef = useRef<HTMLDivElement>(null);\n if (ref) {\n containerRef = ref;\n }\n const [isTouched, markIsTouched, unmarkIsTouched] = useFlag();\n\n const {\n isContextMenuOpen, contextMenuPosition,\n handleBeforeContextMenu, handleContextMenu,\n handleContextMenuClose, handleContextMenuHide,\n } = useContextMenuHandlers(containerRef, !contextActions);\n\n const getTriggerElement = useCallback(() => containerRef.current, []);\n\n const getRootElement = useCallback(\n () => containerRef.current!.closest('.custom-scroll'),\n [],\n );\n\n const getMenuElement = useCallback(\n () => containerRef.current!.querySelector('.ListItem-context-menu .bubble'),\n [],\n );\n\n const { positionX, positionY, style: menuStyle } = useContextMenuPosition(\n contextMenuPosition,\n getTriggerElement,\n getRootElement,\n getMenuElement,\n );\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n if (disabled || !onClick) {\n return;\n }\n onClick(e);\n\n if (IS_TOUCH_ENV && !ripple) {\n markIsTouched();\n fastRaf(unmarkIsTouched);\n }\n }, [disabled, markIsTouched, onClick, ripple, unmarkIsTouched]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n if (inactive || IS_TOUCH_ENV) {\n return;\n }\n if (contextActions && (e.button === 2 || !onClick)) {\n handleBeforeContextMenu(e);\n }\n if (e.button === 0) {\n if (!onClick) {\n handleContextMenu(e);\n } else {\n handleClick(e);\n }\n }\n }, [inactive, contextActions, onClick, handleBeforeContextMenu, handleContextMenu, handleClick]);\n\n const lang = useLang();\n\n const fullClassName = buildClassName(\n 'ListItem',\n className,\n !isStatic && 'no-selection',\n ripple && 'has-ripple',\n narrow && 'narrow',\n disabled && 'disabled',\n inactive && 'inactive',\n contextMenuPosition && 'has-menu-open',\n focus && 'focus',\n destructive && 'destructive',\n multiline && 'multiline',\n isStatic && 'is-static',\n );\n\n return (\n <div\n ref={containerRef}\n className={fullClassName}\n dir={lang.isRtl ? 'rtl' : undefined}\n // @ts-ignore\n style={style}\n >\n <div\n className={buildClassName('ListItem-button', isTouched && 'active')}\n role=\"button\"\n ref={buttonRef}\n tabIndex={0}\n onClick={!inactive && IS_TOUCH_ENV ? handleClick : undefined}\n onMouseDown={handleMouseDown}\n onContextMenu={!inactive && contextActions ? handleContextMenu : undefined}\n >\n {icon && (\n <i className={`icon-${icon}`} />\n )}\n {multiline && (<div className=\"multiline-item\">{children}</div>)}\n {!multiline && children}\n {!disabled && !inactive && ripple && (\n <RippleEffect />\n )}\n </div>\n {contextActions && contextMenuPosition !== undefined && (\n <Menu\n isOpen={isContextMenuOpen}\n positionX={positionX}\n positionY={positionY}\n style={menuStyle}\n className=\"ListItem-context-menu\"\n autoClose\n onClose={handleContextMenuClose}\n onCloseAnimationEnd={handleContextMenuHide}\n >\n {contextActions.map((action) => (\n <MenuItem\n key={action.title}\n icon={action.icon}\n destructive={action.destructive}\n disabled={!action.handler}\n onClick={action.handler}\n >\n {action.title}\n </MenuItem>\n ))}\n </Menu>\n )}\n </div>\n );\n};\n\nexport default ListItem;\n","import React, {\n FC, useEffect, useRef,\n} from '../../lib/teact/teact';\n\nimport { TextPart } from '../common/helpers/renderMessageText';\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?: any;\n hasCloseButton?: boolean;\n noBackdrop?: boolean;\n children: any;\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n onEnter?: () => void;\n};\n\ntype StateProps = {\n shouldSkipHistoryAnimations?: boolean;\n};\n\nconst Modal: FC<OwnProps & StateProps> = ({\n title,\n className,\n isOpen,\n header,\n hasCloseButton,\n noBackdrop,\n children,\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 const { forceClose } = useHistoryBack(isOpen, onClose);\n\n // For modals that are closed by unmounting without changing `isOpen` to `false`\n useEffect(() => {\n return () => {\n if (isOpen) {\n forceClose();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffectWithPrevDeps(([prevIsOpen]) => {\n document.body.classList.toggle('has-open-dialog', 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\">\n {renderHeader()}\n <div className=\"modal-content custom-scroll\">\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 React, {\n FC,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from '../../lib/teact/teact';\n\nimport { ANIMATION_END_DELAY } from '../../config';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport { TextPart } from '../common/helpers/renderMessageText';\nimport buildClassName from '../../util/buildClassName';\nimport captureEscKeyListener from '../../util/captureEscKeyListener';\n\nimport Portal from './Portal';\n\nimport './Notification.scss';\n\ntype OwnProps = {\n containerId?: string;\n message: TextPart[];\n duration?: number;\n onDismiss: () => void;\n};\n\nconst DEFAULT_DURATION = 3000;\nconst ANIMATION_DURATION = 150;\n\nconst Notification: FC<OwnProps> = ({\n message, duration = DEFAULT_DURATION, containerId, onDismiss,\n}) => {\n const [isOpen, setIsOpen] = useState(true);\n // eslint-disable-next-line no-null/no-null\n const timerRef = useRef<number | undefined>(null);\n\n const { transitionClassNames } = useShowTransition(isOpen);\n\n const closeAndDismiss = useCallback(() => {\n setIsOpen(false);\n setTimeout(onDismiss, ANIMATION_DURATION + ANIMATION_END_DELAY);\n }, [onDismiss]);\n\n useEffect(() => (isOpen ? captureEscKeyListener(closeAndDismiss) : undefined), [isOpen, closeAndDismiss]);\n\n useEffect(() => {\n timerRef.current = window.setTimeout(closeAndDismiss, duration);\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n };\n }, [duration, closeAndDismiss]);\n\n const handleMouseEnter = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n timerRef.current = window.setTimeout(closeAndDismiss, duration);\n }, [duration, closeAndDismiss]);\n\n return (\n <Portal className=\"Notification-container\" containerId={containerId}>\n <div\n className={buildClassName('Notification', transitionClassNames)}\n onClick={closeAndDismiss}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <div className=\"content\">\n {message}\n </div>\n </div>\n </Portal>\n );\n};\n\nexport default Notification;\n","import { FC, useRef, useLayoutEffect } from '../../lib/teact/teact';\nimport TeactDOM from '../../lib/teact/teact-dom';\n\ntype OwnProps = {\n containerId?: string;\n className?: string;\n children: any;\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 React, {\n FC, useEffect, useRef, memo,\n} from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport './ProgressSpinner.scss';\n\nconst RADIUSES = {\n s: 22, m: 25, l: 28, xl: 20,\n};\nconst STROKE_WIDTH = 2;\nconst MIN_PROGRESS = 0.05;\nconst MAX_PROGRESS = 1;\n\nconst ProgressSpinner: FC<{\n progress?: number;\n size?: 's' | 'm' | 'l' | 'xl';\n square?: boolean;\n transparent?: boolean;\n noCross?: boolean;\n onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n}> = ({\n progress = 0,\n size = 'l',\n square,\n transparent,\n noCross,\n onClick,\n}) => {\n const radius = RADIUSES[size];\n const circleRadius = radius - STROKE_WIDTH * 2;\n const borderRadius = radius - 1;\n const circumference = circleRadius * 2 * Math.PI;\n // eslint-disable-next-line no-null/no-null\n const container = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!container.current) {\n return;\n }\n\n const svg = container.current.firstElementChild;\n const strokeDashOffset = circumference - Math.min(Math.max(MIN_PROGRESS, progress), MAX_PROGRESS) * circumference;\n\n if (!svg) {\n container.current.innerHTML = `<svg\n viewBox=\"0 0 ${borderRadius * 2} ${borderRadius * 2}\"\n height=\"${borderRadius * 2}\"\n width=\"${borderRadius * 2}\"\n >\n <circle\n stroke=\"white\"\n fill=\"transparent\"\n stroke-width=${STROKE_WIDTH}\n stroke-dasharray=\"${circumference} ${circumference}\"}\n stroke-dashoffset=\"${strokeDashOffset}\"\n stroke-linecap=\"round\"\n r=${circleRadius}\n cx=${borderRadius}\n cy=${borderRadius}\n />\n </svg>`;\n } else {\n (svg.firstElementChild as SVGElement).setAttribute('stroke-dashoffset', strokeDashOffset.toString());\n }\n }, [container, circumference, borderRadius, circleRadius, progress]);\n\n const className = buildClassName(\n `ProgressSpinner size-${size}`,\n transparent && 'transparent',\n square && 'square',\n noCross && 'no-cross',\n );\n\n return (\n <div\n ref={container}\n className={className}\n onClick={onClick}\n />\n );\n};\n\nexport default memo(ProgressSpinner);\n","import { ChangeEvent } from 'react';\nimport React, { FC, memo } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport Spinner from './Spinner';\n\nimport './Radio.scss';\n\ntype OwnProps = {\n id?: string;\n name: string;\n label: string;\n subLabel?: string;\n value: string;\n checked: boolean;\n disabled?: boolean;\n hidden?: boolean;\n isLoading?: boolean;\n onChange: (e: ChangeEvent<HTMLInputElement>) => void;\n};\n\nconst Radio: FC<OwnProps> = ({\n id,\n label,\n subLabel,\n value,\n name,\n checked,\n disabled,\n hidden,\n isLoading,\n onChange,\n}) => {\n const lang = useLang();\n const className = buildClassName(\n 'Radio',\n disabled && 'disabled',\n hidden && 'hidden-widget',\n isLoading && 'loading',\n );\n\n return (\n <label className={className} dir={lang.isRtl ? 'rtl' : undefined}>\n <input\n type=\"radio\"\n name={name}\n value={value}\n id={id}\n checked={checked}\n onChange={onChange}\n disabled={disabled || hidden}\n />\n <div className=\"Radio-main\">\n <span className=\"label\" dir={lang.isRtl ? 'auto' : undefined}>{label}</span>\n {subLabel && <span className=\"subLabel\" dir={lang.isRtl ? 'auto' : undefined}>{subLabel}</span>}\n </div>\n {isLoading && <Spinner />}\n </label>\n );\n};\n\nexport default memo(Radio);\n","import { ChangeEvent } from 'react';\nimport React, { FC, useCallback, memo } from '../../lib/teact/teact';\n\nimport Radio from './Radio';\n\ntype IRadioOption = {\n label: string;\n subLabel?: string;\n value: string;\n hidden?: boolean;\n};\n\ntype OwnProps = {\n id?: string;\n name: string;\n options: IRadioOption[];\n selected?: string;\n disabled?: boolean;\n loadingOption?: string;\n onChange: (value: string) => void;\n};\n\nconst RadioGroup: FC<OwnProps> = ({\n id,\n name,\n options,\n selected,\n disabled,\n loadingOption,\n onChange,\n}) => {\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n const { value } = event.currentTarget;\n onChange(value);\n }, [onChange]);\n\n return (\n <div id={id} className=\"radio-group\">\n {options.map((option) => (\n <Radio\n name={name}\n label={option.label}\n subLabel={option.subLabel}\n value={option.value}\n checked={option.value === selected}\n hidden={option.hidden}\n disabled={disabled}\n isLoading={loadingOption ? loadingOption === option.value : undefined}\n onChange={handleChange}\n />\n ))}\n </div>\n );\n};\n\nexport default memo(RadioGroup);\n","import { RefObject } from 'react';\nimport React, {\n FC, useRef, useEffect, memo, useCallback,\n} from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useFlag from '../../hooks/useFlag';\nimport useLang from '../../hooks/useLang';\n\nimport Loading from './Loading';\nimport Button from './Button';\n\nimport './SearchInput.scss';\n\ntype OwnProps = {\n ref?: RefObject<HTMLInputElement>;\n children?: any;\n parentContainerClassName?: string;\n className?: string;\n inputId?: string;\n value?: string;\n focused?: boolean;\n isLoading?: boolean;\n placeholder?: string;\n disabled?: boolean;\n autoComplete?: string;\n canClose?: boolean;\n onChange: (value: string) => void;\n onReset?: NoneToVoidFunction;\n onFocus?: NoneToVoidFunction;\n onBlur?: NoneToVoidFunction;\n};\n\nconst SearchInput: FC<OwnProps> = ({\n ref,\n children,\n parentContainerClassName,\n value,\n inputId,\n className,\n focused,\n isLoading,\n placeholder,\n disabled,\n autoComplete,\n canClose,\n onChange,\n onReset,\n onFocus,\n onBlur,\n}) => {\n // eslint-disable-next-line no-null/no-null\n let inputRef = useRef<HTMLInputElement>(null);\n if (ref) {\n inputRef = ref;\n }\n\n const [isInputFocused, markInputFocused, unmarkInputFocused] = useFlag(focused);\n\n useEffect(() => {\n if (!inputRef.current) {\n return;\n }\n\n if (focused) {\n inputRef.current.focus();\n } else {\n inputRef.current.blur();\n }\n }, [focused, placeholder]); // Trick for setting focus when selecting a contact to search for\n\n const lang = useLang();\n\n function handleChange(event: React.ChangeEvent<HTMLInputElement>) {\n const { currentTarget } = event;\n onChange(currentTarget.value);\n }\n\n function handleFocus() {\n markInputFocused();\n if (onFocus) {\n onFocus();\n }\n }\n\n function handleBlur() {\n unmarkInputFocused();\n if (onBlur) {\n onBlur();\n }\n }\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter') {\n const element = document.querySelector(`.${parentContainerClassName} .ListItem-button`) as HTMLElement;\n if (element) {\n element.focus();\n }\n }\n }, [parentContainerClassName]);\n\n return (\n <div\n className={buildClassName('SearchInput', className, isInputFocused && 'has-focus')}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {children}\n <input\n ref={inputRef}\n id={inputId}\n type=\"text\"\n dir=\"auto\"\n placeholder={placeholder || lang('Search')}\n className=\"form-control\"\n value={value}\n disabled={disabled}\n autoComplete={autoComplete}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n />\n <i className=\"icon-search\" />\n {isLoading && (\n <Loading />\n )}\n {!isLoading && (value || canClose) && onReset && (\n <Button\n round\n size=\"tiny\"\n color=\"translucent\"\n onClick={onReset}\n >\n <span className=\"icon-close\" />\n </Button>\n )}\n </div>\n );\n};\n\nexport default memo(SearchInput);\n","import React, { FC, useRef } from '../../lib/teact/teact';\n\nimport useShowTransition from '../../hooks/useShowTransition';\nimport usePrevious from '../../hooks/usePrevious';\nimport buildClassName from '../../util/buildClassName';\n\ntype ChildrenFn = () => any;\n\ntype OwnProps = {\n isOpen: boolean;\n isCustom?: boolean;\n id?: string;\n className?: string;\n onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n children: ChildrenFn;\n};\n\nconst ShowTransition: FC<OwnProps> = ({\n isOpen, isCustom, id, className, onClick, children,\n}) => {\n const { shouldRender, transitionClassNames } = useShowTransition(\n isOpen, undefined, undefined, isCustom ? false : undefined,\n );\n const prevIsOpen = usePrevious(isOpen);\n const prevChildren = usePrevious(children);\n const fromChildrenRef = useRef<ChildrenFn>();\n\n if (prevIsOpen && !isOpen) {\n fromChildrenRef.current = prevChildren;\n }\n\n return (\n shouldRender && (\n <div id={id} className={buildClassName(className, transitionClassNames)} onClick={onClick}>\n {isOpen ? children() : fromChildrenRef.current!()}\n </div>\n )\n );\n};\n\nexport default ShowTransition;\n","import { ChangeEvent } from 'react';\nimport React, { FC, memo, useCallback } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport './Switcher.scss';\n\ntype OwnProps = {\n id?: string;\n name?: string;\n value?: string;\n label: string;\n checked?: boolean;\n disabled?: boolean;\n inactive?: boolean;\n noAnimation?: boolean;\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void;\n onCheck?: (isChecked: boolean) => void;\n};\n\nconst Switcher: FC<OwnProps> = ({\n id,\n name,\n value,\n label,\n checked = false,\n disabled,\n inactive,\n noAnimation,\n onChange,\n onCheck,\n}) => {\n const handleChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n onChange(e);\n }\n\n if (onCheck) {\n onCheck(e.currentTarget.checked);\n }\n }, [onChange, onCheck]);\n\n const className = buildClassName(\n 'Switcher',\n disabled && 'disabled',\n inactive && 'inactive',\n noAnimation && 'no-animation',\n );\n\n return (\n <label className={className} title={label}>\n <input\n type=\"checkbox\"\n id={id}\n name={name}\n value={value}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n />\n <span className=\"widget\" />\n </label>\n );\n};\n\nexport default memo(Switcher);\n","import React, {\n FC, useLayoutEffect, useRef, memo,\n} from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport renderText from '../common/helpers/renderText';\n\nimport './Tab.scss';\n\ntype OwnProps = {\n className?: string;\n title: string;\n active?: boolean;\n badgeCount?: number;\n isBadgeActive?: boolean;\n previousActiveTab?: number;\n onClick: (arg: number) => void;\n clickArg: number;\n};\n\nconst Tab: FC<OwnProps> = ({\n className,\n title,\n active,\n badgeCount,\n isBadgeActive,\n previousActiveTab,\n onClick,\n clickArg,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const tabRef = useRef<HTMLButtonElement>(null);\n\n useLayoutEffect(() => {\n if (!active || previousActiveTab === undefined) {\n return;\n }\n\n const tab = tabRef.current!;\n const indicator = tab.querySelector('i')!;\n const prevTab = tab.parentElement!.children[previousActiveTab];\n if (!prevTab) {\n return;\n }\n const currentIndicator = prevTab.querySelector('i')!;\n\n currentIndicator.classList.remove('animate');\n indicator.classList.remove('animate');\n\n // We move and resize our indicator so it repeats the position and size of the previous one.\n const shiftLeft = currentIndicator.parentElement!.offsetLeft - indicator.parentElement!.offsetLeft;\n const scaleFactor = currentIndicator.clientWidth / indicator.clientWidth;\n indicator.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;\n\n // 3 AFs needed here to synchronize animations with Transition component\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n // Now we remove the transform to let it animate to its own position and size.\n indicator.classList.add('animate');\n indicator.style.transform = 'none';\n });\n });\n });\n }, [active, previousActiveTab]);\n\n return (\n <button\n type=\"button\"\n className={buildClassName('Tab', className, active && 'active')}\n onClick={() => onClick(clickArg)}\n ref={tabRef}\n >\n <span>\n {renderText(title)}\n {!!badgeCount && (\n <span className={buildClassName('badge', isBadgeActive && 'active')}>{badgeCount}</span>\n )}\n <i />\n </span>\n </button>\n );\n};\n\nexport default memo(Tab);\n","import React, {\n FC, memo, useRef, useEffect,\n} from '../../lib/teact/teact';\n\nimport fastSmoothScrollHorizontal from '../../util/fastSmoothScrollHorizontal';\nimport usePrevious from '../../hooks/usePrevious';\nimport useHorizontalScroll from '../../hooks/useHorizontalScroll';\nimport useLang from '../../hooks/useLang';\n\nimport Tab from './Tab';\n\nimport './TabList.scss';\n\nexport type TabWithProperties = {\n title: string;\n badgeCount?: number;\n isBadgeActive?: boolean;\n};\n\ntype OwnProps = {\n tabs: readonly TabWithProperties[];\n activeTab: number;\n big?: boolean;\n onSwitchTab: (index: number) => void;\n};\n\nconst TAB_SCROLL_THRESHOLD_PX = 16;\n\nconst TabList: FC<OwnProps> = ({\n tabs, activeTab, big, onSwitchTab,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const containerRef = useRef<HTMLDivElement>(null);\n const previousActiveTab = usePrevious(activeTab);\n\n useHorizontalScroll(containerRef.current);\n\n // Scroll container to place active tab in the center\n useEffect(() => {\n const container = containerRef.current!;\n if (container.scrollWidth <= container.offsetWidth) {\n return;\n }\n\n const activeTabElement = container.querySelector('.Tab.active') as HTMLElement | null;\n if (activeTabElement) {\n const newLeft = activeTabElement.offsetLeft - (container.offsetWidth / 2) + (activeTabElement.offsetWidth / 2);\n\n // Prevent scrolling by only a couple of pixels, which doesn't look smooth\n if (Math.abs(newLeft - container.scrollLeft) < TAB_SCROLL_THRESHOLD_PX) {\n return;\n }\n\n fastSmoothScrollHorizontal(container, newLeft);\n }\n }, [activeTab]);\n\n const lang = useLang();\n\n return (\n <div\n className={`TabList no-selection no-scrollbar ${big ? 'big' : ''}`}\n ref={containerRef}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {tabs.map((tab, i) => (\n <Tab\n key={tab.title}\n title={lang(tab.title)}\n active={i === activeTab}\n badgeCount={tab.badgeCount}\n isBadgeActive={tab.isBadgeActive}\n previousActiveTab={previousActiveTab}\n onClick={onSwitchTab}\n clickArg={i}\n />\n ))}\n </div>\n );\n};\n\nexport default memo(TabList);\n","import { RefObject } from 'react';\nimport React, {\n FC, useLayoutEffect, useRef,\n} from '../../lib/teact/teact';\nimport { getGlobal } from '../../lib/teact/teactn';\n\nimport useForceUpdate from '../../hooks/useForceUpdate';\nimport usePrevious from '../../hooks/usePrevious';\nimport buildClassName from '../../util/buildClassName';\nimport { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';\nimport { waitForAnimationEnd } from '../../util/cssAnimationEndListeners';\n\nimport './Transition.scss';\n\ntype ChildrenFn = (isActive: boolean, isFrom: boolean, currentKey: number) => any;\ntype OwnProps = {\n ref?: RefObject<HTMLDivElement>;\n activeKey: number;\n name: (\n 'none' | 'slide' | 'slide-reversed' | 'mv-slide' | 'slide-fade' | 'zoom-fade' | 'slide-layers'\n | 'fade' | 'push-slide' | 'reveal'\n );\n direction?: 'auto' | 'inverse' | 1 | -1;\n renderCount?: number;\n shouldRestoreHeight?: boolean;\n shouldCleanup?: boolean;\n cleanupExceptionKey?: number;\n id?: string;\n className?: string;\n onStart?: () => void;\n onStop?: () => void;\n children: ChildrenFn;\n};\n\nconst CLEANED_UP = Symbol('CLEANED_UP');\n\nconst Transition: FC<OwnProps> = ({\n ref,\n activeKey,\n name,\n direction = 'auto',\n renderCount,\n shouldRestoreHeight,\n shouldCleanup,\n cleanupExceptionKey,\n id,\n className,\n onStart,\n onStop,\n children,\n}) => {\n // No need for a container to update on change\n const { animationLevel } = getGlobal().settings.byKey;\n const currentKeyRef = useRef<number>();\n\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 rendersRef = useRef<Record<number, ChildrenFn | typeof CLEANED_UP>>({});\n const prevActiveKey = usePrevious<any>(activeKey);\n const forceUpdate = useForceUpdate();\n\n const activeKeyChanged = prevActiveKey !== undefined && activeKey !== prevActiveKey;\n\n if (!renderCount && activeKeyChanged) {\n rendersRef.current = { [prevActiveKey]: rendersRef.current[prevActiveKey] };\n }\n\n rendersRef.current[activeKey] = children;\n\n useLayoutEffect(() => {\n function cleanup() {\n if (!shouldCleanup || (cleanupExceptionKey !== undefined && cleanupExceptionKey === prevActiveKey)) {\n return;\n }\n\n rendersRef.current = { [prevActiveKey]: CLEANED_UP };\n forceUpdate();\n }\n\n const container = containerRef.current!;\n\n const childElements = container.children;\n if (childElements.length === 1 && !activeKeyChanged) {\n childElements[0].classList.add('active');\n\n return;\n }\n\n const childNodes = Array.from(container.childNodes);\n\n if (!activeKeyChanged || !childNodes.length) {\n return;\n }\n\n const isBackwards = (\n direction === -1\n || (direction === 'auto' && prevActiveKey > activeKey)\n || (direction === 'inverse' && prevActiveKey < activeKey)\n );\n\n container.classList.remove('animating');\n container.classList.toggle('backwards', isBackwards);\n\n const keys = Object.keys(rendersRef.current).map(Number);\n const prevActiveIndex = renderCount ? prevActiveKey : keys.indexOf(prevActiveKey);\n const activeIndex = renderCount ? activeKey : keys.indexOf(activeKey);\n\n if (name === 'none' || animationLevel === 0) {\n childNodes.forEach((node, i) => {\n if (node instanceof HTMLElement) {\n node.classList.remove('from', 'through', 'to');\n node.classList.toggle('active', i === activeIndex);\n }\n });\n\n cleanup();\n\n return;\n }\n\n childNodes.forEach((node, i) => {\n if (node instanceof HTMLElement) {\n node.classList.remove('active');\n node.classList.toggle('from', i === prevActiveIndex);\n node.classList.toggle('through', (\n (i > prevActiveIndex && i < activeIndex) || (i < prevActiveIndex && i > activeIndex)\n ));\n node.classList.toggle('to', i === activeIndex);\n }\n });\n\n let dispatchHeavyAnimationStop: NoneToVoidFunction;\n if (animationLevel > 0) {\n dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();\n }\n\n requestAnimationFrame(() => {\n container.classList.add('animating');\n\n if (onStart) {\n onStart();\n }\n\n function onAnimationEnd() {\n requestAnimationFrame(() => {\n if (activeKey !== currentKeyRef.current) {\n return;\n }\n\n container.classList.remove('animating', 'backwards');\n\n childNodes.forEach((node, i) => {\n if (node instanceof HTMLElement) {\n node.classList.remove('from', 'through', 'to');\n node.classList.toggle('active', i === activeIndex);\n }\n });\n\n if (shouldRestoreHeight) {\n const activeElement = container.querySelector<HTMLDivElement>('.active');\n\n if (activeElement) {\n activeElement.style.height = 'auto';\n container.style.height = `${activeElement.clientHeight}px`;\n }\n }\n\n if (dispatchHeavyAnimationStop) {\n dispatchHeavyAnimationStop();\n }\n\n cleanup();\n\n if (onStop) {\n onStop();\n }\n });\n }\n\n const watchedNode = name === 'mv-slide'\n ? childNodes[activeIndex] && childNodes[activeIndex].firstChild\n : name === 'reveal' && isBackwards\n ? childNodes[prevActiveIndex]\n : childNodes[activeIndex];\n\n currentKeyRef.current = activeKey;\n\n if (animationLevel > 0 && watchedNode) {\n waitForAnimationEnd(watchedNode, onAnimationEnd);\n } else {\n onAnimationEnd();\n }\n });\n }, [\n activeKey,\n prevActiveKey,\n activeKeyChanged,\n direction,\n name,\n onStart,\n onStop,\n renderCount,\n shouldRestoreHeight,\n shouldCleanup,\n cleanupExceptionKey,\n animationLevel,\n forceUpdate,\n ]);\n\n useLayoutEffect(() => {\n if (shouldRestoreHeight) {\n const container = containerRef.current!;\n const activeElement = container.querySelector<HTMLDivElement>('.active')\n || container.querySelector<HTMLDivElement>('.from');\n\n if (activeElement) {\n activeElement.style.height = 'auto';\n container.style.height = `${activeElement.clientHeight}px`;\n container.style.flexBasis = `${activeElement.clientHeight}px`;\n }\n }\n }, [shouldRestoreHeight, children]);\n\n const renders = rendersRef.current;\n const collection = Object.keys(renderCount ? new Array(renderCount).fill(undefined) : renders).map(Number);\n const contents = collection.map((key) => {\n const render = renders[key];\n\n return (\n typeof render === 'function'\n ? <div key={key}>{render(key === activeKey, key === prevActiveKey, activeKey)}</div>\n : undefined\n );\n });\n\n const fullClassName = buildClassName(\n 'Transition',\n className,\n name,\n );\n\n return (\n <div ref={containerRef} id={id} className={fullClassName}>\n {contents}\n </div>\n );\n};\n\nexport default Transition;\n","import useReducer, { StateReducer, Dispatch } from '../useReducer';\nimport { ApiChatFolder } from '../../api/types';\nimport { pick, omit } from '../../util/iteratees';\n\nexport type FolderChatType = {\n icon: string;\n title: string;\n key: keyof Pick<ApiChatFolder, (\n 'contacts' | 'nonContacts' | 'groups' | 'channels' | 'bots' |\n 'excludeMuted' | 'excludeArchived' | 'excludeRead'\n )>;\n};\n\nexport const INCLUDED_CHAT_TYPES: FolderChatType[] = [\n { icon: 'user', title: 'FilterContacts', key: 'contacts' },\n { icon: 'non-contacts', title: 'FilterNonContacts', key: 'nonContacts' },\n { icon: 'group', title: 'FilterGroups', key: 'groups' },\n { icon: 'channel', title: 'FilterChannels', key: 'channels' },\n { icon: 'bots', title: 'FilterBots', key: 'bots' },\n];\n\nexport const EXCLUDED_CHAT_TYPES: FolderChatType[] = [\n { icon: 'mute', title: 'FilterMuted', key: 'excludeMuted' },\n { icon: 'archive', title: 'FilterArchived', key: 'excludeArchived' },\n { icon: 'readchats', title: 'FilterRead', key: 'excludeRead' },\n];\n\nconst INCLUDE_FILTER_FIELDS: Array<keyof FolderIncludeFilters> = [\n 'includedChatIds', 'bots', 'channels', 'groups', 'contacts', 'nonContacts',\n];\nconst EXCLUDE_FILTER_FIELDS: Array<keyof FolderExcludeFilters> = [\n 'excludedChatIds', 'excludeArchived', 'excludeMuted', 'excludeRead',\n];\n\nexport function selectChatFilters(state: FoldersState, mode: 'included' | 'excluded', selectTemp?: boolean) {\n let selectedChatIds: number[] = [];\n let selectedChatTypes: FolderChatType['key'][] = [];\n\n if (mode === 'included') {\n const {\n includedChatIds,\n ...includeFilters\n } = selectTemp\n ? state.includeFilters || {}\n : pick(\n state.folder,\n INCLUDE_FILTER_FIELDS,\n );\n\n selectedChatIds = includedChatIds || [];\n selectedChatTypes = (Object.keys(includeFilters) as Array<keyof typeof includeFilters>)\n .filter((key) => Boolean(includeFilters[key]));\n } else {\n const {\n excludedChatIds,\n ...excludeFilters\n } = selectTemp\n ? state.excludeFilters || {}\n : pick(\n state.folder,\n EXCLUDE_FILTER_FIELDS,\n );\n\n selectedChatIds = excludedChatIds || [];\n selectedChatTypes = (Object.keys(excludeFilters) as Array<keyof typeof excludeFilters>)\n .filter((key) => Boolean(excludeFilters[key]));\n }\n\n return {\n selectedChatIds,\n selectedChatTypes,\n };\n}\n\nfunction getSuggestedFolderName(includeFilters?: FolderIncludeFilters) {\n if (includeFilters) {\n const {\n includedChatIds,\n ...filters\n } = includeFilters;\n\n if (\n Object.values(filters).filter(Boolean).length > 1\n || (includedChatIds && includedChatIds.length)\n ) {\n return '';\n }\n\n if (filters.bots) {\n return 'Bots';\n } else if (filters.groups) {\n return 'Groups';\n } else if (filters.channels) {\n return 'Channels';\n } else if (filters.contacts) {\n return 'Contacts';\n } else if (filters.nonContacts) {\n return 'Non-Contacts';\n }\n }\n\n return '';\n}\n\ntype FolderIncludeFilters = Pick<ApiChatFolder, (\n 'includedChatIds' | 'bots' | 'channels' | 'groups' | 'contacts' | 'nonContacts'\n)>;\ntype FolderExcludeFilters = Pick<ApiChatFolder, 'excludedChatIds' | 'excludeArchived' | 'excludeMuted' | 'excludeRead'>;\n\nexport type FoldersState = {\n mode: 'create' | 'edit';\n isLoading?: boolean;\n isTouched?: boolean;\n error?: string;\n folderId?: number;\n chatFilter: string;\n folder: Omit<ApiChatFolder, 'id' | 'description' | 'emoticon'>;\n includeFilters?: FolderIncludeFilters;\n excludeFilters?: FolderExcludeFilters;\n};\nexport type FoldersActions = (\n 'setTitle' | 'saveFilters' | 'editFolder' | 'reset' | 'setChatFilter' | 'setIsLoading' | 'setError' |\n 'editIncludeFilters' | 'editExcludeFilters' | 'setIncludeFilters' | 'setExcludeFilters'\n);\nexport type FolderEditDispatch = Dispatch<FoldersActions>;\n\nconst INITIAL_STATE: FoldersState = {\n mode: 'create',\n chatFilter: '',\n folder: {\n title: '',\n includedChatIds: [],\n excludedChatIds: [],\n },\n};\n\nconst foldersReducer: StateReducer<FoldersState, FoldersActions> = (\n state,\n action,\n) => {\n switch (action.type) {\n case 'setTitle':\n return {\n ...state,\n folder: {\n ...state.folder,\n title: action.payload,\n },\n isTouched: true,\n };\n case 'editIncludeFilters':\n return {\n ...state,\n includeFilters: pick(\n state.folder,\n INCLUDE_FILTER_FIELDS,\n ),\n };\n case 'editExcludeFilters':\n return {\n ...state,\n excludeFilters: pick(\n state.folder,\n EXCLUDE_FILTER_FIELDS,\n ),\n };\n case 'setIncludeFilters':\n return {\n ...state,\n includeFilters: action.payload,\n chatFilter: '',\n };\n case 'setExcludeFilters':\n return {\n ...state,\n excludeFilters: action.payload,\n chatFilter: '',\n };\n case 'saveFilters':\n if (state.includeFilters) {\n return {\n ...state,\n folder: {\n ...omit(state.folder, INCLUDE_FILTER_FIELDS),\n title: state.folder.title ? state.folder.title : getSuggestedFolderName(state.includeFilters),\n ...state.includeFilters,\n },\n includeFilters: undefined,\n chatFilter: '',\n isTouched: true,\n };\n } else if (state.excludeFilters) {\n return {\n ...state,\n folder: {\n ...omit(state.folder, EXCLUDE_FILTER_FIELDS),\n ...state.excludeFilters,\n },\n excludeFilters: undefined,\n chatFilter: '',\n isTouched: true,\n };\n } else {\n return state;\n }\n case 'editFolder': {\n const { id: folderId, description, ...folder } = action.payload;\n\n return {\n mode: 'edit',\n folderId,\n folder,\n chatFilter: '',\n };\n }\n case 'setChatFilter': {\n return {\n ...state,\n chatFilter: action.payload,\n };\n }\n case 'setIsLoading': {\n return {\n ...state,\n isLoading: action.payload,\n };\n }\n case 'setError': {\n return {\n ...state,\n error: action.payload,\n };\n }\n case 'reset':\n return INITIAL_STATE;\n default:\n return state;\n }\n};\n\nexport default () => {\n return useReducer(foldersReducer, INITIAL_STATE);\n};\n","import {\n useCallback, useEffect, useRef, useState,\n} from '../lib/teact/teact';\n\nimport { register } from '../util/audioPlayer';\nimport useEffectWithPrevDeps from './useEffectWithPrevDeps';\nimport { isSafariPatchInProgress } from '../util/patchSafariProgressiveAudio';\nimport useOnChange from './useOnChange';\n\ntype Handler = (e: Event) => void;\n\nexport default (\n trackId: string,\n originalDuration: number, // Sometimes incorrect for voice messages\n src?: string,\n handlers?: Record<string, Handler>,\n onInit?: (element: HTMLAudioElement) => void,\n shouldPlay = false,\n onForcePlay?: NoneToVoidFunction,\n noPlaylist = false,\n) => {\n // eslint-disable-next-line no-null/no-null\n const controllerRef = useRef<ReturnType<typeof register>>(null);\n\n const [isPlaying, setIsPlaying] = useState(false);\n let isPlayingSync = isPlaying;\n\n const [playProgress, setPlayProgress] = useState<number>(0);\n\n useOnChange(() => {\n controllerRef.current = register(trackId, (eventName, e) => {\n switch (eventName) {\n case 'onPlay':\n setIsPlaying(true);\n break;\n case 'onPause':\n setIsPlaying(false);\n break;\n case 'onTimeUpdate': {\n const { proxy } = controllerRef.current!;\n const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;\n setPlayProgress(proxy.currentTime / duration);\n break;\n }\n }\n\n if (handlers && handlers[eventName]) {\n handlers[eventName](e);\n }\n }, onForcePlay);\n\n const { proxy } = controllerRef.current!;\n\n if (!isPlaying && !proxy.paused) {\n setIsPlaying(true);\n isPlayingSync = true;\n }\n\n if (onInit) {\n onInit(proxy);\n }\n }, [trackId]);\n\n const {\n play, pause, setCurrentTime, proxy, destroy,\n } = controllerRef.current!;\n const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;\n\n // RAF progress\n useEffect(() => {\n if (duration && !isSafariPatchInProgress(proxy)) {\n setPlayProgress(proxy.currentTime / duration);\n }\n }, [duration, playProgress, proxy]);\n\n // Cleanup\n useEffect(() => () => {\n destroy(noPlaylist);\n }, [destroy, noPlaylist]);\n\n // Autoplay once `src` is present\n useEffectWithPrevDeps(([prevShouldPlay, prevSrc]) => {\n if (prevShouldPlay === shouldPlay && src === prevSrc) {\n return;\n }\n\n // When paused by another player\n if (proxy.src && proxy.paused) {\n return;\n }\n\n if (shouldPlay && src && !isPlaying) {\n play(src);\n }\n }, [shouldPlay, src, isPlaying, play, proxy.src, proxy.paused]);\n\n const playPause = useCallback(() => {\n if (isPlaying) {\n pause();\n } else if (src) {\n play(src);\n }\n }, [src, pause, play, isPlaying]);\n\n return {\n isPlaying: isPlayingSync,\n playProgress,\n playPause,\n setCurrentTime,\n audioProxy: proxy,\n duration,\n };\n};\n","import { useEffect } from '../lib/teact/teact';\n\nexport default function useBackgroundMode(\n onBlur?: AnyToVoidFunction,\n onFocus?: AnyToVoidFunction,\n) {\n useEffect(() => {\n if (onBlur && !document.hasFocus()) {\n onBlur();\n }\n\n if (onBlur) {\n window.addEventListener('blur', onBlur);\n }\n\n if (onFocus) {\n window.addEventListener('focus', onFocus);\n }\n\n return () => {\n if (onFocus) {\n window.removeEventListener('focus', onFocus);\n }\n\n if (onBlur) {\n window.removeEventListener('blur', onBlur);\n }\n };\n }, [onBlur, onFocus]);\n}\n","import { useEffect, useRef } from '../lib/teact/teact';\n\nimport fastBlur from '../lib/fastBlur';\nimport { imgToCanvas } from '../util/files';\nimport useForceUpdate from './useForceUpdate';\n\nconst RADIUS = 2;\nconst ITERATIONS = 2;\nconst MAX_CACHE_SIZE = 1000;\n\nconst cache = new Map<string, string>();\n\nexport default function useBlur(dataUri?: string, isDisabled = false, delay?: number) {\n const blurredRef = useRef<string | undefined>(dataUri ? cache.get(dataUri) : undefined);\n const timeoutRef = useRef<number>();\n const forceUpdate = useForceUpdate();\n\n if (timeoutRef.current && isDisabled) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n\n useEffect(() => {\n if (!dataUri || blurredRef.current || isDisabled) {\n return;\n }\n\n const img = new Image();\n\n img.onload = () => {\n const canvas = imgToCanvas(img);\n fastBlur(canvas.getContext('2d'), 0, 0, canvas.width, canvas.height, RADIUS, ITERATIONS);\n const blurredDataUri = canvas.toDataURL();\n\n blurredRef.current = blurredDataUri;\n forceUpdate();\n\n if (cache.size >= MAX_CACHE_SIZE) {\n cache.clear();\n }\n cache.set(dataUri, blurredDataUri);\n };\n\n if (delay) {\n timeoutRef.current = window.setTimeout(() => {\n img.src = dataUri;\n }, delay);\n } else {\n img.src = dataUri;\n }\n }, [dataUri, delay, forceUpdate, isDisabled]);\n\n return blurredRef.current;\n}\n","import { useRef } from '../lib/teact/teact';\n\nimport fastBlur from '../lib/fastBlur';\nimport useOnChange from './useOnChange';\nimport useBlur from './useBlur';\nimport { imgToCanvas } from '../util/files';\n\nconst RADIUS = 2;\nconst ITERATIONS = 2;\n\nexport default function useBlurSync(dataUri: string | false | undefined) {\n const blurredRef = useRef<string>();\n\n let isChanged = false;\n\n useOnChange(() => {\n isChanged = true;\n\n blurredRef.current = undefined;\n\n if (!dataUri) {\n return;\n }\n\n const img = new Image();\n img.src = dataUri;\n if (!img.width) {\n return;\n }\n\n const canvas = imgToCanvas(img);\n fastBlur(canvas.getContext('2d'), 0, 0, canvas.width, canvas.height, RADIUS, ITERATIONS);\n\n blurredRef.current = canvas.toDataURL();\n }, [dataUri]);\n\n // Sometimes `Image` do not manage to load synchronously,\n // so we fall back the non-blurred variant and prepare the async one at least for the next time\n const blurredAsync = useBlur(dataUri || undefined, Boolean(blurredRef.current));\n\n return blurredRef.current || (!isChanged && blurredAsync) || dataUri || undefined;\n}\n","import React, { useCallback, useMemo, useState } from '../lib/teact/teact';\nimport { debounce } from '../util/schedulers';\nimport { isSafariPatchInProgress } from '../util/patchSafariProgressiveAudio';\n\ntype BufferingEvent = (e: Event | React.SyntheticEvent<HTMLMediaElement>) => void;\n\nconst MIN_READY_STATE = 3;\n// Avoid flickering when re-mounting previously buffered video\nconst DEBOUNCE = 200;\n\nexport default (noInitiallyBuffered = false) => {\n const [isBuffered, setIsBuffered] = useState(!noInitiallyBuffered);\n const [bufferedProgress, setBufferedProgress] = useState(0);\n\n const setIsBufferedDebounced = useMemo(() => {\n return debounce(setIsBuffered, DEBOUNCE, false, true);\n }, []);\n\n const handleBuffering = useCallback<BufferingEvent>((e) => {\n const media = e.currentTarget as HTMLMediaElement;\n\n if (!isSafariPatchInProgress(media)) {\n if (media.buffered.length) {\n setBufferedProgress(media.buffered.end(0) / media.duration);\n }\n\n setIsBufferedDebounced(media.readyState >= MIN_READY_STATE || media.currentTime > 0);\n }\n }, [setIsBufferedDebounced]);\n\n const bufferingHandlers = {\n onLoadedData: handleBuffering,\n onPlaying: handleBuffering,\n onLoadStart: handleBuffering, // Needed for Safari to start\n onPause: handleBuffering, // Needed for Chrome when seeking\n onTimeUpdate: handleBuffering, // Needed for audio buffering progress\n onProgress: handleBuffering, // Needed for video buffering progress\n };\n\n return {\n isBuffered,\n bufferedProgress,\n bufferingHandlers,\n checkBuffering(element: HTMLMediaElement) {\n setIsBufferedDebounced(element.readyState >= MIN_READY_STATE);\n },\n };\n};\n","import { useEffect, useRef } from '../lib/teact/teact';\n\nimport fastBlur from '../lib/fastBlur';\nimport useForceUpdate from './useForceUpdate';\nimport { IS_CANVAS_FILTER_SUPPORTED } from '../util/environment';\n\nconst RADIUS = 2;\nconst ITERATIONS = 2;\n\nexport default function useCanvasBlur(dataUri?: string, isDisabled = false, withRaf?: boolean) {\n // eslint-disable-next-line no-null/no-null\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n const canvas = canvasRef.current;\n\n if (!dataUri || !canvas || isDisabled) {\n return;\n }\n\n const img = new Image();\n\n const processBlur = () => {\n canvas.width = img.width;\n canvas.height = img.height;\n\n const ctx = canvas.getContext('2d', { alpha: false })!;\n\n if (IS_CANVAS_FILTER_SUPPORTED) {\n ctx.filter = `blur(${RADIUS}px)`;\n }\n\n ctx.drawImage(img, -RADIUS * 2, -RADIUS * 2, canvas.width + RADIUS * 4, canvas.height + RADIUS * 4);\n\n if (!IS_CANVAS_FILTER_SUPPORTED) {\n fastBlur(ctx, 0, 0, canvas.width, canvas.height, RADIUS, ITERATIONS);\n }\n };\n\n img.onload = () => {\n if (withRaf) {\n requestAnimationFrame(processBlur);\n } else {\n processBlur();\n }\n };\n\n img.src = dataUri;\n }, [canvasRef, dataUri, forceUpdate, isDisabled, withRaf]);\n\n return canvasRef;\n}\n","import { useMemo } from '../lib/teact/teact';\nimport { getDispatch } from '../lib/teact/teactn';\n\nimport { ApiChat, ApiUser } from '../api/types';\n\nimport {\n isChatArchived, getCanDeleteChat, isChatPrivate, isChatChannel,\n} from '../modules/helpers';\nimport useLang from './useLang';\n\nexport default ({\n chat,\n privateChatUser,\n handleDelete,\n folderId,\n isPinned,\n isMuted,\n}: {\n chat: ApiChat | undefined;\n privateChatUser: ApiUser | undefined;\n handleDelete: () => void;\n folderId?: number;\n isPinned?: boolean;\n isMuted?: boolean;\n}) => {\n const lang = useLang();\n\n const {\n toggleChatPinned,\n updateChatMutedState,\n toggleChatArchived,\n toggleChatUnread,\n } = getDispatch();\n\n return useMemo(() => {\n if (!chat) {\n return undefined;\n }\n\n const isChatWithSelf = privateChatUser && privateChatUser.isSelf;\n\n const actionUnreadMark = chat.unreadCount || chat.hasUnreadMark\n ? { title: lang('MarkAsRead'), icon: 'readchats', handler: () => toggleChatUnread({ id: chat.id }) }\n : { title: lang('MarkAsUnread'), icon: 'unread', handler: () => toggleChatUnread({ id: chat.id }) };\n\n const actionPin = isPinned\n ? {\n title: lang('UnpinFromTop'),\n icon: 'unpin',\n handler: () => toggleChatPinned({ id: chat.id, folderId }),\n }\n : { title: lang('PinToTop'), icon: 'pin', handler: () => toggleChatPinned({ id: chat.id, folderId }) };\n\n const actionMute = isMuted\n ? {\n title: lang('ChatList.Unmute'),\n icon: 'unmute',\n handler: () => updateChatMutedState({ chatId: chat.id, isMuted: false }),\n }\n : {\n title: lang('ChatList.Mute'),\n icon: 'mute',\n handler: () => updateChatMutedState({ chatId: chat.id, isMuted: true }),\n };\n\n const actionArchive = isChatArchived(chat)\n ? { title: lang('Unarchive'), icon: 'unarchive', handler: () => toggleChatArchived({ id: chat.id }) }\n : { title: lang('Archive'), icon: 'archive', handler: () => toggleChatArchived({ id: chat.id }) };\n\n const actionDelete = {\n title: isChatPrivate(chat.id)\n ? lang('Delete')\n : lang(getCanDeleteChat(chat)\n ? 'DeleteChat'\n : (isChatChannel(chat) ? 'LeaveChannel' : 'Group.LeaveGroup')),\n icon: 'delete',\n destructive: true,\n handler: handleDelete,\n };\n\n return [\n actionUnreadMark,\n actionPin,\n ...(!isChatWithSelf ? [\n actionMute,\n actionArchive,\n ] : []),\n actionDelete,\n ];\n }, [\n chat, privateChatUser, lang, isPinned, handleDelete, toggleChatUnread, toggleChatPinned, folderId,\n updateChatMutedState, toggleChatArchived, isMuted,\n ]);\n};\n","import { RefObject } from 'react';\nimport { useState, useEffect, useCallback } from '../lib/teact/teact';\n\nimport { IAnchorPosition } from '../types';\nimport { IS_TOUCH_ENV, IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';\n\nconst LONG_TAP_DURATION_MS = 200;\nconst SELECTION_ANIMATION_DURATION_MS = 200;\n\nlet contextMenuCounter = 0;\n\nfunction checkIsDisabledForMobile() {\n return IS_SINGLE_COLUMN_LAYOUT\n && window.document.body.classList.contains('enable-symbol-menu-transforms');\n}\n\nexport default (\n elementRef: RefObject<HTMLElement>,\n isMenuDisabled?: boolean,\n shouldDisableOnLink?: boolean,\n shouldDisableOnLongTap?: boolean,\n) => {\n const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);\n const [contextMenuPosition, setContextMenuPosition] = useState<IAnchorPosition | undefined>(undefined);\n\n const handleBeforeContextMenu = useCallback((e: React.MouseEvent) => {\n if (!isMenuDisabled && e.button === 2) {\n document.body.classList.add('no-selection');\n }\n }, [isMenuDisabled]);\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n document.body.classList.remove('no-selection');\n\n if (isMenuDisabled || (shouldDisableOnLink && (e.target as HTMLElement).matches('a.text-entity-link[href]'))) {\n return;\n }\n e.preventDefault();\n\n if (contextMenuPosition) {\n return;\n }\n document.body.classList.remove('no-selection');\n if (contextMenuCounter === 0) {\n document.body.classList.add('has-context-menu');\n }\n contextMenuCounter++;\n\n setIsContextMenuOpen(true);\n setContextMenuPosition({ x: e.clientX, y: e.clientY });\n }, [isMenuDisabled, shouldDisableOnLink, contextMenuPosition]);\n\n const handleContextMenuClose = useCallback(() => {\n setIsContextMenuOpen(false);\n }, []);\n\n const handleContextMenuHide = useCallback(() => {\n setContextMenuPosition(undefined);\n document.body.classList.remove('no-selection');\n\n setTimeout(() => {\n contextMenuCounter--;\n if (contextMenuCounter === 0) {\n document.body.classList.remove('has-context-menu');\n }\n }, SELECTION_ANIMATION_DURATION_MS);\n }, []);\n\n // Support context menu on touch-devices\n useEffect(() => {\n if (isMenuDisabled || !IS_TOUCH_ENV || shouldDisableOnLongTap) {\n return undefined;\n }\n\n const element = elementRef.current;\n if (!element) {\n return undefined;\n }\n\n let timer: number | undefined;\n\n const clearLongPressTimer = () => {\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const emulateContextMenuEvent = (originalEvent: TouchEvent) => {\n clearLongPressTimer();\n\n const { clientX, clientY, target } = originalEvent.touches[0];\n\n if (contextMenuPosition || (shouldDisableOnLink && (target as HTMLElement).matches('a.text-entity-link[href]'))) {\n return;\n }\n\n // temporarily intercept and clear the next click\n element.addEventListener('touchend', function cancelClickOnce(e) {\n element.removeEventListener('touchend', cancelClickOnce, true);\n e.stopImmediatePropagation();\n e.preventDefault();\n e.stopPropagation();\n }, true);\n\n document.body.classList.add('no-selection');\n setIsContextMenuOpen(true);\n setContextMenuPosition({ x: clientX, y: clientY });\n };\n\n const startLongPressTimer = (e: TouchEvent) => {\n if (isMenuDisabled || checkIsDisabledForMobile()) {\n return;\n }\n clearLongPressTimer();\n\n timer = window.setTimeout(() => emulateContextMenuEvent(e), LONG_TAP_DURATION_MS);\n };\n\n // @perf Consider event delegation\n element.addEventListener('touchstart', startLongPressTimer, { passive: true });\n element.addEventListener('touchcancel', clearLongPressTimer, true);\n element.addEventListener('touchend', clearLongPressTimer, true);\n element.addEventListener('touchmove', clearLongPressTimer, { passive: true });\n\n return () => {\n clearLongPressTimer();\n element.removeEventListener('touchstart', startLongPressTimer);\n element.removeEventListener('touchcancel', clearLongPressTimer, true);\n element.removeEventListener('touchend', clearLongPressTimer, true);\n element.removeEventListener('touchmove', clearLongPressTimer);\n };\n }, [contextMenuPosition, isMenuDisabled, shouldDisableOnLongTap, elementRef, shouldDisableOnLink]);\n\n return {\n isContextMenuOpen,\n contextMenuPosition,\n handleBeforeContextMenu,\n handleContextMenu,\n handleContextMenuClose,\n handleContextMenuHide,\n };\n};\n","import { useState, useEffect } from '../lib/teact/teact';\nimport { IAnchorPosition } from '../types';\n\nconst MENU_POSITION_VISUAL_COMFORT_SPACE_PX = 16;\n\nexport default (\n anchor: IAnchorPosition | undefined,\n getTriggerElement: () => HTMLElement | null,\n getRootElement: () => HTMLElement | null,\n getMenuElement: () => HTMLElement | null,\n extraPaddingX = 0,\n extraTopPadding = 0,\n) => {\n const [positionX, setPositionX] = useState<'right' | 'left'>('right');\n const [positionY, setPositionY] = useState<'top' | 'bottom'>('bottom');\n const [style, setStyle] = useState('');\n\n useEffect(() => {\n const triggerEl = getTriggerElement();\n if (!anchor || !triggerEl) {\n return;\n }\n\n let { x, y } = anchor;\n const emptyRect = {\n width: 0, left: 0, height: 0, top: 0,\n };\n\n const menuEl = getMenuElement();\n const rootEl = getRootElement();\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const menuRect = menuEl ? { width: menuEl.offsetWidth, height: menuEl.offsetHeight } : emptyRect;\n const rootRect = rootEl ? rootEl.getBoundingClientRect() : emptyRect;\n\n let horizontalPostition: 'left' | 'right';\n if (x + menuRect.width + extraPaddingX < rootRect.width + rootRect.left) {\n x += 3;\n horizontalPostition = 'left';\n } else if (x - menuRect.width > 0) {\n horizontalPostition = 'right';\n x -= 3;\n } else {\n horizontalPostition = 'left';\n x = 16;\n }\n setPositionX(horizontalPostition);\n\n if (y + menuRect.height < rootRect.height + rootRect.top) {\n setPositionY('top');\n } else {\n setPositionY('bottom');\n\n if (y - menuRect.height < rootRect.top + extraTopPadding) {\n y = rootRect.top + extraTopPadding + menuRect.height;\n }\n }\n\n const left = horizontalPostition === 'left'\n ? Math.min(x - triggerRect.left, rootRect.width - menuRect.width - MENU_POSITION_VISUAL_COMFORT_SPACE_PX)\n : Math.max((x - triggerRect.left), menuRect.width + MENU_POSITION_VISUAL_COMFORT_SPACE_PX);\n\n setStyle(`left: ${left}px; top: ${y - triggerRect.top}px;`);\n }, [\n anchor, extraPaddingX, extraTopPadding,\n getMenuElement, getRootElement, getTriggerElement,\n ]);\n\n return {\n positionX,\n positionY,\n style,\n };\n};\n","import usePrevious from './usePrevious';\n\nexport default function useCurrentOrPrev<T extends any>(\n current: T, shouldSkipUndefined = false, shouldForceCurrent = false,\n): T | undefined {\n const prev = usePrevious(current, shouldSkipUndefined);\n\n // eslint-disable-next-line no-null/no-null\n return shouldForceCurrent || (current !== null && current !== undefined) ? current : prev;\n}\n","import { useEffect, useMemo } from '../lib/teact/teact';\nimport { getDispatch } from '../lib/teact/teactn';\n\nimport { ApiMessage } from '../api/types';\n\nimport { throttle } from '../util/schedulers';\n\nexport default (\n chatId: number,\n messageId?: number,\n message?: ApiMessage,\n replyOriginForId?: number,\n) => {\n const { loadMessage } = getDispatch();\n const loadMessageThrottled = useMemo(() => {\n const throttled = throttle(loadMessage, 500, true);\n return () => {\n throttled({ chatId, messageId, replyOriginForId });\n };\n }, [loadMessage, chatId, messageId, replyOriginForId]);\n\n useEffect(() => {\n if (messageId && !message) {\n loadMessageThrottled();\n }\n });\n};\n","import { useEffect } from '../lib/teact/teact';\n\nexport default (container: HTMLElement | null, isDisabled?: boolean) => {\n useEffect(() => {\n if (!container) {\n return undefined;\n }\n\n function handleScroll(e: WheelEvent) {\n // Ignore horizontal scroll and let it work natively (e.g. on touchpad)\n if (!e.deltaX) {\n container!.scrollLeft += e.deltaY / 4;\n }\n }\n\n container.addEventListener('wheel', handleScroll, { passive: true });\n\n return () => {\n container.removeEventListener('wheel', handleScroll);\n };\n }, [container, isDisabled]);\n};\n","import { useCallback, useEffect, 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?: number }) => void;\n\nconst DEFAULT_LIST_SLICE = 30;\n\nexport default (\n loadMoreBackwards?: LoadMoreBackwards,\n listIds?: number[],\n isDisabled = false,\n listSlice = DEFAULT_LIST_SLICE,\n forceFullPreload = false,\n): [number[]?, GetMore?] => {\n const lastParamsRef = useRef<{\n direction?: LoadMoreDirection;\n offsetId?: number;\n }>();\n\n const viewportIdsRef = useRef<number[] | undefined>((() => {\n // Only run once to initialize\n if (!listIds || lastParamsRef.current) {\n return undefined;\n }\n\n const { newViewportIds } = getViewportSlice(listIds, listIds[0], LoadMoreDirection.Forwards, listSlice);\n return newViewportIds;\n })());\n\n const forceUpdate = useForceUpdate();\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, offsetId, direction, listSlice);\n\n if (!viewportIdsRef.current || !areSortedArraysEqual(viewportIdsRef.current, newViewportIds)) {\n viewportIdsRef.current = newViewportIds;\n }\n }\n\n useEffect(() => {\n if (listIds && !isDisabled && loadMoreBackwards && forceFullPreload) {\n const viewportIds = viewportIdsRef.current!;\n loadMoreBackwards({ offsetId: viewportIds[viewportIds.length - 1] });\n }\n }, [listIds, isDisabled, loadMoreBackwards, forceFullPreload]);\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, offsetId, direction, listSlice);\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(\n sourceIds: number[],\n offsetId = 0,\n direction: LoadMoreDirection,\n listSlice: number,\n) {\n const { length } = sourceIds;\n const index = sourceIds.indexOf(offsetId);\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","import { RefObject } from 'react';\nimport {\n useEffect, useRef, useCallback, useState,\n} from '../lib/teact/teact';\n\nimport { throttle, debounce } from '../util/schedulers';\nimport useHeavyAnimationCheck from './useHeavyAnimationCheck';\n\ntype TargetCallback = (entry: IntersectionObserverEntry) => void;\ntype RootCallback = (entries: IntersectionObserverEntry[]) => void;\ntype ObserveCleanup = NoneToVoidFunction;\nexport type ObserveFn = (target: HTMLElement, targetCallback?: TargetCallback) => ObserveCleanup;\n\ninterface IntersectionController {\n observer: IntersectionObserver;\n callbacks: Map<HTMLElement, TargetCallback>;\n}\n\ninterface Response {\n observe: ObserveFn;\n freeze: NoneToVoidFunction;\n unfreeze: NoneToVoidFunction;\n}\n\nconst AUTO_UNFREEZE_TIMEOUT = 2000;\n\nexport function useIntersectionObserver({\n rootRef,\n throttleMs,\n debounceMs,\n shouldSkipFirst,\n margin,\n threshold,\n isDisabled,\n}: {\n rootRef: RefObject<HTMLDivElement>;\n throttleMs?: number;\n debounceMs?: number;\n shouldSkipFirst?: boolean;\n margin?: number;\n threshold?: number | number[];\n isDisabled?: boolean;\n}, rootCallback?: RootCallback): Response {\n const controllerRef = useRef<IntersectionController>();\n const rootCallbackRef = useRef<RootCallback>();\n const freezeFlagsRef = useRef(0);\n const autoUnfreezeTimeoutRef = useRef<number>();\n const onUnfreezeRef = useRef<NoneToVoidFunction>();\n\n rootCallbackRef.current = rootCallback;\n\n const unfreeze = useCallback(() => {\n if (!freezeFlagsRef.current) {\n return;\n }\n\n freezeFlagsRef.current--;\n\n if (!freezeFlagsRef.current && onUnfreezeRef.current) {\n onUnfreezeRef.current();\n onUnfreezeRef.current = undefined;\n }\n }, []);\n\n const freeze = useCallback(() => {\n freezeFlagsRef.current++;\n\n if (autoUnfreezeTimeoutRef.current) {\n clearTimeout(autoUnfreezeTimeoutRef.current);\n autoUnfreezeTimeoutRef.current = undefined;\n }\n\n // Make sure to unfreeze even if unfreeze callback was not called (which was some hardly-reproducible bug)\n autoUnfreezeTimeoutRef.current = window.setTimeout(() => {\n autoUnfreezeTimeoutRef.current = undefined;\n\n if (!freezeFlagsRef.current) {\n return;\n }\n\n freezeFlagsRef.current = 1;\n unfreeze();\n }, AUTO_UNFREEZE_TIMEOUT);\n }, [unfreeze]);\n\n useHeavyAnimationCheck(freeze, unfreeze);\n\n useEffect(() => {\n if (isDisabled) {\n return undefined;\n }\n\n return () => {\n if (controllerRef.current) {\n controllerRef.current.observer.disconnect();\n controllerRef.current.callbacks.clear();\n controllerRef.current = undefined;\n }\n };\n }, [isDisabled]);\n\n function initController() {\n const callbacks = new Map();\n const entriesAccumulator = new Map<Element, IntersectionObserverEntry>();\n const observerCallbackSync = () => {\n const entries = Array.from(entriesAccumulator.values());\n\n entries.forEach((entry: IntersectionObserverEntry) => {\n const callback = callbacks.get(entry.target);\n if (callback) {\n callback!(entry, entries);\n }\n });\n\n if (rootCallbackRef.current) {\n rootCallbackRef.current(entries);\n }\n\n entriesAccumulator.clear();\n };\n const scheduler = throttleMs ? throttle : debounceMs ? debounce : undefined;\n const observerCallback = scheduler\n ? scheduler(observerCallbackSync, (throttleMs || debounceMs)!, !shouldSkipFirst)\n : observerCallbackSync;\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n entriesAccumulator.set(entry.target, entry);\n });\n\n if (freezeFlagsRef.current) {\n onUnfreezeRef.current = () => {\n observerCallback();\n };\n } else {\n observerCallback();\n }\n },\n {\n root: rootRef.current,\n rootMargin: margin ? `${margin}px` : undefined,\n threshold,\n },\n );\n\n controllerRef.current = { observer, callbacks };\n }\n\n const observe = useCallback((target, targetCallback) => {\n if (!controllerRef.current) {\n initController();\n }\n\n const controller = controllerRef.current!;\n controller.observer.observe(target);\n\n if (targetCallback) {\n controller.callbacks.set(target, targetCallback);\n }\n\n return () => {\n if (targetCallback) {\n controller.callbacks.delete(target);\n }\n\n controller.observer.unobserve(target);\n };\n // Arguments should never change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isDisabled]);\n\n return { observe, freeze, unfreeze };\n}\n\nexport function useOnIntersect(\n targetRef: RefObject<HTMLDivElement>, observe?: ObserveFn, callback?: TargetCallback,\n) {\n useEffect(() => {\n return observe ? observe(targetRef.current!, callback) : undefined;\n // Arguments should never change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\nexport function useIsIntersecting(\n targetRef: RefObject<HTMLDivElement>, observe?: ObserveFn, callback?: TargetCallback,\n) {\n const [isIntersecting, setIsIntersecting] = useState(!observe);\n\n useOnIntersect(targetRef, observe, (entry) => {\n setIsIntersecting(entry.isIntersecting);\n\n if (callback) {\n callback(entry);\n }\n });\n\n return isIntersecting;\n}\n","import { useLayoutEffect } from '../lib/teact/teact';\nimport usePrevious from './usePrevious';\n\nexport default <T extends any[], PT = T>(cb: (args: PT) => void, dependencies: T, debugKey?: string) => {\n const prevDeps = usePrevious<T>(dependencies);\n return useLayoutEffect(() => {\n // @ts-ignore (workaround for \"could be instantiated with a different subtype\" issue)\n return cb(prevDeps || []);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies, debugKey);\n};\n","import { useEffect } from '../lib/teact/teact';\n\nimport { ApiMediaFormat } from '../api/types';\n\nimport * as mediaLoader from '../util/mediaLoader';\nimport useForceUpdate from './useForceUpdate';\n\nexport default <T extends ApiMediaFormat = ApiMediaFormat.BlobUrl>(\n mediaHash: string | false | undefined,\n noLoad = false,\n // @ts-ignore (workaround for \"could be instantiated with a different subtype\" issue)\n mediaFormat: T = ApiMediaFormat.BlobUrl,\n cacheBuster?: number,\n delay?: number | false,\n) => {\n const mediaData = mediaHash ? mediaLoader.getFromMemory<T>(mediaHash) : undefined;\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n if (!noLoad && mediaHash && !mediaData) {\n const startedAt = Date.now();\n\n mediaLoader.fetch(mediaHash, mediaFormat).then(() => {\n const spentTime = Date.now() - startedAt;\n if (!delay || spentTime >= delay) {\n forceUpdate();\n } else {\n setTimeout(forceUpdate, delay - spentTime);\n }\n });\n }\n }, [noLoad, mediaHash, mediaData, mediaFormat, cacheBuster, forceUpdate, delay]);\n\n return mediaData;\n};\n","import React, { useCallback, useEffect, useState } from '../lib/teact/teact';\n\nimport useMediaWithDownloadProgress from './useMediaWithDownloadProgress';\nimport download from '../util/download';\n\nexport default function useMediaDownload(\n mediaHash?: string,\n fileName?: string,\n) {\n const [isDownloadStarted, setIsDownloadStarted] = useState(false);\n\n const { mediaData, downloadProgress } = useMediaWithDownloadProgress(mediaHash, !isDownloadStarted);\n\n // Download with browser when fully loaded\n useEffect(() => {\n if (isDownloadStarted && mediaData) {\n download(mediaData, fileName!);\n setIsDownloadStarted(false);\n }\n }, [fileName, mediaData, isDownloadStarted]);\n\n // Cancel download on source change\n useEffect(() => {\n setIsDownloadStarted(false);\n }, [mediaHash]);\n\n const handleDownloadClick = useCallback((e: React.SyntheticEvent<HTMLElement>) => {\n e.stopPropagation();\n setIsDownloadStarted((isAllowed) => !isAllowed);\n }, []);\n\n return {\n isDownloadStarted,\n downloadProgress,\n handleDownloadClick,\n };\n}\n","import {\n useEffect, useMemo, useRef, useState,\n} from '../lib/teact/teact';\n\nimport { IS_PROGRESSIVE_SUPPORTED } from '../util/environment';\nimport { ApiMediaFormat } from '../api/types';\nimport { throttle } from '../util/schedulers';\nimport * as mediaLoader from '../util/mediaLoader';\nimport useForceUpdate from './useForceUpdate';\n\nconst STREAMING_PROGRESS = 0.75;\nconst STREAMING_TIMEOUT = 1500;\nconst PROGRESS_THROTTLE = 500;\n\nexport default <T extends ApiMediaFormat = ApiMediaFormat.BlobUrl>(\n mediaHash: string | undefined,\n noLoad = false,\n // @ts-ignore (workaround for \"could be instantiated with a different subtype\" issue)\n mediaFormat: T = ApiMediaFormat.BlobUrl,\n cacheBuster?: number,\n delay?: number | false,\n isHtmlAllowed = false,\n) => {\n const mediaData = mediaHash ? mediaLoader.getFromMemory<T>(mediaHash) : undefined;\n const isStreaming = mediaFormat === ApiMediaFormat.Stream || (\n IS_PROGRESSIVE_SUPPORTED && mediaFormat === ApiMediaFormat.Progressive\n );\n const forceUpdate = useForceUpdate();\n const [downloadProgress, setDownloadProgress] = useState(mediaData && !isStreaming ? 1 : 0);\n const startedAtRef = useRef<number>();\n\n const handleProgress = useMemo(() => {\n return throttle((progress: number) => {\n if (!delay || (Date.now() - startedAtRef.current! > delay)) {\n setDownloadProgress(progress);\n }\n }, PROGRESS_THROTTLE, true);\n }, [delay]);\n\n useEffect(() => {\n if (!noLoad && mediaHash) {\n if (!mediaData) {\n setDownloadProgress(0);\n\n if (startedAtRef.current) {\n mediaLoader.cancelProgress(handleProgress);\n }\n\n startedAtRef.current = Date.now();\n\n mediaLoader.fetch(mediaHash, mediaFormat, isHtmlAllowed, handleProgress).then(() => {\n const spentTime = Date.now() - startedAtRef.current!;\n startedAtRef.current = undefined;\n\n if (!delay || spentTime >= delay) {\n forceUpdate();\n } else {\n setTimeout(forceUpdate, delay - spentTime);\n }\n });\n } else if (isStreaming) {\n setTimeout(() => {\n setDownloadProgress(STREAMING_PROGRESS);\n }, STREAMING_TIMEOUT);\n }\n }\n }, [\n noLoad, mediaHash, mediaData, mediaFormat, cacheBuster, forceUpdate, isStreaming, delay, handleProgress,\n isHtmlAllowed,\n ]);\n\n useEffect(() => {\n if (noLoad && startedAtRef.current) {\n mediaLoader.cancelProgress(handleProgress);\n setDownloadProgress(0);\n }\n }, [handleProgress, noLoad]);\n\n return { mediaData, downloadProgress };\n};\n","import { useCallback, useEffect, useRef } from '../lib/teact/teact';\n\nimport { IS_TOUCH_ENV } from '../util/environment';\n\nconst MENU_CLOSE_TIMEOUT = 250;\nlet closeTimeout: number | undefined;\n\nexport default function useMouseInside(\n isOpen: boolean, onClose: NoneToVoidFunction, menuCloseTimeout = MENU_CLOSE_TIMEOUT, isDisabled = false,\n) {\n const isMouseInside = useRef(true);\n\n useEffect(() => {\n if (isOpen) {\n isMouseInside.current = true;\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (closeTimeout) {\n clearTimeout(closeTimeout);\n closeTimeout = undefined;\n }\n\n if (isOpen && !IS_TOUCH_ENV && !isDisabled) {\n closeTimeout = window.setTimeout(() => {\n if (!isMouseInside.current) {\n onClose();\n }\n }, menuCloseTimeout * 2);\n }\n }, [isDisabled, isOpen, menuCloseTimeout, onClose]);\n\n const handleMouseEnter = useCallback(() => {\n isMouseInside.current = true;\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n isMouseInside.current = false;\n\n if (closeTimeout) {\n clearTimeout(closeTimeout);\n closeTimeout = undefined;\n }\n\n closeTimeout = window.setTimeout(() => {\n if (!isMouseInside.current) {\n onClose();\n }\n }, menuCloseTimeout);\n }, [menuCloseTimeout, onClose]);\n\n return [handleMouseEnter, handleMouseLeave];\n}\n","import { useRef } from '../lib/teact/teact';\n\nimport usePrevious from './usePrevious';\nimport useForceUpdate from './useForceUpdate';\nimport useOnChange from './useOnChange';\n\nexport default function usePrevDuringAnimation(current: any, duration?: number) {\n const prev = usePrevious(current, true);\n const timeoutRef = useRef<number>();\n const forceUpdate = useForceUpdate();\n // eslint-disable-next-line no-null/no-null\n const isCurrentPresent = current !== undefined && current !== null;\n // eslint-disable-next-line no-null/no-null\n const isPrevPresent = prev !== undefined && prev !== null;\n\n if (isCurrentPresent && timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n\n useOnChange(() => {\n // When `current` becomes empty\n if (duration && !isCurrentPresent && isPrevPresent && !timeoutRef.current) {\n timeoutRef.current = window.setTimeout(() => {\n timeoutRef.current = undefined;\n forceUpdate();\n }, duration);\n }\n }, [current]);\n\n return !timeoutRef.current || !duration || isCurrentPresent ? current : prev;\n}\n","import { useState, useCallback, useRef } from '../lib/teact/teact';\n\nexport type ReducerAction<Actions> = { type: Actions; payload?: any };\nexport type StateReducer<State, Actions> = (state: State, action: ReducerAction<Actions>) => State;\nexport type Dispatch<Actions> = (action: ReducerAction<Actions>) => void;\n\nexport default function useReducer<State, Actions>(\n reducer: StateReducer<State, Actions>,\n initialState: State,\n) {\n const reducerRef = useRef(reducer);\n const [state, setState] = useState<State>(initialState);\n\n const dispatch = useCallback((action: ReducerAction<Actions>) => {\n setState((currentState) => reducerRef.current(currentState, action));\n }, []);\n\n return [\n state,\n dispatch,\n ] as [State, Dispatch<Actions>];\n}\n","import { useEffect, useRef, useState } from '../lib/teact/teact';\n\nimport useShowTransition from './useShowTransition';\n\nconst SPEED = {\n fast: 200,\n slow: 350,\n};\n\nexport default (mediaData?: any, speed: keyof typeof SPEED = 'fast', noAnimate = false) => {\n const isMediaLoaded = Boolean(mediaData);\n const willAnimate = !useRef(isMediaLoaded).current && !noAnimate;\n const [shouldRenderThumb, setShouldRenderThumb] = useState(!isMediaLoaded);\n\n const {\n shouldRender: shouldRenderFullMedia,\n transitionClassNames,\n } = useShowTransition(isMediaLoaded, undefined, !willAnimate, speed);\n\n useEffect(() => {\n if (shouldRenderFullMedia) {\n if (willAnimate) {\n setTimeout(() => {\n setShouldRenderThumb(false);\n }, SPEED[speed]);\n } else {\n setShouldRenderThumb(false);\n }\n }\n }, [willAnimate, shouldRenderFullMedia, speed]);\n\n return {\n shouldRenderThumb,\n shouldRenderFullMedia,\n transitionClassNames,\n };\n};\n","import { 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","/* eslint-disable no-nested-ternary */\n/* eslint-disable no-bitwise */\n/* eslint-disable no-multi-assign */\n/* eslint-disable no-cond-assign */\n/* eslint-disable no-param-reassign */\n/* eslint-disable prefer-const */\n/* eslint-disable eqeqeq */\n\n/*\nSuperfast Blur - a fast Box Blur For Canvas\n\nVersion: 0.5\nAuthor: Mario Klingemann\nContact: mario@quasimondo.com\nWebsite: http://www.quasimondo.com/BoxBlurForCanvas\nTwitter: @quasimondo\n\nIn case you find this class useful - especially in commercial projects -\nI am not totally unhappy for a small donation to my PayPal account\nmario@quasimondo.de\n\nOr support me on flattr:\nhttps://flattr.com/thing/140066/Superfast-Blur-a-pretty-fast-Box-Blur-Effect-for-CanvasJavascript\n\nCopyright (c) 2011 Mario Klingemann\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n*/\n\n// eslint-disable-next-line max-len\nconst mul_table = [1, 57, 41, 21, 203, 34, 97, 73, 227, 91, 149, 62, 105, 45, 39, 137, 241, 107, 3, 173, 39, 71, 65, 238, 219, 101, 187, 87, 81, 151, 141, 133, 249, 117, 221, 209, 197, 187, 177, 169, 5, 153, 73, 139, 133, 127, 243, 233, 223, 107, 103, 99, 191, 23, 177, 171, 165, 159, 77, 149, 9, 139, 135, 131, 253, 245, 119, 231, 224, 109, 211, 103, 25, 195, 189, 23, 45, 175, 171, 83, 81, 79, 155, 151, 147, 9, 141, 137, 67, 131, 129, 251, 123, 30, 235, 115, 113, 221, 217, 53, 13, 51, 50, 49, 193, 189, 185, 91, 179, 175, 43, 169, 83, 163, 5, 79, 155, 19, 75, 147, 145, 143, 35, 69, 17, 67, 33, 65, 255, 251, 247, 243, 239, 59, 29, 229, 113, 111, 219, 27, 213, 105, 207, 51, 201, 199, 49, 193, 191, 47, 93, 183, 181, 179, 11, 87, 43, 85, 167, 165, 163, 161, 159, 157, 155, 77, 19, 75, 37, 73, 145, 143, 141, 35, 138, 137, 135, 67, 33, 131, 129, 255, 63, 250, 247, 61, 121, 239, 237, 117, 29, 229, 227, 225, 111, 55, 109, 216, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 48, 190, 47, 93, 185, 183, 181, 179, 178, 176, 175, 173, 171, 85, 21, 167, 165, 41, 163, 161, 5, 79, 157, 78, 154, 153, 19, 75, 149, 74, 147, 73, 144, 143, 71, 141, 140, 139, 137, 17, 135, 134, 133, 66, 131, 65, 129, 1];\n// eslint-disable-next-line max-len\nconst shg_table = [0, 9, 10, 10, 14, 12, 14, 14, 16, 15, 16, 15, 16, 15, 15, 17, 18, 17, 12, 18, 16, 17, 17, 19, 19, 18, 19, 18, 18, 19, 19, 19, 20, 19, 20, 20, 20, 20, 20, 20, 15, 20, 19, 20, 20, 20, 21, 21, 21, 20, 20, 20, 21, 18, 21, 21, 21, 21, 20, 21, 17, 21, 21, 21, 22, 22, 21, 22, 22, 21, 22, 21, 19, 22, 22, 19, 20, 22, 22, 21, 21, 21, 22, 22, 22, 18, 22, 22, 21, 22, 22, 23, 22, 20, 23, 22, 22, 23, 23, 21, 19, 21, 21, 21, 23, 23, 23, 22, 23, 23, 21, 23, 22, 23, 18, 22, 23, 20, 22, 23, 23, 23, 21, 22, 20, 22, 21, 22, 24, 24, 24, 24, 24, 22, 21, 24, 23, 23, 24, 21, 24, 23, 24, 22, 24, 24, 22, 24, 24, 22, 23, 24, 24, 24, 20, 23, 22, 23, 24, 24, 24, 24, 24, 24, 24, 23, 21, 23, 22, 23, 24, 24, 24, 22, 24, 24, 24, 23, 22, 24, 24, 25, 23, 25, 25, 23, 24, 25, 25, 24, 22, 25, 25, 25, 24, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 23, 25, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 22, 25, 25, 23, 25, 25, 20, 24, 25, 24, 25, 25, 22, 24, 25, 24, 25, 24, 25, 25, 24, 25, 25, 25, 25, 22, 25, 25, 25, 24, 25, 24, 25, 18];\n\nexport default function boxBlurCanvasRGB(context, top_x, top_y, width, height, radius, iterations) {\n if (Number.isNaN(radius) || radius < 1) return;\n\n radius |= 0;\n\n if (Number.isNaN(iterations)) iterations = 1;\n iterations |= 0;\n if (iterations > 3) iterations = 3;\n if (iterations < 1) iterations = 1;\n\n const imageData = context.getImageData(top_x, top_y, width, height);\n\n const pixels = imageData.data;\n\n let rsum;\n let gsum;\n let bsum;\n let x;\n let y;\n let i;\n let p;\n let p1;\n let p2;\n let yp;\n let yi;\n let yw;\n let wm = width - 1;\n let hm = height - 1;\n let rad1 = radius + 1;\n\n let r = [];\n let g = [];\n let b = [];\n\n let mul_sum = mul_table[radius];\n let shg_sum = shg_table[radius];\n\n let vmin = [];\n let vmax = [];\n\n while (iterations-- > 0) {\n yw = yi = 0;\n\n for (y = 0; y < height; y++) {\n rsum = pixels[yw] * rad1;\n gsum = pixels[yw + 1] * rad1;\n bsum = pixels[yw + 2] * rad1;\n\n for (i = 1; i <= radius; i++) {\n p = yw + (((i > wm ? wm : i)) << 2);\n rsum += pixels[p++];\n gsum += pixels[p++];\n bsum += pixels[p++];\n }\n\n for (x = 0; x < width; x++) {\n r[yi] = rsum;\n g[yi] = gsum;\n b[yi] = bsum;\n\n if (y == 0) {\n vmin[x] = ((p = x + rad1) < wm ? p : wm) << 2;\n vmax[x] = ((p = x - radius) > 0 ? p << 2 : 0);\n }\n\n p1 = yw + vmin[x];\n p2 = yw + vmax[x];\n\n rsum += pixels[p1++] - pixels[p2++];\n gsum += pixels[p1++] - pixels[p2++];\n bsum += pixels[p1++] - pixels[p2++];\n\n yi++;\n }\n yw += (width << 2);\n }\n\n for (x = 0; x < width; x++) {\n yp = x;\n rsum = r[yp] * rad1;\n gsum = g[yp] * rad1;\n bsum = b[yp] * rad1;\n\n for (i = 1; i <= radius; i++) {\n yp += (i > hm ? 0 : width);\n rsum += r[yp];\n gsum += g[yp];\n bsum += b[yp];\n }\n\n yi = x << 2;\n for (y = 0; y < height; y++) {\n pixels[yi] = (rsum * mul_sum) >>> shg_sum;\n pixels[yi + 1] = (gsum * mul_sum) >>> shg_sum;\n pixels[yi + 2] = (bsum * mul_sum) >>> shg_sum;\n\n if (x == 0) {\n vmin[y] = ((p = y + rad1) < hm ? p : hm) * width;\n vmax[y] = ((p = y - radius) > 0 ? p * width : 0);\n }\n\n p1 = x + vmin[y];\n p2 = x + vmax[y];\n\n rsum += r[p1] - r[p2];\n gsum += g[p1] - g[p2];\n bsum += b[p1] - b[p2];\n\n yi += width << 2;\n }\n }\n }\n\n context.putImageData(imageData, top_x, top_y);\n}\n","import { IS_SAFARI } from './environment';\nimport safePlay from './safePlay';\nimport { patchSafariProgressiveAudio, isSafariPatchInProgress } from './patchSafariProgressiveAudio';\nimport { getDispatch } from '../lib/teact/teactn';\nimport { parseMessageKey } from '../modules/helpers';\n\ntype Handler = (eventName: string, e: Event) => void;\n\ninterface Track {\n audio: HTMLAudioElement;\n proxy: HTMLAudioElement;\n handlers: Handler[];\n onForcePlay?: NoneToVoidFunction;\n}\n\nconst tracks = new Map<string, Track>();\nlet queue: string[] = [];\n\nlet currentTrackId: string | undefined;\n\nfunction createAudio(trackId: string, onForcePlay?: NoneToVoidFunction) {\n const audio = new Audio();\n\n function handleEvent(eventName: string) {\n return (e: Event) => {\n if (!tracks.has(trackId)) {\n return;\n }\n\n if (isSafariPatchInProgress(audio)) {\n return;\n }\n\n tracks.get(trackId)!.handlers.forEach((handler) => {\n handler(eventName, e);\n });\n };\n }\n\n audio.addEventListener('timeupdate', handleEvent('onTimeUpdate'));\n audio.addEventListener('play', handleEvent('onPlay'));\n audio.addEventListener('pause', handleEvent('onPause'));\n audio.addEventListener('loadstart', handleEvent('onLoadStart'));\n audio.addEventListener('loadeddata', handleEvent('onLoadedData'));\n audio.addEventListener('playing', handleEvent('onPlaying'));\n audio.addEventListener('ended', () => {\n if (isSafariPatchInProgress(audio)) {\n return;\n }\n\n const nextTrackId = queue[queue.indexOf(trackId) + 1];\n if (!nextTrackId) {\n return;\n }\n\n if (!tracks.has(nextTrackId)) {\n // A bit hacky way to continue playlist when switching chat\n getDispatch().openAudioPlayer(parseMessageKey(nextTrackId));\n\n return;\n }\n\n const nextTrack = tracks.get(nextTrackId)!;\n\n if (nextTrack.onForcePlay) {\n nextTrack.onForcePlay();\n }\n\n currentTrackId = nextTrackId;\n\n if (nextTrack.audio.src) {\n safePlay(nextTrack.audio);\n }\n });\n\n return {\n audio,\n proxy: new Proxy(audio, {\n get: (origin, key: keyof HTMLAudioElement) => origin[key],\n }),\n handlers: [],\n onForcePlay,\n };\n}\n\nexport function stopCurrentAudio() {\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack) {\n currentTrack.audio.pause();\n }\n}\n\nexport function register(trackId: string, handler: Handler, onForcePlay?: NoneToVoidFunction) {\n if (!tracks.has(trackId)) {\n tracks.set(trackId, createAudio(trackId, onForcePlay));\n\n if (!queue.includes(trackId)) {\n queue.push(trackId);\n }\n }\n\n const { audio, proxy, handlers } = tracks.get(trackId)!;\n\n handlers.push(handler);\n\n return {\n play(src: string) {\n if (currentTrackId && currentTrackId !== trackId) {\n tracks.get(currentTrackId)!.audio.pause();\n }\n\n currentTrackId = trackId;\n\n if (!audio.src) {\n audio.src = src;\n audio.preload = 'auto';\n\n if (src.includes('/progressive/') && IS_SAFARI) {\n patchSafariProgressiveAudio(audio);\n }\n }\n\n safePlay(audio);\n },\n\n pause() {\n if (currentTrackId === trackId) {\n audio.pause();\n }\n },\n\n setCurrentTime(time: number) {\n if (currentTrackId === trackId) {\n audio.currentTime = time;\n }\n },\n\n proxy,\n\n destroy(shouldRemoveFromQueue = false) {\n const track = tracks.get(trackId);\n if (!track) {\n return;\n }\n\n track.handlers = track.handlers.filter((h) => h !== handler);\n\n if (!track.handlers.length) {\n track.audio.pause();\n tracks.delete(trackId);\n\n if (shouldRemoveFromQueue) {\n queue = queue.filter((id) => id !== trackId);\n }\n\n if (trackId === currentTrackId) {\n currentTrackId = undefined;\n }\n }\n },\n };\n}\n","import { IS_IOS, IS_TOUCH_ENV } from './environment';\n\nexport enum SwipeDirection {\n Up,\n Down,\n Left,\n Right,\n}\n\ninterface CaptureOptions {\n onCapture?: (e: MouseEvent | TouchEvent) => void;\n onRelease?: (e: MouseEvent | TouchEvent) => void;\n onDrag?: (\n e: MouseEvent | TouchEvent,\n captureEvent: MouseEvent | TouchEvent,\n params: {\n dragOffsetX: number;\n dragOffsetY: number;\n },\n ) => void;\n onSwipe?: (e: Event, direction: SwipeDirection) => boolean;\n onClick?: (e: MouseEvent | TouchEvent) => void;\n excludedClosestSelector?: string;\n selectorToPreventScroll?: string;\n withCursor?: boolean;\n}\n\n// https://stackoverflow.com/questions/11287877/how-can-i-get-e-offsetx-on-mobile-ipad\n// Android does not have this value, and iOS has it but as read-only\nexport interface RealTouchEvent extends TouchEvent {\n pageX?: number;\n pageY?: number;\n}\n\ntype TSwipeAxis =\n 'x'\n | 'y'\n | undefined;\n\nconst IOS_SCREEN_EDGE_THRESHOLD = 20;\nconst MOVED_THRESHOLD = 15;\nconst SWIPE_THRESHOLD = 50;\n\nexport function captureEvents(element: HTMLElement, options: CaptureOptions) {\n let captureEvent: MouseEvent | RealTouchEvent | undefined;\n let hasMoved = false;\n let hasSwiped = false;\n\n function onCapture(e: MouseEvent | RealTouchEvent) {\n if (options.excludedClosestSelector && (\n (e.target as HTMLElement).matches(options.excludedClosestSelector)\n || (e.target as HTMLElement).closest(options.excludedClosestSelector)\n )) {\n return;\n }\n\n captureEvent = e;\n\n if (e.type === 'mousedown') {\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onRelease);\n } else if (e.type === 'touchstart') {\n // We need to always listen on `touchstart` target:\n // https://stackoverflow.com/questions/33298828/touch-move-event-dont-fire-after-touch-start-target-is-removed\n const target = e.target as HTMLElement;\n target.addEventListener('touchmove', onMove);\n target.addEventListener('touchend', onRelease);\n target.addEventListener('touchcancel', onRelease);\n\n if ('touches' in e) {\n if (e.pageX === undefined) {\n e.pageX = e.touches[0].pageX;\n }\n\n if (e.pageY === undefined) {\n e.pageY = e.touches[0].pageY;\n }\n }\n }\n\n document.body.classList.add('no-selection');\n if (options.withCursor) {\n document.body.classList.add('cursor-grabbing');\n }\n\n if (options.onCapture) {\n options.onCapture(e);\n }\n }\n\n function onRelease(e: MouseEvent | TouchEvent) {\n if (captureEvent) {\n if (options.withCursor) {\n document.body.classList.remove('cursor-grabbing');\n }\n document.body.classList.remove('no-selection');\n\n document.removeEventListener('mouseup', onRelease);\n document.removeEventListener('mousemove', onMove);\n (captureEvent.target as HTMLElement).removeEventListener('touchcancel', onRelease);\n (captureEvent.target as HTMLElement).removeEventListener('touchend', onRelease);\n (captureEvent.target as HTMLElement).removeEventListener('touchmove', onMove);\n\n captureEvent = undefined;\n\n if (options.selectorToPreventScroll) {\n Array.from(document.querySelectorAll<HTMLElement>(options.selectorToPreventScroll)).forEach((scrollable) => {\n scrollable.style.overflow = '';\n });\n }\n\n if (hasMoved) {\n if (options.onRelease) {\n options.onRelease(e);\n }\n } else if (options.onClick && (!('button' in e) || e.button === 0)) {\n options.onClick(e);\n }\n }\n\n hasMoved = false;\n hasSwiped = false;\n }\n\n function onMove(e: MouseEvent | RealTouchEvent) {\n if (captureEvent) {\n if (e.type === 'touchmove' && ('touches' in e)) {\n if (e.pageX === undefined) {\n e.pageX = e.touches[0].pageX;\n }\n\n if (e.pageY === undefined) {\n e.pageY = e.touches[0].pageY;\n }\n }\n\n const dragOffsetX = e.pageX! - captureEvent.pageX!;\n const dragOffsetY = e.pageY! - captureEvent.pageY!;\n\n if (Math.abs(dragOffsetX) >= MOVED_THRESHOLD || Math.abs(dragOffsetY) >= MOVED_THRESHOLD) {\n hasMoved = true;\n }\n\n let shouldPreventScroll = false;\n\n if (options.onDrag) {\n options.onDrag(e, captureEvent, { dragOffsetX, dragOffsetY });\n shouldPreventScroll = true;\n }\n\n if (options.onSwipe && !hasSwiped) {\n hasSwiped = onSwipe(e, dragOffsetX, dragOffsetY);\n shouldPreventScroll = hasSwiped;\n }\n\n if (IS_TOUCH_ENV && shouldPreventScroll && options.selectorToPreventScroll) {\n if (options.selectorToPreventScroll) {\n Array.from(document.querySelectorAll<HTMLElement>(options.selectorToPreventScroll)).forEach((scrollable) => {\n scrollable.style.overflow = 'hidden';\n });\n }\n }\n }\n }\n\n function onSwipe(e: MouseEvent | RealTouchEvent, dragOffsetX: number, dragOffsetY: number) {\n // Avoid conflicts with swipe-to-back gestures\n if (IS_IOS) {\n const x = (e as RealTouchEvent).touches[0].pageX;\n if (x <= IOS_SCREEN_EDGE_THRESHOLD || x >= window.innerWidth - IOS_SCREEN_EDGE_THRESHOLD) {\n return false;\n }\n }\n\n const xAbs = Math.abs(dragOffsetX);\n const yAbs = Math.abs(dragOffsetY);\n\n if (dragOffsetX && dragOffsetY) {\n const ratio = Math.max(xAbs, yAbs) / Math.min(xAbs, yAbs);\n // Diagonal swipe\n if (ratio < 2) {\n return false;\n }\n }\n\n let axis: TSwipeAxis | undefined;\n if (xAbs >= SWIPE_THRESHOLD) {\n axis = 'x';\n } else if (yAbs >= SWIPE_THRESHOLD) {\n axis = 'y';\n }\n\n if (!axis) {\n return false;\n }\n\n return processSwipe(e, axis, dragOffsetX, dragOffsetY, options.onSwipe!);\n }\n\n element.addEventListener('mousedown', onCapture);\n element.addEventListener('touchstart', onCapture, { passive: true });\n\n return () => {\n element.removeEventListener('mousedown', onCapture);\n element.removeEventListener('touchstart', onCapture);\n };\n}\n\nfunction processSwipe(\n e: Event,\n currentSwipeAxis: TSwipeAxis,\n dragOffsetX: number,\n dragOffsetY: number,\n onSwipe: (e: Event, direction: SwipeDirection) => boolean,\n) {\n if (currentSwipeAxis === 'x') {\n if (dragOffsetX < 0) {\n return onSwipe(e, SwipeDirection.Left);\n } else {\n return onSwipe(e, SwipeDirection.Right);\n }\n } else if (currentSwipeAxis === 'y') {\n if (dragOffsetY < 0) {\n return onSwipe(e, SwipeDirection.Up);\n } else {\n return onSwipe(e, SwipeDirection.Down);\n }\n }\n\n return false;\n}\n","import { DEBUG } from '../config';\n\nexport const CLIPBOARD_ITEM_SUPPORTED = navigator.clipboard && window.ClipboardItem;\n\nconst textCopyEl = document.createElement('textarea');\ntextCopyEl.setAttribute('readonly', '');\ntextCopyEl.tabIndex = -1;\ntextCopyEl.className = 'visually-hidden';\n\nexport const copyTextToClipboard = (str: string): void => {\n textCopyEl.value = str;\n document.body.appendChild(textCopyEl);\n const selection = document.getSelection();\n\n if (selection) {\n // Store previous selection\n const rangeToRestore = selection.rangeCount > 0 && selection.getRangeAt(0);\n textCopyEl.select();\n document.execCommand('copy');\n // Restore the original selection\n if (rangeToRestore) {\n selection.removeAllRanges();\n selection.addRange(rangeToRestore);\n }\n }\n\n document.body.removeChild(textCopyEl);\n};\n\nexport const copyImageToClipboard = (imageUrl?: string) => {\n if (!imageUrl) return;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n const imageEl = new Image();\n imageEl.onload = (e: Event) => {\n if (ctx && e.currentTarget) {\n const img = e.currentTarget as HTMLImageElement;\n canvas.width = img.width;\n canvas.height = img.height;\n ctx.drawImage(img, 0, 0, img.width, img.height);\n canvas.toBlob(copyBlobToClipboard, 'image/png', 1);\n }\n };\n\n imageEl.src = imageUrl;\n};\n\nasync function copyBlobToClipboard(pngBlob: Blob | null) {\n if (!pngBlob || !CLIPBOARD_ITEM_SUPPORTED) {\n return;\n }\n\n try {\n await navigator.clipboard.write([\n new window.ClipboardItem({\n [pngBlob.type]: pngBlob,\n }),\n ]);\n } catch (error) {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n }\n}\n","// Sometimes event is fired earlier than animation completes\nconst ANIMATION_END_DELAY = 50;\n\nexport function waitForTransitionEnd(node: Node, handler: NoneToVoidFunction, propertyName?: string) {\n waitForEndEvent('transitionend', node, handler, propertyName);\n}\n\nexport function waitForAnimationEnd(node: Node, handler: NoneToVoidFunction, animationName?: string) {\n waitForEndEvent('animationend', node, handler, animationName);\n}\n\nfunction waitForEndEvent(\n eventType: 'transitionend' | 'animationend',\n node: Node,\n handler: NoneToVoidFunction,\n detailedName?: string,\n) {\n let isHandled = false;\n\n node.addEventListener(eventType, function handleAnimationEnd(e: TransitionEvent | AnimationEvent) {\n if (isHandled || e.target !== e.currentTarget) {\n return;\n }\n\n if (detailedName && (\n (e instanceof TransitionEvent && e.propertyName === detailedName)\n || (e instanceof AnimationEvent && e.animationName === detailedName)\n )) {\n return;\n }\n\n isHandled = true;\n\n node.removeEventListener(eventType, handleAnimationEnd as EventListener);\n\n setTimeout(() => {\n handler();\n }, ANIMATION_END_DELAY);\n } as EventListener);\n}\n","export default function cycleRestrict(length: number, index: number) {\n return index - Math.floor(index / length) * length;\n}\n","export default function download(url: string, filename: string) {\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n link.click();\n}\n","import { getGlobal } from '../lib/teact/teactn';\n\nimport { FocusDirection } from '../types';\n\nimport {\n ANIMATION_LEVEL_MIN,\n FAST_SMOOTH_MAX_DISTANCE, FAST_SMOOTH_MAX_DURATION, FAST_SMOOTH_MIN_DURATION,\n FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE,\n} from '../config';\nimport { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';\nimport { animateSingle } from './animation';\n\nlet isAnimating = false;\n\nexport default function fastSmoothScroll(\n container: HTMLElement,\n element: HTMLElement,\n position: ScrollLogicalPosition | 'centerOrTop',\n margin = 0,\n maxDistance = FAST_SMOOTH_MAX_DISTANCE,\n forceDirection?: FocusDirection,\n forceDuration?: number,\n forceNormalContainerHeight?: boolean,\n) {\n const scrollFrom = calculateScrollFrom(container, element, maxDistance, forceDirection);\n\n if (forceDirection === FocusDirection.Static) {\n scrollWithJs(container, element, scrollFrom, position, margin, 0);\n return;\n }\n\n if (getGlobal().settings.byKey.animationLevel === ANIMATION_LEVEL_MIN) {\n forceDuration = 0;\n }\n\n scrollWithJs(container, element, scrollFrom, position, margin, forceDuration, forceNormalContainerHeight);\n}\n\nexport function isAnimatingScroll() {\n return isAnimating;\n}\n\nfunction calculateScrollFrom(\n container: HTMLElement,\n element: HTMLElement,\n maxDistance = FAST_SMOOTH_MAX_DISTANCE,\n forceDirection?: FocusDirection,\n) {\n const { offsetTop: elementTop } = element;\n const { scrollTop } = container;\n\n if (forceDirection === undefined) {\n const offset = elementTop - container.scrollTop;\n\n if (offset < -maxDistance) {\n return scrollTop + (offset + maxDistance);\n } else if (offset > maxDistance) {\n return scrollTop + (offset - maxDistance);\n }\n } else if (forceDirection === FocusDirection.Up) {\n return elementTop + maxDistance;\n } else if (forceDirection === FocusDirection.Down) {\n return Math.max(0, elementTop - maxDistance);\n }\n\n return scrollTop;\n}\n\nfunction scrollWithJs(\n container: HTMLElement,\n element: HTMLElement,\n scrollFrom: number,\n position: ScrollLogicalPosition | 'centerOrTop',\n margin = 0,\n forceDuration?: number,\n forceNormalContainerHeight?: boolean,\n) {\n const { offsetTop: elementTop, offsetHeight: elementHeight } = element;\n const { scrollTop: currentScrollTop, offsetHeight: containerHeight, scrollHeight } = container;\n const targetContainerHeight = forceNormalContainerHeight && container.dataset.normalHeight\n ? Number(container.dataset.normalHeight)\n : containerHeight;\n\n if (currentScrollTop !== scrollFrom) {\n container.scrollTop = scrollFrom;\n }\n\n let path!: number;\n\n switch (position) {\n case 'start':\n path = (elementTop - margin) - scrollFrom;\n break;\n case 'end':\n path = (elementTop + elementHeight + margin) - (scrollFrom + targetContainerHeight);\n break;\n // 'nearest' is not supported yet\n case 'nearest':\n case 'center':\n case 'centerOrTop':\n path = elementHeight < targetContainerHeight\n ? (elementTop + elementHeight / 2) - (scrollFrom + targetContainerHeight / 2)\n : (elementTop - margin) - scrollFrom;\n break;\n }\n\n if (path < 0) {\n const remainingPath = -scrollFrom;\n path = Math.max(path, remainingPath);\n } else if (path > 0) {\n const remainingPath = scrollHeight - (scrollFrom + targetContainerHeight);\n path = Math.min(path, remainingPath);\n }\n\n if (path === 0) {\n return;\n }\n\n const target = scrollFrom + path;\n\n if (forceDuration === 0) {\n container.scrollTop = target;\n return;\n }\n\n isAnimating = true;\n\n const absPath = Math.abs(path);\n const transition = absPath < FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE ? shortTransition : longTransition;\n const duration = forceDuration || (\n FAST_SMOOTH_MIN_DURATION\n + (absPath / FAST_SMOOTH_MAX_DISTANCE) * (FAST_SMOOTH_MAX_DURATION - FAST_SMOOTH_MIN_DURATION)\n );\n const startAt = Date.now();\n const onHeavyAnimationStop = dispatchHeavyAnimationEvent();\n\n animateSingle(() => {\n const t = Math.min((Date.now() - startAt) / duration, 1);\n const currentPath = path * (1 - transition(t));\n\n container.scrollTop = Math.round(target - currentPath);\n\n isAnimating = t < 1;\n\n if (!isAnimating) {\n onHeavyAnimationStop();\n }\n\n return isAnimating;\n });\n}\n\nfunction longTransition(t: number) {\n return 1 - ((1 - t) ** 5);\n}\n\nfunction shortTransition(t: number) {\n return 1 - ((1 - t) ** 3.5);\n}\n","import { getGlobal } from '../lib/teact/teactn';\n\nimport { ANIMATION_LEVEL_MIN } from '../config';\nimport { IS_IOS } from './environment';\nimport { animate } from './animation';\n\nconst DEFAULT_DURATION = 300;\n\nexport default function fastSmoothScrollHorizontal(container: HTMLElement, left: number, duration = DEFAULT_DURATION) {\n if (getGlobal().settings.byKey.animationLevel === ANIMATION_LEVEL_MIN) {\n duration = 0;\n }\n\n // Native way seems to be smoother in Chrome\n if (!IS_IOS) {\n container.scrollTo({\n left,\n ...(duration && { behavior: 'smooth' }),\n });\n } else {\n scrollWithJs(container, left, duration);\n }\n}\n\nfunction scrollWithJs(container: HTMLElement, left: number, duration: number) {\n const { scrollLeft, offsetWidth: containerWidth, scrollWidth } = container;\n let path = left - scrollLeft;\n\n if (path < 0) {\n const remainingPath = -scrollLeft;\n path = Math.max(path, remainingPath);\n } else if (path > 0) {\n const remainingPath = scrollWidth - (scrollLeft + containerWidth);\n path = Math.min(path, remainingPath);\n }\n\n if (path === 0) {\n return;\n }\n\n const target = scrollLeft + path;\n\n if (duration === 0) {\n container.scrollLeft = target;\n return;\n }\n\n const startAt = Date.now();\n\n animate(() => {\n const t = Math.min((Date.now() - startAt) / duration, 1);\n\n const currentPath = path * (1 - transition(t));\n container.scrollLeft = Math.round(target - currentPath);\n\n return t < 1;\n });\n}\n\nfunction transition(t: number) {\n return 1 - ((1 - t) ** 3.5);\n}\n","import { IS_TOUCH_ENV } from './environment';\n\nexport default function focusEditableElement(element: HTMLElement, force?: boolean) {\n if (!force && element === document.activeElement) {\n return;\n }\n\n const selection = window.getSelection()!;\n const range = document.createRange();\n const lastChild = element.lastChild || element;\n\n if (!IS_TOUCH_ENV && (!lastChild || !lastChild.nodeValue)) {\n element.focus();\n return;\n }\n\n range.selectNodeContents(lastChild);\n // `false` means collapse to the end rather than the start\n range.collapse(false);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n","/*\n * Thanks to Ace Monkey for this mind-blowing patch.\n */\n\nexport function patchSafariProgressiveAudio(audioEl: HTMLAudioElement) {\n if (audioEl.dataset.patchedForSafari) {\n return;\n }\n\n audioEl.addEventListener('play', () => {\n const t = audioEl.currentTime;\n\n function onProgress() {\n if (!audioEl.buffered.length) {\n return;\n }\n\n audioEl.dataset.patchForSafariInProgress = 'true';\n audioEl.currentTime = audioEl.duration - 1;\n audioEl.addEventListener('progress', () => {\n delete audioEl.dataset.patchForSafariInProgress;\n audioEl.currentTime = t;\n if (audioEl.paused) {\n audioEl.play();\n }\n }, { once: true });\n\n audioEl.removeEventListener('progress', onProgress);\n }\n\n audioEl.addEventListener('progress', onProgress);\n }, { once: true });\n\n audioEl.dataset.patchedForSafari = 'true';\n}\n\nexport function isSafariPatchInProgress(audioEl: HTMLAudioElement) {\n return Boolean(audioEl.dataset.patchForSafariInProgress);\n}\n","import { IS_IOS } from './environment';\n\nexport default (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","import { DEBUG } from '../config';\n\nexport default (mediaEl: HTMLMediaElement) => {\n mediaEl.play().catch((err) => {\n if (DEBUG) {\n // eslint-disable-next-line no-console\n console.warn(err);\n }\n });\n};\n"],"names":["WIDTH","large","medium","small","sticker","size","observeIntersection","lastSyncTime","forceLoadPreview","ref","useRef","isAnimationLoaded","markAnimationLoaded","useFlag","localMediaHash","id","isIntersecting","useIsIntersecting","thumbDataUri","thumbnail","dataUri","previewBlobUrl","useMedia","ApiMediaFormat","transitionClassNames","useTransitionForMedia","mediaData","isMediaLoaded","Boolean","playKey","setPlayKey","useState","String","Math","random","handleClick","useCallback","width","style","className","onClick","src","LIKE_STICKER_ID","undefined","alt","key","animationData","quality","play","noLoop","onLoad","lottiePromise","RLottie","async","ensureLottie","default","setTimeout","memo","playSegment","speed","isLowPriority","animation","setAnimation","container","wasPlaying","isFrozen","playRef","current","playSegmentRef","useEffect","exec","newAnimation","setSpeed","then","fastRaf","destroy","playAnimation","shouldRestart","goToAndPlay","pauseAnimation","pause","freezeAnimation","isPlaying","unfreezeAnimation","unfreezeAnimationOnRaf","useHeavyAnimationCheck","useBackgroundMode","fullClassName","buildClassName","MIN_SPIKES","IS_SINGLE_COLUMN_LAYOUT","MAX_SPIKES","renderSeekline","playProgress","bufferedProgress","handleStartSeek","handleSeek","handleStopSeek","onMouseDown","onMouseMove","onMouseUp","theme","message","senderTitle","uploadProgress","target","date","isSelectable","isSelected","onPlay","onReadMedia","onCancelUpload","onDateClick","content","audio","voice","isMediaUnread","isVoice","isSeeking","lang","useLang","isActivated","setIsActivated","shouldDownload","downloadProgress","useMediaWithDownloadProgress","getMessageMediaHash","getMessageMediaFormat","isBuffered","bufferingHandlers","checkBuffering","useBuffering","playPause","setCurrentTime","duration","useAudioPlayer","getMessageKey","getMediaDuration","chatId","isMessageLocal","isDownloadStarted","directDownloadProgress","handleDownloadClick","useMediaDownload","getMessageAudioCaption","isLoadingForPlaying","isUploading","isTransferring","transferProgress","getMediaTransferState","shouldRender","shouldRenderSpinner","spinnerClassNames","useShowTransition","handleButtonClick","e","seekBar","currentTarget","closest","left","getBoundingClientRect","clientX","handleDateClick","seekHandlers","isOwn","isOwnMessage","renderedWaveform","useMemo","waveform","fillColor","fillOwnColor","progressFillColor","progressFillOwnColor","durationFactor","min","spikesCount","round","decodedWaveform","encoded5bit","bitsCount","length","valuesCount","floor","result","Array","bitsData","i","l","byteIndex","bitShift","value","lastByteIndex","lastBitShift","lastValue","decodeWaveform","Uint8Array","data","spikes","peak","fitCount","newData","springFactor","leftFiller","rightFiller","idx","val","interpolateArray","height","progress","fillStyle","progressFillStyle","canvas","document","createElement","ctx","getContext","scale","forEach","item","globalAlpha","spikeHeight","max","x","y","radius","beginPath","moveTo","arcTo","closePath","roundedRectangle","fill","toDataURL","renderWaveformToDataUri","draggable","renderWaveform","buttonClassNames","push","showSeekline","contentClassName","dir","isRtl","Button","ripple","join","ariaLabel","ProgressSpinner","transparent","noCross","renderText","title","fileName","getFirstLine","Link","formatPastTimeShort","formatMediaDuration","performer","getSecondLine","formatMediaDateTime","renderAudio","renderVoice","chat","user","text","withOnlineStatus","isSavedMessages","isDeleted","isDeletedUser","imageHash","getChatAvatarHash","shouldRenderFullMedia","decoding","userFullName","getUserFullName","getFirstLetters","getChatTitle","isChatPrivate","isOnline","isUserOnline","getUserColorKey","senderId","IS_TEST","withGlobal","global","chatOrUserId","selectChat","selectUser","isMuted","selectIsChatMuted","selectNotifySettings","selectNotifyExceptions","canInviteUsers","isChatChannel","isUserRightBanned","getHasAdminRight","setGlobal","actions","pick","forceShowSelf","loadFullUser","showNotification","updateChatMutedState","userId","fullInfo","username","phoneNumber","isSelf","handleNotificationChange","isRestricted","copy","entity","copyTextToClipboard","formattedNumber","formatPhoneNumberWithCode","link","getChatLink","description","bio","getChatDescription","icon","multiline","narrow","isStatic","label","checked","inactive","isPrivateChat","isChatWithSelf","selectIsChatWithSelf","getPrivateChatUserId","isBot","isUserBot","isSupport","canDeleteForAll","contactName","getUserFirstOrLastName","isChannel","isBasicGroup","isChatBasicGroup","isSuperGroup","isChatSuperGroup","currentUserId","isOpen","onClose","onCloseAnimationEnd","leaveChannel","deleteHistory","deleteChannel","deleteChatUser","blockContact","chatTitle","handleDeleteMessageForAll","shouldDeleteForAll","handleDeleteAndStop","contactId","accessHash","handleDeleteChat","isCreator","header","color","isText","smaller","withDate","datetime","sender","onMediaClick","extension","getDocumentExtension","timestamp","withMediaViewer","mediaType","isDownloadAllowed","setIsDownloadAllowed","hasPreview","getDocumentHasPreview","getMessageMediaThumbDataUri","localBlobUrl","previewData","isAllowed","download","name","thumbnailDataUri","actionIcon","isMessageDocumentVideo","elementRef","shouldSpinnerRender","getColorFromExtension","sizeString","getFileSizeString","shouldRenderThumb","getDocumentThumbnailDimensions","onlineCount","selectChatOnlineCount","areMessagesLoaded","selectChatMessages","typingStatus","avatarSize","withUsername","withFullInfo","withUpdatingStatus","withChatType","noRtl","loadFullChat","openMediaViewer","isMin","handleAvatarViewerOpen","hasPhoto","stopPropagation","avatarOwnerId","origin","MediaViewerOrigin","isVerified","getChatTypeString","handle","groupStatus","chatTypeString","membersCount","getGroupStatus","onlineStatus","renderStatusOrTyping","outgoingStatus","status","idPrefix","mediaBlobUrl","video","getMessageVideo","isGif","Keys","activeKey","itemIds","selectedIds","filterValue","filterPlaceholder","notFoundText","searchInputId","isLoading","noScrollRestore","onSelectedIdsChange","onFilterChange","onLoadMore","inputRef","shouldMinimize","requestAnimationFrame","focus","handleItemClick","newSelectedIds","includes","splice","indexOf","handleFilterChange","viewportIds","getMore","useInfiniteScroll","map","isMinimized","canClose","clickArg","onChange","placeholder","items","iconElement","titleText","serverTimeOffset","noStatusOrTyping","fullName","getUserStatus","photo","isFirstPhoto","getMediaHash","forceAvatar","hash","fullMediaData","startsWith","avatarThumbnailData","useBlurSync","imageSrc","prevImageSrc","usePrevious","Spinner","connectionState","animationLevel","settings","byKey","photos","slideAnimation","currentPhotoIndex","setCurrentPhotoIndex","isFirst","isLast","profile","currentIndex","slice","mediaLoader","usePhotosPreload","handleProfilePhotoClick","profilePhotoIndex","selectPreviousMedia","selectNextMedia","element","querySelector","captureEvents","selectorToPreventScroll","onSwipe","IS_TOUCH_ENV","direction","SwipeDirection","renderPhoto","isVerifiedIconShown","_","renderPhotoTabs","Transition","type","VerifiedIcon","noAnimate","onUnfaveClick","stickerSelector","shouldPlay","lottieData","isAnimated","markLoaded","unmarkLoaded","canAnimatedPlay","shouldRenderPreview","previewTransitionClassNames","emoji","preventDefault","props","StickerSetModal","useModuleLoader","Bundles","typingUser","typingUserName","action","replace","trim","onMessageClick","linkData","getMessageWebPage","getFirstLinkInMessage","url","domain","messageText","getMessageSummaryText","siteName","handleMessageClick","displayUrl","truncatedDescription","trimText","MEDIA_VIEWER_MEDIA_QUERY","REM","parseInt","getComputedStyle","documentElement","fontSize","ROUND_VIDEO_DIMENSIONS","AVATAR_FULL_DIMENSIONS","DEFAULT_MEDIA_DIMENSIONS","cachedMaxWidthOwn","cachedMaxWidth","cachedMaxWidthNoAvatar","getAvailableWidth","fromOwnMessage","isForwarded","isWebPagePhoto","noAvatars","extraPaddingRem","regularMaxWidth","windowWidth","windowSize","getMaxMessageWidthRem","calculateDimensionsForMessageMedia","aspectRatio","calculateDimensions","getAvailableHeight","getMediaViewerAvailableDimensions","withFooter","isVideo","mql","window","matchMedia","windowHeight","occupiedHeightRem","matches","calculateInlineImageDimensions","getPhotoInlineDimensions","calculateVideoDimensions","getVideoDimensions","getPictogramDimensions","getStickerDimensions","baseWidth","STICKER_SIZE_INLINE_MOBILE_FACTOR","STICKER_SIZE_INLINE_DESKTOP_FACTOR","calculatedHeight","calculateMediaViewerDimensions","availableWidth","availableHeight","mediaWidth","mediaHeight","calculatedWidth","renderMessageText","highlight","shouldRenderHqEmoji","formattedText","rawText","getMessageText","entities","renderTextWithEntities","organizeEntity","index","organizedEntityIndexes","offset","organizedIndexes","Set","has","nestedEntities","filter","parsedEntity","isChanged","organizedIndex","add","organizeEntities","organizedEntities","organizedEntity","shouldRenderAsHtml","renderMessagePart","deleteLineBreakAfterPre","renderEntity","textPartStart","textPartEnd","isLastEntity","renderResult","textBefore","substring","textBeforeLength","substr","entityStartIndex","entityEndIndex","entityContent","nestedEntityContent","ApiMessageEntityTypes","nestedIndex","nestedEntity","nestedEntityIndex","nestedResult","nestedEntityEndIndex","newEntity","rawEntityText","renderedContent","getLinkUrl","processEntityAsHtml","entityText","handleBotCommandClick","handleHashtagClick","href","rel","processEntity","isArray","textAfter","arrayIndex","c","emojiFilter","getDispatch","sendBotCommand","command","innerText","setLocalTextSearchQuery","query","searchTextMessagesLocal","ChatAnimationTypes","isPinned","isShown","unreadCount","hasUnreadMark","renderContent","unreadMentionsCount","formatIntegerCompact","ShowTransition","isCustom","lastMessage","replyToMessageId","isOutgoing","lastMessageSender","lastMessageAction","getMessageAction","actionTargetMessage","selectChatMessage","targetUserIds","actionTargetUserIds","targetChatId","actionTargetChatId","privateChatUserId","byId","usersById","users","currentChatId","threadId","currentThreadId","messageListType","selectCurrentMessageList","MAIN_THREAD_ID","draft","selectDraft","canScrollDown","lastMessageOutgoingStatus","selectOutgoingStatus","privateChatUser","folderId","orderDiff","animationType","openChat","focusLastMessage","isDeleteModalOpen","openDeleteModal","closeDeleteModal","shouldRenderDeleteModal","markRenderDeleteModal","unmarkRenderDeleteModal","isAction","isActionMessage","useEnsureMessage","mediaThumbnail","getMessageSticker","isRoundVideo","getMessageRoundVideo","actionTargetUsers","useLayoutEffect","Opacity","opacity","classList","Move","transform","remove","ANIMATION_END_DELAY","shouldReplaceHistory","contextActions","useChatContextActions","handleDelete","ListItem","Avatar","LastMessageMeta","TypingStatus","actionOrigin","renderActionMessageText","asPlain","senderName","getMessageSenderName","blobUrl","renderMessageSummary","renderLastMessageOrTyping","DeleteChatModal","folderType","chatFolder","selectChatFolder","animatedEmoji","selectAnimatedEmoji","foldersDispatch","onScreenSelect","handleEditFolder","payload","SettingsScreens","AnimatedEmoji","fluid","pill","FolderTypeToListType","chats","listIds","chatsById","orderedPinnedIds","listType","notifySettings","notifyExceptions","isActive","loadMoreChats","preloadTopChatMessages","openNextChat","currentListIds","currentPinnedIds","prepareFolderListIds","orderById","orderedIds","newChatArrays","prepareChatList","singleList","pinnedChats","otherChats","newOrderedIds","reduce","acc","prevOrderById","orderDiffById","mapValues","order","Infinity","loadMoreOfType","CHAT_LIST_SLICE","ALL_CHATS_PRELOAD_DISABLED","chatArrays","getAnimationType","movesUp","movesDown","orderDiffIds","Object","keys","Number","numberOfUp","numberOfDown","None","useChatAnimationType","handleKeyDown","IS_PWA","IS_MAC_OS","metaKey","ctrlKey","code","digit","match","position","altKey","targetIndexDelta","addEventListener","removeEventListener","InfiniteScroll","preloadBackwards","noFastList","viewportOffset","pinnedOffset","IS_ANDROID","CHAT_HEIGHT_PX","teactFastList","teactOrderKey","getChatOrder","renderChats","Loading","isQuick","onFileSelect","isHovered","markHovered","unmarkHovered","onDrop","onDragEnter","onDragLeave","relatedTarget","toTarget","DropAreaState","withQuick","onHide","hideTimeoutRef","prevWithQuick","captureEscKeyListener","handleFilesDrop","dataTransfer","dt","files","from","handleQuickFilesDrop","handleDragLeave","fromTarget","onDragOver","clearTimeout","EmojiTooltip","MAX_INPUT_HEIGHT","messageSendKeyCombo","replyingToId","selectReplyingToId","noTabCapture","isPollModalOpen","payment","isPaymentModalOpen","isAttachmentModalInput","editableInputId","html","forcedPlaceholder","shouldSetFocus","shouldSuppressFocus","shouldSuppressTextFormatter","onUpdate","onSuppressedFocus","onSend","editLastMessage","replyToNextMessage","cloneRef","isContextMenuOpenRef","isTextFormatterOpen","openTextFormatter","closeTextFormatter","textFormatterAnchorPosition","setTextFormatterAnchorPosition","selectedRange","setSelectedRange","updateInputHeight","useLayoutEffectWithPrevDeps","prevHtml","innerHTML","focusInput","focusEditableElement","handleCloseTextFormatter","selection","getSelection","removeAllRanges","empty","clearSelection","checkSelection","IS_IOS","rangeCount","selectionRange","getRangeAt","selectedText","toString","isSelectionInsideInput","EDITABLE_INPUT_ID","parseEmojiOnlyString","START_TO_END","selectionRect","inputRect","top","willSend","input","clone","currentHeight","newHeight","scrollHeight","transitionDuration","log","abs","toggle","captureFirstTab","debounce","captureKeyboardListeners","onTab","suppressFocus","blur","contentEditable","textContent","onKeyDown","shiftKey","handleKeyUp","event","button","closeContextMenuMouseListener","closeContextMenuKeyListener","handleMouseUp","onContextMenu","onTouchCancel","anchorPosition","TEXT_FORMAT_BY_TAG_NAME","B","STRONG","I","EM","U","DEL","CODE","fragmentEl","containerRef","linkUrlInputRef","isLinkControlOpen","openLinkControl","closeLinkControl","linkUrl","setLinkUrl","isEditingLink","setIsEditingLink","inputClassName","setInputClassName","selectedTextFormats","setSelectedTextFormats","useVirtualBackdrop","selectedFormats","parentElement","commonAncestorContainer","textFormat","tagName","getSelectedText","getSelectedElement","updateInputStyles","offsetWidth","scrollWidth","scrollLeft","getFormatButtonClassName","some","fKey","monospace","strikethrough","handleBoldText","execCommand","bold","handleItalicText","italic","handleUnderlineText","underline","handleStrikethroughText","replaceWith","handleMonospaceText","handleLinkUrlConfirm","formattedLinkUrl","encodeURI","addRange","restoreSelection","handler","KeyK","KeyB","KeyU","KeyI","KeyM","KeyS","linkUrlConfirmClassName","autoComplete","inputMode","onScroll","ENTITY_CLASS_BY_NODE_NAME","S","STRIKE","PRE","BLOCKQUOTE","parseMessageInput","fragment","parsedHtml","IS_EMOJI_SUPPORTED","parseMarkdown","textIndex","recursionDeepness","addEntity","node","nodeName","anchor","dataset","entityType","getEntityTypeFromNode","rawIndex","getEntityDataFromNode","hasChildNodes","childNodes","inputId","parentNode","iterations","emojiDataPromise","emojiRawData","emojiData","RE_EMOJI_SEARCH","RE_BR","RE_SPACE","RE_CLEAN_HTML","RegExp","useEmojiTooltip","recentEmojiIds","onUpdateHtml","baseEmojiKeywords","emojiKeywords","isDisabled","markIsOpen","unmarkIsOpen","setById","keywords","setKeywords","byKeyword","setByKeyword","names","setNames","byName","setByName","shouldForceInsertEmoji","setShouldForceInsertEmoji","filteredEmojis","setFilteredEmojis","MEMO_EMPTY_ARRAY","recentEmojis","values","pickTruthy","emojis","uncompressEmoji","ensureEmojiData","byNative","buildCollectionByKey","baseEmojisByKeyword","natives","emojisByKeyword","emojisByName","getEmojiCode","forceSend","endsWith","matched","matchedKeywords","keyword","sort","concat","flatten","matchedNames","unique","insertEmoji","textEmoji","isForce","atIndex","lastIndexOf","messageInput","getElementById","native","isEmojiTooltipOpen","closeEmojiTooltip","searchUserName","usernameLowered","toLowerCase","fullNameLowered","filterLowered","searchWords","runThrottled","throttle","cb","RE_USERNAME_SEARCH","useMentionTooltip","canSuggestMembers","groupChatMembers","topInlineBotIds","usersToMention","setUsersToMention","topInlineBots","getFilteredUsers","withInlineBots","inlineBots","inlineBot","chatMembers","usernameFilter","getUsernameFilter","canSuggestInlineBots","insertMention","forceFocus","insertedHtml","isMentionTooltipOpen","closeMentionTooltip","mentionFilteredUsers","useAsyncRendering","dependencies","delay","shouldRenderRef","timeoutRef","forceUpdate","useForceUpdate","useOnChange","textParts","confirmLabel","confirmHandler","confirmIsDestructive","isButtonsInOneRow","onEnter","split","textPart","disabled","children","buttonClassName","tabIndex","itemSelector","sensitiveArea","noScrollRestoreOnTop","cacheBuster","stateRef","loadMoreBackwards","loadMoreForwards","noScroll","LoadMoreDirection","clientHeight","state","newScrollTop","listItemElements","querySelectorAll","currentAnchor","scrollTop","currentAnchorTop","nextAnchor","resetScroll","isScrollTopJustUpdated","handleScroll","listLength","offsetHeight","isNearTop","offsetTop","isNearBottom","isUpdated","nextAnchorTop","newAnchorTop","offsetParent","buttonRef","destructive","isTouched","markIsTouched","unmarkIsTouched","isContextMenuOpen","contextMenuPosition","handleBeforeContextMenu","handleContextMenu","handleContextMenuClose","handleContextMenuHide","useContextMenuHandlers","getTriggerElement","getRootElement","getMenuElement","positionX","positionY","menuStyle","useContextMenuPosition","handleMouseDown","role","autoClose","hasCloseButton","noBackdrop","shouldSkipHistoryAnimations","modalRef","onEsc","focusableElements","currentFocusedIndex","findIndex","em","isSameNode","activeElement","newFocusedIndex","trapFocus","forceClose","useHistoryBack","useEffectWithPrevDeps","prevIsOpen","body","dispatchHeavyAnimationEvent","Portal","containerId","onDismiss","setIsOpen","timerRef","closeAndDismiss","handleMouseEnter","handleMouseLeave","onMouseEnter","onMouseLeave","appendChild","TeactDOM","removeChild","RADIUSES","s","m","xl","square","circleRadius","STROKE_WIDTH","borderRadius","circumference","PI","svg","firstElementChild","strokeDashOffset","setAttribute","subLabel","hidden","options","selected","loadingOption","handleChange","option","parentContainerClassName","focused","onReset","onFocus","onBlur","isInputFocused","markInputFocused","unmarkInputFocused","prevChildren","fromChildrenRef","noAnimation","onCheck","active","badgeCount","isBadgeActive","previousActiveTab","tabRef","tab","indicator","prevTab","currentIndicator","shiftLeft","offsetLeft","scaleFactor","clientWidth","tabs","activeTab","big","onSwitchTab","useHorizontalScroll","activeTabElement","newLeft","fastSmoothScrollHorizontal","CLEANED_UP","Symbol","renderCount","shouldRestoreHeight","shouldCleanup","cleanupExceptionKey","onStart","onStop","getGlobal","currentKeyRef","rendersRef","prevActiveKey","activeKeyChanged","cleanup","childElements","isBackwards","prevActiveIndex","activeIndex","HTMLElement","dispatchHeavyAnimationStop","onAnimationEnd","watchedNode","firstChild","waitForAnimationEnd","flexBasis","renders","contents","render","INCLUDED_CHAT_TYPES","EXCLUDED_CHAT_TYPES","INCLUDE_FILTER_FIELDS","EXCLUDE_FILTER_FIELDS","selectChatFilters","mode","selectTemp","selectedChatIds","selectedChatTypes","includedChatIds","includeFilters","folder","excludedChatIds","excludeFilters","getSuggestedFolderName","filters","bots","groups","channels","contacts","nonContacts","INITIAL_STATE","chatFilter","foldersReducer","omit","error","useReducer","trackId","originalDuration","handlers","onInit","onForcePlay","noPlaylist","controllerRef","setIsPlaying","isPlayingSync","setPlayProgress","register","eventName","proxy","isFinite","currentTime","paused","isSafariPatchInProgress","prevShouldPlay","prevSrc","audioProxy","hasFocus","cache","Map","blurredRef","img","Image","imgToCanvas","fastBlur","blurredAsync","get","onload","blurredDataUri","clear","set","useBlur","noInitiallyBuffered","setIsBuffered","setBufferedProgress","setIsBufferedDebounced","handleBuffering","media","buffered","end","readyState","onLoadedData","onPlaying","onLoadStart","onPause","onTimeUpdate","onProgress","useCanvasBlur","withRaf","canvasRef","processBlur","alpha","IS_CANVAS_FILTER_SUPPORTED","drawImage","RADIUS","toggleChatPinned","toggleChatArchived","toggleChatUnread","actionUnreadMark","actionPin","actionMute","actionArchive","isChatArchived","getCanDeleteChat","contextMenuCounter","isMenuDisabled","shouldDisableOnLink","shouldDisableOnLongTap","setIsContextMenuOpen","setContextMenuPosition","clientY","timer","clearLongPressTimer","startLongPressTimer","contains","originalEvent","touches","cancelClickOnce","stopImmediatePropagation","emulateContextMenuEvent","passive","extraPaddingX","extraTopPadding","setPositionX","setPositionY","setStyle","triggerEl","emptyRect","menuEl","rootEl","triggerRect","menuRect","rootRect","horizontalPostition","useCurrentOrPrev","shouldSkipUndefined","shouldForceCurrent","prev","messageId","replyOriginForId","loadMessage","loadMessageThrottled","throttled","deltaX","deltaY","listSlice","forceFullPreload","lastParamsRef","viewportIdsRef","newViewportIds","getViewportSlice","prevListIds","prevIsDisabled","offsetId","areSortedArraysEqual","areSomeLocal","areAllLocal","sourceIds","indexForDirection","to","useIntersectionObserver","rootRef","throttleMs","debounceMs","shouldSkipFirst","margin","threshold","rootCallback","rootCallbackRef","freezeFlagsRef","autoUnfreezeTimeoutRef","onUnfreezeRef","unfreeze","freeze","observer","disconnect","callbacks","observe","targetCallback","entriesAccumulator","observerCallbackSync","entries","entry","callback","scheduler","observerCallback","IntersectionObserver","root","rootMargin","initController","controller","delete","unobserve","useOnIntersect","targetRef","setIsIntersecting","debugKey","prevDeps","mediaHash","noLoad","mediaFormat","startedAt","Date","now","spentTime","setIsDownloadStarted","isHtmlAllowed","isStreaming","IS_PROGRESSIVE_SUPPORTED","setDownloadProgress","startedAtRef","handleProgress","closeTimeout","useMouseInside","menuCloseTimeout","isMouseInside","usePrevDuringAnimation","isCurrentPresent","isPrevPresent","reducer","initialState","reducerRef","setState","currentState","SPEED","fast","slow","willAnimate","setShouldRenderThumb","useVideoCleanup","videoRef","videoEl","load","mul_table","shg_table","boxBlurCanvasRGB","context","top_x","top_y","isNaN","imageData","getImageData","pixels","rsum","gsum","bsum","p","p1","p2","yp","yi","yw","wm","hm","rad1","r","g","b","mul_sum","shg_sum","vmin","vmax","putImageData","tracks","currentTrackId","queue","stopCurrentAudio","currentTrack","Audio","handleEvent","nextTrackId","openAudioPlayer","parseMessageKey","nextTrack","safePlay","Proxy","createAudio","preload","IS_SAFARI","patchSafariProgressiveAudio","time","shouldRemoveFromQueue","track","h","captureEvent","hasMoved","hasSwiped","onCapture","excludedClosestSelector","onMove","onRelease","pageX","pageY","withCursor","scrollable","overflow","dragOffsetX","dragOffsetY","shouldPreventScroll","onDrag","innerWidth","xAbs","yAbs","axis","currentSwipeAxis","Left","Right","Up","Down","processSwipe","CLIPBOARD_ITEM_SUPPORTED","navigator","clipboard","ClipboardItem","textCopyEl","str","rangeToRestore","select","copyImageToClipboard","imageUrl","imageEl","toBlob","copyBlobToClipboard","pngBlob","write","DEBUG","console","waitForTransitionEnd","propertyName","waitForEndEvent","animationName","eventType","detailedName","isHandled","handleAnimationEnd","TransitionEvent","AnimationEvent","cycleRestrict","filename","click","isAnimating","fastSmoothScroll","maxDistance","FAST_SMOOTH_MAX_DISTANCE","forceDirection","forceDuration","forceNormalContainerHeight","scrollFrom","elementTop","FocusDirection","calculateScrollFrom","ANIMATION_LEVEL_MIN","scrollWithJs","isAnimatingScroll","elementHeight","currentScrollTop","containerHeight","targetContainerHeight","normalHeight","path","remainingPath","absPath","transition","FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE","shortTransition","longTransition","FAST_SMOOTH_MIN_DURATION","FAST_SMOOTH_MAX_DURATION","startAt","onHeavyAnimationStop","animateSingle","t","currentPath","containerWidth","animate","scrollTo","behavior","force","range","createRange","lastChild","nodeValue","selectNodeContents","collapse","audioEl","patchedForSafari","patchForSafariInProgress","once","mediaEl","catch","err","warn"],"sourceRoot":""} |