Bluesky app fork with some witchin' additions 馃挮
at main 147 lines 4.1 kB view raw
1import {msg} from '@lingui/core/macro' 2import {useLingui} from '@lingui/react' 3import {Trans} from '@lingui/react/macro' 4 5import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons' 6import {atoms as a} from '#/alf' 7import {Button, ButtonText} from '#/components/Button' 8import * as Dialog from '#/components/Dialog' 9import * as Prompt from '#/components/Prompt' 10import {useAnalytics} from '#/analytics' 11import {DraftsListDialog} from './DraftsListDialog' 12import {useSaveDraftMutation} from './state/queries' 13import {type DraftSummary} from './state/schema' 14 15export function DraftsButton({ 16 onSelectDraft, 17 onSaveDraft, 18 onDiscard, 19 isEmpty, 20 isDirty, 21 isEditingDraft, 22 canSaveDraft, 23 textLength, 24}: { 25 onSelectDraft: (draft: DraftSummary) => void 26 onSaveDraft: () => Promise<{success: boolean}> 27 onDiscard: () => void 28 isEmpty: boolean 29 isDirty: boolean 30 isEditingDraft: boolean 31 canSaveDraft: boolean 32 textLength: number 33}) { 34 const {_} = useLingui() 35 const enableSquareButtons = useEnableSquareButtons() 36 const ax = useAnalytics() 37 const draftsDialogControl = Dialog.useDialogControl() 38 const savePromptControl = Prompt.usePromptControl() 39 const {isPending: isSaving} = useSaveDraftMutation() 40 41 const handlePress = () => { 42 if (isEmpty || !isDirty) { 43 // Composer is empty or has no unsaved changes, go directly to drafts list 44 draftsDialogControl.open() 45 } else { 46 // Composer has unsaved changes, ask what to do 47 savePromptControl.open() 48 } 49 } 50 51 const handleSaveAndOpen = async () => { 52 const {success} = await onSaveDraft() 53 if (success) { 54 draftsDialogControl.open() 55 } 56 } 57 58 const handleDiscardAndOpen = () => { 59 // Fire draft:discard metric before discarding 60 ax.metric('draft:discard', { 61 logContext: 'BeforeDraftsList', 62 hadContent: !isEmpty, 63 textLength, 64 }) 65 onDiscard() 66 draftsDialogControl.open() 67 } 68 69 return ( 70 <> 71 <Button 72 label={_(msg`Drafts`)} 73 variant="ghost" 74 color="primary" 75 shape="default" 76 size="small" 77 style={[ 78 enableSquareButtons ? a.rounded_sm : a.rounded_full, 79 a.py_sm, 80 a.px_md, 81 a.mx_xs, 82 ]} 83 disabled={isSaving} 84 onPress={handlePress}> 85 <ButtonText style={[a.text_md]}> 86 <Trans>Drafts</Trans> 87 </ButtonText> 88 </Button> 89 90 <DraftsListDialog 91 control={draftsDialogControl} 92 onSelectDraft={onSelectDraft} 93 /> 94 95 <Prompt.Outer control={savePromptControl}> 96 <Prompt.Content> 97 <Prompt.TitleText> 98 {canSaveDraft ? ( 99 isEditingDraft ? ( 100 <Trans>Save changes?</Trans> 101 ) : ( 102 <Trans>Save draft?</Trans> 103 ) 104 ) : ( 105 <Trans>Discard draft?</Trans> 106 )} 107 </Prompt.TitleText> 108 </Prompt.Content> 109 <Prompt.DescriptionText> 110 {canSaveDraft ? ( 111 isEditingDraft ? ( 112 <Trans> 113 You have unsaved changes. Would you like to save them before 114 viewing your drafts? 115 </Trans> 116 ) : ( 117 <Trans> 118 Would you like to save this as a draft before viewing your 119 drafts? 120 </Trans> 121 ) 122 ) : ( 123 <Trans> 124 You can only save drafts up to 1000 characters. Would you like to 125 discard this post before viewing your drafts? 126 </Trans> 127 )} 128 </Prompt.DescriptionText> 129 <Prompt.Actions> 130 {canSaveDraft && ( 131 <Prompt.Action 132 cta={isEditingDraft ? _(msg`Save changes`) : _(msg`Save draft`)} 133 onPress={handleSaveAndOpen} 134 color="primary" 135 /> 136 )} 137 <Prompt.Action 138 cta={_(msg`Discard`)} 139 onPress={handleDiscardAndOpen} 140 color="negative_subtle" 141 /> 142 <Prompt.Cancel cta={_(msg`Keep editing`)} /> 143 </Prompt.Actions> 144 </Prompt.Outer> 145 </> 146 ) 147}