telegram-tt/dist/37.a4576a2f0b9a0e6ee909.js.map
Alexander Zinchuk 0b1fc0904e [Build]
2022-03-11 19:41:56 +01:00

1 line
471 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"version":3,"file":"37.a4576a2f0b9a0e6ee909.js","mappings":"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IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,EAAG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,EAAG,GAAI,IAAK,GAAI,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,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,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,GA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","sources":["webpack://telegram-t/./src/components/common/AnimatedEmoji.tsx","webpack://telegram-t/./src/components/common/helpers/waveform.ts","webpack://telegram-t/./src/util/waveform.ts","webpack://telegram-t/./src/components/common/Audio.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/DotAnimation.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/ReactionStaticEmoji.tsx","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/hooks/useAnimatedEmoji.ts","webpack://telegram-t/./src/components/left/ChatFolderModal.async.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/ChatCallStatus.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/left/search/helpers/getSenderName.ts","webpack://telegram-t/./src/components/middle/composer/CustomSendMenu.async.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/getFilesFromDataTransferItems.ts","webpack://telegram-t/./src/components/middle/composer/helpers/prepareForRegExp.ts","webpack://telegram-t/./src/components/middle/composer/helpers/selection.ts","webpack://telegram-t/./src/util/memoized.ts","webpack://telegram-t/./src/components/middle/composer/hooks/useEmojiTooltip.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/CheckboxGroup.tsx","webpack://telegram-t/./src/components/ui/FloatingActionButton.tsx","webpack://telegram-t/./src/components/ui/ListItem.tsx","webpack://telegram-t/./src/components/ui/Notification.tsx","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/RangeSlider.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/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/useDebounce.ts","webpack://telegram-t/./src/hooks/useEnsureMessage.ts","webpack://telegram-t/./src/hooks/useFolderManager.ts","webpack://telegram-t/./src/hooks/useHorizontalScroll.ts","webpack://telegram-t/./src/hooks/useInputFocusOnOpen.ts","webpack://telegram-t/./src/hooks/useIntersectionObserver.ts","webpack://telegram-t/./src/hooks/useInterval.ts","webpack://telegram-t/./src/hooks/useLayoutEffectWithPrevDeps.ts","webpack://telegram-t/./src/hooks/useMediaTransition.ts","webpack://telegram-t/./src/hooks/useUniqueId.ts","webpack://telegram-t/./src/hooks/useMediaWithLoadProgress.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/useSendMessageAction.ts","webpack://telegram-t/./src/hooks/useStateRef.ts","webpack://telegram-t/./src/hooks/useTimeout.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/cssAnimationEndListeners.ts","webpack://telegram-t/./src/util/cycleRestrict.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/getKeyFromEvent.ts","webpack://telegram-t/./src/util/getMessageIdsForSelectedText.ts","webpack://telegram-t/./src/util/mediaSession.ts","webpack://telegram-t/./src/util/parseMessageInput.ts","webpack://telegram-t/./src/util/patchSafariProgressiveAudio.ts","webpack://telegram-t/./src/util/stopEvent.ts","webpack://telegram-t/./src/util/systemFilesDialog.ts"],"sourcesContent":["import React, {\n FC, memo,\n} from '../../lib/teact/teact';\n\nimport { ApiMediaFormat, ApiSticker } from '../../api/types';\nimport { ActiveEmojiInteraction } from '../../global/types';\n\nimport buildClassName from '../../util/buildClassName';\nimport { ObserveFn, useIsIntersecting } from '../../hooks/useIntersectionObserver';\nimport useMedia from '../../hooks/useMedia';\nimport useMediaTransition from '../../hooks/useMediaTransition';\nimport useAnimatedEmoji from './hooks/useAnimatedEmoji';\nimport { LIKE_STICKER_ID } from './helpers/mediaDimensions';\n\nimport AnimatedSticker from './AnimatedSticker';\n\nimport './AnimatedEmoji.scss';\n\ntype OwnProps = {\n sticker: ApiSticker;\n effect?: ApiSticker;\n isOwn?: boolean;\n soundId?: string;\n observeIntersection?: ObserveFn;\n size?: 'large' | 'medium' | 'small';\n lastSyncTime?: number;\n forceLoadPreview?: boolean;\n messageId?: number;\n chatId?: string;\n activeEmojiInteractions?: ActiveEmojiInteraction[];\n};\n\nconst QUALITY = 1;\n\nconst AnimatedEmoji: FC<OwnProps> = ({\n sticker,\n effect,\n isOwn,\n soundId,\n size = 'medium',\n observeIntersection,\n lastSyncTime,\n forceLoadPreview,\n messageId,\n chatId,\n activeEmojiInteractions,\n}) => {\n const {\n markAnimationLoaded,\n isAnimationLoaded,\n ref,\n width,\n style,\n handleClick,\n playKey,\n } = useAnimatedEmoji(size, chatId, messageId, soundId, activeEmojiInteractions, isOwn, undefined, effect?.emoji);\n\n const localMediaHash = `sticker${sticker.id}`;\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n\n const thumbDataUri = sticker.thumbnail?.dataUri;\n const previewBlobUrl = useMedia(\n `${localMediaHash}?size=m`,\n !isIntersecting && !forceLoadPreview,\n ApiMediaFormat.BlobUrl,\n lastSyncTime,\n );\n const transitionClassNames = useMediaTransition(previewBlobUrl);\n\n const mediaData = useMedia(localMediaHash, !isIntersecting, ApiMediaFormat.Lottie, lastSyncTime);\n const isMediaLoaded = Boolean(mediaData);\n\n return (\n <div\n ref={ref}\n className={buildClassName('AnimatedEmoji media-inner', sticker.id === LIKE_STICKER_ID && 'like-sticker-thumb')}\n style={style}\n onClick={handleClick}\n >\n {!isAnimationLoaded && thumbDataUri && (\n <img src={thumbDataUri} alt=\"\" />\n )}\n {!isAnimationLoaded && previewBlobUrl && (\n <img src={previewBlobUrl} className={transitionClassNames} alt=\"\" />\n )}\n {isMediaLoaded && localMediaHash && (\n <AnimatedSticker\n key={localMediaHash}\n id={localMediaHash}\n animationData={mediaData!}\n size={width}\n quality={QUALITY}\n play={isIntersecting && playKey}\n forceOnHeavyAnimation\n noLoop\n onLoad={markAnimationLoaded}\n />\n )}\n </div>\n );\n};\n\nexport default memo(AnimatedEmoji);\n","type IWaveformProps = {\n peak: number;\n fillStyle: string;\n progressFillStyle: string;\n};\n\nexport const MAX_EMPTY_WAVEFORM_POINTS = 30;\nconst SPIKE_WIDTH = 2;\nconst SPIKE_STEP = 4;\nconst SPIKE_RADIUS = 1;\nconst HEIGHT = 23;\n\nexport function renderWaveform(\n canvas: HTMLCanvasElement,\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 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\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","/* 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","import React, {\n FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,\n} from '../../lib/teact/teact';\nimport { getDispatch } from '../../lib/teact/teactn';\n\nimport {\n ApiAudio, ApiMediaFormat, ApiMessage, ApiVoice,\n} from '../../api/types';\nimport { AudioOrigin, 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 getMessageMediaFormat,\n getMessageMediaHash,\n isMessageLocal,\n isOwnMessage,\n} from '../../modules/helpers';\nimport { MAX_EMPTY_WAVEFORM_POINTS, renderWaveform } from './helpers/waveform';\nimport buildClassName from '../../util/buildClassName';\nimport renderText from './helpers/renderText';\nimport { getFileSizeString } from './helpers/documentInfo';\nimport { decodeWaveform, interpolateArray } from '../../util/waveform';\nimport useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useBuffering from '../../hooks/useBuffering';\nimport useAudioPlayer from '../../hooks/useAudioPlayer';\nimport useLang, { LangFn } from '../../hooks/useLang';\nimport { captureEvents } from '../../util/captureEvents';\nimport useMedia from '../../hooks/useMedia';\nimport { makeTrackId } from '../../util/audioPlayer';\nimport { getTranslation } from '../../util/langProvider';\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 origin: AudioOrigin;\n date?: number;\n lastSyncTime?: number;\n className?: string;\n isSelectable?: boolean;\n isSelected?: boolean;\n isDownloading: boolean;\n onPlay: (messageId: number, chatId: string) => void;\n onReadMedia?: () => void;\n onCancelUpload?: () => void;\n onDateClick?: (messageId: number, chatId: string) => void;\n};\n\nconst AVG_VOICE_DURATION = 10;\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 origin,\n date,\n lastSyncTime,\n className,\n isSelectable,\n isSelected,\n isDownloading,\n onPlay,\n onReadMedia,\n onCancelUpload,\n onDateClick,\n}) => {\n const { content: { audio, voice, video }, isMediaUnread } = message;\n const isVoice = Boolean(voice || video);\n const isSeeking = useRef<boolean>(false);\n const playStateBeforeSeeking = useRef<boolean>(false);\n // eslint-disable-next-line no-null/no-null\n const seekerRef = useRef<HTMLDivElement>(null);\n const lang = useLang();\n const { isRtl } = lang;\n const dispatch = getDispatch();\n\n const [isActivated, setIsActivated] = useState(false);\n const shouldLoad = (isActivated || PRELOAD) && lastSyncTime;\n const coverHash = getMessageMediaHash(message, 'pictogram');\n const coverBlobUrl = useMedia(coverHash, false, ApiMediaFormat.BlobUrl);\n\n const mediaData = useMedia(\n getMessageMediaHash(message, 'inline'),\n !shouldLoad,\n getMessageMediaFormat(message, 'inline'),\n );\n\n const { loadProgress: downloadProgress } = useMediaWithLoadProgress(\n getMessageMediaHash(message, 'download'),\n !isDownloading,\n );\n\n const handleForcePlay = useCallback(() => {\n setIsActivated(true);\n onPlay(message.id, message.chatId);\n }, [message, onPlay]);\n\n const handleTrackChange = useCallback(() => {\n setIsActivated(false);\n }, []);\n\n const {\n isBuffered, bufferedProgress, bufferingHandlers, checkBuffering,\n } = useBuffering();\n\n const {\n isPlaying, playProgress, playPause, play, pause, setCurrentTime, duration,\n } = useAudioPlayer(\n makeTrackId(message),\n getMediaDuration(message)!,\n isVoice ? 'voice' : 'audio',\n mediaData,\n bufferingHandlers,\n undefined,\n checkBuffering,\n isActivated,\n handleForcePlay,\n handleTrackChange,\n isMessageLocal(message),\n );\n\n const isOwn = isOwnMessage(message);\n const waveformCanvasRef = useWaveformCanvas(theme, voice, (isMediaUnread && !isOwn) ? 1 : playProgress, isOwn);\n\n const withSeekline = isPlaying || (playProgress > 0 && playProgress < 1);\n\n useEffect(() => {\n setIsActivated(isPlaying);\n }, [isPlaying]);\n\n const isLoadingForPlaying = isActivated && !isBuffered;\n\n const {\n isUploading, isTransferring, transferProgress,\n } = getMediaTransferState(\n message,\n uploadProgress || downloadProgress,\n isLoadingForPlaying || isDownloading,\n );\n\n const {\n shouldRender: shouldRenderSpinner,\n transitionClassNames: spinnerClassNames,\n } = useShowTransition(isTransferring);\n\n const shouldRenderCross = shouldRenderSpinner && (isLoadingForPlaying || isUploading);\n\n const handleButtonClick = useCallback(() => {\n if (isUploading) {\n onCancelUpload?.();\n return;\n }\n\n if (!isPlaying) {\n onPlay(message.id, message.chatId);\n }\n\n getDispatch().setAudioPlayerOrigin({ origin });\n setIsActivated(!isActivated);\n playPause();\n }, [isUploading, isPlaying, isActivated, playPause, onCancelUpload, onPlay, message.id, message.chatId, origin]);\n\n useEffect(() => {\n if (onReadMedia && isMediaUnread && (isPlaying || isDownloading)) {\n onReadMedia();\n }\n }, [isPlaying, isMediaUnread, onReadMedia, isDownloading]);\n\n const handleDownloadClick = useCallback(() => {\n if (isDownloading) {\n dispatch.cancelMessageMediaDownload({ message });\n } else {\n dispatch.downloadMessageMedia({ message });\n }\n }, [dispatch, isDownloading, message]);\n\n const handleSeek = useCallback((e: MouseEvent | TouchEvent) => {\n if (isSeeking.current && seekerRef.current) {\n const { width, left } = seekerRef.current.getBoundingClientRect();\n const clientX = e instanceof MouseEvent ? e.clientX : e.targetTouches[0].clientX;\n e.stopPropagation(); // Prevent Slide-to-Reply activation\n // Prevent track skipping while seeking near end\n setCurrentTime(Math.max(Math.min(duration * ((clientX - left) / width), duration - 0.1), 0.001));\n }\n }, [duration, setCurrentTime]);\n\n const handleStartSeek = useCallback((e: MouseEvent | TouchEvent) => {\n if (e instanceof MouseEvent && e.button === 2) return;\n isSeeking.current = true;\n playStateBeforeSeeking.current = isPlaying;\n pause();\n handleSeek(e);\n }, [handleSeek, pause, isPlaying]);\n\n const handleStopSeek = useCallback(() => {\n isSeeking.current = false;\n if (playStateBeforeSeeking.current) play();\n }, [play]);\n\n const handleDateClick = useCallback(() => {\n onDateClick!(message.id, message.chatId);\n }, [onDateClick, message.id, message.chatId]);\n\n useEffect(() => {\n if (!seekerRef.current || !withSeekline) return undefined;\n return captureEvents(seekerRef.current, {\n onCapture: handleStartSeek,\n onRelease: handleStopSeek,\n onClick: handleStopSeek,\n onDrag: handleSeek,\n });\n }, [withSeekline, handleStartSeek, handleSeek, handleStopSeek]);\n\n function renderFirstLine() {\n if (isVoice) {\n return senderTitle || 'Voice';\n }\n\n const { title, fileName } = audio!;\n\n return title || fileName;\n }\n\n function renderSecondLine() {\n if (isVoice) {\n return (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n {formatMediaDuration((voice || video)!.duration)}\n </div>\n );\n }\n\n const { performer } = audio!;\n\n return (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n {formatMediaDuration(duration)}\n <span className=\"bullet\">&bull;</span>\n {performer && <span className=\"performer\" title={performer}>{renderText(performer)}</span>}\n {performer && senderTitle && <span className=\"bullet\">&bull;</span>}\n {senderTitle && <span title={senderTitle}>{renderText(senderTitle)}</span>}\n </div>\n );\n }\n\n const fullClassName = buildClassName(\n 'Audio',\n className,\n isOwn && origin === AudioOrigin.Inline && 'own',\n (origin === AudioOrigin.Search || origin === AudioOrigin.SharedMedia) && 'bigger',\n isSelected && 'audio-is-selected',\n );\n\n const buttonClassNames = ['toggle-play'];\n if (shouldRenderCross) {\n buttonClassNames.push('loading');\n } else if (isPlaying) {\n buttonClassNames.push('pause');\n } else if (!isPlaying) {\n buttonClassNames.push('play');\n }\n\n const contentClassName = buildClassName('content', withSeekline && 'with-seekline');\n\n function renderWithTitle() {\n return (\n <>\n <div className={contentClassName}>\n <div className=\"content-row\">\n <p className=\"title\" dir=\"auto\" title={renderFirstLine()}>{renderText(renderFirstLine())}</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 {withSeekline && (\n <div className=\"meta search-result\" dir={isRtl ? 'rtl' : undefined}>\n <span className=\"duration with-seekline\" dir=\"auto\">\n {playProgress < 1 && `${formatMediaDuration(duration * playProgress, duration)}`}\n </span>\n {renderSeekline(playProgress, bufferedProgress, seekerRef)}\n </div>\n )}\n {!withSeekline && renderSecondLine()}\n </div>\n </>\n );\n }\n\n return (\n <div className={fullClassName} dir={lang.isRtl ? 'rtl' : 'ltr'}>\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=\"smaller\"\n color={coverBlobUrl ? 'translucent-white' : 'primary'}\n className={buttonClassNames.join(' ')}\n ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}\n onClick={handleButtonClick}\n isRtl={lang.isRtl}\n backgroundImage={coverBlobUrl}\n >\n <i className=\"icon-play\" />\n <i className=\"icon-pause\" />\n </Button>\n {shouldRenderSpinner && (\n <div className={buildClassName('media-loading', spinnerClassNames, shouldRenderCross && 'interactive')}>\n <ProgressSpinner\n progress={transferProgress}\n transparent\n size=\"m\"\n onClick={shouldRenderCross ? handleButtonClick : undefined}\n noCross={!shouldRenderCross}\n />\n </div>\n )}\n {audio && !isUploading && (\n <Button\n round\n size=\"tiny\"\n className=\"download-button\"\n ariaLabel={isDownloading ? 'Cancel download' : 'Download'}\n onClick={handleDownloadClick}\n >\n <i className={isDownloading ? 'icon-close' : 'icon-arrow-down'} />\n </Button>\n )}\n {origin === AudioOrigin.Search && renderWithTitle()}\n {origin !== AudioOrigin.Search && audio && renderAudio(\n lang, audio, duration, isPlaying, playProgress, bufferedProgress, seekerRef,\n (isDownloading || isUploading), date, transferProgress, onDateClick ? handleDateClick : undefined,\n )}\n {origin === AudioOrigin.SharedMedia && (voice || video) && renderWithTitle()}\n {origin === AudioOrigin.Inline && voice && (\n renderVoice(voice, seekerRef, waveformCanvasRef, playProgress, isMediaUnread)\n )}\n </div>\n );\n};\n\nfunction renderAudio(\n lang: LangFn,\n audio: ApiAudio,\n duration: number,\n isPlaying: boolean,\n playProgress: number,\n bufferedProgress: number,\n seekerRef: React.Ref<HTMLElement>,\n showProgress?: boolean,\n date?: number,\n progress?: number,\n handleDateClick?: NoneToVoidFunction,\n) {\n const {\n title, performer, fileName,\n } = audio;\n const showSeekline = isPlaying || (playProgress > 0 && playProgress < 1);\n const { isRtl } = getTranslation;\n\n return (\n <div className=\"content\">\n <p className=\"title\" dir=\"auto\" title={title}>{renderText(title || fileName)}</p>\n {showSeekline && (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n <span className=\"duration with-seekline\" dir=\"auto\">\n {formatMediaDuration(duration * playProgress, duration)}\n </span>\n {renderSeekline(playProgress, bufferedProgress, seekerRef)}\n </div>\n )}\n {!showSeekline && showProgress && (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n {progress ? `${getFileSizeString(audio!.size * progress)} / ` : undefined}{getFileSizeString(audio!.size)}\n </div>\n )}\n {!showSeekline && !showProgress && (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n <span className=\"duration\" dir=\"auto\">{formatMediaDuration(duration)}</span>\n <span className=\"bullet\">&bull;</span>\n <span className=\"performer\" dir=\"auto\" title={performer}>{renderText(performer || 'Unknown')}</span>\n {date && (\n <>\n <span className=\"bullet\">&bull;</span>\n <Link className=\"date\" onClick={handleDateClick}>\n {formatMediaDateTime(lang, date * 1000, true)}\n </Link>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction renderVoice(\n voice: ApiVoice,\n seekerRef: React.Ref<HTMLDivElement>,\n waveformCanvasRef: React.Ref<HTMLCanvasElement>,\n playProgress: number,\n isMediaUnread?: boolean,\n) {\n return (\n <div className=\"content\">\n <div\n className=\"waveform\"\n draggable={false}\n ref={seekerRef}\n >\n <canvas ref={waveformCanvasRef} />\n </div>\n <p className={buildClassName('voice-duration', isMediaUnread && 'unread')} dir=\"auto\">\n {playProgress === 0 ? formatMediaDuration(voice.duration) : formatMediaDuration(voice.duration * playProgress)}\n </p>\n </div>\n );\n}\n\nfunction useWaveformCanvas(\n theme: ISettings['theme'],\n voice?: ApiVoice,\n playProgress = 0,\n isOwn = false,\n) {\n // eslint-disable-next-line no-null/no-null\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const { data: spikes, peak } = useMemo(() => {\n if (!voice) {\n return undefined;\n }\n\n const { waveform, duration } = voice;\n if (!waveform) {\n return {\n data: new Array(Math.min(duration, MAX_EMPTY_WAVEFORM_POINTS)).fill(0),\n peak: 0,\n };\n }\n\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\n return interpolateArray(decodedWaveform, spikesCount);\n }, [voice]) || {};\n\n useLayoutEffect(() => {\n const canvas = canvasRef.current;\n\n if (!canvas || !spikes || peak === undefined) {\n return;\n }\n\n const fillColor = theme === 'dark' ? '#494A78' : '#ADD3F7';\n const fillOwnColor = theme === 'dark' ? '#B7ABED' : '#AEDFA4';\n const progressFillColor = theme === 'dark' ? '#8774E1' : '#3390EC';\n const progressFillOwnColor = theme === 'dark' ? '#FFFFFF' : '#4FAE4E';\n\n renderWaveform(canvas, spikes, playProgress, {\n peak,\n fillStyle: isOwn ? fillOwnColor : fillColor,\n progressFillStyle: isOwn ? progressFillOwnColor : progressFillColor,\n });\n }, [isOwn, peak, playProgress, spikes, theme]);\n\n return canvasRef;\n}\n\nfunction renderSeekline(\n playProgress: number,\n bufferedProgress: number,\n seekerRef: React.Ref<HTMLElement>,\n) {\n return (\n <div\n className=\"seekline no-selection\"\n ref={seekerRef as React.Ref<HTMLDivElement>}\n >\n <span className=\"seekline-buffered-progress\">\n <i\n style={`transform: translateX(${bufferedProgress * 100}%)`}\n />\n </span>\n <span className=\"seekline-play-progress\">\n <i\n style={`transform: translateX(${playProgress * 100}%)`}\n />\n </span>\n <span className=\"seekline-thumb\">\n <i\n style={`transform: translateX(${playProgress * 100}%)`}\n />\n </span>\n </div>\n );\n}\n\nexport default memo(Audio);\n","import React, {\n FC, memo, useCallback, useEffect,\n} from '../../lib/teact/teact';\nimport { getDispatch, withGlobal } from '../../lib/teact/teactn';\n\nimport { GlobalState } from '../../global/types';\nimport { ApiChat, ApiCountryCode, ApiUser } from '../../api/types';\n\nimport {\n selectChat, selectNotifyExceptions, selectNotifySettings, selectUser,\n} from '../../modules/selectors';\nimport {\n getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isUserId, isUserRightBanned, selectIsChatMuted,\n} from '../../modules/helpers';\nimport renderText from './helpers/renderText';\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: string;\n forceShowSelf?: boolean;\n};\n\ntype StateProps =\n {\n user?: ApiUser;\n chat?: ApiChat;\n canInviteUsers?: boolean;\n isMuted?: boolean;\n phoneCodeList: ApiCountryCode[];\n }\n & Pick<GlobalState, 'lastSyncTime'>;\n\nconst ChatExtra: FC<OwnProps & StateProps> = ({\n lastSyncTime,\n user,\n chat,\n forceShowSelf,\n canInviteUsers,\n isMuted,\n phoneCodeList,\n}) => {\n const {\n loadFullUser,\n showNotification,\n updateChatMutedState,\n } = getDispatch();\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(phoneCodeList, phoneNumber);\n const link = getChatLink(chat);\n const description = (fullInfo?.bio) || getChatDescription(chat);\n\n return (\n <div className=\"ChatExtra\">\n {formattedNumber && Boolean(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 && Boolean(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\n icon={chat.username ? 'mention' : 'link'}\n multiline\n narrow\n ripple\n onClick={() => copy(link, lang('SetUrlPlaceholder'))}\n >\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, countryList: { phoneCodes: phoneCodeList } } = global;\n\n const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;\n const user = isUserId(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, phoneCodeList, chat, user, canInviteUsers, isMuted,\n };\n },\n)(ChatExtra));\n","import React, { FC, useCallback, memo } from '../../lib/teact/teact';\nimport { getDispatch, withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiChat } from '../../api/types';\n\nimport { selectIsChatWithSelf, selectUser } from '../../modules/selectors';\nimport {\n isUserId,\n isUserBot,\n getUserFirstOrLastName,\n getPrivateChatUserId,\n isChatBasicGroup,\n isChatSuperGroup,\n isChatChannel,\n getChatTitle,\n} from '../../modules/helpers';\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: string | undefined;\n canDeleteForAll?: boolean;\n contactName?: string;\n};\n\nconst DeleteChatModal: FC<OwnProps & StateProps> = ({\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}) => {\n const {\n leaveChannel,\n deleteHistory,\n deleteChannel,\n deleteChatUser,\n blockContact,\n } = getDispatch();\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 const handleLeaveChat = useCallback(() => {\n if (isChannel || isSuperGroup) {\n leaveChannel({ chatId: chat.id });\n onClose();\n } else {\n handleDeleteChat();\n }\n }, [chat.id, handleDeleteChat, isChannel, isSuperGroup, leaveChannel, onClose]);\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 {!isPrivateChat && chat.isCreator && (\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteChat}>\n {lang('DeleteForAll')}\n </Button>\n )}\n <Button\n color=\"danger\"\n className=\"confirm-dialog-button\"\n isText\n onClick={isPrivateChat ? handleDeleteChat : handleLeaveChat}\n >\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 = isUserId(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)(DeleteChatModal));\n","import React, {\n FC, useCallback, memo, useRef, useEffect, useState,\n} from '../../lib/teact/teact';\nimport { getDispatch } from '../../lib/teact/teactn';\n\nimport { 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 useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';\nimport useMedia from '../../hooks/useMedia';\nimport useFlag from '../../hooks/useFlag';\n\nimport File from './File';\n\ntype OwnProps = {\n message: ApiMessage;\n observeIntersection?: ObserveFn;\n smaller?: boolean;\n isSelected?: boolean;\n isSelectable?: boolean;\n canAutoLoad?: boolean;\n uploadProgress?: number;\n withDate?: boolean;\n datetime?: number;\n className?: string;\n sender?: string;\n autoLoadFileMaxSizeMb?: number;\n isDownloading: boolean;\n onCancelUpload?: () => void;\n onMediaClick?: () => void;\n onDateClick?: (messageId: number, chatId: string) => void;\n};\n\nconst BYTES_PER_MB = 1024 * 1024;\n\nconst Document: FC<OwnProps> = ({\n message,\n observeIntersection,\n smaller,\n canAutoLoad,\n autoLoadFileMaxSizeMb,\n uploadProgress,\n withDate,\n datetime,\n className,\n sender,\n isSelected,\n isSelectable,\n onCancelUpload,\n onMediaClick,\n onDateClick,\n isDownloading,\n}) => {\n const dispatch = getDispatch();\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 { fileName, size, timestamp } = document;\n const extension = getDocumentExtension(document) || '';\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n const [wasIntersected, markIntersected] = useFlag();\n useEffect(() => {\n if (isIntersecting) {\n markIntersected();\n }\n }, [isIntersecting, markIntersected]);\n\n // Auto-loading does not use global download manager because requires additional click to save files locally\n const [isLoadAllowed, setIsLoadAllowed] = useState(\n canAutoLoad && (!autoLoadFileMaxSizeMb || size <= autoLoadFileMaxSizeMb * BYTES_PER_MB),\n );\n\n const shouldDownload = Boolean(isDownloading || (isLoadAllowed && wasIntersected));\n\n const documentHash = getMessageMediaHash(message, 'download');\n const { loadProgress: downloadProgress, mediaData } = useMediaWithLoadProgress(\n documentHash, !shouldDownload, undefined, undefined, undefined, true,\n );\n const isLoaded = Boolean(mediaData);\n\n const {\n isUploading, isTransferring, transferProgress,\n } = getMediaTransferState(message, uploadProgress || downloadProgress, shouldDownload && !isLoaded);\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 withMediaViewer = onMediaClick && Boolean(document.mediaType);\n\n const handleClick = useCallback(() => {\n if (isUploading) {\n if (onCancelUpload) {\n onCancelUpload();\n }\n return;\n }\n\n if (isDownloading) {\n dispatch.cancelMessageMediaDownload({ message });\n return;\n }\n\n if (isTransferring) {\n setIsLoadAllowed(false);\n return;\n }\n\n if (withMediaViewer) {\n onMediaClick!();\n } else {\n dispatch.downloadMessageMedia({ message });\n }\n }, [\n isUploading, isDownloading, isTransferring, withMediaViewer, onCancelUpload, dispatch, message, onMediaClick,\n ]);\n\n const handleDateClick = useCallback(() => {\n onDateClick!(message.id, message.chatId);\n }, [onDateClick, message.id, message.chatId]);\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 React, { FC } from '../../lib/teact/teact';\n\nimport useLang from '../../hooks/useLang';\nimport buildClassName from '../../util/buildClassName';\n\nimport './DotAnimation.scss';\n\ntype OwnProps = {\n content: string;\n className?: string;\n};\n\nconst DotAnimation: FC<OwnProps> = ({ content, className }) => {\n const lang = useLang();\n return (\n <span className={buildClassName('DotAnimation', className)} dir={lang.isRtl ? 'rtl' : 'auto'}>\n {content}\n <span className=\"ellipsis\" />\n </span>\n );\n};\n\nexport default DotAnimation;\n","import { RefObject } from 'react';\nimport React, { FC, memo, useRef } from '../../lib/teact/teact';\n\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useMediaTransition from '../../hooks/useMediaTransition';\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 transitionClassNames = useMediaTransition(previewData);\n const {\n shouldRender: shouldSpinnerRender,\n transitionClassNames: spinnerClassNames,\n } = useShowTransition(isTransferring, undefined, true);\n\n const color = getColorFromExtension(extension);\n const sizeString = getFileSizeString(size);\n\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 <img\n src={thumbnailDataUri}\n width={width}\n height={height}\n className=\"thumbnail\"\n alt=\"\"\n />\n <img\n src={previewData}\n className={buildClassName('full-media', transitionClassNames)}\n width={width}\n height={height}\n alt=\"\"\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 <span className=\"bullet\" />\n <Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000, true)}</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 { getDispatch, withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiChat, ApiTypingStatus } from '../../api/types';\nimport { 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 useLang, { LangFn } from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\nimport VerifiedIcon from './VerifiedIcon';\nimport TypingStatus from './TypingStatus';\nimport DotAnimation from './DotAnimation';\n\ntype OwnProps = {\n chatId: string;\n typingStatus?: ApiTypingStatus;\n avatarSize?: 'small' | 'medium' | 'large' | 'jumbo';\n status?: string;\n withDots?: boolean;\n withMediaViewer?: boolean;\n withUsername?: boolean;\n withFullInfo?: boolean;\n withUpdatingStatus?: boolean;\n withChatType?: boolean;\n noRtl?: boolean;\n};\n\ntype StateProps =\n {\n chat?: ApiChat;\n onlineCount?: number;\n areMessagesLoaded: boolean;\n }\n & Pick<GlobalState, 'lastSyncTime'>;\n\nconst GroupChatInfo: FC<OwnProps & StateProps> = ({\n typingStatus,\n avatarSize = 'medium',\n status,\n withDots,\n withMediaViewer,\n withUsername,\n withFullInfo,\n withUpdatingStatus,\n withChatType,\n noRtl,\n chat,\n onlineCount,\n areMessagesLoaded,\n lastSyncTime,\n}) => {\n const {\n loadFullChat,\n openMediaViewer,\n } = getDispatch();\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 (status) {\n return withDots ? (\n <DotAnimation className=\"status\" content={status} />\n ) : (\n <span className=\"status\" dir=\"auto\">{status}</span>\n );\n }\n\n if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {\n return (\n <DotAnimation className=\"status\" content={lang('Updating')} />\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 <span className=\"status\" dir=\"auto\">{lang(getChatTypeString(chat))}</span>\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 <span 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 </span>\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)(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, useRef } from '../../lib/teact/teact';\n\nimport { ApiMessage } from '../../api/types';\n\nimport { formatMediaDuration } from '../../util/dateFormat';\nimport stopEvent from '../../util/stopEvent';\nimport {\n getMessageHtmlId,\n getMessageMediaHash,\n getMessageMediaThumbDataUri,\n getMessageVideo,\n} from '../../modules/helpers';\nimport buildClassName from '../../util/buildClassName';\nimport useMedia from '../../hooks/useMedia';\nimport useMediaTransition from '../../hooks/useMediaTransition';\nimport { ObserveFn, useIsIntersecting } from '../../hooks/useIntersectionObserver';\n\nimport './Media.scss';\n\ntype OwnProps = {\n message: ApiMessage;\n idPrefix?: string;\n isProtected?: boolean;\n observeIntersection?: ObserveFn;\n onClick?: (messageId: number, chatId: string) => void;\n};\n\nconst Media: FC<OwnProps> = ({\n message,\n idPrefix = 'shared-media',\n isProtected,\n observeIntersection,\n onClick,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n const thumbDataUri = getMessageMediaThumbDataUri(message);\n const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram'), !isIntersecting);\n const transitionClassNames = useMediaTransition(mediaBlobUrl);\n\n const video = getMessageVideo(message);\n\n const handleClick = useCallback(() => {\n onClick!(message.id, message.chatId);\n }, [message.id, message.chatId, onClick]);\n\n return (\n <div\n ref={ref}\n id={`${idPrefix}${getMessageHtmlId(message.id)}`}\n className=\"Media scroll-item\"\n onClick={onClick ? handleClick : undefined}\n >\n <img\n src={thumbDataUri}\n alt=\"\"\n draggable={!isProtected}\n decoding=\"async\"\n onContextMenu={isProtected ? stopEvent : undefined}\n />\n <img\n src={mediaBlobUrl}\n className={buildClassName('full-media', transitionClassNames)}\n alt=\"\"\n draggable={!isProtected}\n decoding=\"async\"\n onContextMenu={isProtected ? stopEvent : undefined}\n />\n {video && <span className=\"video-duration\">{video.isGif ? 'GIF' : formatMediaDuration(video.duration)}</span>}\n {isProtected && <span className=\"protector\" />}\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 <i className={`icon-message-${status}`} />\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 { isUserId } 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: string[];\n selectedIds: string[];\n filterValue?: string;\n filterPlaceholder?: string;\n notFoundText?: string;\n searchInputId?: string;\n isLoading?: boolean;\n noScrollRestore?: boolean;\n onSelectedIdsChange: (ids: string[]) => 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: string) => {\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?.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 {isUserId(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, isUserId } 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?: string;\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?.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 = isUserId(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 { getDispatch, withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiUser, ApiTypingStatus, ApiUserStatus } from '../../api/types';\nimport { GlobalState } from '../../global/types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport { selectChatMessages, selectUser, selectUserStatus } from '../../modules/selectors';\nimport { getUserFullName, getUserStatus, isUserOnline } from '../../modules/helpers';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\nimport VerifiedIcon from './VerifiedIcon';\nimport TypingStatus from './TypingStatus';\nimport DotAnimation from './DotAnimation';\n\ntype OwnProps = {\n userId: string;\n typingStatus?: ApiTypingStatus;\n avatarSize?: 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';\n forceShowSelf?: boolean;\n status?: string;\n withDots?: boolean;\n withMediaViewer?: boolean;\n withUsername?: boolean;\n withFullInfo?: boolean;\n withUpdatingStatus?: boolean;\n noStatusOrTyping?: boolean;\n noRtl?: boolean;\n};\n\ntype StateProps =\n {\n user?: ApiUser;\n userStatus?: ApiUserStatus;\n isSavedMessages?: boolean;\n areMessagesLoaded: boolean;\n serverTimeOffset: number;\n }\n & Pick<GlobalState, 'lastSyncTime'>;\n\nconst PrivateChatInfo: FC<OwnProps & StateProps> = ({\n typingStatus,\n avatarSize = 'medium',\n status,\n withDots,\n withMediaViewer,\n withUsername,\n withFullInfo,\n withUpdatingStatus,\n noStatusOrTyping,\n noRtl,\n user,\n userStatus,\n isSavedMessages,\n areMessagesLoaded,\n lastSyncTime,\n serverTimeOffset,\n}) => {\n const {\n loadFullUser,\n openMediaViewer,\n } = getDispatch();\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 withDots ? (\n <DotAnimation className=\"status\" content={status} />\n ) : (\n <span className=\"status\" dir=\"auto\">{status}</span>\n );\n }\n\n if (withUpdatingStatus && !areMessagesLoaded) {\n return (\n <DotAnimation className=\"status\" content={lang('Updating')} />\n );\n }\n\n if (!user) {\n return undefined;\n }\n\n if (typingStatus) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n return (\n <span className={`status ${isUserOnline(user, userStatus) ? 'online' : ''}`}>\n {withUsername && user.username && <span className=\"handle\">{user.username}</span>}\n <span className=\"user-status\" dir=\"auto\">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>\n </span>\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?.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 userStatus = selectUserStatus(global, userId);\n const isSavedMessages = !forceShowSelf && user && user.isSelf;\n const areMessagesLoaded = Boolean(selectChatMessages(global, userId));\n\n return {\n lastSyncTime, user, userStatus, isSavedMessages, areMessagesLoaded, serverTimeOffset,\n };\n },\n)(PrivateChatInfo));\n","import React, { FC, memo } from '../../lib/teact/teact';\n\nimport {\n ApiChat, ApiMediaFormat, ApiPhoto, ApiUser,\n} from '../../api/types';\n\nimport {\n getChatAvatarHash,\n getChatTitle,\n getUserColorKey,\n getUserFullName,\n isUserId,\n isChatWithRepliesBot,\n isDeletedUser,\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 const isRepliesChat = chat && isChatWithRepliesBot(chat.id);\n\n function getMediaHash(size: 'normal' | '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 && !isRepliesChat) {\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 photoBlobUrl = useMedia(getMediaHash('big'), false, ApiMediaFormat.BlobUrl, lastSyncTime);\n const avatarMediaHash = isFirstPhoto && !photoBlobUrl ? getMediaHash('normal', true) : undefined;\n const avatarBlobUrl = useMedia(avatarMediaHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);\n const thumbDataUri = useBlurSync(!photoBlobUrl && photo && photo.thumbnail && photo.thumbnail.dataUri);\n const imageSrc = photoBlobUrl || avatarBlobUrl || 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 (isRepliesChat) {\n content = <i className=\"icon-reply-filled\" />;\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, isUserId(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 isRepliesChat && 'replies-bot-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 { getDispatch, withGlobal } from '../../lib/teact/teactn';\n\nimport { ApiUser, ApiChat, ApiUserStatus } from '../../api/types';\nimport { GlobalState } from '../../global/types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport { IS_TOUCH_ENV } from '../../util/environment';\nimport { selectChat, selectUser, selectUserStatus } from '../../modules/selectors';\nimport {\n getUserFullName, getUserStatus, isChatChannel, isUserOnline,\n} from '../../modules/helpers';\nimport renderText from './helpers/renderText';\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: string;\n forceShowSelf?: boolean;\n};\n\ntype StateProps =\n {\n user?: ApiUser;\n userStatus?: ApiUserStatus;\n chat?: ApiChat;\n isSavedMessages?: boolean;\n animationLevel: 0 | 1 | 2;\n serverTimeOffset: number;\n }\n & Pick<GlobalState, 'connectionState'>;\n\nconst ProfileInfo: FC<OwnProps & StateProps> = ({\n forceShowSelf,\n user,\n userStatus,\n chat,\n isSavedMessages,\n connectionState,\n animationLevel,\n serverTimeOffset,\n}) => {\n const {\n loadFullUser,\n openMediaViewer,\n } = getDispatch();\n\n const lang = useLang();\n\n const { id: userId } = user || {};\n const { id: chatId } = chat || {};\n const fullName = user ? getUserFullName(user) : (chat ? chat.title : '');\n const photos = user?.photos || chat?.photos || [];\n const slideAnimation = animationLevel >= 1\n ? (lang.isRtl ? 'slide-optimized-rtl' : 'slide-optimized')\n : '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 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, userStatus) ? 'online' : ''}`}>\n <span className=\"user-status\" dir=\"auto\">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>\n </div>\n );\n }\n\n return (\n <span className=\"status\" dir=\"auto\">{\n isChatChannel(chat!)\n ? lang('Subscribers', chat!.membersCount ?? 0, 'i')\n : lang('Members', chat!.membersCount ?? 0, 'i')\n }\n </span>\n );\n }\n\n const isVerifiedIconShown = (user || 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 userStatus = selectUserStatus(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,\n user,\n userStatus,\n chat,\n isSavedMessages,\n animationLevel,\n serverTimeOffset,\n };\n },\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 { RefObject } from 'react';\nimport React, { FC, memo } from '../../lib/teact/teact';\nimport { getGlobal } from '../../lib/teact/teactn';\n\nimport { ApiMediaFormat } from '../../api/types';\n\nimport useMedia from '../../hooks/useMedia';\nimport buildClassName from '../../util/buildClassName';\n\nimport './ReactionStaticEmoji.scss';\n\ntype OwnProps = {\n reaction: string;\n ref?: RefObject<HTMLImageElement>;\n className?: string;\n};\n\nconst ReactionStaticEmoji: FC<OwnProps> = ({\n reaction,\n ref,\n className,\n}) => {\n const staticIconId = getGlobal().availableReactions?.find((l) => l.reaction === reaction)?.staticIcon?.id;\n const mediaData = useMedia(`document${staticIconId}`, !staticIconId, ApiMediaFormat.BlobUrl);\n\n return (\n <img\n className={buildClassName('ReactionStaticEmoji', className)}\n ref={ref}\n src={mediaData}\n alt=\"\"\n />\n );\n};\n\nexport default memo(ReactionStaticEmoji);\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 useShowTransition from '../../hooks/useShowTransition';\nimport useFlag from '../../hooks/useFlag';\nimport buildClassName from '../../util/buildClassName';\nimport { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';\nimport safePlay from '../../util/safePlay';\nimport { IS_WEBM_SUPPORTED } from '../../util/environment';\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.isLottie && localMediaHash, !shouldPlay, ApiMediaFormat.Lottie);\n const [isLottieLoaded, markLoaded, unmarkLoaded] = useFlag(Boolean(lottieData));\n const canLottiePlay = isLottieLoaded && shouldPlay;\n const isVideo = sticker.isVideo && IS_WEBM_SUPPORTED;\n const videoBlobUrl = useMedia(isVideo && localMediaHash, !shouldPlay, ApiMediaFormat.BlobUrl);\n const canVideoPlay = Boolean(isVideo && videoBlobUrl && shouldPlay);\n\n const { transitionClassNames: previewTransitionClassNames } = useShowTransition(\n Boolean(previewBlobUrl || canLottiePlay),\n undefined,\n undefined,\n 'slow',\n );\n\n // To avoid flickering\n useEffect(() => {\n if (!shouldPlay) {\n unmarkLoaded();\n }\n }, [unmarkLoaded, shouldPlay]);\n\n useEffect(() => {\n if (!isVideo || !ref.current) return;\n const video = ref.current.querySelector('video');\n if (!video) return;\n if (canVideoPlay) {\n safePlay(video);\n } else {\n video.pause();\n }\n }, [isVideo, canVideoPlay]);\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 onClick && 'interactive',\n stickerSelector,\n className,\n );\n\n const style = (thumbDataUri && !canLottiePlay && !canVideoPlay) ? `background-image: url('${thumbDataUri}');` : '';\n\n return (\n <div\n ref={ref}\n className={fullClassName}\n title={title || (sticker?.emoji)}\n style={style}\n data-sticker-id={sticker.id}\n onMouseDown={preventMessageInputBlurWithBubbling}\n onClick={handleClick}\n >\n {!canLottiePlay && !canVideoPlay && (\n // eslint-disable-next-line jsx-a11y/alt-text\n <img src={previewBlobUrl} className={previewTransitionClassNames} />\n )}\n {isVideo && (\n <video\n className={previewTransitionClassNames}\n src={videoBlobUrl}\n autoPlay={canVideoPlay}\n loop\n playsInline\n muted\n />\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 DotAnimation from './DotAnimation';\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 const content = lang(typingStatus.action)\n // Fix for translation \"{user} is typing\"\n .replace('{user}', '')\n .replace('{emoji}', typingStatus.emoji).trim();\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 <DotAnimation content={content} />\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';\nimport { ObserveFn } from '../../hooks/useIntersectionObserver';\n\nimport {\n getFirstLinkInMessage, getMessageText,\n getMessageWebPage,\n} 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';\nimport { renderMessageSummary, TextPart } from './helpers/renderMessageText';\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 isProtected?: boolean;\n observeIntersection?: ObserveFn;\n onMessageClick: (messageId: number, chatId: string) => void;\n};\n\ntype ApiWebPageWithFormatted =\n ApiWebPage\n & { formattedDescription?: TextPart[] };\n\nconst WebLink: FC<OwnProps> = ({\n message, senderTitle, isProtected, observeIntersection, onMessageClick,\n}) => {\n const lang = useLang();\n\n let linkData: ApiWebPageWithFormatted | undefined = getMessageWebPage(message);\n\n if (!linkData) {\n const link = getFirstLinkInMessage(message);\n if (link) {\n const { url, domain } = link;\n\n linkData = {\n siteName: domain.replace(/^www./, ''),\n url: url.includes('://') ? url : url.includes('@') ? `mailto:${url}` : `http://${url}`,\n formattedDescription: getMessageText(message) !== url\n ? renderMessageSummary(lang, message, undefined, undefined, MAX_TEXT_LENGTH)\n : undefined,\n } as ApiWebPageWithFormatted;\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 formattedDescription,\n photo,\n video,\n } = linkData;\n\n const truncatedDescription = !senderTitle && description && 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} isProtected={isProtected} observeIntersection={observeIntersection} />\n )}\n <div className=\"content\">\n <Link isRtl={lang.isRtl} className=\"site-title\" onClick={handleMessageClick}>\n {renderText(title || siteName || displayUrl)}\n </Link>\n {(truncatedDescription || formattedDescription) && (\n <Link isRtl={lang.isRtl} className=\"site-description\" onClick={handleMessageClick}>\n {formattedDescription || (truncatedDescription && 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, IS_TOUCH_ENV } 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_PX = 240;\nexport const GIF_MIN_WIDTH = 300;\nexport const AVATAR_FULL_DIMENSIONS = { width: 640, height: 640 };\nexport const LIKE_STICKER_ID = '4986041492570112461';\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 const mediaWidth = isGif ? Math.max(GIF_MIN_WIDTH, width) : width;\n const mediaHeight = isGif ? height * (mediaWidth / width) : height;\n\n return calculateDimensions(availableWidth, availableHeight, mediaWidth, mediaHeight);\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 && !IS_TOUCH_ENV) {\n occupiedHeightRem = mql.matches ? 10 : 12.5;\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 {\n useCallback, useEffect, useRef, useState,\n} from '../../../lib/teact/teact';\nimport safePlay from '../../../util/safePlay';\nimport { getDispatch } from '../../../lib/teact/teactn';\nimport useMedia from '../../../hooks/useMedia';\nimport { ActiveEmojiInteraction } from '../../../global/types';\nimport useFlag from '../../../hooks/useFlag';\nimport { selectLocalAnimatedEmojiEffectByName } from '../../../modules/selectors';\n\nconst WIDTH = {\n large: 160,\n medium: 128,\n small: 104,\n};\nconst INTERACTION_BUNCH_TIME = 1000;\nconst MS_DIVIDER = 1000;\nconst TIME_DEFAULT = 0;\n\nexport default function useAnimatedEmoji(\n size: 'large' | 'medium' | 'small',\n chatId?: string,\n messageId?: number,\n soundId?: string,\n activeEmojiInteractions?: ActiveEmojiInteraction[],\n isOwn?: boolean,\n localEffect?: string,\n emoji?: string,\n) {\n const {\n interactWithAnimatedEmoji, sendEmojiInteraction, sendWatchingEmojiInteraction,\n } = getDispatch();\n\n const hasEffect = localEffect || emoji;\n const [isAnimationLoaded, markAnimationLoaded] = useFlag();\n\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n // eslint-disable-next-line no-null/no-null\n const audioRef = useRef<HTMLAudioElement | undefined>(null);\n\n const soundMediaData = useMedia(soundId ? `document${soundId}` : undefined, !soundId);\n\n const width = WIDTH[size];\n const style = `width: ${width}px; height: ${width}px;`;\n\n const [playKey, setPlayKey] = useState(String(Math.random()));\n const interactions = useRef<number[] | undefined>(undefined);\n const startedInteractions = useRef<number | undefined>(undefined);\n const sendInteractionBunch = useCallback(() => {\n const container = ref.current;\n\n if (!container) return;\n\n sendEmojiInteraction({\n chatId,\n messageId,\n localEffect,\n emoji,\n interactions: interactions.current,\n });\n startedInteractions.current = undefined;\n interactions.current = undefined;\n }, [sendEmojiInteraction, chatId, messageId, localEffect, emoji]);\n\n const play = useCallback(() => {\n setPlayKey(String(Math.random()));\n\n const audio = audioRef.current;\n if (soundMediaData) {\n if (audio) {\n audio.pause();\n audio.remove();\n }\n audioRef.current = new Audio();\n audioRef.current.src = soundMediaData;\n safePlay(audioRef.current);\n audioRef.current.addEventListener('ended', () => {\n audioRef.current = undefined;\n }, { once: true });\n }\n }, [soundMediaData]);\n\n const handleClick = useCallback(() => {\n play();\n\n const container = ref.current;\n\n if (!hasEffect || !container || !messageId || !chatId) {\n return;\n }\n\n const { x, y } = container.getBoundingClientRect();\n\n interactWithAnimatedEmoji({\n localEffect,\n emoji,\n x,\n y,\n startSize: width,\n isReversed: !isOwn,\n });\n\n if (!interactions.current) {\n interactions.current = [];\n startedInteractions.current = performance.now();\n setTimeout(sendInteractionBunch, INTERACTION_BUNCH_TIME);\n }\n\n interactions.current.push(startedInteractions.current\n ? (performance.now() - startedInteractions.current) / MS_DIVIDER\n : TIME_DEFAULT);\n }, [\n chatId, emoji, hasEffect, interactWithAnimatedEmoji, isOwn,\n localEffect, messageId, play, sendInteractionBunch, width,\n ]);\n\n // Set an end anchor for remote activated interaction\n useEffect(() => {\n const container = ref.current;\n\n if (!container || !activeEmojiInteractions) return;\n\n activeEmojiInteractions.forEach(({\n id,\n startSize,\n messageId: interactionMessageId,\n }) => {\n if (startSize || messageId !== interactionMessageId) {\n return;\n }\n\n const { x, y } = container.getBoundingClientRect();\n\n sendWatchingEmojiInteraction({\n id,\n chatId,\n emoticon: localEffect ? selectLocalAnimatedEmojiEffectByName(localEffect) : emoji,\n startSize: width,\n x,\n y,\n isReversed: !isOwn,\n });\n play();\n });\n }, [\n activeEmojiInteractions, chatId, emoji, isOwn, localEffect, messageId, play, sendWatchingEmojiInteraction, width,\n ]);\n\n return {\n playKey,\n ref,\n style,\n width,\n handleClick,\n markAnimationLoaded,\n isAnimationLoaded,\n };\n}\n","import React, { FC, memo } from '../../lib/teact/teact';\nimport { Bundles } from '../../util/moduleLoader';\nimport { OwnProps } from './ChatFolderModal';\n\nimport useModuleLoader from '../../hooks/useModuleLoader';\n\nconst ChatFolderModalAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const ChatFolderModal = useModuleLoader(Bundles.Extra, 'ChatFolderModal', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return ChatFolderModal ? <ChatFolderModal {...props} /> : undefined;\n};\n\nexport default memo(ChatFolderModalAsync);\n","import { useMemo } from '../../../../lib/teact/teact';\n\nexport enum ChatAnimationTypes {\n Move,\n Opacity,\n None,\n}\n\nexport function useChatAnimationType(orderDiffById: Record<string, number>) {\n return useMemo(() => {\n const orderDiffs = Object.values(orderDiffById);\n const numberOfUp = orderDiffs.filter((diff) => diff < 0).length;\n const numberOfDown = orderDiffs.filter((diff) => diff > 0).length;\n\n return (chatId: string): ChatAnimationTypes => {\n const orderDiff = orderDiffById[chatId];\n if (orderDiff === 0) {\n return ChatAnimationTypes.None;\n }\n\n if (\n orderDiff === Infinity\n || orderDiff === -Infinity\n || (numberOfUp <= numberOfDown && orderDiff < 0)\n || (numberOfDown < numberOfUp && orderDiff > 0)\n ) {\n return ChatAnimationTypes.Opacity;\n }\n\n return ChatAnimationTypes.Move;\n };\n }, [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, { FC, memo } from '../../../lib/teact/teact';\nimport buildClassName from '../../../util/buildClassName';\n\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\n\nimport './ChatCallStatus.scss';\n\ntype OwnProps = {\n isSelected?: boolean;\n isActive?: boolean;\n};\n\nconst ChatCallStatus: FC<OwnProps> = ({\n isSelected,\n isActive,\n}) => {\n return (\n <div className={buildClassName(\n 'ChatCallStatus',\n isActive && 'active',\n isSelected && !IS_SINGLE_COLUMN_LAYOUT && 'selected',\n )}\n >\n <div className=\"indicator\">\n <div />\n <div />\n <div />\n </div>\n </div>\n );\n};\n\nexport default memo(ChatCallStatus);\n","import React, {\n FC, memo, useCallback, useLayoutEffect, useMemo, useRef,\n} from '../../../lib/teact/teact';\nimport { getDispatch, getGlobal, withGlobal } from '../../../lib/teact/teactn';\n\nimport useLang, { LangFn } from '../../../hooks/useLang';\n\nimport {\n ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus, ApiFormattedText, MAIN_THREAD_ID, ApiUserStatus,\n} from '../../../api/types';\n\nimport { ANIMATION_END_DELAY } from '../../../config';\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\nimport {\n getChatTitle,\n isUserId,\n isActionMessage,\n getPrivateChatUserId,\n getMessageAction,\n getMessageSenderName,\n isChatChannel,\n getMessageMediaHash,\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, selectUserStatus,\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 useEnsureMessage from '../../../hooks/useEnsureMessage';\nimport useChatContextActions from '../../../hooks/useChatContextActions';\nimport useFlag from '../../../hooks/useFlag';\nimport useMedia from '../../../hooks/useMedia';\nimport { ChatAnimationTypes } from './hooks';\nimport { renderMessageSummary } from '../../common/helpers/renderMessageText';\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';\nimport ChatFolderModal from '../ChatFolderModal.async';\nimport ChatCallStatus from './ChatCallStatus';\n\nimport './Chat.scss';\n\ntype OwnProps = {\n style?: string;\n chatId: string;\n folderId?: number;\n orderDiff: number;\n animationType: ChatAnimationTypes;\n isPinned?: boolean;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n isMuted?: boolean;\n user?: ApiUser;\n userStatus?: ApiUserStatus;\n actionTargetUserIds?: string[];\n actionTargetMessage?: ApiMessage;\n actionTargetChatId?: string;\n lastMessageSender?: ApiUser;\n lastMessageOutgoingStatus?: ApiMessageOutgoingStatus;\n draft?: ApiFormattedText;\n animationLevel?: number;\n isSelected?: boolean;\n canScrollDown?: boolean;\n canChangeFolder?: boolean;\n lastSyncTime?: number;\n};\n\nconst ANIMATION_DURATION = 200;\n\nconst Chat: FC<OwnProps & StateProps> = ({\n style,\n chatId,\n folderId,\n orderDiff,\n animationType,\n isPinned,\n chat,\n isMuted,\n user,\n userStatus,\n actionTargetUserIds,\n lastMessageSender,\n lastMessageOutgoingStatus,\n actionTargetMessage,\n actionTargetChatId,\n draft,\n animationLevel,\n isSelected,\n canScrollDown,\n canChangeFolder,\n lastSyncTime,\n}) => {\n const {\n openChat,\n focusLastMessage,\n } = getDispatch();\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 [isChatFolderModalOpen, openChatFolderModal, closeChatFolderModal] = useFlag();\n const [shouldRenderDeleteModal, markRenderDeleteModal, unmarkRenderDeleteModal] = useFlag();\n const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = 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 if (!actionTargetUserIds) {\n return undefined;\n }\n\n // No need for expensive global updates on users, so we avoid them\n const usersById = getGlobal().users.byId;\n return actionTargetUserIds.map((userId) => usersById[userId]).filter<ApiUser>(Boolean as any);\n }, [actionTargetUserIds]);\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 function handleChatFolderChange() {\n markRenderChatFolderModal();\n openChatFolderModal();\n }\n\n const contextActions = useChatContextActions({\n chat,\n user,\n handleDelete,\n handleChatFolderChange,\n folderId,\n isPinned,\n isMuted,\n canChangeFolder,\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?.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 isChat = chat && (isChatChannel(chat) || lastMessage.senderId === lastMessage.chatId);\n\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n {renderActionMessageText(\n lang,\n lastMessage,\n !isChat ? lastMessageSender : undefined,\n isChat ? chat : undefined,\n actionTargetUsers,\n actionTargetMessage,\n actionTargetChatId,\n { asTextWithSpoilers: true },\n )}\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 {renderSummary(lang, lastMessage!, mediaBlobUrl || mediaThumbnail, isRoundVideo)}\n </p>\n );\n }\n\n const className = buildClassName(\n 'Chat chat-item-clickable',\n isUserId(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={user}\n userStatus={userStatus}\n isSavedMessages={user?.isSelf}\n lastSyncTime={lastSyncTime}\n />\n {chat.isCallActive && chat.isCallNotEmpty && (\n <ChatCallStatus isSelected={isSelected} isActive={animationLevel !== 0} />\n )}\n </div>\n <div className=\"info\">\n <div className=\"title\">\n <h3>{renderText(getChatTitle(lang, chat, user))}</h3>\n {chat.isVerified && <VerifiedIcon />}\n {isMuted && <i className=\"icon-muted\" />}\n {chat.lastMessage && (\n <LastMessageMeta\n message={chat.lastMessage}\n outgoingStatus={lastMessageOutgoingStatus}\n />\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 {shouldRenderChatFolderModal && (\n <ChatFolderModal\n isOpen={isChatFolderModalOpen}\n onClose={closeChatFolderModal}\n onCloseAnimationEnd={unmarkRenderChatFolderModal}\n chatId={chatId}\n />\n )}\n </ListItem>\n );\n};\n\nfunction renderSummary(lang: LangFn, message: ApiMessage, blobUrl?: string, isRoundVideo?: boolean) {\n if (!blobUrl) {\n return renderMessageSummary(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 {renderMessageSummary(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 {\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 canChangeFolder: Boolean(global.chatFolders.orderedIds?.length),\n lastSyncTime: global.lastSyncTime,\n ...(isOutgoing && { lastMessageOutgoingStatus: selectOutgoingStatus(global, chat.lastMessage) }),\n ...(privateChatUserId && {\n user: selectUser(global, privateChatUserId),\n userStatus: selectUserStatus(global, privateChatUserId),\n }),\n };\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, useEffect,\n} from '../../../lib/teact/teact';\nimport { getDispatch } from '../../../lib/teact/teactn';\n\nimport { SettingsScreens } from '../../../types';\nimport { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';\n\nimport {\n ALL_FOLDER_ID,\n ARCHIVED_FOLDER_ID,\n CHAT_HEIGHT_PX,\n CHAT_LIST_SLICE,\n} from '../../../config';\nimport { IS_MAC_OS, IS_PWA } from '../../../util/environment';\nimport { mapValues } from '../../../util/iteratees';\nimport { getPinnedChatsCount } from '../../../util/folderManager';\nimport usePrevious from '../../../hooks/usePrevious';\nimport useInfiniteScroll from '../../../hooks/useInfiniteScroll';\nimport { useFolderManagerForOrderedIds } from '../../../hooks/useFolderManager';\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 lastSyncTime?: number;\n foldersDispatch?: FolderEditDispatch;\n onScreenSelect?: (screen: SettingsScreens) => void;\n};\n\nconst ChatList: FC<OwnProps> = ({\n folderType,\n folderId,\n isActive,\n foldersDispatch,\n onScreenSelect,\n}) => {\n const { openChat, openNextChat } = getDispatch();\n\n const resolvedFolderId = (\n folderType === 'all' ? ALL_FOLDER_ID : folderType === 'archived' ? ARCHIVED_FOLDER_ID : folderId!\n );\n\n const orderedIds = useFolderManagerForOrderedIds(resolvedFolderId);\n\n const orderById = useMemo(() => {\n if (!orderedIds) {\n return undefined;\n }\n\n return orderedIds.reduce((acc, id, i) => {\n acc[id] = i;\n return acc;\n }, {} as Record<string, number>);\n }, [orderedIds]);\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 prevOrderById[id] !== undefined ? order - prevOrderById[id] : -Infinity;\n });\n }, [orderById, prevOrderById]);\n\n const [viewportIds, getMore] = useInfiniteScroll(undefined, orderedIds, undefined, CHAT_LIST_SLICE);\n\n // Support <Cmd>+<Digit> and <Alt>+<Up/Down> to navigate between chats\n useEffect(() => {\n if (!isActive || !orderedIds) {\n return undefined;\n }\n\n function handleKeyDown(e: KeyboardEvent) {\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 document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [isActive, openChat, openNextChat, orderedIds]);\n\n const getAnimationType = useChatAnimationType(orderDiffById);\n\n function renderChats() {\n const viewportOffset = orderedIds!.indexOf(viewportIds![0]);\n const pinnedCount = getPinnedChatsCount(resolvedFolderId) || 0;\n\n return viewportIds!.map((id, i) => (\n <Chat\n key={id}\n teactOrderKey={i}\n chatId={id}\n isPinned={viewportOffset + i < pinnedCount}\n folderId={folderId}\n animationType={getAnimationType(id)}\n orderDiff={orderDiffById[id]}\n style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}\n />\n ));\n }\n\n return (\n <InfiniteScroll\n className=\"chat-list custom-scroll\"\n items={viewportIds}\n preloadBackwards={CHAT_LIST_SLICE}\n withAbsolutePositioning\n maxHeight={(orderedIds?.length || 0) * CHAT_HEIGHT_PX}\n onLoadMore={getMore}\n >\n {viewportIds?.length ? (\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(ChatList);\n","import { ApiChat, ApiMessage, ApiUser } from '../../../../api/types';\nimport {\n getChatTitle,\n getSenderTitle,\n isUserId,\n isChatGroup,\n} from '../../../../modules/helpers';\nimport { LangFn } from '../../../../hooks/useLang';\n\nexport function getSenderName(\n lang: LangFn, message: ApiMessage, chatsById: Record<string, ApiChat>, usersById: Record<string, ApiUser>,\n) {\n const { senderId } = message;\n if (!senderId) {\n return undefined;\n }\n\n const sender = isUserId(senderId) ? usersById[senderId] : chatsById[senderId];\n\n let senderName = getSenderTitle(lang, sender);\n\n const chat = chatsById[message.chatId];\n if (chat) {\n if (isUserId(senderId) && (sender as ApiUser).isSelf) {\n senderName = `${lang('FromYou')} → ${getChatTitle(lang, chat)}`;\n } else if (isChatGroup(chat)) {\n senderName += ` → ${getChatTitle(lang, chat)}`;\n }\n }\n\n return senderName;\n}\n","import React, { FC, memo } from '../../../lib/teact/teact';\nimport { OwnProps } from './CustomSendMenu';\nimport { Bundles } from '../../../util/moduleLoader';\n\nimport useModuleLoader from '../../../hooks/useModuleLoader';\n\nconst CustomSendMenuAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const CustomSend = useModuleLoader(Bundles.Extra, 'CustomSendMenu', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return CustomSend ? <CustomSend {...props} /> : undefined;\n};\n\nexport default memo(CustomSendMenuAsync);\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';\nimport getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems';\n\nimport captureEscKeyListener from '../../../util/captureEscKeyListener';\nimport usePrevious from '../../../hooks/usePrevious';\n\nimport Portal from '../../ui/Portal';\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(async (e: React.DragEvent<HTMLDivElement>) => {\n const { dataTransfer: dt } = e;\n let files: File[] = [];\n\n if (dt.files && dt.files.length > 0 && (!dt.items || !dt.items.length)) {\n files = files.concat(Array.from(dt.files));\n } else if (dt.items && dt.items.length > 0) {\n const folderFiles = await getFilesFromDataTransferItems(dt.items);\n if (folderFiles.length) {\n files = files.concat(folderFiles);\n }\n }\n\n onHide();\n onFileSelect(files, false);\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 <Portal containerId=\"#middle-column-portals\">\n <div className={className} onDragLeave={handleDragLeave} onDragOver={handleDragOver} onDrop={onHide}>\n <DropTarget onFileSelect={handleFilesDrop} />\n {(withQuick || prevWithQuick) && <DropTarget onFileSelect={handleQuickFilesDrop} isQuick />}\n </div>\n </Portal>\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 { getDispatch, withGlobal } from '../../../lib/teact/teactn';\n\nimport { IAnchorPosition, ISettings } from '../../../types';\n\nimport { EDITABLE_INPUT_ID } from '../../../config';\nimport { selectReplyingToId } from '../../../modules/selectors';\nimport { debounce } from '../../../util/schedulers';\nimport focusEditableElement from '../../../util/focusEditableElement';\nimport buildClassName from '../../../util/buildClassName';\nimport {\n IS_ANDROID, IS_EMOJI_SUPPORTED, 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 { isHeavyAnimating } from '../../../hooks/useHeavyAnimationCheck';\nimport useSendMessageAction from '../../../hooks/useSendMessageAction';\nimport useLang from '../../../hooks/useLang';\nimport parseEmojiOnlyString from '../../common/helpers/parseEmojiOnlyString';\nimport { isSelectionInsideInput } from './helpers/selection';\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 chatId: string;\n threadId: number;\n isAttachmentModalInput?: boolean;\n editableInputId?: string;\n html: string;\n placeholder: string;\n forcedPlaceholder?: string;\n canAutoFocus: boolean;\n shouldSuppressFocus?: boolean;\n shouldSuppressTextFormatter?: boolean;\n onUpdate: (html: string) => void;\n onSuppressedFocus?: () => void;\n onSend: () => void;\n};\n\ntype StateProps = {\n replyingToId?: number;\n noTabCapture?: boolean;\n messageSendKeyCombo?: ISettings['messageSendKeyCombo'];\n};\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> = ({\n id,\n chatId,\n threadId,\n isAttachmentModalInput,\n editableInputId,\n html,\n placeholder,\n forcedPlaceholder,\n canAutoFocus,\n shouldSuppressFocus,\n shouldSuppressTextFormatter,\n replyingToId,\n noTabCapture,\n messageSendKeyCombo,\n onUpdate,\n onSuppressedFocus,\n onSend,\n}) => {\n const {\n editLastMessage,\n replyToNextMessage,\n } = getDispatch();\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 const sendMessageAction = useSendMessageAction(chatId, threadId);\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 chatIdRef = useRef(chatId);\n chatIdRef.current = chatId;\n const focusInput = useCallback(() => {\n if (!inputRef.current) {\n return;\n }\n\n if (isHeavyAnimating()) {\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 false;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount || isContextMenuOpenRef.current) {\n closeTextFormatter();\n return false;\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 false;\n }\n\n return true;\n }\n\n function processSelection() {\n if (!checkSelection()) {\n return;\n }\n\n const selectionRange = window.getSelection()!.getRangeAt(0);\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 processSelection();\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 processSelection();\n\n e.target.removeEventListener('keyup', handleKeyUp);\n }\n\n if (!html.length && (e.metaKey || e.ctrlKey)) {\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.ctrlKey && !e.altKey) {\n e.preventDefault();\n editLastMessage();\n } else {\n e.target.addEventListener('keyup', handleKeyUp);\n }\n }\n\n function handleChange(e: ChangeEvent<HTMLDivElement>) {\n const { innerHTML, textContent } = e.currentTarget;\n\n onUpdate(innerHTML === SAFARI_BR ? '' : innerHTML);\n sendMessageAction({ type: 'typing' });\n\n // Reset focus on the input to remove any active styling when input is cleared\n if (\n !IS_TOUCH_ENV\n && (!textContent || !textContent.length)\n // When emojis are not supported, innerHTML contains an emoji img tag that doesn't exist in the textContext\n && !(!IS_EMOJI_SUPPORTED && innerHTML.includes('emoji-small'))\n ) {\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 (!checkSelection()) {\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 (canAutoFocus) {\n focusInput();\n }\n }, [chatId, focusInput, replyingToId, canAutoFocus]);\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={IS_ANDROID ? stopEvent : undefined}\n onTouchCancel={IS_ANDROID ? processSelection : undefined}\n aria-label={placeholder}\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 setSelectedRange={setSelectedRange}\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, { chatId, threadId }: OwnProps): StateProps => {\n const { messageSendKeyCombo } = global.settings.byKey;\n\n return {\n messageSendKeyCombo,\n replyingToId: chatId && threadId ? selectReplyingToId(global, chatId, threadId) : undefined,\n noTabCapture: global.isPollModalOpen || global.payment.isPaymentModalOpen,\n };\n },\n)(MessageInput));\n","import React, {\n FC, memo, useCallback, useEffect, useRef, useState,\n} from '../../../lib/teact/teact';\n\nimport { IAnchorPosition } from '../../../types';\nimport { ApiMessageEntityTypes } from '../../../api/types';\n\nimport { EDITABLE_INPUT_ID } from '../../../config';\nimport buildClassName from '../../../util/buildClassName';\nimport { ensureProtocol } from '../../../util/ensureProtocol';\nimport captureEscKeyListener from '../../../util/captureEscKeyListener';\nimport getKeyFromEvent from '../../../util/getKeyFromEvent';\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 setSelectedRange: (range: Range) => void;\n onClose: () => void;\n};\n\ninterface ISelectedTextFormats {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n monospace?: boolean;\n spoiler?: 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 SPAN: 'spoiler',\n};\nconst fragmentEl = document.createElement('div');\n\nconst TextFormatter: FC<OwnProps> = ({\n isOpen,\n anchorPosition,\n selectedRange,\n setSelectedRange,\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 updateSelectedRange = useCallback(() => {\n const selection = window.getSelection();\n if (selection) {\n setSelectedRange(selection.getRangeAt(0));\n }\n }, [setSelectedRange]);\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 && Boolean(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 handleSpoilerText = useCallback(() => {\n if (selectedTextFormats.spoiler) {\n const element = getSelectedElement();\n if (\n !selectedRange\n || !element\n || element.dataset.entityType !== ApiMessageEntityTypes.Spoiler\n || !element.textContent\n ) {\n return;\n }\n\n element.replaceWith(element.textContent);\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n spoiler: false,\n }));\n\n return;\n }\n\n const text = getSelectedText();\n document.execCommand(\n 'insertHTML', false, `<span class=\"spoiler\" data-entity-type=\"${ApiMessageEntityTypes.Spoiler}\">${text}</span>`,\n );\n onClose();\n }, [getSelectedElement, getSelectedText, onClose, selectedRange, selectedTextFormats.spoiler]);\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') && Boolean(selectedFormats[key])) {\n document.execCommand(key);\n }\n });\n\n updateSelectedRange();\n return {\n ...selectedFormats,\n bold: !selectedFormats.bold,\n };\n });\n }, [updateSelectedRange]);\n\n const handleItalicText = useCallback(() => {\n document.execCommand('italic');\n updateSelectedRange();\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n italic: !selectedFormats.italic,\n }));\n }, [updateSelectedRange]);\n\n const handleUnderlineText = useCallback(() => {\n document.execCommand('underline');\n updateSelectedRange();\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n underline: !selectedFormats.underline,\n }));\n }, [updateSelectedRange]);\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, 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\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, selectedRange, selectedTextFormats.monospace,\n ]);\n\n function handleLinkUrlConfirm() {\n const formattedLinkUrl = encodeURI(ensureProtocol(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\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: Record<string, AnyToVoidFunction> = {\n k: openLinkControl,\n b: handleBoldText,\n u: handleUnderlineText,\n i: handleItalicText,\n m: handleMonospaceText,\n s: handleStrikethroughText,\n p: handleSpoilerText,\n };\n\n const handler = HANDLERS_BY_KEY[getKeyFromEvent(e)];\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 openLinkControl, handleBoldText, handleUnderlineText, handleItalicText, handleMonospaceText,\n handleStrikethroughText, handleSpoilerText,\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 Boolean(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 style={style}\n onKeyDown={handleContainerKeyDown}\n >\n <div className=\"TextFormatter-buttons\">\n <Button\n color=\"translucent\"\n ariaLabel=\"Spoiler text\"\n className={getFormatButtonClassName('spoiler')}\n onClick={handleSpoilerText}\n >\n <i className=\"icon-eye-closed\" />\n </Button>\n <div className=\"TextFormatter-divider\" />\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","export default async function getFilesFromDataTransferItems(dataTransferItems: DataTransferItemList) {\n const files: File[] = [];\n\n function traverseFileTreePromise(entry: FileSystemEntry | File, item: DataTransferItem) {\n return new Promise(resolve => {\n if (entry instanceof File) {\n files.push(entry);\n resolve(entry);\n } else if (entry.isFile) {\n const itemFile = item.getAsFile();\n (entry as FileSystemFileEntry).file((file) => {\n files.push(file);\n resolve(file);\n }, () => {\n // iOS Safari throws an error \"NotFoundError: Path does not exist\" for files from the clipboard\n // https://stackoverflow.com/a/50059309\n if (itemFile) {\n files.push(itemFile);\n }\n resolve(itemFile);\n });\n } else if (entry.isDirectory) {\n let dirReader = (entry as FileSystemDirectoryEntry).createReader();\n dirReader.readEntries((entries) => {\n let entriesPromises = [];\n for (let entr of entries) {\n entriesPromises.push(traverseFileTreePromise(entr, item));\n }\n resolve(Promise.all(entriesPromises));\n });\n }\n });\n }\n\n let entriesPromises = [];\n for (let item of dataTransferItems) {\n if (item.kind === 'file') {\n const entry = item.webkitGetAsEntry() || item.getAsFile();\n if (entry) {\n entriesPromises.push(traverseFileTreePromise(entry, item));\n }\n }\n }\n\n await Promise.all(entriesPromises);\n\n return files;\n}\n\n","const RE_BR = /(<br>|<br\\s?\\/>)/g;\nconst RE_SPACE = /(&nbsp;|\\u00A0)/g;\nconst RE_CLEAN_HTML = /(<div>|<\\/div>)/gi;\nconst RE_EXTRA_NEW_LINE = /\\n$/i;\n\nexport function prepareForRegExp(html: string) {\n return html\n .replace(RE_SPACE, ' ')\n .replace(RE_BR, '\\n')\n .replace(RE_CLEAN_HTML, '')\n .replace(RE_EXTRA_NEW_LINE, '');\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 { areSortedArraysEqual } from './iteratees';\n\nconst cache = new WeakMap<AnyFunction, {\n lastArgs: any[];\n lastResult: any;\n}>();\n\nexport default function memoized<T extends AnyFunction>(fn: T) {\n return (...args: Parameters<T>): ReturnType<T> => {\n const cached = cache.get(fn);\n if (cached && areSortedArraysEqual(cached.lastArgs, args)) {\n return cached.lastResult;\n }\n\n const result = fn(...args);\n cache.set(fn, { lastArgs: args, lastResult: result });\n return result;\n };\n}\n","import {\n useCallback, useEffect, useState,\n} from '../../../../lib/teact/teact';\n\nimport { EDITABLE_INPUT_ID } from '../../../../config';\nimport { MEMO_EMPTY_ARRAY } from '../../../../util/memo';\nimport { prepareForRegExp } from '../helpers/prepareForRegExp';\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 memoized from '../../../../util/memoized';\nimport useFlag from '../../../../hooks/useFlag';\nimport renderText from '../../../common/helpers/renderText';\n\ninterface Library {\n keywords: string[];\n byKeyword: Record<string, Emoji[]>;\n names: string[];\n byName: Record<string, Emoji[]>;\n}\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;\n\nconst prepareRecentEmojisMemo = memoized(prepareRecentEmojis);\nconst prepareLibraryMemo = memoized(prepareLibrary);\nconst searchInLibraryMemo = memoized(searchInLibrary);\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 htmlRef: { current: 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 const [byId, setById] = useState<Record<string, Emoji> | undefined>();\n const [shouldForceInsertEmoji, setShouldForceInsertEmoji] = useState(false);\n const [filteredEmojis, setFilteredEmojis] = useState<Emoji[]>(MEMO_EMPTY_ARRAY);\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 const html = htmlRef.current;\n useEffect(() => {\n if (!isAllowed || !html || !byId || isDisabled) {\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[] = MEMO_EMPTY_ARRAY;\n\n setShouldForceInsertEmoji(forceSend);\n\n if (!filter) {\n matched = prepareRecentEmojisMemo(byId, recentEmojiIds, EMOJIS_LIMIT);\n } else if (filter.length >= FILTER_MIN_LENGTH) {\n const library = prepareLibraryMemo(byId, baseEmojiKeywords, emojiKeywords);\n matched = searchInLibraryMemo(library, filter, EMOJIS_LIMIT);\n }\n\n if (matched.length) {\n if (!forceSend) {\n markIsOpen();\n }\n setFilteredEmojis(matched);\n } else {\n unmarkIsOpen();\n }\n }, [\n byId, html, isAllowed, markIsOpen, recentEmojiIds, unmarkIsOpen, setShouldForceInsertEmoji,\n isDisabled, baseEmojiKeywords, emojiKeywords,\n ]);\n\n const insertEmoji = useCallback((textEmoji: string, isForce?: boolean) => {\n const currentHtml = htmlRef.current;\n const atIndex = currentHtml.lastIndexOf(':', isForce ? currentHtml.lastIndexOf(':') - 1 : undefined);\n if (atIndex !== -1) {\n onUpdateHtml(`${currentHtml.substr(0, atIndex)}${renderText(textEmoji, ['emoji_html'])}`);\n const messageInput = document.getElementById(inputId)!;\n requestAnimationFrame(() => {\n focusEditableElement(messageInput, true, true);\n });\n }\n\n unmarkIsOpen();\n }, [htmlRef, 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 = prepareForRegExp(html).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\nfunction prepareRecentEmojis(byId: Record<string, Emoji>, recentEmojiIds: string[], limit: number) {\n if (!byId || !recentEmojiIds.length) {\n return MEMO_EMPTY_ARRAY;\n }\n\n return Object.values(pickTruthy(byId, recentEmojiIds)).slice(0, limit);\n}\n\nfunction prepareLibrary(\n byId: Record<string, Emoji>,\n baseEmojiKeywords?: Record<string, string[]>,\n emojiKeywords?: Record<string, string[]>,\n): Library {\n const emojis = Object.values(byId);\n\n const byNative = buildCollectionByKey<Emoji>(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 const byKeyword = { ...baseEmojisByKeyword, ...emojisByKeyword };\n const keywords = ([] as string[]).concat(Object.keys(baseEmojisByKeyword), Object.keys(emojisByKeyword));\n\n const byName = 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\n const names = Object.keys(byName);\n\n return {\n byKeyword,\n keywords,\n byName,\n names,\n };\n}\n\nfunction searchInLibrary(library: Library, filter: string, limit: number) {\n const {\n byKeyword, keywords, byName, names,\n } = library;\n\n let matched: Emoji[] = MEMO_EMPTY_ARRAY;\n\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 return matched.slice(0, limit);\n}\n","import {\n useCallback, useEffect, useState,\n} from '../../../../lib/teact/teact';\nimport { getGlobal } from '../../../../lib/teact/teactn';\n\nimport { ApiMessageEntityTypes, ApiChatMember, ApiUser } from '../../../../api/types';\nimport { EDITABLE_INPUT_ID } from '../../../../config';\nimport { filterUsersByName, getUserFirstOrLastName } from '../../../../modules/helpers';\nimport { prepareForRegExp } from '../helpers/prepareForRegExp';\nimport focusEditableElement from '../../../../util/focusEditableElement';\nimport useFlag from '../../../../hooks/useFlag';\nimport { pickTruthy, unique } from '../../../../util/iteratees';\nimport { throttle } from '../../../../util/schedulers';\n\nconst runThrottled = throttle((cb) => cb(), 500, true);\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 htmlRef: { current: string },\n onUpdateHtml: (html: string) => void,\n inputId: string = EDITABLE_INPUT_ID,\n groupChatMembers?: ApiChatMember[],\n topInlineBotIds?: string[],\n currentUserId?: string,\n) {\n const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();\n const [usersToMention, setUsersToMention] = useState<ApiUser[] | undefined>();\n\n const updateFilteredUsers = useCallback((filter, withInlineBots: boolean) => {\n // No need for expensive global updates on users, so we avoid them\n const usersById = getGlobal().users.byId;\n\n if (!(groupChatMembers || topInlineBotIds) || !usersById) {\n setUsersToMention(undefined);\n\n return;\n }\n\n runThrottled(() => {\n const memberIds = groupChatMembers?.reduce((acc: string[], member) => {\n if (member.userId !== currentUserId) {\n acc.push(member.userId);\n }\n\n return acc;\n }, []);\n\n const filteredIds = filterUsersByName(unique([\n ...((withInlineBots && topInlineBotIds) || []),\n ...(memberIds || []),\n ]), usersById, filter);\n\n setUsersToMention(Object.values(pickTruthy(usersById, filteredIds)));\n });\n }, [currentUserId, groupChatMembers, topInlineBotIds]);\n\n const html = htmlRef.current;\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 updateFilteredUsers(filter, canSuggestInlineBots(html));\n } else {\n unmarkIsOpen();\n }\n }, [canSuggestMembers, updateFilteredUsers, markIsOpen, unmarkIsOpen, html]);\n\n useEffect(() => {\n if (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 currentHtml = htmlRef.current;\n const atIndex = currentHtml.lastIndexOf('@');\n if (atIndex !== -1) {\n onUpdateHtml(`${currentHtml.substr(0, atIndex)}${insertedHtml}&nbsp;`);\n const messageInput = document.getElementById(inputId)!;\n requestAnimationFrame(() => {\n focusEditableElement(messageInput, forceFocus);\n });\n }\n\n unmarkIsOpen();\n }, [htmlRef, 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 = prepareForRegExp(html).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 { ChangeEvent } from 'react';\nimport React, {\n FC, useCallback, memo, useState,\n} from '../../lib/teact/teact';\n\nimport Checkbox from './Checkbox';\n\ntype IRadioOption = {\n label: string;\n subLabel?: string;\n value: string;\n};\n\ntype OwnProps = {\n id?: string;\n options: IRadioOption[];\n selected?: string[];\n disabled?: boolean;\n round?: boolean;\n loadingOptions?: string[];\n onChange: (value: string[]) => void;\n};\n\nconst CheckboxGroup: FC<OwnProps> = ({\n id,\n options,\n selected = [],\n disabled,\n round,\n loadingOptions,\n onChange,\n}) => {\n const [values, setValues] = useState<string[]>(selected || []);\n\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n const { value, checked } = event.currentTarget;\n let newValues: string[];\n if (checked) {\n newValues = [...values, value];\n } else {\n newValues = values.filter((v) => v !== value);\n }\n\n setValues(newValues);\n onChange(newValues);\n }, [onChange, values]);\n\n return (\n <div id={id} className=\"radio-group\">\n {options.map((option) => (\n <Checkbox\n label={option.label}\n subLabel={option.subLabel}\n value={option.value}\n checked={selected.indexOf(option.value) !== -1}\n disabled={disabled}\n round={round}\n isLoading={loadingOptions ? loadingOptions.indexOf(option.value) !== -1 : undefined}\n onChange={handleChange}\n />\n ))}\n </div>\n );\n};\n\nexport default memo(CheckboxGroup);\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: React.ReactNode;\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 } 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';\nimport Button from './Button';\n\nimport './ListItem.scss';\n\ninterface MenuItemContextAction {\n title: string;\n icon: string;\n destructive?: boolean;\n handler?: () => void;\n}\n\ninterface OwnProps {\n ref?: RefObject<HTMLDivElement>;\n buttonRef?: RefObject<HTMLDivElement>;\n icon?: string;\n secondaryIcon?: string;\n className?: string;\n style?: string;\n children: React.ReactNode;\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 onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onSecondaryIconClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nconst ListItem: FC<OwnProps> = ({\n ref,\n buttonRef,\n icon,\n secondaryIcon,\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 onMouseDown,\n onClick,\n onSecondaryIconClick,\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 {\n positionX, positionY, transformOriginX, transformOriginY, style: menuStyle,\n } = 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 handleSecondaryIconClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (disabled || e.button !== 0 || (!onSecondaryIconClick && !contextActions)) return;\n e.stopPropagation();\n if (onSecondaryIconClick) {\n onSecondaryIconClick(e);\n } else {\n handleContextMenu(e);\n }\n };\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 style={style}\n onMouseDown={onMouseDown}\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 {secondaryIcon && (\n <Button\n className=\"secondary-icon\"\n round\n color=\"translucent\"\n size=\"smaller\"\n onClick={IS_TOUCH_ENV ? handleSecondaryIconClick : undefined}\n onMouseDown={!IS_TOUCH_ENV ? handleSecondaryIconClick : undefined}\n >\n <i className={`icon-${secondaryIcon}`} />\n </Button>\n )}\n </div>\n {contextActions && contextMenuPosition !== undefined && (\n <Menu\n isOpen={isContextMenuOpen}\n transformOriginX={transformOriginX}\n transformOriginY={transformOriginY}\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,\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 buildClassName from '../../util/buildClassName';\nimport captureEscKeyListener from '../../util/captureEscKeyListener';\nimport { TextPart } from '../common/helpers/renderMessageText';\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 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\nexport type 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 { ChangeEvent } from 'react';\nimport React, {\n FC, useCallback, useMemo, memo,\n} from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport './RangeSlider.scss';\n\ntype OwnProps = {\n options?: string[];\n min?: number;\n max?: number;\n step?: number;\n label?: string;\n value: number;\n renderValue?: (value: number) => string;\n disabled?: boolean;\n onChange: (value: number) => void;\n};\n\nconst RangeSlider: FC<OwnProps> = ({\n options,\n min = 0,\n max = options ? options.length - 1 : 100,\n step = 1,\n label,\n value,\n renderValue,\n disabled,\n onChange,\n}) => {\n const lang = useLang();\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n onChange(Number(event.currentTarget.value));\n }, [onChange]);\n\n const className = buildClassName(\n 'RangeSlider',\n disabled && 'disabled',\n );\n\n const trackWidth = useMemo(() => {\n if (options) {\n return (value / (options.length - 1)) * 100;\n } else {\n const possibleValuesLength = (max - min) / step;\n return ((value - min) / possibleValuesLength) * 100;\n }\n }, [options, value, max, min, step]);\n\n return (\n <div className={className}>\n {label && (\n <div className=\"slider-top-row\" dir={lang.isRtl ? 'rtl' : undefined}>\n <span className=\"label\" dir=\"auto\">{label}</span>\n {!options && (\n <span className=\"value\" dir=\"auto\">{renderValue ? renderValue(value) : value}</span>\n )}\n </div>\n )}\n <div className=\"slider-main\">\n <div\n className=\"slider-fill-track\"\n style={`width: ${trackWidth}%`}\n />\n <input\n min={min}\n max={max}\n value={value}\n step={step}\n type=\"range\"\n onChange={handleChange}\n />\n {options && (\n <div className=\"slider-options\">\n {options.map((option, index) => (\n <div\n className={buildClassName('slider-option no-selection', index === value && 'active')}\n onClick={() => onChange(index)}\n >\n {option}\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default memo(RangeSlider);\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';\nimport useInputFocusOnOpen from '../../hooks/useInputFocusOnOpen';\n\nimport Loading from './Loading';\nimport Button from './Button';\nimport ShowTransition from './ShowTransition';\n\nimport './SearchInput.scss';\n\ntype OwnProps = {\n ref?: RefObject<HTMLInputElement>;\n children?: React.ReactNode;\n parentContainerClassName?: string;\n className?: string;\n inputId?: string;\n value?: string;\n focused?: boolean;\n isLoading?: boolean;\n spinnerColor?: 'yellow';\n spinnerBackgroundColor?: 'light';\n placeholder?: string;\n disabled?: boolean;\n autoComplete?: string;\n canClose?: boolean;\n autoFocusSearch?: boolean;\n onChange: (value: string) => void;\n onReset?: NoneToVoidFunction;\n onFocus?: NoneToVoidFunction;\n onBlur?: NoneToVoidFunction;\n onSpinnerClick?: NoneToVoidFunction;\n};\n\nconst SearchInput: FC<OwnProps> = ({\n ref,\n children,\n parentContainerClassName,\n value,\n inputId,\n className,\n focused,\n isLoading,\n spinnerColor,\n spinnerBackgroundColor,\n placeholder,\n disabled,\n autoComplete,\n canClose,\n autoFocusSearch,\n onChange,\n onReset,\n onFocus,\n onBlur,\n onSpinnerClick,\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 useInputFocusOnOpen(inputRef, autoFocusSearch, unmarkInputFocused);\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 <ShowTransition isOpen={Boolean(isLoading)} className=\"slow\">\n <Loading color={spinnerColor} backgroundColor={spinnerBackgroundColor} onClick={onSpinnerClick} />\n </ShowTransition>\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\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: React.ReactNode;\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<React.ReactNode>();\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, useRef, memo, useEffect,\n} from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport forceReflow from '../../util/forceReflow';\nimport renderText from '../common/helpers/renderText';\n\nimport './Tab.scss';\n\ntype OwnProps = {\n className?: string;\n title: string;\n isActive?: boolean;\n badgeCount?: number;\n isBadgeActive?: boolean;\n previousActiveTab?: number;\n onClick: (arg: number) => void;\n clickArg: number;\n};\n\nconst classNames = {\n active: 'Tab--active',\n badgeActive: 'Tab__badge--active',\n};\n\nconst Tab: FC<OwnProps> = ({\n className,\n title,\n isActive,\n badgeCount,\n isBadgeActive,\n previousActiveTab,\n onClick,\n clickArg,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const tabRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n // Set initial active state\n if (isActive && previousActiveTab === undefined && tabRef.current) {\n tabRef.current.classList.add(classNames.active);\n }\n\n if (!isActive || previousActiveTab === undefined) {\n return;\n }\n\n const tabEl = tabRef.current!;\n const prevTabEl = tabEl.parentElement!.children[previousActiveTab];\n if (!prevTabEl) {\n return;\n }\n\n const platformEl = tabEl.querySelector('i')!;\n const prevPlatformEl = prevTabEl.querySelector('i')!;\n\n // We move and resize the platform, so it repeats the position and size of the previous one\n const shiftLeft = prevPlatformEl.parentElement!.offsetLeft - platformEl.parentElement!.offsetLeft;\n const scaleFactor = prevPlatformEl.clientWidth / platformEl.clientWidth;\n\n prevPlatformEl.classList.remove('animate');\n platformEl.classList.remove('animate');\n platformEl.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;\n forceReflow(platformEl);\n platformEl.classList.add('animate');\n platformEl.style.transform = 'none';\n\n prevTabEl.classList.remove(classNames.active);\n tabEl.classList.add(classNames.active);\n }, [isActive, previousActiveTab]);\n\n return (\n <div\n className={buildClassName('Tab', className)}\n onClick={() => onClick(clickArg)}\n ref={tabRef}\n >\n <span>\n {renderText(title)}\n {Boolean(badgeCount) && (\n <span className={buildClassName('badge', isBadgeActive && classNames.badgeActive)}>{badgeCount}</span>\n )}\n <i />\n </span>\n </div>\n );\n};\n\nexport default memo(Tab);\n","import React, {\n FC, memo, useRef, useEffect,\n} from '../../lib/teact/teact';\n\nimport { IS_ANDROID, IS_IOS } from '../../util/environment';\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// Should match duration from `--slide-transition` CSS variable\nconst SCROLL_DURATION = IS_IOS ? 450 : IS_ANDROID ? 400 : 300;\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 const { scrollWidth, offsetWidth, scrollLeft } = container;\n if (scrollWidth <= offsetWidth) {\n return;\n }\n\n const activeTabElement = container.childNodes[activeTab] as HTMLElement | null;\n if (!activeTabElement) {\n return;\n }\n\n const { offsetLeft: activeTabOffsetLeft, offsetWidth: activeTabOffsetWidth } = activeTabElement;\n const newLeft = activeTabOffsetLeft - (offsetWidth / 2) + (activeTabOffsetWidth / 2);\n\n // Prevent scrolling by only a couple of pixels, which doesn't look smooth\n if (Math.abs(newLeft - scrollLeft) < TAB_SCROLL_THRESHOLD_PX) {\n return;\n }\n\n fastSmoothScrollHorizontal(container, newLeft, SCROLL_DURATION);\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 isActive={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';\nimport { GlobalState } from '../../global/types';\n\nimport { ANIMATION_LEVEL_MIN } from '../../config';\nimport buildClassName from '../../util/buildClassName';\nimport forceReflow from '../../util/forceReflow';\nimport { waitForAnimationEnd, waitForTransitionEnd } from '../../util/cssAnimationEndListeners';\nimport useForceUpdate from '../../hooks/useForceUpdate';\nimport usePrevious from '../../hooks/usePrevious';\nimport { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';\n\nimport './Transition.scss';\n\nexport type ChildrenFn = (isActive: boolean, isFrom: boolean, currentKey: number) => React.ReactNode;\nexport type TransitionProps = {\n ref?: RefObject<HTMLDivElement>;\n activeKey: number;\n name: (\n 'none' | 'slide' | 'slide-rtl' | 'mv-slide' | 'slide-fade' | 'zoom-fade' | 'slide-layers'\n | 'fade' | 'push-slide' | 'reveal' | 'slide-optimized' | 'slide-optimized-rtl'\n );\n direction?: 'auto' | 'inverse' | 1 | -1;\n renderCount?: number;\n shouldRestoreHeight?: boolean;\n shouldCleanup?: boolean;\n cleanupExceptionKey?: number;\n isDisabled?: boolean;\n id?: string;\n className?: string;\n onStart?: NoneToVoidFunction;\n onStop?: NoneToVoidFunction;\n children: React.ReactNode | ChildrenFn;\n};\n\nconst classNames = {\n active: 'Transition__slide--active',\n};\n\nconst Transition: FC<TransitionProps> = ({\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, React.ReactNode | ChildrenFn>>({});\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) {\n return;\n }\n\n const preservedRender = cleanupExceptionKey !== undefined ? rendersRef.current[cleanupExceptionKey] : undefined;\n\n rendersRef.current = preservedRender ? { [cleanupExceptionKey!]: preservedRender } : {};\n\n forceUpdate();\n }\n\n const container = containerRef.current!;\n\n const childElements = container.children;\n if (childElements.length === 1 && !activeKeyChanged) {\n if (name.startsWith('slide-optimized')) {\n (childElements[0] as HTMLElement).style.transition = 'none';\n (childElements[0] as HTMLElement).style.transform = 'translate3d(0, 0, 0)';\n }\n\n childElements[0].classList.add(classNames.active);\n\n return;\n }\n\n const childNodes = Array.from(container.childNodes);\n\n if (!activeKeyChanged || !childNodes.length) {\n return;\n }\n\n currentKeyRef.current = activeKey;\n\n const isBackwards = (\n direction === -1\n || (direction === 'auto' && prevActiveKey > activeKey)\n || (direction === 'inverse' && prevActiveKey < activeKey)\n );\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 === 'slide-optimized' || name === 'slide-optimized-rtl') {\n performSlideOptimized(\n animationLevel,\n name,\n isBackwards,\n cleanup,\n activeKey,\n currentKeyRef,\n container,\n shouldRestoreHeight,\n onStart,\n onStop,\n childNodes[activeIndex] as HTMLElement,\n childNodes[prevActiveIndex] as HTMLElement,\n );\n\n return;\n }\n\n container.classList.remove('animating');\n container.classList.toggle('backwards', isBackwards);\n\n if (name === 'none' || animationLevel === ANIMATION_LEVEL_MIN) {\n childNodes.forEach((node, i) => {\n if (node instanceof HTMLElement) {\n node.classList.remove('from', 'through', 'to');\n node.classList.toggle(classNames.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(classNames.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 const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();\n\n requestAnimationFrame(() => {\n container.classList.add('animating');\n\n onStart?.();\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(classNames.active, i === activeIndex);\n }\n });\n\n if (shouldRestoreHeight) {\n const activeElement = container.querySelector<HTMLDivElement>(`.${classNames.active}`);\n\n if (activeElement) {\n activeElement.style.height = 'auto';\n container.style.height = `${activeElement.clientHeight}px`;\n }\n }\n\n onStop?.();\n dispatchHeavyAnimationStop();\n cleanup();\n });\n }\n\n const watchedNode = name === 'mv-slide'\n ? childNodes[activeIndex]?.firstChild\n : name === 'reveal' && isBackwards\n ? childNodes[prevActiveIndex]\n : childNodes[activeIndex];\n\n if (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>(`.${classNames.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 renderKeys = Object.keys(renderCount ? new Array(renderCount).fill(undefined) : renders).map(Number);\n const contents = renderKeys.map((key) => {\n const render = renders[key];\n if (!render) {\n return undefined;\n }\n\n return (\n <div key={key} teactOrderKey={key}>{\n typeof render === 'function'\n ? render(key === activeKey, key === prevActiveKey, activeKey)\n : render\n }</div>\n );\n });\n\n return (\n <div\n ref={containerRef}\n id={id}\n className={buildClassName('Transition', className, name)}\n teactFastList={!renderCount}\n >\n {contents}\n </div>\n );\n};\n\nexport default Transition;\n\nfunction performSlideOptimized(\n animationLevel: GlobalState['settings']['byKey']['animationLevel'],\n name: 'slide-optimized' | 'slide-optimized-rtl',\n isBackwards: boolean,\n cleanup: NoneToVoidFunction,\n activeKey: number,\n currentKeyRef: { current: number | undefined },\n container: HTMLElement,\n shouldRestoreHeight?: boolean,\n onStart?: NoneToVoidFunction,\n onStop?: NoneToVoidFunction,\n toSlide?: HTMLElement,\n fromSlide?: HTMLElement,\n) {\n if (!fromSlide || !toSlide) {\n return;\n }\n\n if (animationLevel === ANIMATION_LEVEL_MIN) {\n fromSlide.style.transition = 'none';\n fromSlide.style.transform = '';\n fromSlide.classList.remove(classNames.active);\n\n toSlide.style.transition = 'none';\n toSlide.style.transform = 'translate3d(0, 0, 0)';\n toSlide.classList.add(classNames.active);\n\n cleanup();\n\n return;\n }\n\n if (name === 'slide-optimized-rtl') {\n isBackwards = !isBackwards;\n }\n\n const dispatchHeavyAnimationStop = dispatchHeavyAnimationEvent();\n\n requestAnimationFrame(() => {\n onStart?.();\n\n fromSlide.style.transition = 'none';\n fromSlide.style.transform = 'translate3d(0, 0, 0)';\n\n toSlide.style.transition = 'none';\n toSlide.style.transform = `translate3d(${isBackwards ? '-' : ''}100%, 0, 0)`;\n\n forceReflow(toSlide);\n\n fromSlide.style.transition = '';\n fromSlide.style.transform = `translate3d(${isBackwards ? '' : '-'}100%, 0, 0)`;\n\n toSlide.style.transition = '';\n toSlide.style.transform = 'translate3d(0, 0, 0)';\n\n fromSlide.classList.remove(classNames.active);\n toSlide.classList.add(classNames.active);\n\n waitForTransitionEnd(fromSlide, () => {\n if (activeKey !== currentKeyRef.current) {\n return;\n }\n\n fromSlide.style.transition = 'none';\n fromSlide.style.transform = '';\n\n if (shouldRestoreHeight) {\n toSlide.style.height = 'auto';\n container.style.height = `${toSlide.clientHeight}px`;\n }\n\n onStop?.();\n dispatchHeavyAnimationStop();\n cleanup();\n });\n });\n}\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: string[] = [];\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?.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\nconst useFoldersReducer = () => {\n return useReducer(foldersReducer, INITIAL_STATE);\n};\n\nexport default useFoldersReducer;\n","import {\n useCallback, useEffect, useRef, useState,\n} from '../lib/teact/teact';\nimport { getDispatch, getGlobal } from '../lib/teact/teactn';\n\nimport { register, Track, TrackId } from '../util/audioPlayer';\nimport useEffectWithPrevDeps from './useEffectWithPrevDeps';\nimport { isSafariPatchInProgress } from '../util/patchSafariProgressiveAudio';\nimport useOnChange from './useOnChange';\nimport {\n MediaSessionHandlers, registerMediaSession, setPlaybackState, setPositionState, updateMetadata,\n} from '../util/mediaSession';\n\ntype Handler = (e: Event) => void;\n\nconst DEFAULT_SKIP_TIME = 10;\n\nconst useAudioPlayer = (\n trackId: TrackId,\n originalDuration: number, // Sometimes incorrect for voice messages\n trackType: Track['type'],\n src?: string,\n handlers?: Record<string, Handler>,\n metadata?: MediaMetadata,\n onInit?: (element: HTMLAudioElement) => void,\n shouldPlay = false,\n onForcePlay?: NoneToVoidFunction,\n onTrackChange?: NoneToVoidFunction,\n noPlaylist = false,\n noProgressUpdates = 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 const handleTrackChange = useCallback(() => {\n setIsPlaying(false);\n if (onTrackChange) onTrackChange();\n }, [onTrackChange]);\n\n useOnChange(() => {\n controllerRef.current = register(trackId, trackType, (eventName, e) => {\n switch (eventName) {\n case 'onPlay': {\n const {\n setVolume, setPlaybackRate, toggleMuted, proxy,\n } = controllerRef.current!;\n setIsPlaying(true);\n\n registerMediaSession(metadata, makeMediaHandlers(controllerRef));\n setPlaybackState('playing');\n setVolume(getGlobal().audioPlayer.volume);\n toggleMuted(Boolean(getGlobal().audioPlayer.isMuted));\n if (trackType === 'voice') {\n setPlaybackRate(getGlobal().audioPlayer.playbackRate);\n }\n\n setPositionState({\n duration: proxy.duration || 0,\n playbackRate: proxy.playbackRate,\n position: proxy.currentTime,\n });\n break;\n }\n case 'onRateChange': {\n const { proxy } = controllerRef.current!;\n setPositionState({\n duration: proxy.duration || 0,\n playbackRate: proxy.playbackRate,\n position: proxy.currentTime,\n });\n break;\n }\n case 'onPause':\n setIsPlaying(false);\n setPlaybackState('paused');\n break;\n case 'onTimeUpdate': {\n const { proxy } = controllerRef.current!;\n const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;\n if (!noProgressUpdates) setPlayProgress(proxy.currentTime / duration);\n break;\n }\n case 'onEnded': {\n setPlaybackState('paused');\n break;\n }\n }\n\n handlers?.[eventName]?.(e);\n }, onForcePlay, handleTrackChange);\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 useEffect(() => {\n if (isPlaying && metadata) updateMetadata(metadata);\n }, [metadata, isPlaying]);\n\n const {\n play,\n pause,\n setCurrentTime,\n proxy,\n destroy,\n setVolume,\n stop,\n isFirst,\n isLast,\n requestNextTrack,\n requestPreviousTrack,\n setPlaybackRate,\n toggleMuted,\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) && !noProgressUpdates) {\n setPlayProgress(proxy.currentTime / duration);\n }\n }, [duration, playProgress, proxy, noProgressUpdates]);\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 playIfPresent = useCallback(() => {\n if (src) {\n play(src);\n }\n }, [src, play]);\n\n const playPause = useCallback(() => {\n if (isPlaying) {\n pause();\n } else {\n playIfPresent();\n }\n }, [pause, playIfPresent, isPlaying]);\n\n const setTime = useCallback((time: number) => {\n setCurrentTime(time);\n if (duration) {\n setPlayProgress(proxy.currentTime / duration);\n }\n }, [duration, proxy, setCurrentTime]);\n\n return {\n isPlaying: isPlayingSync,\n playProgress,\n playPause,\n pause,\n play: playIfPresent,\n stop,\n setCurrentTime: setTime,\n setVolume,\n audioProxy: proxy,\n duration,\n requestNextTrack,\n requestPreviousTrack,\n isFirst,\n isLast,\n setPlaybackRate,\n toggleMuted,\n };\n};\n\nfunction makeMediaHandlers(controllerRef: React.RefObject<ReturnType<typeof register>>) {\n let mediaHandlers: MediaSessionHandlers = {};\n if (controllerRef && controllerRef.current) {\n const {\n play, pause, setCurrentTime, proxy, requestNextTrack, requestPreviousTrack, isFirst, isLast,\n } = controllerRef.current;\n mediaHandlers = {\n play: () => {\n play(proxy.src);\n },\n pause: () => {\n pause();\n },\n stop: () => {\n pause();\n setCurrentTime(0);\n getDispatch().closeAudioPlayer();\n },\n seekbackward: (event) => {\n const skipTime = event.seekOffset || DEFAULT_SKIP_TIME;\n setCurrentTime(Math.max(proxy.currentTime - skipTime, 0));\n },\n seekforward: (event) => {\n const skipTime = event.seekOffset || DEFAULT_SKIP_TIME;\n setCurrentTime(Math.min(proxy.currentTime + skipTime, proxy.duration));\n },\n seekTo: (event) => {\n if (event.seekTime) {\n setCurrentTime(event.seekTime);\n }\n },\n };\n\n if (!isLast()) {\n mediaHandlers.nexttrack = () => {\n requestNextTrack();\n };\n }\n if (!isFirst()) {\n mediaHandlers.previoustrack = () => {\n requestPreviousTrack();\n };\n }\n }\n return mediaHandlers;\n}\n\nexport default useAudioPlayer;\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\nconst useBuffering = (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\nexport default useBuffering;\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 { SERVICE_NOTIFICATIONS_USER_ID } from '../config';\nimport {\n isChatArchived, getCanDeleteChat, isUserId, isChatChannel,\n} from '../modules/helpers';\nimport { compact } from '../util/iteratees';\nimport useLang from './useLang';\n\nconst useChatContextActions = ({\n chat,\n user,\n folderId,\n isPinned,\n isMuted,\n canChangeFolder,\n handleDelete,\n handleChatFolderChange,\n}: {\n chat: ApiChat | undefined;\n user: ApiUser | undefined;\n folderId?: number;\n isPinned?: boolean;\n isMuted?: boolean;\n canChangeFolder?: boolean;\n handleDelete: () => void;\n handleChatFolderChange: () => void;\n}, isInSearch = false) => {\n const lang = useLang();\n\n const { isSelf } = user || {};\n const isServiceNotifications = user?.id === SERVICE_NOTIFICATIONS_USER_ID;\n\n return useMemo(() => {\n if (!chat) {\n return undefined;\n }\n\n const {\n toggleChatPinned,\n updateChatMutedState,\n toggleChatArchived,\n toggleChatUnread,\n } = getDispatch();\n\n const actionAddToFolder = canChangeFolder ? {\n title: lang('ChatList.Filter.AddToFolder'),\n icon: 'folder',\n handler: handleChatFolderChange,\n } : undefined;\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 if (isInSearch) {\n return compact([actionPin, actionAddToFolder]);\n }\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 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: isUserId(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 const isInFolder = folderId !== undefined;\n\n return compact([\n actionAddToFolder,\n actionUnreadMark,\n actionPin,\n !isSelf && actionMute,\n !isSelf && !isServiceNotifications && !isInFolder && actionArchive,\n actionDelete,\n ]);\n }, [\n chat, canChangeFolder, lang, handleChatFolderChange, isPinned, isInSearch, isMuted, handleDelete, folderId, isSelf,\n isServiceNotifications,\n ]);\n};\n\nexport default useChatContextActions;\n","import { RefObject } from 'react';\nimport { useState, useEffect, useCallback } from '../lib/teact/teact';\n\nimport { IAnchorPosition } from '../types';\nimport {\n IS_TOUCH_ENV, IS_SINGLE_COLUMN_LAYOUT, IS_PWA, IS_IOS,\n} from '../util/environment';\n\nconst LONG_TAP_DURATION_MS = 200;\n\nfunction checkIsDisabledForMobile() {\n return IS_SINGLE_COLUMN_LAYOUT\n && window.document.body.classList.contains('enable-symbol-menu-transforms');\n}\n\nfunction stopEvent(e: Event) {\n e.stopImmediatePropagation();\n e.preventDefault();\n e.stopPropagation();\n}\n\nconst useContextMenuHandlers = (\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 (e.target as HTMLElement).classList.add('no-selection');\n }\n }, [isMenuDisabled]);\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n (e.target as HTMLElement).classList.remove('no-selection');\n\n if (isMenuDisabled || (shouldDisableOnLink && (e.target as HTMLElement).matches('a[href]'))) {\n return;\n }\n e.preventDefault();\n\n if (contextMenuPosition) {\n return;\n }\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\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[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 stopEvent(e);\n }, true);\n\n // On iOS15, in PWA mode, the context menu immediately closes after opening\n if (IS_PWA && IS_IOS) {\n element.addEventListener('mousedown', function cancelClickOnce(e) {\n element.removeEventListener('mousedown', cancelClickOnce, true);\n stopEvent(e);\n }, true);\n }\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\nexport default useContextMenuHandlers;\n","import { useState, useEffect } from '../lib/teact/teact';\nimport { IAnchorPosition } from '../types';\n\ninterface Layout {\n extraPaddingX?: number;\n extraTopPadding?: number;\n marginSides?: number;\n extraMarginTop?: number;\n}\n\nconst MENU_POSITION_VISUAL_COMFORT_SPACE_PX = 16;\nconst MENU_POSITION_BOTTOM_MARGIN = 12;\nconst EMPTY_RECT = {\n width: 0, left: 0, height: 0, top: 0,\n};\n\nexport default function useContextMenuPosition(\n anchor: IAnchorPosition | undefined,\n getTriggerElement: () => HTMLElement | null,\n getRootElement: () => HTMLElement | null,\n getMenuElement: () => HTMLElement | null,\n getLayout?: () => Layout,\n) {\n const [positionX, setPositionX] = useState<'right' | 'left'>('right');\n const [positionY, setPositionY] = useState<'top' | 'bottom'>('bottom');\n const [transformOriginX, setTransformOriginX] = useState<number>();\n const [transformOriginY, setTransformOriginY] = useState<number>();\n const [withScroll, setWithScroll] = useState(false);\n const [style, setStyle] = useState('');\n const [menuStyle, setMenuStyle] = useState('opacity: 0;');\n\n useEffect(() => {\n const triggerEl = getTriggerElement();\n if (!anchor || !triggerEl) {\n return;\n }\n\n let { x, y } = anchor;\n const anchorX = x;\n const anchorY = y;\n\n const menuEl = getMenuElement();\n const rootEl = getRootElement();\n\n const {\n extraPaddingX = 0,\n extraTopPadding = 0,\n marginSides = 0,\n extraMarginTop = 0,\n } = getLayout?.() || {};\n\n const marginTop = menuEl ? parseInt(getComputedStyle(menuEl).marginTop, 10) + extraMarginTop : undefined;\n\n const menuRect = menuEl ? {\n width: menuEl.offsetWidth,\n height: menuEl.offsetHeight + marginTop!,\n } : EMPTY_RECT;\n\n const rootRect = rootEl ? rootEl.getBoundingClientRect() : EMPTY_RECT;\n\n let horizontalPosition: 'left' | 'right';\n let verticalPosition: 'top' | 'bottom';\n if (x + menuRect.width + extraPaddingX < rootRect.width + rootRect.left) {\n x += 3;\n horizontalPosition = 'left';\n } else if (x - menuRect.width > 0) {\n horizontalPosition = 'right';\n x -= 3;\n } else {\n horizontalPosition = 'left';\n x = 16;\n }\n setPositionX(horizontalPosition);\n\n if (marginSides\n && horizontalPosition === 'right' && (x + extraPaddingX + marginSides >= rootRect.width + rootRect.left)) {\n x -= marginSides;\n }\n\n if (marginSides && horizontalPosition === 'left') {\n if (x + extraPaddingX + marginSides + menuRect.width >= rootRect.width + rootRect.left) {\n x -= marginSides;\n } else if (x - marginSides <= 0) {\n x += marginSides;\n }\n }\n\n if (y + menuRect.height < rootRect.height + rootRect.top) {\n verticalPosition = 'top';\n } else {\n verticalPosition = 'bottom';\n\n if (y - menuRect.height < rootRect.top + extraTopPadding) {\n y = rootRect.top + rootRect.height;\n }\n }\n setPositionY(verticalPosition);\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const left = horizontalPosition === '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 const top = Math.min(\n rootRect.height - triggerRect.top + triggerRect.height - MENU_POSITION_BOTTOM_MARGIN + (marginTop || 0),\n y - triggerRect.top,\n );\n const menuMaxHeight = rootRect.height - MENU_POSITION_BOTTOM_MARGIN - (marginTop || 0);\n\n setWithScroll(menuMaxHeight < menuRect.height);\n setMenuStyle(`max-height: ${menuMaxHeight}px;`);\n setStyle(`left: ${left}px; top: ${top}px`);\n const offsetX = (anchorX - triggerRect.left) - left;\n const offsetY = (anchorY - triggerRect.top) - top - (marginTop || 0);\n setTransformOriginX(horizontalPosition === 'left' ? offsetX : menuRect.width + offsetX);\n setTransformOriginY(verticalPosition === 'bottom' ? menuRect.height + offsetY : offsetY);\n }, [\n anchor, getMenuElement, getRootElement, getTriggerElement, getLayout,\n ]);\n\n return {\n positionX,\n positionY,\n transformOriginX,\n transformOriginY,\n style,\n menuStyle,\n withScroll,\n };\n}\n","import { useMemo } from '../lib/teact/teact';\n\nimport { debounce } from '../util/schedulers';\n\nexport default function useDebounce(ms: number, noFirst?: boolean, noLast?: boolean) {\n return useMemo(() => {\n return debounce((cb) => cb(), ms, !noFirst, !noLast);\n }, [ms, noFirst, noLast]);\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\nconst useEnsureMessage = (\n chatId: string,\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\nexport default useEnsureMessage;\n","import { useEffect, useState } from '../lib/teact/teact';\nimport {\n getOrderedIds,\n getUnreadCounters,\n getChatsCount,\n addOrderedIdsCallback,\n addUnreadCountersCallback,\n addChatsCountCallback,\n} from '../util/folderManager';\n\nexport function useFolderManagerForOrderedIds(folderId: number) {\n const [orderedIds, setOrderedIds] = useState(getOrderedIds(folderId));\n\n useEffect(() => addOrderedIdsCallback(folderId, setOrderedIds), [folderId]);\n\n return orderedIds;\n}\n\nexport function useFolderManagerForUnreadCounters() {\n const [unreadCounters, setUnreadCounters] = useState(getUnreadCounters());\n\n useEffect(() => addUnreadCountersCallback(setUnreadCounters), []);\n\n return unreadCounters;\n}\n\nexport function useFolderManagerForChatsCount() {\n const [chatsCount, setChatsCount] = useState(getChatsCount());\n\n useEffect(() => addChatsCountCallback(setChatsCount), []);\n\n return chatsCount;\n}\n","import { useEffect } from '../lib/teact/teact';\n\nconst useHorizontalScroll = (container: HTMLElement | null, isDisabled?: boolean) => {\n useEffect(() => {\n if (!container || isDisabled) {\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\nexport default useHorizontalScroll;\n","import { RefObject } from 'react';\nimport { useEffect } from '../lib/teact/teact';\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';\n\n// Focus slows down animation, also it breaks transition layout in Chrome\nconst FOCUS_DELAY_MS = 500;\nconst MODAL_HIDE_DELAY_MS = 300;\n\nexport default function useInputFocusOnOpen(\n inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement>,\n isOpen?: boolean,\n onClose?: NoneToVoidFunction,\n) {\n useEffect(() => {\n if (isOpen) {\n if (!IS_SINGLE_COLUMN_LAYOUT) {\n setTimeout(() => {\n requestAnimationFrame(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n }\n });\n }, FOCUS_DELAY_MS);\n }\n } else {\n if (inputRef.current) {\n inputRef.current.blur();\n }\n\n if (onClose) {\n setTimeout(onClose, MODAL_HIDE_DELAY_MS);\n }\n }\n }, [inputRef, isOpen, onClose]);\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\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 onUnfreezeRef = useRef<NoneToVoidFunction>();\n\n rootCallbackRef.current = rootCallback;\n\n const freeze = useCallback(() => {\n freezeFlagsRef.current++;\n }, []);\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 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 { useEffect, useLayoutEffect, useRef } from '../lib/teact/teact';\n\nfunction useInterval(callback: NoneToVoidFunction, delay?: number, noFirst = false) {\n const savedCallback = useRef(callback);\n\n useLayoutEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (delay === undefined) {\n return undefined;\n }\n\n const id = setInterval(() => savedCallback.current(), delay);\n if (!noFirst) savedCallback.current();\n\n return () => clearInterval(id);\n }, [delay, noFirst]);\n}\n\nexport default useInterval;\n","import { useLayoutEffect } from '../lib/teact/teact';\nimport usePrevious from './usePrevious';\n\nconst useLayoutEffectWithPrevDeps = <T extends readonly any[]>(\n cb: (args: T | readonly []) => void, dependencies: T, debugKey?: string,\n) => {\n const prevDeps = usePrevious<T>(dependencies);\n return useLayoutEffect(() => {\n return cb(prevDeps || []);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies, debugKey);\n};\n\nexport default useLayoutEffectWithPrevDeps;\n","import useShowTransition from './useShowTransition';\n\nexport default function useMediaTransition(mediaData?: any) {\n const isMediaReady = Boolean(mediaData);\n const { transitionClassNames } = useShowTransition(isMediaReady, undefined, isMediaReady, 'slow');\n\n return transitionClassNames;\n}\n","import { useRef } from '../lib/teact/teact';\nimport generateIdFor from '../util/generateIdFor';\n\nconst store: Record<string, boolean> = {};\n\nconst useUniqueId = () => {\n const idRef = useRef<string>();\n\n if (!idRef.current) {\n idRef.current = generateIdFor(store);\n store[idRef.current] = true;\n }\n\n return idRef.current;\n};\n\nexport default useUniqueId;\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';\nimport useUniqueId from './useUniqueId';\n\nconst STREAMING_PROGRESS = 0.75;\nconst STREAMING_TIMEOUT = 1500;\nconst PROGRESS_THROTTLE = 500;\n\nexport default function useMediaWithLoadProgress(\n mediaHash: string | undefined,\n noLoad = false,\n mediaFormat = ApiMediaFormat.BlobUrl,\n cacheBuster?: number,\n delay?: number | false,\n isHtmlAllowed = false,\n) {\n const mediaData = mediaHash ? mediaLoader.getFromMemory(mediaHash) : undefined;\n const isStreaming = mediaFormat === ApiMediaFormat.Stream || (\n IS_PROGRESSIVE_SUPPORTED && mediaFormat === ApiMediaFormat.Progressive\n );\n const forceUpdate = useForceUpdate();\n const id = useUniqueId();\n const [loadProgress, setLoadProgress] = useState(mediaData && !isStreaming ? 1 : 0);\n const startedAtRef = useRef<number>();\n\n const handleProgress = useMemo(() => {\n return throttle((progress: number) => {\n if (startedAtRef.current && (!delay || (Date.now() - startedAtRef.current > delay))) {\n setLoadProgress(progress);\n }\n }, PROGRESS_THROTTLE, true);\n }, [delay]);\n\n useEffect(() => {\n if (!noLoad && mediaHash) {\n if (!mediaData) {\n setLoadProgress(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, id).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 setLoadProgress(STREAMING_PROGRESS);\n }, STREAMING_TIMEOUT);\n }\n }\n }, [\n noLoad, mediaHash, mediaData, mediaFormat, cacheBuster, forceUpdate, isStreaming, delay, handleProgress,\n isHtmlAllowed, id,\n ]);\n\n useEffect(() => {\n if (noLoad && startedAtRef.current) {\n mediaLoader.cancelProgress(handleProgress);\n setLoadProgress(0);\n startedAtRef.current = undefined;\n }\n }, [handleProgress, noLoad]);\n\n useEffect(() => {\n return () => {\n if (mediaHash) {\n mediaLoader.removeCallback(mediaHash, id);\n }\n };\n }, [id, mediaHash]);\n\n return { mediaData, loadProgress };\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(false);\n\n const markMouseInside = useCallback(() => {\n isMouseInside.current = true;\n }, []);\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, markMouseInside];\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 { useMemo } from '../lib/teact/teact';\nimport { getDispatch } from '../lib/teact/teactn';\n\nimport { ApiSendMessageAction } from '../api/types';\n\nimport { SEND_MESSAGE_ACTION_INTERVAL } from '../config';\nimport { throttle } from '../util/schedulers';\n\nconst useSendMessageAction = (chatId: string, threadId?: number) => {\n return useMemo(() => {\n return throttle((action: ApiSendMessageAction) => {\n getDispatch().sendMessageAction({ chatId, threadId, action });\n }, SEND_MESSAGE_ACTION_INTERVAL);\n }, [chatId, threadId]);\n};\n\nexport default useSendMessageAction;\n","import { useRef } from '../lib/teact/teact';\n\nimport useOnChange from './useOnChange';\n\n// Allows to use state value as \"silent\" dependency in hooks (not causing updates).\n// Useful for state values that update frequently (such as controlled input value).\nexport function useStateRef<T>(value: T) {\n const ref = useRef<T>(value);\n\n useOnChange(() => {\n ref.current = value;\n }, [value]);\n\n return ref;\n}\n","import { useEffect, useLayoutEffect, useRef } from '../lib/teact/teact';\n\nfunction useTimeout(callback: () => void, delay?: number) {\n const savedCallback = useRef(callback);\n\n useLayoutEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (typeof delay !== 'number') {\n return undefined;\n }\n const id = setTimeout(() => savedCallback.current(), delay);\n return () => clearTimeout(id);\n }, [delay]);\n}\n\nexport default useTimeout;\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 { getDispatch, getGlobal } from '../lib/teact/teactn';\n\nimport { AudioOrigin, GlobalSearchContent } from '../types';\nimport { ApiMessage } from '../api/types';\n\nimport { IS_SAFARI } from './environment';\nimport safePlay from './safePlay';\nimport { patchSafariProgressiveAudio, isSafariPatchInProgress } from './patchSafariProgressiveAudio';\nimport { getMessageKey, MessageKey, parseMessageKey } from '../modules/helpers';\nimport { fastRaf } from './schedulers';\nimport { selectCurrentMessageList } from '../modules/selectors';\n\ntype Handler = (eventName: string, e: Event) => void;\nexport type TrackId = `${MessageKey}-${number}`;\n\nexport interface Track {\n audio: HTMLAudioElement;\n proxy: HTMLAudioElement;\n type: 'voice' | 'audio';\n handlers: Handler[];\n onForcePlay?: NoneToVoidFunction;\n onTrackChange?: NoneToVoidFunction;\n}\n\nconst tracks = new Map<TrackId, Track>();\nlet voiceQueue: TrackId[] = [];\nlet musicQueue: TrackId[] = [];\n\nlet currentTrackId: TrackId | undefined;\n\nfunction createAudio(\n trackId: TrackId,\n type: Track['type'],\n onForcePlay?: NoneToVoidFunction,\n onTrackChange?: NoneToVoidFunction,\n): Track {\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 (!tracks.has(trackId)) {\n return;\n }\n\n if (isSafariPatchInProgress(audio)) {\n return;\n }\n\n playNext(trackId);\n });\n\n return {\n audio,\n type,\n proxy: new Proxy(audio, {\n get: (target, key: keyof HTMLAudioElement) => target[key],\n }),\n handlers: [],\n onForcePlay,\n onTrackChange,\n };\n}\n\nfunction playNext(trackId: TrackId, isReverseOrder?: boolean) {\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack) {\n currentTrack.audio.pause();\n currentTrack.audio.currentTime = 0;\n if (currentTrack.onTrackChange) currentTrack.onTrackChange();\n }\n\n const origin = getGlobal().audioPlayer.origin || AudioOrigin.Inline;\n\n const nextTrackId = findNextInQueue(trackId, origin, isReverseOrder);\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(splitTrackId(nextTrackId).messageKey));\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\nexport function stopCurrentAudio() {\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack) {\n currentTrack.audio.pause();\n }\n}\n\nexport function register(\n trackId: TrackId,\n trackType: Track['type'],\n handler: Handler,\n onForcePlay?: NoneToVoidFunction,\n onTrackChange?: NoneToVoidFunction,\n) {\n if (!tracks.has(trackId)) {\n const track = createAudio(trackId, trackType, onForcePlay, onTrackChange);\n tracks.set(trackId, track);\n addTrackToQueue(track, trackId);\n }\n const { audio, proxy, handlers } = tracks.get(trackId)!;\n\n handlers.push(handler);\n\n return {\n play(src: string) {\n if (!audio.paused) return;\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack && currentTrackId !== trackId) {\n currentTrack.audio.pause();\n currentTrack.audio.currentTime = 0;\n if (isSafariPatchInProgress(currentTrack.audio)) {\n currentTrack.audio.dataset.preventPlayAfterPatch = 'true';\n }\n if (currentTrack.onTrackChange) currentTrack.onTrackChange();\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 delete audio.dataset.preventPlayAfterPatch;\n patchSafariProgressiveAudio(audio);\n }\n }\n\n safePlay(audio);\n cleanUpQueue(trackType, trackId);\n },\n\n pause() {\n if (currentTrackId === trackId) {\n audio.pause();\n }\n },\n\n stop() {\n if (currentTrackId === trackId) {\n // Hack, reset src to remove default media session notification\n const prevSrc = audio.src;\n audio.pause();\n // onPause not called otherwise, but required to sync UI\n fastRaf(() => {\n audio.src = '';\n audio.src = prevSrc;\n });\n }\n },\n\n setCurrentTime(time: number) {\n if (currentTrackId === trackId) {\n if (audio.fastSeek) {\n audio.fastSeek(time);\n } else {\n audio.currentTime = time;\n }\n }\n },\n\n setVolume(volume: number) {\n if (currentTrackId === trackId) {\n audio.volume = volume;\n audio.muted = false;\n }\n },\n\n setPlaybackRate(rate: number) {\n if (currentTrackId === trackId) {\n audio.playbackRate = rate;\n }\n },\n\n toggleMuted(muted?: boolean) {\n if (muted === undefined) {\n audio.muted = !audio.muted;\n } else {\n audio.muted = muted;\n }\n },\n\n proxy,\n\n requestNextTrack() {\n playNext(trackId);\n },\n\n isLast() {\n return !findNextInQueue(trackId, getGlobal().audioPlayer.origin);\n },\n\n isFirst() {\n return !findNextInQueue(trackId, getGlobal().audioPlayer.origin, true);\n },\n\n requestPreviousTrack() {\n playNext(trackId, true);\n },\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 removeFromQueue(track, trackId);\n }\n\n if (trackId === currentTrackId) {\n currentTrackId = undefined;\n }\n }\n },\n };\n}\n\nfunction getTrackQueue(track: Track) {\n switch (track.type) {\n case 'audio': return musicQueue;\n case 'voice': return voiceQueue;\n default: return undefined;\n }\n}\n\nfunction addTrackToQueue(track: Track, trackId: TrackId) {\n if (track.type === 'audio' && !musicQueue.includes(trackId)) {\n musicQueue.push(trackId);\n musicQueue.sort(trackIdComparator);\n }\n\n if (track.type === 'voice' && !voiceQueue.includes(trackId)) {\n voiceQueue.push(trackId);\n voiceQueue.sort(trackIdComparator);\n }\n}\n\nfunction removeFromQueue(track: Track, trackId: TrackId) {\n const trackIdFilter = (el: TrackId) => el !== trackId;\n if (track.type === 'audio') {\n musicQueue = musicQueue.filter(trackIdFilter);\n }\n\n if (track.type === 'voice') {\n voiceQueue = voiceQueue.filter(trackIdFilter);\n }\n}\n\nfunction cleanUpQueue(type: Track['type'], trackId: TrackId) {\n if (getGlobal().globalSearch.currentContent === GlobalSearchContent.Music) return;\n const { chatId } = parseMessageKey(splitTrackId(trackId).messageKey);\n const openedChatId = selectCurrentMessageList(getGlobal())?.chatId;\n const queueFilter = (id: string) => (\n id.startsWith(`msg${chatId}`) || (openedChatId && id.startsWith(`msg${openedChatId}`))\n );\n\n if (type === 'audio') {\n musicQueue = musicQueue.filter(queueFilter);\n }\n\n if (type === 'voice') {\n voiceQueue = voiceQueue.filter(queueFilter);\n }\n}\n\nfunction findNextInQueue(currentId: TrackId, origin = AudioOrigin.Inline, isReverseOrder?: boolean) {\n const track = tracks.get(currentId)!;\n const queue = getTrackQueue(track);\n if (!queue) return undefined;\n\n if (origin === AudioOrigin.Search) {\n const index = queue.indexOf(currentId);\n if (index < 0) return undefined;\n const direction = isReverseOrder ? -1 : 1;\n return queue[index + direction];\n }\n\n const { chatId } = parseMessageKey(splitTrackId(currentId).messageKey);\n const chatAudio = queue.filter((id) => id.startsWith(`msg${chatId}`));\n const index = chatAudio.indexOf(currentId);\n if (index < 0) return undefined;\n let direction = origin === AudioOrigin.Inline ? -1 : 1;\n if (isReverseOrder) direction *= -1;\n return chatAudio[index + direction];\n}\n\nexport function makeTrackId(message: ApiMessage): TrackId {\n return `${getMessageKey(message)}-${message.date}`;\n}\n\nfunction splitTrackId(trackId: TrackId) {\n const messageKey = trackId.match(/^msg(-?\\d+)-(\\d+)/)![0] as MessageKey;\n const date = Number(trackId.split('-').pop());\n return {\n messageKey,\n date,\n };\n}\n\n// Descending order by date\nfunction trackIdComparator(one?: TrackId, two?: TrackId) {\n if (!one || !two) return 0;\n const { date: dateOne, messageKey: keyOne } = splitTrackId(one);\n const { date: dateTwo, messageKey: keyTwo } = splitTrackId(two);\n const diff = dateTwo - dateOne;\n return diff === 0 ? keyTwo.localeCompare(keyOne) : diff;\n}\n","import { IS_IOS } 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 onZoom?: (e: TouchEvent, params: {\n // Relative zoom factor\n zoomFactor: number;\n\n // center coordinate of the initial pinch\n initialCenterX: number;\n initialCenterY: number;\n\n // offset of the pinch center (current from initial)\n dragOffsetX: number;\n dragOffsetY: number;\n\n // center coordinate of the current pinch\n currentCenterX: number;\n currentCenterY: number;\n }) => void;\n onClick?: (e: MouseEvent | TouchEvent) => void;\n onDoubleClick?: (e: MouseEvent | RealTouchEvent, params: { centerX: number; centerY: number }) => void;\n excludedClosestSelector?: string;\n selectorToPreventScroll?: string;\n maxZoom?: number;\n minZoom?: number;\n isNotPassive?: boolean;\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\nexport const IOS_SCREEN_EDGE_THRESHOLD = 20;\nconst MOVED_THRESHOLD = 15;\nconst SWIPE_THRESHOLD = 50;\n\nfunction getDistance(a: Touch, b?: Touch) {\n if (!b) return 0;\n return Math.sqrt((b.pageX - a.pageX) ** 2 + (b.pageY - a.pageY) ** 2);\n}\n\nfunction getTouchCenter(a: Touch, b: Touch) {\n return {\n x: (a.pageX + b.pageX) / 2,\n y: (a.pageY + b.pageY) / 2,\n };\n}\n\nlet lastClickTime = 0;\n\nexport function captureEvents(element: HTMLElement, options: CaptureOptions) {\n let captureEvent: MouseEvent | RealTouchEvent | undefined;\n let hasMoved = false;\n let hasSwiped = false;\n let initialDistance = 0;\n let initialTouchCenter = { x: window.innerWidth / 2, y: window.innerHeight / 2 };\n let initialSwipeAxis: TSwipeAxis | undefined;\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, { passive: true });\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 if (e.touches.length === 2) {\n initialDistance = getDistance(e.touches[0], e.touches[1]);\n initialTouchCenter = getTouchCenter(e.touches[0], e.touches[1]);\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 if (IS_IOS && options.selectorToPreventScroll) {\n Array.from(document.querySelectorAll<HTMLElement>(options.selectorToPreventScroll)).forEach((scrollable) => {\n scrollable.style.overflow = '';\n });\n }\n\n if (e) {\n if (hasMoved) {\n if (options.onRelease) {\n options.onRelease(e);\n }\n } else if (e.type === 'mouseup') {\n if (options.onDoubleClick && Date.now() - lastClickTime < 300) {\n options.onDoubleClick(e, {\n centerX: captureEvent!.pageX!,\n centerY: captureEvent!.pageY!,\n });\n } else if (options.onClick && (!('button' in e) || e.button === 0)) {\n options.onClick(e);\n }\n lastClickTime = Date.now();\n }\n }\n }\n\n hasMoved = false;\n hasSwiped = false;\n initialDistance = 0;\n initialSwipeAxis = undefined;\n initialTouchCenter = { x: window.innerWidth / 2, y: window.innerHeight / 2 };\n captureEvent = undefined;\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 if (options.onZoom && initialDistance > 0 && e.touches.length === 2) {\n const endDistance = getDistance(e.touches[0], e.touches[1]);\n const touchCenter = getTouchCenter(e.touches[0], e.touches[1]);\n const dragOffsetX = touchCenter.x - initialTouchCenter.x;\n const dragOffsetY = touchCenter.y - initialTouchCenter.y;\n const zoomFactor = endDistance / initialDistance;\n options.onZoom(e, {\n zoomFactor,\n initialCenterX: initialTouchCenter.x,\n initialCenterY: initialTouchCenter.y,\n dragOffsetX,\n dragOffsetY,\n currentCenterX: touchCenter.x,\n currentCenterY: touchCenter.y,\n });\n if (zoomFactor !== 1) hasMoved = true;\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_IOS && shouldPreventScroll && options.selectorToPreventScroll) {\n Array.from(document.querySelectorAll<HTMLElement>(options.selectorToPreventScroll)).forEach((scrollable) => {\n scrollable.style.overflow = 'hidden';\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 if (!initialSwipeAxis) {\n initialSwipeAxis = axis;\n } else if (initialSwipeAxis !== axis) {\n // Prevent horizontal swipe after vertical to prioritize scroll\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: !options.isNotPassive });\n\n return () => {\n onRelease();\n\n element.removeEventListener('touchstart', onCapture);\n element.removeEventListener('mousedown', 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","// 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","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 { IS_ANDROID } from './environment';\nimport { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';\nimport { animateSingle } from './animation';\nimport { fastRaf } from './schedulers';\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 + (IS_ANDROID ? 1 : 0);\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 fastRaf(() => {\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}\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 { animate } from './animation';\nimport { fastRaf } from './schedulers';\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 scrollWithJs(container, left, duration);\n}\n\nfunction scrollWithJs(container: HTMLElement, left: number, duration: number) {\n const isRtl = container.getAttribute('dir') === 'rtl';\n const { scrollLeft, offsetWidth: containerWidth, scrollWidth } = container;\n let path = left - scrollLeft;\n\n if (path < 0) {\n const remainingPath = -scrollLeft * (isRtl ? -1 : 1);\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 fastRaf(() => {\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}\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, forcePlaceCaretAtEnd?: 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 && !forcePlaceCaretAtEnd && (!lastChild || !lastChild.nodeValue)) {\n element.focus();\n return;\n }\n\n range.selectNodeContents(forcePlaceCaretAtEnd ? element : 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","export default function getKeyFromEvent(e: KeyboardEvent) {\n const key = 'key' in e ? e.key : e.code;\n\n return key.startsWith('Key') ? key.slice(3).toLowerCase() : key;\n}\n","const ELEMENT_NODE = 1;\n\nexport default function getMessageIdsForSelectedText() {\n const selection = window.getSelection();\n let selectedFragments = selection && selection.rangeCount ? selection.getRangeAt(0).cloneContents() : undefined;\n if (!selectedFragments || selectedFragments.childElementCount === 0) {\n return;\n }\n\n const messageIds = Array.from(selectedFragments.children)\n .reduce((result, node) => {\n if (node.nodeType === ELEMENT_NODE && node.classList.contains('message-date-group')) {\n return Array.from(node.querySelectorAll('.Message'))\n .reduce((acc, messageEl) => acc.concat(Number((messageEl as HTMLElement).dataset.messageId)), result);\n } else if (node.nodeType === ELEMENT_NODE && node.classList.contains('Message')) {\n return result.concat(Number((node as HTMLElement).dataset.messageId));\n }\n\n return result;\n }, [] as number[]);\n\n\n // Cleanup a document fragment because it is playing media content in the background\n while (selectedFragments.firstChild) {\n selectedFragments.removeChild(selectedFragments.firstChild);\n }\n selectedFragments = undefined;\n\n return messageIds;\n}\n","export type MediaSessionHandlers = {\n play?: () => void;\n pause?: () => void;\n stop?: () => void;\n\n previoustrack?: () => void;\n nexttrack?: () => void;\n\n togglemicrophone?: () => void;\n togglecamera?: () => void;\n hangup?: () => void;\n\n seekbackward?: (details: MediaSessionActionDetails) => void;\n seekforward?: (details: MediaSessionActionDetails) => void;\n seekTo?: ((details: MediaSessionActionDetails) => void);\n};\n\ninterface MediaMetadataParameters {\n title?: string;\n artist?: string;\n album?: string;\n artwork?: MediaImage[];\n}\n\nconst DEFAULT_HANDLERS = {\n play: undefined,\n pause: undefined,\n seekbackward: undefined,\n seekforward: undefined,\n previoustrack: undefined,\n nexttrack: undefined,\n stop: undefined,\n seekTo: undefined,\n};\n\nexport function registerMediaSession(metadata?: MediaMetadata, handlers?: MediaSessionHandlers) {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n if (metadata) updateMetadata(metadata);\n if (handlers) setMediaSessionHandlers(handlers);\n } else {\n // eslint-disable-next-line no-console\n console.warn('MediaSession API not supported in this browser');\n }\n}\n\nexport function updateMetadata(metadata?: MediaMetadata) {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n // eslint-disable-next-line no-null/no-null\n mediaSession.metadata = metadata ?? null;\n }\n}\n\nexport function setMediaSessionHandlers(handlers: MediaSessionHandlers) {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n Object.entries({ ...DEFAULT_HANDLERS, ...handlers }).forEach(([key, handler]) => {\n try {\n // @ts-ignore API not standardized yet\n mediaSession.setActionHandler(key, handler);\n } catch (err) {\n // Handler not supported, ignoring\n }\n });\n }\n}\n\nexport function clearMediaSession() {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n // eslint-disable-next-line no-null/no-null\n mediaSession.metadata = null;\n setMediaSessionHandlers(DEFAULT_HANDLERS);\n if (mediaSession.playbackState) mediaSession.playbackState = 'none';\n mediaSession.setPositionState?.();\n }\n}\n\nexport function setPlaybackState(state: 'none' | 'paused' | 'playing' = 'none') {\n const { mediaSession } = window.navigator;\n if (mediaSession && mediaSession.playbackState) {\n mediaSession.playbackState = state;\n }\n}\n\nexport function setPositionState(state?: MediaPositionState) {\n if (!state || state.position === undefined || state.duration === undefined) return;\n state.position = Math.min(state.position, state.duration);\n\n const { mediaSession } = window.navigator;\n mediaSession?.setPositionState?.(state);\n}\n\nexport function setMicrophoneActive(active: boolean) {\n const { mediaSession } = window.navigator;\n mediaSession?.setMicrophoneActive?.(active);\n}\n\nexport function setCameraActive(active: boolean) {\n const { mediaSession } = window.navigator;\n mediaSession?.setCameraActive?.(active);\n}\n\nexport function buildMediaMetadata({\n title, artist, album, artwork,\n}: MediaMetadataParameters) {\n if ('MediaMetadata' in window) {\n return new window.MediaMetadata({\n title,\n artist,\n album,\n artwork,\n });\n }\n return undefined;\n}\n","import { ApiMessageEntity, ApiMessageEntityTypes, ApiFormattedText } from '../api/types';\nimport { IS_EMOJI_SUPPORTED } from './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 nbsp's\n parsedHtml = parsedHtml.replace(/&nbsp;/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(\n /(^|\\s)(?!<code[^<]*|<\\/)[*]{2}([^*\\n]+)[*]{2}(?![^<]*<\\/code>)(\\s|$)/g,\n '$1<b>$2</b>$3',\n );\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<code[^<]*|<\\/)[_]{2}([^_\\n]+)[_]{2}(?![^<]*<\\/code>)(\\s|$)/g,\n '$1<i>$2</i>$3',\n );\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<code[^<]*|<\\/)[~]{2}([^~\\n]+)[~]{2}(?![^<]*<\\/code>)(\\s|$)/g,\n '$1<s>$2</s>$3',\n );\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<code[^<]*|<\\/)[|]{2}([^|\\n]+)[|]{2}(?![^<]*<\\/code>)(\\s|$)/g,\n `$1<span data-entity-type=\"${ApiMessageEntityTypes.Spoiler}\">$2</span>$3`,\n );\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: string | undefined;\n if (type === ApiMessageEntityTypes.TextUrl) {\n url = (node as HTMLAnchorElement).href;\n }\n if (type === ApiMessageEntityTypes.MentionName) {\n userId = (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","/*\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 audioEl.dataset.patchForSafariInProgress = 'true';\n function onProgress() {\n if (!audioEl.buffered.length) {\n return;\n }\n audioEl.currentTime = audioEl.duration - 1;\n audioEl.addEventListener('progress', () => {\n delete audioEl.dataset.patchForSafariInProgress;\n audioEl.currentTime = t;\n if (audioEl.paused && !audioEl.dataset.preventPlayAfterPatch) {\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 React from '../lib/teact/teact';\n\nconst stopEvent = (e: React.UIEvent | Event) => {\n e.stopPropagation();\n e.preventDefault();\n};\n\nexport default stopEvent;\n","let fileSelector: HTMLInputElement;\n\nexport function openSystemFilesDialog(accept = '*', callback: (e: Event) => void, noMultiple = false) {\n if (!fileSelector) {\n fileSelector = document.createElement('input');\n fileSelector.setAttribute('type', 'file');\n }\n\n fileSelector.setAttribute('accept', accept);\n\n if (noMultiple) {\n fileSelector.removeAttribute('multiple');\n } else {\n fileSelector.setAttribute('multiple', 'multiple');\n }\n\n // eslint-disable-next-line no-null/no-null\n fileSelector.onchange = null;\n fileSelector.value = '';\n fileSelector.onchange = callback;\n\n fileSelector.click();\n}\n"],"names":["memo","sticker","effect","isOwn","soundId","size","observeIntersection","lastSyncTime","forceLoadPreview","messageId","chatId","activeEmojiInteractions","markAnimationLoaded","isAnimationLoaded","ref","width","style","handleClick","playKey","useAnimatedEmoji","undefined","emoji","localMediaHash","id","isIntersecting","useIsIntersecting","thumbDataUri","thumbnail","dataUri","previewBlobUrl","useMedia","ApiMediaFormat","transitionClassNames","useMediaTransition","mediaData","isMediaLoaded","Boolean","className","buildClassName","LIKE_STICKER_ID","onClick","src","alt","key","animationData","quality","play","forceOnHeavyAnimation","noLoop","onLoad","renderWaveform","canvas","spikes","progress","peak","fillStyle","progressFillStyle","length","height","ctx","getContext","scale","forEach","item","i","globalAlpha","spikeHeight","Math","max","x","y","radius","beginPath","moveTo","arcTo","closePath","roundedRectangle","fill","decodeWaveform","encoded5bit","bitsCount","valuesCount","floor","result","Array","bitsData","l","byteIndex","bitShift","value","lastByteIndex","lastBitShift","lastValue","interpolateArray","data","fitCount","newData","springFactor","leftFiller","rightFiller","idx","val","MIN_SPIKES","IS_SINGLE_COLUMN_LAYOUT","MAX_SPIKES","renderSeekline","playProgress","bufferedProgress","seekerRef","theme","message","senderTitle","uploadProgress","origin","date","isSelectable","isSelected","isDownloading","onPlay","onReadMedia","onCancelUpload","onDateClick","content","audio","voice","video","isMediaUnread","isVoice","isSeeking","useRef","playStateBeforeSeeking","lang","useLang","isRtl","dispatch","getDispatch","isActivated","setIsActivated","useState","shouldLoad","coverHash","getMessageMediaHash","coverBlobUrl","getMessageMediaFormat","loadProgress","downloadProgress","useMediaWithLoadProgress","handleForcePlay","useCallback","handleTrackChange","isBuffered","bufferingHandlers","checkBuffering","useBuffering","isPlaying","playPause","pause","setCurrentTime","duration","useAudioPlayer","makeTrackId","getMediaDuration","isMessageLocal","isOwnMessage","waveformCanvasRef","canvasRef","useMemo","waveform","min","durationFactor","spikesCount","round","Uint8Array","useLayoutEffect","current","useWaveformCanvas","withSeekline","useEffect","isLoadingForPlaying","isUploading","isTransferring","transferProgress","getMediaTransferState","shouldRender","shouldRenderSpinner","spinnerClassNames","useShowTransition","shouldRenderCross","handleButtonClick","setAudioPlayerOrigin","handleDownloadClick","cancelMessageMediaDownload","downloadMessageMedia","handleSeek","e","left","getBoundingClientRect","clientX","MouseEvent","targetTouches","stopPropagation","handleStartSeek","button","handleStopSeek","handleDateClick","renderFirstLine","title","fileName","captureEvents","onCapture","onRelease","onDrag","fullClassName","AudioOrigin","buttonClassNames","push","contentClassName","renderWithTitle","dir","renderText","Link","formatPastTimeShort","formatMediaDuration","performer","renderSecondLine","Button","ripple","color","join","ariaLabel","backgroundImage","ProgressSpinner","transparent","noCross","showProgress","showSeekline","getTranslation","getFileSizeString","formatMediaDateTime","renderAudio","draggable","renderVoice","withGlobal","global","chatOrUserId","countryList","phoneCodes","phoneCodeList","chat","selectChat","user","isUserId","selectUser","isMuted","selectIsChatMuted","selectNotifySettings","selectNotifyExceptions","canInviteUsers","isChatChannel","isUserRightBanned","getHasAdminRight","forceShowSelf","loadFullUser","showNotification","updateChatMutedState","userId","fullInfo","username","phoneNumber","isSelf","handleNotificationChange","isRestricted","copy","text","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","getChatTitle","handleDeleteMessageForAll","shouldDeleteForAll","handleDeleteAndStop","contactId","accessHash","handleDeleteChat","isCreator","handleLeaveChat","header","isSavedMessages","isText","smaller","canAutoLoad","autoLoadFileMaxSizeMb","withDate","datetime","sender","onMediaClick","document","timestamp","extension","getDocumentExtension","wasIntersected","markIntersected","useFlag","isLoadAllowed","setIsLoadAllowed","shouldDownload","documentHash","isLoaded","hasPreview","getDocumentHasPreview","getMessageMediaThumbDataUri","localBlobUrl","previewData","withMediaViewer","mediaType","name","thumbnailDataUri","actionIcon","isMessageDocumentVideo","elementRef","shouldSpinnerRender","getColorFromExtension","sizeString","getDocumentThumbnailDimensions","onlineCount","selectChatOnlineCount","areMessagesLoaded","selectChatMessages","typingStatus","avatarSize","status","withDots","withUsername","withFullInfo","withUpdatingStatus","withChatType","noRtl","loadFullChat","openMediaViewer","isMin","handleAvatarViewerOpen","hasPhoto","avatarOwnerId","MediaViewerOrigin","isVerified","getChatTypeString","handle","groupStatus","chatTypeString","membersCount","getGroupStatus","onlineStatus","renderStatusOrTyping","outgoingStatus","idPrefix","isProtected","mediaBlobUrl","getMessageVideo","getMessageHtmlId","decoding","onContextMenu","stopEvent","isGif","Keys","activeKey","DEFAULT_TEXT","itemIds","selectedIds","filterValue","filterPlaceholder","notFoundText","searchInputId","isLoading","noScrollRestore","onSelectedIdsChange","onFilterChange","onLoadMore","inputRef","shouldMinimize","setTimeout","requestAnimationFrame","focus","handleItemClick","newSelectedIds","includes","splice","indexOf","handleFilterChange","currentTarget","viewportIds","getMore","useInfiniteScroll","map","isMinimized","canClose","clickArg","onChange","placeholder","items","iconElement","titleText","serverTimeOffset","userStatus","selectUserStatus","noStatusOrTyping","fullName","getUserFullName","isUserOnline","getUserStatus","photo","isFirstPhoto","isDeleted","isDeletedUser","isRepliesChat","isChatWithRepliesBot","getMediaHash","forceAvatar","hash","getChatAvatarHash","photoBlobUrl","avatarMediaHash","avatarBlobUrl","useBlurSync","imageSrc","prevImageSrc","usePrevious","userFullName","getFirstLetters","Spinner","getUserColorKey","connectionState","animationLevel","settings","byKey","photos","slideAnimation","currentPhotoIndex","setCurrentPhotoIndex","isFirst","isLast","profile","currentIndex","slice","mediaLoader","usePhotosPreload","handleProfilePhotoClick","profilePhotoIndex","selectPreviousMedia","selectNextMedia","element","querySelector","selectorToPreventScroll","onSwipe","IS_TOUCH_ENV","direction","SwipeDirection","isVerifiedIconShown","_","renderPhotoTabs","Transition","renderPhoto","type","VerifiedIcon","reaction","staticIconId","getGlobal","availableReactions","find","staticIcon","noAnimate","onUnfaveClick","stickerSelector","shouldPlay","lottieData","isLottie","isLottieLoaded","markLoaded","unmarkLoaded","canLottiePlay","isVideo","IS_WEBM_SUPPORTED","videoBlobUrl","canVideoPlay","previewTransitionClassNames","safePlay","onMouseDown","preventMessageInputBlurWithBubbling","autoPlay","loop","playsInline","muted","isLowPriority","preventDefault","props","StickerSetModal","useModuleLoader","Bundles","typingUser","typingUserName","action","replace","trim","onMessageClick","linkData","getMessageWebPage","getFirstLinkInMessage","url","domain","siteName","formattedDescription","getMessageText","renderMessageSummary","handleMessageClick","displayUrl","truncatedDescription","trimText","MEDIA_VIEWER_MEDIA_QUERY","REM","parseInt","getComputedStyle","documentElement","fontSize","ROUND_VIDEO_DIMENSIONS_PX","AVATAR_FULL_DIMENSIONS","DEFAULT_MEDIA_DIMENSIONS","cachedMaxWidthOwn","cachedMaxWidth","cachedMaxWidthNoAvatar","getAvailableWidth","fromOwnMessage","isForwarded","isWebPagePhoto","noAvatars","extraPaddingRem","availableWidthRem","regularMaxWidth","windowWidth","windowSize","getMaxMessageWidthRem","calculateDimensionsForMessageMedia","aspectRatio","availableWidth","availableHeight","getAvailableHeight","mediaWidth","calculateDimensions","getMediaViewerAvailableDimensions","withFooter","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","mediaHeight","calculatedWidth","WIDTH","large","medium","small","localEffect","interactWithAnimatedEmoji","sendEmojiInteraction","sendWatchingEmojiInteraction","hasEffect","audioRef","soundMediaData","setPlayKey","String","random","interactions","startedInteractions","sendInteractionBunch","remove","Audio","addEventListener","once","container","startSize","isReversed","performance","now","interactionMessageId","emoticon","selectLocalAnimatedEmojiEffectByName","ChatFolderModal","ChatAnimationTypes","isPinned","isShown","unreadCount","hasUnreadMark","ShowTransition","isCustom","unreadMentionsCount","formatIntegerCompact","isActive","lastMessage","senderId","replyToMessageId","isOutgoing","lastMessageSender","lastMessageAction","getMessageAction","actionTargetMessage","selectChatMessage","targetUserIds","actionTargetUserIds","targetChatId","actionTargetChatId","privateChatUserId","currentChatId","threadId","currentThreadId","messageListType","selectCurrentMessageList","MAIN_THREAD_ID","draft","selectDraft","canScrollDown","canChangeFolder","chatFolders","orderedIds","lastMessageOutgoingStatus","selectOutgoingStatus","folderId","orderDiff","animationType","openChat","focusLastMessage","isDeleteModalOpen","openDeleteModal","closeDeleteModal","isChatFolderModalOpen","openChatFolderModal","closeChatFolderModal","shouldRenderDeleteModal","markRenderDeleteModal","unmarkRenderDeleteModal","shouldRenderChatFolderModal","markRenderChatFolderModal","unmarkRenderChatFolderModal","isAction","isActionMessage","useEnsureMessage","mediaThumbnail","getMessageSticker","isRoundVideo","getMessageRoundVideo","actionTargetUsers","usersById","users","byId","filter","Opacity","opacity","fastRaf","classList","add","Move","transform","ANIMATION_END_DELAY","shouldReplaceHistory","contextActions","useChatContextActions","handleDelete","handleChatFolderChange","ListItem","Avatar","isCallActive","isCallNotEmpty","LastMessageMeta","TypingStatus","isChat","renderActionMessageText","asTextWithSpoilers","senderName","getMessageSenderName","blobUrl","renderSummary","renderLastMessageOrTyping","DeleteChatModal","folderType","chatFolder","selectChatFolder","animatedEmoji","selectAnimatedEmoji","foldersDispatch","onScreenSelect","handleEditFolder","payload","SettingsScreens","AnimatedEmoji","fluid","pill","openNextChat","resolvedFolderId","ALL_FOLDER_ID","ARCHIVED_FOLDER_ID","useFolderManagerForOrderedIds","orderById","reduce","acc","prevOrderById","orderDiffById","mapValues","order","CHAT_LIST_SLICE","handleKeyDown","removeEventListener","IS_PWA","IS_MAC_OS","metaKey","ctrlKey","code","startsWith","digit","match","position","Number","altKey","targetIndexDelta","getAnimationType","orderDiffs","Object","values","numberOfUp","diff","numberOfDown","None","Infinity","useChatAnimationType","InfiniteScroll","preloadBackwards","withAbsolutePositioning","maxHeight","CHAT_HEIGHT_PX","viewportOffset","pinnedCount","getPinnedChatsCount","teactOrderKey","renderChats","Loading","getSenderName","chatsById","getSenderTitle","isChatGroup","CustomSend","isQuick","onFileSelect","isHovered","markHovered","unmarkHovered","onDrop","onDragEnter","onDragLeave","relatedTarget","toTarget","DropAreaState","withQuick","onHide","hideTimeoutRef","prevWithQuick","captureEscKeyListener","handleFilesDrop","async","dataTransfer","dt","files","folderFiles","getFilesFromDataTransferItems","concat","from","handleQuickFilesDrop","handleDragLeave","target","fromTarget","Portal","containerId","onDragOver","clearTimeout","EmojiTooltip","MAX_INPUT_HEIGHT","messageSendKeyCombo","replyingToId","selectReplyingToId","noTabCapture","isPollModalOpen","payment","isPaymentModalOpen","isAttachmentModalInput","editableInputId","html","forcedPlaceholder","canAutoFocus","shouldSuppressFocus","shouldSuppressTextFormatter","onUpdate","onSuppressedFocus","onSend","editLastMessage","replyToNextMessage","cloneRef","isContextMenuOpenRef","isTextFormatterOpen","openTextFormatter","closeTextFormatter","textFormatterAnchorPosition","setTextFormatterAnchorPosition","selectedRange","setSelectedRange","sendMessageAction","useSendMessageAction","updateInputHeight","useLayoutEffectWithPrevDeps","prevHtml","innerHTML","focusInput","isHeavyAnimating","focusEditableElement","handleCloseTextFormatter","selection","getSelection","removeAllRanges","empty","clearSelection","checkSelection","IS_IOS","rangeCount","selectionRange","getRangeAt","selectedText","toString","isSelectionInsideInput","EDITABLE_INPUT_ID","parseEmojiOnlyString","START_TO_END","processSelection","selectionRect","inputRect","top","willSend","input","clone","currentHeight","newHeight","scrollHeight","transitionDuration","log","abs","exec","toggle","captureFirstTab","debounce","captureKeyboardListeners","onTab","suppressFocus","blur","contentEditable","textContent","IS_EMOJI_SUPPORTED","onKeyDown","shiftKey","handleKeyUp","IS_ANDROID","event","closeContextMenuMouseListener","closeContextMenuKeyListener","handleMouseUp","onTouchCancel","anchorPosition","TEXT_FORMAT_BY_TAG_NAME","B","STRONG","I","EM","U","DEL","CODE","SPAN","fragmentEl","createElement","containerRef","linkUrlInputRef","isLinkControlOpen","openLinkControl","closeLinkControl","linkUrl","setLinkUrl","isEditingLink","setIsEditingLink","inputClassName","setInputClassName","selectedTextFormats","setSelectedTextFormats","useVirtualBackdrop","selectedFormats","parentElement","commonAncestorContainer","textFormat","tagName","updateSelectedRange","getSelectedText","innerText","getSelectedElement","updateInputStyles","offsetWidth","scrollWidth","scrollLeft","getFormatButtonClassName","keys","some","fKey","monospace","strikethrough","handleSpoilerText","spoiler","dataset","entityType","ApiMessageEntityTypes","replaceWith","execCommand","handleBoldText","bold","handleItalicText","italic","handleUnderlineText","underline","handleStrikethroughText","handleMonospaceText","handleLinkUrlConfirm","formattedLinkUrl","encodeURI","ensureProtocol","href","addRange","restoreSelection","handler","k","b","u","m","s","p","getKeyFromEvent","linkUrlConfirmClassName","autoComplete","inputMode","onScroll","dataTransferItems","traverseFileTreePromise","entry","Promise","resolve","File","isFile","itemFile","getAsFile","file","isDirectory","createReader","readEntries","entries","entriesPromises","entr","all","kind","webkitGetAsEntry","RE_BR","RE_SPACE","RE_CLEAN_HTML","RE_EXTRA_NEW_LINE","prepareForRegExp","inputId","parentNode","iterations","cache","WeakMap","memoized","fn","cached","get","args","areSortedArraysEqual","lastArgs","lastResult","set","emojiDataPromise","emojiRawData","emojiData","RE_EMOJI_SEARCH","prepareRecentEmojisMemo","recentEmojiIds","limit","pickTruthy","MEMO_EMPTY_ARRAY","prepareLibraryMemo","baseEmojiKeywords","emojiKeywords","emojis","byNative","buildCollectionByKey","baseEmojisByKeyword","natives","emojisByKeyword","byKeyword","keywords","byName","names","searchInLibraryMemo","library","matched","matchedKeywords","keyword","sort","flatten","matchedNames","unique","RegExp","useEmojiTooltip","isAllowed","htmlRef","onUpdateHtml","isDisabled","markIsOpen","unmarkIsOpen","setById","shouldForceInsertEmoji","setShouldForceInsertEmoji","filteredEmojis","setFilteredEmojis","ensureEmojiData","then","getEmojiCode","forceSend","endsWith","substr","insertEmoji","textEmoji","isForce","currentHtml","atIndex","lastIndexOf","messageInput","getElementById","native","isEmojiTooltipOpen","closeEmojiTooltip","default","uncompressEmoji","runThrottled","throttle","cb","RE_USERNAME_SEARCH","useMentionTooltip","canSuggestMembers","groupChatMembers","topInlineBotIds","usersToMention","setUsersToMention","updateFilteredUsers","withInlineBots","memberIds","member","filteredIds","filterUsersByName","usernameFilter","getUsernameFilter","canSuggestInlineBots","insertMention","forceFocus","insertedHtml","isMentionTooltipOpen","closeMentionTooltip","mentionFilteredUsers","useAsyncRendering","dependencies","delay","shouldRenderRef","timeoutRef","forceUpdate","useForceUpdate","useOnChange","options","selected","disabled","loadingOptions","setValues","handleChange","newValues","v","option","subLabel","children","buttonClassName","tabIndex","buttonRef","secondaryIcon","destructive","onSecondaryIconClick","isTouched","markIsTouched","unmarkIsTouched","isContextMenuOpen","contextMenuPosition","handleBeforeContextMenu","handleContextMenu","handleContextMenuClose","handleContextMenuHide","useContextMenuHandlers","getTriggerElement","getRootElement","closest","getMenuElement","positionX","positionY","transformOriginX","transformOriginY","menuStyle","useContextMenuPosition","handleSecondaryIconClick","handleMouseDown","role","autoClose","DEFAULT_DURATION","onDismiss","setIsOpen","timerRef","closeAndDismiss","handleMouseEnter","handleMouseLeave","onMouseEnter","onMouseLeave","RADIUSES","xl","square","circleRadius","STROKE_WIDTH","borderRadius","circumference","PI","svg","firstElementChild","strokeDashOffset","setAttribute","hidden","loadingOption","step","renderValue","trackWidth","index","parentContainerClassName","focused","spinnerColor","spinnerBackgroundColor","autoFocusSearch","onReset","onFocus","onBlur","onSpinnerClick","isInputFocused","markInputFocused","unmarkInputFocused","useInputFocusOnOpen","backgroundColor","prevIsOpen","prevChildren","fromChildrenRef","noAnimation","onCheck","classNames","badgeCount","isBadgeActive","previousActiveTab","tabRef","tabEl","prevTabEl","platformEl","prevPlatformEl","shiftLeft","offsetLeft","scaleFactor","clientWidth","forceReflow","SCROLL_DURATION","tabs","activeTab","big","onSwitchTab","useHorizontalScroll","activeTabElement","childNodes","activeTabOffsetLeft","activeTabOffsetWidth","newLeft","fastSmoothScrollHorizontal","tab","renderCount","shouldRestoreHeight","shouldCleanup","cleanupExceptionKey","onStart","onStop","currentKeyRef","rendersRef","prevActiveKey","activeKeyChanged","cleanup","preservedRender","childElements","transition","isBackwards","prevActiveIndex","activeIndex","toSlide","fromSlide","ANIMATION_LEVEL_MIN","dispatchHeavyAnimationStop","dispatchHeavyAnimationEvent","waitForTransitionEnd","clientHeight","performSlideOptimized","node","HTMLElement","onAnimationEnd","activeElement","watchedNode","firstChild","waitForAnimationEnd","flexBasis","renders","contents","render","teactFastList","INCLUDED_CHAT_TYPES","EXCLUDED_CHAT_TYPES","INCLUDE_FILTER_FIELDS","EXCLUDE_FILTER_FIELDS","selectChatFilters","state","mode","selectTemp","selectedChatIds","selectedChatTypes","includedChatIds","includeFilters","pick","folder","excludedChatIds","excludeFilters","getSuggestedFolderName","filters","bots","groups","channels","contacts","nonContacts","INITIAL_STATE","chatFilter","foldersReducer","omit","error","useReducer","makeMediaHandlers","controllerRef","mediaHandlers","proxy","requestNextTrack","requestPreviousTrack","stop","closeAudioPlayer","seekbackward","skipTime","seekOffset","currentTime","seekforward","seekTo","seekTime","nexttrack","previoustrack","trackId","originalDuration","trackType","handlers","metadata","onInit","onForcePlay","onTrackChange","noPlaylist","noProgressUpdates","setIsPlaying","isPlayingSync","setPlayProgress","register","eventName","setVolume","setPlaybackRate","toggleMuted","registerMediaSession","setPlaybackState","audioPlayer","volume","playbackRate","setPositionState","isFinite","paused","updateMetadata","destroy","isSafariPatchInProgress","useEffectWithPrevDeps","prevShouldPlay","prevSrc","playIfPresent","setTime","time","audioProxy","Map","blurredRef","isChanged","img","Image","imgToCanvas","fastBlur","toDataURL","blurredAsync","onload","blurredDataUri","clear","useBlur","noInitiallyBuffered","setIsBuffered","setBufferedProgress","setIsBufferedDebounced","handleBuffering","media","buffered","end","readyState","onLoadedData","onPlaying","onLoadStart","onPause","onTimeUpdate","onProgress","useCanvasBlur","withRaf","processBlur","alpha","IS_CANVAS_FILTER_SUPPORTED","drawImage","RADIUS","isInSearch","isServiceNotifications","SERVICE_NOTIFICATIONS_USER_ID","toggleChatPinned","toggleChatArchived","toggleChatUnread","actionAddToFolder","actionPin","compact","actionUnreadMark","actionMute","actionArchive","isChatArchived","actionDelete","getCanDeleteChat","isInFolder","stopImmediatePropagation","isMenuDisabled","shouldDisableOnLink","shouldDisableOnLongTap","setIsContextMenuOpen","setContextMenuPosition","clientY","body","timer","clearLongPressTimer","startLongPressTimer","contains","originalEvent","touches","cancelClickOnce","emulateContextMenuEvent","passive","EMPTY_RECT","anchor","getLayout","setPositionX","setPositionY","setTransformOriginX","setTransformOriginY","withScroll","setWithScroll","setStyle","setMenuStyle","triggerEl","anchorX","anchorY","menuEl","rootEl","extraPaddingX","extraTopPadding","marginSides","extraMarginTop","marginTop","menuRect","offsetHeight","rootRect","horizontalPosition","verticalPosition","triggerRect","menuMaxHeight","offsetX","offsetY","useDebounce","ms","noFirst","noLast","replyOriginForId","loadMessage","loadMessageThrottled","throttled","setOrderedIds","getOrderedIds","addOrderedIdsCallback","useFolderManagerForUnreadCounters","unreadCounters","setUnreadCounters","getUnreadCounters","addUnreadCountersCallback","useFolderManagerForChatsCount","chatsCount","setChatsCount","getChatsCount","addChatsCountCallback","handleScroll","deltaX","deltaY","useIntersectionObserver","rootCallback","rootRef","throttleMs","debounceMs","shouldSkipFirst","margin","threshold","rootCallbackRef","freezeFlagsRef","onUnfreezeRef","freeze","unfreeze","useHeavyAnimationCheck","observer","disconnect","callbacks","observe","targetCallback","entriesAccumulator","observerCallbackSync","callback","scheduler","observerCallback","IntersectionObserver","root","rootMargin","initController","controller","delete","unobserve","useOnIntersect","targetRef","setIsIntersecting","savedCallback","setInterval","clearInterval","debugKey","prevDeps","isMediaReady","store","idRef","generateIdFor","mediaHash","noLoad","mediaFormat","cacheBuster","isHtmlAllowed","isStreaming","IS_PROGRESSIVE_SUPPORTED","useUniqueId","setLoadProgress","startedAtRef","handleProgress","Date","spentTime","closeTimeout","useMouseInside","menuCloseTimeout","isMouseInside","markMouseInside","usePrevDuringAnimation","prev","isCurrentPresent","isPrevPresent","reducer","initialState","reducerRef","setState","currentState","SEND_MESSAGE_ACTION_INTERVAL","useStateRef","useVideoCleanup","videoRef","videoEl","load","mul_table","shg_table","boxBlurCanvasRGB","context","top_x","top_y","isNaN","imageData","getImageData","pixels","rsum","gsum","bsum","p1","p2","yp","yi","yw","wm","hm","rad1","r","g","mul_sum","shg_sum","vmin","vmax","putImageData","tracks","currentTrackId","voiceQueue","musicQueue","playNext","isReverseOrder","currentTrack","nextTrackId","findNextInQueue","has","openAudioPlayer","parseMessageKey","splitTrackId","messageKey","nextTrack","stopCurrentAudio","track","handleEvent","Proxy","createAudio","trackIdComparator","addTrackToQueue","preventPlayAfterPatch","preload","IS_SAFARI","patchSafariProgressiveAudio","globalSearch","currentContent","GlobalSearchContent","openedChatId","queueFilter","cleanUpQueue","fastSeek","rate","shouldRemoveFromQueue","h","trackIdFilter","el","removeFromQueue","getTrackQueue","currentId","queue","chatAudio","getMessageKey","split","pop","one","two","dateOne","keyOne","dateTwo","keyTwo","localeCompare","IOS_SCREEN_EDGE_THRESHOLD","getDistance","a","sqrt","pageX","pageY","getTouchCenter","lastClickTime","captureEvent","initialSwipeAxis","hasMoved","hasSwiped","initialDistance","initialTouchCenter","innerWidth","innerHeight","excludedClosestSelector","onMove","withCursor","querySelectorAll","scrollable","overflow","onDoubleClick","centerX","centerY","onZoom","endDistance","touchCenter","dragOffsetX","dragOffsetY","zoomFactor","initialCenterX","initialCenterY","currentCenterX","currentCenterY","shouldPreventScroll","xAbs","yAbs","axis","currentSwipeAxis","Left","Right","Up","Down","processSwipe","isNotPassive","propertyName","waitForEndEvent","animationName","eventType","detailedName","isHandled","handleAnimationEnd","TransitionEvent","AnimationEvent","cycleRestrict","isAnimating","fastSmoothScroll","maxDistance","FAST_SMOOTH_MAX_DISTANCE","forceDirection","forceDuration","forceNormalContainerHeight","scrollFrom","calculateScrollFrom","FocusDirection","scrollWithJs","isAnimatingScroll","offsetTop","elementTop","scrollTop","offset","elementHeight","currentScrollTop","containerHeight","targetContainerHeight","normalHeight","path","remainingPath","absPath","FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE","shortTransition","longTransition","FAST_SMOOTH_MIN_DURATION","FAST_SMOOTH_MAX_DURATION","startAt","onHeavyAnimationStop","animateSingle","t","currentPath","getAttribute","containerWidth","animate","force","forcePlaceCaretAtEnd","range","createRange","lastChild","nodeValue","selectNodeContents","collapse","toLowerCase","getMessageIdsForSelectedText","selectedFragments","cloneContents","childElementCount","messageIds","nodeType","messageEl","removeChild","DEFAULT_HANDLERS","mediaSession","navigator","setMediaSessionHandlers","console","warn","setActionHandler","err","clearMediaSession","playbackState","buildMediaMetadata","artist","album","artwork","MediaMetadata","ENTITY_CLASS_BY_NODE_NAME","S","STRIKE","PRE","BLOCKQUOTE","parseMessageInput","fragment","parsedHtml","parseMarkdown","textIndex","recursionDeepness","entities","addEntity","rawText","nodeName","getEntityTypeFromNode","rawIndex","substring","getEntityDataFromNode","hasChildNodes","audioEl","patchedForSafari","patchForSafariInProgress","fileSelector","openSystemFilesDialog","accept","noMultiple","removeAttribute","onchange","click"],"sourceRoot":""}