Live video on the AT Protocol
79
fork

Configure Feed

Select the types of activity you want to include in your feed.

at eli/database-resync 143 lines 4.1 kB view raw
1import { DrawerNavigationOptions } from "@react-navigation/drawer"; 2import { DrawerDescriptorMap } from "@react-navigation/drawer/lib/typescript/src/types"; 3import { 4 CommonActions, 5 DrawerNavigationState, 6 ParamListBase, 7} from "@react-navigation/native"; 8import { FileQuestion } from "@tamagui/lucide-icons"; 9import { Platform } from "react-native"; 10import { SharedValue, useAnimatedStyle } from "react-native-reanimated"; 11import { Image, styled, Text, View, YStack } from "tamagui"; 12import SidebarItem from "./sidebar-item"; 13 14const AnimatedYStack = styled(YStack, { 15 name: "AnimatedYStack", 16}); 17 18export interface ExternalDrawerItem { 19 item: React.NamedExoticComponent<any>; 20 label: React.ComponentType<any> | string; 21 onPress: () => void; 22} 23 24interface CustomSidebarProps { 25 collapsed: boolean; 26 hidden: boolean; 27 widthAnim: SharedValue<number>; 28 descriptors: DrawerDescriptorMap; 29 state: DrawerNavigationState<ParamListBase>; 30 externalItems?: ExternalDrawerItem[]; 31} 32 33// Combine standard drawer props with custom props 34type SidebarProps = CustomSidebarProps & DrawerNavigationOptions; 35 36export default function Sidebar({ 37 state, 38 descriptors, 39 collapsed, 40 hidden, 41 widthAnim, 42 externalItems = [], 43}: SidebarProps) { 44 // Apply the defined type to the component props 45 const animatedSidebarStyle = useAnimatedStyle(() => { 46 return { 47 minWidth: widthAnim.value, 48 maxWidth: widthAnim.value, 49 }; 50 }); 51 52 if (hidden) { 53 return <View />; 54 } 55 56 return ( 57 <AnimatedYStack 58 style={animatedSidebarStyle} // Apply the animated style 59 padding="$2" 60 gap="$2" 61 > 62 <View 63 marginTop={Platform.OS === "ios" ? 29 : 12} 64 marginBottom="$5" 65 paddingLeft="$2.5" 66 gap="$3" 67 flexDirection="row" 68 justifyContent="flex-start" 69 alignItems="center" 70 > 71 <Image 72 source={require("../../assets/images/cube.png")} 73 height="$2" 74 width="$2" 75 /> 76 {!collapsed && ( 77 <Text fontSize="$7" minWidth={200} numberOfLines={1}> 78 Streamplace 79 </Text> 80 )} 81 </View> 82 83 {state.routes.map((route) => { 84 const descriptor = descriptors[route.key]; 85 const options = descriptor?.options ?? {}; 86 87 const label = 88 typeof options.drawerLabel === "function" 89 ? options.drawerLabel({ focused: false, color: "$color" }) 90 : (options.drawerLabel ?? options.title ?? route.name); 91 92 const IconComponent = options.drawerIcon as 93 | React.ComponentType<any> 94 | undefined; 95 96 return ( 97 <SidebarItem 98 key={route.key} 99 icon={IconComponent ? IconComponent : FileQuestion} 100 label={label} 101 active={descriptor.navigation.isFocused()} 102 collapsed={collapsed} 103 onPress={() => { 104 if (route.name === "Home") { 105 // copy logic for 'Home' to reset the stack 106 descriptor.navigation.dispatch( 107 CommonActions.reset({ 108 index: 0, 109 routes: [ 110 { 111 name: "Home", 112 state: { 113 routes: [{ name: "StreamList" }], 114 }, 115 }, 116 ], 117 }), 118 ); 119 } else { 120 descriptor.navigation.navigate(route.name); 121 } 122 }} 123 style={options.drawerItemStyle} 124 tint={options.drawerActiveTintColor as string} // Assuming tint is a string color or undefined 125 /> 126 ); 127 })} 128 {externalItems.map((i) => { 129 return ( 130 <SidebarItem 131 key={JSON.stringify(i.label)} 132 icon={i.item} 133 label={i.label || "Fix this label!"} 134 active={false} 135 collapsed={collapsed} 136 onPress={() => i.onPress()} 137 tint="rgba(189, 110, 134)" 138 /> 139 ); 140 })} 141 </AnimatedYStack> 142 ); 143}