diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-11-02 20:02:24 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-11-02 20:02:24 -0400 |
| commit | 22ce0549e20ee397cf5953bd6b7aafc752deaa28 (patch) | |
| tree | 59e116cd0a198de04a2dbd3bbb632ec3dee6fed5 /ui | |
| parent | 0e14a3b7e365c05992848cfbc4b8d7d9681d6d04 (diff) | |
Run prettier, make lint part of pre-commit
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/lib/apiServer.js | 148 | ||||
| -rw-r--r-- | ui/lib/components/ActiveChannel.svelte | 62 | ||||
| -rw-r--r-- | ui/lib/components/Channel.svelte | 27 | ||||
| -rw-r--r-- | ui/lib/components/ChannelList.svelte | 18 | ||||
| -rw-r--r-- | ui/lib/components/CreateChannelForm.svelte | 34 | ||||
| -rw-r--r-- | ui/lib/components/CurrentUser.svelte | 33 | ||||
| -rw-r--r-- | ui/lib/components/Invite.svelte | 5 | ||||
| -rw-r--r-- | ui/lib/components/Invites.svelte | 12 | ||||
| -rw-r--r-- | ui/lib/components/LogIn.svelte | 48 | ||||
| -rw-r--r-- | ui/lib/components/Message.svelte | 44 | ||||
| -rw-r--r-- | ui/lib/components/MessageInput.svelte | 50 | ||||
| -rw-r--r-- | ui/lib/components/MessageRun.svelte | 33 | ||||
| -rw-r--r-- | ui/lib/store/messages.js | 5 | ||||
| -rw-r--r-- | ui/routes/(app)/+layout.svelte | 238 | ||||
| -rw-r--r-- | ui/routes/(app)/ch/[channel]/+page.svelte | 8 | ||||
| -rw-r--r-- | ui/routes/(app)/me/+page.svelte | 46 | ||||
| -rw-r--r-- | ui/routes/(login)/invite/[invite]/+page.js | 2 | ||||
| -rw-r--r-- | ui/routes/(login)/invite/[invite]/+page.svelte | 49 | ||||
| -rw-r--r-- | ui/routes/(login)/login/+page.svelte | 33 | ||||
| -rw-r--r-- | ui/routes/(login)/setup/+page.svelte | 33 | ||||
| -rw-r--r-- | ui/routes/+layout.svelte | 58 |
21 files changed, 518 insertions, 468 deletions
diff --git a/ui/lib/apiServer.js b/ui/lib/apiServer.js index 5c6e5ef..3714b63 100644 --- a/ui/lib/apiServer.js +++ b/ui/lib/apiServer.js @@ -2,122 +2,124 @@ import axios from 'axios'; import { channelsList, logins, messages } from '$lib/store'; export const apiServer = axios.create({ - baseURL: '/api/', - validateStatus: () => true, + baseURL: '/api/', + validateStatus: () => true }); export async function boot() { - return apiServer.get('/boot'); + return apiServer.get('/boot'); } export async function setup(name, password) { - return apiServer.post('/setup', { name, password }); + return apiServer.post('/setup', { name, password }); } export async function logIn(name, password) { - return apiServer.post('/auth/login', { name, password }); + return apiServer.post('/auth/login', { name, password }); } export async function logOut() { - return apiServer.post('/auth/logout', {}); + return apiServer.post('/auth/logout', {}); } export async function changePassword(password, to) { - return apiServer.post('/password', { password, to }); + return apiServer.post('/password', { password, to }); } export async function createChannel(name) { - return apiServer.post('/channels', { name }); + return apiServer.post('/channels', { name }); } export async function postToChannel(channelId, body) { - return apiServer.post(`/channels/${channelId}`, { body }); + return apiServer.post(`/channels/${channelId}`, { body }); } export async function deleteMessage(messageId) { - // TODO + // TODO } export async function createInvite() { - return apiServer.post(`/invite`, {}); + return apiServer.post(`/invite`, {}); } export async function getInvite(inviteId) { - return apiServer.get(`/invite/${inviteId}`); + return apiServer.get(`/invite/${inviteId}`); } export async function acceptInvite(inviteId, username, password) { - const data = { - name: username, - password, - }; - return apiServer.post(`/invite/${inviteId}`, data); + const data = { + name: username, + password + }; + return apiServer.post(`/invite/${inviteId}`, data); } export function subscribeToEvents(resume_point) { - const eventsUrl = new URL('/api/events', window.location); - eventsUrl.searchParams.append('resume_point', resume_point); - const evtSource = new EventSource(eventsUrl.toString()); - // TODO: this should process all incoming events and store them. - // TODO: eventually we'll need to handle expiring old info, so as not to use - // infinite browser memory. - /* - * Known message types as of now: - * - created: a channel is created. - * - action: ignore. - * - message: a message is created. - * - action: display message in channel. - * - message_deleted: a message is deleted. - * - action: replace message with <...>. - * - deleted: a channel is deleted. - * - action: remove channel from sidebar. - */ - evtSource.onmessage = (evt) => { - const data = JSON.parse(evt.data); - - switch (data.type) { - case 'login': - onLoginEvent(data); - break; - case 'channel': - onChannelEvent(data); - break; - case 'message': - onMessageEvent(data); - break; - } - } - - return evtSource; + const eventsUrl = new URL('/api/events', window.location); + eventsUrl.searchParams.append('resume_point', resume_point); + const evtSource = new EventSource(eventsUrl.toString()); + // TODO: this should process all incoming events and store them. + // TODO: eventually we'll need to handle expiring old info, so as not to use + // infinite browser memory. + /* + * Known message types as of now: + * - created: a channel is created. + * - action: ignore. + * - message: a message is created. + * - action: display message in channel. + * - message_deleted: a message is deleted. + * - action: replace message with <...>. + * - deleted: a channel is deleted. + * - action: remove channel from sidebar. + */ + evtSource.onmessage = (evt) => { + const data = JSON.parse(evt.data); + + switch (data.type) { + case 'login': + onLoginEvent(data); + break; + case 'channel': + onChannelEvent(data); + break; + case 'message': + onMessageEvent(data); + break; + } + }; + + return evtSource; } function onLoginEvent(data) { - switch (data.event) { - case 'created': - logins.update((value) => value.addLogin(data.id, data.name)) - break; - } + switch (data.event) { + case 'created': + logins.update((value) => value.addLogin(data.id, data.name)); + break; + } } function onChannelEvent(data) { - switch (data.event) { - case 'created': - channelsList.update((value) => value.addChannel(data.id, data.name)) - break; - case 'deleted': - channelsList.update((value) => value.deleteChannel(data.id)); - messages.update((value) => value.deleteChannel(data.id)); - break; - } + switch (data.event) { + case 'created': + channelsList.update((value) => value.addChannel(data.id, data.name)); + break; + case 'deleted': + channelsList.update((value) => value.deleteChannel(data.id)); + messages.update((value) => value.deleteChannel(data.id)); + break; + } } function onMessageEvent(data) { - switch (data.event) { - case 'sent': - messages.update((value) => value.addMessage(data.channel, data.id, data.at, data.sender, data.body)); - break; - case 'deleted': - messages.update((value) => value.deleteMessage(data.id)); - break; - } + switch (data.event) { + case 'sent': + messages.update((value) => + value.addMessage(data.channel, data.id, data.at, data.sender, data.body) + ); + break; + case 'deleted': + messages.update((value) => value.deleteMessage(data.id)); + break; + } } diff --git a/ui/lib/components/ActiveChannel.svelte b/ui/lib/components/ActiveChannel.svelte index 76bf13a..212048a 100644 --- a/ui/lib/components/ActiveChannel.svelte +++ b/ui/lib/components/ActiveChannel.svelte @@ -1,42 +1,42 @@ <script> - import { messages } from '$lib/store'; - import MessageRun from './MessageRun.svelte'; + import { messages } from '$lib/store'; + import MessageRun from './MessageRun.svelte'; - export let channel = null; - $: messageList = channel !== null ? $messages.inChannel(channel) : []; + export let channel = null; + $: messageList = channel !== null ? $messages.inChannel(channel) : []; - function *chunkBy(xs, fn) { - let chunk; - let key; - for (let x of xs) { - let newKey = fn(x); - if (key !== newKey) { - if (chunk !== undefined) { - yield [key, chunk]; - } + function* chunkBy(xs, fn) { + let chunk; + let key; + for (let x of xs) { + let newKey = fn(x); + if (key !== newKey) { + if (chunk !== undefined) { + yield [key, chunk]; + } - chunk = [x]; - key = newKey; - } else { - chunk.push(x); - } - } - if (chunk !== undefined) { - yield [key, chunk]; - } - } + chunk = [x]; + key = newKey; + } else { + chunk.push(x); + } + } + if (chunk !== undefined) { + yield [key, chunk]; + } + } </script> <div class="container"> - {#each chunkBy(messageList, msg => msg.sender) as [sender, messages]} - <div> - <MessageRun {sender} {messages} /> - </div> - {/each} + {#each chunkBy(messageList, (msg) => msg.sender) as [sender, messages]} + <div> + <MessageRun {sender} {messages} /> + </div> + {/each} </div> <style> - .container { - overflow: auto; - } + .container { + overflow: auto; + } </style> diff --git a/ui/lib/components/Channel.svelte b/ui/lib/components/Channel.svelte index bbe9ff7..60c9092 100644 --- a/ui/lib/components/Channel.svelte +++ b/ui/lib/components/Channel.svelte @@ -1,21 +1,18 @@ <script> - import { showMenu } from '$lib/store'; + import { showMenu } from '$lib/store'; - export let id; - export let name; - export let active = false; + export let id; + export let name; + export let active = false; - function hideMenu() { - showMenu.update(() => false); - } + function hideMenu() { + showMenu.update(() => false); + } </script> -<li - class="rounded-full" - class:bg-slate-400={active} -> -<a href="/ch/{id}" on:click={hideMenu}> - <span class="badge bg-primary-500">#</span> - <span class="flex-auto">{name}</span> -</a> +<li class="rounded-full" class:bg-slate-400={active}> + <a href="/ch/{id}" on:click={hideMenu}> + <span class="badge bg-primary-500">#</span> + <span class="flex-auto">{name}</span> + </a> </li> diff --git a/ui/lib/components/ChannelList.svelte b/ui/lib/components/ChannelList.svelte index 316e404..f7376c1 100644 --- a/ui/lib/components/ChannelList.svelte +++ b/ui/lib/components/ChannelList.svelte @@ -1,16 +1,16 @@ <script> - import { channelsList } from '$lib/store'; - import Channel from './Channel.svelte'; + import { channelsList } from '$lib/store'; + import Channel from './Channel.svelte'; - export let active = null; + export let active = null; - $: channels = $channelsList.channels; + $: channels = $channelsList.channels; </script> <nav class="list-nav"> - <ul> - {#each channels as channel} - <Channel {...channel} active={active === channel.id} /> - {/each} - </ul> + <ul> + {#each channels as channel} + <Channel {...channel} active={active === channel.id} /> + {/each} + </ul> </nav> diff --git a/ui/lib/components/CreateChannelForm.svelte b/ui/lib/components/CreateChannelForm.svelte index b716736..6b50fb1 100644 --- a/ui/lib/components/CreateChannelForm.svelte +++ b/ui/lib/components/CreateChannelForm.svelte @@ -1,23 +1,29 @@ <script> - import { createChannel } from '$lib/apiServer'; + import { createChannel } from '$lib/apiServer'; - let name = ""; - let pending = false; - $: disabled = pending; + let name = ''; + let pending = false; + $: disabled = pending; - async function handleSubmit(event) { - pending = true; - const response = await createChannel(name); - if (200 <= response.status && response.status < 300) { - name = ''; - } - pending = false; - } + async function handleSubmit(event) { + pending = true; + const response = await createChannel(name); + if (200 <= response.status && response.status < 300) { + name = ''; + } + pending = false; + } </script> <form on:submit|preventDefault={handleSubmit} class="form form-row flex-nowrap"> - <input type="text" placeholder="create channel" bind:value={name} disabled={disabled} class="input flex-auto h-6 w-9/12" /> - <button type="submit" class="flex-none w-6 h-6">➕</button> + <input + type="text" + placeholder="create channel" + bind:value={name} + {disabled} + class="input flex-auto h-6 w-9/12" + /> + <button type="submit" class="flex-none w-6 h-6">➕</button> </form> <style> diff --git a/ui/lib/components/CurrentUser.svelte b/ui/lib/components/CurrentUser.svelte index 4b1b974..97ff980 100644 --- a/ui/lib/components/CurrentUser.svelte +++ b/ui/lib/components/CurrentUser.svelte @@ -1,25 +1,24 @@ <script> - import { goto } from '$app/navigation'; - import { logOut} from '$lib/apiServer'; - import { currentUser } from '$lib/store'; + import { goto } from '$app/navigation'; + import { logOut } from '$lib/apiServer'; + import { currentUser } from '$lib/store'; - async function handleLogout() { - const response = await logOut(); - if (200 <= response.status && response.status < 300) { - currentUser.update(() => null); - goto('/login'); - } - } + async function handleLogout() { + const response = await logOut(); + if (200 <= response.status && response.status < 300) { + currentUser.update(() => null); + goto('/login'); + } + } </script> <form on:submit|preventDefault={handleLogout}> - {#if $currentUser} - <a href="/me">@{$currentUser.username}</a> - {/if} - <button - class="border-slate-500 border-solid border-2 font-bold p-1 rounded" - type="submit" - >log out</button> + {#if $currentUser} + <a href="/me">@{$currentUser.username}</a> + {/if} + <button class="border-slate-500 border-solid border-2 font-bold p-1 rounded" type="submit" + >log out</button + > </form> <style> diff --git a/ui/lib/components/Invite.svelte b/ui/lib/components/Invite.svelte index 7fdc753..ea8dd1d 100644 --- a/ui/lib/components/Invite.svelte +++ b/ui/lib/components/Invite.svelte @@ -7,7 +7,6 @@ <button class="border-slate-500 border-solid border-2 font-bold p-1 rounded" - use:clipboard={inviteUrl}>Copy</button> + use:clipboard={inviteUrl}>Copy</button +> <span data-clipboard="inviteUrl">{inviteUrl}</span> - - diff --git a/ui/lib/components/Invites.svelte b/ui/lib/components/Invites.svelte index df51afb..bfaf2b6 100644 --- a/ui/lib/components/Invites.svelte +++ b/ui/lib/components/Invites.svelte @@ -4,25 +4,21 @@ import Invite from '$lib/components/Invite.svelte'; let invites = writable([]); - $: $invites, console.log("invites", $invites); + $: $invites, console.log('invites', $invites); async function onSubmit() { let response = await createInvite(); if (response.status == 200) { - invites.update(val => [...val, response.data]); + invites.update((val) => [...val, response.data]); } } </script> <ul> {#each $invites as invite} - <li><Invite id={invite.id} /></li> + <li><Invite id={invite.id} /></li> {/each} </ul> <form on:submit|preventDefault={onSubmit}> - <button - class="btn variant-filled" - type="submit"> - Create Invitation - </button> + <button class="btn variant-filled" type="submit"> Create Invitation </button> </form> diff --git a/ui/lib/components/LogIn.svelte b/ui/lib/components/LogIn.svelte index bb80ccd..4346c47 100644 --- a/ui/lib/components/LogIn.svelte +++ b/ui/lib/components/LogIn.svelte @@ -1,22 +1,36 @@ <script> - export let disabled = false; - export let username = ''; - export let password = ''; - export let legend = 'sign in'; + export let disabled = false; + export let username = ''; + export let password = ''; + export let legend = 'sign in'; </script> <div class="card m-4 p-4"> - <form on:submit|preventDefault> - <label class="label" for="username"> - username - <input class="input" name="username" type="text" placeholder="username" bind:value={username} disabled={disabled}> - </label> - <label class="label" for="password"> - password - <input class="input" name="password" type="password" placeholder="password" bind:value={password} disabled={disabled}> - </label> - <button class="btn variant-filled" type="submit"> - {legend} - </button> - </form> + <form on:submit|preventDefault> + <label class="label" for="username"> + username + <input + class="input" + name="username" + type="text" + placeholder="username" + bind:value={username} + {disabled} + /> + </label> + <label class="label" for="password"> + password + <input + class="input" + name="password" + type="password" + placeholder="password" + bind:value={password} + {disabled} + /> + </label> + <button class="btn variant-filled" type="submit"> + {legend} + </button> + </form> </div> diff --git a/ui/lib/components/Message.svelte b/ui/lib/components/Message.svelte index b71cf3c..9376cbe 100644 --- a/ui/lib/components/Message.svelte +++ b/ui/lib/components/Message.svelte @@ -1,33 +1,33 @@ <script> - import { marked } from 'marked'; - import DOMPurify from 'dompurify'; + import { marked } from 'marked'; + import DOMPurify from 'dompurify'; - export let at; - export let body; + export let at; + export let body; - $: renderedBody = DOMPurify.sanitize(marked.parse(body)); + $: renderedBody = DOMPurify.sanitize(marked.parse(body)); - let scroll = (message) => { - message.scrollIntoView(); - } + let scroll = (message) => { + message.scrollIntoView(); + }; </script> <div class="message relative"> - <span class="timestamp chip variant-soft absolute top-0 right-0">{at}</span> - <section use:scroll class="py-1 message-body"> - {@html renderedBody} - </section> + <span class="timestamp chip variant-soft absolute top-0 right-0">{at}</span> + <section use:scroll class="py-1 message-body"> + {@html renderedBody} + </section> </div> <style> - .message .timestamp { - display: none; - } - .message:hover .timestamp { - display: flex; - } - .message-body:empty:after { - content: "."; - visibility: hidden; - } + .message .timestamp { + display: none; + } + .message:hover .timestamp { + display: flex; + } + .message-body:empty:after { + content: '.'; + visibility: hidden; + } </style> diff --git a/ui/lib/components/MessageInput.svelte b/ui/lib/components/MessageInput.svelte index 03ac7fa..7aac442 100644 --- a/ui/lib/components/MessageInput.svelte +++ b/ui/lib/components/MessageInput.svelte @@ -1,28 +1,38 @@ <script> - import { tick } from 'svelte'; - import { postToChannel } from '$lib/apiServer'; + import { tick } from 'svelte'; + import { postToChannel } from '$lib/apiServer'; - export let channel = null; - let input; - let value = ''; - let pending = false; + export let channel = null; + let input; + let value = ''; + let pending = false; - $: disabled = pending || (channel === null); + $: disabled = pending || channel === null; - async function handleSubmit() { - if (channel !== null) { - pending = true; - // TODO try/catch: - await postToChannel(channel, value); - pending = false; - value = ''; - await tick(); - input.focus(); - } - } + async function handleSubmit() { + if (channel !== null) { + pending = true; + // TODO try/catch: + await postToChannel(channel, value); + pending = false; + value = ''; + await tick(); + input.focus(); + } + } </script> <form on:submit|preventDefault={handleSubmit} class="flex flex-row flex-nowrap"> - <input bind:this={input} bind:value={value} disabled={disabled} type="search" class="flex-auto h-6 input rounded-r-none" /> - <button color="primary variant-filled-secondary" type="submit" class="flex-none w-6 h-6 btn-icon variant-filled rounded-l-none">»</button> + <input + bind:this={input} + bind:value + {disabled} + type="search" + class="flex-auto h-6 input rounded-r-none" + /> + <button + color="primary variant-filled-secondary" + type="submit" + class="flex-none w-6 h-6 btn-icon variant-filled rounded-l-none">»</button + > </form> diff --git a/ui/lib/components/MessageRun.svelte b/ui/lib/components/MessageRun.svelte index af699ab..4894885 100644 --- a/ui/lib/components/MessageRun.svelte +++ b/ui/lib/components/MessageRun.svelte @@ -1,23 +1,24 @@ <script> - import { logins, currentUser } from '$lib/store'; - import Message from '$lib/components/Message.svelte'; + import { logins, currentUser } from '$lib/store'; + import Message from '$lib/components/Message.svelte'; - export let sender; - export let messages; + export let sender; + export let messages; - let name; - $: name = $logins.get(sender); - $: ownMessage = $currentUser.id == sender; + let name; + $: name = $logins.get(sender); + $: ownMessage = $currentUser.id == sender; </script> <div - class="card card-hover m-4 px-4 py-1 relative" - class:own-message={ownMessage} - class:other-message={!ownMessage}> - <span class="chip variant-soft sticky top-o left-0"> - @{name}: - </span> - {#each messages as { at, body }} - <Message {at} {body} /> - {/each} + class="card card-hover m-4 px-4 py-1 relative" + class:own-message={ownMessage} + class:other-message={!ownMessage} +> + <span class="chip variant-soft sticky top-o left-0"> + @{name}: + </span> + {#each messages as { at, body }} + <Message {at} {body} /> + {/each} </div> diff --git a/ui/lib/store/messages.js b/ui/lib/store/messages.js index 7d1fbe1..884b296 100644 --- a/ui/lib/store/messages.js +++ b/ui/lib/store/messages.js @@ -4,7 +4,7 @@ export class Messages { } inChannel(channel) { - return this.channels[channel] = (this.channels[channel] || []); + return (this.channels[channel] = this.channels[channel] || []); } addMessage(channel, id, at, sender, body) { @@ -15,12 +15,11 @@ export class Messages { setMessages(messages) { this.channels = {}; for (let { channel, id, at, sender, body } of messages) { - this.inChannel(channel).push({ id, at, sender, body, }); + this.inChannel(channel).push({ id, at, sender, body }); } return this; } - deleteMessage(message) { for (let channel in this.channels) { this.updateChannel(channel, (messages) => messages.filter((msg) => msg.id != message)); diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte index ae80324..9843979 100644 --- a/ui/routes/(app)/+layout.svelte +++ b/ui/routes/(app)/+layout.svelte @@ -1,145 +1,147 @@ <script> - import { page } from '$app/stores'; - import { goto } from '$app/navigation'; + import { page } from '$app/stores'; + import { goto } from '$app/navigation'; import { onMount, onDestroy } from 'svelte'; import { boot, subscribeToEvents } from '$lib/apiServer'; import { showMenu, currentUser, logins, channelsList, messages } from '$lib/store'; - import ChannelList from '$lib/components/ChannelList.svelte'; - import CreateChannelForm from '$lib/components/CreateChannelForm.svelte'; - import MessageInput from '$lib/components/MessageInput.svelte'; - - let loading = true; - let events = null; - let showMenuValue; - showMenu.subscribe((value) => { - showMenuValue = value; - }); + import ChannelList from '$lib/components/ChannelList.svelte'; + import CreateChannelForm from '$lib/components/CreateChannelForm.svelte'; + import MessageInput from '$lib/components/MessageInput.svelte'; + let loading = true; + let events = null; + let showMenuValue; + showMenu.subscribe((value) => { + showMenuValue = value; + }); - function toggleMenu() { - showMenu.update((value) => !value); - } + function toggleMenu() { + showMenu.update((value) => !value); + } - $: channel = $page?.params?.channel; + $: channel = $page?.params?.channel; - function onBooted(boot) { - currentUser.update(() => ({ - id: boot.login.id, - username: boot.login.name, - })); - logins.update((value) => value.setLogins(boot.logins)); - channelsList.update((value) => value.setChannels(boot.channels)); - messages.update((value) => value.setMessages(boot.messages)); - } + function onBooted(boot) { + currentUser.update(() => ({ + id: boot.login.id, + username: boot.login.name + })); + logins.update((value) => value.setLogins(boot.logins)); + channelsList.update((value) => value.setChannels(boot.channels)); + messages.update((value) => value.setMessages(boot.messages)); + } onMount(async () => { - let response = await boot(); - switch (response.status) { - case 200: - onBooted(response.data); - events = subscribeToEvents(response.data.resume_point); - break; - case 401: - currentUser.update(() => null); - goto('/login'); - break; - case 503: - currentUser.update(() => null); - goto('/setup'); - break; - default: - // TODO: display error. - break; - } - loading = false; + let response = await boot(); + switch (response.status) { + case 200: + onBooted(response.data); + events = subscribeToEvents(response.data.resume_point); + break; + case 401: + currentUser.update(() => null); + goto('/login'); + break; + case 503: + currentUser.update(() => null); + goto('/setup'); + break; + default: + // TODO: display error. + break; + } + loading = false; }); - onDestroy(async () => { - if (events !== null) { - events.close(); - } - }); + onDestroy(async () => { + if (events !== null) { + events.close(); + } + }); </script> <svelte:head> - <title>understory</title> + <title>understory</title> </svelte:head> {#if loading} - <h2>Loading…</h2> + <h2>Loading…</h2> {:else} - <div id="interface" class="p-2"> - <nav id="sidebar" data-expanded={showMenuValue}> - <div class="channel-list"> - <ChannelList active={channel} /> - </div> - <div class="create-channel"> - <CreateChannelForm /> - </div> - </nav> - <main> - <div class="active-channel"> - <slot /> - </div> - <div class="create-message max-h-full"> - <MessageInput {channel} /> - </div> - </main> - </div> + <div id="interface" class="p-2"> + <nav id="sidebar" data-expanded={showMenuValue}> + <div class="channel-list"> + <ChannelList active={channel} /> + </div> + <div class="create-channel"> + <CreateChannelForm /> + </div> + </nav> + <main> + <div class="active-channel"> + <slot /> + </div> + <div class="create-message max-h-full"> + <MessageInput {channel} /> + </div> + </main> + </div> {/if} <style> -:root { - --app-bar-height: 68px; - --input-row-height: 2rem; - --interface-padding: 16px; -} + :root { + --app-bar-height: 68px; + --input-row-height: 2rem; + --interface-padding: 16px; + } -#interface { - margin: unset; - display: grid; - grid-template: - 'side main' 1fr - / auto 1fr - ; - height: calc(100vh - var(--app-bar-height)); + #interface { + margin: unset; + display: grid; + grid-template: + 'side main' 1fr + / auto 1fr; + height: calc(100vh - var(--app-bar-height)); - @media (width > 640px) { - --overlay: static; - --translate: 0; - } -} -nav { - grid-area: side; - background-color: rgb(var(--color-surface-800)); - inset: auto auto 0 0; - padding: 0.25rem; - position: var(--overlay, absolute); - transition: translate 300ms ease-out; - width: 21rem; - height: calc(100vh - var(--app-bar-height) - var(--interface-padding)); - z-index: 10; -} -nav button { - position: absolute; - top: 0; - right: 0; -} -main { - grid-area: main; - height: calc(100vh - var(--app-bar-height) - var(--interface-padding)); -} -.active-channel { - height: calc(100vh - var(--app-bar-height) - var(--interface-padding) - var(--input-row-height)); - overflow: auto; -} -.channel-list { - height: calc(100vh - var(--app-bar-height) - var(--interface-padding) - var(--input-row-height)); - overflow: auto; -} -nav[data-expanded=false] { - translate: var(--translate, -100% 0); -} + @media (width > 640px) { + --overlay: static; + --translate: 0; + } + } + nav { + grid-area: side; + background-color: rgb(var(--color-surface-800)); + inset: auto auto 0 0; + padding: 0.25rem; + position: var(--overlay, absolute); + transition: translate 300ms ease-out; + width: 21rem; + height: calc(100vh - var(--app-bar-height) - var(--interface-padding)); + z-index: 10; + } + nav button { + position: absolute; + top: 0; + right: 0; + } + main { + grid-area: main; + height: calc(100vh - var(--app-bar-height) - var(--interface-padding)); + } + .active-channel { + height: calc( + 100vh - var(--app-bar-height) - var(--interface-padding) - var(--input-row-height) + ); + overflow: auto; + } + .channel-list { + height: calc( + 100vh - var(--app-bar-height) - var(--interface-padding) - var(--input-row-height) + ); + overflow: auto; + } + nav[data-expanded='false'] { + translate: var(--translate, -100% 0); + } </style> diff --git a/ui/routes/(app)/ch/[channel]/+page.svelte b/ui/routes/(app)/ch/[channel]/+page.svelte index 7bd28d9..74ad28b 100644 --- a/ui/routes/(app)/ch/[channel]/+page.svelte +++ b/ui/routes/(app)/ch/[channel]/+page.svelte @@ -1,10 +1,10 @@ <script> - import { page } from '$app/stores'; - import ActiveChannel from '$lib/components/ActiveChannel.svelte'; + import { page } from '$app/stores'; + import ActiveChannel from '$lib/components/ActiveChannel.svelte'; - $: channel = $page?.params?.channel; + $: channel = $page?.params?.channel; </script> <div class="active-channel"> - <ActiveChannel {channel} /> + <ActiveChannel {channel} /> </div> diff --git a/ui/routes/(app)/me/+page.svelte b/ui/routes/(app)/me/+page.svelte index 82af3c7..26537ad 100644 --- a/ui/routes/(app)/me/+page.svelte +++ b/ui/routes/(app)/me/+page.svelte @@ -3,9 +3,12 @@ import Invites from '$lib/components/Invites.svelte'; - let currentPassword = "", newPassword = "", confirmPassword = "", passwordForm; + let currentPassword = '', + newPassword = '', + confirmPassword = '', + passwordForm; let pending = false; - $: valid = (newPassword === confirmPassword) && (newPassword !== currentPassword); + $: valid = newPassword === confirmPassword && newPassword !== currentPassword; $: disabled = pending || !valid; async function onPasswordChange() { @@ -20,22 +23,41 @@ } </script> -<form on:submit|preventDefault={onPasswordChange} bind:this={passwordForm} > - <label>current password - <input class="input" name="currentPassword" type="password" placeholder="password" bind:value={currentPassword}> +<form on:submit|preventDefault={onPasswordChange} bind:this={passwordForm}> + <label + >current password + <input + class="input" + name="currentPassword" + type="password" + placeholder="password" + bind:value={currentPassword} + /> </label> - <label>new password - <input class="input" name="newPassword" type="password" placeholder="password" bind:value={newPassword}> + <label + >new password + <input + class="input" + name="newPassword" + type="password" + placeholder="password" + bind:value={newPassword} + /> </label> - <label>confirm new password - <input class="input" name="confirmPassword" type="password" placeholder="password" bind:value={confirmPassword}> + <label + >confirm new password + <input + class="input" + name="confirmPassword" + type="password" + placeholder="password" + bind:value={confirmPassword} + /> </label> - <button class="btn variant-filled" type="submit" disabled={disabled}> - change password - </button> + <button class="btn variant-filled" type="submit" {disabled}> change password </button> </form> <Invites /> diff --git a/ui/routes/(login)/invite/[invite]/+page.js b/ui/routes/(login)/invite/[invite]/+page.js index e6664d2..ced109a 100644 --- a/ui/routes/(login)/invite/[invite]/+page.js +++ b/ui/routes/(login)/invite/[invite]/+page.js @@ -5,7 +5,7 @@ export async function load({ params }) { let response = await getInvite(invite); switch (response.status) { case 200: - let invite = response.data + let invite = response.data; return { invite }; break; case 404: diff --git a/ui/routes/(login)/invite/[invite]/+page.svelte b/ui/routes/(login)/invite/[invite]/+page.svelte index 7ae388a..8f4d1a4 100644 --- a/ui/routes/(login)/invite/[invite]/+page.svelte +++ b/ui/routes/(login)/invite/[invite]/+page.svelte @@ -1,34 +1,35 @@ <script> - import { goto } from '$app/navigation'; - import { acceptInvite } from '$lib/apiServer'; + import { goto } from '$app/navigation'; + import { acceptInvite } from '$lib/apiServer'; - import LogIn from '$lib/components/LogIn.svelte'; + import LogIn from '$lib/components/LogIn.svelte'; - export let data; + export let data; - let username = "", password = ""; - let pending = false; - $: disabled = pending; + let username = '', + password = ''; + let pending = false; + $: disabled = pending; - async function onSubmit() { - pending = true; - const response = await acceptInvite(data.invite.id, username, password); - if (200 <= response.status && response.status < 300) { - username = ''; - password = ''; - goto('/'); - } - pending = false; - } + async function onSubmit() { + pending = true; + const response = await acceptInvite(data.invite.id, username, password); + if (200 <= response.status && response.status < 300) { + username = ''; + password = ''; + goto('/'); + } + pending = false; + } </script> {#await data} -<div class="card m-4 p-4"> - <p>Loading invitation…</p> -</div> + <div class="card m-4 p-4"> + <p>Loading invitation…</p> + </div> {:then { invite }} -<div class="card m-4 p-4"> - <p>Hi there! {invite.issuer} invites you to the conversation.</p> -</div> -<LogIn bind:disabled bind:username bind:password on:submit={onSubmit} /> + <div class="card m-4 p-4"> + <p>Hi there! {invite.issuer} invites you to the conversation.</p> + </div> + <LogIn bind:disabled bind:username bind:password on:submit={onSubmit} /> {/await} diff --git a/ui/routes/(login)/login/+page.svelte b/ui/routes/(login)/login/+page.svelte index 0387e4a..dba7f5a 100644 --- a/ui/routes/(login)/login/+page.svelte +++ b/ui/routes/(login)/login/+page.svelte @@ -1,23 +1,24 @@ <script> - import { goto } from '$app/navigation'; - import { logIn } from '$lib/apiServer'; + import { goto } from '$app/navigation'; + import { logIn } from '$lib/apiServer'; - import LogIn from '$lib/components/LogIn.svelte'; + import LogIn from '$lib/components/LogIn.svelte'; - let username = "", password = ""; - let pending = false; - $: disabled = pending; + let username = '', + password = ''; + let pending = false; + $: disabled = pending; - async function onSubmit() { - pending = true; - const response = await logIn(username, password); - if (200 <= response.status && response.status < 300) { - username = ''; - password = ''; - goto('/'); - } - pending = false; - } + async function onSubmit() { + pending = true; + const response = await logIn(username, password); + if (200 <= response.status && response.status < 300) { + username = ''; + password = ''; + goto('/'); + } + pending = false; + } </script> <LogIn bind:disabled bind:username bind:password on:submit={onSubmit} /> diff --git a/ui/routes/(login)/setup/+page.svelte b/ui/routes/(login)/setup/+page.svelte index a1974b8..2f098ef 100644 --- a/ui/routes/(login)/setup/+page.svelte +++ b/ui/routes/(login)/setup/+page.svelte @@ -1,23 +1,24 @@ <script> - import { goto } from '$app/navigation'; - import { setup } from '$lib/apiServer'; + import { goto } from '$app/navigation'; + import { setup } from '$lib/apiServer'; - import LogIn from '$lib/components/LogIn.svelte'; + import LogIn from '$lib/components/LogIn.svelte'; - let username = "", password = ""; - let pending = false; - $: disabled = pending; + let username = '', + password = ''; + let pending = false; + $: disabled = pending; - async function onSubmit() { - pending = true; - const response = await setup(username, password); - if (200 <= response.status && response.status < 300) { - username = ''; - password = ''; - goto('/'); - } - pending = false; - } + async function onSubmit() { + pending = true; + const response = await setup(username, password); + if (200 <= response.status && response.status < 300) { + username = ''; + password = ''; + goto('/'); + } + pending = false; + } </script> <LogIn bind:disabled bind:username bind:password legend="set up" on:submit={onSubmit} /> diff --git a/ui/routes/+layout.svelte b/ui/routes/+layout.svelte index a86a7e8..22377bb 100644 --- a/ui/routes/+layout.svelte +++ b/ui/routes/+layout.svelte @@ -1,41 +1,41 @@ <script> - import "../app.css"; - import logo from '$lib/assets/logo.png'; + import '../app.css'; + import logo from '$lib/assets/logo.png'; - import { AppBar } from '@skeletonlabs/skeleton'; - import { showMenu, currentUser } from '$lib/store'; + import { AppBar } from '@skeletonlabs/skeleton'; + import { showMenu, currentUser } from '$lib/store'; - import CurrentUser from '$lib/components/CurrentUser.svelte'; + import CurrentUser from '$lib/components/CurrentUser.svelte'; - function toggleMenu() { - showMenu.update((value) => !value); - } + function toggleMenu() { + showMenu.update((value) => !value); + } </script> <div id="app" class="m-0 p-0 h-vh w-full"> - <div class="w-full"> - <AppBar class="app-bar"> - <svelte:fragment slot="lead"> - <a on:click|preventDefault={toggleMenu} class="cursor-pointer"> - <img class="w-8 h-8" alt="logo" src={logo} /> - </a> - </svelte:fragment> - <a href="/">understory</a> - <svelte:fragment slot="trail"> - {#if $currentUser} - <CurrentUser /> - {/if} - </svelte:fragment> - </AppBar> - </div> + <div class="w-full"> + <AppBar class="app-bar"> + <svelte:fragment slot="lead"> + <a on:click|preventDefault={toggleMenu} class="cursor-pointer"> + <img class="w-8 h-8" alt="logo" src={logo} /> + </a> + </svelte:fragment> + <a href="/">understory</a> + <svelte:fragment slot="trail"> + {#if $currentUser} + <CurrentUser /> + {/if} + </svelte:fragment> + </AppBar> + </div> - <slot /> + <slot /> </div> <style> - #app { - margin: 0; - height: 100vh; - width: 100%; - } + #app { + margin: 0; + height: 100vh; + width: 100%; + } </style> |
