forked from DebaucheryLibrarian/traxxx
				
			
		
			
				
	
	
		
			415 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Vue
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			415 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Vue
		
	
	
		
			Executable File
		
	
	
| <template>
 | |
| 	<div
 | |
| 		class="sidebar-container"
 | |
| 		@click="events.emit('toggleSidebar', false)"
 | |
| 	>
 | |
| 		<div
 | |
| 			class="sidebar"
 | |
| 			@click.stop
 | |
| 		>
 | |
| 			<div class="sidebar-section">
 | |
| 				<div class="sidebar-header">
 | |
| 					<RouterLink
 | |
| 						to="/updates"
 | |
| 						class="logo-link"
 | |
| 						@click="events.emit('toggleSidebar', false)"
 | |
| 					>
 | |
| 						<h1 class="sidebar-logo">
 | |
| 							<div
 | |
| 								class="logo"
 | |
| 								v-html="logo"
 | |
| 							/>
 | |
| 						</h1>
 | |
| 					</RouterLink>
 | |
| 
 | |
| 					<Icon
 | |
| 						icon="cross2"
 | |
| 						class="sidebar-close noselect"
 | |
| 						@click.native="events.emit('toggleSidebar', false)"
 | |
| 					/>
 | |
| 				</div>
 | |
| 
 | |
| 				<Search
 | |
| 					class="search"
 | |
| 					@search="events.emit('toggleSidebar', false)"
 | |
| 				/>
 | |
| 
 | |
| 				<nav class="nav">
 | |
| 					<ul class="nolist">
 | |
| 						<li
 | |
| 							class="nav-item"
 | |
| 							@click="events.emit('toggleSidebar', false)"
 | |
| 						>
 | |
| 							<RouterLink
 | |
| 								v-slot="{ href, isActive, navigate }"
 | |
| 								to="/updates"
 | |
| 								custom
 | |
| 							>
 | |
| 								<a
 | |
| 									class="nav-link"
 | |
| 									:href="href"
 | |
| 									:class="{ active: isActive }"
 | |
| 									@click="navigate"
 | |
| 								>Home</a>
 | |
| 							</RouterLink>
 | |
| 						</li>
 | |
| 
 | |
| 						<li
 | |
| 							class="nav-item"
 | |
| 							@click="events.emit('toggleSidebar', false)"
 | |
| 						>
 | |
| 							<RouterLink
 | |
| 								v-slot="{ href, isActive, navigate }"
 | |
| 								to="/actors"
 | |
| 								custom
 | |
| 							>
 | |
| 								<a
 | |
| 									class="nav-link"
 | |
| 									:href="href"
 | |
| 									:class="{ active: isActive }"
 | |
| 									@click="navigate"
 | |
| 								>Actors</a>
 | |
| 							</RouterLink>
 | |
| 						</li>
 | |
| 
 | |
| 						<li
 | |
| 							class="nav-item"
 | |
| 							@click="events.emit('toggleSidebar', false)"
 | |
| 						>
 | |
| 							<RouterLink
 | |
| 								v-slot="{ href, isActive, navigate }"
 | |
| 								to="/channels"
 | |
| 								custom
 | |
| 							>
 | |
| 								<a
 | |
| 									class="nav-link"
 | |
| 									:href="href"
 | |
| 									:class="{ active: isActive }"
 | |
| 									@click="navigate"
 | |
| 								>Channels</a>
 | |
| 							</RouterLink>
 | |
| 						</li>
 | |
| 
 | |
| 						<li
 | |
| 							class="nav-item"
 | |
| 							@click="events.emit('toggleSidebar', false)"
 | |
| 						>
 | |
| 							<RouterLink
 | |
| 								v-slot="{ href, isActive, navigate }"
 | |
| 								to="/movies"
 | |
| 								custom
 | |
| 							>
 | |
| 								<a
 | |
| 									class="nav-link"
 | |
| 									:href="href"
 | |
| 									:class="{ active: isActive }"
 | |
| 									@click="navigate"
 | |
| 								>Movies</a>
 | |
| 							</RouterLink>
 | |
| 						</li>
 | |
| 
 | |
| 						<li
 | |
| 							class="nav-item"
 | |
| 							@click="events.emit('toggleSidebar', false)"
 | |
| 						>
 | |
| 							<RouterLink
 | |
| 								v-slot="{ href, isActive, navigate }"
 | |
| 								to="/tags"
 | |
| 								custom
 | |
| 							>
 | |
| 								<a
 | |
| 									class="nav-link"
 | |
| 									:href="href"
 | |
| 									:class="{ active: isActive }"
 | |
| 									@click="navigate"
 | |
| 								>Tags</a>
 | |
| 							</RouterLink>
 | |
| 						</li>
 | |
| 					</ul>
 | |
| 				</nav>
 | |
| 			</div>
 | |
| 
 | |
| 			<div class="sidebar-section controls noselect">
 | |
| 				<label
 | |
| 					v-if="login && me"
 | |
| 					@click="events.emit('toggleSidebar', false)"
 | |
| 				>
 | |
| 					<RouterLink
 | |
| 						:to="{ name: 'user', params: { username: me.username } }"
 | |
| 						class="toggle username nolink"
 | |
| 					>{{ me.username }}</RouterLink>
 | |
| 				</label>
 | |
| 
 | |
| 				<div class="toggles noselect">
 | |
| 					<label
 | |
| 						v-if="login && !me"
 | |
| 						@click="events.emit('toggleSidebar', false)"
 | |
| 					>
 | |
| 						<RouterLink
 | |
| 							:to="{ name: 'login', query: { ref: $route.path } }"
 | |
| 							class="toggle nolink"
 | |
| 						><Icon icon="enter2" />Log in</RouterLink>
 | |
| 					</label>
 | |
| 
 | |
| 					<label
 | |
| 						v-if="login && 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="events.emit('toggleSettings', true)"
 | |
| 					><Icon icon="cog" />Settings</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 login(state) {
 | |
| 	return state.auth.login;
 | |
| }
 | |
| 
 | |
| function signup(state) {
 | |
| 	return state.auth.signup;
 | |
| }
 | |
| 
 | |
| 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,
 | |
| 	},
 | |
| 	data() {
 | |
| 		return {
 | |
| 			logo,
 | |
| 		};
 | |
| 	},
 | |
| 	computed: {
 | |
| 		...mapState({
 | |
| 			login,
 | |
| 			signup,
 | |
| 			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>
 |