game on #27
@@ -83,15 +83,24 @@ class SessionConsumer(WebsocketConsumer):
|
||||
for track in tracks:
|
||||
if next:
|
||||
session.current_track = track
|
||||
next = False
|
||||
break
|
||||
if session.current_track == track:
|
||||
next = True
|
||||
if next:
|
||||
# We didnt get a next track, so it must have been the last one
|
||||
session.current_track = None
|
||||
else:
|
||||
session.current_track = tracks.first()
|
||||
session.save()
|
||||
async_to_sync(self.channel_layer.group_send)(
|
||||
self.session_name, {"type": "announce.track"}
|
||||
)
|
||||
if session.current_track is None:
|
||||
async_to_sync(self.channel_layer.group_send)(
|
||||
self.session_name, {"type": "announce.done"}
|
||||
)
|
||||
else:
|
||||
async_to_sync(self.channel_layer.group_send)(
|
||||
self.session_name, {"type": "announce.track"}
|
||||
)
|
||||
|
||||
|
||||
def announce(self, event):
|
||||
@@ -100,6 +109,8 @@ class SessionConsumer(WebsocketConsumer):
|
||||
|
||||
def announce_track(self, event):
|
||||
self.send(text_data=json.dumps({"track": {}}))
|
||||
def announce_done(self, event):
|
||||
self.send(text_data=json.dumps({"done": {}}))
|
||||
|
||||
def voted(self, event):
|
||||
user = event["user"]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Markazi_Text, Nunito } from "next/font/google";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useAuth } from "react-oidc-context";
|
||||
@@ -28,8 +29,12 @@ export default function Lobby() {
|
||||
const [spotifyId, setSpotifyId] = useState<string | null>(null);
|
||||
const auth = useAuth();
|
||||
const user = getUser();
|
||||
const router = useRouter();
|
||||
const controller = useSpotifyIframe();
|
||||
const [revealed, setRevealed] = useState(false);
|
||||
const [playingPercentage, setPlayingPercentage] = useState(0);
|
||||
const [secondsLeft, setSecondsLeft] = useState(30);
|
||||
const [state, setState] = useState("lobby"); // lobby, playing, waiting, loading
|
||||
|
||||
// Main message handler and dispatcher
|
||||
function onMessage(e) {
|
||||
@@ -42,6 +47,8 @@ export default function Lobby() {
|
||||
getTrack();
|
||||
} else if (key == "voted") {
|
||||
voteUser(data[key]);
|
||||
} else if (key == "done") {
|
||||
router.push("/post-game");
|
||||
}
|
||||
}
|
||||
console.log(data);
|
||||
@@ -78,6 +85,7 @@ export default function Lobby() {
|
||||
|
||||
function startSession() {
|
||||
setSessionState("voting");
|
||||
setState("loading");
|
||||
getTrack();
|
||||
}
|
||||
|
||||
@@ -152,6 +160,7 @@ export default function Lobby() {
|
||||
|
||||
async function getTrack() {
|
||||
setSongLoading(true);
|
||||
setState("loading");
|
||||
setUserList((prevUserList) => {
|
||||
return prevUserList.map((user) => {
|
||||
return { ...user, hidden: false };
|
||||
@@ -174,6 +183,9 @@ export default function Lobby() {
|
||||
}
|
||||
|
||||
async function nextTrack() {
|
||||
console.log("nextTrack");
|
||||
setState("loading");
|
||||
setRevealed(false);
|
||||
setSongLoading(true);
|
||||
sessionSocket.send(
|
||||
JSON.stringify({
|
||||
@@ -183,19 +195,64 @@ export default function Lobby() {
|
||||
);
|
||||
}
|
||||
|
||||
async function endPlay() {
|
||||
controller?.seek(100);
|
||||
}
|
||||
|
||||
// Spotify Player stuff
|
||||
useEffect(() => {
|
||||
if (controller) {
|
||||
console.log("Loaded track:", spotifyId);
|
||||
controller.loadUri(`spotify:track:${spotifyId}`);
|
||||
controller.play();
|
||||
// Note: do not set playing state here, but later when its actually playing.
|
||||
console.log(controller._listeners);
|
||||
if (controller._listeners["playback_update"].length === 0) {
|
||||
controller.addListener("playback_update", (e) => {
|
||||
updatePlayback(e);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log("Spotify player not initialized");
|
||||
}
|
||||
}, [controller, spotifyId]);
|
||||
function updatePlayback(e) {
|
||||
let duration = e.data.duration;
|
||||
let playingPosition = e.data.position;
|
||||
const playingSeconds = Math.floor((duration - playingPosition) / 1000);
|
||||
setPlayingPercentage((playingPosition / duration) * 100);
|
||||
setSecondsLeft((s) => {
|
||||
setState((state) => {
|
||||
if (playingSeconds >= 1) {
|
||||
return "playing";
|
||||
}
|
||||
if (state == "playing" && s <= 0) {
|
||||
console.log("track ended");
|
||||
return "waiting";
|
||||
}
|
||||
return state;
|
||||
});
|
||||
return playingSeconds;
|
||||
});
|
||||
}
|
||||
async function playTrack() {
|
||||
controller.play();
|
||||
}
|
||||
async function pauseTrack() {
|
||||
controller.togglePlay();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log("useEffect state:", state);
|
||||
if (state == "waiting") {
|
||||
setRevealed(true);
|
||||
setTimeout(() => {
|
||||
setState("next");
|
||||
}, 5000);
|
||||
} else if (state == "next") {
|
||||
nextTrack();
|
||||
}
|
||||
}, [state]);
|
||||
|
||||
if (sessionState == "lobby") {
|
||||
return (
|
||||
@@ -218,7 +275,8 @@ export default function Lobby() {
|
||||
</div>
|
||||
<button
|
||||
onClick={startSession}
|
||||
className="rounded-lg border-2 border-black bg-yellow-500 p-4 text-2xl font-extrabold text-blue-600 hover:bg-yellow-400"
|
||||
className="rounded-lg border-2 border-black bg-yellow-500 p-4 text-2xl font-extrabold text-blue-600 hover:bg-yellow-400 disabled:bg-yellow-900 disabled:text-gray-400"
|
||||
disabled={sessionId === null}
|
||||
>
|
||||
START
|
||||
</button>
|
||||
@@ -265,21 +323,17 @@ export default function Lobby() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between gap-4 p-24">
|
||||
<div className="flex w-full items-start justify-between text-center">
|
||||
<div className="flex-1">
|
||||
{" "}
|
||||
<button
|
||||
onClick={() => setRevealed(!revealed)}
|
||||
className="rounded bg-blue-600 px-4 py-2 text-white"
|
||||
>
|
||||
{revealed ? "Gordijntje dicht" : "Gordijntje open"}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1"></div>
|
||||
<div className="flex flex-1 items-center justify-center">
|
||||
<div className="flex h-[170px] w-[170px] items-center justify-center rounded-full border-2 bg-orange-400">
|
||||
<div className="text-5xl text-white drop-shadow-sm drop-shadow-black">
|
||||
<button onClick={getTrack}>30</button>
|
||||
{(state == "playing" || state == "waiting") && (
|
||||
<div
|
||||
className={`flex h-[170px] w-[170px] items-center justify-center rounded-full border-2 ${state == "playing" ? "bg-orange-400" : ""} ${state == "waiting" ? "bg-green-400" : ""}`}
|
||||
>
|
||||
<div className="text-5xl text-white drop-shadow-sm drop-shadow-black">
|
||||
{secondsLeft}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-row items-center justify-end gap-4">
|
||||
@@ -289,15 +343,15 @@ export default function Lobby() {
|
||||
>
|
||||
PLAY
|
||||
</button>
|
||||
<Link
|
||||
href="/pause"
|
||||
<button
|
||||
onClick={pauseTrack}
|
||||
className="w-30 rounded-lg border-2 border-black bg-yellow-500 p-4 text-2xl font-extrabold text-blue-600 hover:bg-yellow-400"
|
||||
>
|
||||
PAUSE
|
||||
</Link>
|
||||
</button>
|
||||
<button
|
||||
className="w-30 rounded-lg border-2 border-black bg-yellow-500 p-4 text-2xl font-extrabold text-blue-600 hover:bg-yellow-400"
|
||||
onClick={nextTrack}
|
||||
onClick={endPlay}
|
||||
>
|
||||
NEXT
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user