175 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
| <template>
 | |
| 	<div class="menu">
 | |
| 		<ul class="menu-items noselect">
 | |
| 			<router-link
 | |
| 				v-if="auth && me"
 | |
| 				:to="{ name: 'user', params: { username: me.username } }"
 | |
| 				class="menu-username"
 | |
| 			>{{ me.username }}</router-link>
 | |
| 
 | |
| 			<router-link
 | |
| 				v-else-if="auth"
 | |
| 				:to="{ name: 'login', query: { ref: $route.path } }"
 | |
| 				class="menu-item"
 | |
| 				@click.stop
 | |
| 			>
 | |
| 				<Icon icon="enter2" />Log in
 | |
| 			</router-link>
 | |
| 
 | |
| 			<li
 | |
| 				v-if="auth && me"
 | |
| 				class="menu-item"
 | |
| 				@click.stop="$store.dispatch('logout')"
 | |
| 			>
 | |
| 				<Icon icon="exit2" />Log out
 | |
| 			</li>
 | |
| 
 | |
| 			<li
 | |
| 				v-show="!sfw"
 | |
| 				class="menu-item"
 | |
| 				@click.stop="setSfw(true)"
 | |
| 			>
 | |
| 				<Icon
 | |
| 					icon="flower"
 | |
| 					class="toggle noselect"
 | |
| 				/>Safe mode
 | |
| 			</li>
 | |
| 
 | |
| 			<li
 | |
| 				v-show="sfw"
 | |
| 				class="menu-item"
 | |
| 				@click.stop="setSfw(false)"
 | |
| 			>
 | |
| 				<Icon
 | |
| 					icon="fire"
 | |
| 					class="toggle noselect"
 | |
| 				/>Filth mode
 | |
| 			</li>
 | |
| 
 | |
| 			<li
 | |
| 				v-show="theme === 'light'"
 | |
| 				class="menu-item"
 | |
| 				@click.stop="setTheme('dark')"
 | |
| 			>
 | |
| 				<Icon
 | |
| 					icon="moon"
 | |
| 					class="toggle noselect"
 | |
| 				/>Dark theme
 | |
| 			</li>
 | |
| 
 | |
| 			<li
 | |
| 				v-show="theme === 'dark'"
 | |
| 				class="menu-item"
 | |
| 				@click.stop="setTheme('light')"
 | |
| 			>
 | |
| 				<Icon
 | |
| 					icon="sun"
 | |
| 					class="toggle noselect"
 | |
| 				/>Light theme
 | |
| 			</li>
 | |
| 
 | |
| 			<li
 | |
| 				class="menu-item"
 | |
| 				@click="$emit('showFilters', true)"
 | |
| 			>
 | |
| 				<Icon icon="filter" />Filters
 | |
| 			</li>
 | |
| 		</ul>
 | |
| 	</div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import { mapState } from 'vuex';
 | |
| 
 | |
| 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 {
 | |
| 	computed: {
 | |
| 		...mapState({
 | |
| 			auth,
 | |
| 			sfw,
 | |
| 			theme,
 | |
| 			me,
 | |
| 		}),
 | |
| 	},
 | |
| 	emits: ['showFilters'],
 | |
| 	methods: {
 | |
| 		setSfw,
 | |
| 		setTheme,
 | |
| 	},
 | |
| };
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| @import 'breakpoints';
 | |
| 
 | |
| .menu-items {
 | |
| 	list-style: none;
 | |
| 	padding: 0;
 | |
| 	margin: 0;
 | |
| }
 | |
| 
 | |
| .menu-item {
 | |
| 	display: flex;
 | |
| 	padding: .75rem 1rem .75rem .75rem;
 | |
| 	color: var(--text);
 | |
| 	text-decoration: none;
 | |
| 
 | |
| 	.icon {
 | |
| 		fill: var(--shadow);
 | |
| 		margin: 0 1rem 0 0;
 | |
| 	}
 | |
| 
 | |
| 	&.disabled {
 | |
| 		color: var(--shadow-weak);
 | |
| 		cursor: default;
 | |
| 
 | |
| 		.icon {
 | |
| 			fill: var(--shadow-weak);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	&:hover:not(.disabled) {
 | |
| 		cursor: pointer;
 | |
| 		color: var(--primary);
 | |
| 
 | |
| 		.icon {
 | |
| 			fill: var(--primary);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| .menu-username {
 | |
| 	display: block;
 | |
| 	font-weight: bold;
 | |
| 	color: var(--shadow-strong);
 | |
| 	font-size: .9rem;
 | |
| 	padding: .75rem 1rem;
 | |
| 	border-bottom: solid 1px var(--shadow-hint);
 | |
| 	text-align: center;
 | |
| 	text-decoration: none;
 | |
| }
 | |
| </style>
 |