further refactoring code into different components

zio/stable
João Ferreiro 2022-11-29 15:35:49 +00:00
parent 0102e91f3a
commit 31be6fbbac
3 changed files with 147 additions and 154 deletions

View File

@ -23,8 +23,9 @@ import * as apilib from '../../../state/lib/api'
import {ComposerOpts} from '../../../state/models/shell-ui' import {ComposerOpts} from '../../../state/models/shell-ui'
import {s, colors, gradients} from '../../lib/styles' import {s, colors, gradients} from '../../lib/styles'
import {detectLinkables} from '../../../lib/strings' import {detectLinkables} from '../../../lib/strings'
import {PhotoCarouselPicker} from './PhotoCarouselPicker'
import {UserLocalPhotosModel} from '../../../state/models/user-local-photos' import {UserLocalPhotosModel} from '../../../state/models/user-local-photos'
import {PhotoCarouselPicker} from './PhotoCarouselPicker'
import {SelectedPhoto} from './SelectedPhoto'
const MAX_TEXT_LENGTH = 256 const MAX_TEXT_LENGTH = 256
const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH
@ -60,7 +61,7 @@ export const ComposePost = observer(function ComposePost({
useEffect(() => { useEffect(() => {
localPhotos.setup() localPhotos.setup()
}, []) }, [localPhotos])
useEffect(() => { useEffect(() => {
// HACK // HACK
@ -130,6 +131,10 @@ export const ComposePost = observer(function ComposePost({
const canPost = text.length <= MAX_TEXT_LENGTH const canPost = text.length <= MAX_TEXT_LENGTH
const progressColor = text.length > DANGER_TEXT_LENGTH ? '#e60000' : undefined const progressColor = text.length > DANGER_TEXT_LENGTH ? '#e60000' : undefined
const selectTextInputLayout =
selectedPhotos.length !== 0
? styles.textInputLayoutWithPhoto
: styles.textInputLayoutWithoutPhoto
const textDecorated = useMemo(() => { const textDecorated = useMemo(() => {
let i = 0 let i = 0
@ -207,13 +212,7 @@ export const ComposePost = observer(function ComposePost({
</View> </View>
</View> </View>
) : undefined} ) : undefined}
<View <View style={[styles.textInputLayout, selectTextInputLayout]}>
style={[
styles.textInputLayout,
selectedPhotos.length !== 0
? styles.textInputLayoutWithPhoto
: styles.textInputLayoutWithoutPhoto,
]}>
<UserAvatar <UserAvatar
handle={store.me.handle || ''} handle={store.me.handle || ''}
displayName={store.me.displayName} displayName={store.me.displayName}
@ -229,12 +228,17 @@ export const ComposePost = observer(function ComposePost({
{textDecorated} {textDecorated}
</TextInput> </TextInput>
</View> </View>
<SelectedPhoto
selectedPhotos={selectedPhotos}
setSelectedPhotos={setSelectedPhotos}
/>
<PhotoCarouselPicker <PhotoCarouselPicker
selectedPhotos={selectedPhotos} selectedPhotos={selectedPhotos}
setSelectedPhotos={setSelectedPhotos} setSelectedPhotos={setSelectedPhotos}
localPhotos={localPhotos} localPhotos={localPhotos}
inputText={text} inputText={text}
/> />
<View style={styles.separator} />
<View style={[s.flexRow, s.pt10, s.pb10, s.pr5, styles.contentCenter]}> <View style={[s.flexRow, s.pt10, s.pb10, s.pr5, styles.contentCenter]}>
<View style={s.flex1} /> <View style={s.flex1} />
<Text style={[s.mr10, {color: progressColor}]}> <Text style={[s.mr10, {color: progressColor}]}>
@ -339,4 +343,9 @@ const styles = StyleSheet.create({
paddingRight: 8, paddingRight: 8,
}, },
contentCenter: {alignItems: 'center'}, contentCenter: {alignItems: 'center'},
separator: {
borderBottomColor: 'black',
borderBottomWidth: StyleSheet.hairlineWidth,
width: '100%',
},
}) })

View File

@ -1,11 +1,5 @@
import React from 'react' import React from 'react'
import { import {Image, StyleSheet, TouchableOpacity, ScrollView} from 'react-native'
Image,
StyleSheet,
TouchableOpacity,
View,
ScrollView,
} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {colors} from '../../lib/styles' import {colors} from '../../lib/styles'
import {openPicker, openCamera} from 'react-native-image-crop-picker' import {openPicker, openCamera} from 'react-native-image-crop-picker'
@ -22,148 +16,60 @@ export const PhotoCarouselPicker = observer(function PhotoCarouselPicker({
inputText: string inputText: string
localPhotos: any localPhotos: any
}) { }) {
return ( return localPhotos.photos != null &&
<> inputText === '' &&
{selectedPhotos.length !== 0 && ( selectedPhotos.length === 0 ? (
<View style={styles.selectedImageContainer}> <ScrollView
{selectedPhotos.length !== 0 && horizontal
selectedPhotos.map((item, index) => ( style={styles.photosContainer}
<View showsHorizontalScrollIndicator={false}>
key={`selected-image-${index}`} <TouchableOpacity
style={[ style={[styles.galleryButton, styles.photo]}
styles.selectedImage, onPress={() => {
selectedPhotos.length === 1 openCamera({multiple: true, maxFiles: 4}).then()
? styles.selectedImage250 }}>
: selectedPhotos.length === 2 <FontAwesomeIcon
? styles.selectedImage175 icon="camera"
: styles.selectedImage85, size={24}
]}> style={{color: colors.blue3}}
<TouchableOpacity />
onPress={() => { </TouchableOpacity>
setSelectedPhotos( {localPhotos.photos.map((item: any, index: number) => (
selectedPhotos.filter(filterItem => filterItem !== item), <TouchableOpacity
) key={`local-image-${index}`}
}} style={styles.photoButton}
style={styles.removePhotoButton}> onPress={() => {
<FontAwesomeIcon setSelectedPhotos([item.node.image.uri, ...selectedPhotos])
icon="xmark" }}>
size={16} <Image style={styles.photo} source={{uri: item.node.image.uri}} />
style={{color: colors.white}} </TouchableOpacity>
/> ))}
</TouchableOpacity> <TouchableOpacity
style={[styles.galleryButton, styles.photo]}
<Image onPress={() => {
style={[ openPicker({multiple: true, maxFiles: 4}).then(items => {
styles.selectedImage, setSelectedPhotos([
selectedPhotos.length === 1 ...items.reduce(
? styles.selectedImage250 (accum, cur) => accum.concat(cur.sourceURL!),
: selectedPhotos.length === 2 [] as string[],
? styles.selectedImage175 ),
: styles.selectedImage85, ...selectedPhotos,
]} ])
source={{uri: item}} })
/> }}>
</View> <FontAwesomeIcon icon="image" style={{color: colors.blue3}} size={24} />
))} </TouchableOpacity>
</View> </ScrollView>
)} ) : null
{localPhotos.photos != null &&
inputText === '' &&
selectedPhotos.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: any, index: number) => (
<TouchableOpacity
key={`local-image-${index}`}
style={styles.photoButton}
onPress={() => {
setSelectedPhotos([item.node.image.uri, ...selectedPhotos])
}}>
<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 => {
setSelectedPhotos([
...items.reduce(
(accum, cur) => accum.concat(cur.sourceURL!),
[] as string[],
),
...selectedPhotos,
])
})
}}>
<FontAwesomeIcon
icon="image"
style={{color: colors.blue3}}
size={24}
/>
</TouchableOpacity>
</ScrollView>
)}
<View style={styles.separator} />
</>
)
}) })
const styles = StyleSheet.create({ const styles = StyleSheet.create({
selectedImageContainer: {
flex: 1,
flexDirection: 'row',
marginTop: 16,
},
selectedImage: {
borderRadius: 8,
margin: 2,
},
selectedImage250: {
width: 250,
height: 250,
},
selectedImage175: {
width: 175,
height: 175,
},
selectedImage85: {
width: 85,
height: 85,
},
photosContainer: { photosContainer: {
width: '100%', width: '100%',
maxHeight: 96, maxHeight: 96,
padding: 8, padding: 8,
overflow: 'hidden', 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: { galleryButton: {
borderWidth: 1, borderWidth: 1,
borderColor: colors.gray3, borderColor: colors.gray3,
@ -184,9 +90,4 @@ const styles = StyleSheet.create({
marginRight: 8, marginRight: 8,
borderRadius: 16, borderRadius: 16,
}, },
separator: {
borderBottomColor: 'black',
borderBottomWidth: StyleSheet.hairlineWidth,
width: '100%',
},
}) })

View File

@ -0,0 +1,83 @@
import React from 'react'
import {Image, StyleSheet, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {colors} from '../../lib/styles'
import {observer} from 'mobx-react-lite'
export const SelectedPhoto = ({
selectedPhotos,
setSelectedPhotos,
}: {
selectedPhotos: string[]
setSelectedPhotos: React.Dispatch<React.SetStateAction<string[]>>
}) => {
const imageStyle =
selectedPhotos.length === 1
? styles.image250
: selectedPhotos.length === 2
? styles.image175
: styles.image85
return selectedPhotos.length !== 0 ? (
<View style={styles.imageContainer}>
{selectedPhotos.length !== 0 &&
selectedPhotos.map((item, index) => (
<View
key={`selected-image-${index}`}
style={[styles.image, imageStyle]}>
<TouchableOpacity
onPress={() => {
setSelectedPhotos(
selectedPhotos.filter(filterItem => filterItem !== item),
)
}}
style={styles.removePhotoButton}>
<FontAwesomeIcon
icon="xmark"
size={16}
style={{color: colors.white}}
/>
</TouchableOpacity>
<Image style={[styles.image, imageStyle]} source={{uri: item}} />
</View>
))}
</View>
) : null
}
const styles = StyleSheet.create({
imageContainer: {
flex: 1,
flexDirection: 'row',
marginTop: 16,
},
image: {
borderRadius: 8,
margin: 2,
},
image250: {
width: 250,
height: 250,
},
image175: {
width: 175,
height: 175,
},
image85: {
width: 85,
height: 85,
},
removePhotoButton: {
position: 'absolute',
top: 8,
right: 8,
width: 24,
height: 24,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.black,
zIndex: 1,
},
})