An ATproto social media client -- with an independent Appview.

Upgrade `@types/react` to 19 and run codemod (attempt 2) (#8918)

* update dependencies

* rm `import type React from 'react'`

* run codemods

* patch discord types

* update types/react-dom

* Update yarn.lock

authored by samuel.fm and committed by

GitHub 3e2c181c d496a223

+157 -143
+3 -4
package.json
··· 213 "react-native-web-webview": "^1.0.2", 214 "react-native-webview": "^13.13.5", 215 "react-remove-scroll-bar": "^2.3.8", 216 - "react-responsive": "^9.0.2", 217 "react-textarea-autosize": "^8.5.3", 218 "sonner": "^2.0.7", 219 "sonner-native": "^0.21.0", ··· 245 "@types/lodash.isequal": "^4.5.6", 246 "@types/lodash.shuffle": "^4.2.7", 247 "@types/psl": "^1.1.1", 248 - "@types/react-dom": "^19.1.2", 249 - "@types/react-responsive": "^8.0.5", 250 "@typescript-eslint/eslint-plugin": "^7.18.0", 251 "@typescript-eslint/parser": "^7.18.0", 252 "babel-jest": "^29.7.0", ··· 284 "@expo/image-utils": "0.6.3", 285 "@react-native/babel-preset": "0.79.3", 286 "@react-native/normalize-colors": "0.79.3", 287 - "@types/react": "^18", 288 "**/expo-constants": "17.0.3", 289 "**/expo-device": "7.1.4", 290 "**/zod": "3.23.8",
··· 213 "react-native-web-webview": "^1.0.2", 214 "react-native-webview": "^13.13.5", 215 "react-remove-scroll-bar": "^2.3.8", 216 + "react-responsive": "^10.0.1", 217 "react-textarea-autosize": "^8.5.3", 218 "sonner": "^2.0.7", 219 "sonner-native": "^0.21.0", ··· 245 "@types/lodash.isequal": "^4.5.6", 246 "@types/lodash.shuffle": "^4.2.7", 247 "@types/psl": "^1.1.1", 248 + "@types/react": "^19.1.12", 249 + "@types/react-dom": "^19.1.8", 250 "@typescript-eslint/eslint-plugin": "^7.18.0", 251 "@typescript-eslint/parser": "^7.18.0", 252 "babel-jest": "^29.7.0", ··· 284 "@expo/image-utils": "0.6.3", 285 "@react-native/babel-preset": "0.79.3", 286 "@react-native/normalize-colors": "0.79.3", 287 "**/expo-constants": "17.0.3", 288 "**/expo-device": "7.1.4", 289 "**/zod": "3.23.8",
+13
patches/@discord+bottom-sheet+4.6.1.patch
···
··· 1 + diff --git a/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts b/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts 2 + index 1c788ab..d30f330 100644 3 + --- a/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts 4 + +++ b/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts 5 + @@ -6,7 +6,7 @@ type Callback = (...args: any[]) => any; 6 + * https://gist.github.com/JakeCoxon/c7ebf6e6496f8468226fd36b596e1985 7 + */ 8 + export const useStableCallback = (callback: Callback) => { 9 + - const callbackRef = useRef<Callback>(); 10 + + const callbackRef = useRef<Callback>(undefined); 11 + const memoCallback = useCallback( 12 + (...args: any) => callbackRef.current && callbackRef.current(...args), 13 + []
+1 -1
src/Navigation.tsx
··· 1 - import {useCallback, useRef} from 'react' 2 import {Linking} from 'react-native' 3 import * as Notifications from 'expo-notifications' 4 import {i18n, type MessageDescriptor} from '@lingui/core'
··· 1 + import {type JSX, useCallback, useRef} from 'react' 2 import {Linking} from 'react-native' 3 import * as Notifications from 'expo-notifications' 4 import {i18n, type MessageDescriptor} from '@lingui/core'
-1
src/alf/typography.tsx
··· 3 import {type StyleProp, type TextStyle} from 'react-native' 4 import {UITextView} from 'react-native-uitextview' 5 import createEmojiRegex from 'emoji-regex' 6 - import type React from 'react' 7 8 import {isNative} from '#/platform/detection' 9 import {isIOS} from '#/platform/detection'
··· 3 import {type StyleProp, type TextStyle} from 'react-native' 4 import {UITextView} from 'react-native-uitextview' 5 import createEmojiRegex from 'emoji-regex' 6 7 import {isNative} from '#/platform/detection' 8 import {isIOS} from '#/platform/detection'
+2 -2
src/components/Button.tsx
··· 71 export type ButtonContext = VariantProps & ButtonState 72 73 type NonTextElements = 74 - | React.ReactElement 75 - | Iterable<React.ReactElement | null | undefined | boolean> 76 77 export type ButtonProps = Pick< 78 PressableProps,
··· 71 export type ButtonContext = VariantProps & ButtonState 72 73 type NonTextElements = 74 + | React.ReactElement<any> 75 + | Iterable<React.ReactElement<any> | null | undefined | boolean> 76 77 export type ButtonProps = Pick< 78 PressableProps,
+2 -1
src/components/ContextMenu/index.tsx
··· 119 const hoverablesSV = useSharedValue< 120 Record<string, {id: string; rect: Measurement}> 121 >({}) 122 - const syncHoverablesThrottleRef = useRef<ReturnType<typeof setTimeout>>() 123 const [hoveredMenuItem, setHoveredMenuItem] = useState<string | null>(null) 124 125 const onHoverableTouchUp = useCallback((id: string) => {
··· 119 const hoverablesSV = useSharedValue< 120 Record<string, {id: string; rect: Measurement}> 121 >({}) 122 + const syncHoverablesThrottleRef = 123 + useRef<ReturnType<typeof setTimeout>>(undefined) 124 const [hoveredMenuItem, setHoveredMenuItem] = useState<string | null>(null) 125 126 const onHoverableTouchUp = useCallback((id: string) => {
-1
src/components/ContextMenu/types.ts
··· 5 type ViewStyle, 6 } from 'react-native' 7 import {type SharedValue} from 'react-native-reanimated' 8 - import type React from 'react' 9 10 import type * as Dialog from '#/components/Dialog' 11 import {
··· 5 type ViewStyle, 6 } from 'react-native' 7 import {type SharedValue} from 'react-native-reanimated' 8 9 import type * as Dialog from '#/components/Dialog' 10 import {
+1 -2
src/components/Dialog/types.ts
··· 5 type StyleProp, 6 type ViewStyle, 7 } from 'react-native' 8 - import type React from 'react' 9 10 import {type ViewStyleProp} from '#/alf' 11 import {type BottomSheetViewProps} from '../../../modules/bottom-sheet' ··· 34 */ 35 export type DialogControlProps = DialogControlRefProps & { 36 id: string 37 - ref: React.RefObject<DialogControlRefProps> 38 isOpen?: boolean 39 } 40
··· 5 type StyleProp, 6 type ViewStyle, 7 } from 'react-native' 8 9 import {type ViewStyleProp} from '#/alf' 10 import {type BottomSheetViewProps} from '../../../modules/bottom-sheet' ··· 33 */ 34 export type DialogControlProps = DialogControlRefProps & { 35 id: string 36 + ref: React.RefObject<DialogControlRefProps | null> 37 isOpen?: boolean 38 } 39
-1
src/components/Lists.tsx
··· 2 import {type StyleProp, View, type ViewStyle} from 'react-native' 3 import {msg, Trans} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 - import type React from 'react' 6 7 import {cleanError} from '#/lib/strings/errors' 8 import {CenteredView} from '#/view/com/util/Views'
··· 2 import {type StyleProp, View, type ViewStyle} from 'react-native' 3 import {msg, Trans} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 6 import {cleanError} from '#/lib/strings/errors' 7 import {CenteredView} from '#/view/com/util/Views'
+1 -1
src/components/Portal.tsx
··· 10 useState, 11 } from 'react' 12 13 - type Component = React.ReactElement 14 15 type ContextType = { 16 outlet: Component | null
··· 10 useState, 11 } from 'react' 12 13 + type Component = React.ReactElement<any> 14 15 type ContextType = { 16 outlet: Component | null
+1 -1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx
··· 139 playlist: string 140 setHasSubtitleTrack: (v: boolean) => void 141 setError: (v: Error | null) => void 142 - videoRef: React.RefObject<HTMLVideoElement> 143 setHlsLoading: (v: boolean) => void 144 }) { 145 const [Hls, setHls] = useState<typeof HlsTypes.default | undefined>(
··· 139 playlist: string 140 setHasSubtitleTrack: (v: boolean) => void 141 setError: (v: Error | null) => void 142 + videoRef: React.RefObject<HTMLVideoElement | null> 143 setHlsLoading: (v: boolean) => void 144 }) { 145 const [Hls, setHls] = useState<typeof HlsTypes.default | undefined>(
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx
··· 1 import {View} from 'react-native' 2 import {msg, Trans} from '@lingui/macro' 3 import {useLingui} from '@lingui/react' 4 - import type React from 'react' 5 6 import {atoms as a, useTheme} from '#/alf' 7 import {Button, ButtonText} from '#/components/Button'
··· 1 import {View} from 'react-native' 2 import {msg, Trans} from '@lingui/macro' 3 import {useLingui} from '@lingui/react' 4 5 import {atoms as a, useTheme} from '#/alf' 6 import {Button, ButtonText} from '#/components/Button'
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx
··· 1 import {type SvgProps} from 'react-native-svg' 2 - import type React from 'react' 3 4 import {PressableWithHover} from '#/view/com/util/PressableWithHover' 5 import {atoms as a, useTheme, web} from '#/alf'
··· 1 import {type SvgProps} from 'react-native-svg' 2 3 import {PressableWithHover} from '#/view/com/util/PressableWithHover' 4 import {atoms as a, useTheme, web} from '#/alf'
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx
··· 2 import {View} from 'react-native' 3 import {msg} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 - import type React from 'react' 6 7 import {isFirefox, isTouchDevice} from '#/lib/browser' 8 import {clamp} from '#/lib/numbers'
··· 2 import {View} from 'react-native' 3 import {msg} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 6 import {isFirefox, isTouchDevice} from '#/lib/browser' 7 import {clamp} from '#/lib/numbers'
+5 -5
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx
··· 46 hlsLoading, 47 hasSubtitleTrack, 48 }: { 49 - videoRef: React.RefObject<HTMLVideoElement> 50 - hlsRef: React.RefObject<Hls | undefined> 51 active: boolean 52 setActive: () => void 53 focused: boolean 54 setFocused: (focused: boolean) => void 55 onScreen: boolean 56 - fullscreenRef: React.RefObject<HTMLDivElement> 57 hlsLoading: boolean 58 hasSubtitleTrack: boolean 59 }) { ··· 232 }, [onSeek, videoRef]) 233 234 const [showCursor, setShowCursor] = useState(true) 235 - const cursorTimeoutRef = useRef<ReturnType<typeof setTimeout>>() 236 const onPointerMoveEmptySpace = useCallback(() => { 237 setShowCursor(true) 238 if (cursorTimeoutRef.current) { ··· 264 [hovered], 265 ) 266 267 - const timeoutRef = useRef<ReturnType<typeof setTimeout>>() 268 269 const onHoverWithTimeout = useCallback(() => { 270 onHover()
··· 46 hlsLoading, 47 hasSubtitleTrack, 48 }: { 49 + videoRef: React.RefObject<HTMLVideoElement | null> 50 + hlsRef: React.RefObject<Hls | undefined | null> 51 active: boolean 52 setActive: () => void 53 focused: boolean 54 setFocused: (focused: boolean) => void 55 onScreen: boolean 56 + fullscreenRef: React.RefObject<HTMLDivElement | null> 57 hlsLoading: boolean 58 hasSubtitleTrack: boolean 59 }) { ··· 232 }, [onSeek, videoRef]) 233 234 const [showCursor, setShowCursor] = useState(true) 235 + const cursorTimeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined) 236 const onPointerMoveEmptySpace = useCallback(() => { 237 setShowCursor(true) 238 if (cursorTimeoutRef.current) { ··· 264 [hovered], 265 ) 266 267 + const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined) 268 269 const onHoverWithTimeout = useCallback(() => { 270 onHover()
-1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx
··· 3 import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' 4 import {msg} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 - import type React from 'react' 7 8 import {isSafari, isTouchDevice} from '#/lib/browser' 9 import {atoms as a} from '#/alf'
··· 3 import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' 4 import {msg} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 7 import {isSafari, isTouchDevice} from '#/lib/browser' 8 import {atoms as a} from '#/alf'
+1 -1
src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/utils.tsx
··· 4 import {logger} from '#/logger' 5 import {useVideoVolumeState} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' 6 7 - export function useVideoElement(ref: RefObject<HTMLVideoElement>) { 8 const [playing, setPlaying] = useState(false) 9 const [muted, setMuted] = useState(true) 10 const [currentTime, setCurrentTime] = useState(0)
··· 4 import {logger} from '#/logger' 5 import {useVideoVolumeState} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' 6 7 + export function useVideoElement(ref: RefObject<HTMLVideoElement | null>) { 8 const [playing, setPlaying] = useState(false) 9 const [muted, setMuted] = useState(true) 10 const [currentTime, setCurrentTime] = useState(0)
+1 -2
src/components/Post/Embed/VideoEmbed/index.web.tsx
··· 10 import {type AppBskyEmbedVideo} from '@atproto/api' 11 import {msg} from '@lingui/macro' 12 import {useLingui} from '@lingui/react' 13 - import type React from 'react' 14 15 import {isFirefox} from '#/lib/browser' 16 import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' ··· 38 useActiveVideoWeb() 39 const [onScreen, setOnScreen] = useState(false) 40 const [isFullscreen] = useFullscreen() 41 - const lastKnownTime = useRef<number | undefined>() 42 43 useEffect(() => { 44 if (!ref.current) return
··· 10 import {type AppBskyEmbedVideo} from '@atproto/api' 11 import {msg} from '@lingui/macro' 12 import {useLingui} from '@lingui/react' 13 14 import {isFirefox} from '#/lib/browser' 15 import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' ··· 37 useActiveVideoWeb() 38 const [onScreen, setOnScreen] = useState(false) 39 const [isFullscreen] = useFullscreen() 40 + const lastKnownTime = useRef<number | undefined>(undefined) 41 42 useEffect(() => { 43 if (!ref.current) return
-1
src/components/PostControls/PostMenu/index.tsx
··· 8 } from '@atproto/api' 9 import {msg} from '@lingui/macro' 10 import {useLingui} from '@lingui/react' 11 - import type React from 'react' 12 13 import {type Shadow} from '#/state/cache/post-shadow' 14 import {EventStopper} from '#/view/com/util/EventStopper'
··· 8 } from '@atproto/api' 9 import {msg} from '@lingui/macro' 10 import {useLingui} from '@lingui/react' 11 12 import {type Shadow} from '#/state/cache/post-shadow' 13 import {EventStopper} from '#/view/com/util/EventStopper'
-1
src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
··· 3 import {msg, Trans} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 import {useNavigation} from '@react-navigation/native' 6 - import type React from 'react' 7 8 import {makeProfileLink} from '#/lib/routes/links' 9 import {type NavigationProp} from '#/lib/routes/types'
··· 3 import {msg, Trans} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 import {useNavigation} from '@react-navigation/native' 6 7 import {makeProfileLink} from '#/lib/routes/links' 8 import {type NavigationProp} from '#/lib/routes/types'
-1
src/components/PostControls/ShareMenu/index.tsx
··· 9 } from '@atproto/api' 10 import {msg} from '@lingui/macro' 11 import {useLingui} from '@lingui/react' 12 - import type React from 'react' 13 14 import {makeProfileLink} from '#/lib/routes/links' 15 import {shareUrl} from '#/lib/sharing'
··· 9 } from '@atproto/api' 10 import {msg} from '@lingui/macro' 11 import {useLingui} from '@lingui/react' 12 13 import {makeProfileLink} from '#/lib/routes/links' 14 import {shareUrl} from '#/lib/sharing'
-2
src/components/ProfileHoverCard/types.ts
··· 1 - import type React from 'react' 2 - 3 import {type ViewStyleProp} from '#/alf' 4 5 export type ProfileHoverCardProps = ViewStyleProp & {
··· 1 import {type ViewStyleProp} from '#/alf' 2 3 export type ProfileHoverCardProps = ViewStyleProp & {
+3 -3
src/components/ProgressGuide/FollowDialog.tsx
··· 293 interestsDisplayNames, 294 }: { 295 guide: Follow10ProgressGuide 296 - inputRef: React.RefObject<TextInput> 297 - listRef: React.RefObject<ListMethods> 298 onSelectTab: (v: string) => void 299 searchText: string 300 setHeaderHeight: (v: number) => void ··· 565 }: { 566 onChangeText: (text: string) => void 567 onEscape: () => void 568 - inputRef: React.RefObject<TextInput> 569 defaultValue: string 570 }) { 571 const t = useTheme()
··· 293 interestsDisplayNames, 294 }: { 295 guide: Follow10ProgressGuide 296 + inputRef: React.RefObject<TextInput | null> 297 + listRef: React.RefObject<ListMethods | null> 298 onSelectTab: (v: string) => void 299 searchText: string 300 setHeaderHeight: (v: number) => void ··· 565 }: { 566 onChangeText: (text: string) => void 567 onEscape: () => void 568 + inputRef: React.RefObject<TextInput | null> 569 defaultValue: string 570 }) { 571 const t = useTheme()
+2 -2
src/components/ProgressGuide/Toast.tsx
··· 14 import {isWeb} from '#/platform/detection' 15 import {atoms as a, useTheme} from '#/alf' 16 import {Portal} from '#/components/Portal' 17 - import {AnimatedCheck, AnimatedCheckRef} from '../anim/AnimatedCheck' 18 import {Text} from '../Typography' 19 20 export interface ProgressGuideToastRef { ··· 39 const translateY = useSharedValue(0) 40 const opacity = useSharedValue(0) 41 const animatedCheckRef = React.useRef<AnimatedCheckRef | null>(null) 42 - const timeoutRef = React.useRef<NodeJS.Timeout | undefined>() 43 const winDim = useWindowDimensions() 44 45 /**
··· 14 import {isWeb} from '#/platform/detection' 15 import {atoms as a, useTheme} from '#/alf' 16 import {Portal} from '#/components/Portal' 17 + import {AnimatedCheck, type AnimatedCheckRef} from '../anim/AnimatedCheck' 18 import {Text} from '../Typography' 19 20 export interface ProgressGuideToastRef { ··· 39 const translateY = useSharedValue(0) 40 const opacity = useSharedValue(0) 41 const animatedCheckRef = React.useRef<AnimatedCheckRef | null>(null) 42 + const timeoutRef = React.useRef<NodeJS.Timeout | undefined>(undefined) 43 const winDim = useWindowDimensions() 44 45 /**
+1 -1
src/components/Select/types.ts
··· 160 item: T, 161 index: number, 162 selectedValue?: string | null, 163 - ) => React.ReactElement 164 /* 165 * Extracts the value from an item. Defaults to `item => item.value` 166 */
··· 160 item: T, 161 index: number, 162 selectedValue?: string | null, 163 + ) => React.ReactElement<any> 164 /* 165 * Extracts the value from an item. Defaults to `item => item.value` 166 */
+1 -1
src/components/dialogs/GifSelect.tsx
··· 37 onClose, 38 onSelectGif: onSelectGifProp, 39 }: { 40 - controlRef: React.RefObject<{open: () => void}> 41 onClose?: () => void 42 onSelectGif: (gif: Gif) => void 43 }) {
··· 37 onClose, 38 onSelectGif: onSelectGifProp, 39 }: { 40 + controlRef: React.RefObject<{open: () => void} | null> 41 onClose?: () => void 42 onSelectGif: (gif: Gif) => void 43 }) {
+1 -1
src/components/dialogs/SearchablePeopleList.tsx
··· 484 value: string 485 onChangeText: (text: string) => void 486 onEscape: () => void 487 - inputRef: React.RefObject<TextInput> 488 }) { 489 const t = useTheme() 490 const {_} = useLingui()
··· 484 value: string 485 onChangeText: (text: string) => void 486 onEscape: () => void 487 + inputRef: React.RefObject<TextInput | null> 488 }) { 489 const t = useTheme() 490 const {_} = useLingui()
-1
src/components/dms/ActionsWrapper.web.tsx
··· 3 import {type ChatBskyConvoDefs} from '@atproto/api' 4 import {msg} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 - import type React from 'react' 7 8 import {useConvoActive} from '#/state/messages/convo' 9 import {useSession} from '#/state/session'
··· 3 import {type ChatBskyConvoDefs} from '@atproto/api' 4 import {msg} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 7 import {useConvoActive} from '#/state/messages/convo' 8 import {useSession} from '#/state/session'
+5 -2
src/components/forms/InputGroup.tsx
··· 23 {React.cloneElement(child, { 24 // @ts-ignore 25 style: [ 26 ...(Array.isArray(child.props?.style) 27 - ? child.props.style 28 - : [child.props.style || {}]), 29 { 30 borderTopLeftRadius: i > 0 ? 0 : undefined, 31 borderTopRightRadius: i > 0 ? 0 : undefined,
··· 23 {React.cloneElement(child, { 24 // @ts-ignore 25 style: [ 26 + // @ts-ignore 27 ...(Array.isArray(child.props?.style) 28 + ? // @ts-ignore 29 + child.props.style 30 + : // @ts-ignore 31 + [child.props.style || {}]), 32 { 33 borderTopLeftRadius: i > 0 ? 0 : undefined, 34 borderTopRightRadius: i > 0 ? 0 : undefined,
+2 -2
src/components/forms/TextField.tsx
··· 28 import {Text} from '#/components/Typography' 29 30 const Context = createContext<{ 31 - inputRef: React.RefObject<TextInput> | null 32 isInvalid: boolean 33 hovered: boolean 34 onHoverIn: () => void ··· 152 value?: string 153 onChangeText?: (value: string) => void 154 isInvalid?: boolean 155 - inputRef?: React.RefObject<TextInput> | React.ForwardedRef<TextInput> 156 } 157 158 export function createInput(Component: typeof TextInput) {
··· 28 import {Text} from '#/components/Typography' 29 30 const Context = createContext<{ 31 + inputRef: React.RefObject<TextInput | null> | null 32 isInvalid: boolean 33 hovered: boolean 34 onHoverIn: () => void ··· 152 value?: string 153 onChangeText?: (value: string) => void 154 isInvalid?: boolean 155 + inputRef?: React.RefObject<TextInput | null> | React.ForwardedRef<TextInput> 156 } 157 158 export function createInput(Component: typeof TextInput) {
+7 -2
src/components/forms/ToggleButton.tsx
··· 1 import React from 'react' 2 - import {AccessibilityProps, TextStyle, View, ViewStyle} from 'react-native' 3 4 import {atoms as a, native, useTheme} from '#/alf' 5 import * as Toggle from '#/components/forms/Toggle' ··· 7 8 type ItemProps = Omit<Toggle.ItemProps, 'style' | 'role' | 'children'> & 9 AccessibilityProps & { 10 - children: React.ReactElement 11 testID?: string 12 } 13
··· 1 import React from 'react' 2 + import { 3 + type AccessibilityProps, 4 + type TextStyle, 5 + View, 6 + type ViewStyle, 7 + } from 'react-native' 8 9 import {atoms as a, native, useTheme} from '#/alf' 10 import * as Toggle from '#/components/forms/Toggle' ··· 12 13 type ItemProps = Omit<Toggle.ItemProps, 'style' | 'role' | 'children'> & 14 AccessibilityProps & { 15 + children: React.ReactElement<any> 16 testID?: string 17 } 18
+1 -1
src/components/hooks/useFullscreen.ts
··· 14 return () => document.removeEventListener('fullscreenchange', onChange) 15 } 16 17 - export function useFullscreen(ref?: React.RefObject<HTMLElement>) { 18 if (!isWeb) throw new Error("'useFullscreen' is a web-only hook") 19 const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () => 20 Boolean(document.fullscreenElement),
··· 14 return () => document.removeEventListener('fullscreenchange', onChange) 15 } 16 17 + export function useFullscreen(ref?: React.RefObject<HTMLElement | null>) { 18 if (!isWeb) throw new Error("'useFullscreen' is a web-only hook") 19 const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () => 20 Boolean(document.fullscreenElement),
-1
src/components/moderation/LabelPreference.tsx
··· 5 } from '@atproto/api' 6 import {msg, Trans} from '@lingui/macro' 7 import {useLingui} from '@lingui/react' 8 - import type React from 'react' 9 10 import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' 11 import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription'
··· 5 } from '@atproto/api' 6 import {msg, Trans} from '@lingui/macro' 7 import {useLingui} from '@lingui/react' 8 9 import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' 10 import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription'
+1 -1
src/lib/hooks/useAnimatedValue.ts
··· 2 import {Animated} from 'react-native' 3 4 export function useAnimatedValue(initialValue: number) { 5 - const lazyRef = React.useRef<Animated.Value>() 6 7 if (lazyRef.current === undefined) { 8 lazyRef.current = new Animated.Value(initialValue)
··· 2 import {Animated} from 'react-native' 3 4 export function useAnimatedValue(initialValue: number) { 5 + const lazyRef = React.useRef<Animated.Value>(undefined) 6 7 if (lazyRef.current === undefined) { 8 lazyRef.current = new Animated.Value(initialValue)
+1 -1
src/lib/hooks/useOTAUpdates.ts
··· 127 const appState = React.useRef<AppStateStatus>('active') 128 const lastMinimize = React.useRef(0) 129 const ranInitialCheck = React.useRef(false) 130 - const timeout = React.useRef<NodeJS.Timeout>() 131 const {currentlyRunning, isUpdatePending} = useUpdates() 132 const currentChannel = currentlyRunning?.channel 133
··· 127 const appState = React.useRef<AppStateStatus>('active') 128 const lastMinimize = React.useRef(0) 129 const ranInitialCheck = React.useRef(false) 130 + const timeout = React.useRef<NodeJS.Timeout>(undefined) 131 const {currentlyRunning, isUpdatePending} = useUpdates() 132 const currentChannel = currentlyRunning?.channel 133
+1 -1
src/lib/merge-refs.ts
··· 13 * returns a ref callback function that can be used to merge multiple refs into a single ref. 14 */ 15 export function mergeRefs<T = any>( 16 - refs: Array<React.MutableRefObject<T> | React.LegacyRef<T>>, 17 ): React.RefCallback<T> { 18 return value => { 19 refs.forEach(ref => {
··· 13 * returns a ref callback function that can be used to merge multiple refs into a single ref. 14 */ 15 export function mergeRefs<T = any>( 16 + refs: Array<React.MutableRefObject<T> | React.Ref<T>>, 17 ): React.RefCallback<T> { 18 return value => { 19 refs.forEach(ref => {
+1 -1
src/screens/Signup/StepCaptcha/CaptchaWebView.tsx
··· 31 onError: (error: unknown) => void 32 }) { 33 const startedAt = useRef(Date.now()) 34 - const successTo = useRef<NodeJS.Timeout>() 35 36 useEffect(() => { 37 return () => {
··· 31 onError: (error: unknown) => void 32 }) { 33 const startedAt = useRef(Date.now()) 34 + const successTo = useRef<NodeJS.Timeout>(undefined) 35 36 useEffect(() => { 37 return () => {
+1 -1
src/screens/Signup/StepInfo/Policies.tsx
··· 72 ) 73 } 74 75 - let els: ReactElement 76 if (tos && pp) { 77 els = ( 78 <Trans>
··· 72 ) 73 } 74 75 + let els: ReactElement<any> 76 if (tos && pp) { 77 els = ( 78 <Trans>
+1 -1
src/screens/Signup/StepInfo/index.tsx
··· 60 61 const [hasWarnedEmail, setHasWarnedEmail] = React.useState<boolean>(false) 62 63 - const tldtsRef = React.useRef<typeof tldts>() 64 React.useEffect(() => { 65 // @ts-expect-error - valid path 66 import('tldts/dist/index.cjs.min.js').then(tldts => {
··· 60 61 const [hasWarnedEmail, setHasWarnedEmail] = React.useState<boolean>(false) 62 63 + const tldtsRef = React.useRef<typeof tldts>(undefined) 64 React.useEffect(() => { 65 // @ts-expect-error - valid path 66 import('tldts/dist/index.cjs.min.js').then(tldts => {
+1 -1
src/state/queries/postgate/index.ts
··· 173 const agent = useAgent() 174 const queryClient = useQueryClient() 175 const getPosts = useGetPosts() 176 - const prevEmbed = React.useRef<AppBskyFeedDefs.PostView['embed']>() 177 178 return useMutation({ 179 mutationFn: async ({
··· 173 const agent = useAgent() 174 const queryClient = useQueryClient() 175 const getPosts = useGetPosts() 176 + const prevEmbed = React.useRef<AppBskyFeedDefs.PostView['embed']>(undefined) 177 178 return useMutation({ 179 mutationFn: async ({
-2
src/state/shell/index.tsx
··· 1 - import type React from 'react' 2 - 3 import {Provider as ColorModeProvider} from './color-mode' 4 import {Provider as DrawerOpenProvider} from './drawer-open' 5 import {Provider as DrawerSwipableProvider} from './drawer-swipe-disabled'
··· 1 import {Provider as ColorModeProvider} from './color-mode' 2 import {Provider as DrawerOpenProvider} from './drawer-open' 3 import {Provider as DrawerSwipableProvider} from './drawer-swipe-disabled'
+1 -1
src/view/com/composer/Composer.tsx
··· 174 videoUri: initVideoUri, 175 cancelRef, 176 }: Props & { 177 - cancelRef?: React.RefObject<CancelRef> 178 }) => { 179 const {currentAccount} = useSession() 180 const agent = useAgent()
··· 174 videoUri: initVideoUri, 175 cancelRef, 176 }: Props & { 177 + cancelRef?: React.RefObject<CancelRef | null> 178 }) => { 179 const {currentAccount} = useSession() 180 const agent = useAgent()
-2
src/view/com/composer/photos/EditImageDialog.tsx
··· 1 - import type React from 'react' 2 - 3 import {type ComposerImage} from '#/state/gallery' 4 import type * as Dialog from '#/components/Dialog' 5
··· 1 import {type ComposerImage} from '#/state/gallery' 2 import type * as Dialog from '#/components/Dialog' 3
+1 -1
src/view/com/composer/photos/EditImageDialog.web.tsx
··· 112 aspectRatio, 113 }: Required<Pick<EditImageDialogProps, 'image'>> & 114 Omit<EditImageDialogProps, 'control' | 'image'> & { 115 - saveRef: React.RefObject<{save: () => Promise<void>}> 116 }) { 117 const t = useTheme() 118 const [isDragging, setIsDragging] = useState(false)
··· 112 aspectRatio, 113 }: Required<Pick<EditImageDialogProps, 'image'>> & 114 Omit<EditImageDialogProps, 'control' | 'image'> & { 115 + saveRef: React.RefObject<{save: () => Promise<void>} | null> 116 }) { 117 const t = useTheme() 118 const [isDragging, setIsDragging] = useState(false)
+8 -1
src/view/com/feeds/FeedPage.tsx
··· 1 - import {useCallback, useEffect, useMemo, useRef, useState} from 'react' 2 import {View} from 'react-native' 3 import {type AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api' 4 import {msg} from '@lingui/macro'
··· 1 + import { 2 + type JSX, 3 + useCallback, 4 + useEffect, 5 + useMemo, 6 + useRef, 7 + useState, 8 + } from 'react' 9 import {View} from 'react-native' 10 import {type AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api' 11 import {msg} from '@lingui/macro'
+2 -1
src/view/com/home/HomeHeaderLayout.web.tsx
··· 1 - import React from 'react' 2 import {View} from 'react-native' 3 import {msg} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 6 import {useKawaiiMode} from '#/state/preferences/kawaii' 7 import {useSession} from '#/state/session'
··· 1 + import {type JSX} from 'react' 2 import {View} from 'react-native' 3 import {msg} from '@lingui/macro' 4 import {useLingui} from '@lingui/react' 5 + import type React from 'react' 6 7 import {useKawaiiMode} from '#/state/preferences/kawaii' 8 import {useSession} from '#/state/session'
+1
src/view/com/home/HomeHeaderLayoutMobile.tsx
··· 1 import {View} from 'react-native' 2 import Animated from 'react-native-reanimated' 3 import {msg} from '@lingui/macro'
··· 1 + import {type JSX} from 'react' 2 import {View} from 'react-native' 3 import Animated from 'react-native-reanimated' 4 import {msg} from '@lingui/macro'
+1 -1
src/view/com/lists/ListMembers.tsx
··· 1 - import React, {useCallback} from 'react' 2 import { 3 Dimensions, 4 type GestureResponderEvent,
··· 1 + import React, {type JSX, useCallback} from 'react' 2 import { 3 Dimensions, 4 type GestureResponderEvent,
+5 -5
src/view/com/lists/MyLists.tsx
··· 1 - import React from 'react' 2 import { 3 ActivityIndicator, 4 FlatList as RNFlatList, 5 RefreshControl, 6 - StyleProp, 7 View, 8 - ViewStyle, 9 } from 'react-native' 10 - import {AppBskyGraphDefs as GraphDefs} from '@atproto/api' 11 import {msg} from '@lingui/macro' 12 import {useLingui} from '@lingui/react' 13 ··· 16 import {s} from '#/lib/styles' 17 import {logger} from '#/logger' 18 import {useModerationOpts} from '#/state/preferences/moderation-opts' 19 - import {MyListsFilter, useMyListsQuery} from '#/state/queries/my-lists' 20 import {atoms as a, useTheme} from '#/alf' 21 import {BulletList_Stroke2_Corner0_Rounded as ListIcon} from '#/components/icons/BulletList' 22 import * as ListCard from '#/components/ListCard'
··· 1 + import React, {type JSX} from 'react' 2 import { 3 ActivityIndicator, 4 FlatList as RNFlatList, 5 RefreshControl, 6 + type StyleProp, 7 View, 8 + type ViewStyle, 9 } from 'react-native' 10 + import {type AppBskyGraphDefs as GraphDefs} from '@atproto/api' 11 import {msg} from '@lingui/macro' 12 import {useLingui} from '@lingui/react' 13 ··· 16 import {s} from '#/lib/styles' 17 import {logger} from '#/logger' 18 import {useModerationOpts} from '#/state/preferences/moderation-opts' 19 + import {type MyListsFilter, useMyListsQuery} from '#/state/queries/my-lists' 20 import {atoms as a, useTheme} from '#/alf' 21 import {BulletList_Stroke2_Corner0_Rounded as ListIcon} from '#/components/icons/BulletList' 22 import * as ListCard from '#/components/ListCard'
+1 -1
src/view/com/notifications/NotificationFeedItem.tsx
··· 248 : '' 249 250 let a11yLabel = '' 251 - let notificationContent: ReactElement 252 let icon = ( 253 <HeartIconFilled 254 size="xl"
··· 248 : '' 249 250 let a11yLabel = '' 251 + let notificationContent: ReactElement<any> 252 let icon = ( 253 <HeartIconFilled 254 size="xl"
+1
src/view/com/pager/Pager.tsx
··· 1 import { 2 memo, 3 useCallback, 4 useContext,
··· 1 import { 2 + type JSX, 3 memo, 4 useCallback, 5 useContext,
+1
src/view/com/pager/Pager.web.tsx
··· 1 import { 2 Children, 3 useCallback, 4 useImperativeHandle, 5 useRef,
··· 1 import { 2 Children, 3 + type JSX, 4 useCallback, 5 useImperativeHandle, 6 useRef,
+1 -1
src/view/com/pager/PagerWithHeader.tsx
··· 1 - import {memo, useCallback, useEffect, useRef, useState} from 'react' 2 import { 3 type LayoutChangeEvent, 4 type NativeScrollEvent,
··· 1 + import {type JSX, memo, useCallback, useEffect, useRef, useState} from 'react' 2 import { 3 type LayoutChangeEvent, 4 type NativeScrollEvent,
+8 -3
src/view/com/pager/PagerWithHeader.web.tsx
··· 1 import * as React from 'react' 2 - import {ScrollView, View} from 'react-native' 3 import {useAnimatedRef} from 'react-native-reanimated' 4 5 - import {Pager, PagerRef, RenderTabBarFnProps} from '#/view/com/pager/Pager' 6 import {atoms as a, web} from '#/alf' 7 import * as Layout from '#/components/Layout' 8 - import {ListMethods} from '../util/List' 9 import {TabBar} from './TabBar' 10 11 export interface PagerWithHeaderChildParams {
··· 1 import * as React from 'react' 2 + import {type JSX} from 'react' 3 + import {type ScrollView, View} from 'react-native' 4 import {useAnimatedRef} from 'react-native-reanimated' 5 6 + import { 7 + Pager, 8 + type PagerRef, 9 + type RenderTabBarFnProps, 10 + } from '#/view/com/pager/Pager' 11 import {atoms as a, web} from '#/alf' 12 import * as Layout from '#/components/Layout' 13 + import {type ListMethods} from '../util/List' 14 import {TabBar} from './TabBar' 15 16 export interface PagerWithHeaderChildParams {
+3 -1
src/view/com/pager/TabBar.web.tsx
··· 106 <PressableWithHover 107 testID={`${testID}-selector-${i}`} 108 key={`${item}-${i}`} 109 - ref={node => (itemRefs.current[i] = node as any)} 110 style={styles.item} 111 hoverStyle={t.atoms.bg_contrast_25} 112 onPress={() => onPressItem(i)}
··· 106 <PressableWithHover 107 testID={`${testID}-selector-${i}`} 108 key={`${item}-${i}`} 109 + ref={node => { 110 + itemRefs.current[i] = node as any 111 + }} 112 style={styles.item} 113 hoverStyle={t.atoms.bg_contrast_25} 114 onPress={() => onPressItem(i)}
+9 -1
src/view/com/posts/PostFeed.tsx
··· 1 - import {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react' 2 import { 3 ActivityIndicator, 4 AppState,
··· 1 + import { 2 + type JSX, 3 + memo, 4 + useCallback, 5 + useEffect, 6 + useMemo, 7 + useRef, 8 + useState, 9 + } from 'react' 10 import { 11 ActivityIndicator, 12 AppState,
-1
src/view/com/util/EventStopper.tsx
··· 1 import {View, type ViewStyle} from 'react-native' 2 - import type React from 'react' 3 4 /** 5 * This utility function captures events and stops
··· 1 import {View, type ViewStyle} from 'react-native' 2 3 /** 4 * This utility function captures events and stops
+1 -1
src/view/com/util/Link.tsx
··· 1 - import {memo, useCallback, useMemo} from 'react' 2 import { 3 type GestureResponderEvent, 4 Platform,
··· 1 + import {type JSX, memo, useCallback, useMemo} from 'react' 2 import { 3 type GestureResponderEvent, 4 Platform,
+1 -1
src/view/com/util/List.tsx
··· 57 ...props 58 }, 59 ref, 60 - ): React.ReactElement => { 61 const isScrolledDown = useSharedValue(false) 62 const t = useTheme() 63 const dedupe = useDedupe(400)
··· 57 ...props 58 }, 59 ref, 60 + ): React.ReactElement<any> => { 61 const isScrolledDown = useSharedValue(false) 62 const t = useTheme() 63 const dedupe = useDedupe(400)
+13 -6
src/view/com/util/List.web.tsx
··· 1 - import React, {isValidElement, memo, startTransition, useRef} from 'react' 2 import { 3 type FlatListProps, 4 StyleSheet, ··· 202 behavior: animated ? 'smooth' : 'instant', 203 }) 204 }, 205 scrollToEnd({animated = true}: {animated?: boolean}) { 206 const element = getScrollableNode() 207 element?.scrollTo({ ··· 382 containerRef, 383 onVisibleChange, 384 }: { 385 - root?: React.RefObject<HTMLDivElement> | null 386 topMargin?: string 387 bottomMargin?: string 388 - containerRef: React.RefObject<Element> 389 onVisibleChange: (isVisible: boolean) => void 390 }) { 391 const [containerHeight, setContainerHeight] = React.useState(0) ··· 404 } 405 406 function useResizeObserver( 407 - ref: React.RefObject<Element>, 408 onResize: undefined | ((w: number, h: number) => void), 409 ) { 410 const handleResize = useNonReactiveCallback(onResize ?? (() => {})) ··· 509 onVisibleChange, 510 style, 511 }: { 512 - root?: React.RefObject<HTMLDivElement> | null 513 topMargin?: string 514 bottomMargin?: string 515 onVisibleChange: (isVisible: boolean) => void ··· 551 552 export const List = memo(React.forwardRef(ListImpl)) as <ItemT>( 553 props: ListProps<ItemT> & {ref?: React.Ref<ListMethods>}, 554 - ) => React.ReactElement 555 556 // https://stackoverflow.com/questions/7944460/detect-safari-browser 557
··· 1 + import React, { 2 + isValidElement, 3 + type JSX, 4 + memo, 5 + startTransition, 6 + useRef, 7 + } from 'react' 8 import { 9 type FlatListProps, 10 StyleSheet, ··· 208 behavior: animated ? 'smooth' : 'instant', 209 }) 210 }, 211 + 212 scrollToEnd({animated = true}: {animated?: boolean}) { 213 const element = getScrollableNode() 214 element?.scrollTo({ ··· 389 containerRef, 390 onVisibleChange, 391 }: { 392 + root?: React.RefObject<HTMLDivElement | null> | null 393 topMargin?: string 394 bottomMargin?: string 395 + containerRef: React.RefObject<Element | null> 396 onVisibleChange: (isVisible: boolean) => void 397 }) { 398 const [containerHeight, setContainerHeight] = React.useState(0) ··· 411 } 412 413 function useResizeObserver( 414 + ref: React.RefObject<Element | null>, 415 onResize: undefined | ((w: number, h: number) => void), 416 ) { 417 const handleResize = useNonReactiveCallback(onResize ?? (() => {})) ··· 516 onVisibleChange, 517 style, 518 }: { 519 + root?: React.RefObject<HTMLDivElement | null> | null 520 topMargin?: string 521 bottomMargin?: string 522 onVisibleChange: (isVisible: boolean) => void ··· 558 559 export const List = memo(React.forwardRef(ListImpl)) as <ItemT>( 560 props: ListProps<ItemT> & {ref?: React.Ref<ListMethods>}, 561 + ) => React.ReactElement<any> 562 563 // https://stackoverflow.com/questions/7944460/detect-safari-browser 564
-1
src/view/com/util/PostMeta.tsx
··· 4 import {msg} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 import {useQueryClient} from '@tanstack/react-query' 7 - import type React from 'react' 8 9 import {useActorStatus} from '#/lib/actor-status' 10 import {makeProfileLink} from '#/lib/routes/links'
··· 4 import {msg} from '@lingui/macro' 5 import {useLingui} from '@lingui/react' 6 import {useQueryClient} from '@tanstack/react-query' 7 8 import {useActorStatus} from '#/lib/actor-status' 9 import {makeProfileLink} from '#/lib/routes/links'
+2 -2
src/view/com/util/TimeElapsed.tsx
··· 1 - import React from 'react' 2 - import {I18n} from '@lingui/core' 3 import {useLingui} from '@lingui/react' 4 5 import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
··· 1 + import React, {type JSX} from 'react' 2 + import {type I18n} from '@lingui/core' 3 import {useLingui} from '@lingui/react' 4 5 import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
+2
src/view/com/util/ViewHeader.tsx
··· 1 import {Header} from '#/components/Layout' 2 3 /**
··· 1 + import {type JSX} from 'react' 2 + 3 import {Header} from '#/components/Layout' 4 5 /**
+4 -4
src/view/com/util/ViewSelector.tsx
··· 1 - import React, {useEffect, useState} from 'react' 2 import { 3 - NativeScrollEvent, 4 - NativeSyntheticEvent, 5 Pressable, 6 RefreshControl, 7 ScrollView, ··· 36 renderItem: (item: any) => JSX.Element 37 ListFooterComponent?: 38 | React.ComponentType<any> 39 - | React.ReactElement 40 | null 41 | undefined 42 onSelectView?: (viewIndex: number) => void
··· 1 + import React, {type JSX, useEffect, useState} from 'react' 2 import { 3 + type NativeScrollEvent, 4 + type NativeSyntheticEvent, 5 Pressable, 6 RefreshControl, 7 ScrollView, ··· 36 renderItem: (item: any) => JSX.Element 37 ListFooterComponent?: 38 | React.ComponentType<any> 39 + | React.ReactElement<any> 40 | null 41 | undefined 42 onSelectView?: (viewIndex: number) => void
+2 -2
src/view/com/util/fab/FABInner.tsx
··· 1 - import {ComponentProps} from 'react' 2 - import {StyleSheet, TouchableWithoutFeedback} from 'react-native' 3 import Animated from 'react-native-reanimated' 4 import {useSafeAreaInsets} from 'react-native-safe-area-context' 5 import {LinearGradient} from 'expo-linear-gradient'
··· 1 + import {type ComponentProps, type JSX} from 'react' 2 + import {StyleSheet, type TouchableWithoutFeedback} from 'react-native' 3 import Animated from 'react-native-reanimated' 4 import {useSafeAreaInsets} from 'react-native-safe-area-context' 5 import {LinearGradient} from 'expo-linear-gradient'
+1 -1
src/view/com/util/forms/NativeDropdown.web.tsx
··· 161 menuRef, 162 }: { 163 items: DropdownItem[] 164 - menuRef: React.RefObject<HTMLDivElement> 165 }) { 166 const pal = usePalette('default') 167 const theme = useTheme()
··· 161 menuRef, 162 }: { 163 items: DropdownItem[] 164 + menuRef: React.RefObject<HTMLDivElement | null> 165 }) { 166 const pal = usePalette('default') 167 const theme = useTheme()
-1
src/view/com/util/images/Gallery.tsx
··· 4 import {type AppBskyEmbedImages} from '@atproto/api' 5 import {msg} from '@lingui/macro' 6 import {useLingui} from '@lingui/react' 7 - import type React from 'react' 8 9 import {type Dimensions} from '#/lib/media/types' 10 import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
··· 4 import {type AppBskyEmbedImages} from '@atproto/api' 5 import {msg} from '@lingui/macro' 6 import {useLingui} from '@lingui/react' 7 8 import {type Dimensions} from '#/lib/media/types' 9 import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
+1 -1
src/view/screens/Storybook/Dialogs.tsx
··· 22 React.useState<boolean>() 23 const [shouldRenderUnmountTest, setShouldRenderUnmountTest] = 24 React.useState(false) 25 - const unmountTestInterval = React.useRef<number>() 26 27 const onUnmountTestStartPressWithClose = () => { 28 setShouldRenderUnmountTest(true)
··· 22 React.useState<boolean>() 23 const [shouldRenderUnmountTest, setShouldRenderUnmountTest] = 24 React.useState(false) 25 + const unmountTestInterval = React.useRef<number>(undefined) 26 27 const onUnmountTestStartPressWithClose = () => { 28 setShouldRenderUnmountTest(true)
+1 -1
src/view/shell/Drawer.tsx
··· 1 - import React, {type ComponentProps} from 'react' 2 import {Linking, ScrollView, TouchableOpacity, View} from 'react-native' 3 import {useSafeAreaInsets} from 'react-native-safe-area-context' 4 import {msg, Plural, plural, Trans} from '@lingui/macro'
··· 1 + import React, {type ComponentProps, type JSX} from 'react' 2 import {Linking, ScrollView, TouchableOpacity, View} from 'react-native' 3 import {useSafeAreaInsets} from 'react-native-safe-area-context' 4 import {msg, Plural, plural, Trans} from '@lingui/macro'
+1 -1
src/view/shell/bottom-bar/BottomBar.tsx
··· 1 - import {useCallback} from 'react' 2 import {type GestureResponderEvent, View} from 'react-native' 3 import Animated from 'react-native-reanimated' 4 import {useSafeAreaInsets} from 'react-native-safe-area-context'
··· 1 + import {type JSX, useCallback} from 'react' 2 import {type GestureResponderEvent, View} from 'react-native' 3 import Animated from 'react-native-reanimated' 4 import {useSafeAreaInsets} from 'react-native-safe-area-context'
+1 -1
src/view/shell/bottom-bar/BottomBarWeb.tsx
··· 230 } 231 232 const NavItem: React.FC<{ 233 - children: (props: {isActive: boolean}) => React.ReactChild 234 href: string 235 routeName: string 236 hasNew?: boolean
··· 230 } 231 232 const NavItem: React.FC<{ 233 + children: (props: {isActive: boolean}) => React.ReactNode 234 href: string 235 routeName: string 236 hasNew?: boolean
+1 -1
src/view/shell/desktop/LeftNav.tsx
··· 1 - import {useCallback, useMemo, useState} from 'react' 2 import {StyleSheet, View} from 'react-native' 3 import {type AppBskyActorDefs} from '@atproto/api' 4 import {msg, plural, Trans} from '@lingui/macro'
··· 1 + import {type JSX, useCallback, useMemo, useState} from 'react' 2 import {StyleSheet, View} from 'react-native' 3 import {type AppBskyActorDefs} from '@atproto/api' 4 import {msg, plural, Trans} from '@lingui/macro'
+22 -41
yarn.lock
··· 7589 resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" 7590 integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== 7591 7592 - "@types/prop-types@*": 7593 - version "15.7.5" 7594 - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" 7595 - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== 7596 - 7597 "@types/psl@^1.1.1": 7598 version "1.1.1" 7599 resolved "https://registry.yarnpkg.com/@types/psl/-/psl-1.1.1.tgz#3ba9e6d4bd2a32652a639fd5df7e539151d0a3b2" ··· 7609 resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" 7610 integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== 7611 7612 - "@types/react-dom@^19.1.2": 7613 - version "19.1.3" 7614 - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.1.3.tgz#3f0c60804441bf34d19f8dd0d44405c0c0e21bfa" 7615 - integrity sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg== 7616 7617 - "@types/react-responsive@^8.0.5": 7618 - version "8.0.5" 7619 - resolved "https://registry.yarnpkg.com/@types/react-responsive/-/react-responsive-8.0.5.tgz#77769862d2a0711434feb972be08e3e6c334440a" 7620 - integrity sha512-k3gQJgI87oP5IrVZe//3LKJFnAeFaqqWmmtl5eoYL2H3HqFcIhUaE30kRK1CsW3DHdojZxcVj4ZNc2ClsEu2PA== 7621 dependencies: 7622 - "@types/react" "*" 7623 - 7624 - "@types/react@*", "@types/react@^18": 7625 - version "18.2.20" 7626 - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.20.tgz#1605557a83df5c8a2cc4eeb743b3dfc0eb6aaeb2" 7627 - integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw== 7628 - dependencies: 7629 - "@types/prop-types" "*" 7630 - "@types/scheduler" "*" 7631 csstype "^3.0.2" 7632 7633 "@types/retry@0.12.0": 7634 version "0.12.0" 7635 resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" 7636 integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== 7637 - 7638 - "@types/scheduler@*": 7639 - version "0.16.3" 7640 - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" 7641 - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== 7642 7643 "@types/semver@^7.3.12": 7644 version "7.5.0" ··· 14515 resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0" 14516 integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q== 14517 14518 - matchmediaquery@^0.3.0: 14519 - version "0.3.1" 14520 - resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.3.1.tgz#8247edc47e499ebb7c58f62a9ff9ccf5b815c6d7" 14521 - integrity sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ== 14522 dependencies: 14523 css-mediaquery "^0.1.2" 14524 ··· 17124 use-callback-ref "^1.3.3" 17125 use-sidecar "^1.1.3" 17126 17127 - react-responsive@^9.0.2: 17128 - version "9.0.2" 17129 - resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-9.0.2.tgz#34531ca77a61e7a8775714016d21241df7e4205c" 17130 - integrity sha512-+4CCab7z8G8glgJoRjAwocsgsv6VA2w7JPxFWHRc7kvz8mec1/K5LutNC2MG28Mn8mu6+bu04XZxHv5gyfT7xQ== 17131 dependencies: 17132 hyphenate-style-name "^1.0.0" 17133 - matchmediaquery "^0.3.0" 17134 prop-types "^15.6.1" 17135 - shallow-equal "^1.2.1" 17136 17137 react-server-dom-webpack@~19.0.0: 17138 version "19.0.0" ··· 17985 resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-1.0.0.tgz#94e9210bf27e7583f9749a0d07bd4f4937ea488f" 17986 integrity sha512-DkS7q3nN68dEMb4E18HFPDAvyrjDZK9YAQQF2QxeFu9gp2xRDXFMF8qLJ1EmQ/qeEGQmop4lmMM1WtYJTIcCMw== 17987 17988 - shallow-equal@^1.2.1: 17989 - version "1.2.1" 17990 - resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" 17991 - integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== 17992 17993 sharp@^0.33.5: 17994 version "0.33.5"
··· 7589 resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" 7590 integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== 7591 7592 "@types/psl@^1.1.1": 7593 version "1.1.1" 7594 resolved "https://registry.yarnpkg.com/@types/psl/-/psl-1.1.1.tgz#3ba9e6d4bd2a32652a639fd5df7e539151d0a3b2" ··· 7604 resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" 7605 integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== 7606 7607 + "@types/react-dom@^19.1.8": 7608 + version "19.1.9" 7609 + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.1.9.tgz#5ab695fce1e804184767932365ae6569c11b4b4b" 7610 + integrity sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ== 7611 7612 + "@types/react@^19.1.12": 7613 + version "19.1.12" 7614 + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.1.12.tgz#7bfaa76aabbb0b4fe0493c21a3a7a93d33e8937b" 7615 + integrity sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w== 7616 dependencies: 7617 csstype "^3.0.2" 7618 7619 "@types/retry@0.12.0": 7620 version "0.12.0" 7621 resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" 7622 integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== 7623 7624 "@types/semver@^7.3.12": 7625 version "7.5.0" ··· 14496 resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0" 14497 integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q== 14498 14499 + matchmediaquery@^0.4.2: 14500 + version "0.4.2" 14501 + resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.4.2.tgz#22582bd4ae63ad9f54c53001bba80cbed0f7eafa" 14502 + integrity sha512-wrZpoT50ehYOudhDjt/YvUJc6eUzcdFPdmbizfgvswCKNHD1/OBOHYJpHie+HXpu6bSkEGieFMYk6VuutaiRfA== 14503 dependencies: 14504 css-mediaquery "^0.1.2" 14505 ··· 17105 use-callback-ref "^1.3.3" 17106 use-sidecar "^1.1.3" 17107 17108 + react-responsive@^10.0.1: 17109 + version "10.0.1" 17110 + resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-10.0.1.tgz#293d4d2562da93409861216f0110d146c5676eb3" 17111 + integrity sha512-OM5/cRvbtUWEX8le8RCT8scA8y2OPtb0Q/IViEyCEM5FBN8lRrkUOZnu87I88A6njxDldvxG+rLBxWiA7/UM9g== 17112 dependencies: 17113 hyphenate-style-name "^1.0.0" 17114 + matchmediaquery "^0.4.2" 17115 prop-types "^15.6.1" 17116 + shallow-equal "^3.1.0" 17117 17118 react-server-dom-webpack@~19.0.0: 17119 version "19.0.0" ··· 17966 resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-1.0.0.tgz#94e9210bf27e7583f9749a0d07bd4f4937ea488f" 17967 integrity sha512-DkS7q3nN68dEMb4E18HFPDAvyrjDZK9YAQQF2QxeFu9gp2xRDXFMF8qLJ1EmQ/qeEGQmop4lmMM1WtYJTIcCMw== 17968 17969 + shallow-equal@^3.1.0: 17970 + version "3.1.0" 17971 + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-3.1.0.tgz#e7a54bac629c7f248eff6c2f5b63122ba4320bec" 17972 + integrity sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg== 17973 17974 sharp@^0.33.5: 17975 version "0.33.5"