From 570b76a71d2f3a3d8d8d6bbefa7aedcf86ecffad Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Thu, 19 Jan 2023 17:36:49 -0600 Subject: Add the ability to paste images into the composer (#56) --- src/view/com/composer/ComposePost.tsx | 53 +++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 11 deletions(-) (limited to 'src/view/com/composer/ComposePost.tsx') diff --git a/src/view/com/composer/ComposePost.tsx b/src/view/com/composer/ComposePost.tsx index a8def6405..3614267b1 100644 --- a/src/view/com/composer/ComposePost.tsx +++ b/src/view/com/composer/ComposePost.tsx @@ -7,11 +7,14 @@ import { SafeAreaView, ScrollView, StyleSheet, - TextInput, TouchableOpacity, TouchableWithoutFeedback, View, } from 'react-native' +import PasteInput, { + PastedFile, + PasteInputRef, +} from '@mattermost/react-native-paste-input' import LinearGradient from 'react-native-linear-gradient' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {UserAutocompleteViewModel} from '../../../state/models/user-autocomplete-view' @@ -33,7 +36,7 @@ import {detectLinkables, extractEntities} from '../../../lib/strings' import {getLinkMeta} from '../../../lib/link-meta' import {downloadAndResize} from '../../../lib/images' import {UserLocalPhotosModel} from '../../../state/models/user-local-photos' -import {PhotoCarouselPicker} from './PhotoCarouselPicker' +import {PhotoCarouselPicker, cropPhoto} from './PhotoCarouselPicker' import {SelectedPhoto} from './SelectedPhoto' import {usePalette} from '../../lib/hooks/usePalette' @@ -54,7 +57,7 @@ export const ComposePost = observer(function ComposePost({ }) { const pal = usePalette('default') const store = useStores() - const textInput = useRef(null) + const textInput = useRef(null) const [isProcessing, setIsProcessing] = useState(false) const [processingState, setProcessingState] = useState('') const [error, setError] = useState('') @@ -78,6 +81,16 @@ export const ComposePost = observer(function ComposePost({ [store], ) + // HACK + // there's a bug with @mattermost/react-native-paste-input where if the input + // is focused during unmount, an exception will throw (seems that a blur method isnt implemented) + // manually blurring before closing gets around that + // -prf + const hackfixOnClose = () => { + textInput.current?.blur() + onClose() + } + // initial setup useEffect(() => { autocompleteView.setup() @@ -134,7 +147,8 @@ export const ComposePost = observer(function ComposePost({ isLoading: false, // done }) } - }, [extLink]) + return cleanup + }, [store, extLink]) useEffect(() => { // HACK @@ -196,9 +210,21 @@ export const ComposePost = observer(function ComposePost({ } } } - const onPressCancel = () => { - onClose() + const onPaste = async (err: string | undefined, files: PastedFile[]) => { + if (err) { + return setError(err) + } + if (selectedPhotos.length >= 4) { + return + } + const imgFile = files.find(file => /\.(jpe?g|png)$/.test(file.fileName)) + if (!imgFile) { + return + } + const finalImgPath = await cropPhoto(imgFile.uri) + onSelectPhotos([...selectedPhotos, finalImgPath]) } + const onPressCancel = () => hackfixOnClose() const onPressPublish = async () => { if (isProcessing) { return @@ -229,7 +255,7 @@ export const ComposePost = observer(function ComposePost({ } store.me.mainFeed.loadLatest() onPost?.() - onClose() + hackfixOnClose() Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`) } const onSelectAutocompleteItem = (item: string) => { @@ -254,7 +280,11 @@ export const ComposePost = observer(function ComposePost({ let i = 0 return detectLinkables(text).map(v => { if (typeof v === 'string') { - return v + return ( + + {v} + + ) } else { return ( @@ -263,7 +293,7 @@ export const ComposePost = observer(function ComposePost({ ) } }) - }, [text]) + }, [text, pal.link]) return ( - onChangeText(text)} + onPaste={onPaste} placeholder={selectTextInputPlaceholder} placeholderTextColor={pal.colors.textLight} style={[ @@ -368,7 +399,7 @@ export const ComposePost = observer(function ComposePost({ styles.textInputFormatting, ]}> {textDecorated} - +