diff --git a/backend/src/app.py b/backend/src/app.py
index d70afd4..559baf1 100644
--- a/backend/src/app.py
+++ b/backend/src/app.py
@@ -5,13 +5,13 @@ from flask import Flask, Response, jsonify, request
from flask_cors import CORS
from flask_socketio import SocketIO, join_room, leave_room
-from .state import State
-from .connect import get_connection
-from .room import Room
-from .song import Song, init_db, get_song_by_title_artist, add_song_in_db, get_song_by_uuid
-from .song_fetch import query_search, yt_get_audio_url, yt_search_song
-from .qrcode_gen import generate_qr
-from .gps import is_within_range, distance_between_coords, Coordinates
+from state import State
+from connect import get_connection
+from room import Room
+from song import Song, init_db, get_song_by_title_artist, add_song_in_db, get_song_by_uuid
+from song_fetch import query_search, yt_get_audio_url, yt_search_song
+from qrcode_gen import generate_qr
+from gps import is_within_range, distance_between_coords, Coordinates
dotenv.load_dotenv()
@@ -29,7 +29,7 @@ init_db(state.db)
state.rooms[1000] = Room(
id=1000,
- coord=(1.0, 5.5),
+ coord=Coordinates(46.6769043, 11.1851585),
name="Test Room",
pin=None,
tags=set(),
@@ -85,7 +85,15 @@ def join():
if room.pin is not None and room.pin != code:
return error("Invalid code")
- if room.distance > room.range_size:
+ distance = distance_between_coords(
+ lhs=room.coord,
+ rhs=Coordinates(
+ latitude=float(request.args["lat"]),
+ longitude=float(request.args["lon"]),
+ ),
+ )
+
+ if distance > room.range_size:
return error("You are not within the room range")
return {"success": True, "ws": f"/ws/{room_id}"}
@@ -144,8 +152,8 @@ def room_new():
lat, lon = room_cords.split(",")
room = Room(
- id=max(state.rooms or [0]) + 1, #
- coord=(float(lat), float(lon)),
+ id=max(state.rooms or [0]) + 1,
+ coord=Coordinates(float(lat), float(lon)),
range_size=int(room_range),
name=room_name,
pin=room_pin,
@@ -165,12 +173,12 @@ def room_new():
def room():
lat = request.args.get("lat")
lon = request.args.get("lon")
+
if lat and lon:
user_coords = Coordinates(latitude=float(lat), longitude=float(lon))
else:
return error("Missing user coordinates")
- distance = distance_between_coords(user_coords, room.coord)
return [
{
"id": room.id,
@@ -178,10 +186,10 @@ def room():
"private": room.pin is not None,
"coords": room.coord,
"range": room.range_size,
- "distance": distance,
+ "distance": d,
}
for room in state.rooms.values()
- if distance <= room.range_size
+ if (d := distance_between_coords(user_coords, room.coord)) <= room.range_size
]
diff --git a/backend/src/gps.py b/backend/src/gps.py
index 546531b..98bda0c 100644
--- a/backend/src/gps.py
+++ b/backend/src/gps.py
@@ -1,9 +1,11 @@
import math
+from dataclasses import dataclass
+@dataclass
class Coordinates:
- latitude: int
- longitude: int
+ latitude: float
+ longitude: float
def distance_between_coords(lhs: Coordinates, rhs: Coordinates) -> float:
diff --git a/backend/src/room.py b/backend/src/room.py
index cad4020..cb775b6 100644
--- a/backend/src/room.py
+++ b/backend/src/room.py
@@ -1,6 +1,7 @@
import random
from dataclasses import dataclass
+from gps import Coordinates
from song import Song
USER_SCORE_WEIGHT = 0.7
@@ -30,12 +31,11 @@ class Rank:
@dataclass
class Room:
id: int
- coord: tuple[float, float]
+ coord: Coordinates
name: str
pin: int | None
tags: set[str]
range_size: int # in meters ??
- distance: float
songs: dict[str, UserScoredSong] # all songs + user score (the playlist)
history: list[Song] # all songs previously played
diff --git a/frontend/src/app.css b/frontend/src/app.css
index 9f0c24a..cb4fb29 100644
--- a/frontend/src/app.css
+++ b/frontend/src/app.css
@@ -1,3 +1,4 @@
+@import url('https://fonts.googleapis.com/css2?family=Lilita+One&display=swap');
@import 'tailwindcss';
@keyframes spin-slower {
@@ -14,6 +15,20 @@
animation: spin-slower 15s linear infinite;
}
+html,
+body {
+ @apply bg-light-pine-base dark:bg-dark-pine-base;
+ /* or use your color class here */
+ height: 100%;
+ margin: 0;
+}
+
+.lilita-one-regular {
+ font-family: "Lilita One", sans-serif;
+ font-weight: 400;
+ font-style: normal;
+}
+
@theme {
--color-dark-pine-base: hsl(249deg, 22%, 12%);
--color-dark-pine-surface: hsl(247deg, 23%, 15%);
diff --git a/frontend/src/lib/components/QueueSlider.svelte b/frontend/src/lib/components/QueueSlider.svelte
index 94430f0..d20003f 100644
--- a/frontend/src/lib/components/QueueSlider.svelte
+++ b/frontend/src/lib/components/QueueSlider.svelte
@@ -8,6 +8,10 @@
queueSongs[playingIndex],
playingIndex == queueSongs.length - 1 ? createEmptySong() : queueSongs[playingIndex + 1],
])
+
+ $effect(() => {
+ console.log(displaySongs)
+ })
@@ -28,11 +32,7 @@
{/if}
{:else}
-
- {#if i === 1}
-
No song in queue
- {/if}
-
+
{/if}
{/each}
diff --git a/frontend/src/lib/components/Room.svelte b/frontend/src/lib/components/Room.svelte
deleted file mode 100644
index db8048f..0000000
--- a/frontend/src/lib/components/Room.svelte
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- {room.name}
- {#if room.private}
- 🔒
- {/if}
-
-
-
-
-
diff --git a/frontend/src/lib/components/RoomComponent.svelte b/frontend/src/lib/components/RoomComponent.svelte
new file mode 100644
index 0000000..e98e000
--- /dev/null
+++ b/frontend/src/lib/components/RoomComponent.svelte
@@ -0,0 +1,18 @@
+
+
+
diff --git a/frontend/src/lib/components/SuggestionInput.svelte b/frontend/src/lib/components/SuggestionInput.svelte
index 09982fd..9659e0d 100644
--- a/frontend/src/lib/components/SuggestionInput.svelte
+++ b/frontend/src/lib/components/SuggestionInput.svelte
@@ -4,15 +4,25 @@
let input = $state("")
async function sendSong() {
- let resp = await fetch(`/api/addsong?room=${roomId}&query=${input}`, { method: "POST" })
+ await fetch(`/api/addsong?room=${roomId}&query=${input}`, { method: "POST" })
input = ""
}
-
-
+
+
{
+ if (e.key == "Enter") {
+ sendSong()
+ }
+ }}
+ />
diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts
index 0c2e8f5..db04654 100644
--- a/frontend/src/lib/types.ts
+++ b/frontend/src/lib/types.ts
@@ -10,19 +10,19 @@ const SongSchema = z.object({
})
export type Song = z.infer
-export const parseSong = async function(song: any): Promise {
+export const parseSong = async function (song: any): Promise {
let resp = await SongSchema.parseAsync(song)
return resp
}
-export const createEmptySong = function(): Song {
+export const createEmptySong = function (): Song {
return {
uuid: "-1",
title: "",
artist: "",
tags: [""],
image_id: "",
- youtube_id: 0,
+ youtube_id: "",
}
}
@@ -31,7 +31,7 @@ const SuggestionSchema = SongSchema.extend({
})
export type Suggestion = z.infer
-export const parseSuggestion = async function(sugg: any): Promise {
+export const parseSuggestion = async function (sugg: any): Promise {
let resp = await SuggestionSchema.parseAsync(sugg)
return resp
}
@@ -41,11 +41,11 @@ const RoomSchema = z.object({
name: z.string(),
private: z.boolean(),
coords: z.tuple([z.number(), z.number()]),
- range: z.number().int()
+ range: z.number().int(),
})
export type Room = z.infer
-export const parseRoom = async function(room: any): Promise {
+export const parseRoom = async function (room: any): Promise {
let resp = await RoomSchema.parseAsync(room)
return resp
}
diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts
index 1b806c5..580b638 100644
--- a/frontend/src/lib/utils.ts
+++ b/frontend/src/lib/utils.ts
@@ -1,7 +1,7 @@
import { parseSong, parseSuggestion, type FetchError, type Song, type Suggestion } from "./types"
-export const joinRoom = async function (roomId: string): Promise<[FetchError | null, string]> {
- let resp = await fetch("/api/join?room=" + roomId)
+export const joinRoom = async function (roomId: string, lat: number, lon: number): Promise<[FetchError | null, string]> {
+ let resp = await fetch(`/api/join?room=${roomId}&lat=${lat}&lon=${lon}`)
if (resp.status != 200) {
return [{ code: 400, message: "Cannot join the room" }, ""]
diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte
index 75d43d8..319ce8d 100644
--- a/frontend/src/routes/+page.svelte
+++ b/frontend/src/routes/+page.svelte
@@ -1,10 +1,40 @@
+
+
+

+
ChillBox
+
+
+

+
Scanning for rooms near you...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/routes/admin/[id]/+page.svelte b/frontend/src/routes/admin/[id]/+page.svelte
index e017cc5..c579bed 100644
--- a/frontend/src/routes/admin/[id]/+page.svelte
+++ b/frontend/src/routes/admin/[id]/+page.svelte
@@ -19,7 +19,7 @@
let url = await getStreamingUrl(currentPlaying.uuid)
if (audioController) {
audioController.src = url
- audioController.play()
+ await audioController.play()
}
}
@@ -29,11 +29,10 @@
queueSongs = songs
playingIndex = index
+ })
- if (audioController) {
- audioController.src = await getStreamingUrl(currentPlaying.uuid)
- audioController.play()
- }
+ $effect(() => {
+ playOnEnd()
})
async function playNext() {
@@ -53,6 +52,6 @@
{/if}
diff --git a/frontend/src/routes/room/[id]/+page.svelte b/frontend/src/routes/room/[id]/+page.svelte
index 6237b13..95acdf5 100644
--- a/frontend/src/routes/room/[id]/+page.svelte
+++ b/frontend/src/routes/room/[id]/+page.svelte
@@ -8,6 +8,8 @@
import { getQueueSongs, getSuggestions, joinRoom } from "$lib/utils.js"
import type { FetchError } from "$lib/types.js"
import { io, Socket } from "socket.io-client"
+ import { get_coords } from "$lib/gps.js"
+ import type { Coordinates } from "$lib/gps.js"
let { data } = $props()
@@ -23,8 +25,14 @@
onMount(async () => {
// Join the room
+ let { coords, error } = await get_coords()
+ if (error || coords == null) {
+ // Default to Lido
+ coords = { latitude: 46.6769043, longitude: 11.1851585 }
+ }
+
let sugg, queue, index
- ;[returnError] = await joinRoom(data.roomId)
+ ;[returnError] = await joinRoom(data.roomId, coords.latitude, coords.longitude)
if (returnError) {
return
}
@@ -69,7 +77,7 @@
{#if returnError}
{:else}
-
+
diff --git a/frontend/static/CHILLBOX.svg b/frontend/static/CHILLBOX.svg
new file mode 100644
index 0000000..8133a23
--- /dev/null
+++ b/frontend/static/CHILLBOX.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/static/icon_small.png b/frontend/static/icon_small.png
new file mode 100644
index 0000000..f518ac7
Binary files /dev/null and b/frontend/static/icon_small.png differ