Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a876aae44ea07494ebea9727350aa060b81f317b 147 lines 4.2 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]} maxFontSizeMultiplier={2}> 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}