diff --git a/package.json b/package.json --- a/package.json +++ b/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock --- a/yarn.lock +++ b/yarn.lock @@ -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,36 +7604,22 @@ 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": version "0.12.0" 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" @@ -14515,10 +14496,10 @@ 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 @@ 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 @@ 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" diff --git a/patches/@discord+bottom-sheet+4.6.1.patch b/patches/@discord+bottom-sheet+4.6.1.patch new file mode 100644 --- /dev/null +++ b/patches/@discord+bottom-sheet+4.6.1.patch @@ -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(); ++ const callbackRef = useRef(undefined); + const memoCallback = useCallback( + (...args: any) => callbackRef.current && callbackRef.current(...args), + [] diff --git a/src/Navigation.tsx b/src/Navigation.tsx --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -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' diff --git a/src/alf/typography.tsx b/src/alf/typography.tsx --- a/src/alf/typography.tsx +++ b/src/alf/typography.tsx @@ -3,7 +3,6 @@ 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' diff --git a/src/components/Button.tsx b/src/components/Button.tsx --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -71,8 +71,8 @@ export type ButtonContext = VariantProps & ButtonState type NonTextElements = - | React.ReactElement - | Iterable + | React.ReactElement + | Iterable | null | undefined | boolean> export type ButtonProps = Pick< PressableProps, diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -2,7 +2,6 @@ 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' diff --git a/src/components/Portal.tsx b/src/components/Portal.tsx --- a/src/components/Portal.tsx +++ b/src/components/Portal.tsx @@ -10,7 +10,7 @@ useState, } from 'react' -type Component = React.ReactElement +type Component = React.ReactElement type ContextType = { outlet: Component | null diff --git a/src/lib/merge-refs.ts b/src/lib/merge-refs.ts --- a/src/lib/merge-refs.ts +++ b/src/lib/merge-refs.ts @@ -13,7 +13,7 @@ * returns a ref callback function that can be used to merge multiple refs into a single ref. */ export function mergeRefs( - refs: Array | React.LegacyRef>, + refs: Array | React.Ref>, ): React.RefCallback { return value => { refs.forEach(ref => { diff --git a/src/components/ContextMenu/index.tsx b/src/components/ContextMenu/index.tsx --- a/src/components/ContextMenu/index.tsx +++ b/src/components/ContextMenu/index.tsx @@ -119,7 +119,8 @@ const hoverablesSV = useSharedValue< Record >({}) - const syncHoverablesThrottleRef = useRef>() + const syncHoverablesThrottleRef = + useRef>(undefined) const [hoveredMenuItem, setHoveredMenuItem] = useState(null) const onHoverableTouchUp = useCallback((id: string) => { diff --git a/src/components/ContextMenu/types.ts b/src/components/ContextMenu/types.ts --- a/src/components/ContextMenu/types.ts +++ b/src/components/ContextMenu/types.ts @@ -5,7 +5,6 @@ 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 { diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -5,7 +5,6 @@ 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 DialogControlProps = DialogControlRefProps & { id: string - ref: React.RefObject + ref: React.RefObject isOpen?: boolean } diff --git a/src/components/ProfileHoverCard/types.ts b/src/components/ProfileHoverCard/types.ts --- a/src/components/ProfileHoverCard/types.ts +++ b/src/components/ProfileHoverCard/types.ts @@ -1,5 +1,3 @@ -import type React from 'react' - import {type ViewStyleProp} from '#/alf' export type ProfileHoverCardProps = ViewStyleProp & { diff --git a/src/components/ProgressGuide/FollowDialog.tsx b/src/components/ProgressGuide/FollowDialog.tsx --- a/src/components/ProgressGuide/FollowDialog.tsx +++ b/src/components/ProgressGuide/FollowDialog.tsx @@ -293,8 +293,8 @@ interestsDisplayNames, }: { guide: Follow10ProgressGuide - inputRef: React.RefObject - listRef: React.RefObject + inputRef: React.RefObject + listRef: React.RefObject onSelectTab: (v: string) => void searchText: string setHeaderHeight: (v: number) => void @@ -565,7 +565,7 @@ }: { onChangeText: (text: string) => void onEscape: () => void - inputRef: React.RefObject + inputRef: React.RefObject defaultValue: string }) { const t = useTheme() diff --git a/src/components/ProgressGuide/Toast.tsx b/src/components/ProgressGuide/Toast.tsx --- a/src/components/ProgressGuide/Toast.tsx +++ b/src/components/ProgressGuide/Toast.tsx @@ -14,7 +14,7 @@ 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 @@ const translateY = useSharedValue(0) const opacity = useSharedValue(0) const animatedCheckRef = React.useRef(null) - const timeoutRef = React.useRef() + const timeoutRef = React.useRef(undefined) const winDim = useWindowDimensions() /** diff --git a/src/components/Select/types.ts b/src/components/Select/types.ts --- a/src/components/Select/types.ts +++ b/src/components/Select/types.ts @@ -160,7 +160,7 @@ item: T, index: number, selectedValue?: string | null, - ) => React.ReactElement + ) => React.ReactElement /* * Extracts the value from an item. Defaults to `item => item.value` */ diff --git a/src/components/dialogs/GifSelect.tsx b/src/components/dialogs/GifSelect.tsx --- a/src/components/dialogs/GifSelect.tsx +++ b/src/components/dialogs/GifSelect.tsx @@ -37,7 +37,7 @@ onClose, onSelectGif: onSelectGifProp, }: { - controlRef: React.RefObject<{open: () => void}> + controlRef: React.RefObject<{open: () => void} | null> onClose?: () => void onSelectGif: (gif: Gif) => void }) { diff --git a/src/components/dialogs/SearchablePeopleList.tsx b/src/components/dialogs/SearchablePeopleList.tsx --- a/src/components/dialogs/SearchablePeopleList.tsx +++ b/src/components/dialogs/SearchablePeopleList.tsx @@ -484,7 +484,7 @@ value: string onChangeText: (text: string) => void onEscape: () => void - inputRef: React.RefObject + inputRef: React.RefObject }) { const t = useTheme() const {_} = useLingui() diff --git a/src/components/dms/ActionsWrapper.web.tsx b/src/components/dms/ActionsWrapper.web.tsx --- a/src/components/dms/ActionsWrapper.web.tsx +++ b/src/components/dms/ActionsWrapper.web.tsx @@ -3,7 +3,6 @@ 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' diff --git a/src/components/forms/InputGroup.tsx b/src/components/forms/InputGroup.tsx --- a/src/components/forms/InputGroup.tsx +++ b/src/components/forms/InputGroup.tsx @@ -23,9 +23,12 @@ {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, diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -28,7 +28,7 @@ import {Text} from '#/components/Typography' const Context = createContext<{ - inputRef: React.RefObject | null + inputRef: React.RefObject | null isInvalid: boolean hovered: boolean onHoverIn: () => void @@ -152,7 +152,7 @@ value?: string onChangeText?: (value: string) => void isInvalid?: boolean - inputRef?: React.RefObject | React.ForwardedRef + inputRef?: React.RefObject | React.ForwardedRef } export function createInput(Component: typeof TextInput) { diff --git a/src/components/forms/ToggleButton.tsx b/src/components/forms/ToggleButton.tsx --- a/src/components/forms/ToggleButton.tsx +++ b/src/components/forms/ToggleButton.tsx @@ -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 @@ type ItemProps = Omit & AccessibilityProps & { - children: React.ReactElement + children: React.ReactElement testID?: string } diff --git a/src/components/hooks/useFullscreen.ts b/src/components/hooks/useFullscreen.ts --- a/src/components/hooks/useFullscreen.ts +++ b/src/components/hooks/useFullscreen.ts @@ -14,7 +14,7 @@ return () => document.removeEventListener('fullscreenchange', onChange) } -export function useFullscreen(ref?: React.RefObject) { +export function useFullscreen(ref?: React.RefObject) { if (!isWeb) throw new Error("'useFullscreen' is a web-only hook") const isFullscreen = useSyncExternalStore(fullscreenSubscribe, () => Boolean(document.fullscreenElement), diff --git a/src/components/moderation/LabelPreference.tsx b/src/components/moderation/LabelPreference.tsx --- a/src/components/moderation/LabelPreference.tsx +++ b/src/components/moderation/LabelPreference.tsx @@ -5,7 +5,6 @@ } 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' diff --git a/src/lib/hooks/useAnimatedValue.ts b/src/lib/hooks/useAnimatedValue.ts --- a/src/lib/hooks/useAnimatedValue.ts +++ b/src/lib/hooks/useAnimatedValue.ts @@ -2,7 +2,7 @@ import {Animated} from 'react-native' export function useAnimatedValue(initialValue: number) { - const lazyRef = React.useRef() + const lazyRef = React.useRef(undefined) if (lazyRef.current === undefined) { lazyRef.current = new Animated.Value(initialValue) diff --git a/src/lib/hooks/useOTAUpdates.ts b/src/lib/hooks/useOTAUpdates.ts --- a/src/lib/hooks/useOTAUpdates.ts +++ b/src/lib/hooks/useOTAUpdates.ts @@ -127,7 +127,7 @@ const appState = React.useRef('active') const lastMinimize = React.useRef(0) const ranInitialCheck = React.useRef(false) - const timeout = React.useRef() + const timeout = React.useRef(undefined) const {currentlyRunning, isUpdatePending} = useUpdates() const currentChannel = currentlyRunning?.channel diff --git a/src/state/shell/index.tsx b/src/state/shell/index.tsx --- a/src/state/shell/index.tsx +++ b/src/state/shell/index.tsx @@ -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' diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -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' diff --git a/src/components/PostControls/PostMenu/index.tsx b/src/components/PostControls/PostMenu/index.tsx --- a/src/components/PostControls/PostMenu/index.tsx +++ b/src/components/PostControls/PostMenu/index.tsx @@ -8,7 +8,6 @@ } 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' diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx --- a/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx +++ b/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx @@ -3,7 +3,6 @@ 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' diff --git a/src/components/PostControls/ShareMenu/index.tsx b/src/components/PostControls/ShareMenu/index.tsx --- a/src/components/PostControls/ShareMenu/index.tsx +++ b/src/components/PostControls/ShareMenu/index.tsx @@ -9,7 +9,6 @@ } 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' diff --git a/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx b/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx --- a/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx +++ b/src/screens/Signup/StepCaptcha/CaptchaWebView.tsx @@ -31,7 +31,7 @@ onError: (error: unknown) => void }) { const startedAt = useRef(Date.now()) - const successTo = useRef() + const successTo = useRef(undefined) useEffect(() => { return () => { diff --git a/src/screens/Signup/StepInfo/Policies.tsx b/src/screens/Signup/StepInfo/Policies.tsx --- a/src/screens/Signup/StepInfo/Policies.tsx +++ b/src/screens/Signup/StepInfo/Policies.tsx @@ -72,7 +72,7 @@ ) } - let els: ReactElement + let els: ReactElement if (tos && pp) { els = ( diff --git a/src/screens/Signup/StepInfo/index.tsx b/src/screens/Signup/StepInfo/index.tsx --- a/src/screens/Signup/StepInfo/index.tsx +++ b/src/screens/Signup/StepInfo/index.tsx @@ -60,7 +60,7 @@ const [hasWarnedEmail, setHasWarnedEmail] = React.useState(false) - const tldtsRef = React.useRef() + const tldtsRef = React.useRef(undefined) React.useEffect(() => { // @ts-expect-error - valid path import('tldts/dist/index.cjs.min.js').then(tldts => { diff --git a/src/state/queries/postgate/index.ts b/src/state/queries/postgate/index.ts --- a/src/state/queries/postgate/index.ts +++ b/src/state/queries/postgate/index.ts @@ -173,7 +173,7 @@ const agent = useAgent() const queryClient = useQueryClient() const getPosts = useGetPosts() - const prevEmbed = React.useRef() + const prevEmbed = React.useRef(undefined) return useMutation({ mutationFn: async ({ diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -174,7 +174,7 @@ videoUri: initVideoUri, cancelRef, }: Props & { - cancelRef?: React.RefObject + cancelRef?: React.RefObject }) => { const {currentAccount} = useSession() const agent = useAgent() diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -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' diff --git a/src/view/com/home/HomeHeaderLayout.web.tsx b/src/view/com/home/HomeHeaderLayout.web.tsx --- a/src/view/com/home/HomeHeaderLayout.web.tsx +++ b/src/view/com/home/HomeHeaderLayout.web.tsx @@ -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' diff --git a/src/view/com/home/HomeHeaderLayoutMobile.tsx b/src/view/com/home/HomeHeaderLayoutMobile.tsx --- a/src/view/com/home/HomeHeaderLayoutMobile.tsx +++ b/src/view/com/home/HomeHeaderLayoutMobile.tsx @@ -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' diff --git a/src/view/com/lists/ListMembers.tsx b/src/view/com/lists/ListMembers.tsx --- a/src/view/com/lists/ListMembers.tsx +++ b/src/view/com/lists/ListMembers.tsx @@ -1,4 +1,4 @@ -import React, {useCallback} from 'react' +import React, {type JSX, useCallback} from 'react' import { Dimensions, type GestureResponderEvent, diff --git a/src/view/com/lists/MyLists.tsx b/src/view/com/lists/MyLists.tsx --- a/src/view/com/lists/MyLists.tsx +++ b/src/view/com/lists/MyLists.tsx @@ -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 {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' diff --git a/src/view/com/notifications/NotificationFeedItem.tsx b/src/view/com/notifications/NotificationFeedItem.tsx --- a/src/view/com/notifications/NotificationFeedItem.tsx +++ b/src/view/com/notifications/NotificationFeedItem.tsx @@ -248,7 +248,7 @@ : '' let a11yLabel = '' - let notificationContent: ReactElement + let notificationContent: ReactElement let icon = ( (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)} diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -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, diff --git a/src/view/com/util/EventStopper.tsx b/src/view/com/util/EventStopper.tsx --- a/src/view/com/util/EventStopper.tsx +++ b/src/view/com/util/EventStopper.tsx @@ -1,5 +1,4 @@ import {View, type ViewStyle} from 'react-native' -import type React from 'react' /** * This utility function captures events and stops diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -1,4 +1,4 @@ -import {memo, useCallback, useMemo} from 'react' +import {type JSX, memo, useCallback, useMemo} from 'react' import { type GestureResponderEvent, Platform, diff --git a/src/view/com/util/List.tsx b/src/view/com/util/List.tsx --- a/src/view/com/util/List.tsx +++ b/src/view/com/util/List.tsx @@ -57,7 +57,7 @@ ...props }, ref, - ): React.ReactElement => { + ): React.ReactElement => { const isScrolledDown = useSharedValue(false) const t = useTheme() const dedupe = useDedupe(400) diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -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 @@ behavior: animated ? 'smooth' : 'instant', }) }, + scrollToEnd({animated = true}: {animated?: boolean}) { const element = getScrollableNode() element?.scrollTo({ @@ -382,10 +389,10 @@ containerRef, onVisibleChange, }: { - root?: React.RefObject | null + root?: React.RefObject | null topMargin?: string bottomMargin?: string - containerRef: React.RefObject + containerRef: React.RefObject onVisibleChange: (isVisible: boolean) => void }) { const [containerHeight, setContainerHeight] = React.useState(0) @@ -404,7 +411,7 @@ } function useResizeObserver( - ref: React.RefObject, + ref: React.RefObject, onResize: undefined | ((w: number, h: number) => void), ) { const handleResize = useNonReactiveCallback(onResize ?? (() => {})) @@ -509,7 +516,7 @@ onVisibleChange, style, }: { - root?: React.RefObject | null + root?: React.RefObject | null topMargin?: string bottomMargin?: string onVisibleChange: (isVisible: boolean) => void @@ -551,7 +558,7 @@ export const List = memo(React.forwardRef(ListImpl)) as ( props: ListProps & {ref?: React.Ref}, -) => React.ReactElement +) => React.ReactElement // https://stackoverflow.com/questions/7944460/detect-safari-browser diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -4,7 +4,6 @@ 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' diff --git a/src/view/com/util/TimeElapsed.tsx b/src/view/com/util/TimeElapsed.tsx --- a/src/view/com/util/TimeElapsed.tsx +++ b/src/view/com/util/TimeElapsed.tsx @@ -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' diff --git a/src/view/com/util/ViewHeader.tsx b/src/view/com/util/ViewHeader.tsx --- a/src/view/com/util/ViewHeader.tsx +++ b/src/view/com/util/ViewHeader.tsx @@ -1,3 +1,5 @@ +import {type JSX} from 'react' + import {Header} from '#/components/Layout' /** diff --git a/src/view/com/util/ViewSelector.tsx b/src/view/com/util/ViewSelector.tsx --- a/src/view/com/util/ViewSelector.tsx +++ b/src/view/com/util/ViewSelector.tsx @@ -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 @@ renderItem: (item: any) => JSX.Element ListFooterComponent?: | React.ComponentType - | React.ReactElement + | React.ReactElement | null | undefined onSelectView?: (viewIndex: number) => void diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx --- a/src/view/screens/Storybook/Dialogs.tsx +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -22,7 +22,7 @@ React.useState() const [shouldRenderUnmountTest, setShouldRenderUnmountTest] = React.useState(false) - const unmountTestInterval = React.useRef() + const unmountTestInterval = React.useRef(undefined) const onUnmountTestStartPressWithClose = () => { setShouldRenderUnmountTest(true) diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx --- a/src/view/shell/bottom-bar/BottomBar.tsx +++ b/src/view/shell/bottom-bar/BottomBar.tsx @@ -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' diff --git a/src/view/shell/bottom-bar/BottomBarWeb.tsx b/src/view/shell/bottom-bar/BottomBarWeb.tsx --- a/src/view/shell/bottom-bar/BottomBarWeb.tsx +++ b/src/view/shell/bottom-bar/BottomBarWeb.tsx @@ -230,7 +230,7 @@ } const NavItem: React.FC<{ - children: (props: {isActive: boolean}) => React.ReactChild + children: (props: {isActive: boolean}) => React.ReactNode href: string routeName: string hasNew?: boolean diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -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' diff --git a/src/components/Post/Embed/VideoEmbed/index.web.tsx b/src/components/Post/Embed/VideoEmbed/index.web.tsx --- a/src/components/Post/Embed/VideoEmbed/index.web.tsx +++ b/src/components/Post/Embed/VideoEmbed/index.web.tsx @@ -10,7 +10,6 @@ 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 @@ useActiveVideoWeb() const [onScreen, setOnScreen] = useState(false) const [isFullscreen] = useFullscreen() - const lastKnownTime = useRef() + const lastKnownTime = useRef(undefined) useEffect(() => { if (!ref.current) return diff --git a/src/view/com/composer/photos/EditImageDialog.tsx b/src/view/com/composer/photos/EditImageDialog.tsx --- a/src/view/com/composer/photos/EditImageDialog.tsx +++ b/src/view/com/composer/photos/EditImageDialog.tsx @@ -1,5 +1,3 @@ -import type React from 'react' - import {type ComposerImage} from '#/state/gallery' import type * as Dialog from '#/components/Dialog' diff --git a/src/view/com/composer/photos/EditImageDialog.web.tsx b/src/view/com/composer/photos/EditImageDialog.web.tsx --- a/src/view/com/composer/photos/EditImageDialog.web.tsx +++ b/src/view/com/composer/photos/EditImageDialog.web.tsx @@ -112,7 +112,7 @@ aspectRatio, }: Required> & Omit & { - saveRef: React.RefObject<{save: () => Promise}> + saveRef: React.RefObject<{save: () => Promise} | null> }) { const t = useTheme() const [isDragging, setIsDragging] = useState(false) diff --git a/src/view/com/util/fab/FABInner.tsx b/src/view/com/util/fab/FABInner.tsx --- a/src/view/com/util/fab/FABInner.tsx +++ b/src/view/com/util/fab/FABInner.tsx @@ -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' diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -161,7 +161,7 @@ menuRef, }: { items: DropdownItem[] - menuRef: React.RefObject + menuRef: React.RefObject }) { const pal = usePalette('default') const theme = useTheme() diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -4,7 +4,6 @@ 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' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx @@ -139,7 +139,7 @@ playlist: string setHasSubtitleTrack: (v: boolean) => void setError: (v: Error | null) => void - videoRef: React.RefObject + videoRef: React.RefObject setHlsLoading: (v: boolean) => void }) { const [Hls, setHls] = useState( diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoFallback.tsx @@ -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' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/ControlButton.tsx @@ -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' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/Scrubber.tsx @@ -2,7 +2,6 @@ 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' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx @@ -46,14 +46,14 @@ hlsLoading, hasSubtitleTrack, }: { - videoRef: React.RefObject - hlsRef: React.RefObject + videoRef: React.RefObject + hlsRef: React.RefObject active: boolean setActive: () => void focused: boolean setFocused: (focused: boolean) => void onScreen: boolean - fullscreenRef: React.RefObject + fullscreenRef: React.RefObject hlsLoading: boolean hasSubtitleTrack: boolean }) { @@ -232,7 +232,7 @@ }, [onSeek, videoRef]) const [showCursor, setShowCursor] = useState(true) - const cursorTimeoutRef = useRef>() + const cursorTimeoutRef = useRef>(undefined) const onPointerMoveEmptySpace = useCallback(() => { setShowCursor(true) if (cursorTimeoutRef.current) { @@ -264,7 +264,7 @@ [hovered], ) - const timeoutRef = useRef>() + const timeoutRef = useRef>(undefined) const onHoverWithTimeout = useCallback(() => { onHover() diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VolumeControl.tsx @@ -3,7 +3,6 @@ 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' diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/utils.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/utils.tsx --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/utils.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/utils.tsx @@ -4,7 +4,7 @@ import {logger} from '#/logger' import {useVideoVolumeState} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' -export function useVideoElement(ref: RefObject) { +export function useVideoElement(ref: RefObject) { const [playing, setPlaying] = useState(false) const [muted, setMuted] = useState(true) const [currentTime, setCurrentTime] = useState(0)