Two teams try and fill in any horizontal, vertical, or diagonal line on a bingo board by playing maps on osu!
osu.bingo
osu
1<script lang="ts">
2 import { MessageSquareText } from 'lucide-svelte';
3 import ChatMessage from './ChatMessage.svelte';
4 import { chats } from '$lib/stores';
5 import { afterUpdate } from 'svelte';
6
7 export let channel = 'global';
8
9 // Autoscroll
10 let box: HTMLDivElement;
11 const scrollToBottom = () => {
12 if (!box) return;
13
14 box.scroll({
15 top: box.scrollHeight,
16 behavior: 'smooth'
17 });
18 };
19 afterUpdate(scrollToBottom);
20
21 export let enabled: boolean = false;
22
23 let input: HTMLInputElement;
24 const keydown = async (ev: KeyboardEvent) => {
25 if (ev.key != 'Enter') return;
26
27 const body = new FormData();
28 body.set('message', input.value);
29 body.set('channel', channel.toUpperCase());
30
31 input.disabled = true;
32 const result = await fetch('?/chat', {
33 method: 'POST',
34 body
35 });
36 if (result.ok) {
37 input.value = '';
38 }
39 input.disabled = false;
40 input.focus();
41 };
42</script>
43
44<div
45 class="relative grid size-full grid-rows-[3rem_calc(100%-3rem-4.5rem)_4.5rem] rounded-xl bg-zinc-800"
46>
47 <h1
48 data-channel={channel}
49 class="flex h-12 w-full items-center gap-x-1 rounded-t-xl bg-zinc-800 p-2 font-rounded text-2xl font-bold capitalize shadow data-[channel=blue]:bg-blue-700 data-[channel=red]:bg-amber-700"
50 >
51 <MessageSquareText size={36} /> <span>{channel ?? 'Global'} Chat</span>
52 </h1>
53 <div bind:this={box} class="overflow-y-scroll">
54 <div class="flex flex-col items-center justify-end overflow-x-hidden">
55 <div class="p-2 text-zinc-500">
56 {#if enabled}
57 <div>Welcome to the chatroom!</div>
58 {/if}
59 {#if channel.toUpperCase() != 'GLOBAL'}
60 <div>Use this channel to collaborate with your fellow teammates!</div>
61 {/if}
62 </div>
63 {#each $chats as event}
64 <ChatMessage {event} />
65 {/each}
66 </div>
67 </div>
68 {#if enabled}
69 <div class="w-full p-5">
70 <input
71 type="text"
72 bind:this={input}
73 on:keydown={keydown}
74 placeholder="Send a message"
75 class="block w-full rounded-full bg-zinc-700 p-2 text-sm outline-none transition focus:shadow-lg disabled:bg-zinc-800"
76 />
77 </div>
78 {:else}
79 <div class="w-full p-5">
80 <input
81 type="text"
82 disabled
83 placeholder="Join the game to chat"
84 class="block w-full rounded-full bg-zinc-700/50 p-2 text-sm outline-none focus:shadow-lg"
85 />
86 </div>
87 {/if}
88</div>