From aac898d229de12479569658ceef42ce1b324e5d2 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 8 Oct 2025 17:09:03 +0300 Subject: [PATCH] fix immutability errors --- .../VideoEmbedInner/VideoEmbedInnerWeb.tsx | 12 ++++++------ src/components/ProgressGuide/FollowDialog.tsx | 11 ++++++----- .../moderation/ModerationDetailsDialog.tsx | 4 +++- src/state/queries/actor-autocomplete.ts | 16 ++++++++-------- src/view/com/pager/TabBar.tsx | 2 +- src/view/com/posts/PostFeed.tsx | 11 +++++++---- src/view/com/util/Views.web.tsx | 9 +++++---- 7 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx index 52449698c2..49dd816c67 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerWeb.tsx @@ -16,13 +16,13 @@ export function VideoEmbedInnerWeb({ active, setActive, onScreen, - lastKnownTime, + lastKnownTime: lastKnownTimeRef, }: { embed: AppBskyEmbedVideo.View active: boolean setActive: () => void onScreen: boolean - lastKnownTime: React.MutableRefObject + lastKnownTime: React.RefObject }) { const containerRef = useRef(null) const videoRef = useRef(null) @@ -47,10 +47,10 @@ export function VideoEmbedInnerWeb({ }) useEffect(() => { - if (lastKnownTime.current && videoRef.current) { - videoRef.current.currentTime = lastKnownTime.current + if (lastKnownTimeRef.current && videoRef.current) { + videoRef.current.currentTime = lastKnownTimeRef.current } - }, [lastKnownTime]) + }, [lastKnownTimeRef]) return ( { - lastKnownTime.current = e.currentTarget.currentTime + lastKnownTimeRef.current = e.currentTarget.currentTime }} /> {embed.alt && ( diff --git a/src/components/ProgressGuide/FollowDialog.tsx b/src/components/ProgressGuide/FollowDialog.tsx index 3dd308e83e..0f286028b9 100644 --- a/src/components/ProgressGuide/FollowDialog.tsx +++ b/src/components/ProgressGuide/FollowDialog.tsx @@ -195,14 +195,15 @@ function DialogInner({guide}: {guide: Follow10ProgressGuide}) { resultsKey, ]) - if ( + const isEmpty = searchText && !isFetchingSearchResults && !items.length && !isSearchResultsError - ) { - items.push({type: 'empty', key: 'empty', message: _(msg`No results`)}) - } + + const allItems = isEmpty + ? [{type: 'empty', key: 'empty', message: _(msg`No results`)}] + : items const renderItems = useCallback( ({item, index}: {item: Item; index: number}) => { @@ -260,7 +261,7 @@ function DialogInner({guide}: {guide: Follow10ProgressGuide}) { return ( - Expires in {timeDiff(Date.now(), modcause.label.exp)} + Expires in {timeDiff(tick, modcause.label.exp)} diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts index 80f7dfabdf..51ddafe169 100644 --- a/src/state/queries/actor-autocomplete.ts +++ b/src/state/queries/actor-autocomplete.ts @@ -29,19 +29,19 @@ export function useActorAutocompleteQuery( const moderationOpts = useModerationOpts() const agent = useAgent() - prefix = prefix.toLowerCase().trim() - if (prefix.endsWith('.')) { + let cleanPrefix = prefix.toLowerCase().trim() + if (cleanPrefix.endsWith('.')) { // Going from "foo" to "foo." should not clear matches. - prefix = prefix.slice(0, -1) + cleanPrefix = cleanPrefix.slice(0, -1) } return useQuery({ staleTime: STALE.MINUTES.ONE, - queryKey: RQKEY(prefix || ''), + queryKey: RQKEY(cleanPrefix || ''), async queryFn() { - const res = prefix + const res = cleanPrefix ? await agent.searchActorsTypeahead({ - q: prefix, + q: cleanPrefix, limit: limit || 8, }) : undefined @@ -50,12 +50,12 @@ export function useActorAutocompleteQuery( select: React.useCallback( (data: AppBskyActorDefs.ProfileViewBasic[]) => { return computeSuggestions({ - q: prefix, + q: cleanPrefix, searched: data, moderationOpts: moderationOpts || DEFAULT_MOD_OPTS, }) }, - [prefix, moderationOpts], + [cleanPrefix, moderationOpts], ), placeholderData: maintainData ? keepPreviousData : undefined, }) diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index 70358fd102..5234a06f50 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -331,7 +331,7 @@ export function TabBar({ syncScrollState.set('unsynced') }} onScroll={e => { - scrollX.value = Math.round(e.nativeEvent.contentOffset.x) + scrollX.set(Math.round(e.nativeEvent.contentOffset.x)) }}> { diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx index fe6351cd44..5f9ac9abbc 100644 --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -226,7 +226,8 @@ let PostFeed = ({ const initialNumToRender = useInitialNumToRender() const feedFeedback = useFeedFeedbackContext() const [isPTRing, setIsPTRing] = useState(false) - const lastFetchRef = useRef(Date.now()) + const [firstFetchTime] = useState(() => Date.now()) + const lastFetchRef = useRef(firstFetchTime) const [feedType, feedUriOrActorDid, feedTab] = feed.split('|') const {gtMobile} = useBreakpoints() const {rightNavVisible} = useLayoutBreakpoints() @@ -263,9 +264,11 @@ let PostFeed = ({ fetchNextPage, } = usePostFeedQuery(feed, feedParams, opts) const lastFetchedAt = data?.pages[0].fetchedAt - if (lastFetchedAt) { - lastFetchRef.current = lastFetchedAt - } + useEffect(() => { + if (lastFetchedAt) { + lastFetchRef.current = lastFetchedAt + } + }, [lastFetchedAt]) const isEmpty = useMemo( () => !isFetching && !data?.pages?.some(page => page.slices.length), [isFetching, data], diff --git a/src/view/com/util/Views.web.tsx b/src/view/com/util/Views.web.tsx index 9a3e8a4aeb..a1d5e777f9 100644 --- a/src/view/com/util/Views.web.tsx +++ b/src/view/com/util/Views.web.tsx @@ -103,6 +103,8 @@ export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl( paddingTop: Math.abs(contentOffset.y), }) } + // @ts-expect-error web only + let dataSet = props.dataSet || {} if (desktopFixedHeight) { if (typeof desktopFixedHeight === 'number') { // @ts-expect-error Web only -prf @@ -121,10 +123,7 @@ export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl( // around this, we set data-stable-gutters which can then be // styled in our external CSS. // -prf - // @ts-expect-error web only -prf - props.dataSet = props.dataSet || {} - // @ts-expect-error web only -prf - props.dataSet.stableGutters = '1' + dataSet = {...dataSet, stableGutters: '1'} } } return ( @@ -133,6 +132,8 @@ export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl( contentContainerStyle={[styles.contentContainer, contentContainerStyle]} style={style} contentOffset={contentOffset} + // @ts-expect-error web only + dataSet={dataSet} {...props} /> )