diff --git a/bskyogcard/src/components/Butterfly.tsx b/bskyogcard/src/components/Butterfly.tsx index 5a4124975c..24cd4b2c4a 100644 --- a/bskyogcard/src/components/Butterfly.tsx +++ b/bskyogcard/src/components/Butterfly.tsx @@ -1,6 +1,6 @@ -import React from 'react' +import {type SVGAttributes} from 'react' -export function Butterfly(props: React.SVGAttributes) { +export function Butterfly(props: SVGAttributes) { return ( , 'src'> & {src: Buffer}, + props: Omit, 'src'> & {src: Buffer}, ) { const {src, ...others} = props return ( diff --git a/bskyogcard/src/components/StarterPack.tsx b/bskyogcard/src/components/StarterPack.tsx index 29bb8f32ab..32ec97e062 100644 --- a/bskyogcard/src/components/StarterPack.tsx +++ b/bskyogcard/src/components/StarterPack.tsx @@ -1,6 +1,5 @@ /* eslint-disable bsky-internal/avoid-unwrapped-text */ -import React from 'react' -import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api' +import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api' import {Butterfly} from './Butterfly.js' import {Img} from './Img.js' diff --git a/bskyogcard/src/routes/starter-pack.tsx b/bskyogcard/src/routes/starter-pack.tsx index 99a3e73fe5..1de450dc48 100644 --- a/bskyogcard/src/routes/starter-pack.tsx +++ b/bskyogcard/src/routes/starter-pack.tsx @@ -1,6 +1,5 @@ import assert from 'node:assert' -import React from 'react' import {type AppBskyGraphDefs, AtUri} from '@atproto/api' import resvg from '@resvg/resvg-js' import {type Express} from 'express' diff --git a/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx b/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx index 2604e0c0b8..765c729f72 100644 --- a/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx +++ b/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx @@ -1,4 +1,5 @@ -import * as React from 'react' +import {Component, createRef} from 'react' +import {type ComponentType, type ContextType, type RefObject} from 'react' import { Dimensions, type LayoutChangeEvent, @@ -21,9 +22,9 @@ import { Context as PortalContext, } from './BottomSheetPortal' -const NativeView: React.ComponentType< +const NativeView: ComponentType< BottomSheetViewProps & { - ref: React.RefObject + ref: RefObject style: StyleProp } > = requireNativeViewManager('BottomSheet') @@ -39,14 +40,14 @@ const IS_IOS15 = const IS_NON_E2E_ANDROID = Platform.OS === 'android' && Number(Platform.Version) < 35 -export class BottomSheetNativeComponent extends React.Component< +export class BottomSheetNativeComponent extends Component< BottomSheetViewProps, { open: boolean viewHeight?: number } > { - ref = React.createRef() + ref = createRef() static contextType = PortalContext @@ -79,7 +80,7 @@ export class BottomSheetNativeComponent extends React.Component< } render() { - const Portal = this.context as React.ContextType + const Portal = this.context as ContextType if (!Portal) { throw new Error( 'BottomSheet: You need to wrap your component tree with a to use the bottom sheet.', @@ -139,7 +140,7 @@ function BottomSheetNativeComponentInner({ onStateChange: ( event: NativeSyntheticEvent<{state: BottomSheetState}>, ) => void - nativeViewRef: React.RefObject + nativeViewRef: RefObject onLayout?: (event: LayoutChangeEvent) => void }) { const insets = useSafeAreaInsets() diff --git a/modules/bottom-sheet/src/BottomSheetPortal.tsx b/modules/bottom-sheet/src/BottomSheetPortal.tsx index e259a28626..0de548566a 100644 --- a/modules/bottom-sheet/src/BottomSheetPortal.tsx +++ b/modules/bottom-sheet/src/BottomSheetPortal.tsx @@ -1,20 +1,17 @@ -import React from 'react' +import {createContext, useContext, useMemo} from 'react' +import {type ElementType, type ReactNode} from 'react' import {createPortalGroup_INTERNAL} from './lib/Portal' -type PortalContext = React.ElementType<{children: React.ReactNode}> +type PortalContext = ElementType<{children: ReactNode}> -export const Context = React.createContext({} as PortalContext) +export const Context = createContext({} as PortalContext) Context.displayName = 'BottomSheetPortalContext' -export const useBottomSheetPortal_INTERNAL = () => React.useContext(Context) +export const useBottomSheetPortal_INTERNAL = () => useContext(Context) -export function BottomSheetPortalProvider({ - children, -}: { - children: React.ReactNode -}) { - const portal = React.useMemo(() => { +export function BottomSheetPortalProvider({children}: {children: ReactNode}) { + const portal = useMemo(() => { return createPortalGroup_INTERNAL() }, []) @@ -32,7 +29,7 @@ const defaultPortal = createPortalGroup_INTERNAL() export const BottomSheetOutlet = defaultPortal.Outlet -export function BottomSheetProvider({children}: {children: React.ReactNode}) { +export function BottomSheetProvider({children}: {children: ReactNode}) { return ( {children} diff --git a/modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider.tsx b/modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider.tsx index 6ecdd1d476..044a8b45b8 100644 --- a/modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider.tsx +++ b/modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider.tsx @@ -1,6 +1,7 @@ -import React from 'react' +import {createContext, useContext, useEffect, useMemo, useState} from 'react' +import {type ReactNode} from 'react' -import {BackgroundNotificationHandlerPreferences} from './ExpoBackgroundNotificationHandler.types' +import {type BackgroundNotificationHandlerPreferences} from './ExpoBackgroundNotificationHandler.types' import {BackgroundNotificationHandler} from './ExpoBackgroundNotificationHandlerModule' interface BackgroundNotificationPreferencesContext { @@ -11,30 +12,29 @@ interface BackgroundNotificationPreferencesContext { ) => void } -const Context = React.createContext( +const Context = createContext( {} as BackgroundNotificationPreferencesContext, ) -export const useBackgroundNotificationPreferences = () => - React.useContext(Context) +export const useBackgroundNotificationPreferences = () => useContext(Context) export function BackgroundNotificationPreferencesProvider({ children, }: { - children: React.ReactNode + children: ReactNode }) { const [preferences, setPreferences] = - React.useState({ + useState({ playSoundChat: true, }) - React.useEffect(() => { + useEffect(() => { ;(async () => { const prefs = await BackgroundNotificationHandler.getAllPrefsAsync() setPreferences(prefs) })() }, []) - const value = React.useMemo( + const value = useMemo( () => ({ preferences, setPref: async < diff --git a/modules/expo-bluesky-gif-view/src/GifView.tsx b/modules/expo-bluesky-gif-view/src/GifView.tsx index 87258de17b..f0051e19a9 100644 --- a/modules/expo-bluesky-gif-view/src/GifView.tsx +++ b/modules/expo-bluesky-gif-view/src/GifView.tsx @@ -1,17 +1,17 @@ -import React from 'react' +import {createRef, PureComponent} from 'react' +import {type ComponentType, type RefObject} from 'react' import {requireNativeModule} from 'expo' import {requireNativeViewManager} from 'expo-modules-core' -import {GifViewProps} from './GifView.types' +import {type GifViewProps} from './GifView.types' const NativeModule = requireNativeModule('ExpoBlueskyGifView') -const NativeView: React.ComponentType< - GifViewProps & {ref: React.RefObject} -> = requireNativeViewManager('ExpoBlueskyGifView') +const NativeView: ComponentType}> = + requireNativeViewManager('ExpoBlueskyGifView') -export class GifView extends React.PureComponent { +export class GifView extends PureComponent { // TODO native types, should all be the same as those in this class - private nativeRef: React.RefObject = React.createRef() + private nativeRef: RefObject = createRef() constructor(props: GifViewProps | Readonly) { super(props) diff --git a/modules/expo-bluesky-gif-view/src/GifView.web.tsx b/modules/expo-bluesky-gif-view/src/GifView.web.tsx index c197e01a1d..56ce92145d 100644 --- a/modules/expo-bluesky-gif-view/src/GifView.web.tsx +++ b/modules/expo-bluesky-gif-view/src/GifView.web.tsx @@ -1,11 +1,11 @@ -import * as React from 'react' +import {createRef, PureComponent} from 'react' +import {type RefObject} from 'react' import {StyleSheet} from 'react-native' -import {GifViewProps} from './GifView.types' +import {type GifViewProps} from './GifView.types' -export class GifView extends React.PureComponent { - private readonly videoPlayerRef: React.RefObject = - React.createRef() +export class GifView extends PureComponent { + private readonly videoPlayerRef: RefObject = createRef() private isLoaded = false constructor(props: GifViewProps | Readonly) { diff --git a/src/App.native.tsx b/src/App.native.tsx index aa6e9bd06b..cce4cbfd67 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -1,7 +1,8 @@ import '#/logger/sentry/setup' import '#/view/icons' -import React, {useEffect, useState} from 'react' +import {useEffect, useState} from 'react' +import * as React from 'react' import {GestureHandlerRootView} from 'react-native-gesture-handler' import {KeyboardProvider as KeyboardControllerProvider} from 'react-native-keyboard-controller' import { diff --git a/src/Splash.tsx b/src/Splash.tsx index 5d46ba617e..94a597403f 100644 --- a/src/Splash.tsx +++ b/src/Splash.tsx @@ -1,4 +1,5 @@ -import React, {useCallback, useEffect} from 'react' +import {forwardRef, useCallback, useEffect, useState} from 'react' +import {type PropsWithChildren} from 'react' import { AccessibilityInfo, Image as RNImage, @@ -29,7 +30,7 @@ const darkSplashImageUri = RNImage.resolveAssetSource( darkSplashImagePointer, ).uri -export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) { +export const Logo = forwardRef(function LogoImpl(props: SvgProps, ref) { const width = 1000 const height = width * (67 / 64) return ( @@ -51,19 +52,17 @@ type Props = { isReady: boolean } -export function Splash(props: React.PropsWithChildren) { +export function Splash(props: PropsWithChildren) { 'use no memo' const insets = useSafeAreaInsets() const intro = useSharedValue(0) const outroLogo = useSharedValue(0) const outroApp = useSharedValue(0) const outroAppOpacity = useSharedValue(0) - const [isAnimationComplete, setIsAnimationComplete] = React.useState(false) - const [isImageLoaded, setIsImageLoaded] = React.useState(false) - const [isLayoutReady, setIsLayoutReady] = React.useState(false) - const [reduceMotion, setReduceMotion] = React.useState( - false, - ) + const [isAnimationComplete, setIsAnimationComplete] = useState(false) + const [isImageLoaded, setIsImageLoaded] = useState(false) + const [isLayoutReady, setIsLayoutReady] = useState(false) + const [reduceMotion, setReduceMotion] = useState(false) const isReady = props.isReady && isImageLoaded && diff --git a/src/alf/index.tsx b/src/alf/index.tsx index 3aff9ddb57..d869521618 100644 --- a/src/alf/index.tsx +++ b/src/alf/index.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useCallback, useContext, useMemo, useState} from 'react' +import {type PropsWithChildren} from 'react' import {type Theme, type ThemeName} from '@bsky.app/alf' import { @@ -46,7 +47,7 @@ export type Alf = { /* * Context */ -export const Context = React.createContext({ +export const Context = createContext({ themeName: 'light', theme: themes.light, themes, @@ -64,16 +65,14 @@ Context.displayName = 'AlfContext' export function ThemeProvider({ children, theme: themeName, -}: React.PropsWithChildren<{theme: ThemeName}>) { - const [fontScale, setFontScale] = React.useState(() => +}: PropsWithChildren<{theme: ThemeName}>) { + const [fontScale, setFontScale] = useState(() => getFontScale(), ) - const [fontScaleMultiplier, setFontScaleMultiplier] = React.useState(() => + const [fontScaleMultiplier, setFontScaleMultiplier] = useState(() => computeFontScaleMultiplier(fontScale), ) - const setFontScaleAndPersist = React.useCallback< - Alf['fonts']['setFontScale'] - >( + const setFontScaleAndPersist = useCallback( fs => { setFontScale(fs) persistFontScale(fs) @@ -81,12 +80,10 @@ export function ThemeProvider({ }, [setFontScale], ) - const [fontFamily, setFontFamily] = React.useState( - () => getFontFamily(), + const [fontFamily, setFontFamily] = useState(() => + getFontFamily(), ) - const setFontFamilyAndPersist = React.useCallback< - Alf['fonts']['setFontFamily'] - >( + const setFontFamilyAndPersist = useCallback( ff => { setFontFamily(ff) persistFontFamily(ff) @@ -94,7 +91,7 @@ export function ThemeProvider({ [setFontFamily], ) - const value = React.useMemo( + const value = useMemo( () => ({ themes, themeName: themeName, @@ -122,12 +119,12 @@ export function ThemeProvider({ } export function useAlf() { - return React.useContext(Context) + return useContext(Context) } export function useTheme(theme?: ThemeName) { const alf = useAlf() - return React.useMemo(() => { + return useMemo(() => { return theme ? alf.themes[theme] : alf.theme }, [theme, alf]) } diff --git a/src/alf/util/useColorModeTheme.ts b/src/alf/util/useColorModeTheme.ts index 836aac3073..7cb9b12723 100644 --- a/src/alf/util/useColorModeTheme.ts +++ b/src/alf/util/useColorModeTheme.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useLayoutEffect} from 'react' import {type ColorSchemeName, useColorScheme} from 'react-native' import {type ThemeName} from '@bsky.app/alf' @@ -9,7 +9,7 @@ import {IS_WEB} from '#/env' export function useColorModeTheme(): ThemeName { const theme = useThemeName() - React.useLayoutEffect(() => { + useLayoutEffect(() => { updateDocument(theme) }, [theme]) diff --git a/src/alf/util/useGutters.ts b/src/alf/util/useGutters.ts index 265d0f23c2..f7dcef51bd 100644 --- a/src/alf/util/useGutters.ts +++ b/src/alf/util/useGutters.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useMemo} from 'react' import {type Breakpoint, useBreakpoints} from '#/alf/breakpoints' import * as tokens from '#/alf/tokens' @@ -52,7 +52,7 @@ export function useGutters([top, right, bottom, left]: Gutter[]) { bottom = top left = right } - return React.useMemo(() => { + return useMemo(() => { return { paddingTop: top === 0 ? 0 : gutters[top][activeBreakpoint || 'default'], paddingRight: diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx index 4a43bf283c..a65eeb0722 100644 --- a/src/components/AccountList.tsx +++ b/src/components/AccountList.tsx @@ -1,4 +1,4 @@ -import React, {useCallback} from 'react' +import {Fragment, useCallback} from 'react' import {View} from 'react-native' import {type AppBskyActorDefs} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -52,7 +52,7 @@ export function AccountList({ t.atoms.border_contrast_low, ]}> {accounts.map(account => ( - + p.did === account.did)} account={account} @@ -61,7 +61,7 @@ export function AccountList({ isPendingAccount={account.did === pendingDid} /> - + ))} + ) + }, +) diff --git a/src/components/dialogs/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx index 57dbf01ae7..d9de31dfdc 100644 --- a/src/components/dialogs/BirthDateSettings.tsx +++ b/src/components/dialogs/BirthDateSettings.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo, useState} from 'react' import {View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -125,12 +125,10 @@ function BirthdayInner({ }) { const {_} = useLingui() const cleanError = useCleanError() - const [date, setDate] = React.useState( - preferences.birthDate || getDateAgo(18), - ) + const [date, setDate] = useState(preferences.birthDate || getDateAgo(18)) const {isPending, error, mutateAsync: setBirthDate} = useBirthdateMutation() const hasChanged = date !== preferences.birthDate - const errorMessage = React.useMemo(() => { + const errorMessage = useMemo(() => { if (error) { const {raw, clean} = cleanError(error) return clean || raw || error.toString() @@ -141,7 +139,7 @@ function BirthdayInner({ const isUnder13 = age < 13 const isUnder18 = age >= 13 && age < 18 - const onSave = React.useCallback(async () => { + const onSave = useCallback(async () => { try { // skip if date is the same if (hasChanged) { diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 94c48dcc23..7a83f3effb 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {useCallback, useState} from 'react' +import {type PropsWithChildren} from 'react' import {View} from 'react-native' import {type AppBskyActorDefs, sanitizeMutedWordValue} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -58,13 +59,13 @@ function MutedWordsInner() { error: preferencesError, } = usePreferencesQuery() const {isPending, mutateAsync: addMutedWord} = useUpsertMutedWordsMutation() - const [field, setField] = React.useState('') - const [targets, setTargets] = React.useState(['content']) - const [error, setError] = React.useState('') - const [durations, setDurations] = React.useState(['forever']) - const [excludeFollowing, setExcludeFollowing] = React.useState(false) + const [field, setField] = useState('') + const [targets, setTargets] = useState(['content']) + const [error, setError] = useState('') + const [durations, setDurations] = useState(['forever']) + const [excludeFollowing, setExcludeFollowing] = useState(false) - const submit = React.useCallback(async () => { + const submit = useCallback(async () => { const sanitizedValue = sanitizeMutedWordValue(field) const surfaces = ['tag', targets.includes('content') && 'content'].filter( Boolean, @@ -431,7 +432,7 @@ function MutedWordRow({ const isExpired = expiryDate && expiryDate < new Date() const formatDistance = useFormatDistance() - const remove = React.useCallback(async () => { + const remove = useCallback(async () => { control.close() removeMutedWord(word) }, [removeMutedWord, word, control]) @@ -624,7 +625,7 @@ function MutedWordRow({ ) } -function TargetToggle({children}: React.PropsWithChildren<{}>) { +function TargetToggle({children}: PropsWithChildren<{}>) { const t = useTheme() const ctx = Toggle.useItemContext() const {gtMobile} = useBreakpoints() diff --git a/src/components/dialogs/Signin.tsx b/src/components/dialogs/Signin.tsx index c4bb895c1e..7d37aaadb3 100644 --- a/src/components/dialogs/Signin.tsx +++ b/src/components/dialogs/Signin.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -32,12 +32,12 @@ function SigninDialogInner({}: {control: Dialog.DialogOuterProps['control']}) { const {requestSwitchToAccount} = useLoggedOutViewControls() const closeAllActiveElements = useCloseAllActiveElements() - const showSignIn = React.useCallback(() => { + const showSignIn = useCallback(() => { closeAllActiveElements() requestSwitchToAccount({requestedAccount: 'none'}) }, [requestSwitchToAccount, closeAllActiveElements]) - const showCreateAccount = React.useCallback(() => { + const showCreateAccount = useCallback(() => { closeAllActiveElements() requestSwitchToAccount({requestedAccount: 'new'}) }, [requestSwitchToAccount, closeAllActiveElements]) diff --git a/src/components/dms/BlockedByListDialog.tsx b/src/components/dms/BlockedByListDialog.tsx index a91811c756..2532122087 100644 --- a/src/components/dms/BlockedByListDialog.tsx +++ b/src/components/dms/BlockedByListDialog.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {Fragment} from 'react' import {View} from 'react-native' import {type ModerationCause} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -25,7 +25,6 @@ export function BlockedByListDialog({ return ( {_(msg`User blocked by list`)} - block.source.type === 'list' ? ( - + {i === 0 ? null : ', '} {block.source.list.name} - + ) : null, )} - {}} /> - ) diff --git a/src/components/dms/ChatEmptyPill.tsx b/src/components/dms/ChatEmptyPill.tsx index 79f98ace06..dba7dbdbe3 100644 --- a/src/components/dms/ChatEmptyPill.tsx +++ b/src/components/dms/ChatEmptyPill.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo, useState} from 'react' import {Pressable, View} from 'react-native' import Animated, { runOnJS, @@ -24,11 +24,11 @@ export function ChatEmptyPill() { const t = useTheme() const {_} = useLingui() const playHaptic = useHaptics() - const [promptIndex, setPromptIndex] = React.useState(lastIndex) + const [promptIndex, setPromptIndex] = useState(lastIndex) const scale = useSharedValue(1) - const prompts = React.useMemo(() => { + const prompts = useMemo(() => { return [ _(msg`Say hello!`), _(msg`Share your favorite feed!`), @@ -40,17 +40,17 @@ export function ChatEmptyPill() { ] }, [_]) - const onPressIn = React.useCallback(() => { + const onPressIn = useCallback(() => { if (IS_WEB) return scale.set(() => withTiming(1.075, {duration: 100})) }, [scale]) - const onPressOut = React.useCallback(() => { + const onPressOut = useCallback(() => { if (IS_WEB) return scale.set(() => withTiming(1, {duration: 100})) }, [scale]) - const onPress = React.useCallback(() => { + const onPress = useCallback(() => { runOnJS(playHaptic)() let randomPromptIndex = Math.floor(Math.random() * prompts.length) while (randomPromptIndex === lastIndex) { diff --git a/src/components/dms/ConvoMenu.tsx b/src/components/dms/ConvoMenu.tsx index 1ea2a90cd6..dcd988ccff 100644 --- a/src/components/dms/ConvoMenu.tsx +++ b/src/components/dms/ConvoMenu.tsx @@ -1,4 +1,5 @@ -import React, {useCallback} from 'react' +import {useCallback} from 'react' +import * as React from 'react' import {Keyboard, View} from 'react-native' import {type ChatBskyConvoDefs, type ModerationCause} from '@atproto/api' import {msg} from '@lingui/core/macro' diff --git a/src/components/dms/DateDivider.tsx b/src/components/dms/DateDivider.tsx index 83b07dca9c..f8b3247261 100644 --- a/src/components/dms/DateDivider.tsx +++ b/src/components/dms/DateDivider.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {memo} from 'react' +import {type ReactNode} from 'react' import {View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -28,7 +29,7 @@ const longDateFormatterWithYear = new Intl.DateTimeFormat(undefined, { year: 'numeric', }) -let DateDivider = ({date: dateStr}: {date: string}): React.ReactNode => { +let DateDivider = ({date: dateStr}: {date: string}): ReactNode => { const {_} = useLingui() const t = useTheme() @@ -78,5 +79,5 @@ let DateDivider = ({date: dateStr}: {date: string}): React.ReactNode => { ) } -DateDivider = React.memo(DateDivider) +DateDivider = memo(DateDivider) export {DateDivider} diff --git a/src/components/dms/MessageContext.tsx b/src/components/dms/MessageContext.tsx index 645079eb26..6da7afacf4 100644 --- a/src/components/dms/MessageContext.tsx +++ b/src/components/dms/MessageContext.tsx @@ -1,18 +1,15 @@ -import React from 'react' +import {createContext, useContext} from 'react' +import {type ReactNode} from 'react' -const MessageContext = React.createContext(false) +const MessageContext = createContext(false) MessageContext.displayName = 'MessageContext' -export function MessageContextProvider({ - children, -}: { - children: React.ReactNode -}) { +export function MessageContextProvider({children}: {children: ReactNode}) { return ( {children} ) } export function useIsWithinMessage() { - return React.useContext(MessageContext) + return useContext(MessageContext) } diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx index abe757d26f..9ab4ee19cd 100644 --- a/src/components/dms/MessageItem.tsx +++ b/src/components/dms/MessageItem.tsx @@ -1,4 +1,5 @@ -import React, {useCallback, useMemo} from 'react' +import {memo, useCallback, useMemo} from 'react' +import {type ReactNode} from 'react' import { type GestureResponderEvent, type StyleProp, @@ -40,7 +41,7 @@ let MessageItem = ({ item, }: { item: ConvoItem & {type: 'message' | 'pending-message'} -}): React.ReactNode => { +}): ReactNode => { const t = useTheme() const {currentAccount} = useSession() const {_} = useLingui() @@ -233,7 +234,7 @@ let MessageItem = ({ ) } -MessageItem = React.memo(MessageItem) +MessageItem = memo(MessageItem) export {MessageItem} let MessageItemMetadata = ({ @@ -242,7 +243,7 @@ let MessageItemMetadata = ({ }: { item: ConvoItem & {type: 'message' | 'pending-message'} style: StyleProp -}): React.ReactNode => { +}): ReactNode => { const t = useTheme() const {_} = useLingui() const {message} = item @@ -328,5 +329,5 @@ let MessageItemMetadata = ({ ) } -MessageItemMetadata = React.memo(MessageItemMetadata) +MessageItemMetadata = memo(MessageItemMetadata) export {MessageItemMetadata} diff --git a/src/components/dms/MessageItemEmbed.tsx b/src/components/dms/MessageItemEmbed.tsx index 6390300c1a..1a43aa7397 100644 --- a/src/components/dms/MessageItemEmbed.tsx +++ b/src/components/dms/MessageItemEmbed.tsx @@ -1,17 +1,17 @@ -import React from 'react' +import {memo} from 'react' +import {type ReactNode} from 'react' import {useWindowDimensions, View} from 'react-native' import {type $Typed, type AppBskyEmbedRecord} from '@atproto/api' import {atoms as a, native, tokens, useTheme, web} from '#/alf' -import {PostEmbedViewContext} from '#/components/Post/Embed' -import {Embed} from '#/components/Post/Embed' +import {Embed, PostEmbedViewContext} from '#/components/Post/Embed' import {MessageContextProvider} from './MessageContext' let MessageItemEmbed = ({ embed, }: { embed: $Typed -}): React.ReactNode => { +}): ReactNode => { const t = useTheme() const screen = useWindowDimensions() @@ -43,5 +43,5 @@ let MessageItemEmbed = ({ ) } -MessageItemEmbed = React.memo(MessageItemEmbed) +MessageItemEmbed = memo(MessageItemEmbed) export {MessageItemEmbed} diff --git a/src/components/dms/MessageProfileButton.tsx b/src/components/dms/MessageProfileButton.tsx index 3429d66854..9a0d93b38a 100644 --- a/src/components/dms/MessageProfileButton.tsx +++ b/src/components/dms/MessageProfileButton.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {View} from 'react-native' import {type AppBskyActorDefs} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -39,7 +39,7 @@ export function MessageProfileButton({ }, }) - const onPress = React.useCallback(() => { + const onPress = useCallback(() => { if (!convoAvailability?.canChat) { return } diff --git a/src/components/dms/MessagesListBlockedFooter.tsx b/src/components/dms/MessagesListBlockedFooter.tsx index 45fb52b60e..48886090ac 100644 --- a/src/components/dms/MessagesListBlockedFooter.tsx +++ b/src/components/dms/MessagesListBlockedFooter.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo} from 'react' import {View} from 'react-native' import {type ModerationDecision} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -38,7 +38,7 @@ export function MessagesListBlockedFooter({ const reportControl = useDialogControl() const blockedByListControl = useDialogControl() - const {listBlocks, userBlock} = React.useMemo(() => { + const {listBlocks, userBlock} = useMemo(() => { const modui = moderation.ui('profileView') const blocks = modui.alerts.filter(alert => alert.type === 'blocking') const listBlocks = blocks.filter(alert => alert.source.type === 'list') @@ -51,7 +51,7 @@ export function MessagesListBlockedFooter({ const isBlocking = !!userBlock || !!listBlocks.length - const onUnblockPress = React.useCallback(() => { + const onUnblockPress = useCallback(() => { if (listBlocks.length) { blockedByListControl.open() } else { diff --git a/src/components/dms/NewMessagesPill.tsx b/src/components/dms/NewMessagesPill.tsx index cfdf4669ff..7abe528784 100644 --- a/src/components/dms/NewMessagesPill.tsx +++ b/src/components/dms/NewMessagesPill.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Pressable, View} from 'react-native' import Animated, { runOnJS, @@ -33,17 +33,17 @@ export function NewMessagesPill({ const scale = useSharedValue(1) - const onPressIn = React.useCallback(() => { + const onPressIn = useCallback(() => { if (IS_WEB) return scale.set(() => withTiming(1.075, {duration: 100})) }, [scale]) - const onPressOut = React.useCallback(() => { + const onPressOut = useCallback(() => { if (IS_WEB) return scale.set(() => withTiming(1, {duration: 100})) }, [scale]) - const onPress = React.useCallback(() => { + const onPress = useCallback(() => { runOnJS(playHaptic)() onPressInner?.() }, [onPressInner, playHaptic]) diff --git a/src/components/forms/HostingProvider.tsx b/src/components/forms/HostingProvider.tsx index 356f8e5efc..735de0cf03 100644 --- a/src/components/forms/HostingProvider.tsx +++ b/src/components/forms/HostingProvider.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Keyboard, View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -28,7 +28,7 @@ export function HostingProvider({ const t = useTheme() const {_} = useLingui() - const onPressSelectService = React.useCallback(() => { + const onPressSelectService = useCallback(() => { Keyboard.dismiss() serverInputControl.open() onOpenDialog?.() diff --git a/src/components/forms/InputGroup.tsx b/src/components/forms/InputGroup.tsx index aacdc60c71..a0f5312d78 100644 --- a/src/components/forms/InputGroup.tsx +++ b/src/components/forms/InputGroup.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {Children, cloneElement, Fragment, isValidElement} from 'react' +import {type PropsWithChildren} from 'react' import {View} from 'react-native' import {atoms, useTheme} from '#/alf' @@ -6,21 +7,21 @@ import {atoms, useTheme} from '#/alf' /** * NOT FINISHED, just here as a reference */ -export function InputGroup(props: React.PropsWithChildren<{}>) { +export function InputGroup(props: PropsWithChildren<{}>) { const t = useTheme() - const children = React.Children.toArray(props.children) + const children = Children.toArray(props.children) const total = children.length return ( {children.map((child, i) => { - return React.isValidElement(child) ? ( - + return isValidElement(child) ? ( + {i > 0 ? ( ) : null} - {React.cloneElement(child, { + {cloneElement(child, { // @ts-ignore style: [ // @ts-ignore @@ -38,7 +39,7 @@ export function InputGroup(props: React.PropsWithChildren<{}>) { }, ], })} - + ) : null })} diff --git a/src/components/hooks/useDelayedLoading.ts b/src/components/hooks/useDelayedLoading.ts index 6c7e2ede06..895c62a5db 100644 --- a/src/components/hooks/useDelayedLoading.ts +++ b/src/components/hooks/useDelayedLoading.ts @@ -1,9 +1,9 @@ -import React from 'react' +import {useEffect, useState} from 'react' export function useDelayedLoading(delay: number, initialState: boolean = true) { - const [isLoading, setIsLoading] = React.useState(initialState) + const [isLoading, setIsLoading] = useState(initialState) - React.useEffect(() => { + useEffect(() => { let timeout: NodeJS.Timeout // on initial load, show a loading spinner for a hot sec to prevent flash if (isLoading) timeout = setTimeout(() => setIsLoading(false), delay) diff --git a/src/components/hooks/useFollowMethods.ts b/src/components/hooks/useFollowMethods.ts index 5e2b18ee13..4617ff83a2 100644 --- a/src/components/hooks/useFollowMethods.ts +++ b/src/components/hooks/useFollowMethods.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -25,7 +25,7 @@ export function useFollowMethods({ logContext, ) - const follow = React.useCallback(() => { + const follow = useCallback(() => { requireAuth(async () => { try { await queueFollow() @@ -38,7 +38,7 @@ export function useFollowMethods({ }) }, [_, queueFollow, requireAuth]) - const unfollow = React.useCallback(() => { + const unfollow = useCallback(() => { requireAuth(async () => { try { await queueUnfollow() diff --git a/src/components/hooks/useInteractionState.ts b/src/components/hooks/useInteractionState.ts index 67042d4a8c..3f55be5434 100644 --- a/src/components/hooks/useInteractionState.ts +++ b/src/components/hooks/useInteractionState.ts @@ -1,16 +1,16 @@ -import React from 'react' +import {useCallback, useMemo, useState} from 'react' export function useInteractionState() { - const [state, setState] = React.useState(false) + const [state, setState] = useState(false) - const onIn = React.useCallback(() => { + const onIn = useCallback(() => { setState(true) }, []) - const onOut = React.useCallback(() => { + const onOut = useCallback(() => { setState(false) }, []) - return React.useMemo( + return useMemo( () => ({ state, onIn, diff --git a/src/components/hooks/useRichText.ts b/src/components/hooks/useRichText.ts index caf6febc04..a1334bb635 100644 --- a/src/components/hooks/useRichText.ts +++ b/src/components/hooks/useRichText.ts @@ -1,12 +1,12 @@ -import React from 'react' +import {useEffect, useState} from 'react' import {RichText as RichTextAPI} from '@atproto/api' import {useAgent} from '#/state/session' export function useRichText(text: string): [RichTextAPI, boolean] { - const [prevText, setPrevText] = React.useState(text) - const [rawRT, setRawRT] = React.useState(() => new RichTextAPI({text})) - const [resolvedRT, setResolvedRT] = React.useState(null) + const [prevText, setPrevText] = useState(text) + const [rawRT, setRawRT] = useState(() => new RichTextAPI({text})) + const [resolvedRT, setResolvedRT] = useState(null) const agent = useAgent() if (text !== prevText) { setPrevText(text) @@ -14,7 +14,7 @@ export function useRichText(text: string): [RichTextAPI, boolean] { setResolvedRT(null) // This will queue an immediate re-render } - React.useEffect(() => { + useEffect(() => { let ignore = false async function resolveRTFacets() { // new each time diff --git a/src/components/hooks/useStarterPackEntry.native.ts b/src/components/hooks/useStarterPackEntry.native.ts index 1e0e79e901..31221d599d 100644 --- a/src/components/hooks/useStarterPackEntry.native.ts +++ b/src/components/hooks/useStarterPackEntry.native.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useEffect, useState} from 'react' import { createStarterPackLinkFromAndroidReferrer, @@ -10,11 +10,11 @@ import {IS_ANDROID} from '#/env' import {Referrer, SharedPrefs} from '../../../modules/expo-bluesky-swiss-army' export function useStarterPackEntry() { - const [ready, setReady] = React.useState(false) + const [ready, setReady] = useState(false) const setActiveStarterPack = useSetActiveStarterPack() const hasCheckedForStarterPack = useHasCheckedForStarterPack() - React.useEffect(() => { + useEffect(() => { if (ready) return // On Android, we cannot clear the referral link. It gets stored for 90 days and all we can do is query for it. So, diff --git a/src/components/hooks/useStarterPackEntry.ts b/src/components/hooks/useStarterPackEntry.ts index 2c2e8c6386..ccbd991574 100644 --- a/src/components/hooks/useStarterPackEntry.ts +++ b/src/components/hooks/useStarterPackEntry.ts @@ -1,14 +1,14 @@ -import React from 'react' +import {useEffect, useState} from 'react' import {httpStarterPackUriToAtUri} from '#/lib/strings/starter-pack' import {useSetActiveStarterPack} from '#/state/shell/starter-pack' export function useStarterPackEntry() { - const [ready, setReady] = React.useState(false) + const [ready, setReady] = useState(false) const setActiveStarterPack = useSetActiveStarterPack() - React.useEffect(() => { + useEffect(() => { const href = window.location.href const atUri = httpStarterPackUriToAtUri(href) diff --git a/src/components/icons/TEMPLATE.tsx b/src/components/icons/TEMPLATE.tsx index 6bde25d76a..4ca1674919 100644 --- a/src/components/icons/TEMPLATE.tsx +++ b/src/components/icons/TEMPLATE.tsx @@ -1,9 +1,9 @@ -import React from 'react' +import {forwardRef} from 'react' import Svg, {Path} from 'react-native-svg' import {type Props, useCommonSVGProps} from '#/components/icons/common' -export const IconTemplate_Stroke2_Corner0_Rounded = React.forwardRef( +export const IconTemplate_Stroke2_Corner0_Rounded = forwardRef( function LogoImpl(props: Props, ref) { const {fill, size, style, ...rest} = useCommonSVGProps(props) @@ -41,7 +41,7 @@ export function createSinglePathSVG({ strokeLinecap?: 'butt' | 'round' | 'square' strokeLinejoin?: 'miter' | 'round' | 'bevel' }) { - return React.forwardRef(function LogoImpl(props, ref) { + return forwardRef(function LogoImpl(props, ref) { const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props) const hasStroke = strokeWidth > 0 @@ -72,7 +72,7 @@ export function createSinglePathSVG({ } export function createSinglePathSVG2({path}: {path: string}) { - return React.forwardRef(function LogoImpl(props, ref) { + return forwardRef(function LogoImpl(props, ref) { const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props) return ( @@ -92,7 +92,7 @@ export function createSinglePathSVG2({path}: {path: string}) { } export function createMultiPathSVG({paths}: {paths: string[]}) { - return React.forwardRef(function LogoImpl(props, ref) { + return forwardRef(function LogoImpl(props, ref) { const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props) return ( diff --git a/src/components/icons/VerifiedCheck.tsx b/src/components/icons/VerifiedCheck.tsx index a98fdfc5d9..5a457e65ae 100644 --- a/src/components/icons/VerifiedCheck.tsx +++ b/src/components/icons/VerifiedCheck.tsx @@ -1,9 +1,9 @@ -import React from 'react' +import {forwardRef} from 'react' import Svg, {Circle, Path} from 'react-native-svg' import {type Props, useCommonSVGProps} from '#/components/icons/common' -export const VerifiedCheck = React.forwardRef( +export const VerifiedCheck = forwardRef( function LogoImpl(props, ref) { const {fill, size, style, ...rest} = useCommonSVGProps(props) diff --git a/src/components/icons/VerifierCheck.tsx b/src/components/icons/VerifierCheck.tsx index 4674fdde88..fdb13dec73 100644 --- a/src/components/icons/VerifierCheck.tsx +++ b/src/components/icons/VerifierCheck.tsx @@ -1,9 +1,9 @@ -import React from 'react' +import {forwardRef} from 'react' import Svg, {Path} from 'react-native-svg' import {type Props, useCommonSVGProps} from '#/components/icons/common' -export const VerifierCheck = React.forwardRef( +export const VerifierCheck = forwardRef( function LogoImpl(props, ref) { const {fill, size, style, ...rest} = useCommonSVGProps(props) diff --git a/src/components/intents/IntentDialogs.tsx b/src/components/intents/IntentDialogs.tsx index 40b227e499..a7b2af5db7 100644 --- a/src/components/intents/IntentDialogs.tsx +++ b/src/components/intents/IntentDialogs.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useMemo, useState} from 'react' +import {type ReactNode} from 'react' import * as Dialog from '#/components/Dialog' import {type DialogControlProps} from '#/components/Dialog' @@ -10,17 +11,17 @@ interface Context { setVerifyEmailState: (state: {code: string} | undefined) => void } -const Context = React.createContext({} as Context) +const Context = createContext({} as Context) Context.displayName = 'IntentDialogsContext' -export const useIntentDialogs = () => React.useContext(Context) +export const useIntentDialogs = () => useContext(Context) -export function Provider({children}: {children: React.ReactNode}) { +export function Provider({children}: {children: ReactNode}) { const verifyEmailDialogControl = Dialog.useDialogControl() - const [verifyEmailState, setVerifyEmailState] = React.useState< + const [verifyEmailState, setVerifyEmailState] = useState< {code: string} | undefined >() - const value = React.useMemo( + const value = useMemo( () => ({ verifyEmailDialogControl, verifyEmailState, diff --git a/src/components/interstitials/Trending.tsx b/src/components/interstitials/Trending.tsx index 74a4a9fa14..98e8f77b2a 100644 --- a/src/components/interstitials/Trending.tsx +++ b/src/components/interstitials/Trending.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {ScrollView, View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -36,7 +36,7 @@ export function Inner() { const {data: trending, error, isLoading} = useTrendingTopics() const noTopics = !isLoading && !error && !trending?.topics?.length - const onConfirmHide = React.useCallback(() => { + const onConfirmHide = useCallback(() => { ax.metric('trendingTopics:hide', {context: 'interstitial'}) setTrendingDisabled(true) }, [ax, setTrendingDisabled]) diff --git a/src/components/moderation/Hider.tsx b/src/components/moderation/Hider.tsx index c6b332e431..e6f85776ce 100644 --- a/src/components/moderation/Hider.tsx +++ b/src/components/moderation/Hider.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useState} from 'react' +import {type PropsWithChildren, type ReactNode} from 'react' import {type ModerationUI} from '@atproto/api' import { @@ -21,24 +22,24 @@ type Context = { } } -const Context = React.createContext({} as Context) +const Context = createContext({} as Context) Context.displayName = 'HiderContext' -export const useHider = () => React.useContext(Context) +export const useHider = () => useContext(Context) export function Outer({ modui, isContentVisibleInitialState, allowOverride, children, -}: React.PropsWithChildren<{ +}: PropsWithChildren<{ isContentVisibleInitialState?: boolean allowOverride?: boolean modui: ModerationUI | undefined }>) { const control = useModerationDetailsDialogControl() const blur = modui?.blurs[0] - const [isContentVisible, setIsContentVisible] = React.useState( + const [isContentVisible, setIsContentVisible] = useState( isContentVisibleInitialState || !blur, ) const info = useModerationCauseDescription(blur) @@ -79,12 +80,12 @@ export function Outer({ ) } -export function Content({children}: {children: React.ReactNode}) { +export function Content({children}: {children: ReactNode}) { const ctx = useHider() return ctx.isContentVisible ? children : null } -export function Mask({children}: {children: React.ReactNode}) { +export function Mask({children}: {children: ReactNode}) { const ctx = useHider() return ctx.isContentVisible ? null : children } diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx index 10e5159c9d..ac498c4c8d 100644 --- a/src/components/moderation/LabelsOnMeDialog.tsx +++ b/src/components/moderation/LabelsOnMeDialog.tsx @@ -1,4 +1,5 @@ -import React, {useState} from 'react' +import {useState} from 'react' +import * as React from 'react' import {View} from 'react-native' import {type ComAtprotoLabelDefs, ToolsOzoneReportDefs} from '@atproto/api' import {XRPCError} from '@atproto/xrpc' diff --git a/src/components/moderation/ScreenHider.tsx b/src/components/moderation/ScreenHider.tsx index 89e2f4ed04..34f8690f25 100644 --- a/src/components/moderation/ScreenHider.tsx +++ b/src/components/moderation/ScreenHider.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {useState} from 'react' +import {type PropsWithChildren} from 'react' import { type StyleProp, TouchableWithoutFeedback, @@ -30,7 +31,7 @@ export function ScreenHider({ style, containerStyle, children, -}: React.PropsWithChildren<{ +}: PropsWithChildren<{ testID?: string screenDescription: string modui: ModerationUI @@ -39,7 +40,7 @@ export function ScreenHider({ }>) { const t = useTheme() const {_} = useLingui() - const [override, setOverride] = React.useState(false) + const [override, setOverride] = useState(false) const navigation = useNavigation() const {isMobile} = useWebMediaQueries() const control = useModerationDetailsDialogControl() diff --git a/src/lib/currency.ts b/src/lib/currency.ts index 8b019fc6da..9ba97ddce9 100644 --- a/src/lib/currency.ts +++ b/src/lib/currency.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useMemo} from 'react' import {deviceLocales} from '#/locale/deviceLocales' import {useLanguagePrefs} from '#/state/preferences' @@ -277,7 +277,7 @@ export function useFormatCurrency( ) { const geolocation = useGeolocation() const {appLanguage} = useLanguagePrefs() - return React.useMemo(() => { + return useMemo(() => { const locale = deviceLocales.at(0) const languageTag = locale?.languageTag || appLanguage || 'en-US' const countryCode = ( diff --git a/src/lib/custom-animations/CountWheel.tsx b/src/lib/custom-animations/CountWheel.tsx index e6ef0f2b6b..e2c206078c 100644 --- a/src/lib/custom-animations/CountWheel.tsx +++ b/src/lib/custom-animations/CountWheel.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useEffect, useRef, useState} from 'react' import {View} from 'react-native' import Animated, { Easing, @@ -105,14 +105,14 @@ export function CountWheel({ // animation // The initial entering/exiting animations will get skipped, since these will happen on screen mounts and would // be unnecessary - const [key, setKey] = React.useState(0) - const [prevCount, setPrevCount] = React.useState(likeCount) - const prevIsLiked = React.useRef(isLiked) + const [key, setKey] = useState(0) + const [prevCount, setPrevCount] = useState(likeCount) + const prevIsLiked = useRef(isLiked) const formatPostStatCount = useFormatPostStatCount() const formattedCount = formatPostStatCount(likeCount) const formattedPrevCount = formatPostStatCount(prevCount) - React.useEffect(() => { + useEffect(() => { if (isLiked === prevIsLiked.current) { return } diff --git a/src/lib/haptics.ts b/src/lib/haptics.ts index 475fd6f94e..c171303035 100644 --- a/src/lib/haptics.ts +++ b/src/lib/haptics.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import * as Device from 'expo-device' import {impactAsync, ImpactFeedbackStyle} from 'expo-haptics' @@ -8,7 +8,7 @@ import {IS_IOS, IS_WEB} from '#/env' export function useHaptics() { const isHapticsDisabled = useHapticsDisabled() - return React.useCallback( + return useCallback( (strength: 'Light' | 'Medium' | 'Heavy' = 'Medium') => { if (isHapticsDisabled || IS_WEB) { return diff --git a/src/lib/hooks/useAnimatedValue.ts b/src/lib/hooks/useAnimatedValue.ts index 9ae14dab62..e7b50ef068 100644 --- a/src/lib/hooks/useAnimatedValue.ts +++ b/src/lib/hooks/useAnimatedValue.ts @@ -1,8 +1,8 @@ -import * as React from 'react' +import {useRef} from 'react' import {Animated} from 'react-native' export function useAnimatedValue(initialValue: number) { - const lazyRef = React.useRef(undefined) + const lazyRef = useRef(undefined) if (lazyRef.current === undefined) { lazyRef.current = new Animated.Value(initialValue) diff --git a/src/lib/hooks/useIntentHandler.ts b/src/lib/hooks/useIntentHandler.ts index 4d4d394bcb..c35ca49b16 100644 --- a/src/lib/hooks/useIntentHandler.ts +++ b/src/lib/hooks/useIntentHandler.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useEffect} from 'react' import {Alert} from 'react-native' import * as Linking from 'expo-linking' import * as WebBrowser from 'expo-web-browser' @@ -28,7 +28,7 @@ export function useIntentHandler() { const {currentAccount} = useSession() const {tryApplyUpdate} = useApplyPullRequestOTAUpdate() - React.useEffect(() => { + useEffect(() => { const handleIncomingURL = async (url: string) => { if (IS_IOS) { // Close in-app browser if it's open (iOS only) @@ -109,7 +109,7 @@ export function useComposeIntent() { const {openComposer} = useOpenComposer() const {hasSession} = useSession() - return React.useCallback( + return useCallback( ({ text, imageUrisStr, @@ -166,7 +166,7 @@ function useVerifyEmailIntent() { const closeAllActiveElements = useCloseAllActiveElements() const {verifyEmailDialogControl: control, setVerifyEmailState: setState} = useIntentDialogs() - return React.useCallback( + return useCallback( (code: string) => { closeAllActiveElements() setState({ diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts index 75b4b4c3b0..9b0ac0ea5f 100644 --- a/src/lib/moderation.ts +++ b/src/lib/moderation.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useMemo} from 'react' import { type AppBskyLabelerDefs, BskyAgent, @@ -122,7 +122,7 @@ export type Subject = export function useLabelSubject({label}: {label: ComAtprotoLabelDefs.Label}): { subject: Subject } { - return React.useMemo(() => { + return useMemo(() => { const {cid, uri} = label if (cid) { return { diff --git a/src/screens/E2E/SharedPreferencesTesterScreen.tsx b/src/screens/E2E/SharedPreferencesTesterScreen.tsx index 5a9e6cd22d..95ead347d0 100644 --- a/src/screens/E2E/SharedPreferencesTesterScreen.tsx +++ b/src/screens/E2E/SharedPreferencesTesterScreen.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useState} from 'react' import {View} from 'react-native' import {ScrollView} from '#/view/com/util/Views' @@ -9,7 +9,7 @@ import {Text} from '#/components/Typography' import {SharedPrefs} from '../../../modules/expo-bluesky-swiss-army' export function SharedPreferencesTesterScreen() { - const [currentTestOutput, setCurrentTestOutput] = React.useState('') + const [currentTestOutput, setCurrentTestOutput] = useState('') return ( diff --git a/src/screens/Home/NoFeedsPinned.tsx b/src/screens/Home/NoFeedsPinned.tsx index 044c248d5a..54957c3fe1 100644 --- a/src/screens/Home/NoFeedsPinned.tsx +++ b/src/screens/Home/NoFeedsPinned.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {View} from 'react-native' import {TID} from '@atproto/common-web' import {msg} from '@lingui/core/macro' @@ -27,7 +27,7 @@ export function NoFeedsPinned({ const {isPending, mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation() - const addRecommendedFeeds = React.useCallback(async () => { + const addRecommendedFeeds = useCallback(async () => { let skippedTimeline = false let skippedDiscover = false let remainingSavedFeeds = [] diff --git a/src/screens/List/ListHiddenScreen.tsx b/src/screens/List/ListHiddenScreen.tsx index f70d1e2b30..e313268b31 100644 --- a/src/screens/List/ListHiddenScreen.tsx +++ b/src/screens/List/ListHiddenScreen.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useState} from 'react' import {View} from 'react-native' import {AppBskyGraphDefs} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -45,7 +45,7 @@ export function ListHiddenScreen({ const isModList = list.purpose === AppBskyGraphDefs.MODLIST - const [isProcessing, setIsProcessing] = React.useState(false) + const [isProcessing, setIsProcessing] = useState(false) const listBlockMutation = useListBlockMutation() const listMuteMutation = useListMuteMutation() const {mutateAsync: removeSavedFeed} = useRemoveFeedMutation() diff --git a/src/screens/Login/ForgotPasswordForm.tsx b/src/screens/Login/ForgotPasswordForm.tsx index 4d3074aa17..1cf3051129 100644 --- a/src/screens/Login/ForgotPasswordForm.tsx +++ b/src/screens/Login/ForgotPasswordForm.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react' +import {useCallback, useState} from 'react' import {Keyboard, View} from 'react-native' import {type ComAtprotoServerDescribeServer} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -44,7 +44,7 @@ export const ForgotPasswordForm = ({ const [email, setEmail] = useState('') const {_} = useLingui() - const onPressSelectService = React.useCallback(() => { + const onPressSelectService = useCallback(() => { Keyboard.dismiss() }, []) diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx index be90ee8c1a..5ce22b68bc 100644 --- a/src/screens/Messages/Conversation.tsx +++ b/src/screens/Messages/Conversation.tsx @@ -1,4 +1,5 @@ -import React, {useCallback, useEffect} from 'react' +import {useCallback, useEffect} from 'react' +import * as React from 'react' import {View} from 'react-native' import { type AppBskyActorDefs, diff --git a/src/screens/ModerationInteractionSettings/index.tsx b/src/screens/ModerationInteractionSettings/index.tsx index 041566fc86..5a984bed4a 100644 --- a/src/screens/ModerationInteractionSettings/index.tsx +++ b/src/screens/ModerationInteractionSettings/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo, useState} from 'react' import {View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -63,9 +63,9 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { const {_} = useLingui() const {mutateAsync: setPostInteractionSettings, isPending} = usePostInteractionSettingsMutation() - const [error, setError] = React.useState(undefined) + const [error, setError] = useState(undefined) - const allowUI = React.useMemo(() => { + const allowUI = useMemo(() => { return threadgateRecordToAllowUISetting({ $type: 'app.bsky.feed.threadgate', post: '', @@ -73,7 +73,7 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { allow: preferences.postInteractionSettings.threadgateAllowRules, }) }, [preferences.postInteractionSettings.threadgateAllowRules]) - const postgate = React.useMemo(() => { + const postgate = useMemo(() => { return createPostgateRecord({ post: '', embeddingRules: @@ -81,17 +81,17 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { }) }, [preferences.postInteractionSettings.postgateEmbeddingRules]) - const [maybeEditedAllowUI, setAllowUI] = React.useState(allowUI) - const [maybeEditedPostgate, setEditedPostgate] = React.useState(postgate) + const [maybeEditedAllowUI, setAllowUI] = useState(allowUI) + const [maybeEditedPostgate, setEditedPostgate] = useState(postgate) - const wasEdited = React.useMemo(() => { + const wasEdited = useMemo(() => { return ( !deepEqual(allowUI, maybeEditedAllowUI) || !deepEqual(postgate.embeddingRules, maybeEditedPostgate.embeddingRules) ) }, [postgate, allowUI, maybeEditedAllowUI, maybeEditedPostgate]) - const onSave = React.useCallback(async () => { + const onSave = useCallback(async () => { setError('') try { diff --git a/src/screens/Post/PostLikedBy.tsx b/src/screens/Post/PostLikedBy.tsx index a612f1bc0c..9578336884 100644 --- a/src/screens/Post/PostLikedBy.tsx +++ b/src/screens/Post/PostLikedBy.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Plural, Trans} from '@lingui/react/macro' import {useFocusEffect} from '@react-navigation/native' @@ -25,7 +25,7 @@ export const PostLikedByScreen = ({route}: Props) => { } useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Post/PostQuotes.tsx b/src/screens/Post/PostQuotes.tsx index 29aa6c5116..13da55ce31 100644 --- a/src/screens/Post/PostQuotes.tsx +++ b/src/screens/Post/PostQuotes.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Plural, Trans} from '@lingui/react/macro' import {useFocusEffect} from '@react-navigation/native' @@ -25,7 +25,7 @@ export const PostQuotesScreen = ({route}: Props) => { } useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Post/PostRepostedBy.tsx b/src/screens/Post/PostRepostedBy.tsx index f9168b4c0a..06d958befb 100644 --- a/src/screens/Post/PostRepostedBy.tsx +++ b/src/screens/Post/PostRepostedBy.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Plural, Trans} from '@lingui/react/macro' import {useFocusEffect} from '@react-navigation/native' @@ -25,7 +25,7 @@ export const PostRepostedByScreen = ({route}: Props) => { } useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Profile/ErrorState.tsx b/src/screens/Profile/ErrorState.tsx index d0a0831117..52d2a6d050 100644 --- a/src/screens/Profile/ErrorState.tsx +++ b/src/screens/Profile/ErrorState.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -16,7 +16,7 @@ export function ErrorState({error}: {error: string}) { const {_} = useLingui() const navigation = useNavigation() - const onPressBack = React.useCallback(() => { + const onPressBack = useCallback(() => { if (navigation.canGoBack()) { navigation.goBack() } else { diff --git a/src/screens/Profile/KnownFollowers.tsx b/src/screens/Profile/KnownFollowers.tsx index cafe504bcc..5d0847dfb4 100644 --- a/src/screens/Profile/KnownFollowers.tsx +++ b/src/screens/Profile/KnownFollowers.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo, useState} from 'react' import {type AppBskyActorDefs} from '@atproto/api' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -51,7 +51,7 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => { const {name} = route.params - const [isPTRing, setIsPTRing] = React.useState(false) + const [isPTRing, setIsPTRing] = useState(false) const { data: resolvedDid, isLoading: isDidLoading, @@ -67,7 +67,7 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => { refetch, } = useProfileKnownFollowersQuery(resolvedDid) - const onRefresh = React.useCallback(async () => { + const onRefresh = useCallback(async () => { setIsPTRing(true) try { await refetch() @@ -77,7 +77,7 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => { setIsPTRing(false) }, [refetch, setIsPTRing]) - const onEndReached = React.useCallback(async () => { + const onEndReached = useCallback(async () => { if (isFetchingNextPage || !hasNextPage || !!error) return try { await fetchNextPage() @@ -86,7 +86,7 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => { } }, [isFetchingNextPage, hasNextPage, error, fetchNextPage]) - const followers = React.useMemo(() => { + const followers = useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.followers) } @@ -96,7 +96,7 @@ export const ProfileKnownFollowersScreen = ({route}: Props) => { const isError = Boolean(resolveError || error) useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Profile/ProfileFollowers.tsx b/src/screens/Profile/ProfileFollowers.tsx index 8481881e64..307ca82270 100644 --- a/src/screens/Profile/ProfileFollowers.tsx +++ b/src/screens/Profile/ProfileFollowers.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Plural} from '@lingui/react/macro' import {useFocusEffect} from '@react-navigation/native' @@ -24,7 +24,7 @@ export const ProfileFollowersScreen = ({route}: Props) => { }) useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Profile/ProfileFollows.tsx b/src/screens/Profile/ProfileFollows.tsx index 66733aa11e..64d5319e5f 100644 --- a/src/screens/Profile/ProfileFollows.tsx +++ b/src/screens/Profile/ProfileFollows.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {Plural} from '@lingui/react/macro' import {useFocusEffect} from '@react-navigation/native' @@ -24,7 +24,7 @@ export const ProfileFollowsScreen = ({route}: Props) => { }) useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Profile/ProfileLabelerLikedBy.tsx b/src/screens/Profile/ProfileLabelerLikedBy.tsx index b629ae3a70..10e886f160 100644 --- a/src/screens/Profile/ProfileLabelerLikedBy.tsx +++ b/src/screens/Profile/ProfileLabelerLikedBy.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' @@ -22,7 +22,7 @@ export function ProfileLabelerLikedByScreen({ const {_} = useLingui() useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) diff --git a/src/screens/Signup/state.ts b/src/screens/Signup/state.ts index cb35fb3368..d94a852091 100644 --- a/src/screens/Signup/state.ts +++ b/src/screens/Signup/state.ts @@ -1,4 +1,5 @@ -import React, {useCallback} from 'react' +import {createContext, useCallback, useContext} from 'react' +import {type Dispatch} from 'react' import {LayoutAnimation} from 'react-native' import { ComAtprotoServerCreateAccount, @@ -248,11 +249,11 @@ export function reducer(s: SignupState, a: SignupAction): SignupState { interface IContext { state: SignupState - dispatch: React.Dispatch + dispatch: Dispatch } -export const SignupContext = React.createContext({} as IContext) +export const SignupContext = createContext({} as IContext) SignupContext.displayName = 'SignupContext' -export const useSignupContext = () => React.useContext(SignupContext) +export const useSignupContext = () => useContext(SignupContext) export function useSubmitSignup() { const ax = useAnalytics() diff --git a/src/screens/SignupQueued.tsx b/src/screens/SignupQueued.tsx index 55878700bf..406b785d2e 100644 --- a/src/screens/SignupQueued.tsx +++ b/src/screens/SignupQueued.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useEffect, useState} from 'react' import {Modal, ScrollView, View} from 'react-native' import {SystemBars} from 'react-native-edge-to-edge' import {useSafeAreaInsets} from 'react-native-safe-area-context' @@ -27,15 +27,15 @@ export function SignupQueued() { const {logoutCurrentAccount} = useSessionApi() const agent = useAgent() - const [isProcessing, setProcessing] = React.useState(false) - const [estimatedTime, setEstimatedTime] = React.useState( + const [isProcessing, setProcessing] = useState(false) + const [estimatedTime, setEstimatedTime] = useState( undefined, ) - const [placeInQueue, setPlaceInQueue] = React.useState( + const [placeInQueue, setPlaceInQueue] = useState( undefined, ) - const checkStatus = React.useCallback(async () => { + const checkStatus = useCallback(async () => { setProcessing(true) try { const res = await agent.com.atproto.temp.checkSignupQueue() @@ -65,7 +65,7 @@ export function SignupQueued() { agent, ]) - React.useEffect(() => { + useEffect(() => { checkStatus() const interval = setInterval(checkStatus, 60e3) return () => clearInterval(interval) diff --git a/src/screens/StarterPack/StarterPackLandingScreen.tsx b/src/screens/StarterPack/StarterPackLandingScreen.tsx index 5f926cb6e6..8d29a27057 100644 --- a/src/screens/StarterPack/StarterPackLandingScreen.tsx +++ b/src/screens/StarterPack/StarterPackLandingScreen.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useEffect, useState} from 'react' import {Pressable, View} from 'react-native' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' import { @@ -75,7 +75,7 @@ export function LandingScreen({ AppBskyGraphDefs.validateStarterPackView(starterPack) && AppBskyGraphStarterpack.validateRecord(starterPack.record) - React.useEffect(() => { + useEffect(() => { if (isErrorStarterPack || (starterPack && !isValid)) { setScreenState(LoggedOutScreenState.S_LoginOrCreateAccount) } @@ -128,8 +128,7 @@ function LandingScreenLoaded({ const androidDialogControl = useDialogControl() const [descriptionRt] = useRichText(record.description || '') - const [appClipOverlayVisible, setAppClipOverlayVisible] = - React.useState(false) + const [appClipOverlayVisible, setAppClipOverlayVisible] = useState(false) const listItemsCount = starterPack.list?.listItemCount ?? 0 diff --git a/src/screens/StarterPack/StarterPackScreen.tsx b/src/screens/StarterPack/StarterPackScreen.tsx index cb3ef828b5..49d826a428 100644 --- a/src/screens/StarterPack/StarterPackScreen.tsx +++ b/src/screens/StarterPack/StarterPackScreen.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useEffect, useState} from 'react' import {View} from 'react-native' import {Image} from 'expo-image' import { @@ -201,16 +201,16 @@ function StarterPackScreenLoaded({ const shareDialogControl = useDialogControl() const shortenLink = useShortenLink() - const [link, setLink] = React.useState() - const [imageLoaded, setImageLoaded] = React.useState(false) + const [link, setLink] = useState() + const [imageLoaded, setImageLoaded] = useState(false) - React.useEffect(() => { + useEffect(() => { ax.metric('starterPack:opened', { starterPack: starterPack.uri, }) }, [ax, starterPack.uri]) - const onOpenShareDialog = React.useCallback(() => { + const onOpenShareDialog = useCallback(() => { const rkey = new AtUri(starterPack.uri).rkey shortenLink(makeStarterPackLink(starterPack.creator.did, rkey)).then( res => { @@ -227,7 +227,7 @@ function StarterPackScreenLoaded({ shareDialogControl.open() }, [shareDialogControl, shortenLink, starterPack]) - React.useEffect(() => { + useEffect(() => { if (routeParams.new) { onOpenShareDialog() } @@ -316,7 +316,7 @@ function Header({ const {requestSwitchToAccount} = useLoggedOutViewControls() const {captureAction} = useProgressGuideControls() - const [isProcessing, setIsProcessing] = React.useState(false) + const [isProcessing, setIsProcessing] = useState(false) const {record, creator} = starterPack const isOwn = creator?.did === currentAccount?.did @@ -325,7 +325,7 @@ function Header({ const navigation = useNavigation() - React.useEffect(() => { + useEffect(() => { const onFocus = () => { if (hasSession) return setActiveStarterPack({ @@ -731,7 +731,7 @@ function InvalidStarterPack({rkey}: {rkey: string}) { const t = useTheme() const navigation = useNavigation() const {gtMobile} = useBreakpoints() - const [isProcessing, setIsProcessing] = React.useState(false) + const [isProcessing, setIsProcessing] = useState(false) const goBack = () => { if (navigation.canGoBack()) { diff --git a/src/screens/Topic.tsx b/src/screens/Topic.tsx index 88e674f943..24259ae562 100644 --- a/src/screens/Topic.tsx +++ b/src/screens/Topic.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo, useState} from 'react' import {type ListRenderItemInfo, View} from 'react-native' import {type AppBskyFeedDefs} from '@atproto/api' import {msg} from '@lingui/core/macro' @@ -39,26 +39,26 @@ export default function TopicScreen({ const {topic} = route.params const {_} = useLingui() - const headerTitle = React.useMemo(() => { + const headerTitle = useMemo(() => { return enforceLen(decodeURIComponent(topic), 24, true, 'middle') }, [topic]) - const onShare = React.useCallback(() => { + const onShare = useCallback(() => { const url = new URL('https://bsky.app') url.pathname = `/topic/${topic}` shareUrl(url.toString()) }, [topic]) - const [activeTab, setActiveTab] = React.useState(0) + const [activeTab, setActiveTab] = useState(0) const setMinimalShellMode = useSetMinimalShellMode() useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) - const onPageSelected = React.useCallback( + const onPageSelected = useCallback( (index: number) => { setMinimalShellMode(false) setActiveTab(index) @@ -66,7 +66,7 @@ export default function TopicScreen({ [setMinimalShellMode], ) - const sections = React.useMemo(() => { + const sections = useMemo(() => { return [ { title: _(msg`Top`), @@ -135,7 +135,7 @@ function TopicScreenTab({ }) { const {_} = useLingui() const initialNumToRender = useInitialNumToRender() - const [isPTR, setIsPTR] = React.useState(false) + const [isPTR, setIsPTR] = useState(false) const trackPostView = usePostViewTracking('Topic') const { @@ -154,17 +154,17 @@ function TopicScreenTab({ enabled: active, }) - const posts = React.useMemo(() => { + const posts = useMemo(() => { return data?.pages.flatMap(page => page.posts) || [] }, [data]) - const onRefresh = React.useCallback(async () => { + const onRefresh = useCallback(async () => { setIsPTR(true) await refetch() setIsPTR(false) }, [refetch]) - const onEndReached = React.useCallback(() => { + const onEndReached = useCallback(() => { if (isFetchingNextPage || !hasNextPage || error) return fetchNextPage() }, [isFetchingNextPage, hasNextPage, error, fetchNextPage]) diff --git a/src/state/a11y.tsx b/src/state/a11y.tsx index 524c713058..ea7b0bd08e 100644 --- a/src/state/a11y.tsx +++ b/src/state/a11y.tsx @@ -1,26 +1,27 @@ -import React from 'react' +import {createContext, useContext, useEffect, useMemo, useState} from 'react' +import {type PropsWithChildren} from 'react' import {AccessibilityInfo} from 'react-native' import {IS_WEB} from '#/env' import {PlatformInfo} from '../../modules/expo-bluesky-swiss-army' -const Context = React.createContext({ +const Context = createContext({ reduceMotionEnabled: false, screenReaderEnabled: false, }) Context.displayName = 'A11yContext' export function useA11y() { - return React.useContext(Context) + return useContext(Context) } -export function Provider({children}: React.PropsWithChildren<{}>) { - const [reduceMotionEnabled, setReduceMotionEnabled] = React.useState(() => +export function Provider({children}: PropsWithChildren<{}>) { + const [reduceMotionEnabled, setReduceMotionEnabled] = useState(() => PlatformInfo.getIsReducedMotionEnabled(), ) - const [screenReaderEnabled, setScreenReaderEnabled] = React.useState(false) + const [screenReaderEnabled, setScreenReaderEnabled] = useState(false) - React.useEffect(() => { + useEffect(() => { const reduceMotionChangedSubscription = AccessibilityInfo.addEventListener( 'reduceMotionChanged', enabled => { @@ -49,7 +50,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } }, []) - const ctx = React.useMemo(() => { + const ctx = useMemo(() => { return { reduceMotionEnabled, /** diff --git a/src/state/cache/thread-mutes.tsx b/src/state/cache/thread-mutes.tsx index 42c3adfe2a..bda21a55a4 100644 --- a/src/state/cache/thread-mutes.tsx +++ b/src/state/cache/thread-mutes.tsx @@ -1,4 +1,11 @@ -import React, {useEffect} from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' import {useAgent, useSession} from '../session' @@ -6,17 +13,15 @@ import {useAgent, useSession} from '../session' type StateContext = Map type SetStateContext = (uri: string, value: boolean) => void -const stateContext = React.createContext(new Map()) +const stateContext = createContext(new Map()) stateContext.displayName = 'ThreadMutesStateContext' -const setStateContext = React.createContext( - (_: string) => false, -) +const setStateContext = createContext((_: string) => false) setStateContext.displayName = 'ThreadMutesSetStateContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(() => new Map()) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(() => new Map()) - const setThreadMute = React.useCallback( + const setThreadMute = useCallback( (uri: string, value: boolean) => { setState(prev => { const next = new Map(prev) @@ -39,16 +44,16 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useMutedThreads() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useIsThreadMuted(uri: string, defaultValue = false) { - const state = React.useContext(stateContext) + const state = useContext(stateContext) return state.get(uri) ?? defaultValue } export function useSetThreadMute() { - return React.useContext(setStateContext) + return useContext(setStateContext) } function useMigrateMutes(setThreadMute: SetStateContext) { diff --git a/src/state/dialogs/index.tsx b/src/state/dialogs/index.tsx index b474e9fe0a..4b46708a3b 100644 --- a/src/state/dialogs/index.tsx +++ b/src/state/dialogs/index.tsx @@ -1,4 +1,17 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useMemo, + useRef, + useState, +} from 'react' +import { + type Dispatch, + type MutableRefObject, + type PropsWithChildren, + type SetStateAction, +} from 'react' import {type DialogControlRefProps} from '#/components/Dialog' import {Provider as GlobalDialogsProvider} from '#/components/dialogs/Context' @@ -9,26 +22,26 @@ interface IDialogContext { /** * The currently active `useDialogControl` hooks. */ - activeDialogs: React.MutableRefObject< - Map> + activeDialogs: MutableRefObject< + Map> > /** * The currently open dialogs, referenced by their IDs, generated from * `useId`. */ - openDialogs: React.MutableRefObject> + openDialogs: MutableRefObject> } interface IDialogControlContext { closeAllDialogs(): boolean setDialogIsOpen(id: string, isOpen: boolean): void - setFullyExpandedCount: React.Dispatch> + setFullyExpandedCount: Dispatch> } -const DialogContext = React.createContext({} as IDialogContext) +const DialogContext = createContext({} as IDialogContext) DialogContext.displayName = 'DialogContext' -const DialogControlContext = React.createContext( +const DialogControlContext = createContext( {} as IDialogControlContext, ) DialogControlContext.displayName = 'DialogControlContext' @@ -37,31 +50,31 @@ DialogControlContext.displayName = 'DialogControlContext' * The number of dialogs that are fully expanded. This is used to determine the background color of the status bar * on iOS. */ -const DialogFullyExpandedCountContext = React.createContext(0) +const DialogFullyExpandedCountContext = createContext(0) DialogFullyExpandedCountContext.displayName = 'DialogFullyExpandedCountContext' export function useDialogStateContext() { - return React.useContext(DialogContext) + return useContext(DialogContext) } export function useDialogStateControlContext() { - return React.useContext(DialogControlContext) + return useContext(DialogControlContext) } /** The number of dialogs that are fully expanded */ export function useDialogFullyExpandedCountContext() { - return React.useContext(DialogFullyExpandedCountContext) + return useContext(DialogFullyExpandedCountContext) } -export function Provider({children}: React.PropsWithChildren<{}>) { - const [fullyExpandedCount, setFullyExpandedCount] = React.useState(0) +export function Provider({children}: PropsWithChildren<{}>) { + const [fullyExpandedCount, setFullyExpandedCount] = useState(0) - const activeDialogs = React.useRef< + const activeDialogs = useRef< Map> >(new Map()) - const openDialogs = React.useRef>(new Set()) + const openDialogs = useRef>(new Set()) - const closeAllDialogs = React.useCallback(() => { + const closeAllDialogs = useCallback(() => { if (IS_WEB) { openDialogs.current.forEach(id => { const dialog = activeDialogs.current.get(id) @@ -75,7 +88,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } }, []) - const setDialogIsOpen = React.useCallback((id: string, isOpen: boolean) => { + const setDialogIsOpen = useCallback((id: string, isOpen: boolean) => { if (isOpen) { openDialogs.current.add(id) } else { @@ -83,14 +96,14 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } }, []) - const context = React.useMemo( + const context = useMemo( () => ({ activeDialogs, openDialogs, }), [activeDialogs, openDialogs], ) - const controls = React.useMemo( + const controls = useMemo( () => ({ closeAllDialogs, setDialogIsOpen, diff --git a/src/state/home-badge.tsx b/src/state/home-badge.tsx index e1000b90b6..5f9565cb15 100644 --- a/src/state/home-badge.tsx +++ b/src/state/home-badge.tsx @@ -1,15 +1,16 @@ -import React from 'react' +import {createContext, useContext, useState} from 'react' +import {type PropsWithChildren} from 'react' type StateContext = boolean type ApiContext = (hasNew: boolean) => void -const stateContext = React.createContext(false) +const stateContext = createContext(false) stateContext.displayName = 'HomeBadgeStateContext' -const apiContext = React.createContext((_: boolean) => {}) +const apiContext = createContext((_: boolean) => {}) apiContext.displayName = 'HomeBadgeApiContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(false) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(false) return ( {children} @@ -18,9 +19,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useHomeBadge() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetHomeBadge() { - return React.useContext(apiContext) + return useContext(apiContext) } diff --git a/src/state/lightbox.tsx b/src/state/lightbox.tsx index 78145d5d7e..5c6eef20bd 100644 --- a/src/state/lightbox.tsx +++ b/src/state/lightbox.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useMemo, useState} from 'react' +import {type PropsWithChildren} from 'react' import {nanoid} from 'nanoid/non-secure' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' @@ -10,14 +11,14 @@ export type Lightbox = { index: number } -const LightboxContext = React.createContext<{ +const LightboxContext = createContext<{ activeLightbox: Lightbox | null }>({ activeLightbox: null, }) LightboxContext.displayName = 'LightboxContext' -const LightboxControlContext = React.createContext<{ +const LightboxControlContext = createContext<{ openLightbox: (lightbox: Omit) => void closeLightbox: () => boolean }>({ @@ -26,10 +27,8 @@ const LightboxControlContext = React.createContext<{ }) LightboxControlContext.displayName = 'LightboxControlContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [activeLightbox, setActiveLightbox] = React.useState( - null, - ) +export function Provider({children}: PropsWithChildren<{}>) { + const [activeLightbox, setActiveLightbox] = useState(null) const openLightbox = useNonReactiveCallback( (lightbox: Omit) => { @@ -51,14 +50,14 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return wasActive }) - const state = React.useMemo( + const state = useMemo( () => ({ activeLightbox, }), [activeLightbox], ) - const methods = React.useMemo( + const methods = useMemo( () => ({ openLightbox, closeLightbox, @@ -76,9 +75,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useLightbox() { - return React.useContext(LightboxContext) + return useContext(LightboxContext) } export function useLightboxControls() { - return React.useContext(LightboxControlContext) + return useContext(LightboxControlContext) } diff --git a/src/state/messages/current-convo-id.tsx b/src/state/messages/current-convo-id.tsx index 082f59919d..ebf4393625 100644 --- a/src/state/messages/current-convo-id.tsx +++ b/src/state/messages/current-convo-id.tsx @@ -1,6 +1,7 @@ -import React from 'react' +import {createContext, useContext, useMemo, useState} from 'react' +import {type ReactNode} from 'react' -const CurrentConvoIdContext = React.createContext<{ +const CurrentConvoIdContext = createContext<{ currentConvoId: string | undefined setCurrentConvoId: (convoId: string | undefined) => void }>({ @@ -10,7 +11,7 @@ const CurrentConvoIdContext = React.createContext<{ CurrentConvoIdContext.displayName = 'CurrentConvoIdContext' export function useCurrentConvoId() { - const ctx = React.useContext(CurrentConvoIdContext) + const ctx = useContext(CurrentConvoIdContext) if (!ctx) { throw new Error( 'useCurrentConvoId must be used within a CurrentConvoIdProvider', @@ -19,15 +20,9 @@ export function useCurrentConvoId() { return ctx } -export function CurrentConvoIdProvider({ - children, -}: { - children: React.ReactNode -}) { - const [currentConvoId, setCurrentConvoId] = React.useState< - string | undefined - >() - const ctx = React.useMemo( +export function CurrentConvoIdProvider({children}: {children: ReactNode}) { + const [currentConvoId, setCurrentConvoId] = useState() + const ctx = useMemo( () => ({currentConvoId, setCurrentConvoId}), [currentConvoId], ) diff --git a/src/state/messages/message-drafts.tsx b/src/state/messages/message-drafts.tsx index 62521965b1..0009d7abff 100644 --- a/src/state/messages/message-drafts.tsx +++ b/src/state/messages/message-drafts.tsx @@ -1,15 +1,23 @@ -import React, {useEffect, useMemo, useReducer, useRef} from 'react' +import { + createContext, + useContext, + useEffect, + useMemo, + useReducer, + useRef, +} from 'react' +import {type ReactNode} from 'react' import {useCurrentConvoId} from './current-convo-id' -const MessageDraftsContext = React.createContext<{ +const MessageDraftsContext = createContext<{ state: State dispatch: React.Dispatch } | null>(null) MessageDraftsContext.displayName = 'MessageDraftsContext' function useMessageDraftsContext() { - const ctx = React.useContext(MessageDraftsContext) + const ctx = useContext(MessageDraftsContext) if (!ctx) { throw new Error( 'useMessageDrafts must be used within a MessageDraftsContext', @@ -69,7 +77,7 @@ function reducer(state: State, action: Actions): State { } } -export function MessageDraftsProvider({children}: {children: React.ReactNode}) { +export function MessageDraftsProvider({children}: {children: ReactNode}) { const [state, dispatch] = useReducer(reducer, {}) const ctx = useMemo(() => { diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index 5f023e0680..62c8ee4ec3 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useMemo, useState} from 'react' +import {type PropsWithChildren} from 'react' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' @@ -25,7 +26,7 @@ export type Modal = // Lists | UserAddRemoveListsModal -const ModalContext = React.createContext<{ +const ModalContext = createContext<{ isModalActive: boolean activeModals: Modal[] }>({ @@ -34,7 +35,7 @@ const ModalContext = React.createContext<{ }) ModalContext.displayName = 'ModalContext' -const ModalControlContext = React.createContext<{ +const ModalControlContext = createContext<{ openModal: (modal: Modal) => void closeModal: () => boolean closeAllModals: () => boolean @@ -45,8 +46,8 @@ const ModalControlContext = React.createContext<{ }) ModalControlContext.displayName = 'ModalControlContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [activeModals, setActiveModals] = React.useState([]) +export function Provider({children}: PropsWithChildren<{}>) { + const [activeModals, setActiveModals] = useState([]) const openModal = useNonReactiveCallback((modal: Modal) => { setActiveModals(modals => [...modals, modal]) @@ -66,7 +67,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return wasActive }) - const state = React.useMemo( + const state = useMemo( () => ({ isModalActive: activeModals.length > 0, activeModals, @@ -74,7 +75,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [activeModals], ) - const methods = React.useMemo( + const methods = useMemo( () => ({ openModal, closeModal, @@ -96,12 +97,12 @@ export function Provider({children}: React.PropsWithChildren<{}>) { * @deprecated use the dialog system from `#/components/Dialog.tsx` */ export function useModals() { - return React.useContext(ModalContext) + return useContext(ModalContext) } /** * @deprecated use the dialog system from `#/components/Dialog.tsx` */ export function useModalControls() { - return React.useContext(ModalControlContext) + return useContext(ModalControlContext) } diff --git a/src/state/preferences/alt-text-required.tsx b/src/state/preferences/alt-text-required.tsx index 1e001752e0..9179f005a9 100644 --- a/src/state/preferences/alt-text-required.tsx +++ b/src/state/preferences/alt-text-required.tsx @@ -1,25 +1,30 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' type StateContext = persisted.Schema['requireAltTextEnabled'] type SetContext = (v: persisted.Schema['requireAltTextEnabled']) => void -const stateContext = React.createContext( +const stateContext = createContext( persisted.defaults.requireAltTextEnabled, ) stateContext.displayName = 'AltTextRequiredStateContext' -const setContext = React.createContext( +const setContext = createContext( (_: persisted.Schema['requireAltTextEnabled']) => {}, ) setContext.displayName = 'AltTextRequiredSetContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState( - persisted.get('requireAltTextEnabled'), - ) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(persisted.get('requireAltTextEnabled')) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (requireAltTextEnabled: persisted.Schema['requireAltTextEnabled']) => { setState(requireAltTextEnabled) persisted.write('requireAltTextEnabled', requireAltTextEnabled) @@ -27,7 +32,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate( 'requireAltTextEnabled', nextRequireAltTextEnabled => { @@ -46,9 +51,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useRequireAltTextEnabled() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetRequireAltTextEnabled() { - return React.useContext(setContext) + return useContext(setContext) } diff --git a/src/state/preferences/autoplay.tsx b/src/state/preferences/autoplay.tsx index fb430487a1..d1f3f4ceb9 100644 --- a/src/state/preferences/autoplay.tsx +++ b/src/state/preferences/autoplay.tsx @@ -1,23 +1,28 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type ReactNode} from 'react' import * as persisted from '#/state/persisted' type StateContext = boolean type SetContext = (v: boolean) => void -const stateContext = React.createContext( +const stateContext = createContext( Boolean(persisted.defaults.disableAutoplay), ) stateContext.displayName = 'AutoplayStateContext' -const setContext = React.createContext((_: boolean) => {}) +const setContext = createContext((_: boolean) => {}) setContext.displayName = 'AutoplaySetContext' -export function Provider({children}: {children: React.ReactNode}) { - const [state, setState] = React.useState( - Boolean(persisted.get('disableAutoplay')), - ) +export function Provider({children}: {children: ReactNode}) { + const [state, setState] = useState(Boolean(persisted.get('disableAutoplay'))) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (autoplayDisabled: persisted.Schema['disableAutoplay']) => { setState(Boolean(autoplayDisabled)) persisted.write('disableAutoplay', autoplayDisabled) @@ -25,7 +30,7 @@ export function Provider({children}: {children: React.ReactNode}) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('disableAutoplay', nextDisableAutoplay => { setState(Boolean(nextDisableAutoplay)) }) @@ -40,5 +45,5 @@ export function Provider({children}: {children: React.ReactNode}) { ) } -export const useAutoplayDisabled = () => React.useContext(stateContext) -export const useSetAutoplayDisabled = () => React.useContext(setContext) +export const useAutoplayDisabled = () => useContext(stateContext) +export const useSetAutoplayDisabled = () => useContext(setContext) diff --git a/src/state/preferences/disable-haptics.tsx b/src/state/preferences/disable-haptics.tsx index 592b80ef38..b452987b35 100644 --- a/src/state/preferences/disable-haptics.tsx +++ b/src/state/preferences/disable-haptics.tsx @@ -1,23 +1,28 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type ReactNode} from 'react' import * as persisted from '#/state/persisted' type StateContext = boolean type SetContext = (v: boolean) => void -const stateContext = React.createContext( +const stateContext = createContext( Boolean(persisted.defaults.disableHaptics), ) stateContext.displayName = 'DisableHapticsStateContext' -const setContext = React.createContext((_: boolean) => {}) +const setContext = createContext((_: boolean) => {}) setContext.displayName = 'DisableHapticsSetContext' -export function Provider({children}: {children: React.ReactNode}) { - const [state, setState] = React.useState( - Boolean(persisted.get('disableHaptics')), - ) +export function Provider({children}: {children: ReactNode}) { + const [state, setState] = useState(Boolean(persisted.get('disableHaptics'))) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (hapticsEnabled: persisted.Schema['disableHaptics']) => { setState(Boolean(hapticsEnabled)) persisted.write('disableHaptics', hapticsEnabled) @@ -25,7 +30,7 @@ export function Provider({children}: {children: React.ReactNode}) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('disableHaptics', nextDisableHaptics => { setState(Boolean(nextDisableHaptics)) }) @@ -40,5 +45,5 @@ export function Provider({children}: {children: React.ReactNode}) { ) } -export const useHapticsDisabled = () => React.useContext(stateContext) -export const useSetHapticsDisabled = () => React.useContext(setContext) +export const useHapticsDisabled = () => useContext(stateContext) +export const useSetHapticsDisabled = () => useContext(setContext) diff --git a/src/state/preferences/hidden-posts.tsx b/src/state/preferences/hidden-posts.tsx index f87460bf6c..0278717d93 100644 --- a/src/state/preferences/hidden-posts.tsx +++ b/src/state/preferences/hidden-posts.tsx @@ -1,4 +1,12 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' @@ -11,20 +19,18 @@ type ApiContext = { unhidePost: ({uri}: {uri: string}) => void } -const stateContext = React.createContext( - persisted.defaults.hiddenPosts, -) +const stateContext = createContext(persisted.defaults.hiddenPosts) stateContext.displayName = 'HiddenPostsStateContext' -const apiContext = React.createContext({ +const apiContext = createContext({ hidePost: () => {}, unhidePost: () => {}, }) apiContext.displayName = 'HiddenPostsApiContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(persisted.get('hiddenPosts')) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(persisted.get('hiddenPosts')) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (fn: SetStateCb) => { const s = fn(persisted.get('hiddenPosts')) setState(s) @@ -33,7 +39,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [setState], ) - const api = React.useMemo( + const api = useMemo( () => ({ hidePost: ({uri}: {uri: string}) => { setStateWrapped(s => [...(s || []), uri]) @@ -45,7 +51,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [setStateWrapped], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('hiddenPosts', nextHiddenPosts => { setState(nextHiddenPosts) }) @@ -59,9 +65,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useHiddenPosts() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useHiddenPostsApi() { - return React.useContext(apiContext) + return useContext(apiContext) } diff --git a/src/state/preferences/in-app-browser.tsx b/src/state/preferences/in-app-browser.tsx index 36c4809694..a4e924e3e4 100644 --- a/src/state/preferences/in-app-browser.tsx +++ b/src/state/preferences/in-app-browser.tsx @@ -1,23 +1,30 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' type StateContext = persisted.Schema['useInAppBrowser'] type SetContext = (v: persisted.Schema['useInAppBrowser']) => void -const stateContext = React.createContext( +const stateContext = createContext( persisted.defaults.useInAppBrowser, ) stateContext.displayName = 'InAppBrowserStateContext' -const setContext = React.createContext( +const setContext = createContext( (_: persisted.Schema['useInAppBrowser']) => {}, ) setContext.displayName = 'InAppBrowserSetContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(persisted.get('useInAppBrowser')) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(persisted.get('useInAppBrowser')) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (inAppBrowser: persisted.Schema['useInAppBrowser']) => { setState(inAppBrowser) persisted.write('useInAppBrowser', inAppBrowser) @@ -25,7 +32,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('useInAppBrowser', nextUseInAppBrowser => { setState(nextUseInAppBrowser) }) @@ -41,9 +48,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useInAppBrowser() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetInAppBrowser() { - return React.useContext(setContext) + return useContext(setContext) } diff --git a/src/state/preferences/label-defs.tsx b/src/state/preferences/label-defs.tsx index a03b69b526..892b191fbf 100644 --- a/src/state/preferences/label-defs.tsx +++ b/src/state/preferences/label-defs.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext} from 'react' +import {type PropsWithChildren} from 'react' import { type AppBskyLabelerDefs, type InterpretedLabelValueDefinition, @@ -11,17 +12,17 @@ interface StateContext { labelers: AppBskyLabelerDefs.LabelerViewDetailed[] } -const stateContext = React.createContext({ +const stateContext = createContext({ labelDefs: {}, labelers: [], }) stateContext.displayName = 'LabelDefsStateContext' -export function Provider({children}: React.PropsWithChildren<{}>) { +export function Provider({children}: PropsWithChildren<{}>) { const state = useLabelDefinitionsQuery() return {children} } export function useLabelDefinitions() { - return React.useContext(stateContext) + return useContext(stateContext) } diff --git a/src/state/preferences/languages.tsx b/src/state/preferences/languages.tsx index fe7dc2105d..4ed2e94830 100644 --- a/src/state/preferences/languages.tsx +++ b/src/state/preferences/languages.tsx @@ -1,4 +1,12 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import {type AppLanguage} from '#/locale/languages' import * as persisted from '#/state/persisted' @@ -16,11 +24,11 @@ type ApiContext = { setAppLanguage: (code2: AppLanguage) => void } -const stateContext = React.createContext( +const stateContext = createContext( persisted.defaults.languagePrefs, ) stateContext.displayName = 'LanguagePrefsStateContext' -const apiContext = React.createContext({ +const apiContext = createContext({ setPrimaryLanguage: (_: string) => {}, setPostLanguage: (_: string) => {}, setContentLanguages: (_: string[]) => {}, @@ -29,10 +37,10 @@ const apiContext = React.createContext({ }) apiContext.displayName = 'LanguagePrefsApiContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(() => persisted.get('languagePrefs')) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(() => persisted.get('languagePrefs')) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (fn: SetStateCb) => { const s = fn(persisted.get('languagePrefs')) setState(s) @@ -41,13 +49,13 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('languagePrefs', nextLanguagePrefs => { setState(nextLanguagePrefs) }) }, [setStateWrapped]) - const api = React.useMemo( + const api = useMemo( () => ({ setPrimaryLanguage(code2: string) { setStateWrapped(s => ({...s, primaryLanguage: code2})) @@ -102,11 +110,11 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useLanguagePrefs() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useLanguagePrefsApi() { - return React.useContext(apiContext) + return useContext(apiContext) } export function getContentLanguages() { diff --git a/src/state/preferences/large-alt-badge.tsx b/src/state/preferences/large-alt-badge.tsx index 64bd68a8a3..442bdc7fac 100644 --- a/src/state/preferences/large-alt-badge.tsx +++ b/src/state/preferences/large-alt-badge.tsx @@ -1,25 +1,30 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' type StateContext = persisted.Schema['largeAltBadgeEnabled'] type SetContext = (v: persisted.Schema['largeAltBadgeEnabled']) => void -const stateContext = React.createContext( +const stateContext = createContext( persisted.defaults.largeAltBadgeEnabled, ) stateContext.displayName = 'LargeAltBadgeStateContext' -const setContext = React.createContext( +const setContext = createContext( (_: persisted.Schema['largeAltBadgeEnabled']) => {}, ) setContext.displayName = 'LargeAltBadgeSetContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState( - persisted.get('largeAltBadgeEnabled'), - ) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(persisted.get('largeAltBadgeEnabled')) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (largeAltBadgeEnabled: persisted.Schema['largeAltBadgeEnabled']) => { setState(largeAltBadgeEnabled) persisted.write('largeAltBadgeEnabled', largeAltBadgeEnabled) @@ -27,7 +32,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate( 'largeAltBadgeEnabled', nextLargeAltBadgeEnabled => { @@ -46,9 +51,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useLargeAltBadgeEnabled() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetLargeAltBadgeEnabled() { - return React.useContext(setContext) + return useContext(setContext) } diff --git a/src/state/preferences/subtitles.tsx b/src/state/preferences/subtitles.tsx index ef7ff3376b..da97296d50 100644 --- a/src/state/preferences/subtitles.tsx +++ b/src/state/preferences/subtitles.tsx @@ -1,23 +1,28 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useState, +} from 'react' +import {type ReactNode} from 'react' import * as persisted from '#/state/persisted' type StateContext = boolean type SetContext = (v: boolean) => void -const stateContext = React.createContext( +const stateContext = createContext( Boolean(persisted.defaults.subtitlesEnabled), ) stateContext.displayName = 'SubtitlesStateContext' -const setContext = React.createContext((_: boolean) => {}) +const setContext = createContext((_: boolean) => {}) setContext.displayName = 'SubtitlesSetContext' -export function Provider({children}: {children: React.ReactNode}) { - const [state, setState] = React.useState( - Boolean(persisted.get('subtitlesEnabled')), - ) +export function Provider({children}: {children: ReactNode}) { + const [state, setState] = useState(Boolean(persisted.get('subtitlesEnabled'))) - const setStateWrapped = React.useCallback( + const setStateWrapped = useCallback( (subtitlesEnabled: persisted.Schema['subtitlesEnabled']) => { setState(Boolean(subtitlesEnabled)) persisted.write('subtitlesEnabled', subtitlesEnabled) @@ -25,7 +30,7 @@ export function Provider({children}: {children: React.ReactNode}) { [setState], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('subtitlesEnabled', nextSubtitlesEnabled => { setState(Boolean(nextSubtitlesEnabled)) }) @@ -40,5 +45,5 @@ export function Provider({children}: {children: React.ReactNode}) { ) } -export const useSubtitlesEnabled = () => React.useContext(stateContext) -export const useSetSubtitlesEnabled = () => React.useContext(setContext) +export const useSubtitlesEnabled = () => useContext(stateContext) +export const useSetSubtitlesEnabled = () => useContext(setContext) diff --git a/src/state/preferences/trending.tsx b/src/state/preferences/trending.tsx index dc1f722c18..340280e600 100644 --- a/src/state/preferences/trending.tsx +++ b/src/state/preferences/trending.tsx @@ -1,4 +1,12 @@ -import React from 'react' +import { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' @@ -18,22 +26,22 @@ type ApiContext = { ): void } -const StateContext = React.createContext({ +const StateContext = createContext({ trendingDisabled: Boolean(persisted.defaults.trendingDisabled), trendingVideoDisabled: Boolean(persisted.defaults.trendingVideoDisabled), }) StateContext.displayName = 'TrendingStateContext' -const ApiContext = React.createContext({ +const ApiContext = createContext({ setTrendingDisabled() {}, setTrendingVideoDisabled() {}, }) ApiContext.displayName = 'TrendingApiContext' function usePersistedBooleanValue(key: T) { - const [value, _set] = React.useState(() => { + const [value, _set] = useState(() => { return Boolean(persisted.get(key)) }) - const set = React.useCallback< + const set = useCallback< (value: Exclude) => void >( hidden => { @@ -42,7 +50,7 @@ function usePersistedBooleanValue(key: T) { }, [key, _set], ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate(key, hidden => { _set(Boolean(hidden)) }) @@ -51,7 +59,7 @@ function usePersistedBooleanValue(key: T) { return [value, set] as const } -export function Provider({children}: React.PropsWithChildren<{}>) { +export function Provider({children}: PropsWithChildren<{}>) { const [trendingDisabled, setTrendingDisabled] = usePersistedBooleanValue('trendingDisabled') const [trendingVideoDisabled, setTrendingVideoDisabled] = @@ -60,11 +68,11 @@ export function Provider({children}: React.PropsWithChildren<{}>) { /* * Context */ - const state = React.useMemo( + const state = useMemo( () => ({trendingDisabled, trendingVideoDisabled}), [trendingDisabled, trendingVideoDisabled], ) - const api = React.useMemo( + const api = useMemo( () => ({setTrendingDisabled, setTrendingVideoDisabled}), [setTrendingDisabled, setTrendingVideoDisabled], ) @@ -77,9 +85,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useTrendingSettings() { - return React.useContext(StateContext) + return useContext(StateContext) } export function useTrendingSettingsApi() { - return React.useContext(ApiContext) + return useContext(ApiContext) } diff --git a/src/state/preferences/used-starter-packs.tsx b/src/state/preferences/used-starter-packs.tsx index 302b0e1f4a..415a6d1580 100644 --- a/src/state/preferences/used-starter-packs.tsx +++ b/src/state/preferences/used-starter-packs.tsx @@ -1,17 +1,18 @@ -import React from 'react' +import {createContext, useContext, useEffect, useState} from 'react' +import {type ReactNode} from 'react' import * as persisted from '#/state/persisted' type StateContext = boolean | undefined type SetContext = (v: boolean) => void -const stateContext = React.createContext(false) +const stateContext = createContext(false) stateContext.displayName = 'UsedStarterPacksStateContext' -const setContext = React.createContext((_: boolean) => {}) +const setContext = createContext((_: boolean) => {}) setContext.displayName = 'UsedStarterPacksSetContext' -export function Provider({children}: {children: React.ReactNode}) { - const [state, setState] = React.useState(() => +export function Provider({children}: {children: ReactNode}) { + const [state, setState] = useState(() => persisted.get('hasCheckedForStarterPack'), ) @@ -20,7 +21,7 @@ export function Provider({children}: {children: React.ReactNode}) { persisted.write('hasCheckedForStarterPack', v) } - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate( 'hasCheckedForStarterPack', nextHasCheckedForStarterPack => { @@ -38,5 +39,5 @@ export function Provider({children}: {children: React.ReactNode}) { ) } -export const useHasCheckedForStarterPack = () => React.useContext(stateContext) -export const useSetHasCheckedForStarterPack = () => React.useContext(setContext) +export const useHasCheckedForStarterPack = () => useContext(stateContext) +export const useSetHasCheckedForStarterPack = () => useContext(setContext) diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts index 80f7dfabdf..c8acb39f96 100644 --- a/src/state/queries/actor-autocomplete.ts +++ b/src/state/queries/actor-autocomplete.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import { type AppBskyActorDefs, moderateProfile, @@ -47,7 +47,7 @@ export function useActorAutocompleteQuery( : undefined return res?.data.actors || [] }, - select: React.useCallback( + select: useCallback( (data: AppBskyActorDefs.ProfileViewBasic[]) => { return computeSuggestions({ q: prefix, @@ -67,7 +67,7 @@ export function useActorAutocompleteFn() { const moderationOpts = useModerationOpts() const agent = useAgent() - return React.useCallback( + return useCallback( async ({query, limit = 8}: {query: string; limit?: number}) => { query = query.toLowerCase() let res diff --git a/src/state/queries/handle.ts b/src/state/queries/handle.ts index 658b9e9c15..c53c878d5f 100644 --- a/src/state/queries/handle.ts +++ b/src/state/queries/handle.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {useMutation, useQueryClient} from '@tanstack/react-query' import {STALE} from '#/state/queries' @@ -16,7 +16,7 @@ export function useFetchHandle() { const queryClient = useQueryClient() const agent = useAgent() - return React.useCallback( + return useCallback( async (handleOrDid: string) => { if (handleOrDid.startsWith('did:')) { const res = await queryClient.fetchQuery({ @@ -55,7 +55,7 @@ export function useFetchDid() { const queryClient = useQueryClient() const agent = useAgent() - return React.useCallback( + return useCallback( async (handleOrDid: string) => { return queryClient.fetchQuery({ staleTime: STALE.INFINITY, diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 0a3cfb6b47..2fbb9e7cbe 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -1,4 +1,4 @@ -import React, {useCallback, useEffect, useRef} from 'react' +import {useCallback, useEffect, useMemo, useRef} from 'react' import {AppState} from 'react-native' import { type AppBskyActorDefs, @@ -164,7 +164,7 @@ export function usePostFeedQuery( const fetchLimit = MIN_POSTS // Make sure this doesn't invalidate unless really needed. - const selectArgs = React.useMemo( + const selectArgs = useMemo( () => ({ feedTuners, moderationOpts, diff --git a/src/state/queries/search-posts.ts b/src/state/queries/search-posts.ts index e7ebae0ec2..50fade8632 100644 --- a/src/state/queries/search-posts.ts +++ b/src/state/queries/search-posts.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useMemo, useRef} from 'react' import { type AppBskyActorDefs, type AppBskyFeedDefs, @@ -39,14 +39,14 @@ export function useSearchPostsQuery({ }) { const agent = useAgent() const moderationOpts = useModerationOpts() - const selectArgs = React.useMemo( + const selectArgs = useMemo( () => ({ isSearchingSpecificUser: /from:(\w+)/.test(query), moderationOpts, }), [query, moderationOpts], ) - const lastRun = React.useRef<{ + const lastRun = useRef<{ data: InfiniteData args: typeof selectArgs result: InfiniteData @@ -72,7 +72,7 @@ export function useSearchPostsQuery({ initialPageParam: undefined, getNextPageParam: lastPage => lastPage.cursor, enabled: enabled ?? !!moderationOpts, - select: React.useCallback( + select: useCallback( (data: InfiniteData) => { const {moderationOpts, isSearchingSpecificUser} = selectArgs diff --git a/src/state/shell/color-mode.tsx b/src/state/shell/color-mode.tsx index 9fed6833aa..8186a60d8d 100644 --- a/src/state/shell/color-mode.tsx +++ b/src/state/shell/color-mode.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useEffect, useMemo, useState} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' @@ -11,23 +12,19 @@ type SetContext = { setDarkTheme: (v: persisted.Schema['darkTheme']) => void } -const stateContext = React.createContext({ +const stateContext = createContext({ colorMode: 'system', darkTheme: 'dark', }) stateContext.displayName = 'ColorModeStateContext' -const setContext = React.createContext({} as SetContext) +const setContext = createContext({} as SetContext) setContext.displayName = 'ColorModeSetContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [colorMode, setColorMode] = React.useState(() => - persisted.get('colorMode'), - ) - const [darkTheme, setDarkTheme] = React.useState(() => - persisted.get('darkTheme'), - ) +export function Provider({children}: PropsWithChildren<{}>) { + const [colorMode, setColorMode] = useState(() => persisted.get('colorMode')) + const [darkTheme, setDarkTheme] = useState(() => persisted.get('darkTheme')) - const stateContextValue = React.useMemo( + const stateContextValue = useMemo( () => ({ colorMode, darkTheme, @@ -35,7 +32,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [colorMode, darkTheme], ) - const setContextValue = React.useMemo( + const setContextValue = useMemo( () => ({ setColorMode: (_colorMode: persisted.Schema['colorMode']) => { setColorMode(_colorMode) @@ -49,7 +46,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { [], ) - React.useEffect(() => { + useEffect(() => { const unsub1 = persisted.onUpdate('darkTheme', nextDarkTheme => { setDarkTheme(nextDarkTheme) }) @@ -72,9 +69,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useThemePrefs() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetThemePrefs() { - return React.useContext(setContext) + return useContext(setContext) } diff --git a/src/state/shell/drawer-swipe-disabled.tsx b/src/state/shell/drawer-swipe-disabled.tsx index 4b72639a22..4c27014352 100644 --- a/src/state/shell/drawer-swipe-disabled.tsx +++ b/src/state/shell/drawer-swipe-disabled.tsx @@ -1,15 +1,16 @@ -import React from 'react' +import {createContext, useContext, useState} from 'react' +import {type PropsWithChildren} from 'react' type StateContext = boolean type SetContext = (v: boolean) => void -const stateContext = React.createContext(false) +const stateContext = createContext(false) stateContext.displayName = 'DrawerSwipeDisabledStateContext' -const setContext = React.createContext((_: boolean) => {}) +const setContext = createContext((_: boolean) => {}) setContext.displayName = 'DrawerSwipeDisabledSetContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, setState] = React.useState(false) +export function Provider({children}: PropsWithChildren<{}>) { + const [state, setState] = useState(false) return ( {children} @@ -18,9 +19,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useIsDrawerSwipeDisabled() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetDrawerSwipeDisabled() { - return React.useContext(setContext) + return useContext(setContext) } diff --git a/src/state/shell/logged-out.tsx b/src/state/shell/logged-out.tsx index 384507a34f..30fb78c7d4 100644 --- a/src/state/shell/logged-out.tsx +++ b/src/state/shell/logged-out.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useMemo, useState} from 'react' +import {type PropsWithChildren} from 'react' import {useSession} from '#/state/session' import {useActiveStarterPack} from '#/state/shell/starter-pack' @@ -35,24 +36,24 @@ type Controls = { clearRequestedAccount: () => void } -const StateContext = React.createContext({ +const StateContext = createContext({ showLoggedOut: false, requestedAccountSwitchTo: undefined, }) StateContext.displayName = 'LoggedOutStateContext' -const ControlsContext = React.createContext({ +const ControlsContext = createContext({ setShowLoggedOut: () => {}, requestSwitchToAccount: () => {}, clearRequestedAccount: () => {}, }) ControlsContext.displayName = 'LoggedOutControlsContext' -export function Provider({children}: React.PropsWithChildren<{}>) { +export function Provider({children}: PropsWithChildren<{}>) { const activeStarterPack = useActiveStarterPack() const {hasSession} = useSession() const shouldShowStarterPack = Boolean(activeStarterPack?.uri) && !hasSession - const [state, setState] = React.useState({ + const [state, setState] = useState({ showLoggedOut: shouldShowStarterPack, requestedAccountSwitchTo: shouldShowStarterPack ? IS_WEB @@ -61,7 +62,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { : undefined, }) - const controls = React.useMemo( + const controls = useMemo( () => ({ setShowLoggedOut(show) { setState(s => ({ @@ -96,9 +97,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useLoggedOutView() { - return React.useContext(StateContext) + return useContext(StateContext) } export function useLoggedOutViewControls() { - return React.useContext(ControlsContext) + return useContext(ControlsContext) } diff --git a/src/state/shell/minimal-mode.tsx b/src/state/shell/minimal-mode.tsx index 93eb47028a..d2d21ae57b 100644 --- a/src/state/shell/minimal-mode.tsx +++ b/src/state/shell/minimal-mode.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useCallback, useContext, useMemo} from 'react' +import {type PropsWithChildren} from 'react' import { type SharedValue, useSharedValue, @@ -11,7 +12,7 @@ type StateContext = { } type SetContext = (v: boolean) => void -const stateContext = React.createContext({ +const stateContext = createContext({ headerMode: { value: 0, addListener() {}, @@ -34,13 +35,13 @@ const stateContext = React.createContext({ }, }) stateContext.displayName = 'MinimalModeStateContext' -const setContext = React.createContext((_: boolean) => {}) +const setContext = createContext((_: boolean) => {}) setContext.displayName = 'MinimalModeSetContext' -export function Provider({children}: React.PropsWithChildren<{}>) { +export function Provider({children}: PropsWithChildren<{}>) { const headerMode = useSharedValue(0) const footerMode = useSharedValue(0) - const setMode = React.useCallback( + const setMode = useCallback( (v: boolean) => { 'worklet' headerMode.set(() => @@ -56,7 +57,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { }, [headerMode, footerMode], ) - const value = React.useMemo( + const value = useMemo( () => ({ headerMode, footerMode, @@ -71,9 +72,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useMinimalShellMode() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useSetMinimalShellMode() { - return React.useContext(setContext) + return useContext(setContext) } diff --git a/src/state/shell/onboarding.tsx b/src/state/shell/onboarding.tsx index 6b48f72ad6..650d59526d 100644 --- a/src/state/shell/onboarding.tsx +++ b/src/state/shell/onboarding.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useEffect, useReducer} from 'react' +import {type PropsWithChildren} from 'react' import * as persisted from '#/state/persisted' @@ -26,11 +27,11 @@ export type StateContext = persisted.Schema['onboarding'] & { } export type DispatchContext = (action: Action) => void -const stateContext = React.createContext( +const stateContext = createContext( compute(persisted.defaults.onboarding), ) stateContext.displayName = 'OnboardingStateContext' -const dispatchContext = React.createContext((_: Action) => {}) +const dispatchContext = createContext((_: Action) => {}) dispatchContext.displayName = 'OnboardingDispatchContext' function reducer(state: StateContext, action: Action): StateContext { @@ -73,13 +74,13 @@ function reducer(state: StateContext, action: Action): StateContext { } } -export function Provider({children}: React.PropsWithChildren<{}>) { - const [state, dispatch] = React.useReducer( +export function Provider({children}: PropsWithChildren<{}>) { + const [state, dispatch] = useReducer( reducer, compute(persisted.get('onboarding')), ) - React.useEffect(() => { + useEffect(() => { return persisted.onUpdate('onboarding', nextOnboarding => { const next = nextOnboarding.step // TODO we've introduced a footgun @@ -102,11 +103,11 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useOnboardingState() { - return React.useContext(stateContext) + return useContext(stateContext) } export function useOnboardingDispatch() { - return React.useContext(dispatchContext) + return useContext(dispatchContext) } export function isOnboardingActive() { diff --git a/src/state/shell/post-progress.tsx b/src/state/shell/post-progress.tsx index 3c91c1607b..894e479cce 100644 --- a/src/state/shell/post-progress.tsx +++ b/src/state/shell/post-progress.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {createContext, useContext} from 'react' interface PostProgressState { progress: number @@ -6,7 +6,7 @@ interface PostProgressState { error?: string } -const PostProgressContext = React.createContext({ +const PostProgressContext = createContext({ progress: 0, status: 'idle', }) @@ -15,5 +15,5 @@ PostProgressContext.displayName = 'PostProgressContext' export function Provider() {} export function usePostProgress() { - return React.useContext(PostProgressContext) + return useContext(PostProgressContext) } diff --git a/src/state/shell/progress-guide.tsx b/src/state/shell/progress-guide.tsx index 85e50f3186..7d999e80d3 100644 --- a/src/state/shell/progress-guide.tsx +++ b/src/state/shell/progress-guide.tsx @@ -1,4 +1,5 @@ -import React, {useMemo} from 'react' +import {useMemo} from 'react' +import * as React from 'react' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' diff --git a/src/state/shell/starter-pack.tsx b/src/state/shell/starter-pack.tsx index 8da2bcc5c9..56b4b14fdc 100644 --- a/src/state/shell/starter-pack.tsx +++ b/src/state/shell/starter-pack.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useContext, useState} from 'react' +import {type ReactNode} from 'react' type StateContext = | { @@ -8,13 +9,13 @@ type StateContext = | undefined type SetContext = (v: StateContext) => void -const stateContext = React.createContext(undefined) +const stateContext = createContext(undefined) stateContext.displayName = 'ActiveStarterPackStateContext' -const setContext = React.createContext((_: StateContext) => {}) +const setContext = createContext((_: StateContext) => {}) setContext.displayName = 'ActiveStarterPackSetContext' -export function Provider({children}: {children: React.ReactNode}) { - const [state, setState] = React.useState() +export function Provider({children}: {children: ReactNode}) { + const [state, setState] = useState() return ( @@ -23,5 +24,5 @@ export function Provider({children}: {children: React.ReactNode}) { ) } -export const useActiveStarterPack = () => React.useContext(stateContext) -export const useSetActiveStarterPack = () => React.useContext(setContext) +export const useActiveStarterPack = () => useContext(stateContext) +export const useSetActiveStarterPack = () => useContext(setContext) diff --git a/src/state/shell/tick-every-minute.tsx b/src/state/shell/tick-every-minute.tsx index d4978470e5..b38de84c49 100644 --- a/src/state/shell/tick-every-minute.tsx +++ b/src/state/shell/tick-every-minute.tsx @@ -1,13 +1,14 @@ -import React from 'react' +import {createContext, useContext, useEffect, useState} from 'react' +import {type PropsWithChildren} from 'react' type StateContext = number -const stateContext = React.createContext(0) +const stateContext = createContext(0) stateContext.displayName = 'TickEveryMinuteContext' -export function Provider({children}: React.PropsWithChildren<{}>) { - const [tick, setTick] = React.useState(Date.now()) - React.useEffect(() => { +export function Provider({children}: PropsWithChildren<{}>) { + const [tick, setTick] = useState(Date.now()) + useEffect(() => { const i = setInterval(() => { setTick(Date.now()) }, 60_000) @@ -17,5 +18,5 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } export function useTickEveryMinute() { - return React.useContext(stateContext) + return useContext(stateContext) } diff --git a/src/state/threadgate-hidden-replies.tsx b/src/state/threadgate-hidden-replies.tsx index af3aaef5d4..213bb94244 100644 --- a/src/state/threadgate-hidden-replies.tsx +++ b/src/state/threadgate-hidden-replies.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {createContext, useCallback, useContext, useMemo, useState} from 'react' +import {type ReactNode} from 'react' import {type AppBskyFeedThreadgate} from '@atproto/api' type StateContext = { @@ -10,25 +11,25 @@ type ApiContext = { removeHiddenReplyUri: (uri: string) => void } -const StateContext = React.createContext({ +const StateContext = createContext({ uris: new Set(), recentlyUnhiddenUris: new Set(), }) StateContext.displayName = 'ThreadgateHiddenRepliesStateContext' -const ApiContext = React.createContext({ +const ApiContext = createContext({ addHiddenReplyUri: () => {}, removeHiddenReplyUri: () => {}, }) ApiContext.displayName = 'ThreadgateHiddenRepliesApiContext' -export function Provider({children}: {children: React.ReactNode}) { - const [uris, setHiddenReplyUris] = React.useState>(new Set()) - const [recentlyUnhiddenUris, setRecentlyUnhiddenUris] = React.useState< - Set - >(new Set()) +export function Provider({children}: {children: ReactNode}) { + const [uris, setHiddenReplyUris] = useState>(new Set()) + const [recentlyUnhiddenUris, setRecentlyUnhiddenUris] = useState>( + new Set(), + ) - const stateCtx = React.useMemo( + const stateCtx = useMemo( () => ({ uris, recentlyUnhiddenUris, @@ -36,7 +37,7 @@ export function Provider({children}: {children: React.ReactNode}) { [uris, recentlyUnhiddenUris], ) - const apiCtx = React.useMemo( + const apiCtx = useMemo( () => ({ addHiddenReplyUri(uri: string) { setHiddenReplyUris(prev => new Set(prev.add(uri))) @@ -64,11 +65,11 @@ export function Provider({children}: {children: React.ReactNode}) { } export function useThreadgateHiddenReplyUris() { - return React.useContext(StateContext) + return useContext(StateContext) } export function useThreadgateHiddenReplyUrisAPI() { - return React.useContext(ApiContext) + return useContext(ApiContext) } export function useMergedThreadgateHiddenReplies({ @@ -77,7 +78,7 @@ export function useMergedThreadgateHiddenReplies({ threadgateRecord?: AppBskyFeedThreadgate.Record }) { const {uris, recentlyUnhiddenUris} = useThreadgateHiddenReplyUris() - return React.useMemo(() => { + return useMemo(() => { const set = new Set([...(threadgateRecord?.hiddenReplies || []), ...uris]) for (const uri of recentlyUnhiddenUris) { set.delete(uri) @@ -88,7 +89,7 @@ export function useMergedThreadgateHiddenReplies({ export function useMergeThreadgateHiddenReplies() { const {uris, recentlyUnhiddenUris} = useThreadgateHiddenReplyUris() - return React.useCallback( + return useCallback( (threadgate?: AppBskyFeedThreadgate.Record) => { const set = new Set([...(threadgate?.hiddenReplies || []), ...uris]) for (const uri of recentlyUnhiddenUris) { diff --git a/src/state/userActionHistory.ts b/src/state/userActionHistory.ts index 8ffe7241e6..a1e9697576 100644 --- a/src/state/userActionHistory.ts +++ b/src/state/userActionHistory.ts @@ -1,4 +1,4 @@ -import React from 'react' +import {useState} from 'react' const LIKE_WINDOW = 100 const FOLLOW_WINDOW = 100 @@ -45,7 +45,7 @@ export function getActionHistory() { } export function useActionHistorySnapshot() { - return React.useState(() => getActionHistory())[0] + return useState(() => getActionHistory())[0] } export function like(postUris: string[]) { diff --git a/src/view/icons/Logo.tsx b/src/view/icons/Logo.tsx index d7208df13c..0822eff9e6 100644 --- a/src/view/icons/Logo.tsx +++ b/src/view/icons/Logo.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {forwardRef} from 'react' import {type TextProps} from 'react-native' import Svg, { Defs, @@ -20,7 +20,7 @@ type Props = { style?: TextProps['style'] } & Omit -export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { +export const Logo = forwardRef(function LogoImpl(props: Props, ref) { const t = useTheme() const {fill, ...rest} = props const gradient = fill === 'sky' diff --git a/src/view/screens/CommunityGuidelines.tsx b/src/view/screens/CommunityGuidelines.tsx index c80981b04a..fa21b7b7f4 100644 --- a/src/view/screens/CommunityGuidelines.tsx +++ b/src/view/screens/CommunityGuidelines.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback} from 'react' import {View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' @@ -28,7 +28,7 @@ export const CommunityGuidelinesScreen = (_props: Props) => { const setMinimalShellMode = useSetMinimalShellMode() useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), )