Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client

Fix jumpy modal regression (#1945)

authored by danabra.mov and committed by

GitHub 3043b324 c03c7440

+33 -6
+23
src/lib/hooks/useNonReactiveCallback.ts
··· 1 + import {useCallback, useInsertionEffect, useRef} from 'react' 2 + 3 + // This should be used sparingly. It erases reactivity, i.e. when the inputs 4 + // change, the function itself will remain the same. This means that if you 5 + // use this at a higher level of your tree, and then some state you read in it 6 + // changes, there is no mechanism for anything below in the tree to "react" 7 + // to this change (e.g. by knowing to call your function again). 8 + // 9 + // Also, you should avoid calling the returned function during rendering 10 + // since the values captured by it are going to lag behind. 11 + export function useNonReactiveCallback<T extends Function>(fn: T): T { 12 + const ref = useRef(fn) 13 + useInsertionEffect(() => { 14 + ref.current = fn 15 + }, [fn]) 16 + return useCallback( 17 + (...args: any) => { 18 + const latestFn = ref.current 19 + return latestFn(...args) 20 + }, 21 + [ref], 22 + ) as unknown as T 23 + }
+10 -6
src/view/com/modals/Modal.tsx
··· 9 9 import once from 'lodash.once' 10 10 11 11 import {useModals, useModalControls} from '#/state/modals' 12 + import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' 12 13 import * as ConfirmModal from './Confirm' 13 14 import * as EditProfileModal from './EditProfile' 14 15 import * as ProfilePreviewModal from './ProfilePreview' ··· 50 51 51 52 const navigateOnce = once(navigate) 52 53 53 - const onBottomSheetAnimate = (_fromIndex: number, toIndex: number) => { 54 - if (activeModal?.name === 'profile-preview' && toIndex === 1) { 55 - // begin loading the profile screen behind the scenes 56 - navigateOnce('Profile', {name: activeModal.did}) 57 - } 58 - } 54 + // It seems like the bottom sheet bugs out when this callback changes. 55 + const onBottomSheetAnimate = useNonReactiveCallback( 56 + (_fromIndex: number, toIndex: number) => { 57 + if (activeModal?.name === 'profile-preview' && toIndex === 1) { 58 + // begin loading the profile screen behind the scenes 59 + navigateOnce('Profile', {name: activeModal.did}) 60 + } 61 + }, 62 + ) 59 63 const onBottomSheetChange = async (snapPoint: number) => { 60 64 if (snapPoint === -1) { 61 65 closeModal()