phanpy-cz/assets/compose-_xw4e_c5.js.map
2024-12-08 17:19:23 +01:00

1 line
223 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,"mappings":"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","names":["Combobox","input","list","tabInsertsSuggestions","defaultFirstOption","event","keyboardBindings","trackComposition","commitWithElement","_a","visible","indexDiff","focusEl","els","focusIndex","indexOfItem","newIndex","target","el","scrollTo","combobox","commit","fireCommitEvent","container","inViewport","element","scrollTop","containerBottom","top","bottom","boundary","query","text","key","cursor","multiWord","lookBackIndex","lastMatchPosition","keyIndex","pre","CustomHTMLElement","InputStyleCloneUpdateEvent","CloneRegistry","_InputStyleCloneElement","__privateAdd","_InputStyleCloneElement_instances","_styleObserver","__privateMethod","updateStyles_fn","_resizeObserver","requestUpdateLayout_fn","_inputRef","_container","_xOffset","_yOffset","_isLayoutUpdating","_onInput","updateText_fn","_onDocumentScrollOrResize","usingInput_fn","clone","__privateSet","__privateGet","input_get","fn","updateLayout_fn","inputStyle","inputRect","cloneRect","prop","propertiesToCopy","InputStyleCloneElement","e","_InputRange","startOffset","endOffset","_InputRange_instances","_inputElement","_startOffset","_endOffset","selectionStart","selectionEnd","offset","clampOffset_fn","toStart","createCloneRange_fn","styleClone_get","cloneElement_get","range","textNode","InputRange","states","TextExpander","expander","match","menu","_b","position","caretRect","targetPosition","currentPosition","delta","currentStyle","item","beginning","remaining","detail","suffix","value","found","providers","provide","result","x","TextExpanderElement","keysAttr","keys","multiWordAttr","globalMultiWord","state","ansiRegex","onlyFirst","pattern","regex","stripAnsi","string","segmenter","stringLength","countAnsiEscapeCodes","length","_","poweredByGiphyURL","PHANPY_IMG_ALT_API_URL","IMG_ALT_API_URL","PHANPY_GIPHY_API_KEY","GIPHY_API_KEY","import","supportedLanguagesMap","supportedLanguages","reduce","acc","l","code","common","native","expiryOptions","i18nDuration","expirySeconds","Object","oneDay","expiresInFromExpiresAt","expiresAt","Date","getTime","now","find","s","document","createElement","role","className","windowMargin","observer","IntersectionObserver","entries","forEach","entry","isIntersecting","left","width","boundingClientRect","innerWidth","window","insetInlineStart","isRTL","style","observe","DEFAULT_LANG","localeMatch","Intl","DateTimeFormat","resolvedOptions","locale","navigator","languages","map","urlRegexObj","RegExp","urlRegex","source","flags","usernameRegex","urlPlaceholder","countableText","inputText","replace","USERNAME_RE","MENTION_RE","HASHTAG_RE","SHORTCODE_RE_FRAGMENT","SCAN_RE","Segmenter","escapeHTML","highlightText","maxCharacters","Infinity","composerCharacterCount","withinLimitHTML","exceedLimitHTML","htmlSegments","segment","index","RTF","mem","RelativeTimeFormat","undefined","LF","ListFormat","CUSTOM_EMOJIS_COUNT","ADD_LABELS","media","id","customEmoji","gif","poll","Compose","onClose","replyToStatus","editStatus","draftStatus","standalone","hasOpener","i18n","useLingui","rtf","lf","console","masto","instance","uiState","setUIState","useState","UID","uid","log","currentAccount","currentAccountInfo","maxMediaAttachments","charactersReservedPerUrl","imageMatrixLimit","supportedMimeTypes","imageSizeLimit","videoSizeLimit","videoMatrixLimit","videoFrameRateLimit","maxExpiration","maxOptions","maxCharactersPerOption","minExpiration","spoilerTextRef","useRef","textareaRef","store","prevLanguage","language","sensitive","setMediaAttachments","setLanguage","oninputTextarea","account","focusTextarea","dispatchEvent","setTimeout","spoilerText","useEffect","visibility2","language2","sensitive2","visibility","current","m","allMentions","prefs","setSensitive","poll2","mediaAttachments","options","expiresIn","statusSource","dataset","mediaAttachments2","setVisibility","composablePoll","status","o","formRef","canClose","hasValue","hasMediaAttachments","isSelf","hasOnlyAcct","confirmClose","hasIDMediaAttachments","beforeUnloadCopy","handleBeforeUnload","sameWithSource","getCharCount","updateCharCount","supportsCloseWatcher","useHotkeys","yes","addEventListener","capture","modals","hasModal","hasOnlyComposer","prevBackgroundDraft","count","escDownRef","ignoreEventWhen","useCloseWatcher","draftKey","getCurrentAccountNS","backgroundDraft","useInterval","db","handleItems","username","acct","i2","items","unsupportedFiles","i18n2","drafts","set","updatedAt","f","debug","error","files","clipboardData","max","file","alert","mediaFiles","allowedFiles","1","2","handleDragover","setShowMentionPicker","showEmoji2Picker","showGIFPicker","useMemo","contentTranslationHideLanguages","autoDetectedLanguages","topLanguages","restLanguages","commonB","type","size","url","codeA","commonA","codeB","onMinimize","saveUnsavedDraft","gifPickerDisabled","onPollButtonClick","setPoll","removeEventListener","addSubToolbarRef","setShowAddButton","useResizeObserver","showMentionPicker","scrollWidth","settings","push","_jsxs","sort","_jsx","AccountBlock","showPollButton","pollButtonDisabled","children","class","confirmText","passData","__STATES__","opener","composerState","Icon","openCompose","showAddButton","avatarStatic","disabled","onClick","Status","replyToStatusMonthsAgo","Trans","formData","components","0","onKeyDown","onSubmit","description","params2","res","attachment","results","mediaPromises","hasNoDescriptions","params","removeNullUndefined","newStatus","saveStatus","i","e2","media_attributes","in_reply_to_id","statuses","visibilityIconsMap","opacity","pointerEvents","checked","onChange","icon","title","limit","action","setShowEmoji2Picker","setAutoDetectedLanguages","Textarea","ref","placeholder","fileID","newAttachments","attachments","_2","j","performSearch","q","v1","resolve","v2","fetch","onTrigger","defaultSearchTerm","Poll","newPoll","onDescriptionChange","Menu2","open","MenuItem","FilePickerInput","onInput","setShowGIFPicker","body","zIndex","_Fragment","Loader","CharCountMeter","alt","localeCode2Text","commonText","composerGIFPicker","restSupportedLanguages","textarea","textBeforeMention","spaceAfterMention","textAfterMention","newText","Modal","CustomEmojisModal","textBeforeEmoji","textAfterEmoji","spaceBeforeEmoji","emojiShortcode","spaceAfterEmoji","onSelect","GIFPickerModal","alt_text","slice","theToast","showToast","blob","newMediaAttachments","hidden","then","autoResizeTextarea","offsetHeight","scrollHeight","clientHeight","height","visibleEmojis","__vitePreload","langs","detectAll","lang","setText","textareaProps","searcherRef","getCustomEmojis","r","searcher","handleChange","text2","_getCustomEmojis","emojis","filter","Fuse","matchesArg","cacheKeyArg","emoji","detectLangs","shortcode","encodeHTML","forwardRef","html","props","textExpanderTextRef","history","displayNameWithEmoji","emojifyText","displayName","search","total","cur","name","shortenNumber","Promise","matched","v","more","textExpanderRef","handleValue","handleCommited","slowHighlightPerf","composeHighlightRef","start","end","debouncedAutoDetectLanguage","useDebouncedCallback","dom","mark","resizeObserver","throttleHighlightText","lastLine","bullet","postSpaces","anything","number","newBullet","pos","dir","rows","cols","charCount","leftChars","ctrlKey","setRangeText","setSelectionRange","scaleDimension","matrix","matrixLimit","scalingFactor","newHeight","newWidth","MediaAttachment","supportsEdit","supports","onScroll","configuration","getCurrentInstanceConfiguration","maxError","setMaxError","checkMaxError","snapStates","imageMatrix","Math","videoMatrix","setDescription","debouncedOnDescriptionChange","timer","details","setImageMatrix","setVideoMatrix","toastRef","showModal","imageSizeLimit2","descTextarea","prettyBytes","videoSize","videoSizeLimit2","videoMatrixLimit2","videoMatrix2","maxErrorToast","maxErrorText","err","imageSize","suffixType","naturalWidth","naturalHeight","3","videoWidth","videoHeight","values","setShowModal","src","onLoad","onLoadedMetadata","onRemove","subtype","response","menuButton","append","multiple","option","required","label","splice","str","char","obj","MentionModal","api","accounts","setAccounts","relationshipsMap","setRelationshipsMap","setSelectedIndex","accounts2","fetchRelationships","relationships","loadAccounts","inputRef","filterShortcodes","searchTerm","bLower","aStartsWith","bStartsWith","aContains","bothContain","bContains","socialAddress","selectedAccount","selectedIndex","selectAccount","listRef","selectedItem","loadRelationships","term","debouncedLoadAccounts","enableOnFormTags","relationship","customEmojisList","recentlyUsedCustomEmojis","customEmojisCatList","emojisCat","customEmojis","othersCat","matches","setMatches","_c","scrollableRef","onFind","onSelectEmoji","useCallback","recentlyUsedCustomEmojis2","recentlyUsedEmojiIndex","emoji2","setCustomEmojis","category","queueMicrotask","CustomEmojisList","memo","setMax","CustomEmojiButton","showMore","showCode","parent","selfRect","rect","targetClassList","addEdges","GIFS_PER_PAGE","fetchGIFs","qRef","closest","currentTarget","remove","debouncedOnInput","onPointerEnter","staticUrl","decoding","setResults","currentOffset","images","fixed_height_small","fixed_height_downsampled","fixed_height","theImage","webp","urlObj","strippedURL","strippedWebP","preventDefault","original","theURL","mp4","url2","strippedURL2","webpObj","parse"],"ignoreList":[0,1,2,3,4],"sources":["../../node_modules/@github/combobox-nav/dist/index.js","../../node_modules/@github/text-expander-element/dist/index.js","../../node_modules/ansi-regex/index.js","../../node_modules/strip-ansi/index.js","../../node_modules/string-length/index.js","../../src/assets/powered-by-giphy.svg","../../src/components/compose.jsx"],"sourcesContent":["export default class Combobox {\n constructor(input, list, { tabInsertsSuggestions, defaultFirstOption } = {}) {\n this.input = input;\n this.list = list;\n this.tabInsertsSuggestions = tabInsertsSuggestions !== null && tabInsertsSuggestions !== void 0 ? tabInsertsSuggestions : true;\n this.defaultFirstOption = defaultFirstOption !== null && defaultFirstOption !== void 0 ? defaultFirstOption : false;\n this.isComposing = false;\n if (!list.id) {\n list.id = `combobox-${Math.random().toString().slice(2, 6)}`;\n }\n this.ctrlBindings = !!navigator.userAgent.match(/Macintosh/);\n this.keyboardEventHandler = event => keyboardBindings(event, this);\n this.compositionEventHandler = event => trackComposition(event, this);\n this.inputHandler = this.clearSelection.bind(this);\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-controls', list.id);\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-haspopup', 'listbox');\n }\n destroy() {\n this.clearSelection();\n this.stop();\n this.input.removeAttribute('role');\n this.input.removeAttribute('aria-controls');\n this.input.removeAttribute('aria-expanded');\n this.input.removeAttribute('aria-autocomplete');\n this.input.removeAttribute('aria-haspopup');\n }\n start() {\n this.input.setAttribute('aria-expanded', 'true');\n this.input.addEventListener('compositionstart', this.compositionEventHandler);\n this.input.addEventListener('compositionend', this.compositionEventHandler);\n this.input.addEventListener('input', this.inputHandler);\n this.input.addEventListener('keydown', this.keyboardEventHandler);\n this.list.addEventListener('click', commitWithElement);\n this.indicateDefaultOption();\n }\n stop() {\n this.clearSelection();\n this.input.setAttribute('aria-expanded', 'false');\n this.input.removeEventListener('compositionstart', this.compositionEventHandler);\n this.input.removeEventListener('compositionend', this.compositionEventHandler);\n this.input.removeEventListener('input', this.inputHandler);\n this.input.removeEventListener('keydown', this.keyboardEventHandler);\n this.list.removeEventListener('click', commitWithElement);\n }\n indicateDefaultOption() {\n var _a;\n if (this.defaultFirstOption) {\n (_a = Array.from(this.list.querySelectorAll('[role=\"option\"]:not([aria-disabled=\"true\"])'))\n .filter(visible)[0]) === null || _a === void 0 ? void 0 : _a.setAttribute('data-combobox-option-default', 'true');\n }\n }\n navigate(indexDiff = 1) {\n const focusEl = Array.from(this.list.querySelectorAll('[aria-selected=\"true\"]')).filter(visible)[0];\n const els = Array.from(this.list.querySelectorAll('[role=\"option\"]')).filter(visible);\n const focusIndex = els.indexOf(focusEl);\n if ((focusIndex === els.length - 1 && indexDiff === 1) || (focusIndex === 0 && indexDiff === -1)) {\n this.clearSelection();\n this.input.focus();\n return;\n }\n let indexOfItem = indexDiff === 1 ? 0 : els.length - 1;\n if (focusEl && focusIndex >= 0) {\n const newIndex = focusIndex + indexDiff;\n if (newIndex >= 0 && newIndex < els.length)\n indexOfItem = newIndex;\n }\n const target = els[indexOfItem];\n if (!target)\n return;\n for (const el of els) {\n el.removeAttribute('data-combobox-option-default');\n if (target === el) {\n this.input.setAttribute('aria-activedescendant', target.id);\n target.setAttribute('aria-selected', 'true');\n scrollTo(this.list, target);\n }\n else {\n el.removeAttribute('aria-selected');\n }\n }\n }\n clearSelection() {\n this.input.removeAttribute('aria-activedescendant');\n for (const el of this.list.querySelectorAll('[aria-selected=\"true\"]')) {\n el.removeAttribute('aria-selected');\n }\n this.indicateDefaultOption();\n }\n}\nfunction keyboardBindings(event, combobox) {\n if (event.shiftKey || event.metaKey || event.altKey)\n return;\n if (!combobox.ctrlBindings && event.ctrlKey)\n return;\n if (combobox.isComposing)\n return;\n switch (event.key) {\n case 'Enter':\n if (commit(combobox.input, combobox.list)) {\n event.preventDefault();\n }\n break;\n case 'Tab':\n if (combobox.tabInsertsSuggestions && commit(combobox.input, combobox.list)) {\n event.preventDefault();\n }\n break;\n case 'Escape':\n combobox.clearSelection();\n break;\n case 'ArrowDown':\n combobox.navigate(1);\n event.preventDefault();\n break;\n case 'ArrowUp':\n combobox.navigate(-1);\n event.preventDefault();\n break;\n case 'n':\n if (combobox.ctrlBindings && event.ctrlKey) {\n combobox.navigate(1);\n event.preventDefault();\n }\n break;\n case 'p':\n if (combobox.ctrlBindings && event.ctrlKey) {\n combobox.navigate(-1);\n event.preventDefault();\n }\n break;\n default:\n if (event.ctrlKey)\n break;\n combobox.clearSelection();\n }\n}\nfunction commitWithElement(event) {\n if (!(event.target instanceof Element))\n return;\n const target = event.target.closest('[role=\"option\"]');\n if (!target)\n return;\n if (target.getAttribute('aria-disabled') === 'true')\n return;\n fireCommitEvent(target);\n}\nfunction commit(input, list) {\n const target = list.querySelector('[aria-selected=\"true\"], [data-combobox-option-default=\"true\"]');\n if (!target)\n return false;\n if (target.getAttribute('aria-disabled') === 'true')\n return true;\n target.click();\n return true;\n}\nfunction fireCommitEvent(target) {\n target.dispatchEvent(new CustomEvent('combobox-commit', { bubbles: true }));\n}\nfunction visible(el) {\n return (!el.hidden &&\n !(el instanceof HTMLInputElement && el.type === 'hidden') &&\n (el.offsetWidth > 0 || el.offsetHeight > 0));\n}\nfunction trackComposition(event, combobox) {\n combobox.isComposing = event.type === 'compositionstart';\n const list = document.getElementById(combobox.input.getAttribute('aria-controls') || '');\n if (!list)\n return;\n combobox.clearSelection();\n}\nfunction scrollTo(container, target) {\n if (!inViewport(container, target)) {\n container.scrollTop = target.offsetTop;\n }\n}\nfunction inViewport(container, element) {\n const scrollTop = container.scrollTop;\n const containerBottom = scrollTop + container.clientHeight;\n const top = element.offsetTop;\n const bottom = top + element.clientHeight;\n return top >= scrollTop && bottom <= containerBottom;\n}\n","import Combobox from '@github/combobox-nav';\n\nconst boundary = /\\s|\\(|\\[/;\nfunction query(text, key, cursor, { multiWord, lookBackIndex, lastMatchPosition } = {\n multiWord: false,\n lookBackIndex: 0,\n lastMatchPosition: null\n}) {\n let keyIndex = text.lastIndexOf(key, cursor - 1);\n if (keyIndex === -1)\n return;\n if (keyIndex < lookBackIndex)\n return;\n if (multiWord) {\n if (lastMatchPosition != null) {\n if (lastMatchPosition === keyIndex)\n return;\n keyIndex = lastMatchPosition - key.length;\n }\n const charAfterKey = text[keyIndex + 1];\n if (charAfterKey === ' ' && cursor >= keyIndex + key.length + 1)\n return;\n const newLineIndex = text.lastIndexOf('\\n', cursor - 1);\n if (newLineIndex > keyIndex)\n return;\n const dotIndex = text.lastIndexOf('.', cursor - 1);\n if (dotIndex > keyIndex)\n return;\n }\n else {\n const spaceIndex = text.lastIndexOf(' ', cursor - 1);\n if (spaceIndex > keyIndex)\n return;\n }\n const pre = text[keyIndex - 1];\n if (pre && !boundary.test(pre))\n return;\n const queryString = text.substring(keyIndex + key.length, cursor);\n return {\n text: queryString,\n position: keyIndex + key.length\n };\n}\n\n/**\n * A custom element is implemented as a class which extends HTMLElement (in the\n * case of autonomous elements) or the interface you want to customize (in the\n * case of customized built-in elements).\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks\n */\nclass CustomHTMLElement extends HTMLElement {\n}\n\nclass InputStyleCloneUpdateEvent extends Event {\n constructor() {\n super(\"update\");\n }\n}\nconst CloneRegistry = new WeakMap();\n/**\n * Create an element that exactly matches an input pixel-for-pixel and automatically stays in sync with it. This\n * is a non-interactive overlay on to the input and can be used to affect the visual appearance of the input\n * without modifying its behavior. The clone element is hidden by default.\n *\n * This lower level API powers the `InputRange` but provides more advanced functionality including event updates.\n *\n * Emits `update` events whenever anything is recalculated: when the layout changes, when the user scrolls, when the\n * input is updated, etc. This event may be emitted more than once per change.\n *\n * @note There may be cases in which the clone cannot observe changes to the input and fails to automatically update.\n * For example, if the `value` property on the input is written to directly, no `input` event is emitted by the input\n * and the clone does not automatically update. In these cases, `forceUpdate` can be used to manually trigger an update.\n */\n// PRIOR ART: This approach was adapted from the following MIT-licensed sources:\n// - primer/react (Copyright (c) 2018 GitHub, Inc.): https://github.com/primer/react/blob/a0db832302702b869aa22b0c4049ad9305ef631f/src/drafts/utils/character-coordinates.ts\n// - component/textarea-caret-position (Copyright (c) 2015 Jonathan Ong me@jongleberry.com): https://github.com/component/textarea-caret-position/blob/b5db7a7e47dd149c2a66276183c69234e4dabe30/index.js\n// - koddsson/textarea-caret-position (Copyright (c) 2015 Jonathan Ong me@jongleberry.com): https://github.com/koddsson/textarea-caret-position/blob/eba40ec8488eed4d77815f109af22e1d9c0751d3/index.js\nclass InputStyleCloneElement extends CustomHTMLElement {\n #styleObserver = new MutationObserver(() => this.#updateStyles());\n #resizeObserver = new ResizeObserver(() => this.#requestUpdateLayout());\n // This class is unique in that it will prevent itself from getting garbage collected because of the subscribed\n // observers (if never detached). Because of this, we want to avoid preventing the existence of this class from also\n // preventing the garbage collection of the associated input. This also allows us to automatically detach if the\n // input gets collected.\n #inputRef;\n #container;\n /**\n * Get the clone for an input, reusing an existing one if available. This avoids creating unecessary clones, which\n * have a performance cost due to their high-frequency event-based updates. Because these elements are shared, they\n * should be mutated with caution.\n *\n * Upon initial creation the clone element will automatically be inserted into the DOM and begin observing the\n * linked input. Only one clone per input can ever exist at a time.\n * @param input The target input to clone.\n */\n static for(input) {\n let clone = CloneRegistry.get(input);\n if (!clone) {\n clone = new InputStyleCloneElement();\n clone.connect(input);\n CloneRegistry.set(input, clone);\n }\n return clone;\n }\n /**\n * Connect this instance to a target input element and insert this instance into the DOM in the correct location.\n *\n * NOTE: calling the static `for` method is nearly always preferable as it will reuse an existing clone if available.\n * However, if reusing clones is problematic (ie, if the clone needs to be mutated), a clone can be constructed\n * directly with `new InputStyleCloneElement()` and then bound to an input and inserted into the DOM with\n * `clone.connect(target)`.\n */\n connect(input) {\n this.#inputRef = new WeakRef(input);\n // We want position:absolute so it doesn't take space in the layout, but that doesn't work with display:table-cell\n // used in the HTMLInputElement approach. So we need a wrapper.\n this.#container = document.createElement(\"div\");\n this.#container.style.position = \"absolute\";\n this.#container.style.pointerEvents = \"none\";\n input.after(this.#container);\n this.#container.appendChild(this);\n }\n /**\n * Force a recalculation. Will emit an `update` event. This is typically not needed unless the input has changed in\n * an unobservable way, eg by directly writing to the `value` property.\n */\n forceUpdate() {\n this.#updateStyles();\n this.#updateText();\n }\n /** @private */\n connectedCallback() {\n this.#usingInput((input) => {\n this.style.pointerEvents = \"none\";\n this.style.userSelect = \"none\";\n this.style.overflow = \"hidden\";\n this.style.display = \"block\";\n // Important not to use display:none which would not render the content at all\n this.style.visibility = \"hidden\";\n if (input instanceof HTMLTextAreaElement) {\n this.style.whiteSpace = \"pre-wrap\";\n this.style.wordWrap = \"break-word\";\n }\n else {\n this.style.whiteSpace = \"nowrap\";\n // text in single-line inputs is vertically centered\n this.style.display = \"table-cell\";\n this.style.verticalAlign = \"middle\";\n }\n this.setAttribute(\"aria-hidden\", \"true\");\n this.#updateStyles();\n this.#updateText();\n this.#styleObserver.observe(input, {\n attributeFilter: [\n \"style\",\n \"dir\", // users can right-click in some browsers to change the text direction dynamically\n ],\n });\n this.#resizeObserver.observe(input);\n document.addEventListener(\"scroll\", this.#onDocumentScrollOrResize, { capture: true });\n window.addEventListener(\"resize\", this.#onDocumentScrollOrResize, { capture: true });\n // capture so this happens first, so other things can respond to `input` events after this data updates\n input.addEventListener(\"input\", this.#onInput, { capture: true });\n });\n }\n /** @private */\n disconnectedCallback() {\n this.#container?.remove();\n this.#styleObserver.disconnect();\n this.#resizeObserver.disconnect();\n document.removeEventListener(\"scroll\", this.#onDocumentScrollOrResize, { capture: true });\n window.removeEventListener(\"resize\", this.#onDocumentScrollOrResize, { capture: true });\n // Can't use `usingInput` here since that could infinitely recurse\n const input = this.#input;\n if (input) {\n input.removeEventListener(\"input\", this.#onInput, { capture: true });\n CloneRegistry.delete(input);\n }\n }\n // --- private ---\n get #input() {\n return this.#inputRef?.deref();\n }\n /** Perform `fn` using the `input` if it is still available. If not, clean up the clone instead. */\n #usingInput(fn) {\n const input = this.#input;\n if (!input)\n return this.remove();\n return fn(input);\n }\n /** Current relative x-adjustment in pixels, executed via CSS transform. */\n #xOffset = 0;\n /** Current relative y-adjustment in pixels, executed via CSS transform. */\n #yOffset = 0;\n /**\n * Update only geometric properties without recalculating styles. Typically call `#requestUpdateLayout` instead to\n * only update once per animation frame.\n */\n #updateLayout() {\n // This runs often, so keep it as fast as possible! Avoid all unecessary updates.\n this.#usingInput((input) => {\n const inputStyle = window.getComputedStyle(input);\n this.style.height = inputStyle.height;\n this.style.width = inputStyle.width;\n // Immediately re-adjust for browser inconsistencies in scrollbar handling, if necessary\n if (input.clientHeight !== this.clientHeight)\n this.style.height = `calc(${inputStyle.height} + ${input.clientHeight - this.clientHeight}px)`;\n if (input.clientWidth !== this.clientWidth)\n this.style.width = `calc(${inputStyle.width} + ${input.clientWidth - this.clientWidth}px)`;\n // Position on top of the input\n const inputRect = input.getBoundingClientRect();\n const cloneRect = this.getBoundingClientRect();\n this.#xOffset = this.#xOffset + inputRect.left - cloneRect.left;\n this.#yOffset = this.#yOffset + inputRect.top - cloneRect.top;\n this.style.transform = `translate(${this.#xOffset}px, ${this.#yOffset}px)`;\n this.scrollTop = input.scrollTop;\n this.scrollLeft = input.scrollLeft;\n this.dispatchEvent(new InputStyleCloneUpdateEvent());\n });\n }\n #isLayoutUpdating = false;\n /** Request a layout update. Will only happen once per animation frame, to avoid unecessary updates. */\n #requestUpdateLayout() {\n if (this.#isLayoutUpdating)\n return;\n this.#isLayoutUpdating = true;\n requestAnimationFrame(() => {\n this.#updateLayout();\n this.#isLayoutUpdating = false;\n });\n }\n /** Update the styles of the clone based on the styles of the input, then request a layout update. */\n #updateStyles() {\n this.#usingInput((input) => {\n const inputStyle = window.getComputedStyle(input);\n for (const prop of propertiesToCopy)\n this.style[prop] = inputStyle[prop];\n this.#requestUpdateLayout();\n });\n }\n /**\n * Update the text content of the clone based on the text content of the input. Triggers a layout update in case the\n * text update caused scrolling.\n */\n #updateText() {\n this.#usingInput((input) => {\n this.textContent = input.value;\n // This is often unecessary on a pure text update, but text updates could potentially cause layout updates like\n // scrolling or resizing. And we run the update on _every frame_ when scrolling, so this isn't that expensive.\n // We don't requestUpdateLayout here because this one should happen synchronously, so that clients can react\n // within their own `input` event handlers.\n this.#updateLayout();\n });\n }\n #onInput = () => this.#updateText();\n #onDocumentScrollOrResize = (event) => {\n this.#usingInput((input) => {\n if (event.target === document ||\n event.target === window ||\n (event.target instanceof Node && event.target.contains(input)))\n this.#requestUpdateLayout();\n });\n };\n}\n// Note that some browsers, such as Firefox, do not concatenate properties\n// into their shorthand (e.g. padding-top, padding-bottom etc. -> padding),\n// so we have to list every single property explicitly.\nconst propertiesToCopy = [\n // RTL / vertical writing modes support:\n \"direction\",\n \"writingMode\",\n \"unicodeBidi\",\n \"textOrientation\",\n \"boxSizing\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"borderStyle\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n \"fontStyle\",\n \"fontVariant\",\n \"fontWeight\",\n \"fontStretch\",\n \"fontSize\",\n \"fontSizeAdjust\",\n \"lineHeight\",\n \"fontFamily\",\n \"textAlign\",\n \"textTransform\",\n \"textIndent\",\n \"textDecoration\",\n \"letterSpacing\",\n \"wordSpacing\",\n \"tabSize\",\n \"MozTabSize\",\n];\n// Inspired by https://github.com/github/catalyst/blob/dc284dcf4f82329a9cac5c867462a8fa529b6c40/src/register.ts\ntry {\n customElements.define(\"input-style-clone\", InputStyleCloneElement);\n}\ncatch (e) {\n // Throws DOMException with NotSupportedError if already defined\n if (!(e instanceof DOMException && e.name === \"NotSupportedError\"))\n throw e;\n}\n\nclass InputRange {\n #inputElement;\n #startOffset;\n #endOffset;\n /**\n * Construct a new `InputRange`.\n * @param element The target input element that contains the content for the range.\n * @param startOffset The inclusive 0-based start index for the range. Will be adjusted to fit in the input contents.\n * @param endOffset The exclusive 0-based end index for the range. Will be adjusted to fit in the input contents.\n */\n constructor(element, startOffset = 0, endOffset = startOffset) {\n this.#inputElement = element;\n this.#startOffset = startOffset;\n this.#endOffset = endOffset;\n }\n /**\n * Create a new range from the current user selection. If the input is not focused, the range will just be the start\n * of the input (offsets `0` to `0`).\n *\n * This can be used to get the caret coordinates: if the resulting range is `collapsed`, the location of the\n * `getBoundingClientRect` will be the location of the caret caret (note, however, that the width will be `0` in\n * this case).\n */\n static fromSelection(input) {\n const { selectionStart, selectionEnd } = input;\n return new InputRange(input, selectionStart ?? undefined, selectionEnd ?? undefined);\n }\n /** Returns true if the start is equal to the end of this range. */\n get collapsed() {\n return this.startOffset === this.endOffset;\n }\n /** Always returns the containing input element. */\n get commonAncestorContainer() {\n return this.#inputElement;\n }\n /** Always returns the containing input element. */\n get endContainer() {\n return this.#inputElement;\n }\n /** Always returns the containing input element. */\n get startContainer() {\n return this.#inputElement;\n }\n get startOffset() {\n return this.#startOffset;\n }\n get endOffset() {\n return this.#endOffset;\n }\n /** Update the inclusive start offset. Will be adjusted to fit within the content size. */\n setStartOffset(offset) {\n this.#startOffset = this.#clampOffset(offset);\n }\n /** Update the exclusive end offset. Will be adjusted to fit within the content size. */\n setEndOffset(offset) {\n this.#endOffset = this.#clampOffset(offset);\n }\n /**\n * Collapse this range to one side.\n * @param toStart If `true`, will collapse to the start side. Otherwise, will collapse to the end.\n */\n collapse(toStart = false) {\n if (toStart)\n this.setEndOffset(this.startOffset);\n else\n this.setStartOffset(this.endOffset);\n }\n /** Returns a `DocumentFragment` containing a new `Text` node containing the content in the range. */\n cloneContents() {\n return this.#createCloneRange().cloneContents();\n }\n /** Create a copy of this range. */\n cloneRange() {\n return new InputRange(this.#inputElement, this.startOffset, this.endOffset);\n }\n /**\n * Obtain one rect that contains the entire contents of the range. If the range spans multiple lines, this box will\n * contain all pieces of the range but may also contain some space outside the range.\n * @see https://iansan5653.github.io/dom-input-range/demos/playground/\n */\n getBoundingClientRect() {\n return this.#createCloneRange().getBoundingClientRect();\n }\n /**\n * Obtain the rects that contain contents of this range. If the range spans multiple lines, there will be multiple\n * bounding boxes. These boxes can be used, for example, to draw a highlight over the range.\n * @see https://iansan5653.github.io/dom-input-range/demos/playground/\n */\n getClientRects() {\n return this.#createCloneRange().getClientRects();\n }\n /** Get the contents of the range as a string. */\n toString() {\n return this.#createCloneRange().toString();\n }\n /**\n * Get the underlying `InputStyleClone` instance powering these calculations. This can be used to listen for\n * updates to trigger layout recalculation.\n */\n getStyleClone() {\n return this.#styleClone;\n }\n // --- private ---\n get #styleClone() {\n return InputStyleCloneElement.for(this.#inputElement);\n }\n get #cloneElement() {\n return this.#styleClone;\n }\n #clampOffset(offset) {\n return Math.max(0, Math.min(offset, this.#inputElement.value.length));\n }\n #createCloneRange() {\n // It's tempting to create a single Range and reuse it across the lifetime of the class. However, this wouldn't be\n // accurate because the contents of the input can change and the contents of the range would become stale. So we\n // must create a new range every time we need it.\n const range = document.createRange();\n const textNode = this.#cloneElement.childNodes[0];\n if (textNode) {\n range.setStart(textNode, this.startOffset);\n range.setEnd(textNode, this.endOffset);\n }\n return range;\n }\n}\n\nconst states = new WeakMap();\nclass TextExpander {\n constructor(expander, input) {\n this.expander = expander;\n this.input = input;\n this.combobox = null;\n this.menu = null;\n this.match = null;\n this.justPasted = false;\n this.lookBackIndex = 0;\n this.oninput = this.onInput.bind(this);\n this.onpaste = this.onPaste.bind(this);\n this.onkeydown = this.onKeydown.bind(this);\n this.oncommit = this.onCommit.bind(this);\n this.onmousedown = this.onMousedown.bind(this);\n this.onblur = this.onBlur.bind(this);\n this.interactingWithList = false;\n input.addEventListener('paste', this.onpaste);\n input.addEventListener('input', this.oninput);\n input.addEventListener('keydown', this.onkeydown);\n input.addEventListener('blur', this.onblur);\n }\n destroy() {\n this.input.removeEventListener('paste', this.onpaste);\n this.input.removeEventListener('input', this.oninput);\n this.input.removeEventListener('keydown', this.onkeydown);\n this.input.removeEventListener('blur', this.onblur);\n }\n dismissMenu() {\n if (this.deactivate()) {\n this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex;\n }\n }\n activate(match, menu) {\n var _a, _b;\n if (this.input !== document.activeElement && this.input !== ((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.activeElement)) {\n return;\n }\n this.deactivate();\n this.menu = menu;\n if (!menu.id)\n menu.id = `text-expander-${Math.floor(Math.random() * 100000).toString()}`;\n this.expander.append(menu);\n this.combobox = new Combobox(this.input, menu);\n this.expander.dispatchEvent(new Event('text-expander-activate'));\n this.positionMenu(menu, match.position);\n this.combobox.start();\n menu.addEventListener('combobox-commit', this.oncommit);\n menu.addEventListener('mousedown', this.onmousedown);\n this.combobox.navigate(1);\n }\n positionMenu(menu, position) {\n const caretRect = new InputRange(this.input, position).getBoundingClientRect();\n const targetPosition = { left: caretRect.left, top: caretRect.top + caretRect.height };\n const currentPosition = menu.getBoundingClientRect();\n const delta = {\n left: targetPosition.left - currentPosition.left,\n top: targetPosition.top - currentPosition.top\n };\n if (delta.left !== 0 || delta.top !== 0) {\n const currentStyle = getComputedStyle(menu);\n menu.style.left = currentStyle.left ? `calc(${currentStyle.left} + ${delta.left}px)` : `${delta.left}px`;\n menu.style.top = currentStyle.top ? `calc(${currentStyle.top} + ${delta.top}px)` : `${delta.top}px`;\n }\n }\n deactivate() {\n const menu = this.menu;\n if (!menu || !this.combobox)\n return false;\n this.expander.dispatchEvent(new Event('text-expander-deactivate'));\n this.menu = null;\n menu.removeEventListener('combobox-commit', this.oncommit);\n menu.removeEventListener('mousedown', this.onmousedown);\n this.combobox.destroy();\n this.combobox = null;\n menu.remove();\n return true;\n }\n onCommit({ target }) {\n var _a;\n const item = target;\n if (!(item instanceof HTMLElement))\n return;\n if (!this.combobox)\n return;\n const match = this.match;\n if (!match)\n return;\n const beginning = this.input.value.substring(0, match.position - match.key.length);\n const remaining = this.input.value.substring(match.position + match.text.length);\n const detail = { item, key: match.key, value: null, continue: false };\n const canceled = !this.expander.dispatchEvent(new CustomEvent('text-expander-value', { cancelable: true, detail }));\n if (canceled)\n return;\n if (!detail.value)\n return;\n let suffix = (_a = this.expander.getAttribute('suffix')) !== null && _a !== void 0 ? _a : ' ';\n if (detail.continue) {\n suffix = '';\n }\n const value = `${detail.value}${suffix}`;\n this.input.value = beginning + value + remaining;\n const cursor = beginning.length + value.length;\n this.deactivate();\n this.input.focus({\n preventScroll: true\n });\n this.input.selectionStart = cursor;\n this.input.selectionEnd = cursor;\n if (!detail.continue) {\n this.lookBackIndex = cursor;\n this.match = null;\n }\n this.expander.dispatchEvent(new CustomEvent('text-expander-committed', { cancelable: false, detail: { input: this.input } }));\n }\n onBlur() {\n if (this.interactingWithList) {\n this.interactingWithList = false;\n return;\n }\n this.deactivate();\n }\n onPaste() {\n this.justPasted = true;\n }\n async onInput() {\n if (this.justPasted) {\n this.justPasted = false;\n return;\n }\n const match = this.findMatch();\n if (match) {\n this.match = match;\n const menu = await this.notifyProviders(match);\n if (!this.match)\n return;\n if (menu) {\n this.activate(match, menu);\n }\n else {\n this.deactivate();\n }\n }\n else {\n this.match = null;\n this.deactivate();\n }\n }\n findMatch() {\n const cursor = this.input.selectionEnd || 0;\n const text = this.input.value;\n if (cursor <= this.lookBackIndex) {\n this.lookBackIndex = cursor - 1;\n }\n for (const { key, multiWord } of this.expander.keys) {\n const found = query(text, key, cursor, {\n multiWord,\n lookBackIndex: this.lookBackIndex,\n lastMatchPosition: this.match ? this.match.position : null\n });\n if (found) {\n return { text: found.text, key, position: found.position };\n }\n }\n }\n async notifyProviders(match) {\n const providers = [];\n const provide = (result) => providers.push(result);\n const canceled = !this.expander.dispatchEvent(new CustomEvent('text-expander-change', { cancelable: true, detail: { provide, text: match.text, key: match.key } }));\n if (canceled)\n return;\n const all = await Promise.all(providers);\n const fragments = all.filter(x => x.matched).map(x => x.fragment);\n return fragments[0];\n }\n onMousedown() {\n this.interactingWithList = true;\n }\n onKeydown(event) {\n if (event.key === 'Escape') {\n this.match = null;\n if (this.deactivate()) {\n this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex;\n event.stopImmediatePropagation();\n event.preventDefault();\n }\n }\n }\n}\nclass TextExpanderElement extends HTMLElement {\n get keys() {\n const keysAttr = this.getAttribute('keys');\n const keys = keysAttr ? keysAttr.split(' ') : [];\n const multiWordAttr = this.getAttribute('multiword');\n const multiWord = multiWordAttr ? multiWordAttr.split(' ') : [];\n const globalMultiWord = multiWord.length === 0 && this.hasAttribute('multiword');\n return keys.map(key => ({ key, multiWord: globalMultiWord || multiWord.includes(key) }));\n }\n set keys(value) {\n this.setAttribute('keys', value);\n }\n connectedCallback() {\n const input = this.querySelector('input[type=\"text\"], textarea');\n if (!(input instanceof HTMLInputElement || input instanceof HTMLTextAreaElement))\n return;\n const state = new TextExpander(this, input);\n states.set(this, state);\n }\n disconnectedCallback() {\n const state = states.get(this);\n if (!state)\n return;\n state.destroy();\n states.delete(this);\n }\n dismiss() {\n const state = states.get(this);\n if (!state)\n return;\n state.dismissMenu();\n }\n}\n\nif (!window.customElements.get('text-expander')) {\n window.TextExpanderElement = TextExpanderElement;\n window.customElements.define('text-expander', TextExpanderElement);\n}\n\nexport { TextExpanderElement as default };\n","export default function ansiRegex({onlyFirst = false} = {}) {\n\tconst pattern = [\n\t '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]+)*|[a-zA-Z\\\\d]+(?:;[-a-zA-Z\\\\d\\\\/#&.:=?%@~_]*)*)?\\\\u0007)',\n\t\t'(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PR-TZcf-ntqry=><~]))'\n\t].join('|');\n\n\treturn new RegExp(pattern, onlyFirst ? undefined : 'g');\n}\n","import ansiRegex from 'ansi-regex';\n\nconst regex = ansiRegex();\n\nexport default function stripAnsi(string) {\n\tif (typeof string !== 'string') {\n\t\tthrow new TypeError(`Expected a \\`string\\`, got \\`${typeof string}\\``);\n\t}\n\n\t// Even though the regex is global, we don't need to reset the `.lastIndex`\n\t// because unlike `.exec()` and `.test()`, `.replace()` does it automatically\n\t// and doing it manually has a performance penalty.\n\treturn string.replace(regex, '');\n}\n","import stripAnsi from 'strip-ansi';\n\nconst segmenter = new Intl.Segmenter();\n\nexport default function stringLength(string, {countAnsiEscapeCodes = false} = {}) {\n\tif (string === '') {\n\t\treturn 0;\n\t}\n\n\tif (!countAnsiEscapeCodes) {\n\t\tstring = stripAnsi(string);\n\t}\n\n\tif (string === '') {\n\t\treturn 0;\n\t}\n\n\tlet length = 0;\n\n\tfor (const _ of segmenter.segment(string)) { // eslint-disable-line no-unused-vars\n\t\tlength++;\n\t}\n\n\treturn length;\n}\n","export default \"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20version='1.0'%20viewBox='0%200%20641%20223'%3e%3cpath%20fill='%23aaa'%20d='M86%20214c-9-1-17-4-24-8l-6-3-5-5-5-4-4-6-4-6-3-8-2-8v-27l2-9%203-9%204-6%204-6%205-5%205-5%207-3%206-4%207-2%207-2%2012-1h12l7%201%208%202%207%204%207%203%205%205%205%204-10%2010-10%209-4-3-10-5-5-1H88l-5%202-6%203-3%204-4%204-2%205-2%206v6l-1%207%201%207%202%207%203%205%202%204%204%203%204%203%205%202%206%202h9l10-1%205-2%206-3v-16H91v-27h59v54l-1%203-2%203-5%204-4%204-5%203-5%202-8%202-8%202-10%201H92l-6-1zm266-62V91h34v46h44V91h34v121h-34v-46h-44v46h-34v-61zm-182-1V90h34v121h-34v-60zm59-1V90h35l36%201%205%202c3%200%208%202%2010%204l5%202%204%205%205%204%203%207%203%207%201%2013v13l-4%206-3%207-4%204-5%205-5%202-5%203-6%202-5%201-18%201h-18v32h-34v-61zm67-2%203-2%202-4%202-5v-5l-2-4-2-4-3-2-3-3h-30v31h30l3-2zm226%2039v-24l-8-12-18-28a1751%201751%200%200%200-20-31v-2h39l7%2012%2012%2021%206%209%2013-21%2013-21h38v2l-41%2061-7%2010v48h-34v-24zM109%2066l-4-1-5-5-5-4-1-5-3-9v-5l1-5c2-7%203-10%208-15l4-4%207-2%207-2h7l6%201%205%202%205%202%203%204%204%203%202%206%202%205v13l-2%205-2%206-4%204-3%203-5%202-4%202-9%201h-9l-5-2zm22-11%204-2%203-4%202-5V34l-2-4-2-4-3-2-4-3-5-1h-6l-4%202-5%202-2%204-3%205-1%203v4l1%205%202%205%202%202%205%203%204%202h10l4-2zM37%2039V11h33l3%201%203%202%204%203%203%203%201%205%201%204v5l-1%204-3%204-3%205-4%201-3%202-11%201H49v16H37V39zm31%200%203-2%201-2%201-2v-4l-1-3-3-2-2-2H49v18h15l4-1zm107%2025a512%20512%200%200%200-19-53h14l4%2014%206%2019%201%204%201-1%207-19%205-17h9l6%2019%207%2018v-1l2-6%205-17%204-13h14v1l-4%2012-16%2041v2h-5l-5-1-6-15-6-15-1%201-3%207-6%2015-2%208h-11l-1-3zm74-25V11h42v11h-29v2l-1%205v4h29v11h-28v11h2l15%201h13v11h-43V39zm55%200V11h33l5%203%205%202%202%204%202%205v10l-2%203-1%204-5%203-5%203%205%205%208%2010%203%204h-14l-7-9-8-10h-9v19h-12V39zm33-3%202-3v-6l-3-3-2-3h-18v16h1v1h17l2-2zm26%203V11h42v11h-29l-1%206v5h29v11h-28v5l-1%205%201%201v1h30v11h-43V39zm54%200V11h17l18%201%204%202%205%203%202%204%203%204%202%206%201%206v5c-1%206-3%2012-6%2015l-3%204-5%203-5%202-17%201h-16V39zm33%2014%205-5%202-3v-6l-1-6-1-3-1-3-4-3-3-2h-5l-6-1-3%201h-3v34h9l8-1%203-2zm50-14V11h34l5%202%204%202%202%203%202%203v9l-2%202-3%204-1%201%203%203%203%204%201%203%201%204-1%204-1%204-3%203-3%203-5%201-5%201h-31V39zm34%2015%202-1v-6l-2-2-2-2h-20v13h20l2-2zm-3-22%204-2v-6l-2-1-2-2h-19v12h16l4-1zm42%2024V45l-6-9-11-17-5-8h15l4%208%207%2011%202%203%207-11%207-11h14l-11%2016-11%2017v23h-12V56z'/%3e%3c/svg%3e\"","import './compose.css';\nimport '@github/text-expander-element';\n\nimport { msg, plural, t, Trans } from '@lingui/macro';\nimport { useLingui } from '@lingui/react';\nimport { MenuItem } from '@szhsin/react-menu';\nimport { deepEqual } from 'fast-equals';\nimport Fuse from 'fuse.js';\nimport { forwardRef, memo } from 'preact/compat';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'preact/hooks';\nimport { useHotkeys } from 'react-hotkeys-hook';\nimport stringLength from 'string-length';\n// import { detectAll } from 'tinyld/light';\nimport { uid } from 'uid/single';\nimport { useDebouncedCallback, useThrottledCallback } from 'use-debounce';\nimport useResizeObserver from 'use-resize-observer';\nimport { useSnapshot } from 'valtio';\n\nimport poweredByGiphyURL from '../assets/powered-by-giphy.svg';\n\nimport Menu2 from '../components/menu2';\nimport supportedLanguages from '../data/status-supported-languages';\nimport urlRegex from '../data/url-regex';\nimport { api } from '../utils/api';\nimport db from '../utils/db';\nimport emojifyText from '../utils/emojify-text';\nimport i18nDuration from '../utils/i18n-duration';\nimport isRTL from '../utils/is-rtl';\nimport localeMatch from '../utils/locale-match';\nimport localeCode2Text from '../utils/localeCode2Text';\nimport mem from '../utils/mem';\nimport openCompose from '../utils/open-compose';\nimport pmem from '../utils/pmem';\nimport prettyBytes from '../utils/pretty-bytes';\nimport { fetchRelationships } from '../utils/relationships';\nimport shortenNumber from '../utils/shorten-number';\nimport showToast from '../utils/show-toast';\nimport states, { saveStatus } from '../utils/states';\nimport store from '../utils/store';\nimport {\n getCurrentAccount,\n getCurrentAccountNS,\n getCurrentInstance,\n getCurrentInstanceConfiguration,\n} from '../utils/store-utils';\nimport supports from '../utils/supports';\nimport useCloseWatcher from '../utils/useCloseWatcher';\nimport useInterval from '../utils/useInterval';\nimport visibilityIconsMap from '../utils/visibility-icons-map';\n\nimport AccountBlock from './account-block';\n// import Avatar from './avatar';\nimport Icon from './icon';\nimport Loader from './loader';\nimport Modal from './modal';\nimport Status from './status';\n\nconst {\n PHANPY_IMG_ALT_API_URL: IMG_ALT_API_URL,\n PHANPY_GIPHY_API_KEY: GIPHY_API_KEY,\n} = import.meta.env;\n\nconst supportedLanguagesMap = supportedLanguages.reduce((acc, l) => {\n const [code, common, native] = l;\n acc[code] = {\n common,\n native,\n };\n return acc;\n}, {});\n\n/* NOTES:\n - Max character limit includes BOTH status text and Content Warning text\n*/\n\nconst expiryOptions = {\n 300: i18nDuration(5, 'minute'),\n 1_800: i18nDuration(30, 'minute'),\n 3_600: i18nDuration(1, 'hour'),\n 21_600: i18nDuration(6, 'hour'),\n 86_400: i18nDuration(1, 'day'),\n 259_200: i18nDuration(3, 'day'),\n 604_800: i18nDuration(1, 'week'),\n};\nconst expirySeconds = Object.keys(expiryOptions);\nconst oneDay = 24 * 60 * 60;\n\nconst expiresInFromExpiresAt = (expiresAt) => {\n if (!expiresAt) return oneDay;\n const delta = (new Date(expiresAt).getTime() - Date.now()) / 1000;\n return expirySeconds.find((s) => s >= delta) || oneDay;\n};\n\nconst menu = document.createElement('ul');\nmenu.role = 'listbox';\nmenu.className = 'text-expander-menu';\n\n// Set IntersectionObserver on menu, reposition it because text-expander doesn't handle it\nconst windowMargin = 16;\nconst observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n const { left, width } = entry.boundingClientRect;\n const { innerWidth } = window;\n if (left + width > innerWidth) {\n const insetInlineStart = isRTL() ? 'right' : 'left';\n menu.style[insetInlineStart] = innerWidth - width - windowMargin + 'px';\n }\n }\n });\n});\nobserver.observe(menu);\n\nconst DEFAULT_LANG = localeMatch(\n [new Intl.DateTimeFormat().resolvedOptions().locale, ...navigator.languages],\n supportedLanguages.map((l) => l[0]),\n 'en',\n);\n\n// https://github.com/mastodon/mastodon/blob/c4a429ed47e85a6bbf0d470a41cc2f64cf120c19/app/javascript/mastodon/features/compose/util/counter.js\nconst urlRegexObj = new RegExp(urlRegex.source, urlRegex.flags);\nconst usernameRegex = /(^|[^\\/\\w])@(([a-z0-9_]+)@[a-z0-9\\.\\-]+[a-z0-9]+)/gi;\nconst urlPlaceholder = '$2xxxxxxxxxxxxxxxxxxxxxxx';\nfunction countableText(inputText) {\n return inputText\n .replace(urlRegexObj, urlPlaceholder)\n .replace(usernameRegex, '$1@$3');\n}\n\n// https://github.com/mastodon/mastodon/blob/c03bd2a238741a012aa4b98dc4902d6cf948ab63/app/models/account.rb#L69\nconst USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i;\nconst MENTION_RE = new RegExp(\n `(^|[^=\\\\/\\\\w])(@${USERNAME_RE.source}(?:@[\\\\p{L}\\\\w.-]+[\\\\w]+)?)`,\n 'uig',\n);\n\n// AI-generated, all other regexes are too complicated\nconst HASHTAG_RE = new RegExp(\n `(^|[^=\\\\/\\\\w])(#[a-z0-9_]+([a-z0-9_.]+[a-z0-9_]+)?)(?![\\\\/\\\\w])`,\n 'ig',\n);\n\n// https://github.com/mastodon/mastodon/blob/23e32a4b3031d1da8b911e0145d61b4dd47c4f96/app/models/custom_emoji.rb#L31\nconst SHORTCODE_RE_FRAGMENT = '[a-zA-Z0-9_]{2,}';\nconst SCAN_RE = new RegExp(\n `(^|[^=\\\\/\\\\w])(:${SHORTCODE_RE_FRAGMENT}:)(?=[^A-Za-z0-9_:]|$)`,\n 'g',\n);\n\nconst segmenter = new Intl.Segmenter();\nfunction escapeHTML(text) {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\nfunction highlightText(text, { maxCharacters = Infinity }) {\n // Exceeded characters limit\n const { composerCharacterCount } = states;\n if (composerCharacterCount > maxCharacters) {\n // Highlight exceeded characters\n let withinLimitHTML = '',\n exceedLimitHTML = '';\n const htmlSegments = segmenter.segment(text);\n for (const { segment, index } of htmlSegments) {\n if (index < maxCharacters) {\n withinLimitHTML += segment;\n } else {\n exceedLimitHTML += segment;\n }\n }\n if (exceedLimitHTML) {\n exceedLimitHTML =\n '<mark class=\"compose-highlight-exceeded\">' +\n escapeHTML(exceedLimitHTML) +\n '</mark>';\n }\n return escapeHTML(withinLimitHTML) + exceedLimitHTML;\n }\n\n return escapeHTML(text)\n .replace(urlRegexObj, '$2<mark class=\"compose-highlight-url\">$3</mark>') // URLs\n .replace(MENTION_RE, '$1<mark class=\"compose-highlight-mention\">$2</mark>') // Mentions\n .replace(HASHTAG_RE, '$1<mark class=\"compose-highlight-hashtag\">$2</mark>') // Hashtags\n .replace(\n SCAN_RE,\n '$1<mark class=\"compose-highlight-emoji-shortcode\">$2</mark>',\n ); // Emoji shortcodes\n}\n\n// const rtf = new Intl.RelativeTimeFormat();\nconst RTF = mem((locale) => new Intl.RelativeTimeFormat(locale || undefined));\nconst LF = mem((locale) => new Intl.ListFormat(locale || undefined));\n\nconst CUSTOM_EMOJIS_COUNT = 100;\n\nconst ADD_LABELS = {\n media: msg`Add media`,\n customEmoji: msg`Add custom emoji`,\n gif: msg`Add GIF`,\n poll: msg`Add poll`,\n};\n\nfunction Compose({\n onClose,\n replyToStatus,\n editStatus,\n draftStatus,\n standalone,\n hasOpener,\n}) {\n const { i18n, _ } = useLingui();\n const rtf = RTF(i18n.locale);\n const lf = LF(i18n.locale);\n\n console.warn('RENDER COMPOSER');\n const { masto, instance } = api();\n const [uiState, setUIState] = useState('default');\n const UID = useRef(draftStatus?.uid || uid());\n console.log('Compose UID', UID.current);\n\n const currentAccount = getCurrentAccount();\n const currentAccountInfo = currentAccount.info;\n\n const configuration = getCurrentInstanceConfiguration();\n console.log('⚙️ Configuration', configuration);\n\n const {\n statuses: {\n maxCharacters,\n maxMediaAttachments, // Beware: it can be undefined!\n charactersReservedPerUrl,\n } = {},\n mediaAttachments: {\n supportedMimeTypes,\n imageSizeLimit,\n imageMatrixLimit,\n videoSizeLimit,\n videoMatrixLimit,\n videoFrameRateLimit,\n } = {},\n polls: {\n maxOptions,\n maxCharactersPerOption,\n maxExpiration,\n minExpiration,\n } = {},\n } = configuration || {};\n\n const textareaRef = useRef();\n const spoilerTextRef = useRef();\n const [visibility, setVisibility] = useState('public');\n const [sensitive, setSensitive] = useState(false);\n const [language, setLanguage] = useState(\n store.session.get('currentLanguage') || DEFAULT_LANG,\n );\n const prevLanguage = useRef(language);\n const [mediaAttachments, setMediaAttachments] = useState([]);\n const [poll, setPoll] = useState(null);\n\n const prefs = store.account.get('preferences') || {};\n\n const oninputTextarea = () => {\n if (!textareaRef.current) return;\n textareaRef.current.dispatchEvent(new Event('input'));\n };\n const focusTextarea = () => {\n setTimeout(() => {\n if (!textareaRef.current) return;\n // status starts with newline, focus on first position\n if (draftStatus?.status?.startsWith?.('\\n')) {\n textareaRef.current.selectionStart = 0;\n textareaRef.current.selectionEnd = 0;\n }\n console.debug('FOCUS textarea');\n textareaRef.current?.focus();\n }, 300);\n };\n\n useEffect(() => {\n if (replyToStatus) {\n const { spoilerText, visibility, language, sensitive } = replyToStatus;\n if (spoilerText && spoilerTextRef.current) {\n spoilerTextRef.current.value = spoilerText;\n }\n const mentions = new Set([\n replyToStatus.account.acct,\n ...replyToStatus.mentions.map((m) => m.acct),\n ]);\n const allMentions = [...mentions].filter(\n (m) => m !== currentAccountInfo.acct,\n );\n if (allMentions.length > 0) {\n textareaRef.current.value = `${allMentions\n .map((m) => `@${m}`)\n .join(' ')} `;\n oninputTextarea();\n }\n focusTextarea();\n setVisibility(\n visibility === 'public' && prefs['posting:default:visibility']\n ? prefs['posting:default:visibility'].toLowerCase()\n : visibility,\n );\n setLanguage(\n language ||\n prefs['posting:default:language']?.toLowerCase() ||\n DEFAULT_LANG,\n );\n setSensitive(sensitive && !!spoilerText);\n } else if (editStatus) {\n const { visibility, language, sensitive, poll, mediaAttachments } =\n editStatus;\n const composablePoll = !!poll?.options && {\n ...poll,\n options: poll.options.map((o) => o?.title || o),\n expiresIn: poll?.expiresIn || expiresInFromExpiresAt(poll.expiresAt),\n };\n setUIState('loading');\n (async () => {\n try {\n const statusSource = await masto.v1.statuses\n .$select(editStatus.id)\n .source.fetch();\n console.log({ statusSource });\n const { text, spoilerText } = statusSource;\n textareaRef.current.value = text;\n textareaRef.current.dataset.source = text;\n oninputTextarea();\n focusTextarea();\n spoilerTextRef.current.value = spoilerText;\n setVisibility(visibility);\n setLanguage(\n language ||\n prefs['posting:default:language']?.toLowerCase() ||\n DEFAULT_LANG,\n );\n setSensitive(sensitive);\n if (composablePoll) setPoll(composablePoll);\n setMediaAttachments(mediaAttachments);\n setUIState('default');\n } catch (e) {\n console.error(e);\n alert(e?.reason || e);\n setUIState('error');\n }\n })();\n } else {\n focusTextarea();\n console.log('Apply prefs', prefs);\n if (prefs['posting:default:visibility']) {\n setVisibility(prefs['posting:default:visibility'].toLowerCase());\n }\n if (prefs['posting:default:language']) {\n setLanguage(prefs['posting:default:language'].toLowerCase());\n }\n if (prefs['posting:default:sensitive']) {\n setSensitive(!!prefs['posting:default:sensitive']);\n }\n }\n if (draftStatus) {\n const {\n status,\n spoilerText,\n visibility,\n language,\n sensitive,\n poll,\n mediaAttachments,\n } = draftStatus;\n const composablePoll = !!poll?.options && {\n ...poll,\n options: poll.options.map((o) => o?.title || o),\n expiresIn: poll?.expiresIn || expiresInFromExpiresAt(poll.expiresAt),\n };\n textareaRef.current.value = status;\n oninputTextarea();\n focusTextarea();\n if (spoilerText) spoilerTextRef.current.value = spoilerText;\n if (visibility) setVisibility(visibility);\n setLanguage(\n language ||\n prefs['posting:default:language']?.toLowerCase() ||\n DEFAULT_LANG,\n );\n if (sensitive !== null) setSensitive(sensitive);\n if (composablePoll) setPoll(composablePoll);\n if (mediaAttachments) setMediaAttachments(mediaAttachments);\n }\n }, [draftStatus, editStatus, replyToStatus]);\n\n const formRef = useRef();\n\n const beforeUnloadCopy = t`You have unsaved changes. Discard this post?`;\n const canClose = () => {\n const { value, dataset } = textareaRef.current;\n\n // check if loading\n if (uiState === 'loading') {\n console.log('canClose', { uiState });\n return false;\n }\n\n // check for status and media attachments\n const hasValue = (value || '')\n .trim()\n .replace(/^\\p{White_Space}+|\\p{White_Space}+$/gu, '');\n const hasMediaAttachments = mediaAttachments.length > 0;\n if (!hasValue && !hasMediaAttachments) {\n console.log('canClose', { value, mediaAttachments });\n return true;\n }\n\n // check if all media attachments have IDs\n const hasIDMediaAttachments =\n mediaAttachments.length > 0 &&\n mediaAttachments.every((media) => media.id);\n if (hasIDMediaAttachments) {\n console.log('canClose', { hasIDMediaAttachments });\n return true;\n }\n\n // check if status contains only \"@acct\", if replying\n const isSelf = replyToStatus?.account.id === currentAccountInfo.id;\n const hasOnlyAcct =\n replyToStatus && value.trim() === `@${replyToStatus.account.acct}`;\n // TODO: check for mentions, or maybe just generic \"@username<space>\", including multiple mentions like \"@username1<space>@username2<space>\"\n if (!isSelf && hasOnlyAcct) {\n console.log('canClose', { isSelf, hasOnlyAcct });\n return true;\n }\n\n // check if status is same with source\n const sameWithSource = value === dataset?.source;\n if (sameWithSource) {\n console.log('canClose', { sameWithSource });\n return true;\n }\n\n console.log('canClose', {\n value,\n hasMediaAttachments,\n hasIDMediaAttachments,\n poll,\n isSelf,\n hasOnlyAcct,\n sameWithSource,\n uiState,\n });\n\n return false;\n };\n\n const confirmClose = () => {\n if (!canClose()) {\n const yes = confirm(beforeUnloadCopy);\n return yes;\n }\n return true;\n };\n\n useEffect(() => {\n // Show warning if user tries to close window with unsaved changes\n const handleBeforeUnload = (e) => {\n if (!canClose()) {\n e.preventDefault();\n e.returnValue = beforeUnloadCopy;\n }\n };\n window.addEventListener('beforeunload', handleBeforeUnload, {\n capture: true,\n });\n return () =>\n window.removeEventListener('beforeunload', handleBeforeUnload, {\n capture: true,\n });\n }, []);\n\n const getCharCount = () => {\n const { value } = textareaRef.current;\n const { value: spoilerText } = spoilerTextRef.current;\n return stringLength(countableText(value)) + stringLength(spoilerText);\n };\n const updateCharCount = () => {\n const count = getCharCount();\n states.composerCharacterCount = count;\n };\n useEffect(updateCharCount, []);\n\n const supportsCloseWatcher = window.CloseWatcher;\n const escDownRef = useRef(false);\n useHotkeys(\n 'esc',\n () => {\n escDownRef.current = true;\n // This won't be true if this event is already handled and not propagated 🤞\n },\n {\n enabled: !supportsCloseWatcher,\n enableOnFormTags: true,\n },\n );\n useHotkeys(\n 'esc',\n () => {\n if (!standalone && escDownRef.current && confirmClose()) {\n onClose();\n }\n escDownRef.current = false;\n },\n {\n enabled: !supportsCloseWatcher,\n enableOnFormTags: true,\n // Use keyup because Esc keydown will close the confirm dialog on Safari\n keyup: true,\n ignoreEventWhen: (e) => {\n const modals = document.querySelectorAll('#modal-container > *');\n const hasModal = !!modals;\n const hasOnlyComposer =\n modals.length === 1 && modals[0].querySelector('#compose-container');\n return hasModal && !hasOnlyComposer;\n },\n },\n );\n useCloseWatcher(() => {\n if (!standalone && confirmClose()) {\n onClose();\n }\n }, [standalone, confirmClose, onClose]);\n\n const prevBackgroundDraft = useRef({});\n const draftKey = () => {\n const ns = getCurrentAccountNS();\n return `${ns}#${UID.current}`;\n };\n const saveUnsavedDraft = () => {\n // Not enabling this for editing status\n // I don't think this warrant a draft mode for a status that's already posted\n // Maybe it could be a big edit change but it should be rare\n if (editStatus) return;\n if (states.composerState.minimized) return;\n const key = draftKey();\n const backgroundDraft = {\n key,\n replyTo: replyToStatus\n ? {\n /* Smaller payload of replyToStatus. Reasons:\n - No point storing whole thing\n - Could have media attachments\n - Could be deleted/edited later\n */\n id: replyToStatus.id,\n account: {\n id: replyToStatus.account.id,\n username: replyToStatus.account.username,\n acct: replyToStatus.account.acct,\n },\n }\n : null,\n draftStatus: {\n uid: UID.current,\n status: textareaRef.current.value,\n spoilerText: spoilerTextRef.current.value,\n visibility,\n language,\n sensitive,\n poll,\n mediaAttachments,\n },\n };\n if (\n !deepEqual(backgroundDraft, prevBackgroundDraft.current) &&\n !canClose()\n ) {\n console.debug('not equal', backgroundDraft, prevBackgroundDraft.current);\n db.drafts\n .set(key, {\n ...backgroundDraft,\n state: 'unsaved',\n updatedAt: Date.now(),\n })\n .then(() => {\n console.debug('DRAFT saved', key, backgroundDraft);\n })\n .catch((e) => {\n console.error('DRAFT failed', key, e);\n });\n prevBackgroundDraft.current = structuredClone(backgroundDraft);\n }\n };\n useInterval(saveUnsavedDraft, 5000); // background save every 5s\n useEffect(() => {\n saveUnsavedDraft();\n // If unmounted, means user discarded the draft\n // Also means pop-out 🙈, but it's okay because the pop-out will persist the ID and re-create the draft\n return () => {\n db.drafts.del(draftKey());\n };\n }, []);\n\n useEffect(() => {\n const handleItems = (e) => {\n const { items } = e.clipboardData || e.dataTransfer;\n const files = [];\n const unsupportedFiles = [];\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (item.kind === 'file') {\n const file = item.getAsFile();\n if (\n supportedMimeTypes !== undefined &&\n !supportedMimeTypes.includes(file.type)\n ) {\n unsupportedFiles.push(file);\n } else {\n files.push(file);\n }\n }\n }\n if (unsupportedFiles.length > 0) {\n alert(\n plural(unsupportedFiles.length, {\n one: `File ${unsupportedFiles[0].name} is not supported.`,\n other: `Files ${lf.format(\n unsupportedFiles.map((f) => f.name),\n )} are not supported.`,\n }),\n );\n }\n if (files.length > 0 && mediaAttachments.length >= maxMediaAttachments) {\n alert(\n plural(maxMediaAttachments, {\n one: 'You can only attach up to 1 file.',\n other: 'You can only attach up to # files.',\n }),\n );\n return;\n }\n console.log({ files });\n if (files.length > 0) {\n e.preventDefault();\n e.stopPropagation();\n // Auto-cut-off files to avoid exceeding maxMediaAttachments\n let allowedFiles = files;\n if (maxMediaAttachments !== undefined) {\n const max = maxMediaAttachments - mediaAttachments.length;\n allowedFiles = allowedFiles.slice(0, max);\n if (allowedFiles.length <= 0) {\n alert(\n plural(maxMediaAttachments, {\n one: 'You can only attach up to 1 file.',\n other: 'You can only attach up to # files.',\n }),\n );\n return;\n }\n }\n const mediaFiles = allowedFiles.map((file) => ({\n file,\n type: file.type,\n size: file.size,\n url: URL.createObjectURL(file),\n id: null,\n description: null,\n }));\n setMediaAttachments([...mediaAttachments, ...mediaFiles]);\n }\n };\n window.addEventListener('paste', handleItems);\n const handleDragover = (e) => {\n // Prevent default if there's files\n if (e.dataTransfer.items.length > 0) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n window.addEventListener('dragover', handleDragover);\n window.addEventListener('drop', handleItems);\n return () => {\n window.removeEventListener('paste', handleItems);\n window.removeEventListener('dragover', handleDragover);\n window.removeEventListener('drop', handleItems);\n };\n }, [mediaAttachments]);\n\n const [showMentionPicker, setShowMentionPicker] = useState(false);\n const [showEmoji2Picker, setShowEmoji2Picker] = useState(false);\n const [showGIFPicker, setShowGIFPicker] = useState(false);\n\n const [autoDetectedLanguages, setAutoDetectedLanguages] = useState(null);\n const [topSupportedLanguages, restSupportedLanguages] = useMemo(() => {\n const topLanguages = [];\n const restLanguages = [];\n const { contentTranslationHideLanguages = [] } = states.settings;\n supportedLanguages.forEach((l) => {\n const [code] = l;\n if (\n code === language ||\n code === prevLanguage.current ||\n code === DEFAULT_LANG ||\n contentTranslationHideLanguages.includes(code) ||\n (autoDetectedLanguages?.length && autoDetectedLanguages.includes(code))\n ) {\n topLanguages.push(l);\n } else {\n restLanguages.push(l);\n }\n });\n topLanguages.sort(([codeA, commonA], [codeB, commonB]) => {\n if (codeA === language) return -1;\n if (codeB === language) return 1;\n return commonA.localeCompare(commonB);\n });\n restLanguages.sort(([codeA, commonA], [codeB, commonB]) =>\n commonA.localeCompare(commonB),\n );\n return [topLanguages, restLanguages];\n }, [language, autoDetectedLanguages]);\n\n const replyToStatusMonthsAgo = useMemo(\n () =>\n !!replyToStatus?.createdAt &&\n Math.floor(\n (Date.now() - new Date(replyToStatus.createdAt)) /\n (1000 * 60 * 60 * 24 * 30),\n ),\n [replyToStatus],\n );\n\n const onMinimize = () => {\n saveUnsavedDraft();\n states.composerState.minimized = true;\n };\n\n const gifPickerDisabled =\n uiState === 'loading' ||\n (maxMediaAttachments !== undefined &&\n mediaAttachments.length >= maxMediaAttachments) ||\n !!poll;\n\n // If maxOptions is not defined or defined and is greater than 1, show poll button\n const showPollButton = maxOptions == null || maxOptions > 1;\n const pollButtonDisabled =\n uiState === 'loading' || !!poll || !!mediaAttachments.length;\n const onPollButtonClick = () => {\n setPoll({\n options: ['', ''],\n expiresIn: 24 * 60 * 60, // 1 day\n multiple: false,\n });\n };\n\n const addSubToolbarRef = useRef();\n const [showAddButton, setShowAddButton] = useState(false);\n useResizeObserver({\n ref: addSubToolbarRef,\n box: 'border-box',\n onResize: ({ width }) => {\n // If scrollable, it's truncated\n const { scrollWidth } = addSubToolbarRef.current;\n const truncated = scrollWidth > width;\n const overTruncated = width < 84; // roughly two buttons width\n setShowAddButton(overTruncated || truncated);\n addSubToolbarRef.current.hidden = overTruncated;\n },\n });\n\n return (\n <div id=\"compose-container-outer\">\n <div id=\"compose-container\" class={standalone ? 'standalone' : ''}>\n <div class=\"compose-top\">\n {currentAccountInfo?.avatarStatic && (\n // <Avatar\n // url={currentAccountInfo.avatarStatic}\n // size=\"xl\"\n // alt={currentAccountInfo.username}\n // squircle={currentAccountInfo?.bot}\n // />\n <AccountBlock\n account={currentAccountInfo}\n accountInstance={currentAccount.instanceURL}\n hideDisplayName\n useAvatarStatic\n />\n )}\n {!standalone ? (\n <span class=\"compose-controls\">\n <button\n type=\"button\"\n class=\"plain4 pop-button\"\n disabled={uiState === 'loading'}\n onClick={() => {\n // If there are non-ID media attachments (not yet uploaded), show confirmation dialog because they are not going to be passed to the new window\n // const containNonIDMediaAttachments =\n // mediaAttachments.length > 0 &&\n // mediaAttachments.some((media) => !media.id);\n // if (containNonIDMediaAttachments) {\n // const yes = confirm(\n // 'You have media attachments that are not yet uploaded. Opening a new window will discard them and you will need to re-attach them. Are you sure you want to continue?',\n // );\n // if (!yes) {\n // return;\n // }\n // }\n\n // const mediaAttachmentsWithIDs = mediaAttachments.filter(\n // (media) => media.id,\n // );\n\n const newWin = openCompose({\n editStatus,\n replyToStatus,\n draftStatus: {\n uid: UID.current,\n status: textareaRef.current.value,\n spoilerText: spoilerTextRef.current.value,\n visibility,\n language,\n sensitive,\n poll,\n mediaAttachments,\n },\n });\n\n if (!newWin) {\n return;\n }\n\n onClose();\n }}\n >\n <Icon icon=\"popout\" alt={t`Pop out`} />\n </button>\n <button\n type=\"button\"\n class=\"plain4 min-button\"\n onClick={onMinimize}\n >\n <Icon icon=\"minimize\" alt={t`Minimize`} />\n </button>{' '}\n <button\n type=\"button\"\n class=\"light close-button\"\n disabled={uiState === 'loading'}\n onClick={() => {\n if (confirmClose()) {\n onClose();\n }\n }}\n >\n <Icon icon=\"x\" alt={t`Close`} />\n </button>\n </span>\n ) : (\n hasOpener && (\n <button\n type=\"button\"\n class=\"light pop-button\"\n disabled={uiState === 'loading'}\n onClick={() => {\n // If there are non-ID media attachments (not yet uploaded), show confirmation dialog because they are not going to be passed to the new window\n // const containNonIDMediaAttachments =\n // mediaAttachments.length > 0 &&\n // mediaAttachments.some((media) => !media.id);\n // if (containNonIDMediaAttachments) {\n // const yes = confirm(\n // 'You have media attachments that are not yet uploaded. Opening a new window will discard them and you will need to re-attach them. Are you sure you want to continue?',\n // );\n // if (!yes) {\n // return;\n // }\n // }\n\n if (!window.opener) {\n alert(t`Looks like you closed the parent window.`);\n return;\n }\n\n if (window.opener.__STATES__.showCompose) {\n if (window.opener.__STATES__.composerState?.publishing) {\n alert(\n t`Looks like you already have a compose field open in the parent window and currently publishing. Please wait for it to be done and try again later.`,\n );\n return;\n }\n\n let confirmText = t`Looks like you already have a compose field open in the parent window. Popping in this window will discard the changes you made in the parent window. Continue?`;\n const yes = confirm(confirmText);\n if (!yes) return;\n }\n\n // const mediaAttachmentsWithIDs = mediaAttachments.filter(\n // (media) => media.id,\n // );\n\n onClose({\n fn: () => {\n const passData = {\n editStatus,\n replyToStatus,\n draftStatus: {\n uid: UID.current,\n status: textareaRef.current.value,\n spoilerText: spoilerTextRef.current.value,\n visibility,\n language,\n sensitive,\n poll,\n mediaAttachments,\n },\n };\n window.opener.__COMPOSE__ = passData; // Pass it here instead of `showCompose` due to some weird proxy issue again\n if (window.opener.__STATES__.showCompose) {\n window.opener.__STATES__.showCompose = false;\n setTimeout(() => {\n window.opener.__STATES__.showCompose = true;\n }, 10);\n } else {\n window.opener.__STATES__.showCompose = true;\n }\n if (window.opener.__STATES__.composerState.minimized) {\n // Maximize it\n window.opener.__STATES__.composerState.minimized = false;\n }\n },\n });\n }}\n >\n <Icon icon=\"popin\" alt={t`Pop in`} />\n </button>\n )\n )}\n </div>\n {!!replyToStatus && (\n <div class=\"status-preview\">\n <Status status={replyToStatus} size=\"s\" previewMode />\n <div class=\"status-preview-legend reply-to\">\n {replyToStatusMonthsAgo > 0 ? (\n <Trans>\n Replying to @\n {replyToStatus.account.acct || replyToStatus.account.username}\n &rsquo;s post (\n <strong>\n {rtf.format(-replyToStatusMonthsAgo, 'month')}\n </strong>\n )\n </Trans>\n ) : (\n <Trans>\n Replying to @\n {replyToStatus.account.acct || replyToStatus.account.username}\n &rsquo;s post\n </Trans>\n )}\n </div>\n </div>\n )}\n {!!editStatus && (\n <div class=\"status-preview\">\n <Status status={editStatus} size=\"s\" previewMode />\n <div class=\"status-preview-legend\">\n <Trans>Editing source post</Trans>\n </div>\n </div>\n )}\n <form\n ref={formRef}\n class={`form-visibility-${visibility}`}\n style={{\n pointerEvents: uiState === 'loading' ? 'none' : 'auto',\n opacity: uiState === 'loading' ? 0.5 : 1,\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {\n formRef.current.dispatchEvent(\n new Event('submit', { cancelable: true }),\n );\n }\n }}\n onSubmit={(e) => {\n e.preventDefault();\n\n const formData = new FormData(e.target);\n const entries = Object.fromEntries(formData.entries());\n console.log('ENTRIES', entries);\n let { status, visibility, sensitive, spoilerText } = entries;\n\n // Pre-cleanup\n sensitive = sensitive === 'on'; // checkboxes return \"on\" if checked\n\n // Validation\n /* Let the backend validate this\n if (stringLength(status) > maxCharacters) {\n alert(`Status is too long! Max characters: ${maxCharacters}`);\n return;\n }\n if (\n sensitive &&\n stringLength(status) + stringLength(spoilerText) > maxCharacters\n ) {\n alert(\n `Status and content warning is too long! Max characters: ${maxCharacters}`,\n );\n return;\n }\n */\n if (poll) {\n if (poll.options.length < 2) {\n alert(t`Poll must have at least 2 options`);\n return;\n }\n if (poll.options.some((option) => option === '')) {\n alert(t`Some poll choices are empty`);\n return;\n }\n }\n // TODO: check for URLs and use `charactersReservedPerUrl` to calculate max characters\n\n if (mediaAttachments.length > 0) {\n // If there are media attachments, check if they have no descriptions\n const hasNoDescriptions = mediaAttachments.some(\n (media) => !media.description?.trim?.(),\n );\n if (hasNoDescriptions) {\n const yes = confirm(\n t`Some media have no descriptions. Continue?`,\n );\n if (!yes) return;\n }\n }\n\n // Post-cleanup\n spoilerText = (sensitive && spoilerText) || undefined;\n status = status === '' ? undefined : status;\n\n // states.composerState.minimized = true;\n states.composerState.publishing = true;\n setUIState('loading');\n (async () => {\n try {\n console.log('MEDIA ATTACHMENTS', mediaAttachments);\n if (mediaAttachments.length > 0) {\n // Upload media attachments first\n const mediaPromises = mediaAttachments.map((attachment) => {\n const { file, description, id } = attachment;\n console.log('UPLOADING', attachment);\n if (id) {\n // If already uploaded\n return attachment;\n } else {\n const params = removeNullUndefined({\n file,\n description,\n });\n return masto.v2.media.create(params).then((res) => {\n if (res.id) {\n attachment.id = res.id;\n }\n return res;\n });\n }\n });\n const results = await Promise.allSettled(mediaPromises);\n\n // If any failed, return\n if (\n results.some((result) => {\n return result.status === 'rejected' || !result.value?.id;\n })\n ) {\n states.composerState.publishing = false;\n states.composerState.publishingError = true;\n setUIState('error');\n // Alert all the reasons\n results.forEach((result) => {\n if (result.status === 'rejected') {\n console.error(result);\n alert(result.reason || t`Attachment #${i} failed`);\n }\n });\n return;\n }\n\n console.log({ results, mediaAttachments });\n }\n\n /* NOTE:\n Using snakecase here because masto.js's `isObject` returns false for `params`, ONLY happens when opening in pop-out window. This is maybe due to `window.masto` variable being passed from the parent window. The check that failed is `x.constructor === Object`, so maybe the `Object` in new window is different than parent window's?\n Code: https://github.com/neet/masto.js/blob/dd0d649067b6a2b6e60fbb0a96597c373a255b00/src/serializers/is-object.ts#L2\n\n // TODO: Note above is no longer true in Masto.js v6. Revisit this.\n */\n let params = {\n status,\n // spoilerText,\n spoiler_text: spoilerText,\n language,\n sensitive,\n poll,\n // mediaIds: mediaAttachments.map((attachment) => attachment.id),\n media_ids: mediaAttachments.map(\n (attachment) => attachment.id,\n ),\n };\n if (editStatus && supports('@mastodon/edit-media-attributes')) {\n params.media_attributes = mediaAttachments.map(\n (attachment) => {\n return {\n id: attachment.id,\n description: attachment.description,\n // focus\n // thumbnail\n };\n },\n );\n } else if (!editStatus) {\n params.visibility = visibility;\n // params.inReplyToId = replyToStatus?.id || undefined;\n params.in_reply_to_id = replyToStatus?.id || undefined;\n }\n params = removeNullUndefined(params);\n console.log('POST', params);\n\n let newStatus;\n if (editStatus) {\n newStatus = await masto.v1.statuses\n .$select(editStatus.id)\n .update(params);\n saveStatus(newStatus, instance, {\n skipThreading: true,\n });\n } else {\n try {\n newStatus = await masto.v1.statuses.create(params, {\n requestInit: {\n headers: {\n 'Idempotency-Key': UID.current,\n },\n },\n });\n } catch (_) {\n // If idempotency key fails, try again without it\n newStatus = await masto.v1.statuses.create(params);\n }\n }\n states.composerState.minimized = false;\n states.composerState.publishing = false;\n setUIState('default');\n\n // Close\n onClose({\n // type: post, reply, edit\n type: editStatus ? 'edit' : replyToStatus ? 'reply' : 'post',\n newStatus,\n instance,\n });\n } catch (e) {\n states.composerState.publishing = false;\n states.composerState.publishingError = true;\n console.error(e);\n alert(e?.reason || e);\n setUIState('error');\n }\n })();\n }}\n >\n <div class=\"toolbar stretch\">\n <input\n ref={spoilerTextRef}\n type=\"text\"\n name=\"spoilerText\"\n placeholder={t`Content warning`}\n disabled={uiState === 'loading'}\n class=\"spoiler-text-field\"\n lang={language}\n spellCheck=\"true\"\n dir=\"auto\"\n style={{\n opacity: sensitive ? 1 : 0,\n pointerEvents: sensitive ? 'auto' : 'none',\n }}\n onInput={() => {\n updateCharCount();\n }}\n />\n <label\n class={`toolbar-button ${sensitive ? 'highlight' : ''}`}\n title={t`Content warning or sensitive media`}\n >\n <input\n name=\"sensitive\"\n type=\"checkbox\"\n checked={sensitive}\n disabled={uiState === 'loading'}\n onChange={(e) => {\n const sensitive = e.target.checked;\n setSensitive(sensitive);\n if (sensitive) {\n spoilerTextRef.current?.focus();\n } else {\n textareaRef.current?.focus();\n }\n }}\n />\n <Icon icon={`eye-${sensitive ? 'close' : 'open'}`} />\n </label>{' '}\n <label\n class={`toolbar-button ${\n visibility !== 'public' && !sensitive ? 'show-field' : ''\n } ${visibility !== 'public' ? 'highlight' : ''}`}\n title={visibility}\n >\n <Icon icon={visibilityIconsMap[visibility]} alt={visibility} />\n <select\n name=\"visibility\"\n value={visibility}\n onChange={(e) => {\n setVisibility(e.target.value);\n }}\n disabled={uiState === 'loading' || !!editStatus}\n dir=\"auto\"\n >\n <option value=\"public\">\n <Trans>Public</Trans>\n </option>\n {(supports('@pleroma/local-visibility-post') ||\n supports('@akkoma/local-visibility-post')) && (\n <option value=\"local\">\n <Trans>Local</Trans>\n </option>\n )}\n <option value=\"unlisted\">\n <Trans>Unlisted</Trans>\n </option>\n <option value=\"private\">\n <Trans>Followers only</Trans>\n </option>\n <option value=\"direct\">\n <Trans>Private mention</Trans>\n </option>\n </select>\n </label>{' '}\n </div>\n <Textarea\n ref={textareaRef}\n placeholder={\n replyToStatus\n ? t`Post your reply`\n : editStatus\n ? t`Edit your post`\n : t`What are you doing?`\n }\n required={mediaAttachments?.length === 0}\n disabled={uiState === 'loading'}\n lang={language}\n onInput={() => {\n updateCharCount();\n }}\n maxCharacters={maxCharacters}\n performSearch={(params) => {\n const { type, q, limit } = params;\n if (type === 'accounts') {\n return masto.v1.accounts.search.list({\n q,\n limit,\n resolve: false,\n });\n }\n return masto.v2.search.fetch(params);\n }}\n onTrigger={(action) => {\n if (action?.name === 'custom-emojis') {\n setShowEmoji2Picker({\n defaultSearchTerm: action?.defaultSearchTerm || null,\n });\n } else if (action?.name === 'mention') {\n setShowMentionPicker({\n defaultSearchTerm: action?.defaultSearchTerm || null,\n });\n } else if (\n action?.name === 'auto-detect-language' &&\n action?.languages\n ) {\n setAutoDetectedLanguages(action.languages);\n }\n }}\n />\n {mediaAttachments?.length > 0 && (\n <div class=\"media-attachments\">\n {mediaAttachments.map((attachment, i) => {\n const { id, file } = attachment;\n const fileID = file?.size + file?.type + file?.name;\n return (\n <MediaAttachment\n key={id || fileID || i}\n attachment={attachment}\n disabled={uiState === 'loading'}\n lang={language}\n onDescriptionChange={(value) => {\n setMediaAttachments((attachments) => {\n const newAttachments = [...attachments];\n newAttachments[i] = {\n ...newAttachments[i],\n description: value,\n };\n return newAttachments;\n });\n }}\n onRemove={() => {\n setMediaAttachments((attachments) => {\n return attachments.filter((_, j) => j !== i);\n });\n }}\n />\n );\n })}\n <label class=\"media-sensitive\">\n <input\n name=\"sensitive\"\n type=\"checkbox\"\n checked={sensitive}\n disabled={uiState === 'loading'}\n onChange={(e) => {\n const sensitive = e.target.checked;\n setSensitive(sensitive);\n }}\n />{' '}\n <span>\n <Trans>Mark media as sensitive</Trans>\n </span>{' '}\n <Icon icon={`eye-${sensitive ? 'close' : 'open'}`} />\n </label>\n </div>\n )}\n {!!poll && (\n <Poll\n lang={language}\n maxOptions={maxOptions}\n maxExpiration={maxExpiration}\n minExpiration={minExpiration}\n maxCharactersPerOption={maxCharactersPerOption}\n poll={poll}\n disabled={uiState === 'loading'}\n onInput={(poll) => {\n if (poll) {\n const newPoll = { ...poll };\n setPoll(newPoll);\n } else {\n setPoll(null);\n }\n }}\n />\n )}\n <div class=\"toolbar compose-footer\">\n <span class=\"add-toolbar-button-group spacer\">\n {showAddButton && (\n <Menu2\n portal={{\n target: document.body,\n }}\n containerProps={{\n style: {\n zIndex: 1001,\n },\n }}\n menuButton={({ open }) => (\n <button\n type=\"button\"\n class={`toolbar-button add-button ${\n open ? 'active' : ''\n }`}\n >\n <Icon icon=\"plus\" title={t`Add`} />\n </button>\n )}\n >\n <MenuItem className=\"compose-menu-add-media\">\n <label class=\"compose-menu-add-media-field\">\n <FilePickerInput\n hidden\n supportedMimeTypes={supportedMimeTypes}\n maxMediaAttachments={maxMediaAttachments}\n mediaAttachments={mediaAttachments}\n disabled={\n uiState === 'loading' ||\n mediaAttachments.length >= maxMediaAttachments ||\n !!poll\n }\n setMediaAttachments={setMediaAttachments}\n />\n </label>\n <Icon icon=\"media\" /> <span>{_(ADD_LABELS.media)}</span>\n </MenuItem>\n <MenuItem\n onClick={() => {\n setShowEmoji2Picker(true);\n }}\n >\n <Icon icon=\"emoji2\" />{' '}\n <span>{_(ADD_LABELS.customEmoji)}</span>\n </MenuItem>\n {!!states.settings.composerGIFPicker && (\n <MenuItem\n disabled={gifPickerDisabled}\n onClick={() => {\n setShowGIFPicker(true);\n }}\n >\n <span class=\"icon icon-gif\" role=\"img\" />\n <span>{_(ADD_LABELS.gif)}</span>\n </MenuItem>\n )}\n <MenuItem\n disabled={pollButtonDisabled}\n onClick={onPollButtonClick}\n >\n <Icon icon=\"poll\" /> <span>{_(ADD_LABELS.poll)}</span>\n </MenuItem>\n </Menu2>\n )}\n <span class=\"add-sub-toolbar-button-group\" ref={addSubToolbarRef}>\n <label class=\"toolbar-button\">\n <FilePickerInput\n supportedMimeTypes={supportedMimeTypes}\n maxMediaAttachments={maxMediaAttachments}\n mediaAttachments={mediaAttachments}\n disabled={\n uiState === 'loading' ||\n mediaAttachments.length >= maxMediaAttachments ||\n !!poll\n }\n setMediaAttachments={setMediaAttachments}\n />\n <Icon icon=\"media\" alt={_(ADD_LABELS.media)} />\n </label>\n {/* <button\n type=\"button\"\n class=\"toolbar-button\"\n disabled={uiState === 'loading'}\n onClick={() => {\n setShowMentionPicker(true);\n }}\n >\n <Icon icon=\"at\" />\n </button> */}\n <button\n type=\"button\"\n class=\"toolbar-button\"\n disabled={uiState === 'loading'}\n onClick={() => {\n setShowEmoji2Picker(true);\n }}\n >\n <Icon icon=\"emoji2\" alt={_(ADD_LABELS.customEmoji)} />\n </button>\n {!!states.settings.composerGIFPicker && (\n <button\n type=\"button\"\n class=\"toolbar-button gif-picker-button\"\n disabled={gifPickerDisabled}\n onClick={() => {\n setShowGIFPicker(true);\n }}\n >\n <span\n class=\"icon icon-gif\"\n aria-label={_(ADD_LABELS.gif)}\n />\n </button>\n )}\n {}\n {showPollButton && (\n <>\n <button\n type=\"button\"\n class=\"toolbar-button\"\n disabled={pollButtonDisabled}\n onClick={onPollButtonClick}\n >\n <Icon icon=\"poll\" alt={_(ADD_LABELS.poll)} />\n </button>\n </>\n )}\n </span>\n </span>\n {/* <div class=\"spacer\" /> */}\n {uiState === 'loading' ? (\n <Loader abrupt />\n ) : (\n <CharCountMeter\n maxCharacters={maxCharacters}\n hidden={uiState === 'loading'}\n />\n )}\n <label\n class={`toolbar-button ${\n language !== prevLanguage.current ||\n (autoDetectedLanguages?.length &&\n !autoDetectedLanguages.includes(language))\n ? 'highlight'\n : ''\n }`}\n >\n <span class=\"icon-text\">\n {supportedLanguagesMap[language]?.native}\n </span>\n <select\n name=\"language\"\n value={language}\n onChange={(e) => {\n const { value } = e.target;\n setLanguage(value || DEFAULT_LANG);\n store.session.set('currentLanguage', value || DEFAULT_LANG);\n }}\n disabled={uiState === 'loading'}\n dir=\"auto\"\n >\n {topSupportedLanguages.map(([code, common, native]) => {\n const commonText = localeCode2Text({\n code,\n fallback: common,\n });\n const showCommon = commonText !== native;\n return (\n <option value={code} key={code}>\n {showCommon ? `${native} - ${commonText}` : commonText}\n </option>\n );\n })}\n <hr />\n {restSupportedLanguages.map(([code, common, native]) => {\n const commonText = localeCode2Text({\n code,\n fallback: common,\n });\n const showCommon = commonText !== native;\n return (\n <option value={code} key={code}>\n {showCommon ? `${native} - ${commonText}` : commonText}\n </option>\n );\n })}\n </select>\n </label>{' '}\n <button type=\"submit\" disabled={uiState === 'loading'}>\n {replyToStatus\n ? t`Reply`\n : editStatus\n ? t`Update`\n : t({\n message: 'Post',\n context: 'Submit button in composer',\n })}\n </button>\n </div>\n </form>\n </div>\n {showMentionPicker && (\n <Modal\n onClick={(e) => {\n if (e.target === e.currentTarget) {\n setShowMentionPicker(false);\n }\n }}\n >\n <MentionModal\n masto={masto}\n instance={instance}\n onClose={() => {\n setShowMentionPicker(false);\n }}\n defaultSearchTerm={showMentionPicker?.defaultSearchTerm}\n onSelect={(socialAddress) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n const { selectionStart, selectionEnd } = textarea;\n const text = textarea.value;\n const textBeforeMention = text.slice(0, selectionStart);\n const spaceBeforeMention = textBeforeMention\n ? /[\\s\\t\\n\\r]$/.test(textBeforeMention)\n ? ''\n : ' '\n : '';\n const textAfterMention = text.slice(selectionEnd);\n const spaceAfterMention = /^[\\s\\t\\n\\r]/.test(textAfterMention)\n ? ''\n : ' ';\n const newText =\n textBeforeMention +\n spaceBeforeMention +\n '@' +\n socialAddress +\n spaceAfterMention +\n textAfterMention;\n textarea.value = newText;\n textarea.selectionStart = textarea.selectionEnd =\n selectionEnd +\n 1 +\n socialAddress.length +\n spaceAfterMention.length;\n textarea.focus();\n textarea.dispatchEvent(new Event('input'));\n }}\n />\n </Modal>\n )}\n {showEmoji2Picker && (\n <Modal\n onClick={(e) => {\n if (e.target === e.currentTarget) {\n setShowEmoji2Picker(false);\n }\n }}\n >\n <CustomEmojisModal\n masto={masto}\n instance={instance}\n onClose={() => {\n setShowEmoji2Picker(false);\n }}\n defaultSearchTerm={showEmoji2Picker?.defaultSearchTerm}\n onSelect={(emojiShortcode) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n const { selectionStart, selectionEnd } = textarea;\n const text = textarea.value;\n const textBeforeEmoji = text.slice(0, selectionStart);\n const spaceBeforeEmoji = textBeforeEmoji\n ? /[\\s\\t\\n\\r]$/.test(textBeforeEmoji)\n ? ''\n : ' '\n : '';\n const textAfterEmoji = text.slice(selectionEnd);\n const spaceAfterEmoji = /^[\\s\\t\\n\\r]/.test(textAfterEmoji)\n ? ''\n : ' ';\n const newText =\n textBeforeEmoji +\n spaceBeforeEmoji +\n emojiShortcode +\n spaceAfterEmoji +\n textAfterEmoji;\n textarea.value = newText;\n textarea.selectionStart = textarea.selectionEnd =\n selectionEnd + emojiShortcode.length + spaceAfterEmoji.length;\n textarea.focus();\n textarea.dispatchEvent(new Event('input'));\n }}\n />\n </Modal>\n )}\n {showGIFPicker && (\n <Modal\n onClick={(e) => {\n if (e.target === e.currentTarget) {\n setShowGIFPicker(false);\n }\n }}\n >\n <GIFPickerModal\n onClose={() => setShowGIFPicker(false)}\n onSelect={({ url, type, alt_text }) => {\n console.log('GIF URL', url);\n if (mediaAttachments.length >= maxMediaAttachments) {\n alert(\n plural(maxMediaAttachments, {\n one: 'You can only attach up to 1 file.',\n other: 'You can only attach up to # files.',\n }),\n );\n return;\n }\n // Download the GIF and insert it as media attachment\n (async () => {\n let theToast;\n try {\n theToast = showToast({\n text: t`Downloading GIF…`,\n duration: -1,\n });\n const blob = await fetch(url, {\n referrerPolicy: 'no-referrer',\n }).then((res) => res.blob());\n const file = new File(\n [blob],\n type === 'video/mp4' ? 'video.mp4' : 'image.gif',\n {\n type,\n },\n );\n const newMediaAttachments = [\n ...mediaAttachments,\n {\n file,\n type,\n size: file.size,\n id: null,\n description: alt_text || '',\n },\n ];\n setMediaAttachments(newMediaAttachments);\n theToast?.hideToast?.();\n } catch (err) {\n console.error(err);\n theToast?.hideToast?.();\n showToast(t`Failed to download GIF`);\n }\n })();\n }}\n />\n </Modal>\n )}\n </div>\n );\n}\n\nfunction FilePickerInput({\n hidden,\n supportedMimeTypes,\n maxMediaAttachments,\n mediaAttachments,\n disabled = false,\n setMediaAttachments,\n}) {\n return (\n <input\n type=\"file\"\n hidden={hidden}\n accept={supportedMimeTypes?.join(',')}\n multiple={\n maxMediaAttachments === undefined ||\n maxMediaAttachments - mediaAttachments >= 2\n }\n disabled={disabled}\n onChange={(e) => {\n const files = e.target.files;\n if (!files) return;\n\n const mediaFiles = Array.from(files).map((file) => ({\n file,\n type: file.type,\n size: file.size,\n url: URL.createObjectURL(file),\n id: null, // indicate uploaded state\n description: null,\n }));\n console.log('MEDIA ATTACHMENTS', files, mediaFiles);\n\n // Validate max media attachments\n if (mediaAttachments.length + mediaFiles.length > maxMediaAttachments) {\n alert(\n plural(maxMediaAttachments, {\n one: 'You can only attach up to 1 file.',\n other: 'You can only attach up to # files.',\n }),\n );\n } else {\n setMediaAttachments((attachments) => {\n return attachments.concat(mediaFiles);\n });\n }\n // Reset\n e.target.value = '';\n }}\n />\n );\n}\n\nfunction autoResizeTextarea(textarea) {\n if (!textarea) return;\n const { value, offsetHeight, scrollHeight, clientHeight } = textarea;\n if (offsetHeight < window.innerHeight) {\n // NOTE: This check is needed because the offsetHeight return 50000 (really large number) on first render\n // No idea why it does that, will re-investigate in far future\n const offset = offsetHeight - clientHeight;\n const height = value ? scrollHeight + offset + 'px' : null;\n textarea.style.height = height;\n }\n}\n\nasync function _getCustomEmojis(instance, masto) {\n const emojis = await masto.v1.customEmojis.list();\n const visibleEmojis = emojis.filter((e) => e.visibleInPicker);\n const searcher = new Fuse(visibleEmojis, {\n keys: ['shortcode'],\n findAllMatches: true,\n });\n return [visibleEmojis, searcher];\n}\nconst getCustomEmojis = pmem(_getCustomEmojis, {\n // Limit by time to reduce memory usage\n // Cached by instance\n matchesArg: (cacheKeyArg, keyArg) => cacheKeyArg.instance === keyArg.instance,\n maxAge: 30 * 60 * 1000, // 30 minutes\n});\n\nconst detectLangs = async (text) => {\n const { detectAll } = await import('tinyld/light');\n const langs = detectAll(text);\n if (langs?.length) {\n // return max 2\n return langs.slice(0, 2).map((lang) => lang.lang);\n }\n return null;\n};\n\nconst Textarea = forwardRef((props, ref) => {\n const { masto, instance } = api();\n const [text, setText] = useState(ref.current?.value || '');\n const {\n maxCharacters,\n performSearch = () => {},\n onTrigger = () => {},\n ...textareaProps\n } = props;\n // const snapStates = useSnapshot(states);\n // const charCount = snapStates.composerCharacterCount;\n\n // const customEmojis = useRef();\n const searcherRef = useRef();\n useEffect(() => {\n getCustomEmojis(instance, masto)\n .then((r) => {\n const [emojis, searcher] = r;\n searcherRef.current = searcher;\n })\n .catch((e) => {\n console.error(e);\n });\n }, []);\n\n const textExpanderRef = useRef();\n const textExpanderTextRef = useRef('');\n useEffect(() => {\n let handleChange, handleValue, handleCommited;\n if (textExpanderRef.current) {\n handleChange = (e) => {\n // console.log('text-expander-change', e);\n const { key, provide, text } = e.detail;\n textExpanderTextRef.current = text;\n\n if (text === '') {\n provide(\n Promise.resolve({\n matched: false,\n }),\n );\n return;\n }\n\n if (key === ':') {\n // const emojis = customEmojis.current.filter((emoji) =>\n // emoji.shortcode.startsWith(text),\n // );\n // const emojis = filterShortcodes(customEmojis.current, text);\n const results = searcherRef.current?.search(text, {\n limit: 5,\n });\n let html = '';\n results.forEach(({ item: emoji }) => {\n const { shortcode, url } = emoji;\n html += `\n <li role=\"option\" data-value=\"${encodeHTML(shortcode)}\">\n <img src=\"${encodeHTML(\n url,\n )}\" width=\"16\" height=\"16\" alt=\"\" loading=\"lazy\" /> \n ${encodeHTML(shortcode)}\n </li>`;\n });\n html += `<li role=\"option\" data-value=\"\" data-more=\"${text}\">${t`More…`}</li>`;\n // console.log({ emojis, html });\n menu.innerHTML = html;\n provide(\n Promise.resolve({\n matched: results.length > 0,\n fragment: menu,\n }),\n );\n return;\n }\n\n const type = {\n '@': 'accounts',\n '#': 'hashtags',\n }[key];\n provide(\n new Promise((resolve) => {\n const searchResults = performSearch({\n type,\n q: text,\n limit: 5,\n });\n searchResults.then((value) => {\n if (text !== textExpanderTextRef.current) {\n return;\n }\n console.log({ value, type, v: value[type] });\n const results = value[type] || value;\n console.log('RESULTS', value, results);\n let html = '';\n results.forEach((result) => {\n const {\n name,\n avatarStatic,\n displayName,\n username,\n acct,\n emojis,\n history,\n } = result;\n const displayNameWithEmoji = emojifyText(displayName, emojis);\n // const item = menuItem.cloneNode();\n if (acct) {\n html += `\n <li role=\"option\" data-value=\"${encodeHTML(acct)}\">\n <span class=\"avatar\">\n <img src=\"${encodeHTML(\n avatarStatic,\n )}\" width=\"16\" height=\"16\" alt=\"\" loading=\"lazy\" />\n </span>\n <span>\n <b>${displayNameWithEmoji || username}</b>\n <br><span class=\"bidi-isolate\">@${encodeHTML(\n acct,\n )}</span>\n </span>\n </li>\n `;\n } else {\n const total = history?.reduce?.(\n (acc, cur) => acc + +cur.uses,\n 0,\n );\n html += `\n <li role=\"option\" data-value=\"${encodeHTML(name)}\">\n <span class=\"grow\">#<b>${encodeHTML(name)}</b></span>\n ${\n total\n ? `<span class=\"count\">${shortenNumber(total)}</span>`\n : ''\n }\n </li>\n `;\n }\n });\n if (type === 'accounts') {\n html += `<li role=\"option\" data-value=\"\" data-more=\"${text}\">${t`More…`}</li>`;\n }\n menu.innerHTML = html;\n console.log('MENU', results, menu);\n resolve({\n matched: results.length > 0,\n fragment: menu,\n });\n });\n }),\n );\n };\n\n textExpanderRef.current.addEventListener(\n 'text-expander-change',\n handleChange,\n );\n\n handleValue = (e) => {\n const { key, item } = e.detail;\n const { value, more } = item.dataset;\n if (key === ':') {\n e.detail.value = value ? `:${value}:` : ''; // zero-width space\n if (more) {\n // Prevent adding space after the above value\n e.detail.continue = true;\n\n setTimeout(() => {\n onTrigger?.({\n name: 'custom-emojis',\n defaultSearchTerm: more,\n });\n }, 300);\n }\n } else if (key === '@') {\n e.detail.value = value ? `@${value} ` : ''; // zero-width space\n if (more) {\n e.detail.continue = true;\n setTimeout(() => {\n onTrigger?.({\n name: 'mention',\n defaultSearchTerm: more,\n });\n }, 300);\n }\n } else {\n e.detail.value = `${key}${value}`;\n }\n };\n\n textExpanderRef.current.addEventListener(\n 'text-expander-value',\n handleValue,\n );\n\n handleCommited = (e) => {\n const { input } = e.detail;\n setText(input.value);\n // fire input event\n if (ref.current) {\n const event = new Event('input', { bubbles: true });\n ref.current.dispatchEvent(event);\n }\n };\n\n textExpanderRef.current.addEventListener(\n 'text-expander-committed',\n handleCommited,\n );\n }\n\n return () => {\n if (textExpanderRef.current) {\n textExpanderRef.current.removeEventListener(\n 'text-expander-change',\n handleChange,\n );\n textExpanderRef.current.removeEventListener(\n 'text-expander-value',\n handleValue,\n );\n textExpanderRef.current.removeEventListener(\n 'text-expander-committed',\n handleCommited,\n );\n }\n };\n }, []);\n\n useEffect(() => {\n // Resize observer for textarea\n const textarea = ref.current;\n if (!textarea) return;\n const resizeObserver = new ResizeObserver(() => {\n // Get height of textarea, set height to textExpander\n if (textExpanderRef.current) {\n const { height } = textarea.getBoundingClientRect();\n textExpanderRef.current.style.height = height + 'px';\n }\n });\n resizeObserver.observe(textarea);\n }, []);\n\n const slowHighlightPerf = useRef(0); // increment if slow\n const composeHighlightRef = useRef();\n const throttleHighlightText = useThrottledCallback((text) => {\n if (!composeHighlightRef.current) return;\n if (slowHighlightPerf.current > 3) {\n // After 3 times of lag, disable highlighting\n composeHighlightRef.current.innerHTML = '';\n composeHighlightRef.current = null; // Destroy the whole thing\n throttleHighlightText?.cancel?.();\n return;\n }\n let start;\n let end;\n if (slowHighlightPerf.current <= 3) start = Date.now();\n composeHighlightRef.current.innerHTML =\n highlightText(text, {\n maxCharacters,\n }) + '\\n';\n if (slowHighlightPerf.current <= 3) end = Date.now();\n console.debug('HIGHLIGHT PERF', { start, end, diff: end - start });\n if (start && end && end - start > 50) {\n // if slow, increment\n slowHighlightPerf.current++;\n }\n // Newline to prevent multiple line breaks at the end from being collapsed, no idea why\n }, 500);\n\n const debouncedAutoDetectLanguage = useDebouncedCallback(() => {\n // Make use of the highlightRef to get the DOM\n // Clone the dom\n const dom = composeHighlightRef.current?.cloneNode(true);\n if (!dom) return;\n // Remove mark\n dom.querySelectorAll('mark').forEach((mark) => {\n mark.remove();\n });\n const text = dom.innerText?.trim();\n if (!text) return;\n (async () => {\n const langs = await detectLangs(text);\n if (langs?.length) {\n onTrigger?.({\n name: 'auto-detect-language',\n languages: langs,\n });\n }\n })();\n }, 2000);\n\n return (\n <text-expander\n ref={textExpanderRef}\n keys=\"@ # :\"\n class=\"compose-field-container\"\n >\n <textarea\n class=\"compose-field\"\n autoCapitalize=\"sentences\"\n autoComplete=\"on\"\n autoCorrect=\"on\"\n spellCheck=\"true\"\n dir=\"auto\"\n rows=\"6\"\n cols=\"50\"\n {...textareaProps}\n ref={ref}\n name=\"status\"\n value={text}\n onKeyDown={(e) => {\n // Get line before cursor position after pressing 'Enter'\n const { key, target } = e;\n if (key === 'Enter' && !(e.ctrlKey || e.metaKey)) {\n try {\n const { value, selectionStart } = target;\n const textBeforeCursor = value.slice(0, selectionStart);\n const lastLine = textBeforeCursor.split('\\n').slice(-1)[0];\n if (lastLine) {\n // If line starts with \"- \" or \"12. \"\n if (/^\\s*(-|\\d+\\.)\\s/.test(lastLine)) {\n // insert \"- \" at cursor position\n const [_, preSpaces, bullet, postSpaces, anything] =\n lastLine.match(/^(\\s*)(-|\\d+\\.)(\\s+)(.+)?/) || [];\n if (anything) {\n e.preventDefault();\n const [number] = bullet.match(/\\d+/) || [];\n const newBullet = number ? `${+number + 1}.` : '-';\n const text = `\\n${preSpaces}${newBullet}${postSpaces}`;\n target.setRangeText(text, selectionStart, selectionStart);\n const pos = selectionStart + text.length;\n target.setSelectionRange(pos, pos);\n } else {\n // trim the line before the cursor, then insert new line\n const pos = selectionStart - lastLine.length;\n target.setRangeText('', pos, selectionStart);\n }\n autoResizeTextarea(target);\n target.dispatchEvent(new Event('input'));\n }\n }\n } catch (e) {\n // silent fail\n console.error(e);\n }\n }\n if (composeHighlightRef.current) {\n composeHighlightRef.current.scrollTop = target.scrollTop;\n }\n }}\n onInput={(e) => {\n const { target } = e;\n // Replace zero-width space\n const text = target.value.replace(/\\u200b/g, '');\n setText(text);\n autoResizeTextarea(target);\n props.onInput?.(e);\n throttleHighlightText(text);\n debouncedAutoDetectLanguage();\n }}\n style={{\n width: '100%',\n height: '4em',\n // '--text-weight': (1 + charCount / 140).toFixed(1) || 1,\n }}\n onScroll={(e) => {\n if (composeHighlightRef.current) {\n const { scrollTop } = e.target;\n composeHighlightRef.current.scrollTop = scrollTop;\n }\n }}\n />\n <div\n ref={composeHighlightRef}\n class=\"compose-highlight\"\n aria-hidden=\"true\"\n />\n </text-expander>\n );\n});\n\nfunction CharCountMeter({ maxCharacters = 500, hidden }) {\n const snapStates = useSnapshot(states);\n const charCount = snapStates.composerCharacterCount;\n const leftChars = maxCharacters - charCount;\n if (hidden) {\n return <span class=\"char-counter\" hidden />;\n }\n return (\n <span\n class=\"char-counter\"\n title={`${leftChars}/${maxCharacters}`}\n style={{\n '--percentage': (charCount / maxCharacters) * 100,\n }}\n >\n <meter\n class={`${\n leftChars <= -10\n ? 'explode'\n : leftChars <= 0\n ? 'danger'\n : leftChars <= 20\n ? 'warning'\n : ''\n }`}\n value={charCount}\n max={maxCharacters}\n />\n <span class=\"counter\">{leftChars}</span>\n </span>\n );\n}\n\nfunction scaleDimension(matrix, matrixLimit, width, height) {\n // matrix = number of pixels\n // matrixLimit = max number of pixels\n // Calculate new width and height, downsize to within the limit, preserve aspect ratio, no decimals\n const scalingFactor = Math.sqrt(matrixLimit / matrix);\n const newWidth = Math.floor(width * scalingFactor);\n const newHeight = Math.floor(height * scalingFactor);\n return { newWidth, newHeight };\n}\n\nfunction MediaAttachment({\n attachment,\n disabled,\n lang,\n onDescriptionChange = () => {},\n onRemove = () => {},\n}) {\n const { i18n } = useLingui();\n const [uiState, setUIState] = useState('default');\n const supportsEdit = supports('@mastodon/edit-media-attributes');\n const { type, id, file } = attachment;\n const url = useMemo(\n () => (file ? URL.createObjectURL(file) : attachment.url),\n [file, attachment.url],\n );\n console.log({ attachment });\n\n const checkMaxError = !!file?.size;\n const configuration = checkMaxError ? getCurrentInstanceConfiguration() : {};\n const {\n mediaAttachments: {\n imageSizeLimit,\n imageMatrixLimit,\n videoSizeLimit,\n videoMatrixLimit,\n videoFrameRateLimit,\n } = {},\n } = configuration || {};\n\n const [maxError, setMaxError] = useState(() => {\n if (!checkMaxError) return null;\n if (\n type.startsWith('image') &&\n imageSizeLimit &&\n file.size > imageSizeLimit\n ) {\n return {\n type: 'imageSizeLimit',\n details: {\n imageSize: file.size,\n imageSizeLimit,\n },\n };\n } else if (\n type.startsWith('video') &&\n videoSizeLimit &&\n file.size > videoSizeLimit\n ) {\n return {\n type: 'videoSizeLimit',\n details: {\n videoSize: file.size,\n videoSizeLimit,\n },\n };\n }\n return null;\n });\n\n const [imageMatrix, setImageMatrix] = useState({});\n useEffect(() => {\n if (!checkMaxError || !imageMatrixLimit) return;\n if (imageMatrix?.matrix > imageMatrixLimit) {\n setMaxError({\n type: 'imageMatrixLimit',\n details: {\n imageMatrix: imageMatrix?.matrix,\n imageMatrixLimit,\n width: imageMatrix?.width,\n height: imageMatrix?.height,\n },\n });\n }\n }, [imageMatrix, imageMatrixLimit, checkMaxError]);\n\n const [videoMatrix, setVideoMatrix] = useState({});\n useEffect(() => {\n if (!checkMaxError || !videoMatrixLimit) return;\n if (videoMatrix?.matrix > videoMatrixLimit) {\n setMaxError({\n type: 'videoMatrixLimit',\n details: {\n videoMatrix: videoMatrix?.matrix,\n videoMatrixLimit,\n width: videoMatrix?.width,\n height: videoMatrix?.height,\n },\n });\n }\n }, [videoMatrix, videoMatrixLimit, checkMaxError]);\n\n const [description, setDescription] = useState(attachment.description);\n const [suffixType, subtype] = type.split('/');\n const debouncedOnDescriptionChange = useDebouncedCallback(\n onDescriptionChange,\n 250,\n );\n useEffect(() => {\n debouncedOnDescriptionChange(description);\n }, [description, debouncedOnDescriptionChange]);\n\n const [showModal, setShowModal] = useState(false);\n const textareaRef = useRef(null);\n useEffect(() => {\n let timer;\n if (showModal && textareaRef.current) {\n timer = setTimeout(() => {\n textareaRef.current.focus();\n }, 100);\n }\n return () => {\n clearTimeout(timer);\n };\n }, [showModal]);\n\n const descTextarea = (\n <>\n {!!id && !supportsEdit ? (\n <div class=\"media-desc\">\n <span class=\"tag\">\n <Trans>Uploaded</Trans>\n </span>\n <p title={description}>\n {attachment.description || <i>No description</i>}\n </p>\n </div>\n ) : (\n <textarea\n ref={textareaRef}\n value={description || ''}\n lang={lang}\n placeholder={\n {\n image: t`Image description`,\n video: t`Video description`,\n audio: t`Audio description`,\n }[suffixType]\n }\n autoCapitalize=\"sentences\"\n autoComplete=\"on\"\n autoCorrect=\"on\"\n spellCheck=\"true\"\n dir=\"auto\"\n disabled={disabled || uiState === 'loading'}\n class={uiState === 'loading' ? 'loading' : ''}\n maxlength=\"1500\" // Not unicode-aware :(\n // TODO: Un-hard-code this maxlength, ref: https://github.com/mastodon/mastodon/blob/b59fb28e90bc21d6fd1a6bafd13cfbd81ab5be54/app/models/media_attachment.rb#L39\n onInput={(e) => {\n const { value } = e.target;\n setDescription(value);\n // debouncedOnDescriptionChange(value);\n }}\n ></textarea>\n )}\n </>\n );\n\n const toastRef = useRef(null);\n useEffect(() => {\n return () => {\n toastRef.current?.hideToast?.();\n };\n }, []);\n\n const maxErrorToast = useRef(null);\n\n const maxErrorText = (err) => {\n const { type, details } = err;\n switch (type) {\n case 'imageSizeLimit': {\n const { imageSize, imageSizeLimit } = details;\n return t`File size too large. Uploading might encounter issues. Try reduce the file size from ${prettyBytes(\n imageSize,\n )} to ${prettyBytes(imageSizeLimit)} or lower.`;\n }\n case 'imageMatrixLimit': {\n const { imageMatrix, imageMatrixLimit, width, height } = details;\n const { newWidth, newHeight } = scaleDimension(\n imageMatrix,\n imageMatrixLimit,\n width,\n height,\n );\n return t`Dimension too large. Uploading might encounter issues. Try reduce dimension from ${i18n.number(\n width,\n )}×${i18n.number(height)}px to ${i18n.number(newWidth)}×${i18n.number(\n newHeight,\n )}px.`;\n }\n case 'videoSizeLimit': {\n const { videoSize, videoSizeLimit } = details;\n return t`File size too large. Uploading might encounter issues. Try reduce the file size from ${prettyBytes(\n videoSize,\n )} to ${prettyBytes(videoSizeLimit)} or lower.`;\n }\n case 'videoMatrixLimit': {\n const { videoMatrix, videoMatrixLimit, width, height } = details;\n const { newWidth, newHeight } = scaleDimension(\n videoMatrix,\n videoMatrixLimit,\n width,\n height,\n );\n return t`Dimension too large. Uploading might encounter issues. Try reduce dimension from ${i18n.number(\n width,\n )}×${i18n.number(height)}px to ${i18n.number(newWidth)}×${i18n.number(\n newHeight,\n )}px.`;\n }\n case 'videoFrameRateLimit': {\n // Not possible to detect this on client-side for now\n return t`Frame rate too high. Uploading might encounter issues.`;\n }\n }\n };\n\n return (\n <>\n <div class=\"media-attachment\">\n <div\n class=\"media-preview\"\n tabIndex=\"0\"\n onClick={() => {\n setShowModal(true);\n }}\n >\n {suffixType === 'image' ? (\n <img\n src={url}\n alt=\"\"\n onLoad={(e) => {\n if (!checkMaxError) return;\n const { naturalWidth, naturalHeight } = e.target;\n setImageMatrix({\n matrix: naturalWidth * naturalHeight,\n width: naturalWidth,\n height: naturalHeight,\n });\n }}\n />\n ) : suffixType === 'video' || suffixType === 'gifv' ? (\n <video\n src={url + '#t=0.1'} // Make Safari show 1st-frame preview\n playsinline\n muted\n disablePictureInPicture\n preload=\"metadata\"\n onLoadedMetadata={(e) => {\n if (!checkMaxError) return;\n const { videoWidth, videoHeight } = e.target;\n if (videoWidth && videoHeight) {\n setVideoMatrix({\n matrix: videoWidth * videoHeight,\n width: videoWidth,\n height: videoHeight,\n });\n }\n }}\n />\n ) : suffixType === 'audio' ? (\n <audio src={url} controls />\n ) : null}\n </div>\n {descTextarea}\n <div class=\"media-aside\">\n <button\n type=\"button\"\n class=\"plain close-button\"\n disabled={disabled}\n onClick={onRemove}\n >\n <Icon icon=\"x\" alt={t`Remove`} />\n </button>\n {!!maxError && (\n <button\n type=\"button\"\n class=\"media-error\"\n title={maxErrorText(maxError)}\n onClick={() => {\n if (maxErrorToast.current) {\n maxErrorToast.current.hideToast();\n }\n maxErrorToast.current = showToast({\n text: maxErrorText(maxError),\n duration: 10_000,\n });\n }}\n >\n <Icon icon=\"alert\" alt={t`Error`} />\n </button>\n )}\n </div>\n </div>\n {showModal && (\n <Modal\n onClose={() => {\n setShowModal(false);\n }}\n >\n <div id=\"media-sheet\" class=\"sheet sheet-max\">\n <button\n type=\"button\"\n class=\"sheet-close\"\n onClick={() => {\n setShowModal(false);\n }}\n >\n <Icon icon=\"x\" alt={t`Close`} />\n </button>\n <header>\n <h2>\n {\n {\n image: t`Edit image description`,\n video: t`Edit video description`,\n audio: t`Edit audio description`,\n }[suffixType]\n }\n </h2>\n </header>\n <main tabIndex=\"-1\">\n <div class=\"media-preview\">\n {suffixType === 'image' ? (\n <img src={url} alt=\"\" />\n ) : suffixType === 'video' || suffixType === 'gifv' ? (\n <video src={url} playsinline controls />\n ) : suffixType === 'audio' ? (\n <audio src={url} controls />\n ) : null}\n </div>\n <div class=\"media-form\">\n {descTextarea}\n <footer>\n {suffixType === 'image' &&\n /^(png|jpe?g|gif|webp)$/i.test(subtype) &&\n !!states.settings.mediaAltGenerator &&\n !!IMG_ALT_API_URL && (\n <Menu2\n portal={{\n target: document.body,\n }}\n containerProps={{\n style: {\n zIndex: 1001,\n },\n }}\n align=\"center\"\n position=\"anchor\"\n overflow=\"auto\"\n menuButton={\n <button type=\"button\" class=\"plain\">\n <Icon icon=\"more\" size=\"l\" alt={t`More`} />\n </button>\n }\n >\n <MenuItem\n disabled={uiState === 'loading'}\n onClick={() => {\n setUIState('loading');\n toastRef.current = showToast({\n text: t`Generating description. Please wait…`,\n duration: -1,\n });\n // POST with multipart\n (async function () {\n try {\n const body = new FormData();\n body.append('image', file);\n const response = await fetch(IMG_ALT_API_URL, {\n method: 'POST',\n body,\n }).then((r) => r.json());\n if (response.error) {\n throw new Error(response.error);\n }\n setDescription(response.description);\n } catch (e) {\n console.error(e);\n showToast(\n e.message\n ? t`Failed to generate description: ${e.message}`\n : t`Failed to generate description`,\n );\n } finally {\n setUIState('default');\n toastRef.current?.hideToast?.();\n }\n })();\n }}\n >\n <Icon icon=\"sparkles2\" />\n {lang && lang !== 'en' ? (\n <small>\n <Trans>Generate description…</Trans>\n <br />\n (English)\n </small>\n ) : (\n <span>\n <Trans>Generate description…</Trans>\n </span>\n )}\n </MenuItem>\n {!!lang && lang !== 'en' && (\n <MenuItem\n disabled={uiState === 'loading'}\n onClick={() => {\n setUIState('loading');\n toastRef.current = showToast({\n text: t`Generating description. Please wait…`,\n duration: -1,\n });\n // POST with multipart\n (async function () {\n try {\n const body = new FormData();\n body.append('image', file);\n const params = `?lang=${lang}`;\n const response = await fetch(\n IMG_ALT_API_URL + params,\n {\n method: 'POST',\n body,\n },\n ).then((r) => r.json());\n if (response.error) {\n throw new Error(response.error);\n }\n setDescription(response.description);\n } catch (e) {\n console.error(e);\n showToast(\n t`Failed to generate description${\n e?.message ? `: ${e.message}` : ''\n }`,\n );\n } finally {\n setUIState('default');\n toastRef.current?.hideToast?.();\n }\n })();\n }}\n >\n <Icon icon=\"sparkles2\" />\n <small>\n <Trans>Generate description…</Trans>\n <br />\n <Trans>\n ({localeCode2Text(lang)}){' '}\n <span class=\"more-insignificant\">\n — experimental\n </span>\n </Trans>\n </small>\n </MenuItem>\n )}\n </Menu2>\n )}\n <button\n type=\"button\"\n class=\"light block\"\n onClick={() => {\n setShowModal(false);\n }}\n disabled={uiState === 'loading'}\n >\n <Trans>Done</Trans>\n </button>\n </footer>\n </div>\n </main>\n </div>\n </Modal>\n )}\n </>\n );\n}\n\nfunction Poll({\n lang,\n poll,\n disabled,\n onInput = () => {},\n maxOptions,\n maxExpiration,\n minExpiration,\n maxCharactersPerOption,\n}) {\n const { _ } = useLingui();\n const { options, expiresIn, multiple } = poll;\n\n return (\n <div class={`poll ${multiple ? 'multiple' : ''}`}>\n <div class=\"poll-choices\">\n {options.map((option, i) => (\n <div class=\"poll-choice\" key={i}>\n <input\n required\n type=\"text\"\n value={option}\n disabled={disabled}\n maxlength={maxCharactersPerOption}\n placeholder={t`Choice ${i + 1}`}\n lang={lang}\n spellCheck=\"true\"\n dir=\"auto\"\n onInput={(e) => {\n const { value } = e.target;\n options[i] = value;\n onInput(poll);\n }}\n />\n <button\n type=\"button\"\n class=\"plain2 poll-button\"\n disabled={disabled || options.length <= 1}\n onClick={() => {\n options.splice(i, 1);\n onInput(poll);\n }}\n >\n <Icon icon=\"x\" size=\"s\" alt={t`Remove`} />\n </button>\n </div>\n ))}\n </div>\n <div class=\"poll-toolbar\">\n <button\n type=\"button\"\n class=\"plain2 poll-button\"\n disabled={disabled || options.length >= maxOptions}\n onClick={() => {\n options.push('');\n onInput(poll);\n }}\n >\n +\n </button>{' '}\n <label class=\"multiple-choices\">\n <input\n type=\"checkbox\"\n checked={multiple}\n disabled={disabled}\n onChange={(e) => {\n const { checked } = e.target;\n poll.multiple = checked;\n onInput(poll);\n }}\n />{' '}\n <Trans>Multiple choices</Trans>\n </label>\n <label class=\"expires-in\">\n <Trans>Duration</Trans>{' '}\n <select\n value={expiresIn}\n disabled={disabled}\n onChange={(e) => {\n const { value } = e.target;\n poll.expiresIn = value;\n onInput(poll);\n }}\n >\n {Object.entries(expiryOptions)\n .filter(([value]) => {\n return value >= minExpiration && value <= maxExpiration;\n })\n .map(([value, label]) => (\n <option value={value} key={value}>\n {label()}\n </option>\n ))}\n </select>\n </label>\n </div>\n <div class=\"poll-toolbar\">\n <button\n type=\"button\"\n class=\"plain remove-poll-button\"\n disabled={disabled}\n onClick={() => {\n onInput(null);\n }}\n >\n <Trans>Remove poll</Trans>\n </button>\n </div>\n </div>\n );\n}\n\nfunction filterShortcodes(emojis, searchTerm) {\n searchTerm = searchTerm.toLowerCase();\n\n // Return an array of shortcodes that start with or contain the search term, sorted by relevance and limited to the first 5\n return emojis\n .sort((a, b) => {\n let aLower = a.shortcode.toLowerCase();\n let bLower = b.shortcode.toLowerCase();\n\n let aStartsWith = aLower.startsWith(searchTerm);\n let bStartsWith = bLower.startsWith(searchTerm);\n let aContains = aLower.includes(searchTerm);\n let bContains = bLower.includes(searchTerm);\n let bothStartWith = aStartsWith && bStartsWith;\n let bothContain = aContains && bContains;\n\n return bothStartWith\n ? a.length - b.length\n : aStartsWith\n ? -1\n : bStartsWith\n ? 1\n : bothContain\n ? a.length - b.length\n : aContains\n ? -1\n : bContains\n ? 1\n : 0;\n })\n .slice(0, 5);\n}\n\nfunction encodeHTML(str) {\n return str.replace(/[&<>\"']/g, function (char) {\n return '&#' + char.charCodeAt(0) + ';';\n });\n}\n\nfunction removeNullUndefined(obj) {\n for (let key in obj) {\n if (obj[key] === null || obj[key] === undefined) {\n delete obj[key];\n }\n }\n return obj;\n}\n\nfunction MentionModal({\n onClose = () => {},\n onSelect = () => {},\n defaultSearchTerm,\n}) {\n const { masto } = api();\n const [uiState, setUIState] = useState('default');\n const [accounts, setAccounts] = useState([]);\n const [relationshipsMap, setRelationshipsMap] = useState({});\n\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const loadRelationships = async (accounts) => {\n if (!accounts?.length) return;\n const relationships = await fetchRelationships(accounts, relationshipsMap);\n if (relationships) {\n setRelationshipsMap({\n ...relationshipsMap,\n ...relationships,\n });\n }\n };\n\n const loadAccounts = (term) => {\n if (!term) return;\n setUIState('loading');\n (async () => {\n try {\n const accounts = await masto.v1.accounts.search.list({\n q: term,\n limit: 40,\n resolve: false,\n });\n setAccounts(accounts);\n loadRelationships(accounts);\n setUIState('default');\n } catch (e) {\n setUIState('error');\n console.error(e);\n }\n })();\n };\n\n const debouncedLoadAccounts = useDebouncedCallback(loadAccounts, 1000);\n\n useEffect(() => {\n loadAccounts();\n }, [loadAccounts]);\n\n const inputRef = useRef();\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n // Put cursor at the end\n if (inputRef.current.value) {\n inputRef.current.selectionStart = inputRef.current.value.length;\n inputRef.current.selectionEnd = inputRef.current.value.length;\n }\n }\n }, []);\n\n useEffect(() => {\n if (defaultSearchTerm) {\n loadAccounts(defaultSearchTerm);\n }\n }, [defaultSearchTerm]);\n\n const selectAccount = (account) => {\n const socialAddress = account.acct;\n onSelect(socialAddress);\n onClose();\n };\n\n useHotkeys(\n 'enter',\n () => {\n const selectedAccount = accounts[selectedIndex];\n if (selectedAccount) {\n selectAccount(selectedAccount);\n }\n },\n {\n preventDefault: true,\n enableOnFormTags: ['input'],\n },\n );\n\n const listRef = useRef();\n useHotkeys(\n 'down',\n () => {\n if (selectedIndex < accounts.length - 1) {\n setSelectedIndex(selectedIndex + 1);\n } else {\n setSelectedIndex(0);\n }\n setTimeout(() => {\n const selectedItem = listRef.current.querySelector('.selected');\n if (selectedItem) {\n selectedItem.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n inline: 'center',\n });\n }\n }, 1);\n },\n {\n preventDefault: true,\n enableOnFormTags: ['input'],\n },\n );\n\n useHotkeys(\n 'up',\n () => {\n if (selectedIndex > 0) {\n setSelectedIndex(selectedIndex - 1);\n } else {\n setSelectedIndex(accounts.length - 1);\n }\n setTimeout(() => {\n const selectedItem = listRef.current.querySelector('.selected');\n if (selectedItem) {\n selectedItem.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n inline: 'center',\n });\n }\n }, 1);\n },\n {\n preventDefault: true,\n enableOnFormTags: ['input'],\n },\n );\n\n return (\n <div id=\"mention-sheet\" class=\"sheet\">\n {!!onClose && (\n <button type=\"button\" class=\"sheet-close\" onClick={onClose}>\n <Icon icon=\"x\" alt={t`Close`} />\n </button>\n )}\n <header>\n <form\n onSubmit={(e) => {\n e.preventDefault();\n debouncedLoadAccounts.flush?.();\n // const searchTerm = inputRef.current.value;\n // debouncedLoadAccounts(searchTerm);\n }}\n >\n <input\n ref={inputRef}\n required\n type=\"search\"\n class=\"block\"\n placeholder={t`Search accounts`}\n onInput={(e) => {\n const { value } = e.target;\n debouncedLoadAccounts(value);\n }}\n autocomplete=\"off\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n spellCheck=\"false\"\n dir=\"auto\"\n defaultValue={defaultSearchTerm || ''}\n />\n </form>\n </header>\n <main>\n {accounts?.length > 0 ? (\n <ul\n ref={listRef}\n class={`accounts-list ${uiState === 'loading' ? 'loading' : ''}`}\n >\n {accounts.map((account, i) => {\n const relationship = relationshipsMap[account.id];\n return (\n <li\n key={account.id}\n class={i === selectedIndex ? 'selected' : ''}\n >\n <AccountBlock\n avatarSize=\"xxl\"\n account={account}\n relationship={relationship}\n showStats\n showActivity\n />\n <button\n type=\"button\"\n class=\"plain2\"\n onClick={() => {\n selectAccount(account);\n }}\n >\n <Icon icon=\"plus\" size=\"xl\" alt={t`Add`} />\n </button>\n </li>\n );\n })}\n </ul>\n ) : uiState === 'loading' ? (\n <div class=\"ui-state\">\n <Loader abrupt />\n </div>\n ) : uiState === 'error' ? (\n <div class=\"ui-state\">\n <p>\n <Trans>Error loading accounts</Trans>\n </p>\n </div>\n ) : null}\n </main>\n </div>\n );\n}\n\nfunction CustomEmojisModal({\n masto,\n instance,\n onClose = () => {},\n onSelect = () => {},\n defaultSearchTerm,\n}) {\n const [uiState, setUIState] = useState('default');\n const customEmojisList = useRef([]);\n const [customEmojis, setCustomEmojis] = useState([]);\n const recentlyUsedCustomEmojis = useMemo(\n () => store.account.get('recentlyUsedCustomEmojis') || [],\n );\n const searcherRef = useRef();\n useEffect(() => {\n setUIState('loading');\n (async () => {\n try {\n const [emojis, searcher] = await getCustomEmojis(instance, masto);\n console.log('emojis', emojis);\n searcherRef.current = searcher;\n setCustomEmojis(emojis);\n setUIState('default');\n } catch (e) {\n setUIState('error');\n console.error(e);\n }\n })();\n }, []);\n\n const customEmojisCatList = useMemo(() => {\n // Group emojis by category\n const emojisCat = {\n '--recent--': recentlyUsedCustomEmojis.filter((emoji) =>\n customEmojis.find((e) => e.shortcode === emoji.shortcode),\n ),\n };\n const othersCat = [];\n customEmojis.forEach((emoji) => {\n customEmojisList.current?.push?.(emoji);\n if (!emoji.category) {\n othersCat.push(emoji);\n return;\n }\n if (!emojisCat[emoji.category]) {\n emojisCat[emoji.category] = [];\n }\n emojisCat[emoji.category].push(emoji);\n });\n if (othersCat.length) {\n emojisCat['--others--'] = othersCat;\n }\n return emojisCat;\n }, [customEmojis]);\n\n const scrollableRef = useRef();\n const [matches, setMatches] = useState(null);\n const onFind = useCallback(\n (e) => {\n const { value } = e.target;\n if (value) {\n const results = searcherRef.current?.search(value, {\n limit: CUSTOM_EMOJIS_COUNT,\n });\n setMatches(results.map((r) => r.item));\n scrollableRef.current?.scrollTo?.(0, 0);\n } else {\n setMatches(null);\n }\n },\n [customEmojis],\n );\n useEffect(() => {\n if (defaultSearchTerm && customEmojis?.length) {\n onFind({ target: { value: defaultSearchTerm } });\n }\n }, [defaultSearchTerm, onFind, customEmojis]);\n\n const onSelectEmoji = useCallback(\n (emoji) => {\n onSelect?.(emoji);\n onClose?.();\n\n queueMicrotask(() => {\n let recentlyUsedCustomEmojis =\n store.account.get('recentlyUsedCustomEmojis') || [];\n const recentlyUsedEmojiIndex = recentlyUsedCustomEmojis.findIndex(\n (e) => e.shortcode === emoji.shortcode,\n );\n if (recentlyUsedEmojiIndex !== -1) {\n // Move emoji to index 0\n recentlyUsedCustomEmojis.splice(recentlyUsedEmojiIndex, 1);\n recentlyUsedCustomEmojis.unshift(emoji);\n } else {\n recentlyUsedCustomEmojis.unshift(emoji);\n // Remove unavailable ones\n recentlyUsedCustomEmojis = recentlyUsedCustomEmojis.filter((e) =>\n customEmojisList.current?.find?.(\n (emoji) => emoji.shortcode === e.shortcode,\n ),\n );\n // Limit to 10\n recentlyUsedCustomEmojis = recentlyUsedCustomEmojis.slice(0, 10);\n }\n\n // Store back\n store.account.set('recentlyUsedCustomEmojis', recentlyUsedCustomEmojis);\n });\n },\n [onSelect],\n );\n\n const inputRef = useRef();\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n // Put cursor at the end\n if (inputRef.current.value) {\n inputRef.current.selectionStart = inputRef.current.value.length;\n inputRef.current.selectionEnd = inputRef.current.value.length;\n }\n }\n }, []);\n\n return (\n <div id=\"custom-emojis-sheet\" class=\"sheet\">\n {!!onClose && (\n <button type=\"button\" class=\"sheet-close\" onClick={onClose}>\n <Icon icon=\"x\" alt={t`Close`} />\n </button>\n )}\n <header>\n <div>\n <b>\n <Trans>Custom emojis</Trans>\n </b>{' '}\n {uiState === 'loading' ? (\n <Loader />\n ) : (\n <small class=\"insignificant\"> • {instance}</small>\n )}\n </div>\n <form\n onSubmit={(e) => {\n e.preventDefault();\n const emoji = matches[0];\n if (emoji) {\n onSelectEmoji(`:${emoji.shortcode}:`);\n }\n }}\n >\n <input\n ref={inputRef}\n type=\"search\"\n placeholder={t`Search emoji`}\n onInput={onFind}\n autocomplete=\"off\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n spellCheck=\"false\"\n dir=\"auto\"\n defaultValue={defaultSearchTerm || ''}\n />\n </form>\n </header>\n <main ref={scrollableRef}>\n {matches !== null ? (\n <ul class=\"custom-emojis-matches custom-emojis-list\">\n {matches.map((emoji) => (\n <li key={emoji.shortcode} class=\"custom-emojis-match\">\n <CustomEmojiButton\n emoji={emoji}\n onClick={() => {\n onSelectEmoji(`:${emoji.shortcode}:`);\n }}\n showCode\n />\n </li>\n ))}\n </ul>\n ) : (\n <div class=\"custom-emojis-list\">\n {uiState === 'error' && (\n <div class=\"ui-state\">\n <p>\n <Trans>Error loading custom emojis</Trans>\n </p>\n </div>\n )}\n {uiState === 'default' &&\n Object.entries(customEmojisCatList).map(\n ([category, emojis]) =>\n !!emojis?.length && (\n <div class=\"section-container\">\n <div class=\"section-header\">\n {{\n '--recent--': t`Recently used`,\n '--others--': t`Others`,\n }[category] || category}\n </div>\n <CustomEmojisList\n emojis={emojis}\n onSelect={onSelectEmoji}\n />\n </div>\n ),\n )}\n </div>\n )}\n </main>\n </div>\n );\n}\n\nconst CustomEmojisList = memo(({ emojis, onSelect }) => {\n const { i18n } = useLingui();\n const [max, setMax] = useState(CUSTOM_EMOJIS_COUNT);\n const showMore = emojis.length > max;\n return (\n <section>\n {emojis.slice(0, max).map((emoji) => (\n <CustomEmojiButton\n key={emoji.shortcode}\n emoji={emoji}\n onClick={() => {\n onSelect(`:${emoji.shortcode}:`);\n }}\n />\n ))}\n {showMore && (\n <button\n type=\"button\"\n class=\"plain small\"\n onClick={() => setMax(max + CUSTOM_EMOJIS_COUNT)}\n >\n <Trans>{i18n.number(emojis.length - max)} more…</Trans>\n </button>\n )}\n </section>\n );\n});\n\nconst CustomEmojiButton = memo(({ emoji, onClick, showCode }) => {\n const addEdges = (e) => {\n // Add edge-left or edge-right class based on self position relative to scrollable parent\n // If near left edge, add edge-left, if near right edge, add edge-right\n const buffer = 88;\n const parent = e.currentTarget.closest('main');\n if (parent) {\n const rect = parent.getBoundingClientRect();\n const selfRect = e.currentTarget.getBoundingClientRect();\n const targetClassList = e.currentTarget.classList;\n if (selfRect.left < rect.left + buffer) {\n targetClassList.add('edge-left');\n targetClassList.remove('edge-right');\n } else if (selfRect.right > rect.right - buffer) {\n targetClassList.add('edge-right');\n targetClassList.remove('edge-left');\n } else {\n targetClassList.remove('edge-left', 'edge-right');\n }\n }\n };\n\n return (\n <button\n type=\"button\"\n className=\"plain4\"\n onClick={onClick}\n data-title={showCode ? undefined : emoji.shortcode}\n onPointerEnter={addEdges}\n onFocus={addEdges}\n >\n <picture>\n {!!emoji.staticUrl && (\n <source\n srcSet={emoji.staticUrl}\n media=\"(prefers-reduced-motion: reduce)\"\n />\n )}\n <img\n className=\"shortcode-emoji\"\n src={emoji.url || emoji.staticUrl}\n alt={emoji.shortcode}\n width=\"24\"\n height=\"24\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </picture>\n {showCode && (\n <>\n {' '}\n <code>{emoji.shortcode}</code>\n </>\n )}\n </button>\n );\n});\n\nconst GIFS_PER_PAGE = 20;\nfunction GIFPickerModal({ onClose = () => {}, onSelect = () => {} }) {\n const { i18n } = useLingui();\n const [uiState, setUIState] = useState('default');\n const [results, setResults] = useState([]);\n const formRef = useRef(null);\n const qRef = useRef(null);\n const currentOffset = useRef(0);\n const scrollableRef = useRef(null);\n\n function fetchGIFs({ offset }) {\n console.log('fetchGIFs', { offset });\n if (!qRef.current?.value) return;\n setUIState('loading');\n scrollableRef.current?.scrollTo?.({\n top: 0,\n left: 0,\n behavior: 'smooth',\n });\n (async () => {\n try {\n const query = {\n api_key: GIPHY_API_KEY,\n q: qRef.current.value,\n rating: 'g',\n limit: GIFS_PER_PAGE,\n bundle: 'messaging_non_clips',\n offset,\n lang: i18n.locale || 'en',\n };\n const response = await fetch(\n 'https://api.giphy.com/v1/gifs/search?' + new URLSearchParams(query),\n {\n referrerPolicy: 'no-referrer',\n },\n ).then((r) => r.json());\n currentOffset.current = response.pagination?.offset || 0;\n setResults(response);\n setUIState('results');\n } catch (e) {\n setUIState('error');\n console.error(e);\n }\n })();\n }\n\n useEffect(() => {\n qRef.current?.focus();\n }, []);\n\n const debouncedOnInput = useDebouncedCallback(() => {\n fetchGIFs({ offset: 0 });\n }, 1000);\n\n return (\n <div id=\"gif-picker-sheet\" class=\"sheet\">\n {!!onClose && (\n <button type=\"button\" class=\"sheet-close\" onClick={onClose}>\n <Icon icon=\"x\" alt={t`Close`} />\n </button>\n )}\n <header>\n <form\n ref={formRef}\n onSubmit={(e) => {\n e.preventDefault();\n fetchGIFs({ offset: 0 });\n }}\n >\n <input\n ref={qRef}\n type=\"search\"\n name=\"q\"\n placeholder={t`Search GIFs`}\n required\n autocomplete=\"off\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n spellCheck=\"false\"\n dir=\"auto\"\n onInput={debouncedOnInput}\n />\n <input\n type=\"image\"\n class=\"powered-button\"\n src={poweredByGiphyURL}\n width=\"86\"\n height=\"30\"\n alt={t`Powered by GIPHY`}\n />\n </form>\n </header>\n <main ref={scrollableRef} class={uiState === 'loading' ? 'loading' : ''}>\n {uiState === 'default' && (\n <div class=\"ui-state\">\n <p class=\"insignificant\">\n <Trans>Type to search GIFs</Trans>\n </p>\n </div>\n )}\n {uiState === 'loading' && !results?.data?.length && (\n <div class=\"ui-state\">\n <Loader abrupt />\n </div>\n )}\n {results?.data?.length > 0 ? (\n <>\n <ul>\n {results.data.map((gif) => {\n const { id, images, title, alt_text } = gif;\n const {\n fixed_height_small,\n fixed_height_downsampled,\n fixed_height,\n original,\n } = images;\n const theImage = fixed_height_small?.url\n ? fixed_height_small\n : fixed_height_downsampled?.url\n ? fixed_height_downsampled\n : fixed_height;\n let { url, webp, width, height } = theImage;\n if (+height > 100) {\n width = (width / height) * 100;\n height = 100;\n }\n const urlObj = URL.parse(url);\n const strippedURL = urlObj.origin + urlObj.pathname;\n let strippedWebP;\n if (webp) {\n const webpObj = URL.parse(webp);\n strippedWebP = webpObj.origin + webpObj.pathname;\n }\n return (\n <li key={id}>\n <button\n type=\"button\"\n onClick={() => {\n const { mp4, url } = original;\n const theURL = mp4 || url;\n const urlObj = URL.parse(theURL);\n const strippedURL = urlObj.origin + urlObj.pathname;\n onClose();\n onSelect({\n url: strippedURL,\n type: mp4 ? 'video/mp4' : 'image/gif',\n alt_text: alt_text || title,\n });\n }}\n >\n <figure\n style={{\n '--figure-width': width + 'px',\n // width: width + 'px'\n }}\n >\n <picture>\n {strippedWebP && (\n <source srcset={strippedWebP} type=\"image/webp\" />\n )}\n <img\n src={strippedURL}\n width={width}\n height={height}\n loading=\"lazy\"\n decoding=\"async\"\n alt={alt_text}\n referrerpolicy=\"no-referrer\"\n onLoad={(e) => {\n e.target.style.backgroundColor = 'transparent';\n }}\n />\n </picture>\n <figcaption>{alt_text || title}</figcaption>\n </figure>\n </button>\n </li>\n );\n })}\n </ul>\n <p class=\"pagination\">\n {results.pagination?.offset > 0 && (\n <button\n type=\"button\"\n class=\"light small\"\n disabled={uiState === 'loading'}\n onClick={() => {\n fetchGIFs({\n offset: results.pagination?.offset - GIFS_PER_PAGE,\n });\n }}\n >\n <Icon icon=\"chevron-left\" />\n <span>\n <Trans>Previous</Trans>\n </span>\n </button>\n )}\n <span />\n {results.pagination?.offset + results.pagination?.count <\n results.pagination?.total_count && (\n <button\n type=\"button\"\n class=\"light small\"\n disabled={uiState === 'loading'}\n onClick={() => {\n fetchGIFs({\n offset: results.pagination?.offset + GIFS_PER_PAGE,\n });\n }}\n >\n <span>\n <Trans>Next</Trans>\n </span>{' '}\n <Icon icon=\"chevron-right\" />\n </button>\n )}\n </p>\n </>\n ) : (\n uiState === 'results' && (\n <div class=\"ui-state\">\n <p>No results</p>\n </div>\n )\n )}\n {uiState === 'error' && (\n <div class=\"ui-state\">\n <p>\n <Trans>Error loading GIFs</Trans>\n </p>\n </div>\n )}\n </main>\n </div>\n );\n}\n\nexport default Compose;\n"],"file":"assets/compose-_xw4e_c5.js"}