Live video on the AT Protocol
79
fork

Configure Feed

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

at natb/spinner-while-loading-chat 165 lines 4.2 kB view raw
1import { 2 Chat, 3 ChatBox, 4 Loader, 5 Resizable, 6 Text, 7 useHandle, 8 useLivestreamInfo, 9 View, 10 zero, 11} from "@streamplace/components"; 12import { useKeyboard } from "hooks/useKeyboard"; 13import { useEffect } from "react"; 14import { Pressable } from "react-native"; 15import Animated, { 16 useAnimatedStyle, 17 useSharedValue, 18 withSpring, 19} from "react-native-reanimated"; 20import { useResponsiveLayout } from "./useResponsiveLayout"; 21 22import { useNavigation } from "@react-navigation/native"; 23import { usePDSAgent } from "@streamplace/components/src/streamplace-store/xrpc"; 24import { ArrowRight } from "@tamagui/lucide-icons"; 25import emojiData from "assets/emoji-data.json"; 26const { borderRadius, gap, layout, flex, px, position, bottom } = zero; 27 28export function DesktopChatPanel({ 29 chatVisible, 30 chatPanelWidth, 31 safeAreaInsets, 32}) { 33 const sidebarOffset = useSharedValue(chatVisible ? 0 : chatPanelWidth); 34 35 const kb = useKeyboard(); 36 37 useEffect(() => { 38 console.log( 39 "Setting sidebar offset x to", 40 chatVisible ? 0 : chatPanelWidth, 41 ); 42 sidebarOffset.value = withSpring(chatVisible ? 0 : chatPanelWidth, { 43 damping: 100, 44 stiffness: 1000, 45 }); 46 }, [chatVisible, chatPanelWidth, sidebarOffset]); 47 48 const animatedSidebarStyle = useAnimatedStyle(() => ({ 49 transform: [ 50 { translateX: sidebarOffset.value }, 51 { translateY: -kb.keyboardHeight }, 52 ], 53 })); 54 55 return ( 56 <Animated.View 57 style={[ 58 layout.position.absolute, 59 position.right[0], 60 { 61 top: safeAreaInsets.top, 62 bottom: safeAreaInsets.bottom, 63 right: safeAreaInsets.right / 2, 64 width: chatPanelWidth, 65 backgroundColor: "rgba(0, 0, 0, 0.85)", 66 borderLeftWidth: 1, 67 borderLeftColor: "rgba(255, 255, 255, 0.1)", 68 zIndex: 999, 69 }, 70 animatedSidebarStyle, 71 ]} 72 > 73 <View style={{ flex: 1, position: "relative" }}> 74 <ChatPanel /> 75 </View> 76 </Animated.View> 77 ); 78} 79 80// MobileChatPanel.tsx 81export function MobileChatPanel({ isPlayerRatioGreater }) { 82 return ( 83 <View 84 style={[ 85 isPlayerRatioGreater 86 ? layout.position.relative 87 : layout.position.absolute, 88 bottom[0], 89 { width: "100%", maxWidth: "100%" }, 90 ]} 91 > 92 <Resizable 93 isPlayerRatioGreater={isPlayerRatioGreater} 94 startingPercentage={0.4} 95 > 96 <ChatPanel /> 97 </Resizable> 98 </View> 99 ); 100} 101 102function ChatPanel() { 103 const { shouldShowChatSidePanel, safeAreaInsets } = useResponsiveLayout(); 104 const { profile } = useLivestreamInfo(); 105 const handle = useHandle(); 106 107 let agent = usePDSAgent(); 108 109 const navigation = useNavigation(); 110 let canModerate = profile?.handle === handle; 111 112 return ( 113 <View 114 style={[ 115 layout.flex.column, 116 flex.values[1], 117 { width: "100%", maxWidth: "100%" }, 118 ]} 119 > 120 <View style={[flex.values[1]]}> 121 <Chat canModerate={canModerate} /> 122 </View> 123 <View style={[layout.flex.column, gap.all[2], px[4]]}> 124 {agent?.did ? ( 125 <ChatBox 126 emojiData={emojiData} 127 chatBoxStyle={{ borderRadius: borderRadius.xl }} 128 /> 129 ) : !agent ? ( 130 <View 131 style={[ 132 layout.flex.row, 133 layout.flex.center, 134 gap.all[1], 135 zero.p[3], 136 { 137 borderRadius: borderRadius.xl, 138 backgroundColor: "rgba(255, 255, 255, 0.1)", 139 }, 140 ]} 141 > 142 <Loader size="large" /> 143 </View> 144 ) : ( 145 <Pressable 146 onPress={() => navigation.navigate("Login")} 147 style={[ 148 layout.flex.row, 149 layout.flex.center, 150 gap.all[2], 151 { 152 padding: 18, 153 borderRadius: borderRadius.xl, 154 backgroundColor: "rgba(255, 255, 255, 0.1)", 155 }, 156 ]} 157 > 158 <Text>Log in or sign up to chat</Text> 159 <ArrowRight /> 160 </Pressable> 161 )} 162 </View> 163 </View> 164 ); 165}