Live video on the AT Protocol
79
fork

Configure Feed

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

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