Create codemod for addressing ESLint warnings (#10032)
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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 +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}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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])
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}],
|
||||
]}>
|
||||
|
||||
@@ -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(() =>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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]),
|
||||
)
|
||||
|
||||
@@ -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]),
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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]),
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]}>
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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]),
|
||||
)
|
||||
|
||||
@@ -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]),
|
||||
)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user