124 lines
3.6 KiB
Svelte
124 lines
3.6 KiB
Svelte
<script>
|
|
import { HashIcon, PlusIcon, MoreVerticalIcon } from "svelte-feather-icons";
|
|
import { quadInOut } from "svelte/easing";
|
|
import { fly } from "svelte/transition";
|
|
import { channels, overlayStore, selectedChannel, showChannelView, showSidebar, smallViewport } from "../stores";
|
|
import UserTopBar from "./UserTopBar.svelte";
|
|
|
|
let pendingSelectChannel = null;
|
|
|
|
const selectChannel = (channel) => $selectedChannel = channel;
|
|
|
|
// janky code to hide the channel view during animation
|
|
// this will make a smooth sidebar animation on smaller viewports (such as a phone, where you switch between sidebar being active)
|
|
|
|
const scheduleSelectChannel = (channel) => {
|
|
if ($smallViewport) {
|
|
$showChannelView = false;
|
|
pendingSelectChannel = channel;
|
|
$showSidebar = false;
|
|
} else {
|
|
selectChannel(channel);
|
|
}
|
|
};
|
|
|
|
const outroEnd = () => {
|
|
if (pendingSelectChannel) {
|
|
selectChannel(pendingSelectChannel);
|
|
pendingSelectChannel = null;
|
|
$showChannelView = true;
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<div class="sidebar-container" transition:fly="{{ duration: 200, easing: quadInOut, x: -10 }}" on:outroend="{ outroEnd }">
|
|
<UserTopBar />
|
|
<div class="sidebar">
|
|
{#each $channels as channel (channel.id)}
|
|
<button on:click="{ scheduleSelectChannel(channel) }" class="sidebar-button" class:selected={ channel.id === $selectedChannel.id }>
|
|
<div>
|
|
<HashIcon />
|
|
</div>
|
|
<span>{ channel.name }</span>
|
|
<button class="icon-button icon-button-auto" on:click|stopPropagation="{ () => overlayStore.open('editChannel', { channel }) }">
|
|
<MoreVerticalIcon />
|
|
</button>
|
|
</button>
|
|
{/each}
|
|
<button on:click="{ () => overlayStore.open('createChannel') }" class="sidebar-button">
|
|
<div>
|
|
<PlusIcon />
|
|
</div>
|
|
<span>Create Channel</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.sidebar-container {
|
|
background-color: var(--background-color-1);
|
|
border-right: 1px solid var(--background-color-2);
|
|
height: 100%;
|
|
min-width: 255px;
|
|
max-width: 255px;
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
.sidebar-container {
|
|
flex-basis: 100%;
|
|
min-width: unset;
|
|
max-width: unset;
|
|
}
|
|
}
|
|
|
|
.sidebar {
|
|
width: 100%;
|
|
height: 100%;
|
|
padding: var(--space-xs);
|
|
}
|
|
|
|
.sidebar-button {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: left;
|
|
border: none;
|
|
background-color: var(--background-color-1);
|
|
padding: var(--space-xs);
|
|
margin-bottom: var(--space-xxs);
|
|
color: currentColor;
|
|
font: inherit;
|
|
border-radius: var(--radius-md);
|
|
width: 100%;
|
|
max-height: 3.4em;
|
|
}
|
|
|
|
.sidebar-button span {
|
|
margin-left: var(--space-xxs);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.sidebar-button div {
|
|
display: inline;
|
|
flex-shrink: 0;
|
|
|
|
/* TODO: HACK! */
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
.sidebar-button .icon-button {
|
|
visibility: hidden;
|
|
}
|
|
|
|
.sidebar-button.selected .icon-button,
|
|
.sidebar-button:hover .icon-button {
|
|
visibility: visible;
|
|
}
|
|
|
|
.sidebar-button.selected,
|
|
.sidebar-button:hover {
|
|
background-color: var(--background-color-2);
|
|
}
|
|
</style>
|