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