about summary refs log tree commit diff
path: root/src/view/com/composer
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/composer')
-rw-r--r--src/view/com/composer/Composer.tsx88
-rw-r--r--src/view/com/composer/ComposerReplyTo.tsx16
-rw-r--r--src/view/com/composer/ExternalEmbed.tsx13
-rw-r--r--src/view/com/composer/Prompt.tsx16
-rw-r--r--src/view/com/composer/char-progress/CharProgress.tsx9
-rw-r--r--src/view/com/composer/labels/LabelsBtn.tsx15
-rw-r--r--src/view/com/composer/photos/Gallery.tsx23
-rw-r--r--src/view/com/composer/photos/OpenCameraBtn.tsx19
-rw-r--r--src/view/com/composer/photos/SelectPhotoBtn.tsx14
-rw-r--r--src/view/com/composer/select-language/SelectLangBtn.tsx22
-rw-r--r--src/view/com/composer/select-language/SuggestedLanguage.tsx24
-rw-r--r--src/view/com/composer/text-input/TextInput.tsx35
-rw-r--r--src/view/com/composer/text-input/TextInput.web.tsx32
-rw-r--r--src/view/com/composer/text-input/mobile/Autocomplete.tsx12
-rw-r--r--src/view/com/composer/text-input/web/Autocomplete.tsx20
-rw-r--r--src/view/com/composer/text-input/web/EmojiPicker.web.tsx3
-rw-r--r--src/view/com/composer/text-input/web/LinkDecorator.ts5
-rw-r--r--src/view/com/composer/text-input/web/TagDecorator.ts4
-rw-r--r--src/view/com/composer/threadgate/ThreadgateBtn.tsx13
-rw-r--r--src/view/com/composer/useExternalLinkFetch.ts17
20 files changed, 211 insertions, 189 deletions
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 2855d4232..57be93ca7 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -1,5 +1,21 @@
-import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
+import {RichText} from '@atproto/api'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {useAnalytics} from 'lib/analytics/analytics'
+import * as apilib from 'lib/api/index'
+import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
+import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
+import {usePalette} from 'lib/hooks/usePalette'
+import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
+import {cleanError} from 'lib/strings/errors'
+import {insertMentionAt} from 'lib/strings/mention-manip'
+import {shortenLinks} from 'lib/strings/rich-text-manip'
+import {toShortUrl} from 'lib/strings/url-helpers'
+import {colors, gradients, s} from 'lib/styles'
 import {observer} from 'mobx-react-lite'
+import {isAndroid, isIOS, isNative, isWeb} from 'platform/detection'
+import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
 import {
   ActivityIndicator,
   BackHandler,
@@ -12,57 +28,43 @@ import {
   TouchableOpacity,
   View,
 } from 'react-native'
-import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import LinearGradient from 'react-native-linear-gradient'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {RichText} from '@atproto/api'
-import {useAnalytics} from 'lib/analytics/analytics'
-import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible'
-import {ExternalEmbed} from './ExternalEmbed'
-import {Text} from '../util/text/Text'
-import * as Toast from '../util/Toast'
-// TODO: Prevent naming components that coincide with RN primitives
-// due to linting false positives
-import {TextInput, TextInputRef} from './text-input/TextInput'
-import {CharProgress} from './char-progress/CharProgress'
-import {UserAvatar} from '../util/UserAvatar'
-import * as apilib from 'lib/api/index'
-import {ComposerOpts} from 'state/shell/composer'
-import {s, colors, gradients} from 'lib/styles'
-import {cleanError} from 'lib/strings/errors'
-import {shortenLinks} from 'lib/strings/rich-text-manip'
-import {toShortUrl} from 'lib/strings/url-helpers'
-import {SelectPhotoBtn} from './photos/SelectPhotoBtn'
-import {OpenCameraBtn} from './photos/OpenCameraBtn'
-import {ThreadgateBtn} from './threadgate/ThreadgateBtn'
-import {usePalette} from 'lib/hooks/usePalette'
-import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {useExternalLinkFetch} from './useExternalLinkFetch'
-import {isWeb, isNative, isAndroid, isIOS} from 'platform/detection'
-import QuoteEmbed from '../util/post-embeds/QuoteEmbed'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
 import {GalleryModel} from 'state/models/media/gallery'
-import {Gallery} from './photos/Gallery'
-import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
-import {LabelsBtn} from './labels/LabelsBtn'
-import {SelectLangBtn} from './select-language/SelectLangBtn'
-import {SuggestedLanguage} from './select-language/SuggestedLanguage'
-import {insertMentionAt} from 'lib/strings/mention-manip'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useModals, useModalControls} from '#/state/modals'
+import {ComposerOpts} from 'state/shell/composer'
+import {ComposerReplyTo} from 'view/com/composer/ComposerReplyTo'
+
+import {logger} from '#/logger'
+import {emitPostCreated} from '#/state/events'
+import {useModalControls, useModals} from '#/state/modals'
 import {useRequireAltTextEnabled} from '#/state/preferences'
 import {
+  toPostLanguages,
   useLanguagePrefs,
   useLanguagePrefsApi,
-  toPostLanguages,
 } from '#/state/preferences/languages'
