Spaces:
Runtime error
Runtime error
File size: 3,474 Bytes
536b6c6 4c8fc93 536b6c6 35d6c3b bc15a99 536b6c6 35d6c3b 536b6c6 bc15a99 536b6c6 d16a2c1 bc15a99 536b6c6 35d6c3b bc15a99 331e32b bc15a99 35d6c3b 331e32b bc15a99 35d6c3b bc15a99 4c8fc93 35d6c3b 536b6c6 35d6c3b bc15a99 35d6c3b bc15a99 6157e63 bc15a99 4c8fc93 bc15a99 67cbe97 bc15a99 67cbe97 bc15a99 35d6c3b bc15a99 35d6c3b bc15a99 35d6c3b bc15a99 536b6c6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
<script lang="ts">
import { page } from '$app/stores';
import Room from '$lib/Icons/Room.svelte';
import Pin from '$lib/Icons/Pin.svelte';
import People from '$lib/Icons/People.svelte';
import { onMount } from 'svelte';
import { PUBLIC_API_BASE } from '$env/static/public';
import type { RoomResponse } from '$lib/types';
import { selectedRoomID } from '$lib/store';
import { MAX_CAPACITY } from '$lib/constants';
export let isLoading = false;
let boxEl: HTMLElement;
let rooms: RoomResponse[] = [];
let collapsed = true;
$: selectedRoom = rooms.find((room) => room.id === $selectedRoomID);
$: loadingRooms = rooms.length > 0;
function clickHandler(event: Event) {
if (!boxEl.contains(event.target as Node)) {
collapsed = true;
}
}
onMount(() => {
refreshRooms();
window.addEventListener('pointerdown', clickHandler, true);
const interval = setInterval(refreshRooms, 3000);
return () => {
window.removeEventListener('pointerdown', clickHandler, true);
clearInterval(interval);
};
});
async function refreshRooms() {
rooms = await fetch(PUBLIC_API_BASE + '/rooms').then((res) => res.json());
}
function changeRoom(room: RoomResponse) {
$selectedRoomID = room.id;
collapsed = true;
$page.url.searchParams.set('roomid', room.room_id);
window.location.search = `?${$page.url.searchParams.toString()}`;
}
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
{#if loadingRooms}
<div
class="text-xs md:text-sm bg-violet-100 text-violet-900 px-3 py-1 font-mono font-medium tracking-tight relative z-0 min-w-[25ch]
{isLoading ? 'opacity-50' : ''}
{collapsed ? 'rounded-xl' : 'rounded-b-xl'}"
title="Choose a different room"
bind:this={boxEl}
>
{#if !collapsed}
<div class="absolute left-0 right-0 bottom-full rounded-t-xl bg-violet-100 px-1">
<ul class="relative overflow-y-scroll max-h-72">
<li class="grid-row gap-2 pb-3 sticky top-0 bg-violet-100 py-2">
<Room />
<span> room </span>
<People />
<span> players </span>
</li>
{#each rooms as room}
<li>
<!-- svelte-ignore a11y-invalid-attribute -->
<a
href="#"
on:click|preventDefault={() => changeRoom(room)}
class="grid-row gap-2 hover:bg-gray-300
{room.id === $selectedRoomID ? 'text-green-600' : ''}"
>
<span>
{#if room.id === $selectedRoomID}
<Pin />
{/if}
</span>
<span>room {room.id} </span>
<span />
<span>{room.users_count} / {MAX_CAPACITY}</span>
</a>
</li>
{/each}
</ul>
<div class="border-t-2 border-t-gray-400 border-opacity-50" />
</div>
{/if}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class={isLoading ? 'cursor-wait' : 'cursor-pointer'}
on:click={() => (isLoading ? null : (collapsed = !collapsed))}
>
{#if selectedRoom}
<div class="grid-row gap-2">
<Room />
<span>
room {selectedRoom?.id}
</span>
<People />
<span>
{selectedRoom?.users_count} / {MAX_CAPACITY}
</span>
</div>
{:else}
<div class="grid-row gap-2">
<Room />
<span>
Loading...
<People />
<span> ... / ... </span>
</span>
</div>
{/if}
</div>
</div>
{/if}
<style lang="postcss" scoped>
.grid-row {
display: grid;
grid-template-columns: 0.5fr 2fr 0.5fr 2fr;
align-items: center;
justify-items: flex-start;
}
</style>
|