From 31df05825ca21df7b0108e200681d6c2ab83fe33 Mon Sep 17 00:00:00 2001 From: renahlee Date: Wed, 19 Apr 2023 10:51:33 -0700 Subject: [PATCH] Support CMD + Enter to publish post --- src/view/com/composer/Composer.tsx | 123 +++++++++--------- .../com/composer/text-input/TextInput.tsx | 1 + .../com/composer/text-input/TextInput.web.tsx | 12 ++ 3 files changed, 77 insertions(+), 59 deletions(-) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index f77005b5..08f977f7 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -123,65 +123,67 @@ export const ComposePost = observer(function ComposePost({ [gallery, track], ) - const onPressPublish = useCallback(async () => { - if (isProcessing || richtext.graphemeLength > MAX_GRAPHEME_LENGTH) { - return - } - - setError('') - - if (richtext.text.trim().length === 0 && gallery.isEmpty) { - setError('Did you want to say anything?') - return false - } - - setIsProcessing(true) - - try { - await apilib.post(store, { - rawText: richtext.text, - replyTo: replyTo?.uri, - images: gallery.paths, - quote: quote, - extLink: extLink, - onStateChange: setProcessingState, - knownHandles: autocompleteView.knownHandles, - }) - track('Create Post', { - imageCount: gallery.size, - }) - } catch (e: any) { - if (extLink) { - setExtLink({ - ...extLink, - isLoading: true, - localThumb: undefined, - } as apilib.ExternalEmbedDraft) + const onPressPublish = useCallback( + async rt => { + if (isProcessing || rt.graphemeLength_ > MAX_GRAPHEME_LENGTH) { + return } - setError(cleanError(e.message)) - setIsProcessing(false) - return - } - store.me.mainFeed.checkForLatest({autoPrepend: true}) - onPost?.() - hackfixOnClose() - Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`) - }, [ - isProcessing, - richtext, - setError, - setIsProcessing, - replyTo, - autocompleteView.knownHandles, - extLink, - hackfixOnClose, - onPost, - quote, - setExtLink, - store, - track, - gallery, - ]) + + setError('') + + if (rt.text.trim().length === 0 && gallery.isEmpty) { + setError('Did you want to say anything?') + return false + } + + setIsProcessing(true) + + try { + await apilib.post(store, { + rawText: rt.text, + replyTo: replyTo?.uri, + images: gallery.paths, + quote: quote, + extLink: extLink, + onStateChange: setProcessingState, + knownHandles: autocompleteView.knownHandles, + }) + track('Create Post', { + imageCount: gallery.size, + }) + } catch (e: any) { + if (extLink) { + setExtLink({ + ...extLink, + isLoading: true, + localThumb: undefined, + } as apilib.ExternalEmbedDraft) + } + setError(cleanError(e.message)) + setIsProcessing(false) + return + } + store.me.mainFeed.checkForLatest({autoPrepend: true}) + onPost?.() + hackfixOnClose() + Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`) + }, + [ + isProcessing, + setError, + setIsProcessing, + replyTo, + autocompleteView.knownHandles, + extLink, + hackfixOnClose, + onPost, + quote, + setExtLink, + store, + track, + gallery, + ], + ) const canPost = graphemeLength <= MAX_GRAPHEME_LENGTH @@ -218,7 +220,9 @@ export const ComposePost = observer(function ComposePost({ ) : canPost ? ( + onPress={() => { + onPressPublish(richtext) + }}> diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx index 9c111bd3..10ac52b5 100644 --- a/src/view/com/composer/text-input/TextInput.tsx +++ b/src/view/com/composer/text-input/TextInput.tsx @@ -34,6 +34,7 @@ interface TextInputProps { autocompleteView: UserAutocompleteModel setRichText: (v: RichText) => void onPhotoPasted: (uri: string) => void + onPressPublish: (richtext: RichText) => Promise onSuggestedLinksChanged: (uris: Set) => void onError: (err: string) => void } diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx index e75da179..f21d4ac1 100644 --- a/src/view/com/composer/text-input/TextInput.web.tsx +++ b/src/view/com/composer/text-input/TextInput.web.tsx @@ -26,6 +26,7 @@ interface TextInputProps { autocompleteView: UserAutocompleteModel setRichText: (v: RichText) => void onPhotoPasted: (uri: string) => void + onPressPublish: (richtext: RichText) => Promise onSuggestedLinksChanged: (uris: Set) => void onError: (err: string) => void } @@ -39,6 +40,7 @@ export const TextInput = React.forwardRef( autocompleteView, setRichText, onPhotoPasted, + onPressPublish, onSuggestedLinksChanged, }: // onError, TODO TextInputProps, @@ -82,6 +84,16 @@ export const TextInput = React.forwardRef( getImageFromUri(items, onPhotoPasted) }, + handleKeyDown: (_, event) => { + if (event.metaKey && event.code === 'Enter') { + // Workaround relying on previous state from `setRichText` to + // get the updated text content during editor initialization + setRichText((state: RichText) => { + onPressPublish(state) + return state + }) + } + }, }, content: richtext.text.toString(), autofocus: true,