Live video on the AT Protocol
1import { useEffect } from "react";
2import {
3 SharedValue,
4 useSharedValue,
5 withTiming,
6} from "react-native-reanimated";
7import { useWindowDimensions } from "tamagui";
8import { useDispatch, useSelector } from "react-redux";
9
10import {
11 toggleSidebar,
12 selectIsSidebarCollapsed,
13 selectSidebarTargetWidth,
14 selectIsSidebarHidden,
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 // Only animate if the sidebar is active
62 animatedWidth.value = withTiming(targetWidth, { duration: 250 });
63 } else {
64 animatedWidth.value = targetWidth;
65 }
66 }, [targetWidth, isActive, animatedWidth]);
67
68 const handleToggle = () => {
69 if (isActive) {
70 // Only allow toggle if the sidebar functionality is active
71 dispatch(toggleSidebar());
72 }
73 };
74
75 return {
76 isActive,
77 isCollapsed,
78 animatedWidth,
79 isHidden,
80 toggle: handleToggle,
81 };
82}