diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-08-17 13:39:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-17 13:39:59 -0700 |
commit | 4a59178cd2d7028e99a977e0ed10193d135e30dd (patch) | |
tree | ad02636ac1987214843a737df94b48d240427819 /src | |
parent | 5e63d3164b58552f81b597eff83cba991bea958e (diff) | |
download | voidsky-4a59178cd2d7028e99a977e0ed10193d135e30dd.tar.zst |
The tiptap useEditor() hook creates an awkward challenge for passing event handlers into its plugins and native events. By introducing a memoized editor, we should be able to shuttle events out of tiptap without retriggering the useEditor hook. The emitter can then change its registered handlers with each state update.
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/composer/Composer.tsx | 10 | ||||
-rw-r--r-- | src/view/com/composer/text-input/TextInput.web.tsx | 31 |
2 files changed, 26 insertions, 15 deletions
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, () => ({ |