Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[Lightbox] Add border radius to avatars (#6136)

* Preserve shape in lightbox

* Rename shapes to semantic meanings

It looks like after all I do want to fork based on those.

* Round avatars on the web

* Oops

authored by

dan and committed by
GitHub
22dd4947 5d0610d4

+108 -61
+1
src/screens/Profile/Header/Shell.tsx
··· 64 64 height: 1000, 65 65 width: 1000, 66 66 }, 67 + type: 'circle-avi', 67 68 }, 68 69 ], 69 70 index: 0,
+1
src/view/com/lightbox/ImageViewing/@types/index.ts
··· 21 21 thumbUri: string 22 22 alt?: string 23 23 dimensions: Dimensions | null 24 + type: 'image' | 'circle-avi' | 'rect-avi' 24 25 }
+10 -4
src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx
··· 302 302 committedTransform.value = withClampedSpring(finalTransform) 303 303 }) 304 304 305 + const innerStyle = useAnimatedStyle(() => ({ 306 + width: '100%', 307 + aspectRatio: imageAspect, 308 + })) 309 + 305 310 const composedGesture = isScrollViewBeingDragged 306 311 ? // If the parent is not at rest, provide a no-op gesture. 307 312 Gesture.Manual() ··· 312 317 singleTap, 313 318 ) 314 319 320 + const type = imageSrc.type 321 + const borderRadius = 322 + type === 'circle-avi' ? 1e5 : type === 'rect-avi' ? 20 : 0 315 323 return ( 316 324 <GestureDetector gesture={composedGesture}> 317 325 <Animated.View style={imageStyle} renderToHardwareTextureAndroid> ··· 326 334 source={{uri: imageSrc.uri}} 327 335 placeholderContentFit="contain" 328 336 placeholder={{uri: imageSrc.thumbUri}} 329 - style={[styles.image]} 337 + style={[innerStyle, {borderRadius}]} 330 338 accessibilityLabel={imageSrc.alt} 331 339 accessibilityHint="" 332 340 accessibilityIgnoresInvertColors ··· 342 350 container: { 343 351 height: '100%', 344 352 overflow: 'hidden', 345 - }, 346 - image: { 347 - flex: 1, 353 + justifyContent: 'center', 348 354 }, 349 355 loading: { 350 356 position: 'absolute',
+4 -1
src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx
··· 143 143 singleTap, 144 144 ) 145 145 146 + const type = imageSrc.type 147 + const borderRadius = 148 + type === 'circle-avi' ? 1e5 : type === 'rect-avi' ? 20 : 0 146 149 return ( 147 150 <GestureDetector gesture={composedGesture}> 148 151 <Animated.ScrollView ··· 163 166 source={{uri: imageSrc.uri}} 164 167 placeholderContentFit="contain" 165 168 placeholder={{uri: imageSrc.thumbUri}} 166 - style={animatedStyle} 169 + style={[animatedStyle, {borderRadius}]} 167 170 accessibilityLabel={imageSrc.alt} 168 171 accessibilityHint="" 169 172 enableLiveTextInteraction={showControls && !scaled}
+87 -55
src/view/com/lightbox/Lightbox.web.tsx
··· 21 21 import {colors, s} from '#/lib/styles' 22 22 import {useLightbox, useLightboxControls} from '#/state/lightbox' 23 23 import {Text} from '../util/text/Text' 24 + import {ImageSource} from './ImageViewing/@types' 24 25 import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader' 25 - 26 - interface Img { 27 - uri: string 28 - alt?: string 29 - } 30 26 31 27 export function Lightbox() { 32 28 const {activeLightbox} = useLightbox() ··· 54 50 initialIndex = 0, 55 51 onClose, 56 52 }: { 57 - imgs: Img[] 53 + imgs: ImageSource[] 58 54 initialIndex: number 59 55 onClose: () => void 60 56 }) { ··· 101 97 return isTabletOrDesktop ? 32 : 24 102 98 }, [isTabletOrDesktop]) 103 99 100 + const img = imgs[index] 101 + const isAvi = img.type === 'circle-avi' || img.type === 'rect-avi' 104 102 return ( 105 103 <View style={styles.mask}> 106 104 <TouchableWithoutFeedback ··· 109 107 accessibilityLabel={_(msg`Close image viewer`)} 110 108 accessibilityHint={_(msg`Exits image view`)} 111 109 onAccessibilityEscape={onClose}> 112 - <View style={styles.imageCenterer}> 113 - <Image 114 - accessibilityIgnoresInvertColors 115 - source={imgs[index]} 116 - style={styles.image as ImageStyle} 117 - accessibilityLabel={imgs[index].alt} 118 - accessibilityHint="" 119 - /> 120 - {canGoLeft && ( 121 - <TouchableOpacity 122 - onPress={onPressLeft} 123 - style={[ 124 - styles.btn, 125 - btnStyle, 126 - styles.leftBtn, 127 - styles.blurredBackground, 128 - ]} 129 - accessibilityRole="button" 130 - accessibilityLabel={_(msg`Previous image`)} 131 - accessibilityHint=""> 132 - <FontAwesomeIcon 133 - icon="angle-left" 134 - style={styles.icon as FontAwesomeIconStyle} 135 - size={iconSize} 136 - /> 137 - </TouchableOpacity> 138 - )} 139 - {canGoRight && ( 140 - <TouchableOpacity 141 - onPress={onPressRight} 142 - style={[ 143 - styles.btn, 144 - btnStyle, 145 - styles.rightBtn, 146 - styles.blurredBackground, 147 - ]} 148 - accessibilityRole="button" 149 - accessibilityLabel={_(msg`Next image`)} 150 - accessibilityHint=""> 151 - <FontAwesomeIcon 152 - icon="angle-right" 153 - style={styles.icon as FontAwesomeIconStyle} 154 - size={iconSize} 155 - /> 156 - </TouchableOpacity> 157 - )} 158 - </View> 110 + {isAvi ? ( 111 + <View style={styles.aviCenterer}> 112 + <img 113 + src={img.uri} 114 + // @ts-ignore web-only 115 + style={ 116 + { 117 + ...styles.avi, 118 + borderRadius: 119 + img.type === 'circle-avi' 120 + ? '50%' 121 + : img.type === 'rect-avi' 122 + ? '10%' 123 + : 0, 124 + } as ImageStyle 125 + } 126 + alt={img.alt} 127 + /> 128 + </View> 129 + ) : ( 130 + <View style={styles.imageCenterer}> 131 + <Image 132 + accessibilityIgnoresInvertColors 133 + source={img} 134 + style={styles.image as ImageStyle} 135 + accessibilityLabel={img.alt} 136 + accessibilityHint="" 137 + /> 138 + {canGoLeft && ( 139 + <TouchableOpacity 140 + onPress={onPressLeft} 141 + style={[ 142 + styles.btn, 143 + btnStyle, 144 + styles.leftBtn, 145 + styles.blurredBackground, 146 + ]} 147 + accessibilityRole="button" 148 + accessibilityLabel={_(msg`Previous image`)} 149 + accessibilityHint=""> 150 + <FontAwesomeIcon 151 + icon="angle-left" 152 + style={styles.icon as FontAwesomeIconStyle} 153 + size={iconSize} 154 + /> 155 + </TouchableOpacity> 156 + )} 157 + {canGoRight && ( 158 + <TouchableOpacity 159 + onPress={onPressRight} 160 + style={[ 161 + styles.btn, 162 + btnStyle, 163 + styles.rightBtn, 164 + styles.blurredBackground, 165 + ]} 166 + accessibilityRole="button" 167 + accessibilityLabel={_(msg`Next image`)} 168 + accessibilityHint=""> 169 + <FontAwesomeIcon 170 + icon="angle-right" 171 + style={styles.icon as FontAwesomeIconStyle} 172 + size={iconSize} 173 + /> 174 + </TouchableOpacity> 175 + )} 176 + </View> 177 + )} 159 178 </TouchableWithoutFeedback> 160 - {imgs[index].alt ? ( 179 + {img.alt ? ( 161 180 <View style={styles.footer}> 162 181 <Pressable 163 182 accessibilityLabel={_(msg`Expand alt text`)} ··· 171 190 style={s.white} 172 191 numberOfLines={isAltExpanded ? 0 : 3} 173 192 ellipsizeMode="tail"> 174 - {imgs[index].alt} 193 + {img.alt} 175 194 </Text> 176 195 </Pressable> 177 196 </View> ··· 202 221 width: '100%', 203 222 height: '100%', 204 223 resizeMode: 'contain', 224 + }, 225 + aviCenterer: { 226 + flex: 1, 227 + alignItems: 'center', 228 + justifyContent: 'center', 229 + }, 230 + avi: { 231 + // @ts-ignore web-only 232 + maxWidth: `calc(min(400px, 100vw))`, 233 + // @ts-ignore web-only 234 + maxHeight: `calc(min(400px, 100vh))`, 235 + padding: 16, 236 + boxSizing: 'border-box', 205 237 }, 206 238 icon: { 207 239 color: colors.white,
+1
src/view/com/profile/ProfileSubpageHeader.tsx
··· 80 80 height: 1000, 81 81 width: 1000, 82 82 }, 83 + type: 'rect-avi', 83 84 }, 84 85 ], 85 86 index: 0,
+4 -1
src/view/com/util/post-embeds/index.tsx
··· 152 152 thumbDims: MeasuredDimensions | null, 153 153 ) => { 154 154 openLightbox({ 155 - images: items, 155 + images: items.map(item => ({ 156 + ...item, 157 + type: 'image', 158 + })), 156 159 index, 157 160 thumbDims, 158 161 })