add query
This commit is contained in:
@@ -8,16 +8,14 @@ import {
|
|||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
|
||||||
|
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {useTheme} from '#/lib/ThemeContext'
|
import {useTheme} from '#/lib/ThemeContext'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {hydrateFeedGenerator} from '#/state/queries/feed'
|
|
||||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
|
||||||
import {RQKEY, useProfileFeedgensQuery} from '#/state/queries/profile-feedgens'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useActorStarterPacksQuery} from 'state/queries/actor-starter-packs'
|
||||||
|
import {usePreferencesQuery} from 'state/queries/preferences'
|
||||||
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
|
||||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
||||||
import {List, ListRef} from 'view/com/util/List'
|
import {List, ListRef} from 'view/com/util/List'
|
||||||
@@ -55,20 +53,23 @@ export const ProfileStarterPacks = React.forwardRef<
|
|||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const [isPTRing, setIsPTRing] = React.useState(false)
|
const [isPTRing, setIsPTRing] = React.useState(false)
|
||||||
const opts = React.useMemo(() => ({enabled}), [enabled])
|
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
isFetching,
|
isFetching,
|
||||||
isFetched,
|
|
||||||
hasNextPage,
|
|
||||||
fetchNextPage,
|
|
||||||
isError,
|
isError,
|
||||||
error,
|
isFetched,
|
||||||
|
fetchNextPage,
|
||||||
refetch,
|
refetch,
|
||||||
} = useProfileFeedgensQuery(did, opts)
|
hasNextPage,
|
||||||
const isEmpty = !isFetching && !data?.pages[0]?.feeds.length
|
error,
|
||||||
|
} = useActorStarterPacksQuery({
|
||||||
|
did,
|
||||||
|
})
|
||||||
const {data: preferences} = usePreferencesQuery()
|
const {data: preferences} = usePreferencesQuery()
|
||||||
|
|
||||||
|
const isEmpty = !isFetching && data?.pages.length === 0
|
||||||
|
|
||||||
const items = React.useMemo(() => {
|
const items = React.useMemo(() => {
|
||||||
let items: any[] = []
|
let items: any[] = []
|
||||||
if (isError && isEmpty) {
|
if (isError && isEmpty) {
|
||||||
@@ -80,7 +81,7 @@ export const ProfileStarterPacks = React.forwardRef<
|
|||||||
items = items.concat([EMPTY])
|
items = items.concat([EMPTY])
|
||||||
} else if (data?.pages) {
|
} else if (data?.pages) {
|
||||||
for (const page of data?.pages) {
|
for (const page of data?.pages) {
|
||||||
items = items.concat(page.feeds.map(feed => hydrateFeedGenerator(feed)))
|
items = page.starterPacks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isError && !isEmpty) {
|
if (isError && !isEmpty) {
|
||||||
@@ -89,18 +90,8 @@ export const ProfileStarterPacks = React.forwardRef<
|
|||||||
return items
|
return items
|
||||||
}, [isError, isEmpty, isFetched, isFetching, data])
|
}, [isError, isEmpty, isFetched, isFetching, data])
|
||||||
|
|
||||||
const queryClient = useQueryClient()
|
|
||||||
|
|
||||||
const onScrollToTop = React.useCallback(() => {
|
|
||||||
scrollElRef.current?.scrollToOffset({
|
|
||||||
animated: isNative,
|
|
||||||
offset: -headerOffset,
|
|
||||||
})
|
|
||||||
queryClient.invalidateQueries({queryKey: RQKEY(did)})
|
|
||||||
}, [scrollElRef, queryClient, headerOffset, did])
|
|
||||||
|
|
||||||
React.useImperativeHandle(ref, () => ({
|
React.useImperativeHandle(ref, () => ({
|
||||||
scrollToTop: onScrollToTop,
|
scrollToTop: () => {},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const onRefresh = React.useCallback(async () => {
|
const onRefresh = React.useCallback(async () => {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import React from 'react'
|
|||||||
import {AppBskyActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs} from '@atproto/api'
|
||||||
import {GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs'
|
import {GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs'
|
||||||
|
|
||||||
|
import {useAgent, useSession} from 'state/session'
|
||||||
|
|
||||||
const steps = ['Details', 'Profiles', 'Feeds'] as const
|
const steps = ['Details', 'Profiles', 'Feeds'] as const
|
||||||
type Step = (typeof steps)[number]
|
type Step = (typeof steps)[number]
|
||||||
|
|
||||||
@@ -28,11 +30,12 @@ interface State {
|
|||||||
processing: boolean
|
processing: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type TStateContext = [State, (action: Action) => void]
|
type TStateContext = [State, (action: Action) => void, () => Promise<void>]
|
||||||
|
|
||||||
const StateContext = React.createContext<TStateContext>([
|
const StateContext = React.createContext<TStateContext>([
|
||||||
{} as State,
|
{} as State,
|
||||||
(_: Action) => {},
|
(_: Action) => {},
|
||||||
|
async () => {},
|
||||||
])
|
])
|
||||||
export const useWizardState = () => React.useContext(StateContext)
|
export const useWizardState = () => React.useContext(StateContext)
|
||||||
|
|
||||||
@@ -107,7 +110,10 @@ export function Provider({
|
|||||||
initialStep?: Step
|
initialStep?: Step
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
const stateAndReducer = React.useReducer(
|
const agent = useAgent()
|
||||||
|
const {currentAccount} = useSession()
|
||||||
|
|
||||||
|
const [state, dispatch] = React.useReducer(
|
||||||
reducer,
|
reducer,
|
||||||
initialState
|
initialState
|
||||||
? {
|
? {
|
||||||
@@ -123,8 +129,60 @@ export function Provider({
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
dispatch({type: 'SetProcessing', processing: true})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const list = await agent.app.bsky.graph.list.create(
|
||||||
|
{repo: currentAccount?.did},
|
||||||
|
{
|
||||||
|
name: state.name ?? '',
|
||||||
|
description: state.description ?? '',
|
||||||
|
descriptionFacets: [],
|
||||||
|
avatar: undefined,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
purpose: 'app.bsky.graph.defs#referencelist',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
await agent.com.atproto.repo.applyWrites({
|
||||||
|
repo: currentAccount!.did,
|
||||||
|
writes: state.profiles.map(p => ({
|
||||||
|
collection: 'app.bsky.graph.listitem',
|
||||||
|
value: {
|
||||||
|
$type: 'app.bsky.graph.listitem',
|
||||||
|
subject: p.did,
|
||||||
|
list: list.uri,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
|
||||||
|
await agent.app.bsky.graph.starterpack.create(
|
||||||
|
{
|
||||||
|
repo: currentAccount!.did,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: state.name ?? '',
|
||||||
|
description: state.description ?? '',
|
||||||
|
descriptionFacets: [],
|
||||||
|
list: list.uri,
|
||||||
|
feeds: state.feeds.map(f => ({
|
||||||
|
uri: f.uri,
|
||||||
|
})),
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
// TODO add error to state
|
||||||
|
console.error(e)
|
||||||
|
} finally {
|
||||||
|
dispatch({type: 'SetProcessing', processing: false})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StateContext.Provider value={stateAndReducer}>
|
<StateContext.Provider value={[state, dispatch, submit]}>
|
||||||
{children}
|
{children}
|
||||||
</StateContext.Provider>
|
</StateContext.Provider>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ function WizardInner() {
|
|||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const [state, dispatch] = useWizardState()
|
const [state, dispatch, submit] = useWizardState()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const {data: currentProfile} = useProfileQuery({
|
const {data: currentProfile} = useProfileQuery({
|
||||||
did: currentAccount?.did,
|
did: currentAccount?.did,
|
||||||
@@ -130,7 +130,7 @@ function WizardInner() {
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
} else if (state.currentStep === 'Feeds') {
|
} else if (state.currentStep === 'Feeds') {
|
||||||
dispatch({type: 'SetProcessing', processing: true})
|
submit()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import {AppBskyGraphGetActorStarterPacks} from '@atproto/api'
|
||||||
|
import {InfiniteData, QueryKey, useInfiniteQuery} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {STALE} from 'state/queries/index'
|
||||||
|
import {useAgent} from 'state/session'
|
||||||
|
|
||||||
|
const RQKEY_ROOT = 'actor-starter-packs'
|
||||||
|
|
||||||
|
export function useActorStarterPacksQuery({did}: {did?: string}) {
|
||||||
|
const agent = useAgent()
|
||||||
|
|
||||||
|
return useInfiniteQuery<
|
||||||
|
AppBskyGraphGetActorStarterPacks.OutputSchema,
|
||||||
|
Error,
|
||||||
|
InfiniteData<AppBskyGraphGetActorStarterPacks.OutputSchema>,
|
||||||
|
QueryKey,
|
||||||
|
string | undefined
|
||||||
|
>({
|
||||||
|
queryKey: [RQKEY_ROOT, did],
|
||||||
|
queryFn: async ({pageParam}: {pageParam?: string}) => {
|
||||||
|
const res = await agent.app.bsky.graph.getActorStarterPacks({
|
||||||
|
actor: did!,
|
||||||
|
limit: 10,
|
||||||
|
cursor: pageParam,
|
||||||
|
})
|
||||||
|
return res.data
|
||||||
|
},
|
||||||
|
enabled: Boolean(did),
|
||||||
|
initialPageParam: undefined,
|
||||||
|
getNextPageParam: lastPage => lastPage.cursor,
|
||||||
|
staleTime: STALE.MINUTES.ONE,
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user