-import {useSession, getAgent} from '#/state/session'
 import {useProfileQuery} from '#/state/queries/profile'
-import {useComposerControls} from '#/state/shell/composer'
-import {emitPostCreated} from '#/state/events'
 import {ThreadgateSetting} from '#/state/queries/threadgate'
-import {logger} from '#/logger'
-import {ComposerReplyTo} from 'view/com/composer/ComposerReplyTo'
+import {getAgent, useSession} from '#/state/session'
+import {useComposerControls} from '#/state/shell/composer'
+
+import QuoteEmbed from '../util/post-embeds/QuoteEmbed'
+import {Text} from '../util/text/Text'
+import * as Toast from '../util/Toast'
+import {UserAvatar} from '../util/UserAvatar'
+import {CharProgress} from './char-progress/CharProgress'
+import {ExternalEmbed} from './ExternalEmbed'
+import {LabelsBtn} from './labels/LabelsBtn'
+import {Gallery} from './photos/Gallery'
+import {OpenCameraBtn} from './photos/OpenCameraBtn'
+import {SelectPhotoBtn} from './photos/SelectPhotoBtn'
+import {SelectLangBtn} from './select-language/SelectLangBtn'
+import {SuggestedLanguage} from './select-language/SuggestedLanguage'
+// TODO: Prevent naming components that coincide with RN primitives
+// due to linting false positives
+import {TextInput, TextInputRef} from './text-input/TextInput'
+import {ThreadgateBtn} from './threadgate/ThreadgateBtn'
+import {useExternalLinkFetch} from './useExternalLinkFetch'
 
 type Props = ComposerOpts
 export const ComposePost = observer(function ComposePost({
diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx
index 39a1473a3..e6fe11565 100644
--- a/src/view/com/composer/ComposerReplyTo.tsx
+++ b/src/view/com/composer/ComposerReplyTo.tsx
@@ -1,21 +1,21 @@
-import React from 'react'
-import {LayoutAnimation, Pressable, StyleSheet, View} from 'react-native'
-import {Image} from 'expo-image'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
 import {
   AppBskyEmbedImages,
   AppBskyEmbedRecord,
   AppBskyEmbedRecordWithMedia,
   AppBskyFeedPost,
 } from '@atproto/api'
-import {ComposerOptsPostRef} from 'state/shell/composer'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {Image} from 'expo-image'
 import {usePalette} from 'lib/hooks/usePalette'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
 import {sanitizeHandle} from 'lib/strings/handles'
-import {UserAvatar} from 'view/com/util/UserAvatar'
-import {Text} from 'view/com/util/text/Text'
+import React from 'react'
+import {LayoutAnimation, Pressable, StyleSheet, View} from 'react-native'
+import {ComposerOptsPostRef} from 'state/shell/composer'
 import QuoteEmbed from 'view/com/util/post-embeds/QuoteEmbed'
+import {Text} from 'view/com/util/text/Text'
+import {UserAvatar} from 'view/com/util/UserAvatar'
 
 export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
   const pal = usePalette('default')
diff --git a/src/view/com/composer/ExternalEmbed.tsx b/src/view/com/composer/ExternalEmbed.tsx
index 02dd1bbd7..c2aebccd6 100644
--- a/src/view/com/composer/ExternalEmbed.tsx
+++ b/src/view/com/composer/ExternalEmbed.tsx
@@ -1,3 +1,9 @@
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {ExternalEmbedDraft} from 'lib/api/index'
+import {usePalette} from 'lib/hooks/usePalette'
+import {s} from 'lib/styles'
 import React from 'react'
 import {
   ActivityIndicator,
@@ -5,14 +11,9 @@ import {
   TouchableOpacity,
   View,
 } from 'react-native'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
+
 import {AutoSizedImage} from '../util/images/AutoSizedImage'
 import {Text} from '../util/text/Text'
-import {s} from 'lib/styles'
-import {usePalette} from 'lib/hooks/usePalette'
-import {ExternalEmbedDraft} from 'lib/api/index'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
 
 export const ExternalEmbed = ({
   link,
diff --git a/src/view/com/composer/Prompt.tsx b/src/view/com/composer/Prompt.tsx
index 632bb2634..5f19a64bd 100644
--- a/src/view/com/composer/Prompt.tsx
+++ b/src/view/com/composer/Prompt.tsx
@@ -1,13 +1,15 @@
-import React from 'react'
-import {StyleSheet, TouchableOpacity} from 'react-native'
-import {UserAvatar} from '../util/UserAvatar'
-import {Text} from '../util/text/Text'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useSession} from '#/state/session'
+import React from 'react'
+import {StyleSheet, TouchableOpacity} from 'react-native'
+
 import {useProfileQuery} from '#/state/queries/profile'
+import {useSession} from '#/state/session'
+
+import {Text} from '../util/text/Text'
+import {UserAvatar} from '../util/UserAvatar'
 
 export function ComposePrompt({onPressCompose}: {onPressCompose: () => void}) {
   const {currentAccount} = useSession()
diff --git a/src/view/com/composer/char-progress/CharProgress.tsx b/src/view/com/composer/char-progress/CharProgress.tsx
index a3fa78a59..3c5cee492 100644
--- a/src/view/com/composer/char-progress/CharProgress.tsx
+++ b/src/view/com/composer/char-progress/CharProgress.tsx
@@ -1,13 +1,14 @@
+import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
+import {usePalette} from 'lib/hooks/usePalette'
+import {s} from 'lib/styles'
 import React from 'react'
 import {View} from 'react-native'
-import {Text} from '../../util/text/Text'
 // @ts-ignore no type definition -prf
 import ProgressCircle from 'react-native-progress/Circle'
 // @ts-ignore no type definition -prf
 import ProgressPie from 'react-native-progress/Pie'
-import {s} from 'lib/styles'
-import {usePalette} from 'lib/hooks/usePalette'
-import {MAX_GRAPHEME_LENGTH} from 'lib/constants'
+
+import {Text} from '../../util/text/Text'
 
 const DANGER_LENGTH = MAX_GRAPHEME_LENGTH
 
diff --git a/src/view/com/composer/labels/LabelsBtn.tsx b/src/view/com/composer/labels/LabelsBtn.tsx
index b880dd330..11f3d03d3 100644
--- a/src/view/com/composer/labels/LabelsBtn.tsx
+++ b/src/view/com/composer/labels/LabelsBtn.tsx
@@ -1,13 +1,14 @@
-import React from 'react'
-import {Keyboard, StyleSheet} from 'react-native'
-import {Button} from 'view/com/util/forms/Button'
-import {usePalette} from 'lib/hooks/usePalette'
-import {ShieldExclamation} from 'lib/icons'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome'
-import {isNative} from 'platform/detection'
-import {useLingui} from '@lingui/react'
 import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {usePalette} from 'lib/hooks/usePalette'
+import {ShieldExclamation} from 'lib/icons'
+import {isNative} from 'platform/detection'
+import React from 'react'
+import {Keyboard, StyleSheet} from 'react-native'
+import {Button} from 'view/com/util/forms/Button'
+
 import {useModalControls} from '#/state/modals'
 
 export function LabelsBtn({
diff --git a/src/view/com/composer/photos/Gallery.tsx b/src/view/com/composer/photos/Gallery.tsx
index 69c8debb0..380b70c9c 100644
--- a/src/view/com/composer/photos/Gallery.tsx
+++ b/src/view/com/composer/photos/Gallery.tsx
@@ -1,19 +1,20 @@
-import React, {useState} from 'react'
-import {ImageStyle, Keyboard, LayoutChangeEvent} from 'react-native'
-import {GalleryModel} from 'state/models/media/gallery'
-import {observer} from 'mobx-react-lite'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {s, colors} from 'lib/styles'
-import {StyleSheet, TouchableOpacity, View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {Image} from 'expo-image'
-import {Text} from 'view/com/util/text/Text'
-import {Dimensions} from 'lib/media/types'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {useModalControls} from '#/state/modals'
+import {Dimensions} from 'lib/media/types'
+import {colors, s} from 'lib/styles'
+import {observer} from 'mobx-react-lite'
 import {isNative} from 'platform/detection'
+import React, {useState} from 'react'
+import {ImageStyle, Keyboard, LayoutChangeEvent} from 'react-native'
+import {StyleSheet, TouchableOpacity, View} from 'react-native'
+import {GalleryModel} from 'state/models/media/gallery'
+import {Text} from 'view/com/util/text/Text'
+
+import {useModalControls} from '#/state/modals'
 
 const IMAGE_GAP = 8
 
diff --git a/src/view/com/composer/photos/OpenCameraBtn.tsx b/src/view/com/composer/photos/OpenCameraBtn.tsx
index 4353704d5..ce5318a2f 100644
--- a/src/view/com/composer/photos/OpenCameraBtn.tsx
+++ b/src/view/com/composer/photos/OpenCameraBtn.tsx
@@ -1,20 +1,21 @@
-import React, {useCallback} from 'react'
-import {TouchableOpacity, StyleSheet} from 'react-native'
-import * as MediaLibrary from 'expo-media-library'
 import {
   FontAwesomeIcon,
   FontAwesomeIconStyle,
 } from '@fortawesome/react-native-fontawesome'
-import {usePalette} from 'lib/hooks/usePalette'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import * as MediaLibrary from 'expo-media-library'
 import {useAnalytics} from 'lib/analytics/analytics'
-import {openCamera} from 'lib/media/picker'
-import {useCameraPermission} from 'lib/hooks/usePermissions'
 import {HITSLOP_10, POST_IMG_MAX} from 'lib/constants'
-import {GalleryModel} from 'state/models/media/gallery'
+import {usePalette} from 'lib/hooks/usePalette'
+import {useCameraPermission} from 'lib/hooks/usePermissions'
+import {openCamera} from 'lib/media/picker'
 import {isMobileWeb, isNative} from 'platform/detection'
+import React, {useCallback} from 'react'
+import {StyleSheet, TouchableOpacity} from 'react-native'
+import {GalleryModel} from 'state/models/media/gallery'
+
 import {logger} from '#/logger'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
 
 type Props = {
   gallery: GalleryModel
diff --git a/src/view/com/composer/photos/SelectPhotoBtn.tsx b/src/view/com/composer/photos/SelectPhotoBtn.tsx
index f7fa9502d..1e0e64090 100644
--- a/src/view/com/composer/photos/SelectPhotoBtn.tsx
+++ b/src/view/com/composer/photos/SelectPhotoBtn.tsx
@@ -1,17 +1,17 @@
-import React, {useCallback} from 'react'
-import {TouchableOpacity, StyleSheet} from 'react-native'
 import {
   FontAwesomeIcon,
   FontAwesomeIconStyle,
 } from '@fortawesome/react-native-fontawesome'
-import {usePalette} from 'lib/hooks/usePalette'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useAnalytics} from 'lib/analytics/analytics'
-import {usePhotoLibraryPermission} from 'lib/hooks/usePermissions'
-import {GalleryModel} from 'state/models/media/gallery'
 import {HITSLOP_10} from 'lib/constants'
+import {usePalette} from 'lib/hooks/usePalette'
+import {usePhotoLibraryPermission} from 'lib/hooks/usePermissions'
 import {isNative} from 'platform/detection'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
+import React, {useCallback} from 'react'
+import {StyleSheet, TouchableOpacity} from 'react-native'
+import {GalleryModel} from 'state/models/media/gallery'
 
 type Props = {
   gallery: GalleryModel
diff --git a/src/view/com/composer/select-language/SelectLangBtn.tsx b/src/view/com/composer/select-language/SelectLangBtn.tsx
index 78b1e9ba2..bfcf248ee 100644
--- a/src/view/com/composer/select-language/SelectLangBtn.tsx
+++ b/src/view/com/composer/select-language/SelectLangBtn.tsx
@@ -1,27 +1,29 @@
-import React, {useCallback, useMemo} from 'react'
-import {StyleSheet, Keyboard} from 'react-native'
 import {
   FontAwesomeIcon,
   FontAwesomeIconStyle,
 } from '@fortawesome/react-native-fontawesome'
-import {Text} from 'view/com/util/text/Text'
+import {msg, t} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import {usePalette} from 'lib/hooks/usePalette'
+import {isNative} from 'platform/detection'
+import React, {useCallback, useMemo} from 'react'
+import {Keyboard, StyleSheet} from 'react-native'
 import {
   DropdownButton,
   DropdownItem,
   DropdownItemButton,
 } from 'view/com/util/forms/DropdownButton'
-import {usePalette} from 'lib/hooks/usePalette'
-import {isNative} from 'platform/detection'
-import {codeToLanguageName} from '../../../../locale/helpers'
+import {Text} from 'view/com/util/text/Text'
+
 import {useModalControls} from '#/state/modals'
 import {
+  hasPostLanguage,
+  toPostLanguages,
   useLanguagePrefs,
   useLanguagePrefsApi,
-  toPostLanguages,
-  hasPostLanguage,
 } from '#/state/preferences/languages'
-import {t, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
+
+import {codeToLanguageName} from '../../../../locale/helpers'
 
 export function SelectLangBtn() {
   const pal = usePalette('default')
diff --git a/src/view/com/composer/select-language/SuggestedLanguage.tsx b/src/view/com/composer/select-language/SuggestedLanguage.tsx
index 0bf62ae0d..97a2a9830 100644
--- a/src/view/com/composer/select-language/SuggestedLanguage.tsx
+++ b/src/view/com/composer/select-language/SuggestedLanguage.tsx
@@ -1,22 +1,24 @@
+import {
+  FontAwesomeIcon,
+  FontAwesomeIconStyle,
+} from '@fortawesome/react-native-fontawesome'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+import lande from 'lande'
 import React, {useEffect, useState} from 'react'
 import {StyleSheet, View} from 'react-native'
-import lande from 'lande'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-import {Text} from '../../util/text/Text'
-import {Button} from '../../util/forms/Button'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {s} from '#/lib/styles'
 import {code3ToCode2Strict, codeToLanguageName} from '#/locale/helpers'
 import {
   toPostLanguages,
   useLanguagePrefs,
   useLanguagePrefsApi,
 } from '#/state/preferences/languages'
-import {usePalette} from '#/lib/hooks/usePalette'
-import {s} from '#/lib/styles'
-import {
-  FontAwesomeIcon,
-  FontAwesomeIconStyle,
-} from '@fortawesome/react-native-fontawesome'
+
+import {Button} from '../../util/forms/Button'
+import {Text} from '../../util/text/Text'
 
 // fallbacks for safari
 const onIdle = globalThis.requestIdleCallback || (cb => setTimeout(cb, 1))
diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx
index 20be585c2..435adfa33 100644
--- a/src/view/com/composer/text-input/TextInput.tsx
+++ b/src/view/com/composer/text-input/TextInput.tsx
@@ -1,10 +1,24 @@
+import {AppBskyRichtextFacet, RichText} from '@atproto/api'
+import PasteInput, {
+  PastedFile,
+  PasteInputRef,
+} from '@mattermost/react-native-paste-input'
+import {POST_IMG_MAX} from 'lib/constants'
+import {usePalette} from 'lib/hooks/usePalette'
+import {downloadAndResize} from 'lib/media/manip'
+import {isUriImage} from 'lib/media/util'
+import {cleanError} from 'lib/strings/errors'
+import {getMentionAt, insertMentionAt} from 'lib/strings/mention-manip'
+import {useTheme} from 'lib/ThemeContext'
+import isEqual from 'lodash.isequal'
+import {isIOS} from 'platform/detection'
 import React, {
+  ComponentProps,
   forwardRef,
   useCallback,
-  useRef,
   useMemo,
+  useRef,
   useState,
-  ComponentProps,
 } from 'react'
 import {
   NativeSyntheticEvent,
@@ -13,22 +27,9 @@ import {
   TextInputSelectionChangeEventData,
   View,
 } from 'react-native'
-import PasteInput, {
-  PastedFile,
-  PasteInputRef,
-} from '@mattermost/react-native-paste-input'
-import {AppBskyRichtextFacet, RichText} from '@atproto/api'
-import isEqual from 'lodash.isequal'
-import {Autocomplete} from './mobile/Autocomplete'
 import {Text} from 'view/com/util/text/Text'
-import {cleanError} from 'lib/strings/errors'
-import {getMentionAt, insertMentionAt} from 'lib/strings/mention-manip'
-import {usePalette} from 'lib/hooks/usePalette'
-import {useTheme} from 'lib/ThemeContext'
-import {isUriImage} from 'lib/media/util'
-import {downloadAndResize} from 'lib/media/manip'
-import {POST_IMG_MAX} from 'lib/constants'
-import {isIOS} from 'platform/detection'
+
+import {Autocomplete} from './mobile/Autocomplete'
 
 export interface TextInputRef {
   focus: () => void
diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx
index c62d11201..6b363558a 100644
--- a/src/view/com/composer/text-input/TextInput.web.tsx
+++ b/src/view/com/composer/text-input/TextInput.web.tsx
@@ -1,28 +1,30 @@
-import React from 'react'
-import {StyleSheet, View} from 'react-native'
-import {RichText, AppBskyRichtextFacet} from '@atproto/api'
-import EventEmitter from 'eventemitter3'
-import {useEditor, EditorContent, JSONContent} from '@tiptap/react'
+import {AppBskyRichtextFacet, RichText} from '@atproto/api'
+import {Trans} from '@lingui/macro'
 import {Document} from '@tiptap/extension-document'
-import History from '@tiptap/extension-history'
 import Hardbreak from '@tiptap/extension-hard-break'
+import History from '@tiptap/extension-history'
 import {Mention} from '@tiptap/extension-mention'
 import {Paragraph} from '@tiptap/extension-paragraph'
 import {Placeholder} from '@tiptap/extension-placeholder'
 import {Text as TiptapText} from '@tiptap/extension-text'
+import {generateJSON} from '@tiptap/html'
+import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
+import EventEmitter from 'eventemitter3'
+import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
+import {blobToDataUri, isUriImage} from 'lib/media/util'
 import isEqual from 'lodash.isequal'
+import React from 'react'
+import {StyleSheet, View} from 'react-native'
+import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
+
+import {Portal} from '#/components/Portal'
+import {usePalette} from '#/lib/hooks/usePalette'
+import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
+
+import {Text} from '../../util/text/Text'
 import {createSuggestion} from './web/Autocomplete'
-import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle'
-import {isUriImage, blobToDataUri} from 'lib/media/util'
 import {Emoji} from './web/EmojiPicker.web'
 import {LinkDecorator} from './web/LinkDecorator'
-import {generateJSON} from '@tiptap/html'
-import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
-import {usePalette} from '#/lib/hooks/usePalette'
-import {Portal} from '#/components/Portal'
-import {Text} from '../../util/text/Text'
-import {Trans} from '@lingui/macro'
-import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
 import {TagDecorator} from './web/TagDecorator'
 
 export interface TextInputRef {
diff --git a/src/view/com/composer/text-input/mobile/Autocomplete.tsx b/src/view/com/composer/text-input/mobile/Autocomplete.tsx
index c400aa48d..1e8b7900b 100644
--- a/src/view/com/composer/text-input/mobile/Autocomplete.tsx
+++ b/src/view/com/composer/text-input/mobile/Autocomplete.tsx
@@ -1,13 +1,15 @@
-import React, {useEffect, useRef} from 'react'
-import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native'
+import {AppBskyActorDefs} from '@atproto/api'
+import {Trans} from '@lingui/macro'
 import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
 import {usePalette} from 'lib/hooks/usePalette'
+import React, {useEffect, useRef} from 'react'
+import {Animated, StyleSheet, TouchableOpacity, View} from 'react-native'
 import {Text} from 'view/com/util/text/Text'
 import {UserAvatar} from 'view/com/util/UserAvatar'
-import {useGrapheme} from '../hooks/useGrapheme'
+
 import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
-import {Trans} from '@lingui/macro'
-import {AppBskyActorDefs} from '@atproto/api'
+
+import {useGrapheme} from '../hooks/useGrapheme'
 
 export function Autocomplete({
   prefix,
diff --git a/src/view/com/composer/text-input/web/Autocomplete.tsx b/src/view/com/composer/text-input/web/Autocomplete.tsx
index 76058fed3..21fae297c 100644
--- a/src/view/com/composer/text-input/web/Autocomplete.tsx
+++ b/src/view/com/composer/text-input/web/Autocomplete.tsx
@@ -1,3 +1,11 @@
+import {Trans} from '@lingui/macro'
+import {ReactRenderer} from '@tiptap/react'
+import {
+  SuggestionKeyDownProps,
+  SuggestionOptions,
+  SuggestionProps,
+} from '@tiptap/suggestion'
+import {usePalette} from 'lib/hooks/usePalette'
 import React, {
   forwardRef,
   useEffect,
@@ -5,19 +13,13 @@ import React, {
   useState,
 } from 'react'
 import {Pressable, StyleSheet, View} from 'react-native'
-import {ReactRenderer} from '@tiptap/react'
 import tippy, {Instance as TippyInstance} from 'tippy.js'
-import {
-  SuggestionOptions,
-  SuggestionProps,
-  SuggestionKeyDownProps,
-} from '@tiptap/suggestion'
-import {ActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
-import {usePalette} from 'lib/hooks/usePalette'
 import {Text} from 'view/com/util/text/Text'
 import {UserAvatar} from 'view/com/util/UserAvatar'
+
+import {ActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
+
 import {useGrapheme} from '../hooks/useGrapheme'
-import {Trans} from '@lingui/macro'
 
 interface MentionListRef {
   onKeyDown: (props: SuggestionKeyDownProps) => boolean
diff --git a/src/view/com/composer/text-input/web/EmojiPicker.web.tsx b/src/view/com/composer/text-input/web/EmojiPicker.web.tsx
index 149362116..d918953de 100644
--- a/src/view/com/composer/text-input/web/EmojiPicker.web.tsx
+++ b/src/view/com/composer/text-input/web/EmojiPicker.web.tsx
@@ -1,11 +1,12 @@
-import React from 'react'
 import Picker from '@emoji-mart/react'
+import React from 'react'
 import {
   StyleSheet,
   TouchableWithoutFeedback,
   useWindowDimensions,
   View,
 } from 'react-native'
+
 import {textInputWebEmitter} from '../TextInput.web'
 
 const HEIGHT_OFFSET = 40
diff --git a/src/view/com/composer/text-input/web/LinkDecorator.ts b/src/view/com/composer/text-input/web/LinkDecorator.ts
index e36ac80e4..207dbe7e4 100644
--- a/src/view/com/composer/text-input/web/LinkDecorator.ts
+++ b/src/view/com/composer/text-input/web/LinkDecorator.ts
@@ -14,12 +14,11 @@
  * the facet-set.
  */
 
+import {URL_REGEX} from '@atproto/api'
 import {Mark} from '@tiptap/core'
-import {Plugin, PluginKey} from '@tiptap/pm/state'
 import {Node as ProsemirrorNode} from '@tiptap/pm/model'
+import {Plugin, PluginKey} from '@tiptap/pm/state'
 import {Decoration, DecorationSet} from '@tiptap/pm/view'
-import {URL_REGEX} from '@atproto/api'
-
 import {isValidDomain} from 'lib/strings/url-helpers'
 
 export const LinkDecorator = Mark.create({
diff --git a/src/view/com/composer/text-input/web/TagDecorator.ts b/src/view/com/composer/text-input/web/TagDecorator.ts
index 2bf3184a8..9225fd6bf 100644
--- a/src/view/com/composer/text-input/web/TagDecorator.ts
+++ b/src/view/com/composer/text-input/web/TagDecorator.ts
@@ -14,11 +14,11 @@
  * the facet-set.
  */
 
+import {TAG_REGEX, TRAILING_PUNCTUATION_REGEX} from '@atproto/api'
 import {Mark} from '@tiptap/core'
-import {Plugin, PluginKey} from '@tiptap/pm/state'
 import {Node as ProsemirrorNode} from '@tiptap/pm/model'
+import {Plugin, PluginKey} from '@tiptap/pm/state'
 import {Decoration, DecorationSet} from '@tiptap/pm/view'
-import {TAG_REGEX, TRAILING_PUNCTUATION_REGEX} from '@atproto/api'
 
 function getDecorations(doc: ProsemirrorNode) {
   const decorations: Decoration[] = []
diff --git a/src/view/com/composer/threadgate/ThreadgateBtn.tsx b/src/view/com/composer/threadgate/ThreadgateBtn.tsx
index ebbc613ff..0647d4215 100644
--- a/src/view/com/composer/threadgate/ThreadgateBtn.tsx
+++ b/src/view/com/composer/threadgate/ThreadgateBtn.tsx
@@ -1,17 +1,18 @@
-import React from 'react'
-import {TouchableOpacity, StyleSheet, Keyboard} from 'react-native'
 import {
   FontAwesomeIcon,
   FontAwesomeIconStyle,
 } from '@fortawesome/react-native-fontawesome'
-import {usePalette} from 'lib/hooks/usePalette'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 import {useAnalytics} from 'lib/analytics/analytics'
 import {HITSLOP_10} from 'lib/constants'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
+import {usePalette} from 'lib/hooks/usePalette'
+import React from 'react'
+import {Keyboard, StyleSheet, TouchableOpacity} from 'react-native'
+
+import {isNative} from '#/platform/detection'
 import {useModalControls} from '#/state/modals'
 import {ThreadgateSetting} from '#/state/queries/threadgate'
-import {isNative} from '#/platform/detection'
 
 export function ThreadgateBtn({
   threadgate,
diff --git a/src/view/com/composer/useExternalLinkFetch.ts b/src/view/com/composer/useExternalLinkFetch.ts
index 54773d565..5daff41ea 100644
--- a/src/view/com/composer/useExternalLinkFetch.ts
+++ b/src/view/com/composer/useExternalLinkFetch.ts
@@ -1,24 +1,25 @@
-import {useState, useEffect} from 'react'
-import {ImageModel} from 'state/models/media/image'
 import * as apilib from 'lib/api/index'
-import {getLinkMeta} from 'lib/link-meta/link-meta'
+import {POST_IMG_MAX} from 'lib/constants'
 import {
-  getPostAsQuote,
   getFeedAsEmbed,
   getListAsEmbed,
+  getPostAsQuote,
 } from 'lib/link-meta/bsky'
+import {getLinkMeta} from 'lib/link-meta/link-meta'
 import {downloadAndResize} from 'lib/media/manip'
 import {
-  isBskyPostUrl,
   isBskyCustomFeedUrl,
   isBskyListUrl,
+  isBskyPostUrl,
 } from 'lib/strings/url-helpers'
+import {useEffect, useState} from 'react'
+import {ImageModel} from 'state/models/media/image'
 import {ComposerOpts} from 'state/shell/composer'
-import {POST_IMG_MAX} from 'lib/constants'
+
 import {logger} from '#/logger'
-import {getAgent} from '#/state/session'
-import {useGetPost} from '#/state/queries/post'
 import {useFetchDid} from '#/state/queries/handle'
+import {useGetPost} from '#/state/queries/post'
+import {getAgent} from '#/state/session'
 
 export function useExternalLinkFetch({
   setQuote,