diff --git a/src/view/com/util/post-ctrls/SubmitButton.tsx b/src/view/com/util/post-ctrls/SubmitButton.tsx
index df641b5373..de145222ce 100644
--- a/src/view/com/util/post-ctrls/SubmitButton.tsx
+++ b/src/view/com/util/post-ctrls/SubmitButton.tsx
@@ -1,35 +1,27 @@
import React from 'react'
import {TextInput, View} from 'react-native'
-import {AppBskyActorDefs, moderateProfile, ModerationOpts} from '@atproto/api'
-import {msg, Plural, Trans} from '@lingui/macro'
+import {AppBskyFeedDefs} from '@atproto/api'
+import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {sanitizeDisplayName} from '#/lib/strings/display-names'
-import {sanitizeHandle} from '#/lib/strings/handles'
import {isWeb} from '#/platform/detection'
-import {useModerationOpts} from '#/state/preferences/moderation-opts'
-import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
-import {useProfilesQuery} from '#/state/queries/profile'
import {ListMethods} from '#/view/com/util/List'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, native, useTheme, web} from '#/alf'
-import {Button, ButtonIcon} from '#/components/Button'
+import {Button, ButtonText} from '#/components/Button'
+import {useFeedsAutocomplete} from '#/components/Composer/FeedsSelector/useFeedsAutocomplete'
import * as Dialog from '#/components/Dialog'
import * as Toggle from '#/components/forms/Toggle'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
-import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {Text} from '#/components/Typography'
-const AVI_SIZE = 30
-const AVI_BORDER = 1
-
type Item =
| {
- type: 'profile'
+ type: 'feed'
key: string
checked: boolean
- profile: AppBskyActorDefs.ProfileView
+ feed: AppBskyFeedDefs.GeneratorView
}
| {
type: 'empty'
@@ -45,306 +37,79 @@ type Item =
key: string
}
-export function UserSelectButton({
- dids,
- onChangeDids,
-}: {
- dids: string[]
- onChangeDids: (dids: string[]) => void
-}) {
- const t = useTheme()
- const {_} = useLingui()
- const control = Dialog.useDialogControl()
- const {data: profiles} = useProfilesQuery({
- handles: dids,
- })
- const moderationOpts = useModerationOpts()
- const slice =
- profiles?.profiles?.slice(0, 3).map(f => {
- if (!moderationOpts) {
- return {
- profile: {
- ...f,
- displayName: f.displayName || f.handle,
- },
- moderation: null,
- }
- }
- const moderation = moderateProfile(f, moderationOpts)
- return {
- profile: {
- ...f,
- displayName: sanitizeDisplayName(
- f.displayName || f.handle,
- moderation.ui('displayName'),
- ),
- },
- moderation,
- }
- }) || []
- const serverCount = dids.length
- const textStyle = [a.text_sm]
-
- return (
- <>
-
-
-
-
-
-
- >
- )
-}
-
export function FeedSelectDialog({
control,
- profiles,
- dids,
- onChangeDids,
}: {
control: Dialog.DialogOuterProps['control']
- profiles: AppBskyActorDefs.ProfileView[]
- dids: string[]
- onChangeDids: (dids: string[]) => void
}) {
const t = useTheme()
const {_} = useLingui()
- const moderationOpts = useModerationOpts()
const listRef = React.useRef(null)
const inputRef = React.useRef(null)
- const [searchText, setSearchText] = React.useState('')
+ const [uris, setUris] = React.useState([])
const {
- data: results,
- isError,
- isFetching,
- } = useActorAutocompleteQuery(searchText, true, 12)
+ query: searchText,
+ suggestions: results,
+ feeds,
+ setQuery: setSearchText,
+ } = useFeedsAutocomplete()
- const onToggleUser = React.useCallback(
- (did: string, checked: boolean) => {
+ const onToggleFeed = React.useCallback(
+ (uri: string, checked: boolean) => {
if (checked) {
- onChangeDids(Array.from(new Set([did, ...dids])))
+ setUris(Array.from(new Set([uri, ...uris])))
} else {
- onChangeDids(dids.filter(d => d !== did))
+ setUris(uris.filter(u => u !== uri))
}
},
- [dids, onChangeDids],
+ [uris],
)
const items = React.useMemo(() => {
let _items: Item[] = []
- if (isError) {
- _items.push({
- type: 'empty',
- key: 'empty',
- message: _(msg`We're having network issues, try again`),
- })
- } else if (searchText.length) {
+ if (searchText.length) {
if (results?.length) {
- for (const profile of results) {
+ for (const feed of results) {
_items.push({
- type: 'profile',
- key: profile.did,
- checked: dids.includes(profile.did),
- profile,
+ type: 'feed',
+ key: feed.uri,
+ checked: uris.includes(feed.uri),
+ feed,
})
}
-
- // _items = _items.sort(item => {
- // // @ts-ignore
- // return item.enabled ? -1 : 1
- // })
}
} else {
- if (profiles.length) {
- for (const profile of profiles) {
+ if (feeds?.length) {
+ for (const feed of feeds) {
_items.push({
- type: 'profile',
- key: profile.did,
- checked: dids.includes(profile.did),
- profile,
+ type: 'feed',
+ key: feed.uri,
+ checked: uris.includes(feed.uri),
+ feed,
})
}
-
- // _items = _items.sort(item => {
- // // @ts-ignore
- // return item.checked ? -1 : 1
- // })
- } else {
- const placeholders: Item[] = Array(10)
- .fill(0)
- .map((__, i) => ({
- type: 'placeholder',
- key: i + '',
- }))
- _items.push(...placeholders)
}
}
-
return _items
- }, [_, dids, profiles, searchText, results, isError])
+ }, [results, uris, feeds, searchText])
- if (searchText && !isFetching && !items.length && !isError) {
+ if (searchText && !items.length) {
items.push({type: 'empty', key: 'empty', message: _(msg`No results`)})
}
const renderItems = React.useCallback(
({item}: {item: Item}) => {
switch (item.type) {
- case 'profile': {
+ case 'feed': {
return (
-
)
}
@@ -358,7 +123,7 @@ export function FeedSelectDialog({
return null
}
},
- [moderationOpts, onToggleUser],
+ [onToggleFeed],
)
React.useLayoutEffect(() => {
@@ -396,21 +161,29 @@ export function FeedSelectDialog({
/>
- {isWeb && (
-
- )}
+
)
- }, [t.atoms.border_contrast_low, t.atoms.bg, _, searchText, control])
+ }, [
+ t.atoms.border_contrast_low,
+ t.atoms.bg,
+ uris,
+ _,
+ searchText,
+ control,
+ setSearchText,
+ ])
return (
void
+ feed: AppBskyFeedDefs.GeneratorView
+ onToggle: (uri: string, checked: boolean) => void
}) {
const t = useTheme()
const {_} = useLingui()
- const moderation = moderateProfile(profile, moderationOpts)
- const handle = sanitizeHandle(profile.handle, '@')
- const displayName = sanitizeDisplayName(
- profile.displayName || sanitizeHandle(profile.handle),
- moderation.ui('displayName'),
- )
+ const displayName = feed.displayName
const handleOnPress = React.useCallback(
(selected: boolean) => {
- onToggle(profile.did, selected)
+ onToggle(feed.uri, selected)
},
- [onToggle, profile.did],
+ [onToggle, feed.uri],
)
return (
{({hovered, pressed, focused}) => (
@@ -479,12 +245,7 @@ function ProfileCard({
? t.atoms.bg_contrast_50
: t.atoms.bg,
]}>
-
+
- {handle}
+ by @{feed.creator.handle}