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} from "../features/base/sidebarSlice";
15import { RootState } from "../store/store";
16
17// Returns *true* if the screen is > 1024px
18function useIsLargeScreen() {
19 const { width } = useWindowDimensions();
20 return width >= 1024;
21}
22
23export interface UseSidebarOutput {
24 isActive: boolean;
25 isCollapsed: boolean;
26 animatedWidth: SharedValue<number>;
27 toggle: () => void;
28}
29
30/*
31 * useSidebarControl
32 * A hook to control the custom sidebar on desktop, using Redux for state.
33 *
34 * Returns: An interface containing:
35 * - isActive: boolean - True if the screen is considered large (width >= 1024px).
36 * - isCollapsed: boolean - The current collapsed state of the sidebar from Redux.
37 * - animatedWidth: SharedValue<number> - An animated value controlling the sidebar's width.
38 * - toggle: () => void - A function to dispatch the Redux action to toggle the sidebar.
39 */
40export function useSidebarControl(): UseSidebarOutput {
41 const dispatch = useDispatch();
42 const isCollapsed = useSelector((state: RootState) =>
43 selectIsSidebarCollapsed(state),
44 );
45 const targetWidth = useSelector((state: RootState) =>
46 selectSidebarTargetWidth(state),
47 );
48
49 const animatedWidth = useSharedValue(targetWidth);
50
51 const isActive = useIsLargeScreen();
52
53 useEffect(() => {
54 if (isActive) {
55 // Only animate if the sidebar is active
56 animatedWidth.value = withTiming(targetWidth, { duration: 250 });
57 } else {
58 animatedWidth.value = targetWidth;
59 }
60 }, [targetWidth, isActive, animatedWidth]);
61
62 const handleToggle = () => {
63 if (isActive) {
64 // Only allow toggle if the sidebar functionality is active
65 dispatch(toggleSidebar());
66 }
67 };
68
69 return {
70 isActive,
71 isCollapsed,
72 animatedWidth,
73 toggle: handleToggle,
74 };
75}