further refactoring code into different components
parent
0102e91f3a
commit
31be6fbbac
|
@ -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%',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -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,54 +16,9 @@ export const PhotoCarouselPicker = observer(function PhotoCarouselPicker({
|
||||||
inputText: string
|
inputText: string
|
||||||
localPhotos: any
|
localPhotos: any
|
||||||
}) {
|
}) {
|
||||||
return (
|
return localPhotos.photos != null &&
|
||||||
<>
|
|
||||||
{selectedPhotos.length !== 0 && (
|
|
||||||
<View style={styles.selectedImageContainer}>
|
|
||||||
{selectedPhotos.length !== 0 &&
|
|
||||||
selectedPhotos.map((item, index) => (
|
|
||||||
<View
|
|
||||||
key={`selected-image-${index}`}
|
|
||||||
style={[
|
|
||||||
styles.selectedImage,
|
|
||||||
selectedPhotos.length === 1
|
|
||||||
? styles.selectedImage250
|
|
||||||
: selectedPhotos.length === 2
|
|
||||||
? styles.selectedImage175
|
|
||||||
: styles.selectedImage85,
|
|
||||||
]}>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => {
|
|
||||||
setSelectedPhotos(
|
|
||||||
selectedPhotos.filter(filterItem => filterItem !== item),
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
style={styles.removePhotoButton}>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="xmark"
|
|
||||||
size={16}
|
|
||||||
style={{color: colors.white}}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
|
|
||||||
<Image
|
|
||||||
style={[
|
|
||||||
styles.selectedImage,
|
|
||||||
selectedPhotos.length === 1
|
|
||||||
? styles.selectedImage250
|
|
||||||
: selectedPhotos.length === 2
|
|
||||||
? styles.selectedImage175
|
|
||||||
: styles.selectedImage85,
|
|
||||||
]}
|
|
||||||
source={{uri: item}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
{localPhotos.photos != null &&
|
|
||||||
inputText === '' &&
|
inputText === '' &&
|
||||||
selectedPhotos.length === 0 && (
|
selectedPhotos.length === 0 ? (
|
||||||
<ScrollView
|
<ScrollView
|
||||||
horizontal
|
horizontal
|
||||||
style={styles.photosContainer}
|
style={styles.photosContainer}
|
||||||
|
@ -92,10 +41,7 @@ export const PhotoCarouselPicker = observer(function PhotoCarouselPicker({
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setSelectedPhotos([item.node.image.uri, ...selectedPhotos])
|
setSelectedPhotos([item.node.image.uri, ...selectedPhotos])
|
||||||
}}>
|
}}>
|
||||||
<Image
|
<Image style={styles.photo} source={{uri: item.node.image.uri}} />
|
||||||
style={styles.photo}
|
|
||||||
source={{uri: item.node.image.uri}}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
))}
|
))}
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
@ -111,59 +57,19 @@ export const PhotoCarouselPicker = observer(function PhotoCarouselPicker({
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
}}>
|
}}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon="image" style={{color: colors.blue3}} size={24} />
|
||||||
icon="image"
|
|
||||||
style={{color: colors.blue3}}
|
|
||||||
size={24}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
)}
|
) : null
|
||||||
<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%',
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in New Issue