Adjust ALT, add crop icon

This commit is contained in:
Eric Bailey
2024-09-04 10:21:06 -05:00
parent 8675fd48ac
commit d849e55fe6
4 changed files with 70 additions and 36 deletions
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M6 2a1 1 0 0 1 1 1v2h11a1 1 0 0 1 1 1v11h2a1 1 0 1 1 0 2h-2v2a1 1 0 1 1-2 0v-2H6a1 1 0 0 1-1-1V7H3a1 1 0 0 1 0-2h2V3a1 1 0 0 1 1-1Zm1 5v10h10V7H7Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 289 B

+5
View File
@@ -0,0 +1,5 @@
import {createSinglePathSVG} from './TEMPLATE'
export const Crop_Stroke2_Corner0_Rounded = createSinglePathSVG({
path: 'M6 2a1 1 0 0 1 1 1v2h11a1 1 0 0 1 1 1v11h2a1 1 0 1 1 0 2h-2v2a1 1 0 1 1-2 0v-2H6a1 1 0 0 1-1-1V7H3a1 1 0 0 1 0-2h2V3a1 1 0 0 1 1-1Zm1 5v10h10V7H7Z',
})
+54 -14
View File
@@ -7,7 +7,10 @@ import {useLingui} from '@lingui/react'
import * as imageSizes from '#/lib/media/image-sizes' import * as imageSizes from '#/lib/media/image-sizes'
import {Dimensions} from '#/lib/media/types' import {Dimensions} from '#/lib/media/types'
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Crop_Stroke2_Corner0_Rounded as Crop} from '#/components/icons/Crop'
import {Text} from '#/components/Typography'
export function useImageAspectRatio({ export function useImageAspectRatio({
src, src,
@@ -16,9 +19,13 @@ export function useImageAspectRatio({
src: string src: string
dimensions: Dimensions | undefined dimensions: Dimensions | undefined
}) { }) {
const [aspectRatio, setAspectRatio] = React.useState<number>( const [rawAspectRatio, setAspectRatio] = React.useState<number>(
dimensions ? calc(dimensions) : 1, dimensions ? calc(dimensions) : 1,
) )
const aspectRatio = React.useMemo(() => {
// max of 3:4 ratio
return Math.max(rawAspectRatio, 0.75)
}, [rawAspectRatio])
React.useEffect(() => { React.useEffect(() => {
let aborted = false let aborted = false
@@ -34,7 +41,9 @@ export function useImageAspectRatio({
return { return {
dimensions, dimensions,
rawAspectRatio,
aspectRatio, aspectRatio,
isCropped: rawAspectRatio < aspectRatio,
} }
} }
@@ -54,13 +63,6 @@ export function SquareFramedImage({
const ratio = Math.min(1 / aspectRatio, 1) const ratio = Math.min(1 / aspectRatio, 1)
return `${ratio * 100}%` return `${ratio * 100}%`
}, [aspectRatio]) }, [aspectRatio])
/**
* Computed as a CSS `aspectRatio` value
*/
const innerAspectRatio = React.useMemo(() => {
// max of 3:4 ratio
return Math.max(aspectRatio, 0.75)
}, [aspectRatio])
return ( return (
<View style={[a.w_full]}> <View style={[a.w_full]}>
@@ -72,7 +74,7 @@ export function SquareFramedImage({
a.rounded_sm, a.rounded_sm,
a.overflow_hidden, a.overflow_hidden,
t.atoms.bg_contrast_25, t.atoms.bg_contrast_25,
{aspectRatio: innerAspectRatio}, {aspectRatio},
]}> ]}>
{children} {children}
</View> </View>
@@ -88,23 +90,25 @@ export function AutoSizedImage({
onPress, onPress,
onLongPress, onLongPress,
onPressIn, onPressIn,
children = null,
}: { }: {
image: AppBskyEmbedImages.ViewImage image: AppBskyEmbedImages.ViewImage
disableCrop?: boolean disableCrop?: boolean
children?: React.ReactNode
onPress?: () => void onPress?: () => void
onLongPress?: () => void onLongPress?: () => void
onPressIn?: () => void onPressIn?: () => void
}) { }) {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const {aspectRatio} = useImageAspectRatio({ const largeAlt = useLargeAltBadgeEnabled()
const {aspectRatio, isCropped: rawIsCropped} = useImageAspectRatio({
src: image.thumb, src: image.thumb,
dimensions: image.aspectRatio, dimensions: image.aspectRatio,
}) })
const isCropped = rawIsCropped && !disableCrop
const hasAlt = !!image.alt
const contents = ( const contents = (
<>
<Image <Image
style={[a.w_full, a.h_full]} style={[a.w_full, a.h_full]}
source={image.thumb} source={image.thumb}
@@ -113,6 +117,44 @@ export function AutoSizedImage({
accessibilityLabel={image.alt} accessibilityLabel={image.alt}
accessibilityHint="" accessibilityHint=""
/> />
{hasAlt || isCropped ? (
<View
accessible={false}
style={[
a.absolute,
a.flex_row,
a.align_center,
a.rounded_xs,
t.atoms.bg_contrast_25,
{
gap: 3,
padding: 3,
bottom: a.p_sm.padding,
right: a.p_sm.padding,
opacity: 0.8,
},
largeAlt && [
{
gap: 4,
padding: 5,
},
],
]}>
{isCropped && (
<Crop
fill={t.atoms.text_contrast_high.color}
width={largeAlt ? 18 : 12}
/>
)}
{hasAlt && (
<Text style={[a.font_heavy, largeAlt ? a.text_xs : {fontSize: 8}]}>
ALT
</Text>
)}
</View>
) : null}
</>
) )
if (disableCrop) { if (disableCrop) {
@@ -132,7 +174,6 @@ export function AutoSizedImage({
{aspectRatio}, {aspectRatio},
]}> ]}>
{contents} {contents}
{children}
</Pressable> </Pressable>
) )
} else { } else {
@@ -147,7 +188,6 @@ export function AutoSizedImage({
accessibilityHint={_(msg`Tap to view full image`)} accessibilityHint={_(msg`Tap to view full image`)}
style={[a.h_full]}> style={[a.h_full]}>
{contents} {contents}
{children}
</Pressable> </Pressable>
</SquareFramedImage> </SquareFramedImage>
) )
+2 -14
View File
@@ -3,7 +3,6 @@ import {
InteractionManager, InteractionManager,
StyleProp, StyleProp,
StyleSheet, StyleSheet,
Text,
View, View,
ViewStyle, ViewStyle,
} from 'react-native' } from 'react-native'
@@ -22,7 +21,6 @@ import {
} from '@atproto/api' } from '@atproto/api'
import {ImagesLightbox, useLightboxControls} from '#/state/lightbox' import {ImagesLightbox, useLightboxControls} from '#/state/lightbox'
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard' import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
@@ -60,7 +58,6 @@ export function PostEmbeds({
contextView?: 'thread-highlighted' contextView?: 'thread-highlighted'
}) { }) {
const {openLightbox} = useLightboxControls() const {openLightbox} = useLightboxControls()
const largeAltBadge = useLargeAltBadgeEnabled()
// quote post with media // quote post with media
// = // =
@@ -134,17 +131,8 @@ export function PostEmbeds({
disableCrop={contextView === 'thread-highlighted'} disableCrop={contextView === 'thread-highlighted'}
image={image} image={image}
onPress={() => _openLightbox(0)} onPress={() => _openLightbox(0)}
onPressIn={() => onPressIn(0)}> onPressIn={() => onPressIn(0)}
{image.alt === '' ? null : ( />
<View style={styles.altContainer}>
<Text
style={[styles.alt, largeAltBadge && a.text_xs]}
accessible={false}>
ALT
</Text>
</View>
)}
</AutoSizedImage>
</View> </View>
</ContentHider> </ContentHider>
) )