Use InnerFlatList and Dialog.Header for drafts dialog
- Switch from ScrollableInner to InnerFlatList - Add Dialog.Header with back button in left slot - Use sticky header Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import {useCallback} from 'react'
|
import {useCallback, useMemo} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} 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'
|
||||||
@@ -11,7 +11,9 @@ import {
|
|||||||
useLoadDraft,
|
useLoadDraft,
|
||||||
} from '#/state/drafts'
|
} from '#/state/drafts'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {Button, ButtonIcon} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
|
import {ArrowLeft_Stroke2_Corner0_Rounded as ArrowLeftIcon} from '#/components/icons/Arrow'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {DraftItem} from './DraftItem'
|
import {DraftItem} from './DraftItem'
|
||||||
@@ -48,42 +50,76 @@ export function DraftsListDialog({
|
|||||||
[deleteDraft],
|
[deleteDraft],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const backButton = useCallback(
|
||||||
|
() => (
|
||||||
|
<Button
|
||||||
|
label={_(msg`Back`)}
|
||||||
|
onPress={() => control.close()}
|
||||||
|
size="small"
|
||||||
|
color="primary"
|
||||||
|
variant="ghost"
|
||||||
|
shape="round">
|
||||||
|
<ButtonIcon icon={ArrowLeftIcon} size="md" />
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
[control, _],
|
||||||
|
)
|
||||||
|
|
||||||
|
const listHeader = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<Dialog.Header renderLeft={backButton}>
|
||||||
|
<Dialog.HeaderText>
|
||||||
|
<Trans>Drafts</Trans>
|
||||||
|
</Dialog.HeaderText>
|
||||||
|
</Dialog.Header>
|
||||||
|
)
|
||||||
|
}, [backButton])
|
||||||
|
|
||||||
|
const renderItem = useCallback(
|
||||||
|
({item}: {item: DraftSummary}) => {
|
||||||
|
return (
|
||||||
|
<DraftItem
|
||||||
|
draft={item}
|
||||||
|
onSelect={handleSelectDraft}
|
||||||
|
onDelete={handleDeleteDraft}
|
||||||
|
isDeleting={isDeleting}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
[handleSelectDraft, handleDeleteDraft, isDeleting],
|
||||||
|
)
|
||||||
|
|
||||||
|
const emptyComponent = useMemo(() => {
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<View style={[a.py_xl, a.align_center]}>
|
||||||
|
<Loader size="lg" />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View style={[a.py_xl, a.align_center]}>
|
||||||
|
<Text style={[t.atoms.text_contrast_medium]}>
|
||||||
|
<Trans>No drafts saved</Trans>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}, [isLoading, t.atoms.text_contrast_medium])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
||||||
<Dialog.Handle />
|
<Dialog.Handle />
|
||||||
<Dialog.ScrollableInner label={_(msg`Your Drafts`)}>
|
<Dialog.InnerFlatList
|
||||||
<View style={[a.gap_md]}>
|
data={drafts ?? []}
|
||||||
<Text style={[a.text_2xl, a.font_semi_bold]}>
|
renderItem={renderItem}
|
||||||
<Trans>Your Drafts</Trans>
|
keyExtractor={item => item.id}
|
||||||
</Text>
|
ListHeaderComponent={listHeader}
|
||||||
|
ListEmptyComponent={emptyComponent}
|
||||||
{isLoading ? (
|
stickyHeaderIndices={[0]}
|
||||||
<View style={[a.py_xl, a.align_center]}>
|
contentContainerStyle={[a.pb_lg]}
|
||||||
<Loader size="lg" />
|
ItemSeparatorComponent={() => <View style={[{height: 8}]} />}
|
||||||
</View>
|
style={[a.px_lg]}
|
||||||
) : drafts && drafts.length > 0 ? (
|
/>
|
||||||
<View style={[a.gap_sm]}>
|
|
||||||
{drafts.map(draft => (
|
|
||||||
<DraftItem
|
|
||||||
key={draft.id}
|
|
||||||
draft={draft}
|
|
||||||
onSelect={handleSelectDraft}
|
|
||||||
onDelete={handleDeleteDraft}
|
|
||||||
isDeleting={isDeleting}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
) : (
|
|
||||||
<View style={[a.py_xl, a.align_center]}>
|
|
||||||
<Text style={[t.atoms.text_contrast_medium]}>
|
|
||||||
<Trans>No drafts saved</Trans>
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Dialog.Close />
|
|
||||||
</Dialog.ScrollableInner>
|
|
||||||
</Dialog.Outer>
|
</Dialog.Outer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user