this repo has no description
1import {msg} from '@lingui/core/macro'
2import {useLingui} from '@lingui/react'
3import {Trans} from '@lingui/react/macro'
4
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 ax = useAnalytics()
35 const draftsDialogControl = Dialog.useDialogControl()
36 const savePromptControl = Prompt.usePromptControl()
37 const {isPending: isSaving} = useSaveDraftMutation()
38
39 const handlePress = () => {
40 if (isEmpty || !isDirty) {
41 // Composer is empty or has no unsaved changes, go directly to drafts list
42 draftsDialogControl.open()
43 } else {
44 // Composer has unsaved changes, ask what to do
45 savePromptControl.open()
46 }
47 }
48
49 const handleSaveAndOpen = async () => {
50 const {success} = await onSaveDraft()
51 if (success) {
52 draftsDialogControl.open()
53 }
54 }
55
56 const handleDiscardAndOpen = () => {
57 // Fire draft:discard metric before discarding
58 ax.metric('draft:discard', {
59 logContext: 'BeforeDraftsList',
60 hadContent: !isEmpty,
61 textLength,
62 })
63 onDiscard()
64 draftsDialogControl.open()
65 }
66
67 return (
68 <>
69 <Button
70 label={_(msg`Drafts`)}
71 variant="ghost"
72 color="primary"
73 shape="default"
74 size="small"
75 style={[a.py_sm, a.px_md, a.mx_xs]}
76 disabled={isSaving}
77 onPress={handlePress}>
78 <ButtonText style={[a.text_md]} maxFontSizeMultiplier={2}>
79 <Trans>Drafts</Trans>
80 </ButtonText>
81 </Button>
82
83 <DraftsListDialog
84 control={draftsDialogControl}
85 onSelectDraft={onSelectDraft}
86 />
87
88 <Prompt.Outer control={savePromptControl}>
89 <Prompt.Content>
90 <Prompt.TitleText>
91 {canSaveDraft ? (
92 isEditingDraft ? (
93 <Trans>Save changes?</Trans>
94 ) : (
95 <Trans>Save draft?</Trans>
96 )
97 ) : (
98 <Trans>Discard draft?</Trans>
99 )}
100 </Prompt.TitleText>
101 </Prompt.Content>
102 <Prompt.DescriptionText>
103 {canSaveDraft ? (
104 isEditingDraft ? (
105 <Trans>
106 You have unsaved changes. Would you like to save them before
107 viewing your drafts?
108 </Trans>
109 ) : (
110 <Trans>
111 Would you like to save this as a draft before viewing your
112 drafts?
113 </Trans>
114 )
115 ) : (
116 <Trans>
117 You can only save drafts up to 1000 characters. Would you like to
118 discard this post before viewing your drafts?
119 </Trans>
120 )}
121 </Prompt.DescriptionText>
122 <Prompt.Actions>
123 {canSaveDraft && (
124 <Prompt.Action
125 cta={isEditingDraft ? _(msg`Save changes`) : _(msg`Save draft`)}
126 onPress={handleSaveAndOpen}
127 color="primary"
128 />
129 )}
130 <Prompt.Action
131 cta={_(msg`Discard`)}
132 onPress={handleDiscardAndOpen}
133 color="negative_subtle"
134 />
135 <Prompt.Cancel cta={_(msg`Keep editing`)} />
136 </Prompt.Actions>
137 </Prompt.Outer>
138 </>
139 )
140}