Merge branch 'main' of https://repos.hackathon.bz.it/2025-summer/team-1
This commit is contained in:
commit
543db8d25f
8 changed files with 60 additions and 35 deletions
|
@ -1,15 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
||||
<body data-sveltekit-preload-data="hover" class="h-max">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
|
||||
<body data-sveltekit-preload-data="hover" class="h-max">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
queueSongs[playingIndex],
|
||||
playingIndex == queueSongs.length - 1 ? createEmptySong() : queueSongs[playingIndex + 1],
|
||||
])
|
||||
|
||||
$effect(() => {
|
||||
console.log(displaySongs)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="relative flex w-full justify-center overflow-hidden">
|
||||
|
@ -28,11 +32,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex h-[60vw] max-h-[250px] w-[60vw] max-w-[250px] items-center justify-center">
|
||||
{#if i === 1}
|
||||
<p>No song in queue</p>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex h-[60vw] max-h-[250px] w-[60vw] max-w-[250px] items-center justify-center"></div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
@ -1,18 +1,39 @@
|
|||
<script lang="ts">
|
||||
let { roomId } = $props()
|
||||
import { LoaderCircle } from "@lucide/svelte"
|
||||
|
||||
let { roomId } = $props()
|
||||
let input = $state("")
|
||||
let disabled: boolean = $state(false)
|
||||
|
||||
async function sendSong() {
|
||||
let resp = await fetch(`/api/addsong?room=${roomId}&query=${input}`, { method: "POST" })
|
||||
disabled = true
|
||||
await fetch(`/api/addsong?room=${roomId}&query=${input}`, { method: "POST" })
|
||||
input = ""
|
||||
disabled = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="bg-lime-500 flex h-full w-full flex-row items-center gap-2 rounded border-2 border-lime-600">
|
||||
<input type="text" placeholder="Song & Artist" class="font-bold outline-none text-white h-[50px] px-4 w-3/4 rounded" bind:value={input} />
|
||||
<div class="flex h-full w-full flex-row items-center gap-2 rounded border-2 border-lime-600 bg-lime-500">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Song & Artist"
|
||||
class="h-[50px] w-3/4 rounded px-4 font-bold text-white outline-none"
|
||||
bind:value={input}
|
||||
onkeydown={(e) => {
|
||||
if (e.key == "Enter") {
|
||||
sendSong()
|
||||
}
|
||||
}}
|
||||
{disabled}
|
||||
/>
|
||||
{#if disabled}
|
||||
<span class="animate-spin">
|
||||
<LoaderCircle />
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
class="shadow-xl hover:scale-105 w-1/4 h-[40px] cursor-pointer bg-lime-600 border-lime-700 font-semibold text-white border-2 i-lucide-check rounded active:scale-90 duration-100"
|
||||
class="i-lucide-check h-[40px] w-1/4 cursor-pointer rounded border-2 border-lime-700 bg-lime-600 font-semibold text-white shadow-xl duration-100 hover:scale-105 active:scale-90"
|
||||
onclick={sendSong}>Add</button
|
||||
>
|
||||
<span class="i-lucide-chevrons-left"></span>
|
||||
|
|
|
@ -10,19 +10,19 @@ const SongSchema = z.object({
|
|||
})
|
||||
export type Song = z.infer<typeof SongSchema>
|
||||
|
||||
export const parseSong = async function(song: any): Promise<Song> {
|
||||
export const parseSong = async function (song: any): Promise<Song> {
|
||||
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<typeof SuggestionSchema>
|
||||
|
||||
export const parseSuggestion = async function(sugg: any): Promise<Suggestion> {
|
||||
export const parseSuggestion = async function (sugg: any): Promise<Suggestion> {
|
||||
let resp = await SuggestionSchema.parseAsync(sugg)
|
||||
return resp
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ const RoomSchema = z.object({
|
|||
})
|
||||
export type Room = z.infer<typeof RoomSchema>
|
||||
|
||||
export const parseRoom = async function(room: any): Promise<Room> {
|
||||
export const parseRoom = async function (room: any): Promise<Room> {
|
||||
let resp = await RoomSchema.parseAsync(room)
|
||||
return resp
|
||||
}
|
||||
|
|
|
@ -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 @@
|
|||
<div class="flex w-full flex-col items-center justify-center p-4 lg:p-10">
|
||||
<QueueSlider {queueSongs} {playingIndex} />
|
||||
<button onclick={playNext}>Next</button>
|
||||
<audio controls autoplay bind:this={audioController} onended={playOnEnd}></audio>
|
||||
<audio controls autoplay bind:this={audioController} onended={playNext}></audio>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -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}
|
||||
<Error {returnError} />
|
||||
{:else}
|
||||
<div class="flex w-full flex-col items-center justify-center py-4 px-2 lg:p-10">
|
||||
<div class="flex w-full flex-col items-center justify-center px-2 py-4 lg:p-10">
|
||||
<QueueSlider {queueSongs} {playingIndex} />
|
||||
<div class="w-full py-6 lg:w-[30vw]">
|
||||
<SuggestionInput roomId={data.roomId} />
|
||||
|
|
BIN
frontend/static/favicon.ico
Normal file
BIN
frontend/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116" style="fill:#ff3e00"/><path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328" style="fill:#fff"/></svg>
|
Before Width: | Height: | Size: 1.5 KiB |
Loading…
Add table
Add a link
Reference in a new issue