<template> <div class="sidebar-container" @click="$emit('toggleSidebar', false)" > <div class="sidebar" @click.stop > <div class="sidebar-section"> <div class="sidebar-header"> <router-link to="/updates" class="logo-link" @click="$emit('toggleSidebar', false)" > <h1 class="sidebar-logo"> <div class="logo" v-html="logo" /> </h1> </router-link> <Icon icon="cross2" class="sidebar-close noselect" @click.native="$emit('toggleSidebar', false)" /> </div> <Search class="search" @search="$emit('toggleSidebar', false)" /> <nav class="nav"> <ul class="nolist"> <li class="nav-item" @click="$emit('toggleSidebar', false)" > <router-link v-slot="{ href, isActive, navigate }" to="/updates" custom > <a class="nav-link" :href="href" :class="{ active: isActive }" @click="navigate" >Home</a> </router-link> </li> <li class="nav-item" @click="$emit('toggleSidebar', false)" > <router-link v-slot="{ href, isActive, navigate }" to="/actors" custom > <a class="nav-link" :href="href" :class="{ active: isActive }" @click="navigate" >Actors</a> </router-link> </li> <li class="nav-item" @click="$emit('toggleSidebar', false)" > <router-link v-slot="{ href, isActive, navigate }" to="/channels" custom > <a class="nav-link" :href="href" :class="{ active: isActive }" @click="navigate" >Channels</a> </router-link> </li> <li class="nav-item" @click="$emit('toggleSidebar', false)" > <router-link v-slot="{ href, isActive, navigate }" to="/movies" custom > <a class="nav-link" :href="href" :class="{ active: isActive }" @click="navigate" >Movies</a> </router-link> </li> <li class="nav-item" @click="$emit('toggleSidebar', false)" > <router-link v-slot="{ href, isActive, navigate }" to="/tags" custom > <a class="nav-link" :href="href" :class="{ active: isActive }" @click="navigate" >Tags</a> </router-link> </li> </ul> </nav> </div> <div class="sidebar-section controls noselect"> <label v-if="auth && me" @click="$emit('toggleSidebar', false)" > <router-link :to="{ name: 'user', params: { username: me.username } }" class="toggle username nolink" >{{ me.username }}</router-link> </label> <div class="toggles noselect"> <label v-if="auth && !me" @click="$emit('toggleSidebar', false)" > <router-link :to="{ name: 'login', query: { ref: $route.path } }" class="toggle nolink" ><Icon icon="enter2" />Log in</router-link> </label> <label v-if="auth && me" class="toggle" @click.stop="$store.dispatch('logout')" ><Icon icon="exit2" />Log out</label> <label v-show="sfw" class="toggle" @click="setSfw(false)" ><Icon icon="fire" />Disable safe mode</label> <label v-show="!sfw" class="toggle" @click="setSfw(true)" ><Icon icon="flower" />Enable safe mode</label> <label v-show="theme === 'dark'" class="toggle" @click="setTheme('light')" ><Icon icon="sun" />Use light theme</label> <label v-show="theme === 'light'" class="toggle" @click="setTheme('dark')" ><Icon icon="moon" />Use dark theme</label> <label class="toggle" @click="$emit('showFilters', true)" ><Icon icon="filter" />Filters</label> </div> </div> </div> </div> </template> <script> import { mapState } from 'vuex'; import Search from '../header/search.vue'; import logo from '../../img/logo.svg'; function sfw(state) { return state.ui.sfw; } function theme(state) { return state.ui.theme; } function auth(state) { return state.auth.enabled; } function me(state) { return state.auth.user; } function setTheme(newTheme) { this.$store.dispatch('setTheme', newTheme); } function setSfw(enabled) { this.$store.dispatch('setSfw', enabled); } export default { components: { Search, }, emits: ['toggleSidebar', 'showFilters'], data() { return { logo, }; }, computed: { ...mapState({ auth, me, sfw, theme, }), }, methods: { setTheme, setSfw, }, }; </script> <style lang="scss" scoped> .sidebar-container { height: 100%; width: 100%; position: absolute; z-index: 10; background: var(--darken-weak); } .sidebar { display: flex; flex-direction: column; justify-content: space-between; width: 15rem; height: 100%; margin: 0 0 0 auto; color: var(--text); background: var(--background); box-shadow: 0 0 3px var(--darken-weak); } .sidebar-header { display: flex; justify-content: space-between; height: 3rem; border-bottom: solid 1px var(--shadow-hint); } .sidebar-close { width: 1.25rem; height: 100%; padding: 0 1.125rem; fill: var(--shadow-modest); &:hover { fill: var(--primary); cursor: pointer; } } .sidebar-logo { height: 100%; display: flex; align-items: center; margin: 0; } .sidebar-section { display: flex; flex-direction: column; overflow: hidden; } .logo-link { display: block; height: 100%; padding: 0 1rem; } .logo { width: 6rem; display: flex; align-items: center; margin: 0; fill: var(--primary); } :deep(.search) { height: 3rem; border-bottom: solid 1px var(--shadow-hint); padding: 0; margin: 0 0 .5rem 0; .search-input { padding: .5rem 0 .5rem 1rem; } } .nav { flex-grow: 1; overflow-x: auto; } .nav-item { display: block; } .nav-link { color: var(--shadow); display: block; padding: 1rem; text-decoration: none; font-weight: bold; &:hover { color: var(--shadow-strong); } &.active { color: var(--primary); } } .controls { margin: .5rem 0 0 0; } .toggles { flex-shrink: 0; border-top: solid 1px var(--shadow-hint); } .toggle { display: flex; padding: 1rem; color: var(--shadow); font-weight: bold; &.username { justify-content: center; } .icon { fill: var(--shadow); margin: 0 1rem 0 0; } &.active .icon { fill: var(--primary); } &:hover { cursor: pointer; color: var(--shadow-strong); &:not(.active) .icon { fill: var(--shadow-strong); } } } .dark .sidebar { background: var(--profile); .nav-link { color: var(--shadow); &.active { color: var(--text-light); } } .sidebar-close { fill: var(--lighten); &:hover { fill: var(--text-light); } } } </style>