File size: 3,171 Bytes
012b226
 
 
 
 
 
 
e0d45d2
012b226
a7fe81f
e0d45d2
a7fe81f
8ebf51a
012b226
e0d45d2
012b226
 
dd24c08
012b226
 
 
a7fe81f
 
 
 
 
 
 
 
 
012b226
 
 
 
e0d45d2
012b226
8ebf51a
e0d45d2
 
 
 
 
3d2cb9e
e0d45d2
80e8f4d
 
e0d45d2
80e8f4d
 
 
 
 
 
 
e0d45d2
80e8f4d
 
 
3d2cb9e
80e8f4d
 
 
 
90beb82
 
 
e0d45d2
 
 
 
8ebf51a
 
 
a7fe81f
 
8ebf51a
 
 
 
012b226
 
759b9dd
e0d45d2
759b9dd
7e89314
759b9dd
012b226
 
8ebf51a
012b226
 
 
 
 
 
 
 
 
 
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
<script lang="ts">
	import { onMount } from 'svelte';
	import { createClient } from '@liveblocks/client';
	import type { Client } from '@liveblocks/client';
	import LiveblocksProvider from '$lib/liveblocks/LiveblocksProvider.svelte';
	import RoomProvider from '$lib/liveblocks/RoomProvider.svelte';
	import App from '$lib/App.svelte';
	import About from '$lib/About.svelte';
	import { PUBLIC_API_BASE } from '$env/static/public';
	import { selectedRoomID, toggleAbout, canvasSize } from '$lib/store';
	import type { RoomResponse } from '$lib/types';
	import { MAX_CAPACITY, FRAME_SIZE } from '$lib/constants';
	import { Status } from '$lib/types';

	let loading = true;
	let client: Client;

	$: roomId = $selectedRoomID;

	onMount(() => {
		// document.addEventListener('wheel', (e) => e.preventDefault(), { passive: false });
		// detect browser is mobile
		if (
			/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
		) {
			$canvasSize = {
				width: 512 * 8,
				height: 512 * 8
			};
		}
		client = createClient({
			authEndpoint: PUBLIC_API_BASE + '/auth'
		});

		updateRooms();
	});

	async function updateRooms() {
		loading = true;
		const roomidParam = new URLSearchParams(window.location.search).get('roomid');
		const res = await fetch(PUBLIC_API_BASE + '/rooms');
		const rooms: RoomResponse[] = await res.json();
		const emptyRoom = rooms.find((room) => room.users_count < MAX_CAPACITY) || null;

		let queriedRoom: string | null = null;
		// init if roomid is set via param
		if (roomidParam) {
			// if room is unlisted, skip the check
			if (roomidParam.startsWith('secret-')) {
				queriedRoom = roomidParam;
			} else {
				// if room is listed, check if it's full
				const room = rooms.find((room) => room.room_id === roomidParam) || null;
				queriedRoom = room && room.users_count < MAX_CAPACITY ? room.room_id : null;
			}
		} else {
			// if roomid is not set via param, select the first empty room
			queriedRoom = emptyRoom ? emptyRoom.room_id : null;
		}
		// if seleceted room is full, select the first empty room
		if (queriedRoom) {
			$selectedRoomID = queriedRoom;
			const state = { roomid: queriedRoom };
			const queryString = '?' + new URLSearchParams(state).toString();
			window.history.replaceState(null, '', queryString);
			window.parent.postMessage({ queryString: queryString }, '*');
		}
		loading = false;
		return { rooms };
	}
	const initialPresence = {
		cursor: null,
		frame: {
			x: $canvasSize.width / 2 - FRAME_SIZE / 2,
			y: $canvasSize.height / 2 - FRAME_SIZE / 2
		},
		status: Status.dragging,
		currentPrompt: ''
	};
</script>

<About classList={$toggleAbout ? 'flex' : 'hidden'} on:click={() => ($toggleAbout = false)} />

{#if loading}
	<div class="inset-0 fixed bg-white animate-pulse" />
{:else}
	<LiveblocksProvider {client}>
		{#if roomId}
			<RoomProvider id={roomId} {initialPresence}>
				<App />
			</RoomProvider>
		{:else}
			<div class="flex flex-col items-center justify-center h-full">
				<h1 class="text-2xl font-bold">No room selected</h1>
				<p class="text-gray-500">Please select a room in the URL</p>
			</div>
		{/if}
	</LiveblocksProvider>
{/if}