Add alt text support and rework image layout (#503)

* Add alt text support and rework image layout

* Add additional BottomSheet implementation to account for nested Composer modal

* Use mobile gallery layout on mobile web

* Missing key

* Fix lint

* Move altimage modal into the standard modal system

* Fix overflow wrapping of images

* Fixes to the alt-image modal

* Remove unnecessary switch

* Restore old imagelayoutgrid code

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
This commit is contained in:
Ollie Hsieh 2023-04-21 14:20:06 -07:00 committed by GitHub
parent 0f5735b616
commit f0706dbe9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 412 additions and 132 deletions

View file

@ -1,4 +1,5 @@
import React, {useCallback} from 'react'
import {ImageStyle, Keyboard} from 'react-native'
import {GalleryModel} from 'state/models/media/gallery'
import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
@ -6,6 +7,8 @@ import {colors} from 'lib/styles'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {ImageModel} from 'state/models/media/image'
import {Image} from 'expo-image'
import {Text} from 'view/com/util/text/Text'
import {isDesktopWeb} from 'platform/detection'
interface Props {
gallery: GalleryModel
@ -13,17 +16,28 @@ interface Props {
export const Gallery = observer(function ({gallery}: Props) {
const getImageStyle = useCallback(() => {
switch (gallery.size) {
case 1:
return styles.image250
case 2:
return styles.image175
default:
return styles.image85
let side: number
if (gallery.size === 1) {
side = 250
} else {
side = (isDesktopWeb ? 560 : 350) / gallery.size
}
return {
height: side,
width: side,
}
}, [gallery])
const imageStyle = getImageStyle()
const handleAddImageAltText = useCallback(
(image: ImageModel) => {
Keyboard.dismiss()
gallery.setAltText(image)
},
[gallery],
)
const handleRemovePhoto = useCallback(
(image: ImageModel) => {
gallery.remove(image)
@ -38,14 +52,68 @@ export const Gallery = observer(function ({gallery}: Props) {
[gallery],
)
const isOverflow = !isDesktopWeb && gallery.size > 2
const imageControlLabelStyle = {
borderRadius: 5,
paddingHorizontal: 10,
position: 'absolute' as const,
width: 46,
zIndex: 1,
...(isOverflow
? {
left: 4,
bottom: 4,
}
: isDesktopWeb && gallery.size < 3
? {
left: 8,
top: 8,
}
: {
left: 4,
top: 4,
}),
}
const imageControlsSubgroupStyle = {
display: 'flex' as const,
flexDirection: 'row' as const,
position: 'absolute' as const,
...(isOverflow
? {
top: 4,
right: 4,
gap: 4,
}
: isDesktopWeb && gallery.size < 3
? {
top: 8,
right: 8,
gap: 8,
}
: {
top: 4,
right: 4,
gap: 4,
}),
zIndex: 1,
}
return !gallery.isEmpty ? (
<View testID="selectedPhotosView" style={styles.gallery}>
{gallery.images.map(image =>
image.compressed !== undefined ? (
<View
key={`selected-image-${image.path}`}
style={[styles.imageContainer, imageStyle]}>
<View style={styles.imageControls}>
<View key={`selected-image-${image.path}`} style={[imageStyle]}>
<TouchableOpacity
testID="altTextButton"
onPress={() => {
handleAddImageAltText(image)
}}
style={[styles.imageControl, imageControlLabelStyle]}>
<Text style={styles.imageControlTextContent}>ALT</Text>
</TouchableOpacity>
<View style={imageControlsSubgroupStyle}>
<TouchableOpacity
testID="cropPhotoButton"
onPress={() => {
@ -72,7 +140,7 @@ export const Gallery = observer(function ({gallery}: Props) {
<Image
testID="selectedPhotoImage"
style={[styles.image, imageStyle]}
style={[styles.image, imageStyle] as ImageStyle}
source={{
uri: image.compressed.path,
}}
@ -88,36 +156,13 @@ const styles = StyleSheet.create({
gallery: {
flex: 1,
flexDirection: 'row',
gap: 8,
marginTop: 16,
},
imageContainer: {
margin: 2,
},
image: {
resizeMode: 'cover',
borderRadius: 8,
},
image250: {
width: 250,
height: 250,
},
image175: {
width: 175,
height: 175,
},
image85: {
width: 85,
height: 85,
},
imageControls: {
position: 'absolute',
display: 'flex',
flexDirection: 'row',
gap: 4,
top: 8,
right: 8,
zIndex: 1,
},
imageControl: {
width: 24,
height: 24,
@ -127,4 +172,10 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
},
imageControlTextContent: {
color: 'white',
fontSize: 12,
fontWeight: 'bold',
letterSpacing: 1,
},
})