Avi
This commit is contained in:
@@ -1,14 +1,17 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
|
import {Image as RNImage} from 'react-native-image-crop-picker'
|
||||||
import {AtUri} from '@atproto/api'
|
import {AtUri} from '@atproto/api'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {compressIfNeeded} from '#/lib/media/manip'
|
||||||
import {NavigationProp} from '#/lib/routes/types'
|
import {NavigationProp} from '#/lib/routes/types'
|
||||||
import {useCreateFeedMutation} from '#/state/queries/feed'
|
import {useCreateFeedMutation} from '#/state/queries/feed'
|
||||||
import {useProfileQuery} from '#/state/queries/profile'
|
import {useProfileQuery} from '#/state/queries/profile'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
|
import {EditableUserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {UserSelectButton} from '#/screens/Feeds/Creator/UserSelectButton'
|
import {UserSelectButton} from '#/screens/Feeds/Creator/UserSelectButton'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Admonition} from '#/components/Admonition'
|
import {Admonition} from '#/components/Admonition'
|
||||||
@@ -47,10 +50,15 @@ export function Creator() {
|
|||||||
const [description, setDescription] = React.useState('')
|
const [description, setDescription] = React.useState('')
|
||||||
const [tags, setTags] = React.useState<string[]>([])
|
const [tags, setTags] = React.useState<string[]>([])
|
||||||
const [actors, setActors] = React.useState<string[]>([])
|
const [actors, setActors] = React.useState<string[]>([])
|
||||||
|
const [avatar, setAvatar] = React.useState<string | undefined>()
|
||||||
|
const [avatarImage, setAvatarImage] = React.useState<
|
||||||
|
RNImage | undefined | null
|
||||||
|
>()
|
||||||
|
|
||||||
const onSubmit = React.useCallback(async () => {
|
const onSubmit = React.useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
await createFeed({
|
await createFeed({
|
||||||
|
avatar: avatarImage ?? undefined,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
actors,
|
actors,
|
||||||
@@ -60,7 +68,26 @@ export function Creator() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(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 (
|
return (
|
||||||
<Layout.Screen>
|
<Layout.Screen>
|
||||||
@@ -85,6 +112,25 @@ export function Creator() {
|
|||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
<View style={[a.flex_row, a.align_center, a.gap_md]}>
|
||||||
|
<View>
|
||||||
|
<EditableUserAvatar
|
||||||
|
type="algo"
|
||||||
|
size={60}
|
||||||
|
avatar={avatar}
|
||||||
|
onSelectNewAvatar={onSelectAvatar}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<TextField.LabelText>
|
||||||
|
<Trans>Add an avatar</Trans>
|
||||||
|
</TextField.LabelText>
|
||||||
|
<Text>
|
||||||
|
<Trans>Be creative!</Trans>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
<View>
|
<View>
|
||||||
<TextField.LabelText>
|
<TextField.LabelText>
|
||||||
<Trans>Title</Trans>
|
<Trans>Title</Trans>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import {useCallback, useEffect, useMemo, useRef} from 'react'
|
import {useCallback, useEffect, useMemo, useRef} from 'react'
|
||||||
|
import {Image as RNImage} from 'react-native-image-crop-picker'
|
||||||
import {
|
import {
|
||||||
AppBskyFeedGetFeedGenerator,
|
AppBskyFeedGetFeedGenerator,
|
||||||
AppBskyRichtextFacet,
|
AppBskyRichtextFacet,
|
||||||
BskyAgent,
|
BskyAgent,
|
||||||
|
ComAtprotoRepoUploadBlob,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {
|
import {
|
||||||
AppBskyActorDefs,
|
AppBskyActorDefs,
|
||||||
@@ -24,6 +26,7 @@ import {
|
|||||||
useQueryClient,
|
useQueryClient,
|
||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {uploadBlob} from '#/lib/api'
|
||||||
import {until} from '#/lib/async/until'
|
import {until} from '#/lib/async/until'
|
||||||
import {DISCOVER_FEED_URI, DISCOVER_SAVED_FEED} from '#/lib/constants'
|
import {DISCOVER_FEED_URI, DISCOVER_SAVED_FEED} from '#/lib/constants'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
@@ -653,6 +656,7 @@ export function precacheFeedFromGeneratorView(
|
|||||||
// --- feeds playground ---
|
// --- feeds playground ---
|
||||||
|
|
||||||
interface UseCreateFeedMutationParams {
|
interface UseCreateFeedMutationParams {
|
||||||
|
avatar?: RNImage
|
||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
actors: string[]
|
actors: string[]
|
||||||
@@ -674,13 +678,30 @@ export function useCreateFeedMutation({
|
|||||||
Error,
|
Error,
|
||||||
UseCreateFeedMutationParams
|
UseCreateFeedMutationParams
|
||||||
>({
|
>({
|
||||||
mutationFn: async ({name, description, actors, tags, handleSuffixes}) => {
|
mutationFn: async ({
|
||||||
|
avatar,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
actors,
|
||||||
|
tags,
|
||||||
|
handleSuffixes,
|
||||||
|
}) => {
|
||||||
let descriptionFacets: AppBskyRichtextFacet.Main[] | undefined
|
let descriptionFacets: AppBskyRichtextFacet.Main[] | undefined
|
||||||
if (description) {
|
if (description) {
|
||||||
const rt = new RichText({text: description})
|
const rt = new RichText({text: description})
|
||||||
await rt.detectFacets(agent)
|
await rt.detectFacets(agent)
|
||||||
descriptionFacets = rt.facets
|
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({
|
const res = await agent.api.com.atproto.repo.createRecord({
|
||||||
repo: agent.session!.did,
|
repo: agent.session!.did,
|
||||||
@@ -689,6 +710,7 @@ export function useCreateFeedMutation({
|
|||||||
$type: 'app.bsky.feed.generator',
|
$type: 'app.bsky.feed.generator',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
did: 'did:web:feeed.club',
|
did: 'did:web:feeed.club',
|
||||||
|
avatar: avatarBlob,
|
||||||
displayName: name,
|
displayName: name,
|
||||||
description,
|
description,
|
||||||
descriptionFacets,
|
descriptionFacets,
|
||||||
|
|||||||
Reference in New Issue
Block a user