Live video on the AT Protocol
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";
20
21import { useNavigation } from "@react-navigation/native";
22import { usePDSAgent } from "@streamplace/components/src/streamplace-store/xrpc";
23import emojiData from "assets/emoji-data.json";
24import { ArrowRight } from "lucide-react-native";
25import { useSafeAreaInsets } from "react-native-safe-area-context";
26const { borderRadius, gap, layout, flex, px, position, bottom } = zero;
27
28export function DesktopChatPanel({ chatVisible, chatPanelWidth }) {
29 let insets = useSafeAreaInsets();
30 let panelWidthWithInsets = chatPanelWidth;
31 const sidebarOffset = useSharedValue(chatVisible ? 0 : panelWidthWithInsets);
32 const sidebarOpacity = useSharedValue(chatVisible ? 1 : 0);
33
34 const kb = useKeyboard();
35
36 useEffect(() => {
37 console.log(
38 "Setting sidebar offset x to",
39 chatVisible ? 0 : panelWidthWithInsets,
40 );
41 sidebarOffset.value = withSpring(chatVisible ? 0 : panelWidthWithInsets, {
42 damping: 100,
43 stiffness: 1000,
44 });
45 sidebarOpacity.value = withSpring(chatVisible ? 1 : 0, {
46 damping: 100,
47 stiffness: 1000,
48 });
49 }, [chatVisible, panelWidthWithInsets, sidebarOffset]);
50
51 const animatedSidebarStyle = useAnimatedStyle(() => ({
52 transform: [
53 { translateX: sidebarOffset.value },
54 { translateY: -kb.keyboardHeight },
55 ],
56 opacity: sidebarOpacity.value,
57 }));
58
59 return (
60 <>
61 <Animated.View
62 style={[
63 {
64 width: chatPanelWidth,
65 flexShrink: 0,
66 },
67 animatedSidebarStyle,
68 ]}
69 />
70 <Animated.View
71 style={[
72 {
73 position: "absolute",
74 right: 0,
75 // attempt to lessen the impact of the safe area inset on the chat panel?
76 paddingRight: insets.right > 0 ? insets.right - 20 : 0,
77 top: 0,
78 bottom: 0,
79 width: panelWidthWithInsets,
80 flexShrink: 0,
81 backgroundColor: "rgba(0, 0, 0, 0.85)",
82 borderLeftWidth: 1,
83 borderLeftColor: "rgba(255, 255, 255, 0.1)",
84 zIndex: 999,
85 },
86 animatedSidebarStyle,
87 ]}
88 >
89 <View style={{ flex: 1, position: "relative" }}>
90 <ChatPanel />
91 </View>
92 </Animated.View>
93 </>
94 );
95}
96
97// MobileChatPanel.tsx
98export function MobileChatPanel({ isPlayerRatioGreater }) {
99 return (
100 <View
101 style={[
102 isPlayerRatioGreater
103 ? layout.position.relative
104 : layout.position.absolute,
105 bottom[0],
106 { width: "100%", maxWidth: "100%" },
107 ]}
108 >
109 <Resizable
110 isPlayerRatioGreater={isPlayerRatioGreater}
111 startingPercentage={0.4}
112 >
113 <ChatPanel />
114 </Resizable>
115 </View>
116 );
117}
118
119function ChatPanel() {
120 const { profile } = useLivestreamInfo();
121 const handle = useHandle();
122
123 let agent = usePDSAgent();
124
125 const navigation = useNavigation();
126
127 return (
128 <View
129 style={[
130 layout.flex.column,
131 flex.values[1],
132 { width: "100%", maxWidth: "100%" },
133 px[2],
134 ]}
135 >
136 <View style={[flex.values[1]]}>
137 <Chat />
138 </View>
139 <View style={[layout.flex.column, gap.all[2]]}>
140 {agent?.did ? (
141 <ChatBox
142 emojiData={emojiData}
143 chatBoxStyle={{ borderRadius: borderRadius.xl }}
144 />
145 ) : !agent ? (
146 <View
147 style={[
148 layout.flex.row,
149 layout.flex.center,
150 gap.all[1],
151 zero.p[3],
152 {
153 borderRadius: borderRadius.xl,
154 backgroundColor: "rgba(255, 255, 255, 0.1)",
155 },
156 ]}
157 >
158 <Loader size="large" />
159 </View>
160 ) : (
161 <Pressable
162 onPress={() => navigation.navigate("Login")}
163 style={[
164 layout.flex.row,
165 layout.flex.center,
166 gap.all[4],
167 {
168 padding: 18,
169 borderRadius: borderRadius.xl,
170 backgroundColor: "rgba(255, 255, 255, 0.1)",
171 },
172 ]}
173 >
174 <Text>Log in or sign up to chat</Text>
175 <ArrowRight />
176 </Pressable>
177 )}
178 </View>
179 </View>
180 );
181}