greatly overhaul overlay system
This commit is contained in:
parent
d8552c0328
commit
4c9e321167
16 changed files with 117 additions and 117 deletions
|
@ -1,15 +1,15 @@
|
||||||
import gateway, { GatewayEventType } from "./gateway";
|
import gateway, { GatewayEventType } from "./gateway";
|
||||||
import { removeItem, setItem } from "./storage";
|
import { removeItem, setItem } from "./storage";
|
||||||
import { overlayStore } from "./stores";
|
import { overlayStore, OverlayType } from "./stores";
|
||||||
|
|
||||||
export function useAuthHandlers() {
|
export function useAuthHandlers() {
|
||||||
gateway.subscribe(GatewayEventType.Ready, () => {
|
gateway.subscribe(GatewayEventType.Ready, () => {
|
||||||
overlayStore.close("login");
|
overlayStore.popType(OverlayType.Login);
|
||||||
overlayStore.close("createAccount");
|
overlayStore.popType(OverlayType.CreateAccount);
|
||||||
});
|
});
|
||||||
|
|
||||||
gateway.subscribe(GatewayEventType.BadAuth, () => {
|
gateway.subscribe(GatewayEventType.BadAuth, () => {
|
||||||
overlayStore.open("login", {});
|
overlayStore.push(OverlayType.Login, {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { HashIcon, MenuIcon, UsersIcon } from "svelte-feather-icons";
|
import { HashIcon, MenuIcon, UsersIcon } from "svelte-feather-icons";
|
||||||
import { getItem } from "../storage";
|
import { getItem } from "../storage";
|
||||||
import { overlayStore, showPresenceSidebar, showSidebar } from "../stores";
|
import { overlayStore, OverlayType, showPresenceSidebar, showSidebar } from "../stores";
|
||||||
|
|
||||||
export let channel;
|
export let channel;
|
||||||
</script>
|
</script>
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
<HashIcon />
|
<HashIcon />
|
||||||
<span class="h5 top-bar-heading" on:click="{ () => overlayStore.open('editChannel', {channel}) }">{ channel.name }</span>
|
<span class="h5 top-bar-heading" on:click="{ () => overlayStore.push(OverlayType.EditChannel, {channel}) }">{ channel.name }</span>
|
||||||
<div class="right-buttons">
|
<div class="right-buttons">
|
||||||
<button class="icon-button" on:click="{ () => showPresenceSidebar.set(!showPresenceSidebar.value) }" aria-label="Toggle user list">
|
<button class="icon-button" on:click="{ () => showPresenceSidebar.set(!showPresenceSidebar.value) }" aria-label="Toggle user list">
|
||||||
<UsersIcon />
|
<UsersIcon />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { CornerUpLeftIcon, MoreVerticalIcon } from "svelte-feather-icons";
|
import { CornerUpLeftIcon, MoreVerticalIcon } from "svelte-feather-icons";
|
||||||
import { overlayStore, setMessageInputEvent, userInfoStore } from "../stores";
|
import { overlayStore, OverlayType, setMessageInputEvent, userInfoStore } from "../stores";
|
||||||
|
|
||||||
export let message;
|
export let message;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
<CornerUpLeftIcon />
|
<CornerUpLeftIcon />
|
||||||
</button>
|
</button>
|
||||||
{#if userInfoStore.value && (message.author_id === userInfoStore.value.id || userInfoStore.value.is_superuser)}
|
{#if userInfoStore.value && (message.author_id === userInfoStore.value.id || userInfoStore.value.is_superuser)}
|
||||||
<button class="icon-button edit-message" on:click="{ () => overlayStore.open('editMessage', { message }) }" aria-label="Edit Message">
|
<button class="icon-button edit-message" on:click="{ () => overlayStore.push(OverlayType.EditMessage, { message }) }" aria-label="Edit Message">
|
||||||
<MoreVerticalIcon />
|
<MoreVerticalIcon />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -71,9 +71,7 @@
|
||||||
messages.deleteMessage({
|
messages.deleteMessage({
|
||||||
id: optimisticMessageId
|
id: optimisticMessageId
|
||||||
});
|
});
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't send message");
|
||||||
message: "Couldn't send message"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { HashIcon, PlusIcon, MoreVerticalIcon, SettingsIcon, CloudIcon } from "svelte-feather-icons";
|
import { HashIcon, PlusIcon, MoreVerticalIcon, SettingsIcon, CloudIcon } from "svelte-feather-icons";
|
||||||
import { quadInOut } from "svelte/easing";
|
import { quadInOut } from "svelte/easing";
|
||||||
import { maybeFly, maybeFlyIf } from "../animations";
|
import { maybeFly, maybeFlyIf } from "../animations";
|
||||||
import { channels, gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore } from "../stores";
|
import { channels, gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore, OverlayType } from "../stores";
|
||||||
import UserTopBar from "./UserTopBar.svelte";
|
import UserTopBar from "./UserTopBar.svelte";
|
||||||
|
|
||||||
const selectChannel = (channel) => {
|
const selectChannel = (channel) => {
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<div class="unread-indicator">{ $unreadStore.get(channel.id) }</div>
|
<div class="unread-indicator">{ $unreadStore.get(channel.id) }</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $userInfoStore && (channel.owner_id === $userInfoStore.id || $userInfoStore.is_superuser)}
|
{#if $userInfoStore && (channel.owner_id === $userInfoStore.id || $userInfoStore.is_superuser)}
|
||||||
<button class="icon-button" on:click|stopPropagation="{ () => overlayStore.open('editChannel', { channel }) }" aria-label="Edit Channel">
|
<button class="icon-button" on:click|stopPropagation="{ () => overlayStore.push(OverlayType.EditChannel, { channel }) }" aria-label="Edit Channel">
|
||||||
<MoreVerticalIcon />
|
<MoreVerticalIcon />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -36,14 +36,14 @@
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
{#if $userInfoStore && $userInfoStore.permissions.create_channel}
|
{#if $userInfoStore && $userInfoStore.permissions.create_channel}
|
||||||
<button on:click="{ () => overlayStore.open('createChannel') }" class="sidebar-button">
|
<button on:click="{ () => overlayStore.push(OverlayType.CreateChannel) }" class="sidebar-button">
|
||||||
<div class="sidebar-button-icon">
|
<div class="sidebar-button-icon">
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
</div>
|
</div>
|
||||||
<span>Create Channel</span>
|
<span>Create Channel</span>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
<button on:click="{ () => overlayStore.open('settings') }" class="sidebar-button">
|
<button on:click="{ () => overlayStore.push(OverlayType.Settings) }" class="sidebar-button">
|
||||||
<div class="sidebar-button-icon">
|
<div class="sidebar-button-icon">
|
||||||
<SettingsIcon />
|
<SettingsIcon />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { overlayStore } from "../../stores";
|
import { overlayStore, OverlayType } from "../../stores";
|
||||||
import request from "../../request";
|
import request from "../../request";
|
||||||
import { apiRoute } from "../../storage";
|
import { apiRoute } from "../../storage";
|
||||||
import { maybeModalFly } from "../../animations";
|
import { maybeModalFly } from "../../animations";
|
||||||
|
@ -8,8 +8,8 @@
|
||||||
let password = "";
|
let password = "";
|
||||||
let buttonsEnabled = true;
|
let buttonsEnabled = true;
|
||||||
let pendingOtherOpen = false;
|
let pendingOtherOpen = false;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
const close = () => overlayStore.close('createAccount');
|
|
||||||
const create = async () => {
|
const create = async () => {
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
const { ok } = await request("POST", apiRoute("users/register"), false, {
|
const { ok } = await request("POST", apiRoute("users/register"), false, {
|
||||||
|
@ -17,14 +17,10 @@
|
||||||
password
|
password
|
||||||
});
|
});
|
||||||
if (ok) {
|
if (ok) {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Account created");
|
||||||
message: "Account created"
|
|
||||||
});
|
|
||||||
loginInstead();
|
loginInstead();
|
||||||
} else {
|
} else {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't create account");
|
||||||
message: "Couldn't create account"
|
|
||||||
});
|
|
||||||
buttonsEnabled = true;
|
buttonsEnabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +31,7 @@
|
||||||
}
|
}
|
||||||
const outroEnd = () => {
|
const outroEnd = () => {
|
||||||
if (pendingOtherOpen) {
|
if (pendingOtherOpen) {
|
||||||
overlayStore.open("login", {});
|
overlayStore.push(OverlayType.Login);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const onKeydown = async (e) => {
|
const onKeydown = async (e) => {
|
||||||
|
|
|
@ -6,17 +6,15 @@
|
||||||
|
|
||||||
let channelName = "";
|
let channelName = "";
|
||||||
let createButtonEnabled = true;
|
let createButtonEnabled = true;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
const close = () => overlayStore.close('createChannel');
|
|
||||||
const create = async () => {
|
const create = async () => {
|
||||||
createButtonEnabled = false;
|
createButtonEnabled = false;
|
||||||
const { ok } = await request("POST", apiRoute("channels"), true, {
|
const { ok } = await request("POST", apiRoute("channels"), true, {
|
||||||
name: channelName
|
name: channelName
|
||||||
});
|
});
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't create channel");
|
||||||
message: "Couldn't create channel"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,17 +8,15 @@
|
||||||
|
|
||||||
let channelName = channel.name;
|
let channelName = channel.name;
|
||||||
let buttonsEnabled = true;
|
let buttonsEnabled = true;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
const close = () => overlayStore.close('editChannel');
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
const { ok } = await request("PUT", apiRoute(`channels/${channel.id}`), true, {
|
const { ok } = await request("PUT", apiRoute(`channels/${channel.id}`), true, {
|
||||||
name: channelName
|
name: channelName
|
||||||
});
|
});
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't edit channel");
|
||||||
message: "Couldn't edit channel"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
@ -26,9 +24,7 @@
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
const { ok } = await request("DELETE", apiRoute(`channels/${channel.id}`), true);
|
const { ok } = await request("DELETE", apiRoute(`channels/${channel.id}`), true);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't delete channel");
|
||||||
message: "Couldn't delete channel"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script>
|
<script>
|
||||||
import { quintInOut } from "svelte/easing";
|
|
||||||
import { overlayStore } from "../../stores";
|
import { overlayStore } from "../../stores";
|
||||||
import request from "../../request";
|
import request from "../../request";
|
||||||
import { apiRoute } from "../../storage";
|
import { apiRoute } from "../../storage";
|
||||||
|
@ -9,17 +8,15 @@
|
||||||
|
|
||||||
let messageContent = message.content;
|
let messageContent = message.content;
|
||||||
let buttonsEnabled = true;
|
let buttonsEnabled = true;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
const close = () => overlayStore.close('editMessage');
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
const { ok } = await request("PUT", apiRoute(`messages/${message.id}`), true, {
|
const { ok } = await request("PUT", apiRoute(`messages/${message.id}`), true, {
|
||||||
content: messageContent
|
content: messageContent
|
||||||
});
|
});
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't edit message");
|
||||||
message: "Couldn't edit message"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
@ -27,9 +24,7 @@
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
const { ok } = await request("DELETE", apiRoute(`messages/${message.id}`), true);
|
const { ok } = await request("DELETE", apiRoute(`messages/${message.id}`), true);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't delete message");
|
||||||
message: "Couldn't delete message"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { overlayStore } from "../../stores";
|
import { overlayStore, OverlayType } from "../../stores";
|
||||||
import request from "../../request";
|
import request from "../../request";
|
||||||
import { apiRoute } from "../../storage";
|
import { apiRoute } from "../../storage";
|
||||||
import { authWithToken } from "../../auth";
|
import { authWithToken } from "../../auth";
|
||||||
|
@ -9,8 +9,8 @@
|
||||||
let password = "";
|
let password = "";
|
||||||
let buttonsEnabled = true;
|
let buttonsEnabled = true;
|
||||||
let pendingOtherOpen = false;
|
let pendingOtherOpen = false;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
const close = () => overlayStore.close('login');
|
|
||||||
const login = async () => {
|
const login = async () => {
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
const { ok, json } = await request("POST", apiRoute("users/login"), false, {
|
const { ok, json } = await request("POST", apiRoute("users/login"), false, {
|
||||||
|
@ -21,13 +21,9 @@
|
||||||
authWithToken(json.token, true);
|
authWithToken(json.token, true);
|
||||||
} else {
|
} else {
|
||||||
if (json && json.code && json.code === 6002) { // 6002 is the code for bad login
|
if (json && json.code && json.code === 6002) { // 6002 is the code for bad login
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Invalid username or password");
|
||||||
message: "Invalid username or password"
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Couldn't log in");
|
||||||
message: "Couldn't log in"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
buttonsEnabled = true;
|
buttonsEnabled = true;
|
||||||
return;
|
return;
|
||||||
|
@ -39,7 +35,7 @@
|
||||||
};
|
};
|
||||||
const outroEnd = () => {
|
const outroEnd = () => {
|
||||||
if (pendingOtherOpen) {
|
if (pendingOtherOpen) {
|
||||||
overlayStore.open("createAccount", {});
|
overlayStore.push(OverlayType.CreateAccount);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const onKeydown = async (e) => {
|
const onKeydown = async (e) => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { overlayStore } from "../../stores";
|
import { overlayStore } from "../../stores";
|
||||||
|
|
||||||
import EditChannel from "./EditChannel.svelte";
|
import EditChannel from "./EditChannel.svelte";
|
||||||
import CreateChannel from "./CreateChannel.svelte";
|
import CreateChannel from "./CreateChannel.svelte";
|
||||||
import Toast from "./Toast.svelte";
|
import Toast from "./Toast.svelte";
|
||||||
|
@ -8,29 +9,19 @@
|
||||||
import EditMessage from "./EditMessage.svelte";
|
import EditMessage from "./EditMessage.svelte";
|
||||||
import Settings from "./Settings.svelte";
|
import Settings from "./Settings.svelte";
|
||||||
import Prompt from "./Prompt.svelte";
|
import Prompt from "./Prompt.svelte";
|
||||||
|
|
||||||
|
const OverlayComponent = {
|
||||||
|
0: CreateChannel,
|
||||||
|
1: EditChannel,
|
||||||
|
2: Toast,
|
||||||
|
3: Login,
|
||||||
|
4: CreateAccount,
|
||||||
|
5: EditMessage,
|
||||||
|
6: Settings,
|
||||||
|
7: Prompt,
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $overlayStore.createChannel}
|
{#each $overlayStore as overlay (overlay.id)}
|
||||||
<CreateChannel />
|
<svelte:component this={ OverlayComponent[overlay.type] } {...overlay.props} />
|
||||||
{/if}
|
{/each}
|
||||||
{#if $overlayStore.editChannel}
|
|
||||||
<EditChannel { ...$overlayStore.editChannel } />
|
|
||||||
{/if}
|
|
||||||
{#if $overlayStore.toast}
|
|
||||||
<Toast { ...$overlayStore.toast } />
|
|
||||||
{/if}
|
|
||||||
{#if $overlayStore.login}
|
|
||||||
<Login />
|
|
||||||
{/if}
|
|
||||||
{#if $overlayStore.createAccount}
|
|
||||||
<CreateAccount />
|
|
||||||
{/if}
|
|
||||||
{#if $overlayStore.editMessage}
|
|
||||||
<EditMessage { ...$overlayStore.editMessage } />
|
|
||||||
{/if}
|
|
||||||
{#if $overlayStore.settings}
|
|
||||||
<Settings />
|
|
||||||
{/if}
|
|
||||||
{#if $overlayStore.prompt}
|
|
||||||
<Prompt { ...$overlayStore.prompt } />
|
|
||||||
{/if}
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { maybeModalFade, maybeModalFly } from "../../animations";
|
import { maybeModalFade, maybeModalFly } from "../../animations";
|
||||||
import { overlayStore } from "../../stores";
|
|
||||||
|
|
||||||
export let onSubmit = async () => {};
|
export let onSubmit = async () => {};
|
||||||
export let onClose = async () => {};
|
export let onClose = async () => {};
|
||||||
|
@ -9,15 +8,16 @@
|
||||||
|
|
||||||
let userInput = "";
|
let userInput = "";
|
||||||
let buttonsEnabled = true;
|
let buttonsEnabled = true;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
const close = async () => {
|
const closePrompt = async () => {
|
||||||
await onClose();
|
await onClose();
|
||||||
overlayStore.close("prompt");
|
close();
|
||||||
};
|
};
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
buttonsEnabled = false;
|
buttonsEnabled = false;
|
||||||
await onSubmit(userInput);
|
await onSubmit(userInput);
|
||||||
close();
|
closePrompt();
|
||||||
};
|
};
|
||||||
const onKeydown = async (e) => {
|
const onKeydown = async (e) => {
|
||||||
if (e.code !== "Enter")
|
if (e.code !== "Enter")
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="modal-backdrop" transition:maybeModalFade on:click="{ close }" on:keydown="{ onKeydown }">
|
<div class="modal-backdrop" transition:maybeModalFade on:click="{ closePrompt }" on:keydown="{ onKeydown }">
|
||||||
<div class="modal" transition:maybeModalFly on:click|stopPropagation>
|
<div class="modal" transition:maybeModalFly on:click|stopPropagation>
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<span class="h4">{ heading }</span>
|
<span class="h4">{ heading }</span>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="button modal-secondary-action" on:click="{ close }">Cancel</button>
|
<button class="button modal-secondary-action" on:click="{ closePrompt }">Cancel</button>
|
||||||
<button class="button button-accent modal-primary-action" on:click="{ save }" disabled="{ !buttonsEnabled }">Submit</button>
|
<button class="button button-accent modal-primary-action" on:click="{ save }" disabled="{ !buttonsEnabled }">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { AtSignIcon } from "svelte-feather-icons";
|
import { AtSignIcon } from "svelte-feather-icons";
|
||||||
import { overlayStore, userInfoStore, smallViewport, theme, doAnimations } from "../../stores";
|
import { overlayStore, userInfoStore, smallViewport, theme, doAnimations, OverlayType } from "../../stores";
|
||||||
import { logOut } from "../../auth";
|
import { logOut } from "../../auth";
|
||||||
import { maybeModalFade, maybeModalFly } from "../../animations";
|
import { maybeModalFade, maybeModalFly } from "../../animations";
|
||||||
import request from "../../request";
|
import request from "../../request";
|
||||||
import { apiRoute, getItem } from "../../storage";
|
import { apiRoute, getItem } from "../../storage";
|
||||||
|
|
||||||
const close = () => overlayStore.close("settings");
|
export let close = () => {};
|
||||||
|
|
||||||
const doDeveloper = () => {
|
const doDeveloper = () => {
|
||||||
overlayStore.open("prompt", {
|
overlayStore.push(OverlayType.Prompt, {
|
||||||
heading: "",
|
heading: "",
|
||||||
valueName: "",
|
valueName: "",
|
||||||
async onSubmit(value) {
|
async onSubmit(value) {
|
||||||
|
@ -19,8 +19,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const respond = (value) => {
|
const respond = (value) => {
|
||||||
overlayStore.close("prompt");
|
overlayStore.toast(value);
|
||||||
overlayStore.open("toast", { message: value });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (parts[0]) {
|
switch (parts[0]) {
|
||||||
|
@ -38,17 +37,15 @@
|
||||||
const doLogout = () => {
|
const doLogout = () => {
|
||||||
close();
|
close();
|
||||||
logOut();
|
logOut();
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Logged out");
|
||||||
message: "Logged out"
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const doSuperuserPrompt = async () => {
|
const doSuperuserPrompt = async () => {
|
||||||
const { ok } = await request("POST", apiRoute("users/self/promote"), true);
|
const { ok } = await request("POST", apiRoute("users/self/promote"), true);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
overlayStore.open("toast", { message: "You have been promoted to superuser" });
|
overlayStore.toast("You have been promoted to superuser");
|
||||||
} else {
|
} else {
|
||||||
overlayStore.open("toast", { message: "Failed to promote to superuser" });
|
overlayStore.toast("Failed to promote to superuser");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import { overlayStore } from "../../stores";
|
import { overlayStore } from "../../stores";
|
||||||
|
|
||||||
export let message;
|
export let message;
|
||||||
|
export let close = () => {};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -25,7 +26,7 @@
|
||||||
{#key message}
|
{#key message}
|
||||||
<div class="toast" transition:maybeModalFly>
|
<div class="toast" transition:maybeModalFly>
|
||||||
<span>{ message }</span>
|
<span>{ message }</span>
|
||||||
<button class="icon-button icon-button-auto" on:click="{ () => overlayStore.close('toast') }">
|
<button class="icon-button icon-button-auto" on:click="{ close }">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getItem } from "./storage";
|
import { getItem } from "./storage";
|
||||||
// TODO: circular dependency
|
// TODO: circular dependency
|
||||||
import { overlayStore } from "./stores";
|
import { overlayStore, OverlayType } from "./stores";
|
||||||
|
|
||||||
export function compatibleFetch(endpoint, options) {
|
export function compatibleFetch(endpoint, options) {
|
||||||
if (window.fetch && typeof window.fetch === "function") {
|
if (window.fetch && typeof window.fetch === "function") {
|
||||||
|
@ -62,7 +62,7 @@ export default function doRequest(method, endpoint, auth=true, body=null, _keyEn
|
||||||
|
|
||||||
if (res.status === 403 && json.code && json.code === 6006 && !_keyEntryDepth) {
|
if (res.status === 403 && json.code && json.code === 6006 && !_keyEntryDepth) {
|
||||||
// This endpoint is password-protected
|
// This endpoint is password-protected
|
||||||
overlayStore.open("prompt", {
|
overlayStore.push(OverlayType.Prompt, {
|
||||||
heading: "Enter Key For Resource",
|
heading: "Enter Key For Resource",
|
||||||
valueName: "Key",
|
valueName: "Key",
|
||||||
async onSubmit(value) {
|
async onSubmit(value) {
|
||||||
|
|
|
@ -234,9 +234,7 @@ class MessageStore extends Store {
|
||||||
this.value = res.json.concat(this.value);
|
this.value = res.json.concat(this.value);
|
||||||
this.updated();
|
this.updated();
|
||||||
} else {
|
} else {
|
||||||
overlayStore.open("toast", {
|
overlayStore.toast("Messages failed to load");
|
||||||
message: "Messages failed to load"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,34 +282,68 @@ class MessagesStoreProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const OverlayType = {
|
||||||
|
CreateChannel: 0,
|
||||||
|
EditChannel: 1,
|
||||||
|
Toast: 2,
|
||||||
|
Login: 3,
|
||||||
|
CreateAccount: 4,
|
||||||
|
EditMessage: 5,
|
||||||
|
Settings: 6,
|
||||||
|
Prompt: 7,
|
||||||
|
};
|
||||||
class OverlayStore extends Store {
|
class OverlayStore extends Store {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super([], "OverlayStore");
|
||||||
createChannel: null,
|
|
||||||
editChannel: null,
|
|
||||||
toast: null,
|
|
||||||
login: null,
|
|
||||||
createAccount: null,
|
|
||||||
editMessage: null,
|
|
||||||
settings: null,
|
|
||||||
prompt: null,
|
|
||||||
}, "OverlayStore");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open(name, props={}) {
|
push(type, props={}) {
|
||||||
if (this.value[name] === undefined)
|
const id = Math.floor(Math.random() * 9999999);
|
||||||
throw new Error(`OverlayStore.open: tried to open unknown overlay with name '${name}' (undefined in overlay map)`);
|
|
||||||
this.value[name] = props;
|
props = {
|
||||||
|
...props,
|
||||||
|
close: () => {
|
||||||
|
this.popId(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value.push({
|
||||||
|
type,
|
||||||
|
props,
|
||||||
|
id
|
||||||
|
});
|
||||||
|
|
||||||
this.updated();
|
this.updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
close(name) {
|
pop() {
|
||||||
if (!this.value[name])
|
this.value.pop();
|
||||||
return;
|
|
||||||
|
|
||||||
this.value[name] = null;
|
|
||||||
this.updated();
|
this.updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popType(type) {
|
||||||
|
for (let i = this.value.length - 1; i >= 0; i--) {
|
||||||
|
if (this.value[i].type === type) {
|
||||||
|
this.value.splice(i, 1);
|
||||||
|
this.updated();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
popId(id) {
|
||||||
|
for (let i = this.value.length - 1; i >= 0; i--) {
|
||||||
|
if (this.value[i].id === id) {
|
||||||
|
this.value.splice(i, 1);
|
||||||
|
this.updated();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toast(message) {
|
||||||
|
this.push(OverlayType.Toast, { message });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypingStore extends Store {
|
class TypingStore extends Store {
|
||||||
|
|
Loading…
Reference in a new issue