waffle/frontend/src/components/Sidebar.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>