Create codemod for addressing ESLint warnings (#10032)

This commit is contained in:
DS Boyce
2026-03-11 15:51:31 -07:00
committed by GitHub
parent 80429ec902
commit 1db01a09a8
240 changed files with 1560 additions and 1347 deletions
+3 -3
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useEffect, useState} from 'react'
import {Pressable, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {msg} from '@lingui/core/macro'
@@ -33,9 +33,9 @@ export const SplashScreen = ({
const {_} = useLingui()
const t = useTheme()
const {isTabletOrMobile: IS_WEB_MOBILE} = useWebMediaQueries()
const [showClipOverlay, setShowClipOverlay] = React.useState(false)
const [showClipOverlay, setShowClipOverlay] = useState(false)
React.useEffect(() => {
useEffect(() => {
const getParams = new URLSearchParams(window.location.search)
const clip = getParams.get('clip')
if (clip === 'true') {
@@ -1,5 +1,4 @@
import {View} from 'react-native'
import type React from 'react'
import {MAX_ALT_TEXT} from '#/lib/constants'
import {CharProgress} from '#/view/com/composer/char-progress/CharProgress'
+17 -15
View File
@@ -1,4 +1,6 @@
import React, {
import {
Fragment,
memo,
useCallback,
useEffect,
useImperativeHandle,
@@ -299,7 +301,7 @@ export const ComposePost = ({
[activePost.id],
)
const selectVideo = React.useCallback(
const selectVideo = useCallback(
(postId: string, asset: ImagePickerAsset) => {
const abortController = new AbortController()
composerDispatch({
@@ -485,7 +487,7 @@ export const ComposePost = ({
[_, agent, currentDid, composerDispatch],
)
const handleSelectDraft = React.useCallback(
const handleSelectDraft = useCallback(
async (draftSummary: DraftSummary) => {
logger.debug('loading draft for editing', {
draftId: draftSummary.id,
@@ -553,7 +555,7 @@ export const ComposePost = ({
revokeAllMediaUrls()
}, [closeComposer, queryClient])
const getDraftSaveError = React.useCallback(
const getDraftSaveError = useCallback(
(e: unknown): string => {
if (e instanceof AppBskyDraftCreateDraft.DraftLimitReachedError) {
return _(msg`You've reached the maximum number of drafts`)
@@ -563,7 +565,7 @@ export const ComposePost = ({
[_],
)
const validateDraftTextOrError = React.useCallback((): boolean => {
const validateDraftTextOrError = useCallback((): boolean => {
const tooLong = composerState.thread.posts.some(
post => post.richtext.graphemeLength > MAX_DRAFT_GRAPHEME_LENGTH,
)
@@ -578,7 +580,7 @@ export const ComposePost = ({
return true
}, [composerState.thread.posts, _])
const handleSaveDraft = React.useCallback(async () => {
const handleSaveDraft = useCallback(async () => {
setError('')
if (!validateDraftTextOrError()) {
return
@@ -621,7 +623,7 @@ export const ComposePost = ({
])
// Save without closing - for use by DraftsButton
const saveCurrentDraft = React.useCallback(async (): Promise<{
const saveCurrentDraft = useCallback(async (): Promise<{
success: boolean
}> => {
setError('')
@@ -648,7 +650,7 @@ export const ComposePost = ({
])
// Handle discard action - fires metric and closes composer
const handleDiscard = React.useCallback(() => {
const handleDiscard = useCallback(() => {
const posts = thread.posts
const hasContent = posts.some(
post =>
@@ -665,7 +667,7 @@ export const ComposePost = ({
}, [thread.posts, ax, onClose])
// Check if composer is empty (no content to save)
const isComposerEmpty = React.useMemo(() => {
const isComposerEmpty = useMemo(() => {
// Has multiple posts means it's not empty
if (thread.posts.length > 1) return false
@@ -683,7 +685,7 @@ export const ComposePost = ({
}, [thread.posts])
// Clear the composer (discard current content)
const handleClearComposer = React.useCallback(() => {
const handleClearComposer = useCallback(() => {
composerDispatch({
type: 'clear',
initInteractionSettings: preferences?.postInteractionSettings,
@@ -794,7 +796,7 @@ export const ComposePost = ({
),
)
const onPressPublish = React.useCallback(async () => {
const onPressPublish = useCallback(async () => {
if (isPublishing) {
return
}
@@ -1015,7 +1017,7 @@ export const ComposePost = ({
onPressPublish()
})
React.useEffect(() => {
useEffect(() => {
if (publishOnUpload) {
let erroredVideos = 0
let uploadingVideos = 0
@@ -1181,7 +1183,7 @@ export const ComposePost = ({
onLayout={onScrollViewLayout}>
{replyTo ? <ComposerReplyTo replyTo={replyTo} /> : undefined}
{thread.posts.map((post, index) => (
<React.Fragment key={post.id + (composerState.draftId ?? '')}>
<Fragment key={post.id + (composerState.draftId ?? '')}>
<ComposerPost
post={post}
dispatch={composerDispatch}
@@ -1201,7 +1203,7 @@ export const ComposePost = ({
{IS_WEBFooterSticky && post.id === activePost.id && (
<View style={styles.stickyFooterWeb}>{footer}</View>
)}
</React.Fragment>
</Fragment>
))}
</Animated.ScrollView>
{!IS_WEBFooterSticky && footer}
@@ -1273,7 +1275,7 @@ export const ComposePost = ({
)
}
let ComposerPost = React.memo(function ComposerPost({
let ComposerPost = memo(function ComposerPost({
post,
dispatch,
textInput,
@@ -1,7 +1,6 @@
import {View} from 'react-native'
import {KeyboardStickyView} from 'react-native-keyboard-controller'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import type React from 'react'
import {atoms as a, useTheme} from '#/alf'
import {IS_WEB} from '#/env'
+32 -33
View File
@@ -1,4 +1,4 @@
import React, {useState} from 'react'
import {memo, useMemo, useState} from 'react'
import {
findNodeHandle,
type ImageStyle,
@@ -37,7 +37,7 @@ interface GalleryProps {
}
export let Gallery = (props: GalleryProps): React.ReactNode => {
const [containerInfo, setContainerInfo] = React.useState<Dimensions>()
const [containerInfo, setContainerInfo] = useState<Dimensions>()
const onLayout = (evt: LayoutChangeEvent) => {
const {width, height} = evt.nativeEvent.layout
@@ -55,7 +55,7 @@ export let Gallery = (props: GalleryProps): React.ReactNode => {
</View>
)
}
Gallery = React.memo(Gallery)
Gallery = memo(Gallery)
interface GalleryInnerProps extends GalleryProps {
containerInfo: Dimensions
@@ -64,39 +64,38 @@ interface GalleryInnerProps extends GalleryProps {
const GalleryInner = ({images, containerInfo, dispatch}: GalleryInnerProps) => {
const {isMobile} = useWebMediaQueries()
const {altTextControlStyle, imageControlsStyle, imageStyle} =
React.useMemo(() => {
const side =
images.length === 1
? 250
: (containerInfo.width - IMAGE_GAP * (images.length - 1)) /
images.length
const {altTextControlStyle, imageControlsStyle, imageStyle} = useMemo(() => {
const side =
images.length === 1
? 250
: (containerInfo.width - IMAGE_GAP * (images.length - 1)) /
images.length
const isOverflow = isMobile && images.length > 2
const isOverflow = isMobile && images.length > 2
return {
altTextControlStyle: isOverflow
? {left: 4, bottom: 4}
return {
altTextControlStyle: isOverflow
? {left: 4, bottom: 4}
: !isMobile && images.length < 3
? {left: 8, top: 8}
: {left: 4, top: 4},
imageControlsStyle: {
display: 'flex' as const,
flexDirection: 'row' as const,
position: 'absolute' as const,
...(isOverflow
? {top: 4, right: 4, gap: 4}
: !isMobile && images.length < 3
? {left: 8, top: 8}
: {left: 4, top: 4},
imageControlsStyle: {
display: 'flex' as const,
flexDirection: 'row' as const,
position: 'absolute' as const,
...(isOverflow
? {top: 4, right: 4, gap: 4}
: !isMobile && images.length < 3
? {top: 8, right: 8, gap: 8}
: {top: 4, right: 4, gap: 4}),
zIndex: 1,
},
imageStyle: {
height: side,
width: side,
},
}
}, [images.length, containerInfo, isMobile])
? {top: 8, right: 8, gap: 8}
: {top: 4, right: 4, gap: 4}),
zIndex: 1,
},
imageStyle: {
height: side,
width: side,
},
}
}, [images.length, containerInfo, isMobile])
return images.length !== 0 ? (
<>
@@ -1,4 +1,4 @@
import React from 'react'
import {useEffect, useMemo, useRef} from 'react'
import {Pressable, useWindowDimensions, View} from 'react-native'
import Picker from '@emoji-mart/react'
import {msg} from '@lingui/core/macro'
@@ -52,9 +52,9 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
const {_} = useLingui()
const {height, width} = useWindowDimensions()
const isShiftDown = React.useRef(false)
const isShiftDown = useRef(false)
const position = React.useMemo(() => {
const position = useMemo(() => {
if (pinToTop) {
return {
top: state.pos.top - PICKER_HEIGHT + HEIGHT_OFFSET - 10,
@@ -86,7 +86,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
}
}, [state.pos, height, width, pinToTop])
React.useEffect(() => {
useEffect(() => {
if (!state.isOpen) return
const onKeyDown = (e: KeyboardEvent) => {
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {init} from 'emoji-mart'
/**
@@ -11,7 +11,7 @@ let loadRequested = false
* {@link https://github.com/missive/emoji-mart/blob/16978d04a766eec6455e2e8bb21cd8dc0b3c7436/README.md?plain=1#L194}
*/
export function useWebPreloadEmoji({immediate}: {immediate?: boolean} = {}) {
const preload = React.useCallback(async () => {
const preload = useCallback(async () => {
if (loadRequested) return
loadRequested = true
try {
@@ -3,7 +3,6 @@ import {View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import type React from 'react'
import {logger} from '#/logger'
import * as Toast from '#/view/com/util/Toast'
+5 -5
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useMemo} from 'react'
import {useNavigation} from '@react-navigation/native'
import {type NavigationProp} from '#/lib/routes/types'
@@ -19,7 +19,7 @@ export function HomeHeader(
const {hasSession} = useSession()
const navigation = useNavigation<NavigationProp>()
const hasPinnedCustom = React.useMemo<boolean>(() => {
const hasPinnedCustom = useMemo<boolean>(() => {
if (!hasSession) return false
return feeds.some(tab => {
const isFollowing = tab.uri === 'following'
@@ -27,7 +27,7 @@ export function HomeHeader(
})
}, [feeds, hasSession])
const items = React.useMemo(() => {
const items = useMemo(() => {
const pinnedNames = feeds.map(f => f.displayName)
if (!hasPinnedCustom) {
return pinnedNames.concat('Feeds ✨')
@@ -35,11 +35,11 @@ export function HomeHeader(
return pinnedNames
}, [hasPinnedCustom, feeds])
const onPressFeedsLink = React.useCallback(() => {
const onPressFeedsLink = useCallback(() => {
navigation.navigate('Feeds')
}, [navigation])
const onSelect = React.useCallback(
const onSelect = useCallback(
(index: number) => {
if (!hasPinnedCustom && index === items.length - 1) {
onPressFeedsLink()
@@ -2,7 +2,6 @@ import {type JSX} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
import {HITSLOP_10} from '#/lib/constants'
import {useKawaiiMode} from '#/state/preferences/kawaii'
@@ -1,4 +1,4 @@
import React, {useState} from 'react'
import {memo, useState} from 'react'
import {ActivityIndicator, StyleSheet} from 'react-native'
import {
Gesture,
@@ -472,4 +472,4 @@ function withClampedSpring(value: any) {
return withSpring(value, {overshootClamping: true})
}
export default React.memo(ImageItem)
export default memo(ImageItem)
@@ -6,7 +6,7 @@
*
*/
import React, {useState} from 'react'
import {memo, useState} from 'react'
import {ActivityIndicator, StyleSheet} from 'react-native'
import {
Gesture,
@@ -363,4 +363,4 @@ const getZoomRectAfterDoubleTap = (
}
}
export default React.memo(ImageItem)
export default memo(ImageItem)
@@ -1,6 +1,6 @@
// default implementation fallback for web
import React from 'react'
import {memo} from 'react'
import {View} from 'react-native'
import {type PanGesture} from 'react-native-gesture-handler'
import {type SharedValue} from 'react-native-reanimated'
@@ -44,4 +44,4 @@ const ImageItem = (_props: Props) => {
return <View />
}
export default React.memo(ImageItem)
export default memo(ImageItem)
+7 -7
View File
@@ -7,7 +7,7 @@
*/
// Original code copied and simplified from the link below as the codebase is currently not maintained:
// https://github.com/jobtoday/react-native-image-viewing
import React, {useCallback, useEffect, useMemo, useState} from 'react'
import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {
LayoutAnimation,
PixelRatio,
@@ -104,7 +104,7 @@ export default function ImageViewRoot({
setActiveLightbox(nextLightbox)
}
React.useEffect(() => {
useEffect(() => {
if (!nextLightbox) {
return
}
@@ -150,7 +150,7 @@ export default function ImageViewRoot({
},
)
const onFlyAway = React.useCallback(() => {
const onFlyAway = useCallback(() => {
'worklet'
openProgress.set(0)
runOnJS(onRequestClose)()
@@ -216,7 +216,7 @@ function ImageView({
const [isDragging, setIsDragging] = useState(false)
const [imageIndex, setImageIndex] = useState(initialImageIndex)
const [showControls, setShowControls] = useState(true)
const [isAltExpanded, setAltExpanded] = React.useState(false)
const [isAltExpanded, setAltExpanded] = useState(false)
const dismissSwipeTranslateY = useSharedValue(0)
const isFlyingAway = useSharedValue(false)
@@ -418,7 +418,7 @@ function LightboxImage({
openProgress: SharedValue<number>
dismissSwipeTranslateY: SharedValue<number>
}) {
const [fetchedDims, setFetchedDims] = React.useState<Dimensions | null>(null)
const [fetchedDims, setFetchedDims] = useState<Dimensions | null>(null)
const dims = fetchedDims ?? imageSrc.dimensions ?? imageSrc.thumbDimensions
let imageAspect: number | undefined
if (dims) {
@@ -432,7 +432,7 @@ function LightboxImage({
width: widthDelayedForJSThreadOnly,
height: heightDelayedForJSThreadOnly,
} = useWindowDimensions()
const measureSafeArea = React.useCallback(() => {
const measureSafeArea = useCallback(() => {
'worklet'
let safeArea: Rect | null = measure(safeAreaRef)
if (!safeArea) {
@@ -563,7 +563,7 @@ function LightboxFooter({
onPressShare: (uri: string) => void
}) {
const {alt: altText, uri} = images[index]
const isMomentumScrolling = React.useRef(false)
const isMomentumScrolling = useRef(false)
return (
<ScrollView
style={styles.footerScrollView}
+8 -8
View File
@@ -1,4 +1,4 @@
import React, {type JSX, useCallback} from 'react'
import {type JSX, useCallback, useMemo, useState} from 'react'
import {
Dimensions,
type GestureResponderEvent,
@@ -57,7 +57,7 @@ export function ListMembers({
}) {
const t = useTheme()
const {_} = useLingui()
const [isRefreshing, setIsRefreshing] = React.useState(false)
const [isRefreshing, setIsRefreshing] = useState(false)
const {openModal} = useModalControls()
const {currentAccount} = useSession()
const moderationOpts = useModerationOpts()
@@ -77,7 +77,7 @@ export function ListMembers({
const isOwner =
currentAccount && data?.pages[0].list.creator.did === currentAccount.did
const items = React.useMemo(() => {
const items = useMemo(() => {
let items: any[] = []
if (isFetched) {
if (isEmpty && isError) {
@@ -102,7 +102,7 @@ export function ListMembers({
// events
// =
const onRefresh = React.useCallback(async () => {
const onRefresh = useCallback(async () => {
setIsRefreshing(true)
try {
await refetch()
@@ -112,7 +112,7 @@ export function ListMembers({
setIsRefreshing(false)
}, [refetch, setIsRefreshing])
const onEndReached = React.useCallback(async () => {
const onEndReached = useCallback(async () => {
if (isFetching || !hasNextPage || isError) return
try {
await fetchNextPage()
@@ -121,11 +121,11 @@ export function ListMembers({
}
}, [isFetching, hasNextPage, isError, fetchNextPage])
const onPressRetryLoadMore = React.useCallback(() => {
const onPressRetryLoadMore = useCallback(() => {
fetchNextPage()
}, [fetchNextPage])
const onPressEditMembership = React.useCallback(
const onPressEditMembership = useCallback(
(e: GestureResponderEvent, profile: bsky.profile.AnyProfileView) => {
e.preventDefault()
openModal({
@@ -141,7 +141,7 @@ export function ListMembers({
// rendering
// =
const renderItem = React.useCallback(
const renderItem = useCallback(
({item}: {item: any}) => {
if (item === EMPTY_ITEM) {
return renderEmptyState()
+5 -5
View File
@@ -1,4 +1,4 @@
import React, {type JSX} from 'react'
import {type JSX, useCallback, useMemo, useState} from 'react'
import {
ActivityIndicator,
FlatList as RNFlatList,
@@ -45,12 +45,12 @@ export function MyLists({
const t = useTheme()
const {_} = useLingui()
const moderationOpts = useModerationOpts()
const [isPTRing, setIsPTRing] = React.useState(false)
const [isPTRing, setIsPTRing] = useState(false)
const {data, isFetching, isFetched, isError, error, refetch} =
useMyListsQuery(filter)
const isEmpty = !isFetching && !data?.length
const items = React.useMemo(() => {
const items = useMemo(() => {
let items: any[] = []
if (isError && isEmpty) {
items = items.concat([ERROR_ITEM])
@@ -85,7 +85,7 @@ export function MyLists({
// events
// =
const onRefresh = React.useCallback(async () => {
const onRefresh = useCallback(async () => {
setIsPTRing(true)
try {
await refetch()
@@ -98,7 +98,7 @@ export function MyLists({
// rendering
// =
const renderItemInner = React.useCallback(
const renderItemInner = useCallback(
({item, index}: {item: any; index: number}) => {
if (item === EMPTY) {
return (
+4 -4
View File
@@ -1,4 +1,4 @@
import React, {useCallback} from 'react'
import {useCallback, useMemo, useState} from 'react'
import {
ActivityIndicator,
StyleSheet,
@@ -56,7 +56,7 @@ export function Component({
closeModal()
}, [closeModal])
const listStyle = React.useMemo(() => {
const listStyle = useMemo(() => {
if (IS_WEB_MOBILE) {
return [pal.border, {height: screenHeight / 2}]
} else if (IS_WEB) {
@@ -141,8 +141,8 @@ function ListItem({
const pal = usePalette('default')
const {_} = useLingui()
const {currentAccount} = useSession()
const [isProcessing, setIsProcessing] = React.useState(false)
const membership = React.useMemo(
const [isProcessing, setIsProcessing] = useState(false)
const membership = useMemo(
() => getMembership(memberships, list.uri, subject),
[memberships, list.uri, subject],
)
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useEffect, useMemo, useState} from 'react'
import {
ActivityIndicator,
type ListRenderItemInfo,
@@ -45,7 +45,7 @@ export function NotificationFeed({
refreshNotifications: () => Promise<void>
}) {
const initialNumToRender = useInitialNumToRender()
const [isPTRing, setIsPTRing] = React.useState(false)
const [isPTRing, setIsPTRing] = useState(false)
const {_} = useLingui()
const moderationOpts = useModerationOpts()
const trackPostView = usePostViewTracking('Notifications')
@@ -70,7 +70,7 @@ export function NotificationFeed({
const isEmpty =
!isFetching && !data?.pages.find(page => page.items.length > 0)
const items = React.useMemo(() => {
const items = useMemo(() => {
let arr: any[] = []
if (isFetched) {
if (isEmpty) {
@@ -89,7 +89,7 @@ export function NotificationFeed({
return arr
}, [isFetched, isError, isEmpty, data])
const onRefresh = React.useCallback(async () => {
const onRefresh = useCallback(async () => {
try {
setIsPTRing(true)
await refreshNotifications()
@@ -102,7 +102,7 @@ export function NotificationFeed({
}
}, [refreshNotifications, setIsPTRing])
const onEndReached = React.useCallback(async () => {
const onEndReached = useCallback(async () => {
if (isFetching || !hasNextPage || isError) return
try {
@@ -112,11 +112,11 @@ export function NotificationFeed({
}
}, [isFetching, hasNextPage, isError, fetchNextPage])
const onPressRetryLoadMore = React.useCallback(() => {
const onPressRetryLoadMore = useCallback(() => {
fetchNextPage()
}, [fetchNextPage])
const renderItem = React.useCallback(
const renderItem = useCallback(
({item, index}: ListRenderItemInfo<any>) => {
if (item === EMPTY_FEED_ITEM) {
return (
@@ -150,7 +150,7 @@ export function NotificationFeed({
[moderationOpts, _, onPressRetryLoadMore, filter],
)
const FeedFooter = React.useCallback(
const FeedFooter = useCallback(
() =>
isFetchingNextPage ? (
<View style={styles.feedFooter}>
@@ -162,7 +162,7 @@ export function NotificationFeed({
[isFetchingNextPage],
)
React.useEffect(() => {
useEffect(() => {
if (!enabled) {
setIsPTRing(false)
}
+3 -3
View File
@@ -1,9 +1,9 @@
import React, {useContext} from 'react'
import {createContext, useContext, useMemo} from 'react'
import {type SharedValue} from 'react-native-reanimated'
import {IS_NATIVE} from '#/env'
export const PagerHeaderContext = React.createContext<{
export const PagerHeaderContext = createContext<{
scrollY: SharedValue<number>
headerHeight: number
} | null>(null)
@@ -24,7 +24,7 @@ export function PagerHeaderProvider({
headerHeight: number
children: React.ReactNode
}) {
const value = React.useMemo(
const value = useMemo(
() => ({scrollY, headerHeight}),
[scrollY, headerHeight],
)
+3 -3
View File
@@ -1,4 +1,4 @@
import React, {useEffect} from 'react'
import {useCallback, useEffect, useRef} from 'react'
import {StyleSheet, View} from 'react-native'
import {
FontAwesomeIcon,
@@ -23,7 +23,7 @@ export function CustomFeedEmptyState() {
const ax = useAnalytics()
const feedFeedback = useFeedFeedbackContext()
const {currentAccount} = useSession()
const hasLoggedDiscoverEmptyErrorRef = React.useRef(false)
const hasLoggedDiscoverEmptyErrorRef = useRef(false)
useEffect(() => {
// Log the empty feed error event
@@ -44,7 +44,7 @@ export function CustomFeedEmptyState() {
const palInverted = usePalette('inverted')
const navigation = useNavigation<NavigationProp>()
const onPressFindAccounts = React.useCallback(() => {
const onPressFindAccounts = useCallback(() => {
if (IS_WEB) {
navigation.navigate('Search', {})
} else {
+3 -3
View File
@@ -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'
@@ -38,7 +38,7 @@ export function FeedShutdownMsg({feedUri}: {feedUri: string}) {
const hasFeedPinned = Boolean(feedConfig)
const hasDiscoverPinned = Boolean(discoverFeedConfig?.pinned)
const onRemoveFeed = React.useCallback(async () => {
const onRemoveFeed = useCallback(async () => {
try {
if (feedConfig) {
await removeFeed(feedConfig)
@@ -58,7 +58,7 @@ export function FeedShutdownMsg({feedUri}: {feedUri: string}) {
}
}, [removeFeed, feedConfig, _, hasDiscoverPinned, setSelectedFeed])
const onReplaceFeed = React.useCallback(async () => {
const onReplaceFeed = useCallback(async () => {
try {
await replaceFeedWithDiscover({
forYouFeedConfig: feedConfig,
+3 -3
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {StyleSheet, View} from 'react-native'
import {
FontAwesomeIcon,
@@ -20,7 +20,7 @@ export function FollowingEmptyState() {
const palInverted = usePalette('inverted')
const navigation = useNavigation<NavigationProp>()
const onPressFindAccounts = React.useCallback(() => {
const onPressFindAccounts = useCallback(() => {
if (IS_WEB) {
navigation.navigate('Search', {})
} else {
@@ -29,7 +29,7 @@ export function FollowingEmptyState() {
}
}, [navigation])
const onPressDiscoverFeeds = React.useCallback(() => {
const onPressDiscoverFeeds = useCallback(() => {
navigation.navigate('Feeds')
}, [navigation])
+3 -3
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {Dimensions, StyleSheet, View} from 'react-native'
import {
FontAwesomeIcon,
@@ -19,7 +19,7 @@ export function FollowingEndOfFeed() {
const palInverted = usePalette('inverted')
const navigation = useNavigation<NavigationProp>()
const onPressFindAccounts = React.useCallback(() => {
const onPressFindAccounts = useCallback(() => {
if (IS_WEB) {
navigation.navigate('Search', {})
} else {
@@ -28,7 +28,7 @@ export function FollowingEndOfFeed() {
}
}, [navigation])
const onPressDiscoverFeeds = React.useCallback(() => {
const onPressDiscoverFeeds = useCallback(() => {
navigation.navigate('Feeds')
}, [navigation])
+7 -7
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useMemo} from 'react'
import {View} from 'react-native'
import {
type AppBskyActorDefs,
@@ -48,7 +48,7 @@ export function PostFeedErrorMessage({
savedFeedConfig?: AppBskyActorDefs.SavedFeed
}) {
const {_: _l} = useLingui()
const knownError = React.useMemo(
const knownError = useMemo(
() => detectKnownError(feedDesc, error),
[feedDesc, error],
)
@@ -101,7 +101,7 @@ function FeedgenErrorMessage({
const pal = usePalette('default')
const {_: _l} = useLingui()
const navigation = useNavigation<NavigationProp>()
const msg = React.useMemo(
const msg = useMemo(
() =>
({
[KnownError.Unknown]: '',
@@ -135,15 +135,15 @@ function FeedgenErrorMessage({
const removePromptControl = Prompt.usePromptControl()
const {mutateAsync: removeFeed} = useRemoveFeedMutation()
const onViewProfile = React.useCallback(() => {
const onViewProfile = useCallback(() => {
navigation.navigate('Profile', {name: ownerDid})
}, [navigation, ownerDid])
const onPressRemoveFeed = React.useCallback(() => {
const onPressRemoveFeed = useCallback(() => {
removePromptControl.open()
}, [removePromptControl])
const onRemoveFeed = React.useCallback(async () => {
const onRemoveFeed = useCallback(async () => {
try {
if (!savedFeedConfig) return
await removeFeed(savedFeedConfig)
@@ -158,7 +158,7 @@ function FeedgenErrorMessage({
}
}, [removeFeed, _l, savedFeedConfig])
const cta = React.useMemo(() => {
const cta = useMemo(() => {
switch (knownError) {
case KnownError.FeedSignedInOnly: {
return null
+2 -2
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useMemo} from 'react'
import {StyleSheet, View} from 'react-native'
import Svg, {Circle, Line} from 'react-native-svg'
import {AtUri} from '@atproto/api'
@@ -19,7 +19,7 @@ export function ViewFullThread({uri}: {uri: string}) {
onOut: onHoverOut,
} = useInteractionState()
const pal = usePalette('default')
const itemHref = React.useMemo(() => {
const itemHref = useMemo(() => {
const urip = new AtUri(uri)
return makeProfileLink({did: urip.hostname, handle: ''}, 'post', urip.rkey)
}, [uri])
+12 -12
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {type AppBskyActorDefs as ActorDefs} from '@atproto/api'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -47,7 +47,7 @@ export function ProfileFollowers({name}: {name: string}) {
const initialNumToRender = useInitialNumToRender()
const {currentAccount} = useSession()
const [isPTRing, setIsPTRing] = React.useState(false)
const [isPTRing, setIsPTRing] = useState(false)
const {
data: resolvedDid,
isLoading: isDidLoading,
@@ -66,7 +66,7 @@ export function ProfileFollowers({name}: {name: string}) {
const isError = !!resolveError || !!error
const isMe = resolvedDid === currentAccount?.did
const followers = React.useMemo(() => {
const followers = useMemo(() => {
if (data?.pages) {
return data.pages.flatMap(page => page.followers)
}
@@ -74,11 +74,11 @@ export function ProfileFollowers({name}: {name: string}) {
}, [data])
// Track pagination events - fire for page 3+ (pages 1-2 may auto-load)
const paginationTrackingRef = React.useRef<{
const paginationTrackingRef = useRef<{
did: string | undefined
page: number
}>({did: undefined, page: 0})
React.useEffect(() => {
useEffect(() => {
const currentPageCount = data?.pages?.length || 0
// Reset tracking when profile changes
if (paginationTrackingRef.current.did !== resolvedDid) {
@@ -99,7 +99,7 @@ export function ProfileFollowers({name}: {name: string}) {
paginationTrackingRef.current.page = currentPageCount
}, [ax, data?.pages?.length, resolvedDid, followers.length])
const onRefresh = React.useCallback(async () => {
const onRefresh = useCallback(async () => {
setIsPTRing(true)
try {
await refetch()
@@ -109,7 +109,7 @@ export function ProfileFollowers({name}: {name: string}) {
setIsPTRing(false)
}, [refetch, setIsPTRing])
const onEndReached = React.useCallback(async () => {
const onEndReached = useCallback(async () => {
if (isFetchingNextPage || !hasNextPage || !!error) return
try {
await fetchNextPage()
@@ -118,14 +118,14 @@ export function ProfileFollowers({name}: {name: string}) {
}
}, [isFetchingNextPage, hasNextPage, error, fetchNextPage])
const renderItemWithContext = React.useCallback(
const renderItemWithContext = useCallback(
({item, index}: {item: ActorDefs.ProfileView; index: number}) =>
renderItem({item, index, contextProfileDid: resolvedDid}),
[resolvedDid],
)
// track pageview
React.useEffect(() => {
useEffect(() => {
if (resolvedDid) {
ax.metric('profile:followers:view', {
contextProfileDid: resolvedDid,
@@ -135,11 +135,11 @@ export function ProfileFollowers({name}: {name: string}) {
}, [ax, resolvedDid, isMe])
// track seen items
const seenItemsRef = React.useRef<Set<string>>(new Set())
React.useEffect(() => {
const seenItemsRef = useRef<Set<string>>(new Set())
useEffect(() => {
seenItemsRef.current.clear()
}, [resolvedDid])
const onItemSeen = React.useCallback(
const onItemSeen = useCallback(
(item: ActorDefs.ProfileView) => {
if (seenItemsRef.current.has(item.did)) {
return
+13 -13
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
import {type AppBskyActorDefs as ActorDefs} from '@atproto/api'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -50,7 +50,7 @@ export function ProfileFollows({name}: {name: string}) {
const {currentAccount} = useSession()
const navigation = useNavigation<NavigationProp>()
const onPressFindAccounts = React.useCallback(() => {
const onPressFindAccounts = useCallback(() => {
if (IS_WEB) {
navigation.navigate('Search', {})
} else {
@@ -59,7 +59,7 @@ export function ProfileFollows({name}: {name: string}) {
}
}, [navigation])
const [isPTRing, setIsPTRing] = React.useState(false)
const [isPTRing, setIsPTRing] = useState(false)
const {
data: resolvedDid,
isLoading: isDidLoading,
@@ -78,7 +78,7 @@ export function ProfileFollows({name}: {name: string}) {
const isError = !!resolveError || !!error
const isMe = resolvedDid === currentAccount?.did
const follows = React.useMemo(() => {
const follows = useMemo(() => {
if (data?.pages) {
return data.pages.flatMap(page => page.follows)
}
@@ -86,11 +86,11 @@ export function ProfileFollows({name}: {name: string}) {
}, [data])
// Track pagination events - fire for page 3+ (pages 1-2 may auto-load)
const paginationTrackingRef = React.useRef<{
const paginationTrackingRef = useRef<{
did: string | undefined
page: number
}>({did: undefined, page: 0})
React.useEffect(() => {
useEffect(() => {
const currentPageCount = data?.pages?.length || 0
// Reset tracking when profile changes
if (paginationTrackingRef.current.did !== resolvedDid) {
@@ -111,7 +111,7 @@ export function ProfileFollows({name}: {name: string}) {
paginationTrackingRef.current.page = currentPageCount
}, [ax, data?.pages?.length, resolvedDid, follows.length])
const onRefresh = React.useCallback(async () => {
const onRefresh = useCallback(async () => {
setIsPTRing(true)
try {
await refetch()
@@ -121,7 +121,7 @@ export function ProfileFollows({name}: {name: string}) {
setIsPTRing(false)
}, [refetch, setIsPTRing])
const onEndReached = React.useCallback(async () => {
const onEndReached = useCallback(async () => {
if (isFetchingNextPage || !hasNextPage || !!error) return
try {
await fetchNextPage()
@@ -130,14 +130,14 @@ export function ProfileFollows({name}: {name: string}) {
}
}, [isFetchingNextPage, hasNextPage, error, fetchNextPage])
const renderItemWithContext = React.useCallback(
const renderItemWithContext = useCallback(
({item, index}: {item: ActorDefs.ProfileView; index: number}) =>
renderItem({item, index, contextProfileDid: resolvedDid}),
[resolvedDid],
)
// track pageview
React.useEffect(() => {
useEffect(() => {
if (resolvedDid) {
ax.metric('profile:following:view', {
contextProfileDid: resolvedDid,
@@ -147,11 +147,11 @@ export function ProfileFollows({name}: {name: string}) {
}, [ax, resolvedDid, isMe])
// track seen items
const seenItemsRef = React.useRef<Set<string>>(new Set())
React.useEffect(() => {
const seenItemsRef = useRef<Set<string>>(new Set())
useEffect(() => {
seenItemsRef.current.clear()
}, [resolvedDid])
const onItemSeen = React.useCallback(
const onItemSeen = useCallback(
(item: ActorDefs.ProfileView) => {
if (seenItemsRef.current.has(item.did)) {
return
+14 -14
View File
@@ -1,4 +1,4 @@
import React, {memo} from 'react'
import {memo, useCallback, useMemo} from 'react'
import {type AppBskyActorDefs} from '@atproto/api'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -108,29 +108,29 @@ let ProfileMenu = ({
const goLiveDisabledDialogControl = useDialogControl()
const addToStarterPacksDialogControl = useDialogControl()
const showLoggedOutWarning = React.useMemo(() => {
const showLoggedOutWarning = useMemo(() => {
return (
profile.did !== currentAccount?.did &&
!!profile.labels?.find(label => label.val === '!no-unauthenticated')
)
}, [currentAccount, profile])
const invalidateProfileQuery = React.useCallback(() => {
const invalidateProfileQuery = useCallback(() => {
queryClient.invalidateQueries({
queryKey: profileQueryKey(profile.did),
})
}, [queryClient, profile.did])
const onPressAddToStarterPacks = React.useCallback(() => {
const onPressAddToStarterPacks = useCallback(() => {
ax.metric('profile:addToStarterPack', {})
addToStarterPacksDialogControl.open()
}, [addToStarterPacksDialogControl])
const onPressShare = React.useCallback(() => {
const onPressShare = useCallback(() => {
shareUrl(toShareUrl(makeProfileLink(profile)))
}, [profile])
const onPressAddRemoveLists = React.useCallback(() => {
const onPressAddRemoveLists = useCallback(() => {
openModal({
name: 'user-add-remove-lists',
subject: profile.did,
@@ -141,7 +141,7 @@ let ProfileMenu = ({
})
}, [profile, openModal, invalidateProfileQuery])
const onPressMuteAccount = React.useCallback(async () => {
const onPressMuteAccount = useCallback(async () => {
if (profile.viewer?.muted) {
try {
await queueUnmute()
@@ -165,7 +165,7 @@ let ProfileMenu = ({
}
}, [ax, profile.viewer?.muted, queueUnmute, _, queueMute])
const blockAccount = React.useCallback(async () => {
const blockAccount = useCallback(async () => {
if (profile.viewer?.blocking) {
try {
await queueUnblock()
@@ -189,7 +189,7 @@ let ProfileMenu = ({
}
}, [ax, profile.viewer?.blocking, _, queueUnblock, queueBlock])
const onPressFollowAccount = React.useCallback(async () => {
const onPressFollowAccount = useCallback(async () => {
try {
await queueFollow()
Toast.show(_(msg({message: 'Account followed', context: 'toast'})))
@@ -201,7 +201,7 @@ let ProfileMenu = ({
}
}, [_, ax, queueFollow])
const onPressUnfollowAccount = React.useCallback(async () => {
const onPressUnfollowAccount = useCallback(async () => {
try {
await queueUnfollow()
Toast.show(_(msg({message: 'Account unfollowed', context: 'toast'})))
@@ -213,19 +213,19 @@ let ProfileMenu = ({
}
}, [_, ax, queueUnfollow])
const onPressReportAccount = React.useCallback(() => {
const onPressReportAccount = useCallback(() => {
reportDialogControl.open()
}, [reportDialogControl])
const onPressShareATUri = React.useCallback(() => {
const onPressShareATUri = useCallback(() => {
shareText(`at://${profile.did}`)
}, [profile.did])
const onPressShareDID = React.useCallback(() => {
const onPressShareDID = useCallback(() => {
shareText(profile.did)
}, [profile.did])
const onPressSearch = React.useCallback(() => {
const onPressSearch = useCallback(() => {
navigation.navigate('ProfileSearch', {name: profile.handle})
}, [navigation, profile.handle])
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {Pressable, View} from 'react-native'
import Animated, {
measure,
@@ -60,7 +60,7 @@ export function ProfileSubpageHeader({
const canGoBack = navigation.canGoBack()
const aviRef = useAnimatedRef()
const _openLightbox = React.useCallback(
const _openLightbox = useCallback(
(uri: string, thumbRect: MeasuredDimensions | null) => {
openLightbox({
images: [
@@ -83,7 +83,7 @@ export function ProfileSubpageHeader({
[openLightbox],
)
const onPressAvi = React.useCallback(() => {
const onPressAvi = useCallback(() => {
if (
avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride)
) {
@@ -8,7 +8,6 @@ import Animated, {
import {type BottomSheetBackdropProps} from '@discord/bottom-sheet/src'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
export function createCustomBackdrop(
onClose?: () => void,
+3 -3
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {isValidElement} from 'react'
import {type StyleProp, type TextStyle, type ViewStyle} from 'react-native'
import {View} from 'react-native'
@@ -45,7 +45,7 @@ export function EmptyState({
return placeholderIcon
}
if (React.isValidElement(icon)) {
if (isValidElement(icon)) {
return icon
}
@@ -77,7 +77,7 @@ export function EmptyState({
a.rounded_full,
a.mt_5xl,
{height: 64, width: 64},
React.isValidElement(icon)
isValidElement(icon)
? a.bg_transparent
: [isTabletOrDesktop && {marginTop: 50}],
]}>
+2 -2
View File
@@ -1,4 +1,4 @@
import React, {useCallback, useEffect} from 'react'
import {useCallback, useEffect} from 'react'
import {type NativeScrollEvent} from 'react-native'
import {
clamp,
@@ -25,7 +25,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
const startMode = useSharedValue<number | null>(null)
const didJustRestoreScroll = useSharedValue<boolean>(false)
const setMode = React.useCallback(
const setMode = useCallback(
(v: boolean) => {
'worklet'
headerMode.set(() =>
+17 -11
View File
@@ -1,4 +1,13 @@
import React, {type JSX, useEffect, useState} from 'react'
import {
forwardRef,
type JSX,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useRef,
useState,
} from 'react'
import {
type NativeScrollEvent,
type NativeSyntheticEvent,
@@ -25,7 +34,7 @@ export type ViewSelectorHandle = {
scrollToTop: () => void
}
export const ViewSelector = React.forwardRef<
export const ViewSelector = forwardRef<
ViewSelectorHandle,
{
sections: string[]
@@ -61,14 +70,14 @@ export const ViewSelector = React.forwardRef<
) {
const pal = usePalette('default')
const [selectedIndex, setSelectedIndex] = useState<number>(0)
const flatListRef = React.useRef<FlatList_INTERNAL>(null)
const flatListRef = useRef<FlatList_INTERNAL>(null)
// events
// =
const keyExtractor = React.useCallback((item: any) => item._reactKey, [])
const keyExtractor = useCallback((item: any) => item._reactKey, [])
const onPressSelection = React.useCallback(
const onPressSelection = useCallback(
(index: number) => setSelectedIndex(clamp(index, 0, sections.length)),
[setSelectedIndex, sections],
)
@@ -76,7 +85,7 @@ export const ViewSelector = React.forwardRef<
onSelectView?.(selectedIndex)
}, [selectedIndex, onSelectView])
React.useImperativeHandle(ref, () => ({
useImperativeHandle(ref, () => ({
scrollToTop: () => {
flatListRef.current?.scrollToOffset({offset: 0})
},
@@ -85,7 +94,7 @@ export const ViewSelector = React.forwardRef<
// rendering
// =
const renderItemInternal = React.useCallback(
const renderItemInternal = useCallback(
({item}: {item: any}) => {
if (item === HEADER_ITEM) {
if (renderHeader) {
@@ -107,10 +116,7 @@ export const ViewSelector = React.forwardRef<
[sections, selectedIndex, onPressSelection, renderHeader, renderItem],
)
const data = React.useMemo(
() => [HEADER_ITEM, SELECTOR_ITEM, ...items],
[items],
)
const data = useMemo(() => [HEADER_ITEM, SELECTOR_ITEM, ...items], [items])
return (
<FlatList_INTERNAL
// @ts-expect-error FlatList_INTERNAL ref type is wrong -sfn
+4 -4
View File
@@ -12,7 +12,7 @@
* need to match layout but which aren't scrolled.
*/
import React from 'react'
import {forwardRef} from 'react'
import {
type FlatList,
type FlatListProps,
@@ -37,7 +37,7 @@ interface AddedProps {
/**
* @deprecated use `Layout` components
*/
export const CenteredView = React.forwardRef(function CenteredView(
export const CenteredView = forwardRef(function CenteredView(
{
style,
topBorder,
@@ -66,7 +66,7 @@ export const CenteredView = React.forwardRef(function CenteredView(
return <View ref={ref} style={style} {...props} />
})
export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl<ItemT>(
export const FlatList_INTERNAL = forwardRef(function FlatListImpl<ItemT>(
{
contentContainerStyle,
style,
@@ -141,7 +141,7 @@ export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl<ItemT>(
/**
* @deprecated use `Layout` components
*/
export const ScrollView = React.forwardRef(function ScrollViewImpl(
export const ScrollView = forwardRef(function ScrollViewImpl(
{contentContainerStyle, ...props}: React.PropsWithChildren<ScrollViewProps>,
ref: React.Ref<Animated.ScrollView>,
) {
-1
View File
@@ -1,5 +1,4 @@
import {Platform} from 'react-native'
import type React from 'react'
const onMouseUp = (e: React.MouseEvent & {target: HTMLElement}) => {
// Only handle whenever it is the middle button
+5 -5
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useState} from 'react'
import {
ActivityIndicator,
type GestureResponderEvent,
@@ -148,8 +148,8 @@ export function Button({
},
)
const [isLoading, setIsLoading] = React.useState(false)
const onPressWrapped = React.useCallback(
const [isLoading, setIsLoading] = useState(false)
const onPressWrapped = useCallback(
async (event: GestureResponderEvent) => {
event.stopPropagation()
event.preventDefault()
@@ -160,7 +160,7 @@ export function Button({
[onPress, withLoading],
)
const getStyle = React.useCallback(
const getStyle = useCallback(
(state: PressableStateCallbackType) => {
const arr = [typeOuterStyle, styles.outer, style]
if (state.pressed) {
@@ -173,7 +173,7 @@ export function Button({
[typeOuterStyle, style],
)
const renderChildern = React.useCallback(() => {
const renderChildern = useCallback(() => {
if (!label) {
return children
}
@@ -1,5 +1,4 @@
import {ScrollView, StyleSheet, View} from 'react-native'
import type React from 'react'
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible'
+2 -2
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useMemo} from 'react'
import {StyleSheet, type TextProps} from 'react-native'
import {UITextView} from 'react-native-uitextview'
@@ -57,7 +57,7 @@ function Text_DEPRECATED({
}
}
const textProps = React.useMemo(() => {
const textProps = useMemo(() => {
const typography = theme.typography[type]
const lineHeightStyle = lineHeight ? lh(theme, type, lineHeight) : undefined
+2 -2
View File
@@ -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<SvgProps, 'style'>
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'
+2 -2
View File
@@ -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]),
)
+2 -2
View File
@@ -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'
@@ -25,7 +25,7 @@ export const CopyrightPolicyScreen = (_props: Props) => {
const setMinimalShellMode = useSetMinimalShellMode()
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
+3 -5
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useState} from 'react'
import {ScrollView, View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -28,9 +28,7 @@ export const DebugScreen = ({}: NativeStackScreenProps<
CommonNavigatorParams,
'Debug'
>) => {
const [colorScheme, setColorScheme] = React.useState<'light' | 'dark'>(
'light',
)
const [colorScheme, setColorScheme] = useState<'light' | 'dark'>('light')
const onToggleColorScheme = () => {
setColorScheme(colorScheme === 'light' ? 'dark' : 'light')
}
@@ -50,7 +48,7 @@ function DebugInner({}: {
colorScheme: 'light' | 'dark'
onToggleColorScheme: () => void
}) {
const [currentView, setCurrentView] = React.useState<number>(0)
const [currentView, setCurrentView] = useState<number>(0)
const pal = usePalette('default')
const {_} = useLingui()
+17 -17
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useMemo, useState} from 'react'
import {View} from 'react-native'
import {
type AppBskyActorDefs,
@@ -65,13 +65,13 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
'DebugMod'
>) => {
const t = useTheme()
const [scenario, setScenario] = React.useState<string[]>(['label'])
const [scenarioSwitches, setScenarioSwitches] = React.useState<string[]>([])
const [label, setLabel] = React.useState<string[]>([LABEL_VALUES[0]])
const [target, setTarget] = React.useState<string[]>(['account'])
const [visibility, setVisiblity] = React.useState<string[]>(['warn'])
const [scenario, setScenario] = useState<string[]>(['label'])
const [scenarioSwitches, setScenarioSwitches] = useState<string[]>([])
const [label, setLabel] = useState<string[]>([LABEL_VALUES[0]])
const [target, setTarget] = useState<string[]>(['account'])
const [visibility, setVisiblity] = useState<string[]>(['warn'])
const [customLabelDef, setCustomLabelDef] =
React.useState<ComAtprotoLabelDefs.LabelValueDefinition>({
useState<ComAtprotoLabelDefs.LabelValueDefinition>({
identifier: 'custom',
blurs: 'content',
severity: 'alert',
@@ -84,7 +84,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
},
],
})
const [view, setView] = React.useState<string[]>(['post'])
const [view, setView] = useState<string[]>(['post'])
const labelStrings = useGlobalLabelStrings()
const {currentAccount} = useSession()
@@ -101,7 +101,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
const did =
isTargetMe && currentAccount ? currentAccount.did : 'did:web:bob.test'
const profile = React.useMemo(() => {
const profile = useMemo(() => {
const mockedProfile = mock.profileViewBasic({
handle: `bob.test`,
displayName: 'Bob Robertson',
@@ -146,7 +146,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
return mockedProfile
}, [scenario, target, label, isSelfLabel, did, isFollowing, currentAccount])
const post = React.useMemo(() => {
const post = useMemo(() => {
return mock.postView({
record: mock.post({
text: "This is the body of the post. It's where the text goes. You get the idea.",
@@ -195,7 +195,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
})
}, [scenario, label, target, profile, isSelfLabel, did])
const replyNotif = React.useMemo(() => {
const replyNotif = useMemo(() => {
const notif = mock.replyNotification({
record: mock.post({
text: "This is the body of the post. It's where the text goes. You get the idea.",
@@ -231,7 +231,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
return item
}, [scenario, label, target, profile, isSelfLabel, did])
const followNotif = React.useMemo(() => {
const followNotif = useMemo(() => {
const notif = mock.followNotification({
author: profile,
subjectDid: currentAccount?.did || '',
@@ -240,7 +240,7 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
return item
}, [profile, currentAccount])
const modOpts = React.useMemo(() => {
const modOpts = useMemo(() => {
return {
userDid: isLoggedOut ? '' : isTargetMe ? did : 'did:web:alice.test',
prefs: {
@@ -265,10 +265,10 @@ export const DebugModScreen = ({}: NativeStackScreenProps<
}
}, [label, visibility, noAdult, isLoggedOut, isTargetMe, did, customLabelDef])
const profileModeration = React.useMemo(() => {
const profileModeration = useMemo(() => {
return moderateProfile(profile, modOpts)
}, [profile, modOpts])
const postModeration = React.useMemo(() => {
const postModeration = useMemo(() => {
return moderatePost(post, modOpts)
}, [post, modOpts])
@@ -706,7 +706,7 @@ function CustomLabelForm({
function Toggler({label, children}: React.PropsWithChildren<{label: string}>) {
const t = useTheme()
const [show, setShow] = React.useState(false)
const [show, setShow] = useState(false)
return (
<View style={a.mb_md}>
<View
@@ -738,7 +738,7 @@ function SmallToggler({
label,
children,
}: React.PropsWithChildren<{label: string}>) {
const [show, setShow] = React.useState(false)
const [show, setShow] = useState(false)
return (
<View>
<View style={[a.flex_row]}>
+15 -15
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useMemo, useRef, useState} from 'react'
import {ActivityIndicator, StyleSheet, View} from 'react-native'
import {type AppBskyFeedDefs} from '@atproto/api'
import {msg} from '@lingui/core/macro'
@@ -108,8 +108,8 @@ export function FeedsScreen(_props: Props) {
const pal = usePalette('default')
const {openComposer} = useOpenComposer()
const {isMobile} = useWebMediaQueries()
const [query, setQuery] = React.useState('')
const [isPTR, setIsPTR] = React.useState(false)
const [query, setQuery] = useState('')
const [isPTR, setIsPTR] = useState(false)
const {
data: savedFeeds,
isPlaceholderData: isSavedFeedsPlaceholder,
@@ -135,20 +135,20 @@ export function FeedsScreen(_props: Props) {
error: searchError,
} = useSearchPopularFeedsMutation()
const {hasSession} = useSession()
const listRef = React.useRef<ListMethods>(null)
const listRef = useRef<ListMethods>(null)
/**
* A search query is present. We may not have search results yet.
*/
const isUserSearching = query.length > 1
const debouncedSearch = React.useMemo(
const debouncedSearch = useMemo(
() => debounce(q => search(q), 500), // debounce for 500ms
[search],
)
const onPressCompose = React.useCallback(() => {
const onPressCompose = useCallback(() => {
openComposer({logContext: 'Fab'})
}, [openComposer])
const onChangeQuery = React.useCallback(
const onChangeQuery = useCallback(
(text: string) => {
setQuery(text)
if (text.length > 1) {
@@ -160,15 +160,15 @@ export function FeedsScreen(_props: Props) {
},
[setQuery, refetchPopularFeeds, debouncedSearch, resetSearch],
)
const onPressCancelSearch = React.useCallback(() => {
const onPressCancelSearch = useCallback(() => {
setQuery('')
refetchPopularFeeds()
resetSearch()
}, [refetchPopularFeeds, setQuery, resetSearch])
const onSubmitQuery = React.useCallback(() => {
const onSubmitQuery = useCallback(() => {
debouncedSearch(query)
}, [query, debouncedSearch])
const onPullToRefresh = React.useCallback(async () => {
const onPullToRefresh = useCallback(async () => {
setIsPTR(true)
await Promise.all([
refetchSavedFeeds().catch(_e => undefined),
@@ -176,7 +176,7 @@ export function FeedsScreen(_props: Props) {
])
setIsPTR(false)
}, [setIsPTR, refetchSavedFeeds, refetchPopularFeeds])
const onEndReached = React.useCallback(() => {
const onEndReached = useCallback(() => {
if (
isPopularFeedsFetching ||
isUserSearching ||
@@ -194,12 +194,12 @@ export function FeedsScreen(_props: Props) {
])
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
const items = React.useMemo(() => {
const items = useMemo(() => {
let slices: FlatlistSlice[] = []
const hasActualSavedCount =
!isSavedFeedsPlaceholder ||
@@ -383,7 +383,7 @@ export function FeedsScreen(_props: Props) {
item => item.type === 'popularFeedsHeader',
)
const onChangeSearchFocus = React.useCallback(
const onChangeSearchFocus = useCallback(
(focus: boolean) => {
if (focus && searchBarIndex > -1) {
if (IS_NATIVE) {
@@ -408,7 +408,7 @@ export function FeedsScreen(_props: Props) {
[searchBarIndex, isMobile],
)
const renderItem = React.useCallback(
const renderItem = useCallback(
({item}: {item: FlatlistSlice}) => {
if (item.type === 'error') {
return <ErrorMessage message={item.error} />
+15 -15
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useEffect, useLayoutEffect, useMemo, useRef} from 'react'
import {ActivityIndicator, StyleSheet} from 'react-native'
import {useFocusEffect} from '@react-navigation/native'
@@ -47,7 +47,7 @@ export function HomeScreen(props: Props) {
const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} =
usePinnedFeedsInfos()
React.useEffect(() => {
useEffect(() => {
if (IS_WEB && !currentAccount) {
const getParams = new URLSearchParams(window.location.search)
const splash = getParams.get('splash')
@@ -106,7 +106,7 @@ function HomeScreenReady({
pinnedFeedInfos: SavedFeedSourceInfo[]
}) {
const ax = useAnalytics()
const allFeeds = React.useMemo(
const allFeeds = useMemo(
() => pinnedFeedInfos.map(f => f.feedDescriptor),
[pinnedFeedInfos],
)
@@ -121,13 +121,13 @@ function HomeScreenReady({
useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName)
useOTAUpdates()
React.useEffect(() => {
useEffect(() => {
requestNotificationsPermission('Home')
}, [requestNotificationsPermission])
const pagerRef = React.useRef<PagerRef>(null)
const lastPagerReportedIndexRef = React.useRef(selectedIndex)
React.useLayoutEffect(() => {
const pagerRef = useRef<PagerRef>(null)
const lastPagerReportedIndexRef = useRef(selectedIndex)
useLayoutEffect(() => {
// Since the pager is not a controlled component, adjust it imperatively
// if the selected index gets out of sync with what it last reported.
// This is supposed to only happen on the web when you use the right nav.
@@ -140,7 +140,7 @@ function HomeScreenReady({
const {hasSession} = useSession()
const setMinimalShellMode = useSetMinimalShellMode()
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
@@ -158,7 +158,7 @@ function HomeScreenReady({
}),
)
const onPageSelected = React.useCallback(
const onPageSelected = useCallback(
(index: number) => {
setMinimalShellMode(false)
const maybeFeed = allFeeds[index]
@@ -179,11 +179,11 @@ function HomeScreenReady({
[ax, setSelectedFeed, setMinimalShellMode, allFeeds],
)
const onPressSelected = React.useCallback(() => {
const onPressSelected = useCallback(() => {
emitSoftReset()
}, [])
const onPageScrollStateChanged = React.useCallback(
const onPageScrollStateChanged = useCallback(
(state: 'idle' | 'dragging' | 'settling') => {
'worklet'
if (state === 'dragging') {
@@ -195,7 +195,7 @@ function HomeScreenReady({
const [demoMode] = useDemoMode()
const renderTabBar = React.useCallback(
const renderTabBar = useCallback(
(props: RenderTabBarFnProps) => {
if (demoMode) {
return (
@@ -222,15 +222,15 @@ function HomeScreenReady({
[onPressSelected, pinnedFeedInfos, demoMode],
)
const renderFollowingEmptyState = React.useCallback(() => {
const renderFollowingEmptyState = useCallback(() => {
return <FollowingEmptyState />
}, [])
const renderCustomFeedEmptyState = React.useCallback(() => {
const renderCustomFeedEmptyState = useCallback(() => {
return <CustomFeedEmptyState />
}, [])
const homeFeedParams = React.useMemo<FeedParams>(() => {
const homeFeedParams = useMemo<FeedParams>(() => {
return {
mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled),
mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled
+3 -3
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {StyleSheet, View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -25,13 +25,13 @@ export const NotFoundScreen = () => {
const setMinimalShellMode = useSetMinimalShellMode()
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
const canGoBack = navigation.canGoBack()
const onPressHome = React.useCallback(() => {
const onPressHome = useCallback(() => {
if (canGoBack) {
navigation.goBack()
} else {
+2 -2
View File
@@ -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'
@@ -25,7 +25,7 @@ export const PrivacyPolicyScreen = (_props: Props) => {
const setMinimalShellMode = useSetMinimalShellMode()
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
+4 -6
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useRef, useState} from 'react'
import {View} from 'react-native'
import {useDialogStateControlContext} from '#/state/dialogs'
@@ -18,11 +18,9 @@ export function Dialogs() {
const testDialog = Dialog.useDialogControl()
const {closeAllDialogs} = useDialogStateControlContext()
const unmountTestDialog = Dialog.useDialogControl()
const [reducedMotionEnabled, setReducedMotionEnabled] =
React.useState<boolean>()
const [shouldRenderUnmountTest, setShouldRenderUnmountTest] =
React.useState(false)
const unmountTestInterval = React.useRef<number>(undefined)
const [reducedMotionEnabled, setReducedMotionEnabled] = useState<boolean>()
const [shouldRenderUnmountTest, setShouldRenderUnmountTest] = useState(false)
const unmountTestInterval = useRef<number>(undefined)
const onUnmountTestStartPressWithClose = () => {
setShouldRenderUnmountTest(true)
+12 -12
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useRef, useState} from 'react'
import {type TextInput, View} from 'react-native'
import {APP_LANGUAGES} from '#/lib/../locale/languages'
@@ -16,21 +16,21 @@ import * as Select from '#/components/Select'
import {H1, H3} from '#/components/Typography'
export function Forms() {
const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a'])
const [toggleGroupBValues, setToggleGroupBValues] = React.useState(['a', 'b'])
const [toggleGroupCValues, setToggleGroupCValues] = React.useState(['a', 'b'])
const [toggleGroupDValues, setToggleGroupDValues] = React.useState(['warn'])
const [segmentedControlValue, setSegmentedControlValue] = React.useState<
const [toggleGroupAValues, setToggleGroupAValues] = useState(['a'])
const [toggleGroupBValues, setToggleGroupBValues] = useState(['a', 'b'])
const [toggleGroupCValues, setToggleGroupCValues] = useState(['a', 'b'])
const [toggleGroupDValues, setToggleGroupDValues] = useState(['warn'])
const [segmentedControlValue, setSegmentedControlValue] = useState<
'hide' | 'warn' | 'show'
>('warn')
const [value, setValue] = React.useState('')
const [date, setDate] = React.useState('2001-01-01')
const [countryCode, setCountryCode] = React.useState<CountryCode>('US')
const [phoneNumber, setPhoneNumber] = React.useState('')
const [lang, setLang] = React.useState('en')
const [value, setValue] = useState('')
const [date, setDate] = useState('2001-01-01')
const [countryCode, setCountryCode] = useState<CountryCode>('US')
const [phoneNumber, setPhoneNumber] = useState('')
const [lang, setLang] = useState('en')
const inputRef = React.useRef<TextInput>(null)
const inputRef = useRef<TextInput>(null)
return (
<View style={[a.gap_4xl, a.align_start]}>
+4 -4
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useMemo, useRef, useState} from 'react'
import {View} from 'react-native'
import {ScrollProvider} from '#/lib/ScrollContext'
@@ -8,10 +8,10 @@ import * as Toggle from '#/components/forms/Toggle'
import {Text} from '#/components/Typography'
export function ListContained() {
const [animated, setAnimated] = React.useState(false)
const ref = React.useRef<ListMethods>(null)
const [animated, setAnimated] = useState(false)
const ref = useRef<ListMethods>(null)
const data = React.useMemo(() => {
const data = useMemo(() => {
return Array.from({length: 100}, (_, i) => ({
id: i,
text: `Message ${i}`,
+2 -2
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useState} from 'react'
import {View} from 'react-native'
import {useNavigation} from '@react-navigation/native'
@@ -28,7 +28,7 @@ import {Typography} from './Typography'
export default function Storybook() {
const {setColorMode, setDarkTheme} = useSetThemePrefs()
const [showContainedList, setShowContainedList] = React.useState(false)
const [showContainedList, setShowContainedList] = useState(false)
const navigation = useNavigation<NavigationProp>()
const requestDeviceGeolocation = useRequestDeviceGeolocation()
const {setDeviceGeolocation} = useDeviceGeolocationApi()
+2 -2
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -25,7 +25,7 @@ export const SupportScreen = (_props: Props) => {
const {_} = useLingui()
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
+2 -2
View File
@@ -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'
@@ -25,7 +25,7 @@ export const TermsOfServiceScreen = (_props: Props) => {
const {_} = useLingui()
useFocusEffect(
React.useCallback(() => {
useCallback(() => {
setMinimalShellMode(false)
}, [setMinimalShellMode]),
)
+3 -3
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useEffect, useRef} from 'react'
import {Modal, View} from 'react-native'
import {useDialogStateControlContext} from '#/state/dialogs'
@@ -14,9 +14,9 @@ export function Composer({}: {winHeight: number}) {
const ref = useComposerCancelRef()
const open = !!state
const prevOpen = React.useRef(open)
const prevOpen = useRef(open)
React.useEffect(() => {
useEffect(() => {
if (open && !prevOpen.current) {
setFullyExpandedCount(c => c + 1)
} else if (!open && prevOpen.current) {
+10 -13
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback, useState} from 'react'
import {StyleSheet, View} from 'react-native'
import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal'
import {RemoveScrollBar} from 'react-remove-scroll-bar'
@@ -41,23 +41,20 @@ function Inner({state}: {state: ComposerOpts}) {
const t = useTheme()
const {gtMobile} = useBreakpoints()
const {reduceMotionEnabled} = useA11y()
const [pickerState, setPickerState] = React.useState<EmojiPickerState>({
const [pickerState, setPickerState] = useState<EmojiPickerState>({
isOpen: false,
pos: {top: 0, left: 0, right: 0, bottom: 0, nextFocusRef: null},
})
const onOpenPicker = React.useCallback(
(pos: EmojiPickerPosition | undefined) => {
if (!pos) return
setPickerState({
isOpen: true,
pos,
})
},
[],
)
const onOpenPicker = useCallback((pos: EmojiPickerPosition | undefined) => {
if (!pos) return
setPickerState({
isOpen: true,
pos,
})
}, [])
const onClosePicker = React.useCallback(() => {
const onClosePicker = useCallback(() => {
setPickerState(prev => ({
...prev,
isOpen: false,
+25 -28
View File
@@ -1,4 +1,4 @@
import React, {type ComponentProps, type JSX} from 'react'
import {type ComponentProps, type JSX, memo, useCallback} from 'react'
import {Linking, ScrollView, TouchableOpacity, View} from 'react-native'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {msg, plural} from '@lingui/core/macro'
@@ -130,7 +130,7 @@ let DrawerProfileCard = ({
</TouchableOpacity>
)
}
DrawerProfileCard = React.memo(DrawerProfileCard)
DrawerProfileCard = memo(DrawerProfileCard)
export {DrawerProfileCard}
let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
@@ -152,7 +152,7 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
// events
// =
const onPressTab = React.useCallback(
const onPressTab = useCallback(
(tab: 'Home' | 'Search' | 'Messages' | 'Notifications' | 'MyProfile') => {
const state = navigation.getState()
setDrawerOpen(false)
@@ -193,48 +193,45 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
[navigation, setDrawerOpen, currentAccount],
)
const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab])
const onPressHome = useCallback(() => onPressTab('Home'), [onPressTab])
const onPressSearch = React.useCallback(
() => onPressTab('Search'),
[onPressTab],
)
const onPressSearch = useCallback(() => onPressTab('Search'), [onPressTab])
const onPressMessages = React.useCallback(
const onPressMessages = useCallback(
() => onPressTab('Messages'),
[onPressTab],
)
const onPressNotifications = React.useCallback(
const onPressNotifications = useCallback(
() => onPressTab('Notifications'),
[onPressTab],
)
const onPressProfile = React.useCallback(() => {
const onPressProfile = useCallback(() => {
onPressTab('MyProfile')
}, [onPressTab])
const onPressMyFeeds = React.useCallback(() => {
const onPressMyFeeds = useCallback(() => {
navigation.navigate('Feeds')
setDrawerOpen(false)
}, [navigation, setDrawerOpen])
const onPressLists = React.useCallback(() => {
const onPressLists = useCallback(() => {
navigation.navigate('Lists')
setDrawerOpen(false)
}, [navigation, setDrawerOpen])
const onPressBookmarks = React.useCallback(() => {
const onPressBookmarks = useCallback(() => {
navigation.navigate('Bookmarks')
setDrawerOpen(false)
}, [navigation, setDrawerOpen])
const onPressSettings = React.useCallback(() => {
const onPressSettings = useCallback(() => {
navigation.navigate('Settings')
setDrawerOpen(false)
}, [navigation, setDrawerOpen])
const onPressFeedback = React.useCallback(() => {
const onPressFeedback = useCallback(() => {
Linking.openURL(
FEEDBACK_FORM_URL({
email: currentAccount?.email,
@@ -243,7 +240,7 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
)
}, [currentAccount])
const onPressHelp = React.useCallback(() => {
const onPressHelp = useCallback(() => {
Linking.openURL(HELP_DESK_URL)
}, [])
@@ -321,7 +318,7 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
</View>
)
}
DrawerContent = React.memo(DrawerContent)
DrawerContent = memo(DrawerContent)
export {DrawerContent}
let DrawerFooter = ({
@@ -375,7 +372,7 @@ let DrawerFooter = ({
</View>
)
}
DrawerFooter = React.memo(DrawerFooter)
DrawerFooter = memo(DrawerFooter)
interface MenuItemProps extends ComponentProps<typeof PressableScale> {
icon: JSX.Element
@@ -408,7 +405,7 @@ let SearchMenuItem = ({
/>
)
}
SearchMenuItem = React.memo(SearchMenuItem)
SearchMenuItem = memo(SearchMenuItem)
let HomeMenuItem = ({
isActive,
@@ -434,7 +431,7 @@ let HomeMenuItem = ({
/>
)
}
HomeMenuItem = React.memo(HomeMenuItem)
HomeMenuItem = memo(HomeMenuItem)
let ChatMenuItem = ({
isActive,
@@ -460,7 +457,7 @@ let ChatMenuItem = ({
/>
)
}
ChatMenuItem = React.memo(ChatMenuItem)
ChatMenuItem = memo(ChatMenuItem)
let NotificationsMenuItem = ({
isActive,
@@ -498,7 +495,7 @@ let NotificationsMenuItem = ({
/>
)
}
NotificationsMenuItem = React.memo(NotificationsMenuItem)
NotificationsMenuItem = memo(NotificationsMenuItem)
let FeedsMenuItem = ({
isActive,
@@ -524,7 +521,7 @@ let FeedsMenuItem = ({
/>
)
}
FeedsMenuItem = React.memo(FeedsMenuItem)
FeedsMenuItem = memo(FeedsMenuItem)
let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
const {_} = useLingui()
@@ -538,7 +535,7 @@ let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
/>
)
}
ListsMenuItem = React.memo(ListsMenuItem)
ListsMenuItem = memo(ListsMenuItem)
let BookmarksMenuItem = ({
isActive,
@@ -564,7 +561,7 @@ let BookmarksMenuItem = ({
/>
)
}
BookmarksMenuItem = React.memo(BookmarksMenuItem)
BookmarksMenuItem = memo(BookmarksMenuItem)
let ProfileMenuItem = ({
isActive,
@@ -589,7 +586,7 @@ let ProfileMenuItem = ({
/>
)
}
ProfileMenuItem = React.memo(ProfileMenuItem)
ProfileMenuItem = memo(ProfileMenuItem)
let SettingsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
const {_} = useLingui()
@@ -602,7 +599,7 @@ let SettingsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => {
/>
)
}
SettingsMenuItem = React.memo(SettingsMenuItem)
SettingsMenuItem = memo(SettingsMenuItem)
function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
const t = useTheme()
+4 -4
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {memo, useCallback} from 'react'
import {View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -18,12 +18,12 @@ let NavSignupCard = ({}: {}): React.ReactNode => {
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'})
// setShowLoggedOut(true)
@@ -71,5 +71,5 @@ let NavSignupCard = ({}: {}): React.ReactNode => {
</View>
)
}
NavSignupCard = React.memo(NavSignupCard)
NavSignupCard = memo(NavSignupCard)
export {NavSignupCard}
+4 -4
View File
@@ -1,4 +1,4 @@
import React from 'react'
import {useCallback} from 'react'
import {View} from 'react-native'
import Animated from 'react-native-reanimated'
import {msg, plural} from '@lingui/core/macro'
@@ -61,18 +61,18 @@ export function BottomBarWeb() {
const unreadMessageCount = useUnreadMessageCount()
const notificationCountStr = useUnreadNotifications()
const showSignIn = React.useCallback(() => {
const showSignIn = useCallback(() => {
closeAllActiveElements()
requestSwitchToAccount({requestedAccount: 'none'})
}, [requestSwitchToAccount, closeAllActiveElements])
const showCreateAccount = React.useCallback(() => {
const showCreateAccount = useCallback(() => {
closeAllActiveElements()
requestSwitchToAccount({requestedAccount: 'new'})
// setShowLoggedOut(true)
}, [requestSwitchToAccount, closeAllActiveElements])
const onLongPressProfile = React.useCallback(() => {
const onLongPressProfile = useCallback(() => {
accountSwitchControl.open()
}, [accountSwitchControl])