diff --git a/schema.ts b/schema.ts index a36d9f0..7e61102 100644 --- a/schema.ts +++ b/schema.ts @@ -9,8 +9,14 @@ const collection = { messages: { messageId: { createdAt: 'timestamp', - senderId: 'userId', content: 'Message content', + senderId: 'userId', + }, + }, + playlist: { + videoId: { + createdAt: 'timestamp', + url: 'https://youtube.com', }, }, }, diff --git a/src/components/RoomHeader.tsx b/src/components/RoomHeader.tsx index bade334..3775798 100644 --- a/src/components/RoomHeader.tsx +++ b/src/components/RoomHeader.tsx @@ -1,21 +1,36 @@ import { IonFabButton, IonIcon, IonInput, IonTitle, IonToolbar } from '@ionic/react'; import { add } from 'ionicons/icons'; import React, { useState } from 'react'; +import { db, timestamp } from '../services/firebase'; import './RoomHeader.css'; type VideoInputProps = { - changeUrl: (newUrl: string) => void; + roomId: string; + userId: string; + ownerId: string; + videoId: string; }; -const VideoInput: React.FC = ({ changeUrl }) => { - const [url, setUrl] = useState(''); +const VideoInput: React.FC = ({ roomId, userId, ownerId, videoId }) => { + const [videoUrl, setVideoUrl] = useState(''); - const onSubmit = () => { - if (url !== '') { - changeUrl(url); - } + const onSubmit = async () => { + if (userId === ownerId) { + if (videoUrl !== '') { + await db.collection('rooms').doc(roomId).collection('playlist').doc(videoId).update({ + url: videoUrl, + }); + + await db.collection('rooms').doc(roomId).collection('messages').add({ + createdAt: timestamp, + senderId: userId, + content: 'changed the video', + type: 'system', + }); + } - setUrl(''); + setVideoUrl(''); + } }; return ( @@ -23,19 +38,25 @@ const VideoInput: React.FC = ({ changeUrl }) => { Turtle - setUrl(e.detail.value!)} - value={url} - onSubmit={onSubmit} - > - - - + {userId === ownerId ? ( + <> + setVideoUrl(e.detail.value!)} + value={videoUrl} + onSubmit={onSubmit} + > + + + + + ) : ( + <> + )} ); }; diff --git a/src/components/VideoPlayer.tsx b/src/components/VideoPlayer.tsx index 56c84b6..7a003ff 100644 --- a/src/components/VideoPlayer.tsx +++ b/src/components/VideoPlayer.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState, useEffect } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import ReactPlayer from 'react-player'; import { db, timestamp } from '../services/firebase'; import { secondsToTimestamp, timestampToSeconds } from '../services/utilities'; @@ -7,12 +7,12 @@ type VideoPlayerProps = { ownerId: string; userId: string; roomId: string; - url: string; }; -const VideoPlayer: React.FC = ({ ownerId, userId, roomId, url }) => { +const VideoPlayer: React.FC = ({ ownerId, userId, roomId }) => { const player = useRef(null); const [playing, setPlaying] = useState(false); + const [videoUrl, setVideoUrl] = useState(''); // Send video playing message to database when owner plays video const onPlay = async () => { @@ -83,10 +83,27 @@ const VideoPlayer: React.FC = ({ ownerId, userId, roomId, url }; }, [roomId, userId]); + // Listen for video URL changes + useEffect(() => { + const urlRef = db.collection('rooms').doc(roomId).collection('playlist'); + + const urlUnsubscribe = urlRef.onSnapshot((querySnapshot) => { + const changes = querySnapshot.docChanges(); + for (const change of changes) { + const data = change.doc.data(); + setVideoUrl(data.url); + } + }); + + return () => { + urlUnsubscribe(); + }; + }, [roomId]); + return ( { const [loading, setLoading] = useState(true); @@ -18,6 +18,11 @@ const Home: React.FC = () => { ownerId: userId, }); + await db.collection('rooms').doc(roomId.id).collection('playlist').add({ + createdAt: timestamp, + url: 'https://www.youtube.com/watch?v=ksHOjnopT_U', + }); + await rtdb.ref('/rooms/' + roomId.id).set({ userCount: 0 }); await rtdb.ref('/available/' + roomId.id).set({ name: 'Room Name', createdAt: new Date().toISOString() }); const path = '/room/' + roomId.id; diff --git a/src/pages/Room.tsx b/src/pages/Room.tsx index 4478a0d..c8e359f 100644 --- a/src/pages/Room.tsx +++ b/src/pages/Room.tsx @@ -14,24 +14,30 @@ const Room: React.FC> = ({ match }) => { const [validRoom, setValidRoom] = useState(false); const [userId, setUserId] = useState(''); - const [ownerId, setOwnerId] = useState(''); + const [ownerId, setOwnerId] = useState('undefined'); const [loading, setLoading] = useState(true); const [userCount, setUserCount] = useState(0); - const [url, setUrl] = useState('https://www.youtube.com/watch?v=ysz5S6PUM-U'); + const [videoId, setVideoId] = useState(''); // Verify that the roomId exists in db useEffect(() => { - const fetchRoom = async () => { - const room = await db.collection('rooms').doc(roomId).get(); + const fetchRoomAndVid = async () => { + const roomRef = db.collection('rooms').doc(roomId); + const room = await roomRef.get(); if (!room.exists) { history.push('/'); } else { setValidRoom(true); setOwnerId(room.data()?.ownerId); + + // Set videoId for RoomHeader component + const playlistSnapshot = await roomRef.collection('playlist').get(); + const vidId = playlistSnapshot.docs[0].id; + setVideoId(vidId); } }; - fetchRoom(); + fetchRoomAndVid(); }, [history, roomId]); // Handle logging in @@ -128,15 +134,10 @@ const Room: React.FC> = ({ match }) => { } }, [userId, validRoom, roomId, loading, userCount]); - // Function passed as prop to VideoInput component - const changeUrl = (newUrl: string) => { - setUrl(newUrl); - }; - return ( - + {loading ? ( Loading... @@ -144,7 +145,7 @@ const Room: React.FC> = ({ match }) => { - +