infinite query, rename file to queries

This commit is contained in:
Samuel Newman
2026-01-16 16:33:12 +02:00
parent 2f731146f8
commit 92824b4b3a
5 changed files with 45 additions and 42 deletions
+11 -11
View File
@@ -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)}
+3 -5
View File
@@ -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)
}
}
@@ -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}