infinite query, rename file to queries
This commit is contained in:
@@ -130,12 +130,8 @@ import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_ANDROID, IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet'
|
||||
import {
|
||||
draftToComposerPosts,
|
||||
threadgateToUISettings,
|
||||
useLoadDraft,
|
||||
useSaveDraft,
|
||||
} from './drafts/state/hooks'
|
||||
import {draftToComposerPosts} from './drafts/state/api'
|
||||
import {useLoadDraft, useSaveDraftMutation} from './drafts/state/queries'
|
||||
import {type DraftSummary} from './drafts/state/schema'
|
||||
import {PostLanguageSelect} from './select-language/PostLanguageSelect'
|
||||
import {
|
||||
@@ -195,7 +191,8 @@ export const ComposePost = ({
|
||||
const setLangPrefs = useLanguagePrefsApi()
|
||||
const textInput = useRef<TextInputRef>(null)
|
||||
const discardPromptControl = Prompt.usePromptControl()
|
||||
const {mutateAsync: saveDraft, isPending: _isSavingDraft} = useSaveDraft()
|
||||
const {mutateAsync: saveDraft, isPending: _isSavingDraft} =
|
||||
useSaveDraftMutation()
|
||||
const loadDraft = useLoadDraft()
|
||||
const {closeAllDialogs} = useDialogStateControlContext()
|
||||
const {closeAllModals} = useModalControls()
|
||||
@@ -338,14 +335,14 @@ export const ComposePost = ({
|
||||
|
||||
// Convert server draft to composer posts
|
||||
const posts = draftToComposerPosts(draft, loadedMedia)
|
||||
const threadgate = threadgateToUISettings(draft.threadgateAllow)
|
||||
|
||||
// Dispatch restore action (this also sets draftId in state)
|
||||
composerDispatch({
|
||||
type: 'restore_from_draft',
|
||||
draftId: draftSummary.id,
|
||||
posts,
|
||||
threadgate,
|
||||
threadgateAllow: draft.threadgateAllow,
|
||||
postgateEmbeddingRules: draft.postgateEmbeddingRules,
|
||||
loadedMedia,
|
||||
})
|
||||
},
|
||||
@@ -402,8 +399,11 @@ export const ComposePost = ({
|
||||
|
||||
// Clear the composer (discard current content)
|
||||
const handleClearComposer = React.useCallback(() => {
|
||||
composerDispatch({type: 'clear'})
|
||||
}, [composerDispatch])
|
||||
composerDispatch({
|
||||
type: 'clear',
|
||||
initInteractionSettings: preferences?.postInteractionSettings,
|
||||
})
|
||||
}, [composerDispatch, preferences?.postInteractionSettings])
|
||||
|
||||
const insets = useSafeAreaInsets()
|
||||
const viewStyles = useMemo(
|
||||
|
||||
@@ -6,7 +6,7 @@ import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import {DraftsListDialog} from './DraftsListDialog'
|
||||
import {useSaveDraft} from './state/hooks'
|
||||
import {useSaveDraftMutation} from './state/queries'
|
||||
import {type DraftSummary} from './state/schema'
|
||||
|
||||
export function DraftsButton({
|
||||
@@ -27,7 +27,7 @@ export function DraftsButton({
|
||||
const {_} = useLingui()
|
||||
const draftsDialogControl = Dialog.useDialogControl()
|
||||
const savePromptControl = Prompt.usePromptControl()
|
||||
const {isPending: isSaving} = useSaveDraft()
|
||||
const {isPending: isSaving} = useSaveDraftMutation()
|
||||
|
||||
const handlePress = () => {
|
||||
if (isEmpty || !isDirty) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as Dialog from '#/components/Dialog'
|
||||
import {PageX_Stroke2_Corner0_Rounded_Large as PageXIcon} from '#/components/icons/PageX'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {DraftItem} from './DraftItem'
|
||||
import {useDeleteDraft, useDrafts} from './state/hooks'
|
||||
import {useDeleteDraftMutation, useDraftsQuery} from './state/queries'
|
||||
import {type DraftSummary} from './state/schema'
|
||||
|
||||
export function DraftsListDialog({
|
||||
@@ -23,8 +23,13 @@ export function DraftsListDialog({
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
const {data: drafts, isLoading} = useDrafts()
|
||||
const {mutate: deleteDraft} = useDeleteDraft()
|
||||
const {data, isLoading} = useDraftsQuery()
|
||||
const {mutate: deleteDraft} = useDeleteDraftMutation()
|
||||
|
||||
const drafts = useMemo(
|
||||
() => data?.pages.flatMap(page => page.drafts) ?? [],
|
||||
[data],
|
||||
)
|
||||
|
||||
const handleSelectDraft = useCallback(
|
||||
(summary: DraftSummary) => {
|
||||
@@ -105,7 +110,7 @@ export function DraftsListDialog({
|
||||
<Dialog.Outer control={control}>
|
||||
{isNative && header}
|
||||
<Dialog.InnerFlatList
|
||||
data={drafts ?? []}
|
||||
data={drafts}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={item => item.id}
|
||||
ListHeaderComponent={web(header)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Type converters for Draft API - convert between ComposerState and server Draft types.
|
||||
*/
|
||||
import {type AppBskyDraftDefs} from '@atproto/api'
|
||||
import {type AppBskyDraftDefs, RichText} from '@atproto/api'
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
|
||||
import {type ComposerImage} from '#/state/gallery'
|
||||
@@ -341,11 +341,9 @@ export function draftToComposerPosts(
|
||||
draft: AppBskyDraftDefs.Draft,
|
||||
loadedMedia: Map<string, string>,
|
||||
): PostDraft[] {
|
||||
// Import these dynamically to avoid circular dependencies
|
||||
const {RichText} = require('@atproto/api')
|
||||
|
||||
return draft.posts.map((post, index) => {
|
||||
const richtext = new RichText({text: post.text || ''})
|
||||
richtext.detectFacetsWithoutResolution()
|
||||
|
||||
const embed: EmbedDraft = {
|
||||
quote: undefined,
|
||||
@@ -434,7 +432,7 @@ export function draftToComposerPosts(
|
||||
// Parse labels
|
||||
const labels: string[] = []
|
||||
if (post.labels && 'values' in post.labels) {
|
||||
for (const val of (post.labels as {values: {val: string}[]}).values) {
|
||||
for (const val of post.labels.values) {
|
||||
labels.push(val.val)
|
||||
}
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,18 +1,16 @@
|
||||
import {useCallback} from 'react'
|
||||
import {AppBskyDraftCreateDraft, type AppBskyDraftDefs} from '@atproto/api'
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
import {
|
||||
useInfiniteQuery,
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {type ComposerState} from '#/view/com/composer/state/composer'
|
||||
import {
|
||||
composerStateToDraft,
|
||||
draftToComposerPosts,
|
||||
draftViewToSummary,
|
||||
threadgateToUISettings,
|
||||
} from './api'
|
||||
import {composerStateToDraft, draftViewToSummary} from './api'
|
||||
import {logger} from './logger'
|
||||
import {type DraftSummary} from './schema'
|
||||
import * as storage from './storage'
|
||||
|
||||
const DRAFTS_QUERY_KEY = ['drafts']
|
||||
@@ -20,19 +18,24 @@ const DRAFTS_QUERY_KEY = ['drafts']
|
||||
/**
|
||||
* Hook to list all drafts for the current account
|
||||
*/
|
||||
export function useDrafts() {
|
||||
export function useDraftsQuery() {
|
||||
const agent = useAgent()
|
||||
|
||||
return useQuery<DraftSummary[]>({
|
||||
return useInfiniteQuery({
|
||||
queryKey: DRAFTS_QUERY_KEY,
|
||||
queryFn: async () => {
|
||||
queryFn: async ({pageParam}) => {
|
||||
// Ensure media cache is populated before checking which media exists
|
||||
await storage.ensureMediaCachePopulated()
|
||||
const res = await agent.app.bsky.draft.getDrafts({})
|
||||
return res.data.drafts.map(view =>
|
||||
draftViewToSummary(view, path => storage.mediaExists(path)),
|
||||
)
|
||||
const res = await agent.app.bsky.draft.getDrafts({cursor: pageParam})
|
||||
return {
|
||||
cursor: res.data.cursor,
|
||||
drafts: res.data.drafts.map(view =>
|
||||
draftViewToSummary(view, path => storage.mediaExists(path)),
|
||||
),
|
||||
}
|
||||
},
|
||||
initialPageParam: undefined as string | undefined,
|
||||
getNextPageParam: page => page.cursor,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -99,7 +102,7 @@ export function useLoadDraft() {
|
||||
/**
|
||||
* Hook to save a draft
|
||||
*/
|
||||
export function useSaveDraft() {
|
||||
export function useSaveDraftMutation() {
|
||||
const agent = useAgent()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
@@ -157,7 +160,7 @@ export function useSaveDraft() {
|
||||
/**
|
||||
* Hook to delete a draft
|
||||
*/
|
||||
export function useDeleteDraft() {
|
||||
export function useDeleteDraftMutation() {
|
||||
const agent = useAgent()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
@@ -191,6 +194,3 @@ export function useDeleteDraft() {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Re-export utilities for use in composer
|
||||
export {draftToComposerPosts, threadgateToUISettings}
|
||||
Reference in New Issue
Block a user