Live video on the AT Protocol
at natb/reporting-interface 83 lines 2.3 kB view raw
1import { useEffect } from "react"; 2import { 3 SharedValue, 4 useSharedValue, 5 withTiming, 6} from "react-native-reanimated"; 7import { useDispatch, useSelector } from "react-redux"; 8import { useWindowDimensions } from "tamagui"; 9 10import { 11 selectIsSidebarCollapsed, 12 selectIsSidebarHidden, 13 selectSidebarTargetWidth, 14 toggleSidebar, 15} from "../features/base/sidebarSlice"; 16import { RootState } from "../store/store"; 17 18// Returns *true* if the screen is > 1024px 19function useIsLargeScreen() { 20 const { width } = useWindowDimensions(); 21 // gtMd breakpoint 22 return width >= 980 + 1; 23} 24 25export interface UseSidebarOutput { 26 isActive: boolean; 27 isCollapsed: boolean; 28 isHidden: boolean; 29 animatedWidth: SharedValue<number>; 30 toggle: () => void; 31} 32 33/* 34 * useSidebarControl 35 * A hook to control the custom sidebar on desktop, using Redux for state. 36 * 37 * Returns: An interface containing: 38 * - isActive: boolean - True if the screen is considered large (width >= 1024px). 39 * - isCollapsed: boolean - The current collapsed state of the sidebar from Redux. 40 * - animatedWidth: SharedValue<number> - An animated value controlling the sidebar's width. 41 * - toggle: () => void - A function to dispatch the Redux action to toggle the sidebar. 42 */ 43export function useSidebarControl(): UseSidebarOutput { 44 const dispatch = useDispatch(); 45 const isCollapsed = useSelector((state: RootState) => 46 selectIsSidebarCollapsed(state), 47 ); 48 const targetWidth = useSelector((state: RootState) => 49 selectSidebarTargetWidth(state), 50 ); 51 52 const isHidden = useSelector((state: RootState) => 53 selectIsSidebarHidden(state), 54 ); 55 56 const animatedWidth = useSharedValue(targetWidth); 57 58 const isActive = useIsLargeScreen(); 59 useEffect(() => { 60 if (isActive) { 61 if (!isHidden && targetWidth < 64) targetWidth == 64; 62 // Only animate if the sidebar is active 63 animatedWidth.value = withTiming(targetWidth, { duration: 250 }); 64 } else { 65 animatedWidth.value = targetWidth; 66 } 67 }, [targetWidth, isActive, animatedWidth]); 68 69 const handleToggle = () => { 70 if (isActive) { 71 // Only allow toggle if the sidebar functionality is active 72 dispatch(toggleSidebar()); 73 } 74 }; 75 76 return { 77 isActive, 78 isCollapsed, 79 animatedWidth, 80 isHidden, 81 toggle: handleToggle, 82 }; 83}