vote feedback

This commit is contained in:
2025-08-17 11:47:14 +02:00
parent 7d54f6c5ce
commit 47583e36dc
2 changed files with 77 additions and 3 deletions
+10
View File
@@ -57,6 +57,7 @@ class SessionConsumer(WebsocketConsumer):
if action == "vote": if action == "vote":
points = text_data_json.get("points", None) points = text_data_json.get("points", None)
track = session.current_track; track = session.current_track;
vote = None
try: try:
vote = Vote.objects.get(user=user, track=track, session=session) vote = Vote.objects.get(user=user, track=track, session=session)
vote.points = points vote.points = points
@@ -68,6 +69,10 @@ class SessionConsumer(WebsocketConsumer):
vote.save() vote.save()
except Exception as e: except Exception as e:
self.logger.error(f"Error voting on {track} by {user} for {points} points: {e}") self.logger.error(f"Error voting on {track} by {user} for {points} points: {e}")
if vote:
async_to_sync(self.channel_layer.group_send)(
self.session_name, {"type": "voted", "user": { "id": user.id, "username": user.username}, "track": track.id, "points": points}
)
if action == "pause": if action == "pause":
pass pass
if action == "next": if action == "next":
@@ -96,6 +101,11 @@ class SessionConsumer(WebsocketConsumer):
def announce_track(self, event): def announce_track(self, event):
self.send(text_data=json.dumps({"track": {}})) self.send(text_data=json.dumps({"track": {}}))
def voted(self, event):
user = event["user"]
#self.session_name, {"type": "voted", "user": { "id": user.id, "username": user.username}, "track": track.id, "points": points}
self.send(text_data=json.dumps({"voted": { "id": user["id"], "username": user["username"], "points": event["points"], "track": event["track"]}}))
# Receive message from room group # Receive message from room group
def chat_message(self, event): def chat_message(self, event):
+67 -3
View File
@@ -17,6 +17,8 @@ const MAX_PARTY_SIZE = 8;
export default function Lobby() { export default function Lobby() {
const [userList, setUserList] = useState<any[]>([]); const [userList, setUserList] = useState<any[]>([]);
const [noList, setNoList] = useState<any[]>([]);
const [yesList, setYesList] = useState<any[]>([]);
const [sessionSocket, setSessionSocket] = useState<WebSocket | null>(null); const [sessionSocket, setSessionSocket] = useState<WebSocket | null>(null);
const { sessionId, setSessionId } = useSession(); const { sessionId, setSessionId } = useSession();
const [sessionState, setSessionState] = useState("lobby"); const [sessionState, setSessionState] = useState("lobby");
@@ -34,6 +36,8 @@ export default function Lobby() {
addUser(data[key]); addUser(data[key]);
} else if (key == "track") { } else if (key == "track") {
getTrack(); getTrack();
} else if (key == "voted") {
voteUser(data[key]);
} }
} }
console.log(data); console.log(data);
@@ -78,6 +82,7 @@ export default function Lobby() {
id: user["id"], id: user["id"],
name: user["username"], name: user["username"],
avatar: `https://i.pravatar.cc/150?img=${user["id"]}`, avatar: `https://i.pravatar.cc/150?img=${user["id"]}`,
hidden: false,
}; };
setUserList((prevUserList) => { setUserList((prevUserList) => {
@@ -89,8 +94,67 @@ export default function Lobby() {
}); });
} }
// Visually processes the incoming vote for a user.
function voteUser(vote: object) {
const userId = vote["id"];
const userName = vote["username"];
const points = vote["points"];
if (points === 0) {
setYesList((prevYesList) => {
//if (prevYesList.find((u) => u.id === userId)) return prevYesList;
return prevYesList.filter((u) => u.id !== userId);
});
setNoList((prevNoList) => {
if (prevNoList.find((u) => u.id === userId)) {
return prevNoList;
}
return [
...prevNoList,
{
id: userId,
name: userName,
avatar: `https://i.pravatar.cc/150?img=${userId}`,
},
];
});
} else {
setNoList((prevNoList) => {
return prevNoList.filter((u) => u.id !== userId);
});
setYesList((prevYesList) => {
if (prevYesList.find((u) => u.id === userId)) {
return prevYesList;
}
return [
...prevYesList,
{
id: userId,
name: userName,
avatar: `https://i.pravatar.cc/150?img=${userId}`,
},
];
});
}
setUserList((prevUserList) => {
// Set hidden true on the user that voted:
return prevUserList.map((user) => {
if (user.id === userId) {
return { ...user, hidden: true };
}
return user;
});
});
}
async function getTrack() { async function getTrack() {
setSongLoading(true); setSongLoading(true);
setUserList((prevUserList) => {
return prevUserList.map((user) => {
return { ...user, hidden: false };
});
});
setYesList([]);
setNoList([]);
const { data: session } = await api.sessions.get({ session_id: sessionId }); const { data: session } = await api.sessions.get({ session_id: sessionId });
const trackId = session?.current_track; const trackId = session?.current_track;
if (trackId) { if (trackId) {
@@ -207,7 +271,7 @@ export default function Lobby() {
<div className="flex flex-col items-center justify-center"> <div className="flex flex-col items-center justify-center">
<div className="flex flex-row items-center justify-center gap-x-32"> <div className="flex flex-row items-center justify-center gap-x-32">
<div className="grid min-w-52 grid-flow-row grid-cols-3 items-start justify-start gap-4 rounded bg-blue-950/80 p-4"> <div className="grid min-w-52 grid-flow-row grid-cols-3 items-start justify-start gap-4 rounded bg-blue-950/80 p-4">
{userList.map((user) => ( {noList.map((user) => (
<div <div
key={user.id} key={user.id}
className="flex h-[120px] w-[120px] flex-col items-center justify-center p-4" className="flex h-[120px] w-[120px] flex-col items-center justify-center p-4"
@@ -244,7 +308,7 @@ export default function Lobby() {
</div> </div>
)} )}
<div className="grid min-w-52 grid-flow-row grid-cols-3 items-start justify-start gap-4 rounded bg-blue-950/80 p-4"> <div className="grid min-w-52 grid-flow-row grid-cols-3 items-start justify-start gap-4 rounded bg-blue-950/80 p-4">
{userList.map((user) => ( {yesList.map((user) => (
<div <div
key={user.id} key={user.id}
className="flex h-[120px] w-[120px] flex-col items-center justify-center p-4" className="flex h-[120px] w-[120px] flex-col items-center justify-center p-4"
@@ -282,7 +346,7 @@ export default function Lobby() {
{userList.map((user) => ( {userList.map((user) => (
<div <div
key={user.id} key={user.id}
className="flex h-[100px] w-[100px] flex-col items-center justify-center p-4" className={`flex h-[100px] w-[100px] flex-col items-center justify-center p-4 ${user.hidden ? "hidden" : ""}`}
> >
<img src={user.avatar} alt={user.name} width={75} height={75} /> <img src={user.avatar} alt={user.name} width={75} height={75} />
<div className="mt-1 min-w-[90px] rounded-3xl px-3 text-center text-3xl font-semibold text-white"> <div className="mt-1 min-w-[90px] rounded-3xl px-3 text-center text-3xl font-semibold text-white">