diff options
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/view/com/composer/Composer.tsx | 10 | ||||
-rw-r--r-- | src/view/com/composer/text-input/TextInput.web.tsx | 31 | ||||
-rw-r--r-- | yarn.lock | 5 |
4 files changed, 32 insertions, 15 deletions
diff --git a/package.json b/package.json index 02492aceb..c897ead5f 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "base64-js": "^1.5.1", "bcp-47-match": "^2.0.3", "email-validator": "^2.0.4", + "eventemitter3": "^5.0.1", "expo": "~48.0.18", "expo-application": "~5.1.1", "expo-build-properties": "~0.5.1", diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index fe9cc834f..ecfef3ecd 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -151,7 +151,7 @@ export const ComposePost = observer(function ComposePost({ [gallery, track], ) - const onPressPublish = async (rt: RichText) => { + const onPressPublish = async () => { if (isProcessing || graphemeLength > MAX_GRAPHEME_LENGTH) { return } @@ -161,7 +161,7 @@ export const ComposePost = observer(function ComposePost({ setError('') - if (rt.text.trim().length === 0 && gallery.isEmpty) { + if (richtext.text.trim().length === 0 && gallery.isEmpty) { setError('Did you want to say anything?') return } @@ -170,7 +170,7 @@ export const ComposePost = observer(function ComposePost({ try { await apilib.post(store, { - rawText: rt.text, + rawText: richtext.text, replyTo: replyTo?.uri, images: gallery.images, quote, @@ -245,9 +245,7 @@ export const ComposePost = observer(function ComposePost({ ) : canPost ? ( <TouchableOpacity testID="composerPublishBtn" - onPress={() => { - onPressPublish(richtext) - }} + onPress={onPressPublish} accessibilityRole="button" accessibilityLabel={replyTo ? 'Publish reply' : 'Publish post'} accessibilityHint={ diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx index 152bb50ea..f64880e15 100644 --- a/src/view/com/composer/text-input/TextInput.web.tsx +++ b/src/view/com/composer/text-input/TextInput.web.tsx @@ -1,6 +1,7 @@ import React from 'react' import {StyleSheet, View} from 'react-native' import {RichText} from '@atproto/api' +import EventEmitter from 'eventemitter3' import {useEditor, EditorContent, JSONContent} from '@tiptap/react' import {Document} from '@tiptap/extension-document' import History from '@tiptap/extension-history' @@ -53,6 +54,22 @@ export const TextInput = React.forwardRef( 'ProseMirror-dark', ) + // we use a memoized emitter to propagate events out of tiptap + // without triggering re-runs of the useEditor hook + const emitter = React.useMemo(() => new EventEmitter(), []) + React.useEffect(() => { + emitter.addListener('publish', onPressPublish) + return () => { + emitter.removeListener('publish', onPressPublish) + } + }, [emitter, onPressPublish]) + React.useEffect(() => { + emitter.addListener('photo-pasted', onPhotoPasted) + return () => { + emitter.removeListener('photo-pasted', onPhotoPasted) + } + }, [emitter, onPhotoPasted]) + const editor = useEditor( { extensions: [ @@ -87,17 +104,13 @@ export const TextInput = React.forwardRef( return } - getImageFromUri(items, onPhotoPasted) + getImageFromUri(items, (uri: string) => { + emitter.emit('photo-pasted', uri) + }) }, handleKeyDown: (_, event) => { if ((event.metaKey || event.ctrlKey) && 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 - }) - return true + emitter.emit('publish') } }, }, @@ -118,7 +131,7 @@ export const TextInput = React.forwardRef( } }, }, - [modeClass], + [modeClass, emitter], ) React.useImperativeHandle(ref, () => ({ diff --git a/yarn.lock b/yarn.lock index 8295df224..f49b9a12d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10150,6 +10150,11 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + events@3.3.0, events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" |