From 85854e56738261a767decdedd982ce894f40f359 Mon Sep 17 00:00:00 2001 From: Simone Tesini Date: Sat, 2 Aug 2025 00:48:21 +0200 Subject: [PATCH 1/2] add socketio to global state --- backend/src/app.py | 12 ++++++------ backend/src/state.py | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/backend/src/app.py b/backend/src/app.py index 2024da5..8848709 100644 --- a/backend/src/app.py +++ b/backend/src/app.py @@ -1,15 +1,15 @@ +from typing import Any + import dotenv from flask import Flask, Response, jsonify, request from flask_cors import CORS from flask_socketio import SocketIO, emit -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 -from .song_fetch import lastfm_query_search, download_song_mp3 - -from typing import Any +from .song import Song, add_song_in_db, get_song_by_title_artist, init_db +from .song_fetch import download_song_mp3, lastfm_query_search +from .state import State dotenv.load_dotenv() @@ -20,7 +20,7 @@ socketio = SocketIO(app) CORS(app) db_conn = get_connection() -state = State(app, db_conn.cursor()) +state = State(app, socketio, db_conn.cursor()) init_db(state.db) state.rooms[1000] = Room( diff --git a/backend/src/state.py b/backend/src/state.py index ab83edc..e1f3e7c 100644 --- a/backend/src/state.py +++ b/backend/src/state.py @@ -2,6 +2,7 @@ from dataclasses import dataclass, field from sqlite3 import Cursor from flask import Flask +from flask_socketio import SocketIO from .room import Room @@ -9,5 +10,6 @@ from .room import Room @dataclass class State: app: Flask + socketio: SocketIO db: Cursor rooms: dict[int, Room] = field(default_factory=dict) # { room_id: room, ... } From ab9bfa41c9a46adc8b592eecd3cdba6d7ed4a544 Mon Sep 17 00:00:00 2001 From: Mat12143 Date: Sat, 2 Aug 2025 00:52:13 +0200 Subject: [PATCH 2/2] feat: added error page + join endpoint --- frontend/package-lock.json | 12 +++ frontend/package.json | 3 + frontend/src/app.css | 14 +++ frontend/src/lib/components/Error.svelte | 8 ++ .../src/lib/components/QueueSlider.svelte | 32 ++++--- frontend/src/lib/types.ts | 28 ++++-- frontend/src/routes/+page.svelte | 25 ++---- frontend/src/routes/admin/[id]/+page.svelte | 37 ++++++++ frontend/src/routes/room/[id]/+page.svelte | 85 +++++++++++-------- frontend/src/routes/room/[id]/+page.ts | 11 +++ 10 files changed, 184 insertions(+), 71 deletions(-) create mode 100644 frontend/src/lib/components/Error.svelte create mode 100644 frontend/src/routes/admin/[id]/+page.svelte create mode 100644 frontend/src/routes/room/[id]/+page.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b3ecdec..cf0b463 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "frontend", "version": "0.0.1", + "dependencies": { + "zod": "^4.0.14" + }, "devDependencies": { "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.22.0", @@ -2304,6 +2307,15 @@ "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", "dev": true, "license": "MIT" + }, + "node_modules/zod": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.0.14.tgz", + "integrity": "sha512-nGFJTnJN6cM2v9kXL+SOBq3AtjQby3Mv5ySGFof5UGRHrRioSJ5iG680cYNjE/yWk671nROcpPj4hAS8nyLhSw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/frontend/package.json b/frontend/package.json index cee9931..cdbbe97 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,5 +26,8 @@ "tailwindcss": "^4.0.0", "typescript": "^5.0.0", "vite": "^7.0.4" + }, + "dependencies": { + "zod": "^4.0.14" } } diff --git a/frontend/src/app.css b/frontend/src/app.css index d4b5078..90d8258 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -1 +1,15 @@ @import 'tailwindcss'; + +@keyframes spin-slower { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +.spin-slower { + animation: spin-slower 15s linear infinite; +} diff --git a/frontend/src/lib/components/Error.svelte b/frontend/src/lib/components/Error.svelte new file mode 100644 index 0000000..47e6a19 --- /dev/null +++ b/frontend/src/lib/components/Error.svelte @@ -0,0 +1,8 @@ + + +
+

Error {code}

+

{message}

+
diff --git a/frontend/src/lib/components/QueueSlider.svelte b/frontend/src/lib/components/QueueSlider.svelte index 1db4c6a..dec52c5 100644 --- a/frontend/src/lib/components/QueueSlider.svelte +++ b/frontend/src/lib/components/QueueSlider.svelte @@ -1,30 +1,38 @@
{#each displaySongs as song, i} - {#if song.name != ""} + {#if song?.title && song.title != ""}
- Song cover +
+ {#if i === 1} +
+ {/if} + Song cover +
{#if i === 1} -

{song.name}

+

{song.title} - {song.artist}

{/if}
{:else} -
+
+ {#if i === 1} +

No song in queue

+ {/if} +
{/if} {/each}
diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index 29c7bd9..85dff04 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -1,9 +1,27 @@ -import * as z from "zod" +import { z } from "zod" export const SongSchema = z.object({ - name: z.string(), - image: z.string(), - points: z.number().optional().default(0), + uuid: z.string(), + title: z.string(), + artist: z.string(), + tags: z.array(z.string()), + image_id: z.string(), + youtube_id: z.number().optional().default(0), }) - export type Song = z.infer + +export const parseSong = async function (song: any): Promise { + let resp = await SongSchema.parseAsync(song) + return resp +} + +export const createEmptySong = function (): Song { + return { + uuid: "-1", + title: "", + artist: "", + tags: [""], + image_id: "", + youtube_id: 0, + } +} diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 6741d1c..48f1755 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -1,21 +1,12 @@ -
-
+
+
+

Scan your nearby rooms

+ Room Test +
+
+

Create your room

+
diff --git a/frontend/src/routes/admin/[id]/+page.svelte b/frontend/src/routes/admin/[id]/+page.svelte new file mode 100644 index 0000000..7573aa2 --- /dev/null +++ b/frontend/src/routes/admin/[id]/+page.svelte @@ -0,0 +1,37 @@ + + +
+ +
diff --git a/frontend/src/routes/room/[id]/+page.svelte b/frontend/src/routes/room/[id]/+page.svelte index eb0a4dc..31254dd 100644 --- a/frontend/src/routes/room/[id]/+page.svelte +++ b/frontend/src/routes/room/[id]/+page.svelte @@ -1,45 +1,56 @@ -
- -
- + +{#if error.code != 0} + +{:else} +
+ +
+ +
+
+ +
-
- -
-
+{/if} diff --git a/frontend/src/routes/room/[id]/+page.ts b/frontend/src/routes/room/[id]/+page.ts new file mode 100644 index 0000000..1776db6 --- /dev/null +++ b/frontend/src/routes/room/[id]/+page.ts @@ -0,0 +1,11 @@ +import { error, type Load, type ServerLoad } from "@sveltejs/kit" +import type { PageLoad } from "./$types" + +export const load: PageLoad = async ({ params }) => { + if (params.id) { + return { + roomId: params.id, + } + } + error(400, "Please provide a room id") +}