diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/composer/ComposePost.tsx | 111 | ||||
-rw-r--r-- | src/view/com/composer/PhotoCarouselPicker.tsx | 11 | ||||
-rw-r--r-- | src/view/com/posts/FeedItem.tsx | 5 | ||||
-rw-r--r-- | src/view/com/util/images/AutoSizedImage.tsx | 59 | ||||
-rw-r--r-- | src/view/index.ts | 10 |
5 files changed, 116 insertions, 80 deletions
diff --git a/src/view/com/composer/ComposePost.tsx b/src/view/com/composer/ComposePost.tsx index c6d371bc6..65120b663 100644 --- a/src/view/com/composer/ComposePost.tsx +++ b/src/view/com/composer/ComposePost.tsx @@ -4,6 +4,7 @@ import { ActivityIndicator, KeyboardAvoidingView, SafeAreaView, + ScrollView, StyleSheet, Text, TextInput, @@ -32,6 +33,7 @@ import {SelectedPhoto} from './SelectedPhoto' const MAX_TEXT_LENGTH = 256 const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH +const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} export const ComposePost = observer(function ComposePost({ replyTo, @@ -48,6 +50,7 @@ export const ComposePost = observer(function ComposePost({ const [processingState, setProcessingState] = useState('') const [error, setError] = useState('') const [text, setText] = useState('') + const [isSelectingPhotos, setIsSelectingPhotos] = useState(false) const [selectedPhotos, setSelectedPhotos] = useState<string[]>([]) const autocompleteView = useMemo<UserAutocompleteViewModel>( @@ -81,10 +84,17 @@ export const ComposePost = observer(function ComposePost({ } }, []) + const onPressSelectPhotos = () => { + if (isSelectingPhotos) { + setIsSelectingPhotos(false) + } else if (selectedPhotos.length < 4) { + setIsSelectingPhotos(true) + } + } const onSelectPhotos = (photos: string[]) => { setSelectedPhotos(photos) + setIsSelectingPhotos(false) } - const onChangeText = (newText: string) => { setText(newText) @@ -211,55 +221,71 @@ export const ComposePost = observer(function ComposePost({ <Text style={[s.red4, s.flex1]}>{error}</Text> </View> )} - {replyTo ? ( - <View style={styles.replyToLayout}> + <ScrollView style={s.flex1}> + {replyTo ? ( + <View style={styles.replyToLayout}> + <UserAvatar + handle={replyTo.author.handle} + displayName={replyTo.author.displayName} + avatar={replyTo.author.avatar} + size={50} + /> + <View style={styles.replyToPost}> + <TextLink + href={`/profile/${replyTo.author.handle}`} + text={replyTo.author.displayName || replyTo.author.handle} + style={[s.f16, s.bold]} + /> + <Text style={[s.f16, s['lh16-1.3']]} numberOfLines={6}> + {replyTo.text} + </Text> + </View> + </View> + ) : undefined} + <View style={[styles.textInputLayout, selectTextInputLayout]}> <UserAvatar - handle={replyTo.author.handle} - displayName={replyTo.author.displayName} - avatar={replyTo.author.avatar} + handle={store.me.handle || ''} + displayName={store.me.displayName} + avatar={store.me.avatar} size={50} /> - <View style={styles.replyToPost}> - <TextLink - href={`/profile/${replyTo.author.handle}`} - text={replyTo.author.displayName || replyTo.author.handle} - style={[s.f16, s.bold]} - /> - <Text style={[s.f16, s['lh16-1.3']]} numberOfLines={6}> - {replyTo.text} - </Text> - </View> + <TextInput + ref={textInput} + multiline + scrollEnabled + onChangeText={(text: string) => onChangeText(text)} + placeholder={selectTextInputPlaceholder} + style={styles.textInput}> + {textDecorated} + </TextInput> </View> - ) : undefined} - <View style={[styles.textInputLayout, selectTextInputLayout]}> - <UserAvatar - handle={store.me.handle || ''} - displayName={store.me.displayName} - avatar={store.me.avatar} - size={50} - /> - <TextInput - ref={textInput} - multiline - scrollEnabled - onChangeText={(text: string) => onChangeText(text)} - placeholder={selectTextInputPlaceholder} - style={styles.textInput}> - {textDecorated} - </TextInput> - </View> - <SelectedPhoto - selectedPhotos={selectedPhotos} - onSelectPhotos={onSelectPhotos} - /> - {localPhotos.photos != null && selectedPhotos.length < 4 && ( - <PhotoCarouselPicker + <SelectedPhoto selectedPhotos={selectedPhotos} onSelectPhotos={onSelectPhotos} - localPhotos={localPhotos} /> - )} + </ScrollView> + {isSelectingPhotos && + localPhotos.photos != null && + selectedPhotos.length < 4 && ( + <PhotoCarouselPicker + selectedPhotos={selectedPhotos} + onSelectPhotos={onSelectPhotos} + localPhotos={localPhotos} + /> + )} <View style={styles.bottomBar}> + <TouchableOpacity + onPress={onPressSelectPhotos} + style={[s.pl5]} + hitSlop={HITSLOP}> + <FontAwesomeIcon + icon={['far', 'image']} + style={{ + color: selectedPhotos.length < 4 ? colors.blue3 : colors.gray3, + }} + size={24} + /> + </TouchableOpacity> <View style={s.flex1} /> <Text style={[s.mr10, {color: progressColor}]}> {MAX_TEXT_LENGTH - text.length} @@ -392,5 +418,6 @@ const styles = StyleSheet.create({ alignItems: 'center', borderTopWidth: 1, borderTopColor: colors.gray2, + backgroundColor: colors.white, }, }) diff --git a/src/view/com/composer/PhotoCarouselPicker.tsx b/src/view/com/composer/PhotoCarouselPicker.tsx index 7095e9dd1..86d23313d 100644 --- a/src/view/com/composer/PhotoCarouselPicker.tsx +++ b/src/view/com/composer/PhotoCarouselPicker.tsx @@ -86,6 +86,11 @@ export const PhotoCarouselPicker = ({ style={{color: colors.blue3}} /> </TouchableOpacity> + <TouchableOpacity + style={[styles.galleryButton, styles.photo]} + onPress={handleOpenGallery}> + <FontAwesomeIcon icon="image" style={{color: colors.blue3}} size={24} /> + </TouchableOpacity> {localPhotos.photos.map((item: any, index: number) => ( <TouchableOpacity key={`local-image-${index}`} @@ -94,11 +99,6 @@ export const PhotoCarouselPicker = ({ <Image style={styles.photo} source={{uri: item.node.image.uri}} /> </TouchableOpacity> ))} - <TouchableOpacity - style={[styles.galleryButton, styles.photo]} - onPress={handleOpenGallery}> - <FontAwesomeIcon icon="image" style={{color: colors.blue3}} size={24} /> - </TouchableOpacity> </ScrollView> ) } @@ -109,6 +109,7 @@ const styles = StyleSheet.create({ maxHeight: 96, padding: 8, overflow: 'hidden', + backgroundColor: colors.white, }, galleryButton: { borderWidth: 1, diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index e66858ff6..984fde289 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -193,7 +193,7 @@ export const FeedItem = observer(function FeedItem({ style={styles.postText} /> </View> - <PostEmbeds embed={item.embed} style={{marginBottom: 10}} /> + <PostEmbeds embed={item.embed} style={styles.postEmbeds} /> <PostCtrls replyCount={item.replyCount} repostCount={item.repostCount} @@ -278,4 +278,7 @@ const styles = StyleSheet.create({ fontSize: 16, lineHeight: 20.8, // 1.3 of 16px }, + postEmbeds: { + marginBottom: 10, + }, }) diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx index 4728f42df..a60ddb89c 100644 --- a/src/view/com/util/images/AutoSizedImage.tsx +++ b/src/view/com/util/images/AutoSizedImage.tsx @@ -1,4 +1,4 @@ -import React, {useState, useEffect, useMemo} from 'react' +import React, {useState, useEffect} from 'react' import { Image, ImageStyle, @@ -8,6 +8,7 @@ import { Text, TouchableWithoutFeedback, View, + ViewStyle, } from 'react-native' import {colors} from '../../../lib/styles' @@ -30,39 +31,29 @@ export function AutoSizedImage({ const [error, setError] = useState<string | undefined>() const [imgInfo, setImgInfo] = useState<Dim | undefined>() const [containerInfo, setContainerInfo] = useState<Dim | undefined>() - const calculatedStyle = useMemo(() => { - if (imgInfo && containerInfo) { - // imgInfo.height / imgInfo.width = x / containerInfo.width - // x = imgInfo.height / imgInfo.width * containerInfo.width - return { - height: Math.min( - MAX_HEIGHT, - (imgInfo.height / imgInfo.width) * containerInfo.width, - ), - } - } - return undefined - }, [imgInfo, containerInfo]) useEffect(() => { let aborted = false - Image.getSize( - uri, - (width: number, height: number) => { - if (!aborted) { - setImgInfo({width, height}) - } - }, - (error: any) => { - if (!aborted) { - setError(String(error)) - } - }, - ) + if (!imgInfo) { + Image.getSize( + uri, + (width: number, height: number) => { + console.log('gotSize') + if (!aborted) { + setImgInfo({width, height}) + } + }, + (error: any) => { + if (!aborted) { + setError(String(error)) + } + }, + ) + } return () => { aborted = true } - }, [uri]) + }, [uri, imgInfo]) const onLayout = (evt: LayoutChangeEvent) => { setContainerInfo({ @@ -71,6 +62,18 @@ export function AutoSizedImage({ }) } + let calculatedStyle: StyleProp<ViewStyle> | undefined + if (imgInfo && containerInfo) { + // imgInfo.height / imgInfo.width = x / containerInfo.width + // x = imgInfo.height / imgInfo.width * containerInfo.width + calculatedStyle = { + height: Math.min( + MAX_HEIGHT, + (imgInfo.height / imgInfo.width) * containerInfo.width, + ), + } + } + return ( <View style={style}> <TouchableWithoutFeedback onPress={onPress}> diff --git a/src/view/index.ts b/src/view/index.ts index 71769471b..8f119cd16 100644 --- a/src/view/index.ts +++ b/src/view/index.ts @@ -18,6 +18,7 @@ import {faBell} from '@fortawesome/free-solid-svg-icons/faBell' import {faBell as farBell} from '@fortawesome/free-regular-svg-icons/faBell' import {faBookmark} from '@fortawesome/free-solid-svg-icons/faBookmark' import {faBookmark as farBookmark} from '@fortawesome/free-regular-svg-icons/faBookmark' +import {faCamera} from '@fortawesome/free-solid-svg-icons/faCamera' import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck' import {faCircleCheck} from '@fortawesome/free-regular-svg-icons/faCircleCheck' import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser' @@ -33,6 +34,8 @@ import {faGlobe} from '@fortawesome/free-solid-svg-icons/faGlobe' import {faHeart} from '@fortawesome/free-regular-svg-icons/faHeart' import {faHeart as fasHeart} from '@fortawesome/free-solid-svg-icons/faHeart' import {faHouse} from '@fortawesome/free-solid-svg-icons/faHouse' +import {faImage as farImage} from '@fortawesome/free-regular-svg-icons/faImage' +import {faImage} from '@fortawesome/free-solid-svg-icons/faImage' import {faLink} from '@fortawesome/free-solid-svg-icons/faLink' import {faLock} from '@fortawesome/free-solid-svg-icons/faLock' import {faMagnifyingGlass} from '@fortawesome/free-solid-svg-icons/faMagnifyingGlass' @@ -58,8 +61,6 @@ import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark' import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket' import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan' import {faX} from '@fortawesome/free-solid-svg-icons/faX' -import {faCamera} from '@fortawesome/free-solid-svg-icons/faCamera' -import {faImage} from '@fortawesome/free-solid-svg-icons/faImage' import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark' export function setup() { @@ -82,6 +83,7 @@ export function setup() { farBell, faBookmark, farBookmark, + faCamera, faCheck, faCircleCheck, faCircleUser, @@ -97,6 +99,8 @@ export function setup() { faHeart, fasHeart, faHouse, + faImage, + farImage, faLink, faLock, faMagnifyingGlass, @@ -122,8 +126,6 @@ export function setup() { faTicket, faTrashCan, faX, - faCamera, - faImage, faXmark, ) } |