File size: 3,171 Bytes
bb88c4d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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}