diff --git a/backend/src/Lobby.js b/backend/src/Lobby.js index d5c8653..592af45 100644 --- a/backend/src/Lobby.js +++ b/backend/src/Lobby.js @@ -67,10 +67,6 @@ module.exports = class Lobby { setTimeout(doTick, Math.floor(waitTime / this.speedFactor)); }; - if (false) { - this.seek(ioLobby, 500); - } - doTick(); } diff --git a/backend/src/index.js b/backend/src/index.js index 37d26ce..6a7d2c7 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -40,10 +40,6 @@ io.on('connection', socket => { socket.join(lobby.name); - if (lobby.running) { - socket.emit('seek', lobby.currentSeconds); - } - callback(null, { status: 'ok', lobby: lobby diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 3158462..626897a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,68 +1,13 @@ -import React, {useEffect, useRef, useState} from 'react'; +import React from 'react'; import './App.sass'; -import logo from "./via-logo.svg" -import {Row} from "antd" -import socket from "./util/socket"; -import NextShot from "./components/NextShot"; -import ShotsTaken from "./components/ShotsTaken"; -import Feed from "./components/Feed"; -import Lobby from "./components/Lobby"; -import {Tick} from "./types/types"; +import {SocketIOProvider} from "use-socketio/lib"; +import Wrapper from "./Wrapper"; const App = () => { - const [started, setStarted] = useState(false); - const player = useRef(new Audio("centurion.m4a")); - - useEffect(() => { - socket.on('started', async () => { - setStarted(true); - - await player.current.play(); - // player.current.volume = 0; - }); - - socket.on('seek', async (sec: number) => { - if (player.current.paused) { - await player.current.play(); - } - - socket.once("tick_event", (tick: Tick) => { - // Wait till the next tick to actually start so we more closely match the leader's sound - setStarted(true); - player.current.currentTime = tick.current - }); - }); - - - return () => { - socket.off("started"); - socket.off("seek"); - } - }); - - const feedContent = ( - - - - - - ); - - const lobbyContent = ( - - ); - - const content = started ? feedContent : lobbyContent; - return ( - <> -
- {content} -
- - + + + ); }; diff --git a/frontend/src/Wrapper.tsx b/frontend/src/Wrapper.tsx new file mode 100644 index 0000000..1af1c94 --- /dev/null +++ b/frontend/src/Wrapper.tsx @@ -0,0 +1,79 @@ +import React, {useEffect, useRef, useState} from "react"; +import {Row} from "antd"; +import NextShot from "./components/NextShot"; +import Feed from "./components/Feed"; +import ShotsTaken from "./components/ShotsTaken"; +import Lobby from "./components/Lobby"; +import {useSocket} from "use-socketio"; +import logo from "./via-logo.svg"; +import {Tick} from "./types/types"; +import {NumberParam, useQueryParam} from "use-query-params"; + +const Wrapper = () => { + const [started, setStarted] = useState(false); + const [wantsToStart, setWantsToStart] = useState(false); + const player = useRef(new Audio("centurion.m4a")); + const [noSound] = useQueryParam('noSound', NumberParam); + + function goStart() { + console.log("Starting from wrapper.."); + setWantsToStart(true); + } + + + const {socket} = useSocket("started", async (obj: any) => { + console.log("got started"); + setStarted(true); + + if (typeof noSound === 'undefined') { + await player.current.play(); + } + }); + + useEffect(() => { + if (noSound === 1) { + // Won't play sound so we don't get DOM Interaction errors. + setWantsToStart(true); + } + }, []); + + useSocket("tick_event", async (tick: Tick) => { + if (!started && wantsToStart) { + if (player.current.paused) { + if (typeof noSound === 'undefined') { + await player.current.play(); + } + } + + setStarted(true); + player.current.currentTime = tick.current; + } + }); + + const feedContent = ( + + + + + + ); + + const lobbyContent = ( + + ); + + const content = started ? feedContent : lobbyContent; + + return ( + <> +
+ {content} +
+
+ logo +
+ + ); +}; + +export default Wrapper; \ No newline at end of file diff --git a/frontend/src/components/Feed.tsx b/frontend/src/components/Feed.tsx index 639244f..d0d9206 100644 --- a/frontend/src/components/Feed.tsx +++ b/frontend/src/components/Feed.tsx @@ -1,11 +1,11 @@ -import React, {useEffect, useState} from 'react'; +import React, {useState} from 'react'; import {Col, Timeline} from "antd" -import socket from "../util/socket"; import {Tick, TimestampEvent} from "../types/types"; import shot from "../img/shot.png"; import song from "../img/song.png"; import talk from "../img/talk.png"; import time from "../img/time.png"; +import {useSocket} from "use-socketio/lib"; const images = { shot, song, talk, time @@ -18,32 +18,26 @@ interface Event extends TimestampEvent { const Feed = () => { const [feedItems, setFeedItems] = useState([]); - useEffect(() => { - socket.on("tick_event", (tick: Tick) => { - if (!tick.next) { - return; - } - - if (tick.current === tick.next.timestamp) { - // Current tick is a new event. + useSocket("tick_event", async (tick: Tick) => { + if (!tick.next) { + return; + } - const newItems: any[] = []; - for (let i = 0; i < feedItems.length; i++) { - newItems.push(feedItems[i]); - } - for (let j = 0; j < tick.next.events.length; j++) { - newItems.push(tick.next.events[j]); - } + if (tick.current === tick.next.timestamp) { + // Current tick is a new event. - // @ts-ignore - // setFeedItems(newItems); + const newItems: any[] = []; + for (let i = 0; i < feedItems.length; i++) { + newItems.push(feedItems[i]); + } + for (let j = 0; j < tick.next.events.length; j++) { + newItems.push(tick.next.events[j]); } - }); - return () => { - socket.off("tick_event"); + // @ts-ignore + // setFeedItems(newItems); } - }, [feedItems]); + }); return ( // diff --git a/frontend/src/components/Lobby.tsx b/frontend/src/components/Lobby.tsx index bdb615f..d6427bb 100644 --- a/frontend/src/components/Lobby.tsx +++ b/frontend/src/components/Lobby.tsx @@ -1,47 +1,50 @@ -import React, {useEffect, useState} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import {Card, Col, InputNumber, Row} from "antd" -import socket, {emit} from "../util/socket"; +import {emit} from "../util/socket"; import "../css/lobby.sass"; import beer from "../img/beer.png" import {NumberParam, useQueryParam} from 'use-query-params'; +import {useSocket} from "use-socketio/lib"; -const Lobby = () => { +const Lobby = (props: any) => { const [lobbyId, setLobbyId] = useQueryParam('lobby', NumberParam); const [isLeader, setIsLeader] = useState(false); + const [isRunning, setIsRunning] = useState(false); const [seekTime, setSeekTime] = useState(0); const [userCount, setUserCount] = useState(0); + const {socket} = useSocket("welcome", async (obj: any) => { + if (lobbyId) { + // lobbyId is already defined, this means we have a queryparam set. + await onChangeLobbyInput(lobbyId); + return; + } + console.log("Got welcome", lobbyId); + + setLobbyId(obj.lobby.name); + setIsLeader(socket.id === obj.lobby.leaderId); + setUserCount(obj.lobby.users?.length || 0); + }); + + const socketRef = useRef(socket); + async function onChangeLobbyInput(i: any) { setLobbyId(i); - const result: any = await emit('join_lobby', i); + const result: any = await emit(socket,'join_lobby', i); setIsLeader(socket.id === result.lobby.leaderId); setUserCount(result.lobby.users?.length || 0); + setIsRunning(result.lobby.running); } - useEffect(() => { - socket.on('welcome', async (obj: any) => { - if (lobbyId) { - // lobbyId is already defined, this means we have a queryparam set. - await onChangeLobbyInput(lobbyId); - return; - } - console.log("Got welcome", lobbyId); - - setLobbyId(obj.lobby.name); - setIsLeader(socket.id === obj.lobby.leaderId); - setUserCount(obj.lobby.users?.length || 0); - }); - return () => { - socket.off("welcome"); - } - }); - useEffect(() => { async function wrapper() { - const result: any = await emit('lobby_info'); - setIsLeader(socket.id === result.lobby.leaderId); + const result: any = await emit(socketRef.current,'lobby_info'); + setIsLeader(socketRef.current.id === result.lobby.leaderId); setUserCount(result.lobby.users?.length || 0); + setIsRunning(result.lobby.running); + + console.log("Got lobby_info"); } wrapper(); @@ -59,7 +62,9 @@ const Lobby = () => {
-

Centurion! beer

+

+ beerCenturion! + beer

@@ -73,9 +78,9 @@ const Lobby = () => { { - await emit('request_start', seekTime) + await emit(socket,'request_start', seekTime) }}>Start, - ] : []}> + ] : [Join]}> Huidige lobby diff --git a/frontend/src/components/NextShot.tsx b/frontend/src/components/NextShot.tsx index 4be590b..6e69fa7 100644 --- a/frontend/src/components/NextShot.tsx +++ b/frontend/src/components/NextShot.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useRef, useState} from 'react'; import {Col, Progress} from "antd" -import socket from "../util/socket"; import {Tick} from "../types/types"; +import {useSocket} from "use-socketio/lib"; const NextShot = () => { @@ -9,34 +9,28 @@ const NextShot = () => { const [remainingPercentage, setRemainingPercentage] = useState(100); const fullTime = useRef(0); - useEffect(() => { - socket.on("tick_event", (tick: Tick) => { - if (!tick.nextShot || !tick.next) { - setRemaining(0); - return; - } - - if (fullTime.current === 0) { - fullTime.current = tick.nextShot.timestamp - tick.current; - } + useSocket("tick_event", async (tick: Tick) => { + if (!tick.nextShot || !tick.next) { + setRemaining(0); + return; + } - const shotEvent = tick.next.events.find(e => e.type === 'shot'); + if (fullTime.current === 0) { + fullTime.current = tick.nextShot.timestamp - tick.current; + } - if (shotEvent && tick.current === tick.next.timestamp) { - fullTime.current = 0; - } + const shotEvent = tick.next.events.find(e => e.type === 'shot'); - const timeRemaining = tick.nextShot.timestamp - tick.current; + if (shotEvent && tick.current === tick.next.timestamp) { + fullTime.current = 0; + } - setRemaining(timeRemaining); - // Fix divide by zero (.. || 1) - setRemainingPercentage(Math.ceil(timeRemaining / (fullTime.current || 1) * 100)); - }); + const timeRemaining = tick.nextShot.timestamp - tick.current; - return () => { - socket.off("tick_event"); - } - }, []); + setRemaining(timeRemaining); + // Fix divide by zero (.. || 1) + setRemainingPercentage(Math.ceil(timeRemaining / (fullTime.current || 1) * 100)); + }); return ( diff --git a/frontend/src/components/ShotsTaken.tsx b/frontend/src/components/ShotsTaken.tsx index 2c98109..e2b610d 100644 --- a/frontend/src/components/ShotsTaken.tsx +++ b/frontend/src/components/ShotsTaken.tsx @@ -1,26 +1,21 @@ -import React, {useEffect, useRef, useState} from 'react'; +import React, {useState} from 'react'; import {Col, Progress} from "antd" -import socket from "../util/socket"; import {Tick} from "../types/types"; +import {useSocket} from "use-socketio/lib"; const ShotsTaken = () => { const [taken, setTaken] = useState(100); - useEffect(() => { - socket.on("tick_event", (tick: Tick) => { - if (!tick.nextShot) { - setTaken(100); - return; - } + useSocket("tick_event", async (tick: Tick) => { + if (!tick.nextShot) { + setTaken(100); + return; + } - setTaken(tick.nextShot.count - 1); - }); + setTaken(tick.nextShot.count - 1); + }); - return () => { - socket.off("tick_event"); - } - }, []); return ( diff --git a/frontend/src/util/socket.ts b/frontend/src/util/socket.ts index 1153c0f..79585e6 100644 --- a/frontend/src/util/socket.ts +++ b/frontend/src/util/socket.ts @@ -1,7 +1,20 @@ -import io from "socket.io-client"; +// const socket = io(window.location.protocol + "//" + window.location.hostname + ":3001"); +const socket = { + on: (...args: any[]) => { + }, + + once: (...args: any[]) => { + + }, + + off: (...args: any[]) => { + + }, + + id: '1' +}; -const socket = io(window.location.protocol + "//" + window.location.hostname); export default socket; /** @@ -9,7 +22,7 @@ export default socket; * @param event * @param arg */ -export function emit(event: string, arg: any = null) { +export function emit(socket: SocketIOClient.Socket, event: string, arg: any = null) { return new Promise((resolve, reject) => { const cb = (err: any, res: any) => { if (err) {