Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

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

at cb7e2ab976d9e2e8e2d13356b79bba7e6870a9fd 152 lines 4.6 kB view raw
1import {useState} from 'react' 2import {View} from 'react-native' 3import {msg, Trans} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5 6import {wait} from '#/lib/async/wait' 7import {isNetworkError, useCleanError} from '#/lib/hooks/useCleanError' 8import {logger} from '#/logger' 9import {atoms as a, useTheme, web} from '#/alf' 10import {Admonition} from '#/components/Admonition' 11import {Button, ButtonIcon, ButtonText} from '#/components/Button' 12import * as Dialog from '#/components/Dialog' 13import {PinLocation_Stroke2_Corner0_Rounded as LocationIcon} from '#/components/icons/PinLocation' 14import {Loader} from '#/components/Loader' 15import {Text} from '#/components/Typography' 16import {IS_WEB} from '#/env' 17import {type Geolocation, useRequestDeviceGeolocation} from '#/geolocation' 18 19export type Props = { 20 onLocationAcquired?: (props: { 21 geolocation: Geolocation 22 setDialogError: (error: string) => void 23 disableDialogAction: () => void 24 closeDialog: (callback?: () => void) => void 25 }) => void 26} 27 28export function DeviceLocationRequestDialog({ 29 control, 30 onLocationAcquired, 31}: Props & { 32 control: Dialog.DialogOuterProps['control'] 33}) { 34 const {_} = useLingui() 35 return ( 36 <Dialog.Outer control={control}> 37 <Dialog.Handle /> 38 39 <Dialog.ScrollableInner 40 label={_(msg`Confirm your location`)} 41 style={[web({maxWidth: 380})]}> 42 <DeviceLocationRequestDialogInner 43 onLocationAcquired={onLocationAcquired} 44 /> 45 <Dialog.Close /> 46 </Dialog.ScrollableInner> 47 </Dialog.Outer> 48 ) 49} 50 51function DeviceLocationRequestDialogInner({onLocationAcquired}: Props) { 52 const t = useTheme() 53 const {_} = useLingui() 54 const {close} = Dialog.useDialogContext() 55 const requestDeviceLocation = useRequestDeviceGeolocation() 56 const cleanError = useCleanError() 57 58 const [isRequesting, setIsRequesting] = useState(false) 59 const [error, setError] = useState<string>('') 60 const [dialogDisabled, setDialogDisabled] = useState(false) 61 62 const onPressConfirm = async () => { 63 setError('') 64 setIsRequesting(true) 65 66 try { 67 const req = await wait(1e3, requestDeviceLocation()) 68 69 if (req.granted) { 70 const location = req.location 71 72 if (location && location.countryCode) { 73 onLocationAcquired?.({ 74 geolocation: location, 75 setDialogError: setError, 76 disableDialogAction: () => setDialogDisabled(true), 77 closeDialog: close, 78 }) 79 } else { 80 setError(_(msg`Failed to resolve location. Please try again.`)) 81 } 82 } else { 83 setError( 84 _( 85 msg`Unable to access location. You'll need to visit your system settings to enable location services for Bluesky.`, 86 ), 87 ) 88 } 89 } catch (e: any) { 90 const {clean, raw} = cleanError(e) 91 setError(clean || raw || e.message) 92 if (!isNetworkError(e)) { 93 logger.error(`blockedGeoOverlay: unexpected error`, { 94 safeMessage: e.message, 95 }) 96 } 97 } finally { 98 setIsRequesting(false) 99 } 100 } 101 102 return ( 103 <View style={[a.gap_md]}> 104 <Text style={[a.text_xl, a.font_bold]}> 105 <Trans>Confirm your location</Trans> 106 </Text> 107 <View style={[a.gap_sm, a.pb_xs]}> 108 <Text style={[a.text_md, a.leading_snug, t.atoms.text_contrast_medium]}> 109 <Trans> 110 Tap below to allow Bluesky to access your GPS location. We will then 111 use that data to more accurately determine the content and features 112 available in your region. 113 </Trans> 114 </Text> 115 </View> 116 117 {error && ( 118 <View style={[a.pb_xs]}> 119 <Admonition type="error">{error}</Admonition> 120 </View> 121 )} 122 123 <View style={[a.gap_sm]}> 124 {!dialogDisabled && ( 125 <Button 126 disabled={isRequesting} 127 label={_(msg`Allow location access`)} 128 onPress={onPressConfirm} 129 size={IS_WEB ? 'small' : 'large'} 130 color="primary"> 131 <ButtonIcon icon={isRequesting ? Loader : LocationIcon} /> 132 <ButtonText> 133 <Trans>Allow location access</Trans> 134 </ButtonText> 135 </Button> 136 )} 137 138 {!IS_WEB && ( 139 <Button 140 label={_(msg`Cancel`)} 141 onPress={() => close()} 142 size={IS_WEB ? 'small' : 'large'} 143 color="secondary"> 144 <ButtonText> 145 <Trans>Cancel</Trans> 146 </ButtonText> 147 </Button> 148 )} 149 </View> 150 </View> 151 ) 152}