diff options
Diffstat (limited to 'src/view/com/composer/ComposePost.tsx')
-rw-r--r-- | src/view/com/composer/ComposePost.tsx | 181 |
1 files changed, 178 insertions, 3 deletions
diff --git a/src/view/com/composer/ComposePost.tsx b/src/view/com/composer/ComposePost.tsx index bb175f166..10305adb6 100644 --- a/src/view/com/composer/ComposePost.tsx +++ b/src/view/com/composer/ComposePost.tsx @@ -9,10 +9,13 @@ import { TextInput, TouchableOpacity, View, + ScrollView, + Image, } from 'react-native' import LinearGradient from 'react-native-linear-gradient' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {UserAutocompleteViewModel} from '../../../state/models/user-autocomplete-view' +import {UserLocalPhotosModel} from '../../../state/models/user-local-photos' import {Autocomplete} from './Autocomplete' import Toast from '../util/Toast' import ProgressCircle from '../util/ProgressCircle' @@ -22,6 +25,7 @@ import * as apilib from '../../../state/lib/api' import {ComposerOpts} from '../../../state/models/shell-ui' import {s, colors, gradients} from '../../lib/styles' import {detectLinkables} from '../../../lib/strings' +import {openPicker, openCamera} from 'react-native-image-crop-picker' const MAX_TEXT_LENGTH = 256 const WARNING_TEXT_LENGTH = 200 @@ -40,15 +44,24 @@ export const ComposePost = observer(function ComposePost({ const [isProcessing, setIsProcessing] = useState(false) const [error, setError] = useState('') const [text, setText] = useState('') + const [photoUris, setPhotoUris] = useState<string[]>([]) const autocompleteView = useMemo<UserAutocompleteViewModel>( () => new UserAutocompleteViewModel(store), [], ) + const localPhotos = useMemo<UserLocalPhotosModel>( + () => new UserLocalPhotosModel(store), + [], + ) useEffect(() => { autocompleteView.setup() }) + useEffect(() => { + localPhotos.setup() + }, []) + const onChangeText = (newText: string) => { setText(newText) @@ -183,12 +196,109 @@ export const ComposePost = observer(function ComposePost({ multiline scrollEnabled onChangeText={(text: string) => onChangeText(text)} - placeholder={replyTo ? 'Write your reply' : "What's up?"} + placeholder={ + replyTo + ? 'Write your reply' + : photoUris.length === 0 + ? "What's up?" + : 'Add a comment...' + } style={styles.textInput}> {textDecorated} </TextInput> - <View - style={[s.flexRow, {alignItems: 'center'}, s.pt10, s.pb10, s.pr5]}> + {photoUris.length !== 0 && ( + <View style={styles.selectedImageContainer}> + {photoUris.length !== 0 && + photoUris.map(item => ( + <View + style={[ + styles.selectedImage, + photoUris.length === 1 + ? styles.selectedImage250 + : photoUris.length === 2 + ? styles.selectedImage175 + : styles.selectedImage85, + ]}> + <TouchableOpacity + onPress={() => { + setPhotoUris( + photoUris.filter(filterItem => filterItem !== item), + ) + }} + style={styles.removePhotoButton}> + <FontAwesomeIcon + icon="xmark" + size={16} + style={{color: colors.white}} + /> + </TouchableOpacity> + + <Image + style={[ + styles.selectedImage, + photoUris.length === 1 + ? styles.selectedImage250 + : photoUris.length === 2 + ? styles.selectedImage175 + : styles.selectedImage85, + ]} + source={{uri: item}} + /> + </View> + ))} + </View> + )} + {localPhotos.photos != null && text === '' && photoUris.length === 0 && ( + <ScrollView + horizontal + style={styles.photosContainer} + showsHorizontalScrollIndicator={false}> + <TouchableOpacity + style={[styles.galleryButton, styles.photo]} + onPress={() => { + openCamera({multiple: true, maxFiles: 4}).then() + }}> + <FontAwesomeIcon + icon="camera" + size={24} + style={{color: colors.blue3}} + /> + </TouchableOpacity> + {localPhotos.photos.map(item => ( + <TouchableOpacity + style={styles.photoButton} + onPress={() => { + setPhotoUris([item.node.image.uri, ...photoUris]) + }}> + <Image + style={styles.photo} + source={{uri: item.node.image.uri}} + /> + </TouchableOpacity> + ))} + <TouchableOpacity + style={[styles.galleryButton, styles.photo]} + onPress={() => { + openPicker({multiple: true, maxFiles: 4}).then(items => { + setPhotoUris([ + ...items.reduce( + (accum, cur) => accum.concat(cur.sourceURL!), + [] as string[], + ), + ...photoUris, + ]) + }) + }}> + <FontAwesomeIcon + icon="image" + style={{color: colors.blue3}} + size={24} + /> + </TouchableOpacity> + </ScrollView> + )} + <View style={styles.separator} /> + <View style={[s.flexRow, s.pt10, s.pb10, s.pr5, styles.contentCenter]}> <View style={s.flex1} /> <Text style={[s.mr10, {color: progressColor}]}> {MAX_TEXT_LENGTH - text.length} @@ -275,4 +385,69 @@ const styles = StyleSheet.create({ marginTop: 5, marginBottom: 10, }, + contentCenter: {alignItems: 'center'}, + selectedImageContainer: { + flex: 10, + flexDirection: 'row', + }, + selectedImage: { + borderRadius: 8, + margin: 2, + }, + selectedImage250: { + width: 250, + height: 250, + }, + selectedImage175: { + width: 175, + height: 175, + }, + selectedImage85: { + width: 85, + height: 85, + }, + photosContainer: { + width: '100%', + maxHeight: 96, + padding: 8, + overflow: 'hidden', + }, + removePhotoButton: { + position: 'absolute', + top: 8, + right: 8, + width: 24, + height: 24, + borderRadius: 12, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: colors.black, + zIndex: 1, + }, + galleryButton: { + borderWidth: 1, + borderColor: colors.gray3, + alignItems: 'center', + justifyContent: 'center', + }, + photoButton: { + width: 75, + height: 75, + marginRight: 8, + borderWidth: 1, + borderRadius: 16, + borderColor: colors.gray3, + }, + photo: { + width: 75, + height: 75, + marginRight: 8, + borderRadius: 16, + }, + separator: { + borderBottomColor: 'black', + borderBottomWidth: StyleSheet.hairlineWidth, + width: '110%', + marginLeft: -16, + }, }) |