diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Splash.android.tsx | 17 | ||||
-rw-r--r-- | src/alf/atoms.ts | 1 | ||||
-rw-r--r-- | src/components/Button.tsx | 73 | ||||
-rw-r--r-- | src/components/GradientFill.tsx | 10 | ||||
-rw-r--r-- | src/components/LinearGradientBackground.tsx | 6 | ||||
-rw-r--r-- | src/components/StarterPack/QrCode.tsx | 1 | ||||
-rw-r--r-- | src/lib/hooks/useNotificationHandler.ts | 12 | ||||
-rw-r--r-- | src/lib/hooks/usePermissions.ts | 4 | ||||
-rw-r--r-- | src/view/com/composer/photos/Gallery.tsx | 6 | ||||
-rw-r--r-- | src/view/com/util/forms/Button.tsx | 1 | ||||
-rw-r--r-- | src/view/com/util/forms/DropdownButton.tsx | 2 | ||||
-rw-r--r-- | src/view/com/util/forms/NativeDropdown.web.tsx | 1 |
12 files changed, 93 insertions, 41 deletions
diff --git a/src/Splash.android.tsx b/src/Splash.android.tsx new file mode 100644 index 000000000..a12b52b8b --- /dev/null +++ b/src/Splash.android.tsx @@ -0,0 +1,17 @@ +import {useEffect} from 'react' +import * as SplashScreen from 'expo-splash-screen' + +type Props = { + isReady: boolean +} + +export function Splash({isReady, children}: React.PropsWithChildren<Props>) { + useEffect(() => { + if (isReady) { + SplashScreen.hideAsync() + } + }, [isReady]) + if (isReady) { + return children + } +} diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index 0870c5767..ad4929ec8 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -68,6 +68,7 @@ export const atoms = { * Used for the outermost components on screens, to ensure that they can fill * the screen and extend beyond. */ + // @ts-ignore - web only minHeight string util_screen_outer: [ web({ minHeight: '100vh', diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 3329dca05..871c17ed5 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -405,37 +405,47 @@ export const Button = React.forwardRef<View, ButtonProps>( } }, [t, variant, color, size, shape, disabled]) - const {gradientColors, gradientHoverColors, gradientLocations} = - React.useMemo(() => { - const colors: string[] = [] - const hoverColors: string[] = [] - const locations: number[] = [] - const gradient = { - primary: tokens.gradients.sky, - secondary: tokens.gradients.sky, - secondary_inverted: tokens.gradients.sky, - negative: tokens.gradients.sky, - gradient_primary: tokens.gradients.primary, - gradient_sky: tokens.gradients.sky, - gradient_midnight: tokens.gradients.midnight, - gradient_sunrise: tokens.gradients.sunrise, - gradient_sunset: tokens.gradients.sunset, - gradient_nordic: tokens.gradients.nordic, - gradient_bonfire: tokens.gradients.bonfire, - }[color || 'primary'] - - if (variant === 'gradient') { - colors.push(...gradient.values.map(([_, color]) => color)) - hoverColors.push(...gradient.values.map(_ => gradient.hover_value)) - locations.push(...gradient.values.map(([location, _]) => location)) + const gradientValues = React.useMemo(() => { + const gradient = { + primary: tokens.gradients.sky, + secondary: tokens.gradients.sky, + secondary_inverted: tokens.gradients.sky, + negative: tokens.gradients.sky, + gradient_primary: tokens.gradients.primary, + gradient_sky: tokens.gradients.sky, + gradient_midnight: tokens.gradients.midnight, + gradient_sunrise: tokens.gradients.sunrise, + gradient_sunset: tokens.gradients.sunset, + gradient_nordic: tokens.gradients.nordic, + gradient_bonfire: tokens.gradients.bonfire, + }[color || 'primary'] + + if (variant === 'gradient') { + if (gradient.values.length < 2) { + throw new Error( + 'Gradient buttons must have at least two colors in the gradient', + ) } return { - gradientColors: colors, - gradientHoverColors: hoverColors, - gradientLocations: locations, + colors: gradient.values.map(([_, color]) => color) as [ + string, + string, + ...string[], + ], + hoverColors: gradient.values.map(_ => gradient.hover_value) as [ + string, + string, + ...string[], + ], + locations: gradient.values.map(([location, _]) => location) as [ + number, + number, + ...number[], + ], } - }, [variant, color]) + } + }, [variant, color]) const context = React.useMemo<ButtonContext>( () => ({ @@ -458,6 +468,7 @@ export const Button = React.forwardRef<View, ButtonProps>( // @ts-ignore - this will always be a pressable ref={ref} aria-label={label} + aria-pressed={state.pressed} accessibilityLabel={label} disabled={disabled || false} accessibilityState={{ @@ -478,7 +489,7 @@ export const Button = React.forwardRef<View, ButtonProps>( onHoverOut={onHoverOut} onFocus={onFocus} onBlur={onBlur}> - {variant === 'gradient' && ( + {variant === 'gradient' && gradientValues && ( <View style={[ a.absolute, @@ -489,10 +500,10 @@ export const Button = React.forwardRef<View, ButtonProps>( <LinearGradient colors={ state.hovered || state.pressed - ? gradientHoverColors - : gradientColors + ? gradientValues.hoverColors + : gradientValues.colors } - locations={gradientLocations} + locations={gradientValues.locations} start={{x: 0, y: 0}} end={{x: 1, y: 1}} style={[a.absolute, a.inset_0]} diff --git a/src/components/GradientFill.tsx b/src/components/GradientFill.tsx index fa39577d4..3dff404d7 100644 --- a/src/components/GradientFill.tsx +++ b/src/components/GradientFill.tsx @@ -14,10 +14,16 @@ export function GradientFill({ | typeof tokens.gradients.summer | typeof tokens.gradients.nordic }) { + if (gradient.values.length < 2) { + throw new Error('Gradient must have at least 2 colors') + } + return ( <LinearGradient - colors={gradient.values.map(c => c[1])} - locations={gradient.values.map(c => c[0])} + colors={gradient.values.map(c => c[1]) as [string, string, ...string[]]} + locations={ + gradient.values.map(c => c[0]) as [number, number, ...number[]] + } start={{x: 0, y: 0}} end={{x: 1, y: 1}} style={[a.absolute, a.inset_0]} diff --git a/src/components/LinearGradientBackground.tsx b/src/components/LinearGradientBackground.tsx index f516b19f5..724df43f3 100644 --- a/src/components/LinearGradientBackground.tsx +++ b/src/components/LinearGradientBackground.tsx @@ -13,7 +13,11 @@ export function LinearGradientBackground({ }) { const gradient = gradients.sky.values.map(([_, color]) => { return color - }) + }) as [string, string, ...string[]] + + if (gradient.length < 2) { + throw new Error('Gradient must have at least 2 colors') + } return ( <LinearGradient colors={gradient} style={style}> diff --git a/src/components/StarterPack/QrCode.tsx b/src/components/StarterPack/QrCode.tsx index c6408109b..515a9059a 100644 --- a/src/components/StarterPack/QrCode.tsx +++ b/src/components/StarterPack/QrCode.tsx @@ -1,5 +1,6 @@ import React from 'react' import {View} from 'react-native' +// @ts-expect-error missing types import QRCode from 'react-native-qrcode-styled' import type ViewShot from 'react-native-view-shot' import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api' diff --git a/src/lib/hooks/useNotificationHandler.ts b/src/lib/hooks/useNotificationHandler.ts index 625ec9e6a..69ae536d0 100644 --- a/src/lib/hooks/useNotificationHandler.ts +++ b/src/lib/hooks/useNotificationHandler.ts @@ -177,7 +177,14 @@ export function useNotificationsHandler() { Notifications.setNotificationHandler({ handleNotification: async e => { - if (e.request.trigger.type !== 'push') return DEFAULT_HANDLER_OPTIONS + if ( + e.request.trigger == null || + typeof e.request.trigger !== 'object' || + !('type' in e.request.trigger) || + e.request.trigger.type !== 'push' + ) { + return DEFAULT_HANDLER_OPTIONS + } logger.debug( 'Notifications: received', @@ -220,6 +227,9 @@ export function useNotificationsHandler() { if ( e.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER && + e.notification.request.trigger != null && + typeof e.notification.request.trigger === 'object' && + 'type' in e.notification.request.trigger && e.notification.request.trigger.type === 'push' ) { logger.debug( diff --git a/src/lib/hooks/usePermissions.ts b/src/lib/hooks/usePermissions.ts index 6da14232f..af4358c78 100644 --- a/src/lib/hooks/usePermissions.ts +++ b/src/lib/hooks/usePermissions.ts @@ -1,5 +1,5 @@ import {Linking} from 'react-native' -import {Camera} from 'expo-camera/legacy' // TODO: Migrate to the new one. +import {useCameraPermissions as useExpoCameraPermissions} from 'expo-camera' import * as MediaLibrary from 'expo-media-library' import {isWeb} from '#/platform/detection' @@ -78,7 +78,7 @@ export function useVideoLibraryPermission() { } export function useCameraPermission() { - const [res, requestPermission] = Camera.useCameraPermissions() + const [res, requestPermission] = useExpoCameraPermissions() const requestCameraAccessIfNeeded = async () => { if (res?.granted) { diff --git a/src/view/com/composer/photos/Gallery.tsx b/src/view/com/composer/photos/Gallery.tsx index af784b4f6..bc18c81f1 100644 --- a/src/view/com/composer/photos/Gallery.tsx +++ b/src/view/com/composer/photos/Gallery.tsx @@ -124,7 +124,7 @@ type GalleryItemProps = { image: ComposerImage altTextControlStyle?: ViewStyle imageControlsStyle?: ViewStyle - imageStyle?: ViewStyle + imageStyle?: ImageStyle onChange: (next: ComposerImage) => void onRemove: () => void } @@ -160,7 +160,7 @@ const GalleryItem = ({ return ( <View - style={imageStyle} + style={imageStyle as ViewStyle} // Fixes ALT and icons appearing with half opacity when the post is inactive renderToHardwareTextureAndroid> <TouchableOpacity @@ -221,7 +221,7 @@ const GalleryItem = ({ <Image testID="selectedPhotoImage" - style={[styles.image, imageStyle] as ImageStyle} + style={[styles.image, imageStyle]} source={{ uri: (image.transformed ?? image.source).path, }} diff --git a/src/view/com/util/forms/Button.tsx b/src/view/com/util/forms/Button.tsx index 62ef2c4f1..96b49a003 100644 --- a/src/view/com/util/forms/Button.tsx +++ b/src/view/com/util/forms/Button.tsx @@ -31,6 +31,7 @@ export type ButtonType = // Augment type for react-native-web (see https://github.com/necolas/react-native-web/issues/1684#issuecomment-766451866) declare module 'react-native' { interface PressableStateCallbackType { + // @ts-ignore web only hovered?: boolean focused?: boolean } diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx index f0751e45b..6cb4b9557 100644 --- a/src/view/com/util/forms/DropdownButton.tsx +++ b/src/view/com/util/forms/DropdownButton.tsx @@ -87,7 +87,7 @@ export function DropdownButton({ }: PropsWithChildren<DropdownButtonProps>) { const {_} = useLingui() - const ref1 = useRef<TouchableOpacity>(null) + const ref1 = useRef<View>(null) const ref2 = useRef<View>(null) const onPress = (e: GestureResponderEvent) => { diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index 364e10d10..c1a0b8096 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -229,6 +229,7 @@ const getKey = (label: string, index: number, id?: string) => { return `${label}_${index}` } +// @ts-expect-error - web only styles. the only style that should be broken here is `outline` const styles = StyleSheet.create({ separator: { height: 1, |