diff --git a/src/screens/Feeds/Creator/index.tsx b/src/screens/Feeds/Creator/index.tsx index 6149382541..3c1380088e 100644 --- a/src/screens/Feeds/Creator/index.tsx +++ b/src/screens/Feeds/Creator/index.tsx @@ -1,14 +1,17 @@ import React from 'react' import {View} from 'react-native' +import {Image as RNImage} from 'react-native-image-crop-picker' import {AtUri} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' +import {compressIfNeeded} from '#/lib/media/manip' import {NavigationProp} from '#/lib/routes/types' import {useCreateFeedMutation} from '#/state/queries/feed' import {useProfileQuery} from '#/state/queries/profile' import {useSession} from '#/state/session' +import {EditableUserAvatar} from '#/view/com/util/UserAvatar' import {UserSelectButton} from '#/screens/Feeds/Creator/UserSelectButton' import {atoms as a, useTheme} from '#/alf' import {Admonition} from '#/components/Admonition' @@ -47,10 +50,15 @@ export function Creator() { const [description, setDescription] = React.useState('') const [tags, setTags] = React.useState([]) const [actors, setActors] = React.useState([]) + const [avatar, setAvatar] = React.useState() + const [avatarImage, setAvatarImage] = React.useState< + RNImage | undefined | null + >() const onSubmit = React.useCallback(async () => { try { await createFeed({ + avatar: avatarImage ?? undefined, name, description, actors, @@ -60,7 +68,26 @@ export function Creator() { } catch (e) { console.error(e) } - }, [name, description, actors, tags, createFeed]) + }, [name, description, actors, tags, createFeed, avatarImage]) + + const onSelectAvatar = React.useCallback( + async (image: RNImage | null) => { + //setImageError('') + if (image === null) { + setAvatar(undefined) + setAvatarImage(null) + return + } + try { + const finalImg = await compressIfNeeded(image, 1000000) + setAvatar(finalImg.path) + setAvatarImage(finalImg) + } catch (e: any) { + //setImageError(cleanError(e)) + } + }, + [setAvatar, setAvatarImage], + ) return ( @@ -85,6 +112,25 @@ export function Creator() { + + + + + + + Add an avatar + + + Be creative! + + + + Title diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts index 7fd4278c11..9fa77f305b 100644 --- a/src/state/queries/feed.ts +++ b/src/state/queries/feed.ts @@ -1,8 +1,10 @@ import {useCallback, useEffect, useMemo, useRef} from 'react' +import {Image as RNImage} from 'react-native-image-crop-picker' import { AppBskyFeedGetFeedGenerator, AppBskyRichtextFacet, BskyAgent, + ComAtprotoRepoUploadBlob, } from '@atproto/api' import { AppBskyActorDefs, @@ -24,6 +26,7 @@ import { useQueryClient, } from '@tanstack/react-query' +import {uploadBlob} from '#/lib/api' import {until} from '#/lib/async/until' import {DISCOVER_FEED_URI, DISCOVER_SAVED_FEED} from '#/lib/constants' import {sanitizeDisplayName} from '#/lib/strings/display-names' @@ -653,6 +656,7 @@ export function precacheFeedFromGeneratorView( // --- feeds playground --- interface UseCreateFeedMutationParams { + avatar?: RNImage name: string description?: string actors: string[] @@ -674,13 +678,30 @@ export function useCreateFeedMutation({ Error, UseCreateFeedMutationParams >({ - mutationFn: async ({name, description, actors, tags, handleSuffixes}) => { + mutationFn: async ({ + avatar, + name, + description, + actors, + tags, + handleSuffixes, + }) => { let descriptionFacets: AppBskyRichtextFacet.Main[] | undefined if (description) { const rt = new RichText({text: description}) await rt.detectFacets(agent) descriptionFacets = rt.facets } + let avatarBlob: + | ComAtprotoRepoUploadBlob.Response['data']['blob'] + | undefined + + if (avatar) { + const res = await uploadBlob(agent, avatar.path, avatar.mime) + if (res.data) { + avatarBlob = res.data.blob + } + } const res = await agent.api.com.atproto.repo.createRecord({ repo: agent.session!.did, @@ -689,6 +710,7 @@ export function useCreateFeedMutation({ $type: 'app.bsky.feed.generator', createdAt: new Date().toISOString(), did: 'did:web:feeed.club', + avatar: avatarBlob, displayName: name, description, descriptionFacets,