From f4a4c46fbcdb26bade18e757862864c5e442214f Mon Sep 17 00:00:00 2001 From: Leonardo Segala Date: Sat, 2 Aug 2025 12:34:27 +0200 Subject: [PATCH 01/11] Fix room creation href --- frontend/src/routes/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index e8fb789..6299c75 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -28,7 +28,7 @@

{sug.upvote}

@@ -56,7 +56,8 @@ class={!picked_suggestions.includes(sug.uuid) ? "text-light-pine-red duration-100 hover:scale-150 dark:text-dark-pine-red" : "text-light-pine-muted dark:text-dark-pine-muted"} disabled={!!picked_suggestions.includes(sug.uuid)} onclick={async () => { - await vote(idx, -1, sug.uuid) + sug.upvode += 1 + await vote(-1, sug.uuid) }}> From efcabd2ee4d8894cac208b1203d5386392e2a709 Mon Sep 17 00:00:00 2001 From: Simone Tesini Date: Sat, 2 Aug 2025 12:51:50 +0200 Subject: [PATCH 03/11] add song cooldonw --- .../src/lib/components/SuggestionInput.svelte | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/frontend/src/lib/components/SuggestionInput.svelte b/frontend/src/lib/components/SuggestionInput.svelte index 8cc5a9a..d23b878 100644 --- a/frontend/src/lib/components/SuggestionInput.svelte +++ b/frontend/src/lib/components/SuggestionInput.svelte @@ -1,20 +1,33 @@
- {#if disabled} + {#if loading} {/if} - Add
From 1063c239b6c0aa9e22d99a749704ebe645af94c0 Mon Sep 17 00:00:00 2001 From: Mat12143 Date: Sat, 2 Aug 2025 13:00:11 +0200 Subject: [PATCH 04/11] feat: block access for pin protected rooms --- frontend/src/lib/utils.ts | 6 +++--- frontend/src/routes/room/[id]/+page.svelte | 2 +- frontend/src/routes/room/[id]/+page.ts | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 6450247..470da85 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -1,8 +1,8 @@ -import { get_coords, type Coordinates } from "./gps" +import { type Coordinates } from "./gps" import { parseSong, parseSuggestion, type FetchError, type Song, type Suggestion } from "./types" -export const joinRoom = async function (roomId: string, coords: Coordinates): Promise<[FetchError | null, string]> { - let res = await fetch(`/api/join?room=${roomId}&lat=${coords.latitude}&lon=${coords.longitude}`) +export const joinRoom = async function (roomId: string, coords: Coordinates, pin: string): Promise<[FetchError | null, string]> { + let res = await fetch(`/api/join?room=${roomId}&lat=${coords.latitude}&lon=${coords.longitude}&pin=${pin}`) if (res.status != 200) { return [{ code: 400, message: "Cannot join the room" }, ""] diff --git a/frontend/src/routes/room/[id]/+page.svelte b/frontend/src/routes/room/[id]/+page.svelte index 76984f3..84d8d67 100644 --- a/frontend/src/routes/room/[id]/+page.svelte +++ b/frontend/src/routes/room/[id]/+page.svelte @@ -31,7 +31,7 @@ } let sugg, queue, index - ;[returnError] = await joinRoom(data.roomId, coords) + ;[returnError] = await joinRoom(data.roomId, coords, data.pin) if (returnError) { return } diff --git a/frontend/src/routes/room/[id]/+page.ts b/frontend/src/routes/room/[id]/+page.ts index 1f9f77d..f3bea98 100644 --- a/frontend/src/routes/room/[id]/+page.ts +++ b/frontend/src/routes/room/[id]/+page.ts @@ -3,5 +3,6 @@ import type { PageLoad } from "./$types" export const load: PageLoad = ({ params, url }) => { return { roomId: params.id || "", + pin: url.searchParams.get("pin") || "", } } From 278a2d94a851efee1e3ee52d08da1c1567659a35 Mon Sep 17 00:00:00 2001 From: Leonardo Segala Date: Sat, 2 Aug 2025 13:10:51 +0200 Subject: [PATCH 05/11] Add custom code insertion during room creation --- frontend/src/routes/room/create/+page.svelte | 43 ++++++++------------ 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/frontend/src/routes/room/create/+page.svelte b/frontend/src/routes/room/create/+page.svelte index c69b19e..d0009f3 100644 --- a/frontend/src/routes/room/create/+page.svelte +++ b/frontend/src/routes/room/create/+page.svelte @@ -9,9 +9,7 @@ let name: string = $state() let range: number = $state() - - const privateStyle = "bg-red-500" - const publicStyle = "bg-green-500" + let pin: number = $state() async function createRoom() { if (creating) { @@ -22,16 +20,12 @@ return } - let pin - if (privateRoom) { - pin = Math.floor(Math.random() * 10000) - } else { - pin = "" - } - creating = true - const res = await fetch(`/api/room/new?name=${encodeURIComponent(name)}&coords=${coord.latitude},${coord.longitude}&range=${encodeURIComponent(range ?? "100")}&pin=${pin}`, { method: "POST" }) + const res = await fetch( + `/api/room/new?name=${encodeURIComponent(name)}&coords=${coord.latitude},${coord.longitude}&range=${encodeURIComponent(range ?? "100")}&pin=${encodeURIComponent(pin ?? "")}`, + { method: "POST" } + ) const json = await res.json() @@ -50,8 +44,10 @@
{coord.latitude},{coord.longitude}

-
- Public Room: - - {#if !privateRoom} -

The room is flagged as public, everyone can join

- {/if} -
+ @@ -56,7 +55,6 @@ class={!picked_suggestions.includes(sug.uuid) ? "text-light-pine-red duration-100 hover:scale-150 dark:text-dark-pine-red" : "text-light-pine-muted dark:text-dark-pine-muted"} disabled={!!picked_suggestions.includes(sug.uuid)} onclick={async () => { - sug.upvode += 1 await vote(-1, sug.uuid) }}> diff --git a/frontend/src/routes/admin/[id]/+page.svelte b/frontend/src/routes/admin/[id]/+page.svelte index 07d6f0e..02f5f08 100644 --- a/frontend/src/routes/admin/[id]/+page.svelte +++ b/frontend/src/routes/admin/[id]/+page.svelte @@ -112,5 +112,7 @@
+ + {/if} From 1763a6b96f891c9578711c49b660b803cff37d3c Mon Sep 17 00:00:00 2001 From: Simone Tesini Date: Sat, 2 Aug 2025 13:19:46 +0200 Subject: [PATCH 07/11] add readme --- README.md | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 65f5fc8..84edd62 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,40 @@ -# team-1 +# ChillBox -Test +> *A project by Pausetta.org, Simone Tesini, Francesco De Carlo, Leonardo Segala, Matteo Peretto* + +**ChillBox** is a web app that lets you create a shared radio station with a democratic voting system, so everyone gets to enjoy their favorite music together. +Perfect for venues like swimming pools, cafΓ©s, or even lively parties. + +--- + +## 🎡 Voting System + +Joining a ChillBox room is easy: users can either scan the QR code displayed on the host screen or use GPS to find nearby rooms. +Hosts can set a location range, ensuring only people physically present can add or vote for songs. + +--- + +## πŸ“Š Ranking Algorithm + +ChillBox uses a smart ranking algorithm to decide what plays next. The score of each song is based on: + +* Votes from users +* How recently similar songs (same genre or artist) have been played (less = better) +* A bit of randomness to keep things interesting +* A strong penalty for songs played too recently + +--- + +## πŸ‘ Hands-Off Experience + +ChillBox is designed to be almost entirely hands-free. +Once the host sets up a room and optionally connects a screen or projector +(to show the current track, QR code, etc.), ChillBox takes care of the rest. + +ChillBox comes with built-in automatic moderation to keep the music fair and on-theme. + +* Users can’t vote for the same song multiple times. +* A cooldown prevents users from spamming song requests. +* Hosts can define preferred genres and overall mood, so no one can hijack your chill beach vibes with unexpected death metal. + +That said, hosts still have access to essential controls, like pause and skip, if needed. From 9a12f39f3e2fa046d4c11d52e9dcb855bbe13848 Mon Sep 17 00:00:00 2001 From: Simone Tesini Date: Sat, 2 Aug 2025 13:22:52 +0200 Subject: [PATCH 08/11] remove words --- frontend/src/routes/+page.svelte | 2 +- frontend/static/{smerdoradar.gif => radar.gif} | Bin .../{smerdo_radar_bonus.gif => radar_bonus.gif} | Bin 3 files changed, 1 insertion(+), 1 deletion(-) rename frontend/static/{smerdoradar.gif => radar.gif} (100%) rename frontend/static/{smerdo_radar_bonus.gif => radar_bonus.gif} (100%) diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 6299c75..b0b35bf 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -23,7 +23,7 @@ ChillBox - radar + radar Scanning for rooms near you... + {#if showPinModal} + + + {/if} + From f7351aecf805cef9107a4d3efc410f25dfc556fa Mon Sep 17 00:00:00 2001 From: Leonardo Segala Date: Sat, 2 Aug 2025 13:41:53 +0200 Subject: [PATCH 10/11] Add default room for testing && show error msg --- backend/src/app.py | 6 +++--- frontend/src/lib/components/SuggestionInput.svelte | 13 ++++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/backend/src/app.py b/backend/src/app.py index aa9d4ee..28c66e9 100644 --- a/backend/src/app.py +++ b/backend/src/app.py @@ -29,9 +29,9 @@ init_db(state.db) state.rooms[1000] = Room( id=1000, coord=Coordinates(46.6769043, 11.1851585), - name="Test Room", - pin=None, - tags=set(), + name="Lido Scena", + pin=1234, + tags=set(["chill", "raggaetton", "spanish", "latino", "mexican", "rock"]), range_size=150, songs={}, history=[], diff --git a/frontend/src/lib/components/SuggestionInput.svelte b/frontend/src/lib/components/SuggestionInput.svelte index d23b878..53a3b34 100644 --- a/frontend/src/lib/components/SuggestionInput.svelte +++ b/frontend/src/lib/components/SuggestionInput.svelte @@ -7,6 +7,7 @@ let input = $state("") let loading: boolean = $state(false) let cooldowned: boolean = $state(false) + let errorMsg: string = $state() $effect(() => { console.log("cooldowned is now", cooldowned) @@ -14,10 +15,15 @@ async function sendSong() { loading = true - await fetch(`/api/addsong?room=${roomId}&query=${input}`, { method: "POST" }) + const res = await fetch(`/api/addsong?room=${roomId}&query=${input}`, { method: "POST" }) + const json = await res.json() input = "" loading = false + if (!json.success) { + errorMsg = json.error + } + cooldowned = true setTimeout(() => { cooldowned = false @@ -35,6 +41,7 @@ class="h-[50px] w-3/4 rounded px-4 font-bold text-white outline-none" bind:value={input} onkeydown={(e) => { + errorMsg = null if (e.key == "Enter") { sendSong() } @@ -56,3 +63,7 @@ > + +

+ {errorMsg} +

From bf71a8103dfab8535bdc0ab562ac8e45db4bec67 Mon Sep 17 00:00:00 2001 From: Simone Tesini Date: Sat, 2 Aug 2025 13:45:27 +0200 Subject: [PATCH 11/11] rush --- SPEECH.md | 15 +++++++++++++++ .../src/lib/components/SuggestionInput.svelte | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 SPEECH.md diff --git a/SPEECH.md b/SPEECH.md new file mode 100644 index 0000000..2ab507f --- /dev/null +++ b/SPEECH.md @@ -0,0 +1,15 @@ +# speech + +## Home screen +We start here in the home page. +We can see this little radar animation, which means that the app is looking for nearby ChillBox rooms to join. +It uses GPS for this feature. + +## Join room +When we join a room, the server checks our location and checks if it's within a specified range. +That way, you must physically be in the location to actually be able to add new songs + +## Talk about the host +As you can see here (and hear) on the left, the host is already playing some music. +Now i will add a song on the client side and it will pop up in the list. + diff --git a/frontend/src/lib/components/SuggestionInput.svelte b/frontend/src/lib/components/SuggestionInput.svelte index d23b878..4e75d3c 100644 --- a/frontend/src/lib/components/SuggestionInput.svelte +++ b/frontend/src/lib/components/SuggestionInput.svelte @@ -1,7 +1,7 @@