start using mutations
This commit is contained in:
@@ -16,7 +16,7 @@ import {createFullHandle} from '#/lib/strings/handles'
|
|||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {useServiceQuery} from '#/state/queries/service'
|
import {useServiceQuery} from '#/state/queries/service'
|
||||||
import {useAgent} from '#/state/session'
|
import {useAgent} from '#/state/session'
|
||||||
import {useStarterPackQuery} from 'state/queries/useStarterPackQuery'
|
import {useStarterPackQuery} from 'state/queries/starter-pack'
|
||||||
import {useActiveStarterPack} from 'state/shell/starter-pack'
|
import {useActiveStarterPack} from 'state/shell/starter-pack'
|
||||||
import {LoggedOutLayout} from '#/view/com/util/layouts/LoggedOutLayout'
|
import {LoggedOutLayout} from '#/view/com/util/layouts/LoggedOutLayout'
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
|||||||
import {createStarterPackGooglePlayUri} from 'lib/strings/starter-pack'
|
import {createStarterPackGooglePlayUri} from 'lib/strings/starter-pack'
|
||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from 'platform/detection'
|
||||||
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
||||||
import {useStarterPackQuery} from 'state/queries/useStarterPackQuery'
|
import {useStarterPackQuery} from 'state/queries/starter-pack'
|
||||||
import {
|
import {
|
||||||
useActiveStarterPack,
|
useActiveStarterPack,
|
||||||
useSetActiveStarterPack,
|
useSetActiveStarterPack,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {logEvent} from 'lib/statsig/statsig'
|
|||||||
import {isWeb} from 'platform/detection'
|
import {isWeb} from 'platform/detection'
|
||||||
import {RQKEY} from 'state/queries/list-members'
|
import {RQKEY} from 'state/queries/list-members'
|
||||||
import {useResolveDidQuery} from 'state/queries/resolve-uri'
|
import {useResolveDidQuery} from 'state/queries/resolve-uri'
|
||||||
import {useStarterPackQuery} from 'state/queries/useStarterPackQuery'
|
import {useStarterPackQuery} from 'state/queries/starter-pack'
|
||||||
import {useAgent, useSession} from 'state/session'
|
import {useAgent, useSession} from 'state/session'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
|
import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
|||||||
import {
|
import {
|
||||||
AppBskyActorDefs,
|
AppBskyActorDefs,
|
||||||
AppBskyGraphDefs,
|
AppBskyGraphDefs,
|
||||||
AppBskyGraphStarterpack,
|
|
||||||
AtUri,
|
AtUri,
|
||||||
ModerationOpts,
|
ModerationOpts,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
@@ -18,28 +17,24 @@ import {msg, Plural, Trans} from '@lingui/macro'
|
|||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
|
||||||
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {HITSLOP_10} from 'lib/constants'
|
import {HITSLOP_10} from 'lib/constants'
|
||||||
import {createStarterPackList} from 'lib/generate-starterpack'
|
|
||||||
import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
|
import {CommonNavigatorParams, NavigationProp} from 'lib/routes/types'
|
||||||
import {logEvent} from 'lib/statsig/statsig'
|
import {logEvent} from 'lib/statsig/statsig'
|
||||||
import {sanitizeDisplayName} from 'lib/strings/display-names'
|
import {sanitizeDisplayName} from 'lib/strings/display-names'
|
||||||
import {sanitizeHandle} from 'lib/strings/handles'
|
import {sanitizeHandle} from 'lib/strings/handles'
|
||||||
import {enforceLen} from 'lib/strings/helpers'
|
import {enforceLen} from 'lib/strings/helpers'
|
||||||
|
import {parseStarterPackUri} from 'lib/strings/starter-pack'
|
||||||
import {isAndroid, isNative, isWeb} from 'platform/detection'
|
import {isAndroid, isNative, isWeb} from 'platform/detection'
|
||||||
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
import {useModerationOpts} from 'state/preferences/moderation-opts'
|
||||||
import {invalidateActorStarterPacksQuery} from 'state/queries/actor-starter-packs'
|
import {useListMembersQuery} from 'state/queries/list-members'
|
||||||
import {
|
|
||||||
invalidateListMembersQuery,
|
|
||||||
useListMembersQuery,
|
|
||||||
} from 'state/queries/list-members'
|
|
||||||
import {useProfileQuery} from 'state/queries/profile'
|
import {useProfileQuery} from 'state/queries/profile'
|
||||||
import {
|
import {
|
||||||
invalidateStarterPack,
|
useCreateStarterPackMutation,
|
||||||
|
useEditStarterPackMutation,
|
||||||
useStarterPackQuery,
|
useStarterPackQuery,
|
||||||
} from 'state/queries/useStarterPackQuery'
|
} from 'state/queries/starter-pack'
|
||||||
import {useAgent, useSession} from 'state/session'
|
import {useAgent, useSession} from 'state/session'
|
||||||
import {useSetMinimalShellMode} from 'state/shell'
|
import {useSetMinimalShellMode} from 'state/shell'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
@@ -120,14 +115,8 @@ export function Wizard({
|
|||||||
return (
|
return (
|
||||||
<Provider starterPack={starterPack} listItems={listItems}>
|
<Provider starterPack={starterPack} listItems={listItems}>
|
||||||
<WizardInner
|
<WizardInner
|
||||||
rkey={rkey}
|
currentStarterPack={starterPack}
|
||||||
createdAt={
|
currentListItems={listItems}
|
||||||
AppBskyGraphStarterpack.isRecord(starterPack?.record)
|
|
||||||
? starterPack.record.createdAt
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
listItems={listItems}
|
|
||||||
listUri={listUri}
|
|
||||||
profile={profile}
|
profile={profile}
|
||||||
moderationOpts={moderationOpts}
|
moderationOpts={moderationOpts}
|
||||||
/>
|
/>
|
||||||
@@ -136,17 +125,13 @@ export function Wizard({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function WizardInner({
|
function WizardInner({
|
||||||
rkey,
|
currentStarterPack,
|
||||||
createdAt: initialCreatedAt,
|
currentListItems,
|
||||||
listUri: initialListUri,
|
|
||||||
listItems: initialListItems,
|
|
||||||
profile,
|
profile,
|
||||||
moderationOpts,
|
moderationOpts,
|
||||||
}: {
|
}: {
|
||||||
rkey?: string
|
currentStarterPack?: AppBskyGraphDefs.StarterPackView
|
||||||
createdAt?: string
|
currentListItems?: AppBskyGraphDefs.ListItemView[]
|
||||||
listUri?: string
|
|
||||||
listItems?: AppBskyGraphDefs.ListItemView[]
|
|
||||||
profile: AppBskyActorDefs.ProfileViewBasic
|
profile: AppBskyActorDefs.ProfileViewBasic
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
}) {
|
}) {
|
||||||
@@ -155,7 +140,6 @@ function WizardInner({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const setMinimalShellMode = useSetMinimalShellMode()
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
const {setEnabled} = useKeyboardController()
|
const {setEnabled} = useKeyboardController()
|
||||||
const queryClient = useQueryClient()
|
|
||||||
const [state, dispatch] = useWizardState()
|
const [state, dispatch] = useWizardState()
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
@@ -163,6 +147,7 @@ function WizardInner({
|
|||||||
did: currentAccount?.did,
|
did: currentAccount?.did,
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
})
|
})
|
||||||
|
const parsed = parseStarterPackUri(currentStarterPack?.uri)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
@@ -218,178 +203,88 @@ function WizardInner({
|
|||||||
}
|
}
|
||||||
const currUiStrings = wizardUiStrings[state.currentStep]
|
const currUiStrings = wizardUiStrings[state.currentStep]
|
||||||
|
|
||||||
const invalidateQueries = async () => {
|
const onSuccessCreate = (data: {uri: string; cid: string}) => {
|
||||||
if (!rkey) return
|
const rkey = new AtUri(data.uri).rkey
|
||||||
|
logEvent('starterPack:create', {
|
||||||
if (initialListUri) {
|
setName: state.name != null,
|
||||||
await invalidateListMembersQuery({queryClient, uri: initialListUri})
|
setDescription: state.description != null,
|
||||||
}
|
profilesCount: state.profiles.length,
|
||||||
await invalidateActorStarterPacksQuery({
|
feedsCount: state.feeds.length,
|
||||||
queryClient,
|
|
||||||
did: currentAccount!.did,
|
|
||||||
})
|
})
|
||||||
await invalidateStarterPack({
|
dispatch({type: 'SetProcessing', processing: false})
|
||||||
queryClient,
|
navigation.replace('StarterPack', {
|
||||||
did: currentAccount!.did,
|
name: currentAccount!.handle,
|
||||||
rkey,
|
rkey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onSuccessEdit = () => {
|
||||||
|
if (navigation.canGoBack()) {
|
||||||
|
navigation.goBack()
|
||||||
|
} else {
|
||||||
|
navigation.replace('StarterPack', {
|
||||||
|
name: currentAccount!.handle,
|
||||||
|
rkey: parsed!.rkey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onError = (e: Error) => {
|
||||||
|
logger.error('Failed to create starter pack', {safeMessage: e})
|
||||||
|
dispatch({type: 'SetProcessing', processing: false})
|
||||||
|
Toast.show(_(msg`Failed to create starter pack`))
|
||||||
|
}
|
||||||
|
|
||||||
|
const {mutate: createStarterPack} = useCreateStarterPackMutation({
|
||||||
|
onSuccess: onSuccessCreate,
|
||||||
|
onError,
|
||||||
|
})
|
||||||
|
const {mutate: editStarterPack} = useEditStarterPackMutation({
|
||||||
|
onSuccess: onSuccessEdit,
|
||||||
|
onError,
|
||||||
|
})
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
dispatch({type: 'SetProcessing', processing: true})
|
dispatch({type: 'SetProcessing', processing: true})
|
||||||
|
if (currentStarterPack && currentListItems) {
|
||||||
try {
|
editStarterPack({
|
||||||
if (rkey) {
|
name: state.name ?? getDefaultName(),
|
||||||
// Editing an existing starter pack
|
description: state.description,
|
||||||
let list: {uri: string; cid: string} | undefined = initialListUri
|
descriptionFacets: [],
|
||||||
? {uri: initialListUri, cid: ''}
|
profiles: state.profiles,
|
||||||
: undefined
|
feeds: state.feeds,
|
||||||
if (initialListUri) {
|
currentStarterPack: currentStarterPack,
|
||||||
const removedItems = initialListItems?.filter(
|
currentListItems: currentListItems,
|
||||||
i => !state.profiles.find(p => p.did === i.subject.did),
|
})
|
||||||
)
|
} else {
|
||||||
if (removedItems && removedItems.length > 0) {
|
createStarterPack({
|
||||||
await agent.com.atproto.repo.applyWrites({
|
name: state.name ?? getDefaultName(),
|
||||||
repo: currentAccount!.did,
|
description: state.description,
|
||||||
writes: removedItems.map(i => ({
|
descriptionFacets: [],
|
||||||
$type: 'com.atproto.repo.applyWrites#delete',
|
profiles: state.profiles,
|
||||||
collection: 'app.bsky.graph.listitem',
|
feeds: state.feeds,
|
||||||
rkey: new AtUri(i.uri).rkey,
|
})
|
||||||
})),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const addedProfiles = state.profiles.filter(
|
|
||||||
p => !initialListItems?.find(i => i.subject.did === p.did),
|
|
||||||
)
|
|
||||||
|
|
||||||
if (addedProfiles.length > 0) {
|
|
||||||
await agent.com.atproto.repo.applyWrites({
|
|
||||||
repo: currentAccount!.did,
|
|
||||||
writes: addedProfiles.map(p => ({
|
|
||||||
$type: 'com.atproto.repo.applyWrites#create',
|
|
||||||
collection: 'app.bsky.graph.listitem',
|
|
||||||
value: {
|
|
||||||
$type: 'app.bsky.graph.listitem',
|
|
||||||
subject: p.did,
|
|
||||||
list: list?.uri,
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list = await createStarterPackList({
|
|
||||||
name: state.name ?? getDefaultName(),
|
|
||||||
description: state.description,
|
|
||||||
descriptionFacets: [],
|
|
||||||
profiles: state.profiles,
|
|
||||||
agent,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
await agent.com.atproto.repo.putRecord({
|
|
||||||
repo: currentAccount!.did,
|
|
||||||
collection: 'app.bsky.graph.starterpack',
|
|
||||||
rkey,
|
|
||||||
record: {
|
|
||||||
name: state.name ?? getDefaultName(),
|
|
||||||
description: state.description,
|
|
||||||
descriptionFacets: [],
|
|
||||||
list: list?.uri,
|
|
||||||
feeds: state.feeds.map(f => ({
|
|
||||||
uri: f.uri,
|
|
||||||
})),
|
|
||||||
createdAt: initialCreatedAt,
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
},
|
|
||||||
validate: false, // TODO remove!
|
|
||||||
})
|
|
||||||
|
|
||||||
setTimeout(async () => {
|
|
||||||
await invalidateQueries()
|
|
||||||
if (navigation.canGoBack()) {
|
|
||||||
navigation.goBack()
|
|
||||||
} else {
|
|
||||||
navigation.replace('StarterPack', {
|
|
||||||
name: currentAccount!.handle,
|
|
||||||
rkey,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
dispatch({type: 'SetProcessing', processing: false})
|
|
||||||
}, 2000)
|
|
||||||
} else {
|
|
||||||
// Creating a new starter pack
|
|
||||||
const list = await createStarterPackList({
|
|
||||||
name: state.name ?? getDefaultName(),
|
|
||||||
description: state.description,
|
|
||||||
descriptionFacets: [],
|
|
||||||
profiles: state.profiles,
|
|
||||||
agent,
|
|
||||||
})
|
|
||||||
const res = await agent.app.bsky.graph.starterpack.create(
|
|
||||||
{
|
|
||||||
repo: currentAccount!.did,
|
|
||||||
validate: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: state.name ?? getDefaultName(),
|
|
||||||
description: state.description,
|
|
||||||
descriptionFacets: [],
|
|
||||||
list: list.uri,
|
|
||||||
feeds: state.feeds.map(f => ({
|
|
||||||
uri: f.uri,
|
|
||||||
})),
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
logEvent('starterPack:create', {
|
|
||||||
setName: state.name != null,
|
|
||||||
setDescription: state.description != null,
|
|
||||||
profilesCount: state.profiles.length,
|
|
||||||
feedsCount: state.feeds.length,
|
|
||||||
})
|
|
||||||
|
|
||||||
const newRkey = new AtUri(res.uri).rkey
|
|
||||||
|
|
||||||
setTimeout(async () => {
|
|
||||||
await invalidateQueries()
|
|
||||||
navigation.replace('StarterPack', {
|
|
||||||
name: currentAccount!.handle,
|
|
||||||
rkey: newRkey,
|
|
||||||
})
|
|
||||||
dispatch({type: 'SetProcessing', processing: false})
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
} catch (e: unknown) {
|
|
||||||
logger.error('Failed to create starter pack', {safeMessage: e})
|
|
||||||
Toast.show(_(msg`Failed to create starter pack`))
|
|
||||||
dispatch({type: 'SetProcessing', processing: false})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteStarterPack = async () => {
|
const deleteStarterPack = async () => {
|
||||||
if (!rkey || !initialListUri) return
|
if (!currentStarterPack || !currentListItems) return
|
||||||
|
|
||||||
dispatch({type: 'SetProcessing', processing: true})
|
dispatch({type: 'SetProcessing', processing: true})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await agent.app.bsky.graph.list.delete({
|
await agent.app.bsky.graph.list.delete({
|
||||||
repo: currentAccount!.did,
|
repo: currentAccount!.did,
|
||||||
rkey: new AtUri(initialListUri).rkey,
|
// TODO list is required, so shouldn't need this assertion
|
||||||
|
rkey: new AtUri(currentStarterPack.list!.uri).rkey,
|
||||||
})
|
})
|
||||||
await agent.app.bsky.graph.starterpack.delete({
|
await agent.app.bsky.graph.starterpack.delete({
|
||||||
repo: currentAccount!.did,
|
repo: currentAccount!.did,
|
||||||
rkey,
|
rkey: new AtUri(currentStarterPack.uri).rkey,
|
||||||
})
|
})
|
||||||
|
|
||||||
setTimeout(async () => {
|
logEvent('starterPack:delete', {})
|
||||||
await invalidateQueries()
|
navigation.popToTop()
|
||||||
logEvent('starterPack:delete', {})
|
|
||||||
navigation.popToTop()
|
|
||||||
}, 2000)
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Toast.show(_(msg`Failed to delete starter pack`))
|
Toast.show(_(msg`Failed to delete starter pack`))
|
||||||
} finally {
|
} finally {
|
||||||
@@ -456,7 +351,7 @@ function WizardInner({
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Container
|
<Container
|
||||||
showDeleteBtn={Boolean(rkey)}
|
showDeleteBtn={Boolean(currentStarterPack)}
|
||||||
deleteStarterPack={deleteStarterPack}>
|
deleteStarterPack={deleteStarterPack}>
|
||||||
{state.currentStep === 'Details' ? (
|
{state.currentStep === 'Details' ? (
|
||||||
<StepDetails />
|
<StepDetails />
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import {
|
|||||||
AppBskyActorDefs,
|
AppBskyActorDefs,
|
||||||
AppBskyFeedDefs,
|
AppBskyFeedDefs,
|
||||||
AppBskyGraphDefs,
|
AppBskyGraphDefs,
|
||||||
AppBskyGraphGetList,
|
AppBskyGraphStarterpack,
|
||||||
|
AtUri,
|
||||||
BskyAgent,
|
BskyAgent,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {StarterPackView} from '@atproto/api/dist/client/types/app/bsky/graph/defs'
|
import {StarterPackView} from '@atproto/api/dist/client/types/app/bsky/graph/defs'
|
||||||
@@ -19,10 +20,8 @@ import {
|
|||||||
httpStarterPackUriToAtUri,
|
httpStarterPackUriToAtUri,
|
||||||
parseStarterPackUri,
|
parseStarterPackUri,
|
||||||
} from 'lib/strings/starter-pack'
|
} from 'lib/strings/starter-pack'
|
||||||
import {
|
import {invalidateActorStarterPacksQuery} from 'state/queries/actor-starter-packs'
|
||||||
invalidateActorStarterPacksQuery,
|
import {invalidateListMembersQuery} from 'state/queries/list-members'
|
||||||
RQKEY,
|
|
||||||
} from 'state/queries/actor-starter-packs'
|
|
||||||
import {useAgent} from 'state/session'
|
import {useAgent} from 'state/session'
|
||||||
|
|
||||||
const RQKEY_ROOT = 'starter-pack'
|
const RQKEY_ROOT = 'starter-pack'
|
||||||
@@ -86,8 +85,9 @@ interface UseCreateStarterPackMutationParams {
|
|||||||
|
|
||||||
export function useCreateStarterPackMutation({
|
export function useCreateStarterPackMutation({
|
||||||
onSuccess,
|
onSuccess,
|
||||||
|
onError,
|
||||||
}: {
|
}: {
|
||||||
onSuccess: () => void
|
onSuccess: (data: {uri: string; cid: string}) => void
|
||||||
onError: (e: Error) => void
|
onError: (e: Error) => void
|
||||||
}) {
|
}) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
@@ -100,7 +100,7 @@ export function useCreateStarterPackMutation({
|
|||||||
>({
|
>({
|
||||||
mutationFn: async params => {
|
mutationFn: async params => {
|
||||||
let listRes
|
let listRes
|
||||||
const listRes = await createStarterPackList({...params, agent})
|
listRes = await createStarterPackList({...params, agent})
|
||||||
return await agent.app.bsky.graph.starterpack.create(
|
return await agent.app.bsky.graph.starterpack.create(
|
||||||
{
|
{
|
||||||
repo: agent.session?.did,
|
repo: agent.session?.did,
|
||||||
@@ -108,22 +108,134 @@ export function useCreateStarterPackMutation({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
...params,
|
...params,
|
||||||
list: listRes.uri,
|
list: listRes?.uri,
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onSuccess: async data => {
|
onSuccess: async data => {
|
||||||
await whenAppViewReady(
|
await whenAppViewReady(agent, data.uri, v => {
|
||||||
agent,
|
return typeof v?.uri === 'string'
|
||||||
data.uri,
|
})
|
||||||
(v?: AppBskyGraphDefs.StarterPackView) => {
|
|
||||||
return typeof v.uri === 'string'
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await invalidateActorStarterPacksQuery({
|
await invalidateActorStarterPacksQuery({
|
||||||
queryClient,
|
queryClient,
|
||||||
did: agent.session?.did,
|
did: agent.session!.did,
|
||||||
|
})
|
||||||
|
onSuccess(data)
|
||||||
|
},
|
||||||
|
onError: async error => {
|
||||||
|
onError(error)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEditStarterPackMutation({
|
||||||
|
onSuccess,
|
||||||
|
onError,
|
||||||
|
}: {
|
||||||
|
onSuccess: () => void
|
||||||
|
onError: (error: Error) => void
|
||||||
|
}) {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
const agent = useAgent()
|
||||||
|
|
||||||
|
return useMutation<
|
||||||
|
void,
|
||||||
|
Error,
|
||||||
|
UseCreateStarterPackMutationParams & {
|
||||||
|
currentStarterPack: AppBskyGraphDefs.StarterPackView
|
||||||
|
currentListItems: AppBskyGraphDefs.ListItemView[]
|
||||||
|
}
|
||||||
|
>({
|
||||||
|
mutationFn: async params => {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
descriptionFacets,
|
||||||
|
feeds,
|
||||||
|
profiles,
|
||||||
|
currentStarterPack,
|
||||||
|
currentListItems,
|
||||||
|
} = params
|
||||||
|
|
||||||
|
if (!AppBskyGraphStarterpack.isRecord(currentStarterPack.record)) {
|
||||||
|
throw new Error('Invalid starter pack')
|
||||||
|
}
|
||||||
|
|
||||||
|
const removedItems = currentListItems.filter(
|
||||||
|
i =>
|
||||||
|
!profiles.find(
|
||||||
|
p => p.did === i.subject.did && p.did !== agent.session!.did,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (removedItems.length !== 0) {
|
||||||
|
await agent.com.atproto.repo.applyWrites({
|
||||||
|
repo: agent.session!.did,
|
||||||
|
writes: removedItems.map(i => ({
|
||||||
|
$type: 'com.atproto.repo.applyWrites#delete',
|
||||||
|
collection: 'app.bsky.graph.listitem',
|
||||||
|
rkey: new AtUri(i.uri).rkey,
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addedProfiles = profiles.filter(
|
||||||
|
p => !currentListItems.find(i => i.subject.did === p.did),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (addedProfiles.length > 0) {
|
||||||
|
await agent.com.atproto.repo.applyWrites({
|
||||||
|
repo: agent.session!.did,
|
||||||
|
writes: addedProfiles.map(p => ({
|
||||||
|
$type: 'com.atproto.repo.applyWrites#create',
|
||||||
|
collection: 'app.bsky.graph.listitem',
|
||||||
|
value: {
|
||||||
|
$type: 'app.bsky.graph.listitem',
|
||||||
|
subject: p.did,
|
||||||
|
list: currentStarterPack.list?.uri,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const rkey = parseStarterPackUri(currentStarterPack.uri)!.rkey
|
||||||
|
await agent.com.atproto.repo.putRecord({
|
||||||
|
repo: agent.session!.did,
|
||||||
|
collection: 'app.bsky.graph.starterpack',
|
||||||
|
rkey,
|
||||||
|
record: {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
descriptionFacets,
|
||||||
|
list: currentStarterPack.list?.uri,
|
||||||
|
feeds,
|
||||||
|
createdAt: currentStarterPack.record.createdAt,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
validate: false, // TODO remove!
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onSuccess: async (_, {currentStarterPack}) => {
|
||||||
|
const parsed = parseStarterPackUri(currentStarterPack.uri)
|
||||||
|
await whenAppViewReady(agent, currentStarterPack.uri, v => {
|
||||||
|
return currentStarterPack.cid !== v?.cid
|
||||||
|
})
|
||||||
|
await invalidateActorStarterPacksQuery({
|
||||||
|
queryClient,
|
||||||
|
did: agent.session!.did,
|
||||||
|
})
|
||||||
|
if (currentStarterPack.list) {
|
||||||
|
await invalidateListMembersQuery({
|
||||||
|
queryClient,
|
||||||
|
uri: currentStarterPack.list.uri,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await invalidateStarterPack({
|
||||||
|
queryClient,
|
||||||
|
did: agent.session!.did,
|
||||||
|
rkey: parsed!.rkey,
|
||||||
})
|
})
|
||||||
onSuccess()
|
onSuccess()
|
||||||
},
|
},
|
||||||
@@ -136,11 +248,11 @@ export function useCreateStarterPackMutation({
|
|||||||
async function whenAppViewReady(
|
async function whenAppViewReady(
|
||||||
agent: BskyAgent,
|
agent: BskyAgent,
|
||||||
uri: string,
|
uri: string,
|
||||||
fn: (res?: AppBskyGraphGetList.Response) => boolean,
|
fn: (res?: AppBskyGraphDefs.StarterPackView) => boolean,
|
||||||
) {
|
) {
|
||||||
await until(
|
await until(
|
||||||
5, // 5 tries
|
10, // 5 tries
|
||||||
1e3, // 1s delay between tries
|
1e5, // 1s delay between tries
|
||||||
fn,
|
fn,
|
||||||
() =>
|
() =>
|
||||||
agent.app.bsky.graph.getStarterPack({
|
agent.app.bsky.graph.getStarterPack({
|
||||||
|
|||||||
Reference in New Issue
Block a user