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
This commit is contained in:
Samuel Newman
2025-09-09 18:09:10 +03:00
committed by GitHub
parent d496a22352
commit 3e2c181c40
73 changed files with 157 additions and 143 deletions
+3 -4
View File
@@ -213,7 +213,7 @@
"react-native-web-webview": "^1.0.2",
"react-native-webview": "^13.13.5",
"react-remove-scroll-bar": "^2.3.8",
"react-responsive": "^9.0.2",
"react-responsive": "^10.0.1",
"react-textarea-autosize": "^8.5.3",
"sonner": "^2.0.7",
"sonner-native": "^0.21.0",
@@ -245,8 +245,8 @@
"@types/lodash.isequal": "^4.5.6",
"@types/lodash.shuffle": "^4.2.7",
"@types/psl": "^1.1.1",
"@types/react-dom": "^19.1.2",
"@types/react-responsive": "^8.0.5",
"@types/react": "^19.1.12",
"@types/react-dom": "^19.1.8",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"babel-jest": "^29.7.0",
@@ -284,7 +284,6 @@
"@expo/image-utils": "0.6.3",
"@react-native/babel-preset": "0.79.3",
"@react-native/normalize-colors": "0.79.3",
"@types/react": "^18",
"**/expo-constants": "17.0.3",
"**/expo-device": "7.1.4",
"**/zod": "3.23.8",
+13
View File
@@ -0,0 +1,13 @@
diff --git a/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts b/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts
index 1c788ab..d30f330 100644
--- a/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts
+++ b/node_modules/@discord/bottom-sheet/src/hooks/useStableCallback.ts
@@ -6,7 +6,7 @@ type Callback = (...args: any[]) => any;
* https://gist.github.com/JakeCoxon/c7ebf6e6496f8468226fd36b596e1985
*/
export const useStableCallback = (callback: Callback) => {
- const callbackRef = useRef<Callback>();
+ const callbackRef = useRef<Callback>(undefined);
const memoCallback = useCallback(
(...args: any) => callbackRef.current && callbackRef.current(...args),
[]
+1 -1
View File
@@ -1,4 +1,4 @@
import {useCallback, useRef} from 'react'
import {type JSX, useCallback, useRef} from 'react'
import {Linking} from 'react-native'
import * as Notifications from 'expo-notifications'
import {i18n, type MessageDescriptor} from '@lingui/core'
-1
View File
@@ -3,7 +3,6 @@ import {type TextProps as RNTextProps} from 'react-native'
import {type StyleProp, type TextStyle} from 'react-native'
import {UITextView} from 'react-native-uitextview'
import createEmojiRegex from 'emoji-regex'
import type React from 'react'
import {isNative} from '#/platform/detection'
import {isIOS} from '#/platform/detection'
+2 -2
View File
@@ -71,8 +71,8 @@ export type ButtonState = {
export type ButtonContext = VariantProps & ButtonState
type NonTextElements =
| React.ReactElement
| Iterable<React.ReactElement | null | undefined | boolean>
| React.ReactElement<any>
| Iterable<React.ReactElement<any> | null | undefined | boolean>
export type ButtonProps = Pick<
PressableProps,
+2 -1
View File
@@ -119,7 +119,8 @@ export function Root({children}: {children: React.ReactNode}) {
const hoverablesSV = useSharedValue<
Record<string, {id: string; rect: Measurement}>
>({})
const syncHoverablesThrottleRef = useRef<ReturnType<typeof setTimeout>>()
const syncHoverablesThrottleRef =
useRef<ReturnType<typeof setTimeout>>(undefined)
const [hoveredMenuItem, setHoveredMenuItem] = useState<string | null>(null)
const onHoverableTouchUp = useCallback((id: string) => {
-1
View File
@@ -5,7 +5,6 @@ import {
type ViewStyle,
} from 'react-native'
import {type SharedValue} from 'react-native-reanimated'
import type React from 'react'
import type * as Dialog from '#/components/Dialog'
import {
+1 -2
View File
@@ -5,7 +5,6 @@ import {
type StyleProp,
type ViewStyle,
} from 'react-native'
import type React from 'react'
import {type ViewStyleProp} from '#/alf'
import {type BottomSheetViewProps} from '../../../modules/bottom-sheet'
@@ -34,7 +33,7 @@ export type DialogControlRefProps = {
*/
export type DialogControlProps = DialogControlRefProps & {
id: string
ref: React.RefObject<DialogControlRefProps>
ref: React.RefObject<DialogControlRefProps | null>
isOpen?: boolean
}
-1
View File
@@ -2,7 +2,6 @@ import {memo} from 'react'
import {type StyleProp, View, type ViewStyle} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {cleanError} from '#/lib/strings/errors'
import {CenteredView} from '#/view/com/util/Views'
+1 -1
View File
@@ -10,7 +10,7 @@ import {
useState,
} from 'react'
type Component = React.ReactElement
type Component = React.ReactElement<any>
type ContextType = {
outlet: Component | null
@@ -139,7 +139,7 @@ function useHLS({
playlist: string
setHasSubtitleTrack: (v: boolean) => void
setError: (v: Error | null) => void
videoRef: React.RefObject<HTMLVideoElement>
videoRef: React.RefObject<HTMLVideoElement | null>
setHlsLoading: (v: boolean) => void
}) {
const [Hls, setHls] = useState<typeof HlsTypes.default | undefined>(
@@ -1,7 +1,6 @@
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
@@ -1,5 +1,4 @@
import {type SvgProps} from 'react-native-svg'
import type React from 'react'
import {PressableWithHover} from '#/view/com/util/PressableWithHover'
import {atoms as a, useTheme, web} from '#/alf'
@@ -2,7 +2,6 @@ import {useCallback, useEffect, useRef, useState} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {isFirefox, isTouchDevice} from '#/lib/browser'
import {clamp} from '#/lib/numbers'
@@ -46,14 +46,14 @@ export function Controls({
hlsLoading,
hasSubtitleTrack,
}: {
videoRef: React.RefObject<HTMLVideoElement>
hlsRef: React.RefObject<Hls | undefined>
videoRef: React.RefObject<HTMLVideoElement | null>
hlsRef: React.RefObject<Hls | undefined | null>
active: boolean
setActive: () => void
focused: boolean
setFocused: (focused: boolean) => void
onScreen: boolean
fullscreenRef: React.RefObject<HTMLDivElement>
fullscreenRef: React.RefObject<HTMLDivElement | null>
hlsLoading: boolean
hasSubtitleTrack: boolean
}) {
@@ -232,7 +232,7 @@ export function Controls({
}, [onSeek, videoRef])
const [showCursor, setShowCursor] = useState(true)
const cursorTimeoutRef = useRef<ReturnType<typeof setTimeout>>()
const cursorTimeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined)
const onPointerMoveEmptySpace = useCallback(() => {
setShowCursor(true)
if (cursorTimeoutRef.current) {
@@ -264,7 +264,7 @@ export function Controls({
[hovered],
)
const timeoutRef = useRef<ReturnType<typeof setTimeout>>()
const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined)
const onHoverWithTimeout = useCallback(() => {
onHover()
@@ -3,7 +3,6 @@ import {View} from 'react-native'
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {isSafari, isTouchDevice} from '#/lib/browser'
import {atoms as a} from '#/alf'
@@ -4,7 +4,7 @@ import {isSafari} from '#/lib/browser'
import {logger} from '#/logger'
import {useVideoVolumeState} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
export function useVideoElement(ref: RefObject<HTMLVideoElement>) {
export function useVideoElement(ref: RefObject<HTMLVideoElement | null>) {
const [playing, setPlaying] = useState(false)
const [muted, setMuted] = useState(true)
const [currentTime, setCurrentTime] = useState(0)
@@ -10,7 +10,6 @@ import {View} from 'react-native'
import {type AppBskyEmbedVideo} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {isFirefox} from '#/lib/browser'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
@@ -38,7 +37,7 @@ export function VideoEmbed({
useActiveVideoWeb()
const [onScreen, setOnScreen] = useState(false)
const [isFullscreen] = useFullscreen()
const lastKnownTime = useRef<number | undefined>()
const lastKnownTime = useRef<number | undefined>(undefined)
useEffect(() => {
if (!ref.current) return
@@ -8,7 +8,6 @@ import {
} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {type Shadow} from '#/state/cache/post-shadow'
import {EventStopper} from '#/view/com/util/EventStopper'
@@ -3,7 +3,6 @@ import {AtUri} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import type React from 'react'
import {makeProfileLink} from '#/lib/routes/links'
import {type NavigationProp} from '#/lib/routes/types'
@@ -9,7 +9,6 @@ import {
} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {makeProfileLink} from '#/lib/routes/links'
import {shareUrl} from '#/lib/sharing'
-2
View File
@@ -1,5 +1,3 @@
import type React from 'react'
import {type ViewStyleProp} from '#/alf'
export type ProfileHoverCardProps = ViewStyleProp & {
@@ -293,8 +293,8 @@ let Header = ({
interestsDisplayNames,
}: {
guide: Follow10ProgressGuide
inputRef: React.RefObject<TextInput>
listRef: React.RefObject<ListMethods>
inputRef: React.RefObject<TextInput | null>
listRef: React.RefObject<ListMethods | null>
onSelectTab: (v: string) => void
searchText: string
setHeaderHeight: (v: number) => void
@@ -565,7 +565,7 @@ function SearchInput({
}: {
onChangeText: (text: string) => void
onEscape: () => void
inputRef: React.RefObject<TextInput>
inputRef: React.RefObject<TextInput | null>
defaultValue: string
}) {
const t = useTheme()
+2 -2
View File
@@ -14,7 +14,7 @@ import {useLingui} from '@lingui/react'
import {isWeb} from '#/platform/detection'
import {atoms as a, useTheme} from '#/alf'
import {Portal} from '#/components/Portal'
import {AnimatedCheck, AnimatedCheckRef} from '../anim/AnimatedCheck'
import {AnimatedCheck, type AnimatedCheckRef} from '../anim/AnimatedCheck'
import {Text} from '../Typography'
export interface ProgressGuideToastRef {
@@ -39,7 +39,7 @@ export const ProgressGuideToast = React.forwardRef<
const translateY = useSharedValue(0)
const opacity = useSharedValue(0)
const animatedCheckRef = React.useRef<AnimatedCheckRef | null>(null)
const timeoutRef = React.useRef<NodeJS.Timeout | undefined>()
const timeoutRef = React.useRef<NodeJS.Timeout | undefined>(undefined)
const winDim = useWindowDimensions()
/**
+1 -1
View File
@@ -160,7 +160,7 @@ export type ContentProps<T> = {
item: T,
index: number,
selectedValue?: string | null,
) => React.ReactElement
) => React.ReactElement<any>
/*
* Extracts the value from an item. Defaults to `item => item.value`
*/
+1 -1
View File
@@ -37,7 +37,7 @@ export function GifSelectDialog({
onClose,
onSelectGif: onSelectGifProp,
}: {
controlRef: React.RefObject<{open: () => void}>
controlRef: React.RefObject<{open: () => void} | null>
onClose?: () => void
onSelectGif: (gif: Gif) => void
}) {
@@ -484,7 +484,7 @@ function SearchInput({
value: string
onChangeText: (text: string) => void
onEscape: () => void
inputRef: React.RefObject<TextInput>
inputRef: React.RefObject<TextInput | null>
}) {
const t = useTheme()
const {_} = useLingui()
@@ -3,7 +3,6 @@ import {Pressable, View} from 'react-native'
import {type ChatBskyConvoDefs} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {useConvoActive} from '#/state/messages/convo'
import {useSession} from '#/state/session'
+5 -2
View File
@@ -23,9 +23,12 @@ export function InputGroup(props: React.PropsWithChildren<{}>) {
{React.cloneElement(child, {
// @ts-ignore
style: [
// @ts-ignore
...(Array.isArray(child.props?.style)
? child.props.style
: [child.props.style || {}]),
? // @ts-ignore
child.props.style
: // @ts-ignore
[child.props.style || {}]),
{
borderTopLeftRadius: i > 0 ? 0 : undefined,
borderTopRightRadius: i > 0 ? 0 : undefined,
+2 -2
View File
@@ -28,7 +28,7 @@ import {type Props as SVGIconProps} from '#/components/icons/common'
import {Text} from '#/components/Typography'
const Context = createContext<{
inputRef: React.RefObject<TextInput> | null
inputRef: React.RefObject<TextInput | null> | null
isInvalid: boolean
hovered: boolean
onHoverIn: () => void
@@ -152,7 +152,7 @@ export type InputProps = Omit<TextInputProps, 'value' | 'onChangeText'> & {
value?: string
onChangeText?: (value: string) => void
isInvalid?: boolean
inputRef?: React.RefObject<TextInput> | React.ForwardedRef<TextInput>
inputRef?: React.RefObject<TextInput | null> | React.ForwardedRef<TextInput>
}
export function createInput(Component: typeof TextInput) {
+7 -2
View File
@@ -1,5 +1,10 @@
import React from 'react'
import {AccessibilityProps, TextStyle, View, ViewStyle} from 'react-native'
import {
type AccessibilityProps,
type TextStyle,
View,
type ViewStyle,
} from 'react-native'
import {atoms as a, native, useTheme} from '#/alf'
import * as Toggle from '#/components/forms/Toggle'
@@ -7,7 +12,7 @@ import {Text} from '#/components/Typography'
type ItemProps = Omit<Toggle.ItemProps, 'style' | 'role' | 'children'> &
AccessibilityProps & {
children: React.ReactElement
children: React.ReactElement<any>
testID?: string
}
+1 -1
View File
@@ -14,7 +14,7 @@ function fullscreenSubscribe(onChange: () => void) {
return () => document.removeEventListener('fullscreenchange', onChange)
}
export function useFullscreen(ref?: React.RefObject<HTMLElement>) {
export function useFullscreen(ref?: React.RefObject<HTMLElement | null>) {
if (!isWeb) throw new Error("'useFullscreen' is a web-only hook")
const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () =>
Boolean(document.fullscreenElement),
@@ -5,7 +5,6 @@ import {
} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings'
import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription'
+1 -1
View File
@@ -2,7 +2,7 @@ import * as React from 'react'
import {Animated} from 'react-native'
export function useAnimatedValue(initialValue: number) {
const lazyRef = React.useRef<Animated.Value>()
const lazyRef = React.useRef<Animated.Value>(undefined)
if (lazyRef.current === undefined) {
lazyRef.current = new Animated.Value(initialValue)
+1 -1
View File
@@ -127,7 +127,7 @@ export function useOTAUpdates() {
const appState = React.useRef<AppStateStatus>('active')
const lastMinimize = React.useRef(0)
const ranInitialCheck = React.useRef(false)
const timeout = React.useRef<NodeJS.Timeout>()
const timeout = React.useRef<NodeJS.Timeout>(undefined)
const {currentlyRunning, isUpdatePending} = useUpdates()
const currentChannel = currentlyRunning?.channel
+1 -1
View File
@@ -13,7 +13,7 @@
* returns a ref callback function that can be used to merge multiple refs into a single ref.
*/
export function mergeRefs<T = any>(
refs: Array<React.MutableRefObject<T> | React.LegacyRef<T>>,
refs: Array<React.MutableRefObject<T> | React.Ref<T>>,
): React.RefCallback<T> {
return value => {
refs.forEach(ref => {
@@ -31,7 +31,7 @@ export function CaptchaWebView({
onError: (error: unknown) => void
}) {
const startedAt = useRef(Date.now())
const successTo = useRef<NodeJS.Timeout>()
const successTo = useRef<NodeJS.Timeout>(undefined)
useEffect(() => {
return () => {
+1 -1
View File
@@ -72,7 +72,7 @@ export const Policies = ({
)
}
let els: ReactElement
let els: ReactElement<any>
if (tos && pp) {
els = (
<Trans>
+1 -1
View File
@@ -60,7 +60,7 @@ export function StepInfo({
const [hasWarnedEmail, setHasWarnedEmail] = React.useState<boolean>(false)
const tldtsRef = React.useRef<typeof tldts>()
const tldtsRef = React.useRef<typeof tldts>(undefined)
React.useEffect(() => {
// @ts-expect-error - valid path
import('tldts/dist/index.cjs.min.js').then(tldts => {
+1 -1
View File
@@ -173,7 +173,7 @@ export function useToggleQuoteDetachmentMutation() {
const agent = useAgent()
const queryClient = useQueryClient()
const getPosts = useGetPosts()
const prevEmbed = React.useRef<AppBskyFeedDefs.PostView['embed']>()
const prevEmbed = React.useRef<AppBskyFeedDefs.PostView['embed']>(undefined)
return useMutation({
mutationFn: async ({
-2
View File
@@ -1,5 +1,3 @@
import type React from 'react'
import {Provider as ColorModeProvider} from './color-mode'
import {Provider as DrawerOpenProvider} from './drawer-open'
import {Provider as DrawerSwipableProvider} from './drawer-swipe-disabled'
+1 -1
View File
@@ -174,7 +174,7 @@ export const ComposePost = ({
videoUri: initVideoUri,
cancelRef,
}: Props & {
cancelRef?: React.RefObject<CancelRef>
cancelRef?: React.RefObject<CancelRef | null>
}) => {
const {currentAccount} = useSession()
const agent = useAgent()
@@ -1,5 +1,3 @@
import type React from 'react'
import {type ComposerImage} from '#/state/gallery'
import type * as Dialog from '#/components/Dialog'
@@ -112,7 +112,7 @@ function EditImageInner({
aspectRatio,
}: Required<Pick<EditImageDialogProps, 'image'>> &
Omit<EditImageDialogProps, 'control' | 'image'> & {
saveRef: React.RefObject<{save: () => Promise<void>}>
saveRef: React.RefObject<{save: () => Promise<void>} | null>
}) {
const t = useTheme()
const [isDragging, setIsDragging] = useState(false)
+8 -1
View File
@@ -1,4 +1,11 @@
import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {
type JSX,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import {View} from 'react-native'
import {type AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api'
import {msg} from '@lingui/macro'
+2 -1
View File
@@ -1,7 +1,8 @@
import React from 'react'
import {type JSX} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {useSession} from '#/state/session'
@@ -1,3 +1,4 @@
import {type JSX} from 'react'
import {View} from 'react-native'
import Animated from 'react-native-reanimated'
import {msg} from '@lingui/macro'
+1 -1
View File
@@ -1,4 +1,4 @@
import React, {useCallback} from 'react'
import React, {type JSX, useCallback} from 'react'
import {
Dimensions,
type GestureResponderEvent,
+5 -5
View File
@@ -1,13 +1,13 @@
import React from 'react'
import React, {type JSX} from 'react'
import {
ActivityIndicator,
FlatList as RNFlatList,
RefreshControl,
StyleProp,
type StyleProp,
View,
ViewStyle,
type ViewStyle,
} from 'react-native'
import {AppBskyGraphDefs as GraphDefs} from '@atproto/api'
import {type AppBskyGraphDefs as GraphDefs} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -16,7 +16,7 @@ import {cleanError} from '#/lib/strings/errors'
import {s} from '#/lib/styles'
import {logger} from '#/logger'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {MyListsFilter, useMyListsQuery} from '#/state/queries/my-lists'
import {type MyListsFilter, useMyListsQuery} from '#/state/queries/my-lists'
import {atoms as a, useTheme} from '#/alf'
import {BulletList_Stroke2_Corner0_Rounded as ListIcon} from '#/components/icons/BulletList'
import * as ListCard from '#/components/ListCard'
@@ -248,7 +248,7 @@ let NotificationFeedItem = ({
: ''
let a11yLabel = ''
let notificationContent: ReactElement
let notificationContent: ReactElement<any>
let icon = (
<HeartIconFilled
size="xl"
+1
View File
@@ -1,4 +1,5 @@
import {
type JSX,
memo,
useCallback,
useContext,
+1
View File
@@ -1,5 +1,6 @@
import {
Children,
type JSX,
useCallback,
useImperativeHandle,
useRef,
+1 -1
View File
@@ -1,4 +1,4 @@
import {memo, useCallback, useEffect, useRef, useState} from 'react'
import {type JSX, memo, useCallback, useEffect, useRef, useState} from 'react'
import {
type LayoutChangeEvent,
type NativeScrollEvent,
+8 -3
View File
@@ -1,11 +1,16 @@
import * as React from 'react'
import {ScrollView, View} from 'react-native'
import {type JSX} from 'react'
import {type ScrollView, View} from 'react-native'
import {useAnimatedRef} from 'react-native-reanimated'
import {Pager, PagerRef, RenderTabBarFnProps} from '#/view/com/pager/Pager'
import {
Pager,
type PagerRef,
type RenderTabBarFnProps,
} from '#/view/com/pager/Pager'
import {atoms as a, web} from '#/alf'
import * as Layout from '#/components/Layout'
import {ListMethods} from '../util/List'
import {type ListMethods} from '../util/List'
import {TabBar} from './TabBar'
export interface PagerWithHeaderChildParams {
+3 -1
View File
@@ -106,7 +106,9 @@ export function TabBar({
<PressableWithHover
testID={`${testID}-selector-${i}`}
key={`${item}-${i}`}
ref={node => (itemRefs.current[i] = node as any)}
ref={node => {
itemRefs.current[i] = node as any
}}
style={styles.item}
hoverStyle={t.atoms.bg_contrast_25}
onPress={() => onPressItem(i)}
+9 -1
View File
@@ -1,4 +1,12 @@
import {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {
type JSX,
memo,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import {
ActivityIndicator,
AppState,
-1
View File
@@ -1,5 +1,4 @@
import {View, type ViewStyle} from 'react-native'
import type React from 'react'
/**
* This utility function captures events and stops
+1 -1
View File
@@ -1,4 +1,4 @@
import {memo, useCallback, useMemo} from 'react'
import {type JSX, memo, useCallback, useMemo} from 'react'
import {
type GestureResponderEvent,
Platform,
+1 -1
View File
@@ -57,7 +57,7 @@ let List = React.forwardRef<ListMethods, ListProps>(
...props
},
ref,
): React.ReactElement => {
): React.ReactElement<any> => {
const isScrolledDown = useSharedValue(false)
const t = useTheme()
const dedupe = useDedupe(400)
+13 -6
View File
@@ -1,4 +1,10 @@
import React, {isValidElement, memo, startTransition, useRef} from 'react'
import React, {
isValidElement,
type JSX,
memo,
startTransition,
useRef,
} from 'react'
import {
type FlatListProps,
StyleSheet,
@@ -202,6 +208,7 @@ function ListImpl<ItemT>(
behavior: animated ? 'smooth' : 'instant',
})
},
scrollToEnd({animated = true}: {animated?: boolean}) {
const element = getScrollableNode()
element?.scrollTo({
@@ -382,10 +389,10 @@ function EdgeVisibility({
containerRef,
onVisibleChange,
}: {
root?: React.RefObject<HTMLDivElement> | null
root?: React.RefObject<HTMLDivElement | null> | null
topMargin?: string
bottomMargin?: string
containerRef: React.RefObject<Element>
containerRef: React.RefObject<Element | null>
onVisibleChange: (isVisible: boolean) => void
}) {
const [containerHeight, setContainerHeight] = React.useState(0)
@@ -404,7 +411,7 @@ function EdgeVisibility({
}
function useResizeObserver(
ref: React.RefObject<Element>,
ref: React.RefObject<Element | null>,
onResize: undefined | ((w: number, h: number) => void),
) {
const handleResize = useNonReactiveCallback(onResize ?? (() => {}))
@@ -509,7 +516,7 @@ let Visibility = ({
onVisibleChange,
style,
}: {
root?: React.RefObject<HTMLDivElement> | null
root?: React.RefObject<HTMLDivElement | null> | null
topMargin?: string
bottomMargin?: string
onVisibleChange: (isVisible: boolean) => void
@@ -551,7 +558,7 @@ Visibility = React.memo(Visibility)
export const List = memo(React.forwardRef(ListImpl)) as <ItemT>(
props: ListProps<ItemT> & {ref?: React.Ref<ListMethods>},
) => React.ReactElement
) => React.ReactElement<any>
// https://stackoverflow.com/questions/7944460/detect-safari-browser
-1
View File
@@ -4,7 +4,6 @@ import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useQueryClient} from '@tanstack/react-query'
import type React from 'react'
import {useActorStatus} from '#/lib/actor-status'
import {makeProfileLink} from '#/lib/routes/links'
+2 -2
View File
@@ -1,5 +1,5 @@
import React from 'react'
import {I18n} from '@lingui/core'
import React, {type JSX} from 'react'
import {type I18n} from '@lingui/core'
import {useLingui} from '@lingui/react'
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
+2
View File
@@ -1,3 +1,5 @@
import {type JSX} from 'react'
import {Header} from '#/components/Layout'
/**
+4 -4
View File
@@ -1,7 +1,7 @@
import React, {useEffect, useState} from 'react'
import React, {type JSX, useEffect, useState} from 'react'
import {
NativeScrollEvent,
NativeSyntheticEvent,
type NativeScrollEvent,
type NativeSyntheticEvent,
Pressable,
RefreshControl,
ScrollView,
@@ -36,7 +36,7 @@ export const ViewSelector = React.forwardRef<
renderItem: (item: any) => JSX.Element
ListFooterComponent?:
| React.ComponentType<any>
| React.ReactElement
| React.ReactElement<any>
| null
| undefined
onSelectView?: (viewIndex: number) => void
+2 -2
View File
@@ -1,5 +1,5 @@
import {ComponentProps} from 'react'
import {StyleSheet, TouchableWithoutFeedback} from 'react-native'
import {type ComponentProps, type JSX} from 'react'
import {StyleSheet, type TouchableWithoutFeedback} from 'react-native'
import Animated from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {LinearGradient} from 'expo-linear-gradient'
@@ -161,7 +161,7 @@ function DropdownContent({
menuRef,
}: {
items: DropdownItem[]
menuRef: React.RefObject<HTMLDivElement>
menuRef: React.RefObject<HTMLDivElement | null>
}) {
const pal = usePalette('default')
const theme = useTheme()
-1
View File
@@ -4,7 +4,6 @@ import {Image, type ImageStyle} from 'expo-image'
import {type AppBskyEmbedImages} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {type Dimensions} from '#/lib/media/types'
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
+1 -1
View File
@@ -22,7 +22,7 @@ export function Dialogs() {
React.useState<boolean>()
const [shouldRenderUnmountTest, setShouldRenderUnmountTest] =
React.useState(false)
const unmountTestInterval = React.useRef<number>()
const unmountTestInterval = React.useRef<number>(undefined)
const onUnmountTestStartPressWithClose = () => {
setShouldRenderUnmountTest(true)
+1 -1
View File
@@ -1,4 +1,4 @@
import React, {type ComponentProps} from 'react'
import React, {type ComponentProps, type JSX} from 'react'
import {Linking, ScrollView, TouchableOpacity, View} from 'react-native'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {msg, Plural, plural, Trans} from '@lingui/macro'
+1 -1
View File
@@ -1,4 +1,4 @@
import {useCallback} from 'react'
import {type JSX, useCallback} from 'react'
import {type GestureResponderEvent, View} from 'react-native'
import Animated from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
+1 -1
View File
@@ -230,7 +230,7 @@ export function BottomBarWeb() {
}
const NavItem: React.FC<{
children: (props: {isActive: boolean}) => React.ReactChild
children: (props: {isActive: boolean}) => React.ReactNode
href: string
routeName: string
hasNew?: boolean
+1 -1
View File
@@ -1,4 +1,4 @@
import {useCallback, useMemo, useState} from 'react'
import {type JSX, useCallback, useMemo, useState} from 'react'
import {StyleSheet, View} from 'react-native'
import {type AppBskyActorDefs} from '@atproto/api'
import {msg, plural, Trans} from '@lingui/macro'
+22 -41
View File
@@ -7589,11 +7589,6 @@
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/prop-types@*":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/psl@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/psl/-/psl-1.1.1.tgz#3ba9e6d4bd2a32652a639fd5df7e539151d0a3b2"
@@ -7609,25 +7604,16 @@
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
"@types/react-dom@^19.1.2":
version "19.1.3"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.1.3.tgz#3f0c60804441bf34d19f8dd0d44405c0c0e21bfa"
integrity sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg==
"@types/react-dom@^19.1.8":
version "19.1.9"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.1.9.tgz#5ab695fce1e804184767932365ae6569c11b4b4b"
integrity sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==
"@types/react-responsive@^8.0.5":
version "8.0.5"
resolved "https://registry.yarnpkg.com/@types/react-responsive/-/react-responsive-8.0.5.tgz#77769862d2a0711434feb972be08e3e6c334440a"
integrity sha512-k3gQJgI87oP5IrVZe//3LKJFnAeFaqqWmmtl5eoYL2H3HqFcIhUaE30kRK1CsW3DHdojZxcVj4ZNc2ClsEu2PA==
"@types/react@^19.1.12":
version "19.1.12"
resolved "https://registry.yarnpkg.com/@types/react/-/react-19.1.12.tgz#7bfaa76aabbb0b4fe0493c21a3a7a93d33e8937b"
integrity sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18":
version "18.2.20"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.20.tgz#1605557a83df5c8a2cc4eeb743b3dfc0eb6aaeb2"
integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/retry@0.12.0":
@@ -7635,11 +7621,6 @@
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
"@types/scheduler@*":
version "0.16.3"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
"@types/semver@^7.3.12":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a"
@@ -14515,10 +14496,10 @@ marky@^1.2.2:
resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0"
integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==
matchmediaquery@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.3.1.tgz#8247edc47e499ebb7c58f62a9ff9ccf5b815c6d7"
integrity sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==
matchmediaquery@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.4.2.tgz#22582bd4ae63ad9f54c53001bba80cbed0f7eafa"
integrity sha512-wrZpoT50ehYOudhDjt/YvUJc6eUzcdFPdmbizfgvswCKNHD1/OBOHYJpHie+HXpu6bSkEGieFMYk6VuutaiRfA==
dependencies:
css-mediaquery "^0.1.2"
@@ -17124,15 +17105,15 @@ react-remove-scroll@^2.6.3:
use-callback-ref "^1.3.3"
use-sidecar "^1.1.3"
react-responsive@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-9.0.2.tgz#34531ca77a61e7a8775714016d21241df7e4205c"
integrity sha512-+4CCab7z8G8glgJoRjAwocsgsv6VA2w7JPxFWHRc7kvz8mec1/K5LutNC2MG28Mn8mu6+bu04XZxHv5gyfT7xQ==
react-responsive@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-10.0.1.tgz#293d4d2562da93409861216f0110d146c5676eb3"
integrity sha512-OM5/cRvbtUWEX8le8RCT8scA8y2OPtb0Q/IViEyCEM5FBN8lRrkUOZnu87I88A6njxDldvxG+rLBxWiA7/UM9g==
dependencies:
hyphenate-style-name "^1.0.0"
matchmediaquery "^0.3.0"
matchmediaquery "^0.4.2"
prop-types "^15.6.1"
shallow-equal "^1.2.1"
shallow-equal "^3.1.0"
react-server-dom-webpack@~19.0.0:
version "19.0.0"
@@ -17985,10 +17966,10 @@ sf-symbols-typescript@^1.0.0:
resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-1.0.0.tgz#94e9210bf27e7583f9749a0d07bd4f4937ea488f"
integrity sha512-DkS7q3nN68dEMb4E18HFPDAvyrjDZK9YAQQF2QxeFu9gp2xRDXFMF8qLJ1EmQ/qeEGQmop4lmMM1WtYJTIcCMw==
shallow-equal@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
shallow-equal@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-3.1.0.tgz#e7a54bac629c7f248eff6c2f5b63122ba4320bec"
integrity sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==
sharp@^0.33.5:
version "0.33.5"