Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Merge pull request #3337 from bluesky-social/samuel/scrollable-loggedoutlayout

Move scrollview to `LoggedOutLayout` to fix scrolling on web

authored by

Samuel Newman and committed by
GitHub
b27a0b8c 772d5281

+95 -81
+10 -31
src/screens/Login/FormContainer.tsx
··· 1 1 import React from 'react' 2 - import { 3 - ScrollView, 4 - type StyleProp, 5 - StyleSheet, 6 - View, 7 - type ViewStyle, 8 - } from 'react-native' 2 + import {type StyleProp, View, type ViewStyle} from 'react-native' 9 3 10 - import {isWeb} from '#/platform/detection' 11 4 import {atoms as a, useBreakpoints, useTheme} from '#/alf' 12 5 import {Text} from '#/components/Typography' 13 6 ··· 16 9 title, 17 10 children, 18 11 style, 19 - contentContainerStyle, 20 12 }: { 21 13 testID?: string 22 14 title?: React.ReactNode 23 15 children: React.ReactNode 24 16 style?: StyleProp<ViewStyle> 25 - contentContainerStyle?: StyleProp<ViewStyle> 26 17 }) { 27 18 const {gtMobile} = useBreakpoints() 28 19 const t = useTheme() 29 20 return ( 30 - <ScrollView 21 + <View 31 22 testID={testID} 32 - style={[styles.maxHeight, contentContainerStyle]} 33 - keyboardShouldPersistTaps="handled"> 34 - <View 35 - style={[a.gap_md, a.flex_1, !gtMobile && [a.px_lg, a.pt_md], style]}> 36 - {title && !gtMobile && ( 37 - <Text style={[a.text_xl, a.font_bold, t.atoms.text_contrast_high]}> 38 - {title} 39 - </Text> 40 - )} 41 - {children} 42 - </View> 43 - </ScrollView> 23 + style={[a.gap_md, a.flex_1, !gtMobile && [a.px_lg, a.py_md], style]}> 24 + {title && !gtMobile && ( 25 + <Text style={[a.text_xl, a.font_bold, t.atoms.text_contrast_high]}> 26 + {title} 27 + </Text> 28 + )} 29 + {children} 30 + </View> 44 31 ) 45 32 } 46 - 47 - const styles = StyleSheet.create({ 48 - maxHeight: { 49 - // @ts-ignore web only -prf 50 - maxHeight: isWeb ? '100vh' : undefined, 51 - height: !isWeb ? '100%' : undefined, 52 - }, 53 - })
+5 -1
src/screens/Login/index.tsx
··· 164 164 165 165 return ( 166 166 <KeyboardAvoidingView testID="signIn" behavior="padding" style={a.flex_1}> 167 - <LoggedOutLayout leadin="" title={title} description={description}> 167 + <LoggedOutLayout 168 + leadin="" 169 + title={title} 170 + description={description} 171 + scrollable> 168 172 <LayoutAnimationConfig skipEntering skipExiting> 169 173 <ScreenTransition key={currentForm}>{content}</ScreenTransition> 170 174 </LayoutAnimationConfig>
+9 -24
src/screens/Signup/StepCaptcha/index.tsx
··· 1 1 import React from 'react' 2 - import {ActivityIndicator, StyleSheet, View} from 'react-native' 2 + import {ActivityIndicator, View} from 'react-native' 3 3 import {msg} from '@lingui/macro' 4 4 import {useLingui} from '@lingui/react' 5 5 import {nanoid} from 'nanoid/non-secure' 6 6 7 7 import {createFullHandle} from '#/lib/strings/handles' 8 - import {isWeb} from '#/platform/detection' 9 8 import {ScreenTransition} from '#/screens/Login/ScreenTransition' 10 9 import {useSignupContext, useSubmitSignup} from '#/screens/Signup/state' 11 10 import {CaptchaWebView} from '#/screens/Signup/StepCaptcha/CaptchaWebView' ··· 54 53 return ( 55 54 <ScreenTransition> 56 55 <View style={[a.gap_lg]}> 57 - <View style={[styles.container, completed && styles.center]}> 56 + <View 57 + style={[ 58 + a.w_full, 59 + a.pb_xl, 60 + a.overflow_hidden, 61 + {minHeight: 500}, 62 + completed && [a.align_center, a.justify_center], 63 + ]}> 58 64 {!completed ? ( 59 65 <CaptchaWebView 60 66 url={url} ··· 72 78 </ScreenTransition> 73 79 ) 74 80 } 75 - 76 - const styles = StyleSheet.create({ 77 - error: { 78 - borderRadius: 6, 79 - marginTop: 10, 80 - }, 81 - // @ts-expect-error: Suppressing error due to incomplete `ViewStyle` type definition in react-native-web, missing `cursor` prop as discussed in https://github.com/necolas/react-native-web/issues/832. 82 - touchable: { 83 - ...(isWeb && {cursor: 'pointer'}), 84 - }, 85 - container: { 86 - minHeight: 500, 87 - width: '100%', 88 - paddingBottom: 20, 89 - overflow: 'hidden', 90 - }, 91 - center: { 92 - alignItems: 'center', 93 - justifyContent: 'center', 94 - }, 95 - })
+24 -17
src/screens/Signup/index.tsx
··· 1 1 import React from 'react' 2 - import {ScrollView, View} from 'react-native' 2 + import {View} from 'react-native' 3 + import {LayoutAnimationConfig} from 'react-native-reanimated' 3 4 import {msg, Trans} from '@lingui/macro' 4 5 import {useLingui} from '@lingui/react' 5 6 ··· 20 21 import {StepCaptcha} from '#/screens/Signup/StepCaptcha' 21 22 import {StepHandle} from '#/screens/Signup/StepHandle' 22 23 import {StepInfo} from '#/screens/Signup/StepInfo' 23 - import {atoms as a, useTheme} from '#/alf' 24 + import {atoms as a, useBreakpoints, useTheme} from '#/alf' 24 25 import {Button, ButtonText} from '#/components/Button' 25 26 import {Divider} from '#/components/Divider' 26 27 import {InlineLink} from '#/components/Link' ··· 32 33 const {screen} = useAnalytics() 33 34 const [state, dispatch] = React.useReducer(reducer, initialState) 34 35 const submit = useSubmitSignup({state, dispatch}) 36 + const {gtMobile} = useBreakpoints() 35 37 36 38 const { 37 39 data: serviceInfo, ··· 125 127 <LoggedOutLayout 126 128 leadin="" 127 129 title={_(msg`Create Account`)} 128 - description={_(msg`We're so excited to have you join us!`)}> 129 - <ScrollView 130 - testID="createAccount" 131 - keyboardShouldPersistTaps="handled" 132 - style={a.h_full} 133 - keyboardDismissMode="on-drag"> 134 - <View style={[a.flex_1, a.px_xl, a.pt_2xl, {paddingBottom: 100}]}> 130 + description={_(msg`We're so excited to have you join us!`)} 131 + scrollable> 132 + <View testID="createAccount" style={a.flex_1}> 133 + <View 134 + style={[ 135 + a.flex_1, 136 + a.px_xl, 137 + a.pt_2xl, 138 + !gtMobile && {paddingBottom: 100}, 139 + ]}> 135 140 <View style={[a.gap_sm, a.pb_3xl]}> 136 141 <Text style={[a.font_semibold, t.atoms.text_contrast_medium]}> 137 142 <Trans>Step</Trans> {state.activeStep + 1} <Trans>of</Trans>{' '} ··· 152 157 </View> 153 158 154 159 <View style={[a.pb_3xl]}> 155 - {state.activeStep === SignupStep.INFO ? ( 156 - <StepInfo /> 157 - ) : state.activeStep === SignupStep.HANDLE ? ( 158 - <StepHandle /> 159 - ) : ( 160 - <StepCaptcha /> 161 - )} 160 + <LayoutAnimationConfig skipEntering skipExiting> 161 + {state.activeStep === SignupStep.INFO ? ( 162 + <StepInfo /> 163 + ) : state.activeStep === SignupStep.HANDLE ? ( 164 + <StepHandle /> 165 + ) : ( 166 + <StepCaptcha /> 167 + )} 168 + </LayoutAnimationConfig> 162 169 </View> 163 170 164 171 <View style={[a.flex_row, a.justify_between, a.pb_lg]}> ··· 208 215 </Text> 209 216 </View> 210 217 </View> 211 - </ScrollView> 218 + </View> 212 219 </LoggedOutLayout> 213 220 </SignupContext.Provider> 214 221 )
+47 -8
src/view/com/util/layouts/LoggedOutLayout.tsx
··· 1 1 import React from 'react' 2 - import {StyleSheet, View} from 'react-native' 3 - import {Text} from '../text/Text' 2 + import {ScrollView, StyleSheet, View} from 'react-native' 3 + 4 + import {isWeb} from '#/platform/detection' 5 + import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle' 4 6 import {usePalette} from 'lib/hooks/usePalette' 5 7 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 6 - import {useColorSchemeStyle} from 'lib/hooks/useColorSchemeStyle' 8 + import {atoms as a} from '#/alf' 9 + import {Text} from '../text/Text' 7 10 8 11 export const LoggedOutLayout = ({ 9 12 leadin, 10 13 title, 11 14 description, 12 15 children, 16 + scrollable, 13 17 }: React.PropsWithChildren<{ 14 18 leadin: string 15 19 title: string 16 20 description: string 21 + scrollable?: boolean 17 22 }>) => { 18 23 const {isMobile, isTabletOrMobile} = useWebMediaQueries() 19 24 const pal = usePalette('default') ··· 25 30 }) 26 31 27 32 if (isMobile) { 28 - return <View style={{paddingTop: 10}}>{children}</View> 33 + if (scrollable) { 34 + return ( 35 + <ScrollView 36 + style={styles.scrollview} 37 + keyboardShouldPersistTaps="handled" 38 + keyboardDismissMode="on-drag"> 39 + <View style={a.pt_md}>{children}</View> 40 + </ScrollView> 41 + ) 42 + } else { 43 + return <View style={a.pt_md}>{children}</View> 44 + } 29 45 } 30 46 return ( 31 47 <View style={styles.container}> ··· 50 66 {description} 51 67 </Text> 52 68 </View> 53 - <View style={[styles.content, contentBg]}> 54 - <View style={styles.contentWrapper}>{children}</View> 55 - </View> 69 + {scrollable ? ( 70 + <View style={[styles.scrollableContent, contentBg]}> 71 + <ScrollView 72 + style={styles.scrollview} 73 + contentContainerStyle={styles.scrollViewContentContainer} 74 + keyboardShouldPersistTaps="handled" 75 + keyboardDismissMode="on-drag"> 76 + <View style={[styles.contentWrapper, isWeb && a.my_auto]}> 77 + {children} 78 + </View> 79 + </ScrollView> 80 + </View> 81 + ) : ( 82 + <View style={[styles.content, contentBg]}> 83 + <View style={styles.contentWrapper}>{children}</View> 84 + </View> 85 + )} 56 86 </View> 57 87 ) 58 88 } ··· 74 104 paddingHorizontal: 40, 75 105 justifyContent: 'center', 76 106 }, 77 - 107 + scrollableContent: { 108 + flex: 2, 109 + }, 110 + scrollview: { 111 + flex: 1, 112 + }, 113 + scrollViewContentContainer: { 114 + flex: 1, 115 + paddingHorizontal: 40, 116 + }, 78 117 leadinText: { 79 118 fontSize: 36, 80 119 fontWeight: '800',