Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Merge branch 'improved-lightbox' into main

+13 -144
+1 -5
src/state/models/shell-ui.ts
··· 99 99 | ReportAccountModal 100 100 | undefined 101 101 isLightboxActive = false 102 - activeLightbox: 103 - | ProfileImageLightbox 104 - | ImageLightbox 105 - | ImagesLightbox 106 - | undefined 102 + activeLightbox: ProfileImageLightbox | ImagesLightbox | undefined 107 103 isComposerActive = false 108 104 composerOpts: ComposerOpts | undefined 109 105
-24
src/view/com/lightbox/Image.tsx
··· 1 - import React from 'react' 2 - import {Image, StyleSheet, useWindowDimensions, View} from 'react-native' 3 - 4 - export function Component({uri}: {uri: string}) { 5 - const winDim = useWindowDimensions() 6 - const top = winDim.height / 2 - (winDim.width - 40) / 2 - 100 7 - return ( 8 - <View style={[styles.container, {top}]}> 9 - <Image style={styles.image} source={{uri}} /> 10 - </View> 11 - ) 12 - } 13 - 14 - const styles = StyleSheet.create({ 15 - container: { 16 - position: 'absolute', 17 - left: 0, 18 - }, 19 - image: { 20 - resizeMode: 'contain', 21 - width: '100%', 22 - aspectRatio: 1, 23 - }, 24 - })
-64
src/view/com/lightbox/Images.tsx
··· 1 - import React from 'react' 2 - import { 3 - ActivityIndicator, 4 - Image, 5 - StyleSheet, 6 - useWindowDimensions, 7 - View, 8 - } from 'react-native' 9 - 10 - export function Component({ 11 - uris, 12 - index, 13 - isZooming, 14 - }: { 15 - uris: string[] 16 - index: number 17 - isZooming: boolean 18 - }) { 19 - const winDim = useWindowDimensions() 20 - const left = index * winDim.width * -1 21 - const spinnerStyle = React.useMemo( 22 - () => ({ 23 - left: winDim.width / 2 - 20, 24 - top: winDim.height / 2 - 50, 25 - }), 26 - [winDim.width, winDim.height], 27 - ) 28 - return ( 29 - <View style={[styles.container, {left}]}> 30 - <ActivityIndicator style={[styles.loading, spinnerStyle]} size="large" /> 31 - {uris.map((uri, i) => ( 32 - <Image 33 - key={i} 34 - style={[ 35 - styles.image, 36 - {left: i * winDim.width}, 37 - isZooming && i !== index ? {opacity: 0} : undefined, 38 - ]} 39 - source={{uri}} 40 - /> 41 - ))} 42 - </View> 43 - ) 44 - } 45 - 46 - const styles = StyleSheet.create({ 47 - container: { 48 - position: 'absolute', 49 - top: 0, 50 - left: 0, 51 - width: '100%', 52 - }, 53 - loading: { 54 - position: 'absolute', 55 - }, 56 - image: { 57 - position: 'absolute', 58 - top: 200, 59 - left: 0, 60 - resizeMode: 'contain', 61 - width: '100%', 62 - aspectRatio: 1, 63 - }, 64 - })
-42
src/view/com/lightbox/ProfileImage.tsx
··· 1 - import React from 'react' 2 - import { 3 - ActivityIndicator, 4 - StyleSheet, 5 - useWindowDimensions, 6 - View, 7 - } from 'react-native' 8 - import {UserAvatar} from '../util/UserAvatar' 9 - import {ProfileViewModel} from '../../../state/models/profile-view' 10 - 11 - export function Component({profileView}: {profileView: ProfileViewModel}) { 12 - const winDim = useWindowDimensions() 13 - const top = winDim.height / 2 - (winDim.width - 40) / 2 - 100 14 - const spinnerStyle = React.useMemo( 15 - () => ({ 16 - left: winDim.width / 2 - 30, 17 - top: winDim.height / 2 - (winDim.width - 40) / 2 - 80, 18 - }), 19 - [winDim.width, winDim.height], 20 - ) 21 - return ( 22 - <View style={[styles.container, {top}]}> 23 - <ActivityIndicator style={[styles.loading, spinnerStyle]} size="large" /> 24 - <UserAvatar 25 - handle={profileView.handle} 26 - displayName={profileView.displayName} 27 - avatar={profileView.avatar} 28 - size={winDim.width - 40} 29 - /> 30 - </View> 31 - ) 32 - } 33 - 34 - const styles = StyleSheet.create({ 35 - container: { 36 - position: 'absolute', 37 - left: 20, 38 - }, 39 - loading: { 40 - position: 'absolute', 41 - }, 42 - })
+12 -9
src/view/shell/mobile/index.tsx
··· 127 127 const scrollElRef = useRef<FlatList | undefined>() 128 128 const winDim = useWindowDimensions() 129 129 const [menuSwipingDirection, setMenuSwipingDirection] = useState(0) 130 + const constZeroInterp = useAnimatedValue(0) 130 131 const swipeGestureInterp = useAnimatedValue(0) 131 132 const minimalShellInterp = useAnimatedValue(0) 132 133 const tabMenuInterp = useAnimatedValue(0) ··· 279 280 const swipeTransform = store.nav.tab.canGoBack 280 281 ? {transform: [{translateX: swipeTranslateX}]} 281 282 : undefined 283 + let shouldRenderMenu = false 282 284 let menuTranslateX 283 285 const menuDrawerWidth = winDim.width - 100 284 286 if (isMenuActive) { 285 287 // menu is active, interpret swipes as closes 286 288 menuTranslateX = Animated.multiply(swipeGestureInterp, menuDrawerWidth * -1) 289 + shouldRenderMenu = true 287 290 } else if (!store.nav.tab.canGoBack) { 288 291 // at back of history, interpret swipes as opens 289 292 menuTranslateX = Animated.subtract( 290 293 menuDrawerWidth * -1, 291 294 Animated.multiply(swipeGestureInterp, menuDrawerWidth), 292 295 ) 293 - } else { 294 - // not at back of history, leave off screen 295 - menuTranslateX = menuDrawerWidth * -1 296 + shouldRenderMenu = true 296 297 } 297 298 const menuSwipeTransform = { 298 299 transform: [{translateX: menuTranslateX}], ··· 425 426 <Animated.View style={[styles.screenMask, menuSwipeOpacity]} /> 426 427 </TouchableWithoutFeedback> 427 428 ) : undefined} 428 - <Animated.View style={[styles.menuDrawer, menuSwipeTransform]}> 429 - <Menu 430 - visible={isMenuActive} 431 - onClose={() => store.shell.setMainMenuOpen(false)} 432 - /> 433 - </Animated.View> 429 + {shouldRenderMenu && ( 430 + <Animated.View style={[styles.menuDrawer, menuSwipeTransform]}> 431 + <Menu 432 + visible={isMenuActive} 433 + onClose={() => store.shell.setMainMenuOpen(false)} 434 + /> 435 + </Animated.View> 436 + )} 434 437 </HorzSwipe> 435 438 </View> 436 439 {isTabsSelectorActive ? (