<template> <div class="container"> <Warning v-if="showWarning" class="warning-container" @enter="(includeQueer) => setConsent(true, includeQueer)" @leave="setConsent(false)" /> <transition name="slide"> <Sidebar v-if="showSidebar" @toggle-sidebar="(state) => toggleSidebar(state)" @show-filters="(state) => toggleFilters(state)" /> </transition> <Header @toggle-sidebar="(state) => toggleSidebar(state)" @show-filters="(state) => toggleFilters(state)" /> <p v-if="config.showDisclaimer" class="disclaimer" >{{ config.disclaimer }}</p> <div ref="content" class="content" @scroll="scroll" > <router-view @scroll="scrollToTop" /> </div> <Filters v-if="showFilters" @close="toggleFilters(false)" /> </div> </template> <script> import Warning from './warning.vue'; import Header from '../header/header.vue'; import Sidebar from '../sidebar/sidebar.vue'; import Filters from '../filters/filters.vue'; function toggleSidebar(state) { this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar; } function toggleFilters(state) { this.showFilters = state; this.showSidebar = false; } async function setConsent(consent, includeQueer) { if (consent) { this.showWarning = false; localStorage.setItem('consent', window.env.sessionId); } if (includeQueer) { this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter(tag => !['gay', 'bisexual', 'transsexual'].includes(tag))); return; } this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.concat(['gay', 'bisexual', 'transsexual'])); } function blur(event) { this.events.emit('blur', event); } function resize(event) { this.events.emit('resize', event); } function scroll(event) { this.events.emit('scroll', event); } function scrollToTop() { this.$refs.content.scrollTop = 0; } function mounted() { document.addEventListener('click', this.blur); window.addEventListener('resize', this.resize); } function beforeUnmount() { document.removeEventListener('click', this.blur); window.removeEventListener('resize', this.resize); } export default { components: { Header, Sidebar, Warning, Filters, }, data() { return { showSidebar: false, showWarning: localStorage.getItem('consent') !== window.env.sessionId, showFilters: false, }; }, mounted, beforeUnmount, methods: { toggleSidebar, toggleFilters, setConsent, blur, resize, scroll, scrollToTop, }, }; </script> <style lang="scss"> .container { position: relative; height: 100%; display: flex; flex-direction: column; overflow: hidden; background: var(--background-soft); color: var(--text); } .content { display: flex; flex-direction: column; flex-grow: 1; overflow-y: auto; overflow-x: hidden; } .content-inner { display: flex; flex-direction: column; flex-grow: 1; overflow-y: auto; overflow-x: hidden; z-index: 1; } .slide-enter-active, .slide-leave-active { &.sidebar-container { transition: background .15s ease-in-out; } .sidebar { transition: transform .15s ease-in-out; } } .slide-enter-from, .slide-leave-to { &.sidebar-container { background: transparent; } .sidebar { transform: translate(100%, 0); } } .column { width: 1200px; max-width: 100%; padding: 0 1rem; margin: 0 auto; box-sizing: border-box; } </style> <style lang="scss" scoped> .disclaimer { padding: .5rem 1rem; margin: 0; color: var(--text-light); background: var(--warn); font-weight: bold; box-shadow: inset 0 0 3px var(--darken-weak); text-align: center; } </style>