Compare commits
4 commits
131a270562
...
f17fd0174b
Author | SHA1 | Date | |
---|---|---|---|
|
f17fd0174b | ||
|
240411ddd3 | ||
|
fbc84a1659 | ||
|
a8479ee549 |
7 changed files with 106 additions and 12 deletions
|
@ -84,7 +84,7 @@ body {
|
||||||
background-color: var(--background-color-1);
|
background-color: var(--background-color-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shared styles for all components */
|
/* top bar */
|
||||||
|
|
||||||
.top-bar {
|
.top-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -102,6 +102,8 @@ body {
|
||||||
margin-left: var(--space-xxs);
|
margin-left: var(--space-xxs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* modal */
|
||||||
|
|
||||||
.modal-backdrop {
|
.modal-backdrop {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
@ -126,7 +128,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
margin-bottom: var(--space-md);
|
margin-bottom: var(--space-norm);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +145,8 @@ body {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* input */
|
||||||
|
|
||||||
.input-label {
|
.input-label {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--foreground-color-2);
|
color: var(--foreground-color-2);
|
||||||
|
@ -158,6 +162,8 @@ body {
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* button */
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
background-color: var(--background-color-2);
|
background-color: var(--background-color-2);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -185,6 +191,25 @@ body {
|
||||||
background-color: var(--purple-2);
|
background-color: var(--purple-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--foreground-color-3);
|
||||||
|
text-align: center;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
font: inherit;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button:hover {
|
||||||
|
color: var(--foreground-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* text */
|
||||||
|
|
||||||
.h1 {
|
.h1 {
|
||||||
font-size: 2.488rem;
|
font-size: 2.488rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<div class="modal-backdrop" transition:fade="{{ duration: 300, easing: quintInOut }}" on:click="{ close }">
|
<div class="modal-backdrop" transition:fade="{{ duration: 300, easing: quintInOut }}" on:click="{ close }">
|
||||||
<div class="modal" transition:fly="{{ duration: 300, easing: quintInOut, y: 10 }}" on:click|stopPropagation>
|
<div class="modal" transition:fly="{{ duration: 300, easing: quintInOut, y: 10 }}" on:click|stopPropagation>
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<span class="h3">Create Channel</span>
|
<span class="h4">Create Channel</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="input-label">
|
<label class="input-label">
|
||||||
|
|
55
frontend/src/components/modals/EditChannel.svelte
Normal file
55
frontend/src/components/modals/EditChannel.svelte
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<script>
|
||||||
|
import { fade, fly } from "svelte/transition";
|
||||||
|
import { quintInOut } from "svelte/easing";
|
||||||
|
import { overlayStore } from "../../stores";
|
||||||
|
import request from "../../request";
|
||||||
|
import { apiRoute } from "../../storage";
|
||||||
|
|
||||||
|
export let channel;
|
||||||
|
|
||||||
|
let channelName = channel.name;
|
||||||
|
let buttonsEnabled = true;
|
||||||
|
|
||||||
|
const close = () => overlayStore.close('editChannel');
|
||||||
|
const save = async () => {
|
||||||
|
buttonsEnabled = false;
|
||||||
|
await request("PUT", apiRoute(`channels/${channel.id}`), true, {
|
||||||
|
name: channelName
|
||||||
|
});
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
const deleteChannel = async () => {
|
||||||
|
buttonsEnabled = false;
|
||||||
|
await request("DELETE", apiRoute(`channels/${channel.id}`), true);
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
color: var(--red-2);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="modal-backdrop" transition:fade="{{ duration: 300, easing: quintInOut }}" on:click="{ close }">
|
||||||
|
<div class="modal" transition:fly="{{ duration: 300, easing: quintInOut, y: 10 }}" on:click|stopPropagation>
|
||||||
|
<div class="modal-header">
|
||||||
|
<span class="h4">Edit Channel</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label class="input-label">
|
||||||
|
Channel Name
|
||||||
|
<input class="input full-width" bind:value={ channelName } />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="button modal-secondary-action" on:click="{ close }">Cancel</button>
|
||||||
|
<button class="button modal-secondary-action delete-button" on:click="{ deleteChannel }">Delete</button>
|
||||||
|
<button class="button button-accent modal-primary-action" on:click="{ save }" disabled="{ !buttonsEnabled }">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,7 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { CloudIcon } from "svelte-feather-icons";
|
import { CloudIcon } from "svelte-feather-icons";
|
||||||
import { gatewayStatus, selectedChannel } from "../../../stores";
|
import { gatewayStatus, selectedChannel } from "../../../stores";
|
||||||
import CreateChannel from "../../modals/CreateChannel.svelte";
|
|
||||||
import ChannelView from "./ChannelView.svelte";
|
import ChannelView from "./ChannelView.svelte";
|
||||||
import OverlayProvider from "./OverlayProvider.svelte";
|
import OverlayProvider from "./OverlayProvider.svelte";
|
||||||
import Sidebar from "./Sidebar.svelte";
|
import Sidebar from "./Sidebar.svelte";
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { overlayStore } from "../../../stores";
|
import { overlayStore } from "../../../stores";
|
||||||
|
import EditChannel from "../../modals/EditChannel.svelte";
|
||||||
import CreateChannel from "../../modals/CreateChannel.svelte";
|
import CreateChannel from "../../modals/CreateChannel.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $overlayStore.createChannel}
|
{#if $overlayStore.createChannel}
|
||||||
<CreateChannel />
|
<CreateChannel { ...$overlayStore.createChannel } />
|
||||||
|
{/if}
|
||||||
|
{#if $overlayStore.editChannel}
|
||||||
|
<EditChannel { ...$overlayStore.editChannel } />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { HashIcon, PlusIcon } from "svelte-feather-icons";
|
import { HashIcon, PlusIcon, MoreVerticalIcon } from "svelte-feather-icons";
|
||||||
import { channels, overlayStore, selectedChannel } from "../../../stores";
|
import { channels, overlayStore, selectedChannel } from "../../../stores";
|
||||||
import UserTopBar from "./UserTopBar.svelte";
|
import UserTopBar from "./UserTopBar.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
@ -13,6 +13,9 @@
|
||||||
<HashIcon />
|
<HashIcon />
|
||||||
</div>
|
</div>
|
||||||
<span>{ channel.name }</span>
|
<span>{ channel.name }</span>
|
||||||
|
<button class="icon-button" on:click|stopPropagation="{ () => overlayStore.open('editChannel', { channel }) }">
|
||||||
|
<MoreVerticalIcon />
|
||||||
|
</button>
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
<button on:click="{ () => overlayStore.open('createChannel') }" class="sidebar-button">
|
<button on:click="{ () => overlayStore.open('createChannel') }" class="sidebar-button">
|
||||||
|
@ -52,7 +55,6 @@
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 3.4em;
|
max-height: 3.4em;
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-button span {
|
.sidebar-button span {
|
||||||
|
@ -71,6 +73,14 @@
|
||||||
height: 24px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-button .icon-button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-button:hover .icon-button {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-button.selected,
|
.sidebar-button.selected,
|
||||||
.sidebar-button:hover {
|
.sidebar-button:hover {
|
||||||
background-color: var(--background-color-2);
|
background-color: var(--background-color-2);
|
||||||
|
|
|
@ -222,17 +222,18 @@ class MessagesStoreProvider {
|
||||||
class OverlayStore extends Store {
|
class OverlayStore extends Store {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
createChannel: false
|
createChannel: null,
|
||||||
|
editChannel: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
open(name) {
|
open(name, props={}) {
|
||||||
this.value[name] = true;
|
this.value[name] = props;
|
||||||
this.updated();
|
this.updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
close(name) {
|
close(name) {
|
||||||
this.value[name] = false;
|
this.value[name] = null;
|
||||||
this.updated();
|
this.updated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue