frontend: add simple settings menu
This commit is contained in:
parent
fb9fccb038
commit
34dc98af95
7 changed files with 116 additions and 2 deletions
|
@ -59,6 +59,15 @@
|
||||||
--radius-xxl: calc(5.25 * var(--sradius-unit));
|
--radius-xxl: calc(5.25 * var(--sradius-unit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-light {
|
||||||
|
--foreground-color-1: hsl(180, 11%, 7%);
|
||||||
|
--foreground-color-2: hsl(180, 11%, 12%);
|
||||||
|
--foreground-color-3: hsl(180, 11%, 17%);
|
||||||
|
--background-color-1: rgb(253, 254, 255);
|
||||||
|
--background-color-2: rgb(218, 219, 220);
|
||||||
|
--background-color-3: rgb(153, 154, 155);
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -210,6 +219,18 @@ body {
|
||||||
background-color: var(--purple-2);
|
background-color: var(--purple-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-red {
|
||||||
|
background-color: var(--red-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-red:hover {
|
||||||
|
background-color: var(--red-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-red:disabled {
|
||||||
|
background-color: var(--red-2);
|
||||||
|
}
|
||||||
|
|
||||||
.icon-button {
|
.icon-button {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
@ -19,4 +19,10 @@ export function authWithToken(token, shouldUpdate=false) {
|
||||||
gateway.init(token);
|
gateway.init(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function logOut() {
|
||||||
|
setAuthToken(null);
|
||||||
|
gateway.close();
|
||||||
|
gateway.dispatch(GatewayEventType.BadAuth, -1);
|
||||||
|
}
|
||||||
|
|
||||||
useAuthHandlers();
|
useAuthHandlers();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { HashIcon, PlusIcon, MoreVerticalIcon } from "svelte-feather-icons";
|
import { HashIcon, PlusIcon, MoreVerticalIcon, SettingsIcon } from "svelte-feather-icons";
|
||||||
import { quadInOut } from "svelte/easing";
|
import { quadInOut } from "svelte/easing";
|
||||||
import { fly } from "svelte/transition";
|
import { fly } from "svelte/transition";
|
||||||
import { channels, overlayStore, selectedChannel, showChannelView, showSidebar, smallViewport, userInfoStore } from "../stores";
|
import { channels, overlayStore, selectedChannel, showChannelView, showSidebar, smallViewport, userInfoStore } from "../stores";
|
||||||
|
@ -53,6 +53,12 @@
|
||||||
</div>
|
</div>
|
||||||
<span>Create Channel</span>
|
<span>Create Channel</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button on:click="{ () => overlayStore.open('settings') }" class="sidebar-button">
|
||||||
|
<div>
|
||||||
|
<SettingsIcon />
|
||||||
|
</div>
|
||||||
|
<span>Settings</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import Login from "./Login.svelte";
|
import Login from "./Login.svelte";
|
||||||
import CreateAccount from "./CreateAccount.svelte";
|
import CreateAccount from "./CreateAccount.svelte";
|
||||||
import EditMessage from "./EditMessage.svelte";
|
import EditMessage from "./EditMessage.svelte";
|
||||||
|
import Settings from "./Settings.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $overlayStore.createChannel}
|
{#if $overlayStore.createChannel}
|
||||||
|
@ -26,3 +27,6 @@
|
||||||
{#if $overlayStore.editMessage}
|
{#if $overlayStore.editMessage}
|
||||||
<EditMessage { ...$overlayStore.editMessage } />
|
<EditMessage { ...$overlayStore.editMessage } />
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $overlayStore.settings}
|
||||||
|
<Settings />
|
||||||
|
{/if}
|
||||||
|
|
63
frontend/src/components/overlays/Settings.svelte
Normal file
63
frontend/src/components/overlays/Settings.svelte
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<script>
|
||||||
|
import { fade, fly } from "svelte/transition";
|
||||||
|
import { quintInOut } from "svelte/easing";
|
||||||
|
import { AtSignIcon } from "svelte-feather-icons";
|
||||||
|
import { overlayStore, userInfoStore, smallViewport } from "../../stores";
|
||||||
|
import { logOut } from "../../auth";
|
||||||
|
|
||||||
|
const close = () => overlayStore.close("settings");
|
||||||
|
|
||||||
|
const doLogout = () => {
|
||||||
|
close();
|
||||||
|
logOut();
|
||||||
|
overlayStore.open("toast", {
|
||||||
|
message: "Logged out"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
margin-bottom: var(--space-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-account-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: left;
|
||||||
|
padding: var(--space-md);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
border: solid 1px var(--background-color-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.large-settings {
|
||||||
|
min-width: 540px;
|
||||||
|
min-height: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-logout-button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="modal-backdrop" transition:fade="{{ duration: 300, easing: quintInOut }}" on:click="{ close }">
|
||||||
|
<div class="modal" class:large-settings="{ !$smallViewport }" transition:fly="{{ duration: 300, easing: quintInOut, y: 10 }}" on:click|stopPropagation>
|
||||||
|
<span class="h4">Account</span>
|
||||||
|
|
||||||
|
<div class="separator" />
|
||||||
|
|
||||||
|
<div class="user-account-card full-width">
|
||||||
|
<AtSignIcon />
|
||||||
|
<span class="h5 top-bar-heading">{ $userInfoStore ? $userInfoStore.username : "" }</span>
|
||||||
|
<button class="button button-red inner-logout-button" on:click="{ doLogout }">Log Out</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="button modal-secondary-action" on:click="{ close }">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -47,6 +47,7 @@ export default {
|
||||||
reconnectDelay: 400,
|
reconnectDelay: 400,
|
||||||
reconnectTimeout: null,
|
reconnectTimeout: null,
|
||||||
handlers: new Map(),
|
handlers: new Map(),
|
||||||
|
disableReconnect: false,
|
||||||
init(token) {
|
init(token) {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
log("no auth token, skipping connection");
|
log("no auth token, skipping connection");
|
||||||
|
@ -59,6 +60,7 @@ export default {
|
||||||
if (this.reconnectTimeout) {
|
if (this.reconnectTimeout) {
|
||||||
clearTimeout(this.reconnectTimeout);
|
clearTimeout(this.reconnectTimeout);
|
||||||
}
|
}
|
||||||
|
this.disableReconnect = false;
|
||||||
this.open = true;
|
this.open = true;
|
||||||
this.dispatch(GatewayEventType.Open, null);
|
this.dispatch(GatewayEventType.Open, null);
|
||||||
log("open");
|
log("open");
|
||||||
|
@ -109,6 +111,9 @@ export default {
|
||||||
this.dispatch(GatewayEventType.BadAuth, 1);
|
this.dispatch(GatewayEventType.BadAuth, 1);
|
||||||
if (this.reconnectTimeout)
|
if (this.reconnectTimeout)
|
||||||
clearTimeout(this.reconnectTimeout);
|
clearTimeout(this.reconnectTimeout);
|
||||||
|
} else if (this.disableReconnect) {
|
||||||
|
if (this.reconnectTimeout)
|
||||||
|
clearTimeout(this.reconnectTimeout);
|
||||||
} else {
|
} else {
|
||||||
if (this.reconnectDelay < 60000) {
|
if (this.reconnectDelay < 60000) {
|
||||||
this.reconnectDelay *= 2;
|
this.reconnectDelay *= 2;
|
||||||
|
@ -155,5 +160,10 @@ export default {
|
||||||
if (eventHandlers.size < 1) {
|
if (eventHandlers.size < 1) {
|
||||||
this.handlers.delete(event);
|
this.handlers.delete(event);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.disableReconnect = true;
|
||||||
|
if (this.ws)
|
||||||
|
this.ws.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -193,6 +193,9 @@ class MessageStore extends Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
async doInitialLoad() {
|
async doInitialLoad() {
|
||||||
|
if (this.channelId === -1)
|
||||||
|
return;
|
||||||
|
|
||||||
await this.loadOlderMessages();
|
await this.loadOlderMessages();
|
||||||
this.didDoInitialLoad = true;
|
this.didDoInitialLoad = true;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +247,8 @@ class OverlayStore extends Store {
|
||||||
editChannel: null,
|
editChannel: null,
|
||||||
toast: null,
|
toast: null,
|
||||||
login: null,
|
login: null,
|
||||||
createAccount: null
|
createAccount: null,
|
||||||
|
settings: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue