Skyler Grey | 51e9e63 | 2023-06-03 10:20:11 +0200 | [diff] [blame] | 1 | <script lang="ts"> |
| 2 | import Button from '$components/ui/button/Button.svelte'; |
| 3 | import Input from '$components/ui/input/Input.svelte'; |
| 4 | import { onMount } from 'svelte'; |
| 5 | import { flip } from 'svelte/animate'; |
| 6 | import { fade } from 'svelte/transition'; |
| 7 | |
| 8 | export let form; |
| 9 | |
| 10 | let messageInput: HTMLInputElement; |
| 11 | function focusMessageInput() { |
| 12 | messageInput.focus(); |
| 13 | } |
| 14 | |
| 15 | let systemMessage = |
| 16 | 'Welcome to the void. Everything you put here is completely private. Messages will fade as they go up the page and disappear after a few minutes, or you can refresh the page to clear them too. Let out your frustrations and watch them slip away into the void...'; |
| 17 | const resetMessage = |
| 18 | "Poof: it's gone; hopefully you feel a little better after letting your frustrations out. If there's something you still need to vent about feel free to continue. I'm still here to listen..."; |
| 19 | let messages: string[] = []; |
| 20 | let currentlyTyped: string = ''; |
| 21 | |
| 22 | if (form?.pastMessages) { |
| 23 | messages = form?.pastMessages.toString().split('\n'); |
| 24 | } |
| 25 | |
| 26 | if (form?.message) { |
| 27 | messages.push(form?.message.toString()); |
| 28 | } |
| 29 | |
| 30 | if (form?.reset) { |
| 31 | systemMessage = resetMessage; |
| 32 | } |
| 33 | |
| 34 | onMount(focusMessageInput); |
| 35 | </script> |
| 36 | |
| 37 | <form |
| 38 | on:submit|preventDefault={() => { |
| 39 | messages.push(currentlyTyped); |
| 40 | messages = messages; |
| 41 | currentlyTyped = ''; |
| 42 | focusMessageInput(); |
| 43 | }} |
| 44 | method="post" |
| 45 | class="p-2 flex flex-col h-screen gap-2 justify-end pt-0" |
| 46 | > |
| 47 | <div class="flex p-2 pt-0 flex-col justify-end overflow-hidden pastMessages"> |
| 48 | {#each (messages.length === 0 ? [systemMessage] : ['']).concat(messages) as message, index (`${index} ${message}`)} |
| 49 | <p class:message="{index !== 0}" transition:fade={{ duration: 100 }} animate:flip={{ duration: 100 }}> |
| 50 | {message} |
| 51 | </p> |
| 52 | {/each} |
| 53 | <input type="hidden" value={messages.join('\n')} name="pastMessages" /> |
| 54 | </div> |
| 55 | |
| 56 | <div class="flex w-full gap-2"> |
| 57 | <Input |
| 58 | bind:element={messageInput} |
| 59 | bind:value={currentlyTyped} |
| 60 | name="message" |
| 61 | placeholder="Write down your worries, and let them slip into the void" |
| 62 | /> |
| 63 | <Button type="submit">Send</Button> |
| 64 | <Button |
| 65 | name="reset" |
| 66 | value="reset" |
| 67 | on:click={() => { |
| 68 | currentlyTyped = ''; |
| 69 | systemMessage = resetMessage; |
| 70 | messages = [systemMessage]; |
| 71 | }}>Clean</Button |
| 72 | > |
| 73 | </div> |
| 74 | </form> |
| 75 | |
| 76 | <style lang="postcss"> |
| 77 | div.pastMessages::after { |
| 78 | content: ''; |
| 79 | position: absolute; |
| 80 | top: 0; |
| 81 | left: 0; |
| 82 | z-index: 1; |
| 83 | width: 100%; |
| 84 | height: 100%; |
| 85 | background: linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%); |
| 86 | } |
| 87 | |
| 88 | @keyframes message-fade-out { |
| 89 | 0% { |
| 90 | opacity: 1; |
| 91 | } |
| 92 | 100% { |
| 93 | opacity: 0; |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | p.message { |
| 98 | animation: message-fade-out 150s ease-in-out forwards; |
| 99 | } |
| 100 | </style> |