Skip to content
Extraits de code Groupes Projets
writebox.svelte 3,18 ko
Newer Older
  • Learn to ignore specific revisions
  • <script lang="ts">
    
    	import config from '$lib/config';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	import { t } from '$lib/services/i18n';
    
    	import type Session from '$lib/types/session';
    	import { toastAlert } from '$lib/utils/toasts';
    	import { Icon, PaperAirplane } from 'svelte-hero-icons';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	import { user } from '$lib/types/user';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	import { onMount } from 'svelte';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	import { get } from 'svelte/store';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    
    	onMount(async () => {
    		await import('emoji-picker-element');
    	});
    
    
    	export let session: Session;
    
    	let metadata: { message: string; date: number }[] = [];
    	let lastMessage = '';
    	let message = '';
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	let showPicker = false;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	let showSpecials = false;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	let textearea: HTMLTextAreaElement;
    
    	let us = get(user);
    
    	let disabled =
    		us == null ||
    		session.users.find((u) => us.id === u.id) === undefined ||
    		new Date() > session.end_time ||
    		new Date() < session.start_time;
    
    	async function sendMessage() {
    		if (message.length == 0) return;
    
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		if ($user === null) return;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		const m = await session.sendMessage($user, message, metadata);
    
    
    		if (m === null) {
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			toastAlert($t('chatbox.sendError'));
    
    			return;
    		}
    
    		message = '';
    		metadata = [];
    	}
    
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    	function keyPress() {
    
    		if (message === lastMessage) return;
    
    		metadata.push({ message: message, date: new Date().getTime() });
    		lastMessage = message;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    
    
    		session.sendTyping();
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    <div class="w-full border-t-2">
    	{#if showSpecials}
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		<ul class="flex justify-around divide-x-2 border-b-2 py-1 flex-wrap md:flex-nowrap">
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			{#each config.SPECIAL_CHARS as char (char)}
    				<button
    					class="border-none"
    					on:click={() => {
    						message += char;
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    						textearea.focus();
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    					}}
    				>
    					<kbd class="kbd">
    						{char}
    					</kbd>
    				</button>
    			{/each}
    		</ul>
    	{/if}
    	<div class="w-full flex relative">
    		<textarea
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			bind:this={textearea}
    			class="flex-grow p-2 resize-none overflow-y-hidden pr-16"
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			placeholder={disabled ? $t('chatbox.disabled') : $t('chatbox.placeholder')}
    			{disabled}
    			bind:value={message}
    			on:keypress={(e) => keyPress()}
    			on:keypress={async (e) => {
    				if (e.key === 'Enter' && !e.shiftKey) {
    					await sendMessage();
    				} else {
    					keyPress();
    				}
    			}}
    		/>
    		<div
    			class="absolute top-1/2 right-20 transform -translate-y-1/2 text-lg select-none cursor-pointer"
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			on:click={() => (showPicker = !showPicker)}
    			data-tooltip-target="tooltip-emoji"
    			data-tooltip-placement="right"
    			data-riple-light="true"
    			aria-hidden={false}
    			role="button"
    			tabindex="0"
    		>
    			😀
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		</div>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		<div class="relative">
    			<div
    				id="tooltip-emoji"
    				data-tooltip="tooltip-emoji"
    				role="tooltip"
    				class:hidden={!showPicker}
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    				class="absolute z-10 tooltip bottom-16 right-0 lg:left-0 lg:right-auto"
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    			>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    				<emoji-picker
    					class="light"
    					on:emoji-click={(event) => {
    						message += event.detail.unicode;
    						textearea.focus();
    					}}
    				>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    				</emoji-picker>
    			</div>
    		</div>
    
    Brieuc Dubois's avatar
    Brieuc Dubois a validé
    		<div
    			class="absolute top-1/2 right-28 kbd transform -translate-y-1/2 text-sm select-none cursor-pointer"
    			on:click={() => (showSpecials = !showSpecials)}
    			aria-hidden={false}
    			role="button"
    			tabindex="0"
    		>
    			É
    		</div>
    
    		<button class="btn btn-primary rounded-none size-16" on:click={sendMessage}>
    
    			<Icon src={PaperAirplane} />
    		</button>
    	</div>
    </div>