Live video on the AT Protocol
1import { useLivestream } from "@streamplace/components";
2import { useToastController } from "@tamagui/toast";
3import {
4 selectNewLivestream,
5 selectUserProfile,
6 updateLivestreamRecord,
7} from "features/bluesky/blueskySlice";
8import { useLiveUser } from "hooks/useLiveUser";
9import { useEffect, useState } from "react";
10import { ScrollView } from "react-native";
11import { useAppDispatch, useAppSelector } from "store/hooks";
12import { Button, H3, Label, Paragraph, Text, TextArea, View } from "tamagui";
13
14export default function UpdateLivestream() {
15 const dispatch = useAppDispatch();
16 const toast = useToastController();
17 const userIsLive = useLiveUser();
18 const [title, setTitle] = useState("");
19 const [loading, setLoading] = useState(false);
20 const profile = useAppSelector(selectUserProfile);
21 const livestream = useLivestream();
22 const newLivestream = useAppSelector(selectNewLivestream);
23
24 useEffect(() => {
25 if (newLivestream?.record) {
26 toast.show("Livestream title updated", {
27 message: newLivestream.record.title,
28 });
29 setTitle("");
30 }
31 }, [newLivestream?.record]);
32 useEffect(() => {
33 if (newLivestream?.error) {
34 toast.show("Error updating livestream", {
35 message: newLivestream.error,
36 });
37 }
38 }, [newLivestream?.error]);
39 const disabled = !userIsLive || loading || title === "";
40
41 // if (!playerId) {
42 // return (
43 // <View justifyContent="center" alignContent="center">
44 // <Text>
45 // Couldn't get the player ID. You may not have created an initial
46 // livestream record.
47 // </Text>
48 // </View>
49 // );
50 // }
51
52 const handleSubmit = async () => {
53 setLoading(true);
54 try {
55 await dispatch(
56 updateLivestreamRecord({
57 title,
58 livestream,
59 }),
60 );
61 } catch (error) {
62 console.error("Error updating livestream:", error);
63 toast.show("Error updating livestream", {
64 message: String(error),
65 });
66 } finally {
67 setLoading(false);
68 }
69 };
70
71 const buttonText = loading
72 ? "Loading..."
73 : !userIsLive
74 ? "Waiting for stream to start..."
75 : "Update Livestream!";
76
77 return (
78 <ScrollView
79 style={{ width: "60%" }}
80 contentContainerStyle={{
81 flexGrow: 1,
82 justifyContent: "flex-start",
83 paddingVertical: 40,
84 }}
85 showsVerticalScrollIndicator={false}
86 >
87 <H3 pl="$4">Change your Current Livestream Title</H3>
88 <View w="100%" alignSelf="center" p="$4" justifyContent="center">
89 <View f={2} minWidth={0} gap="$3">
90 <Label asChild={true} display="flex">
91 <View flexDirection="row" alignItems="center" w="100%">
92 <Paragraph pb="$2" minWidth={100} textAlign="left">
93 Streamer
94 </Paragraph>
95 <Paragraph pb="$2" fontWeight="bold">
96 @{profile?.handle}
97 </Paragraph>
98 </View>
99 </Label>
100 <Label asChild={true}>
101 <View flexDirection="row" alignItems="center" w="100%">
102 <Paragraph pb="$2" minWidth={100} textAlign="left">
103 Title
104 </Paragraph>
105 <View flex={1}>
106 <TextArea
107 id="livestream-title"
108 value={title}
109 onChangeText={setTitle}
110 size="$4"
111 minHeight={100}
112 maxLength={140}
113 w="100%"
114 />
115 </View>
116 </View>
117 </Label>
118 <Label asChild={true} mt="$-4">
119 <View flexDirection="row" alignItems="center" w="100%">
120 <Paragraph minWidth={100} textAlign="left"></Paragraph>
121 <View flex={1}>
122 <Text fontSize="$1" color="$gray11">
123 Updating will not send out notifications to viewers or create
124 a new social media post.
125 </Text>
126 </View>
127 </View>
128 </Label>
129 <View w="100%" alignItems="center" mt="$-4">
130 <Button
131 disabled={disabled}
132 opacity={disabled ? 0.5 : 1}
133 size="$4"
134 w="100%"
135 onPress={handleSubmit}
136 >
137 {buttonText}
138 </Button>
139 </View>
140 </View>
141 </View>
142 </ScrollView>
143 );
144}