summaryrefslogtreecommitdiff
path: root/ui/routes
diff options
context:
space:
mode:
Diffstat (limited to 'ui/routes')
-rw-r--r--ui/routes/(app)/+layout.svelte238
-rw-r--r--ui/routes/(app)/ch/[channel]/+page.svelte8
-rw-r--r--ui/routes/(app)/me/+page.svelte46
-rw-r--r--ui/routes/(login)/invite/[invite]/+page.js2
-rw-r--r--ui/routes/(login)/invite/[invite]/+page.svelte49
-rw-r--r--ui/routes/(login)/login/+page.svelte33
-rw-r--r--ui/routes/(login)/setup/+page.svelte33
-rw-r--r--ui/routes/+layout.svelte58
8 files changed, 247 insertions, 220 deletions
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&hellip;</h2>
+ <h2>Loading&hellip;</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>