Two teams try and fill in any horizontal, vertical, or diagonal line on a bingo board by playing maps on osu! osu.bingo
osu
at microservice 88 lines 2.3 kB view raw
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>