koel/resources/assets/js/components/layout/main-wrapper/Sidebar.vue

212 lines
5.1 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
2022-04-24 08:29:14 +00:00
<nav id="sidebar" :class="{ showing }" class="side side-nav">
2022-04-15 14:24:30 +00:00
<section class="music">
<h1>Your Music</h1>
<ul class="menu">
<li>
<a :class="['home', currentView === 'Home' ? 'active' : '']" href="#!/home">Home</a>
</li>
<li>
2022-04-24 08:29:14 +00:00
<a v-koel-droppable="handleDrop" :class="['queue', currentView === 'Queue' ? 'active' : '']" href="#!/queue">
Current Queue
</a>
2022-04-15 14:24:30 +00:00
</li>
<li>
<a :class="['songs', currentView === 'Songs' ? 'active' : '']" href="#!/songs">All Songs</a>
</li>
<li>
<a :class="['albums', currentView === 'Albums' ? 'active' : '']" href="#!/albums">Albums</a>
</li>
<li>
2022-04-24 08:29:14 +00:00
<a :class="['artists', currentView === 'Artists' ? 'active' : '']" href="#!/artists">Artists</a>
2022-04-15 14:24:30 +00:00
</li>
2022-04-24 08:29:14 +00:00
<li v-if="useYouTube">
<a :class="['youtube', currentView === 'YouTube' ? 'active' : '']" href="#!/youtube">YouTube Video</a>
2022-04-15 14:24:30 +00:00
</li>
</ul>
</section>
2022-04-15 17:00:08 +00:00
<PlaylistList :current-view="currentView"/>
2022-04-15 14:24:30 +00:00
2022-04-24 08:29:14 +00:00
<section v-if="user.is_admin" class="manage">
2022-04-15 14:24:30 +00:00
<h1>Manage</h1>
<ul class="menu">
<li>
<a :class="['settings', currentView === 'Settings' ? 'active' : '']" href="#!/settings">Settings</a>
</li>
<li>
<a :class="['upload', currentView === 'Upload' ? 'active' : '']" href="#!/upload">Upload</a>
</li>
<li>
<a :class="['users', currentView === 'Users' ? 'active' : '']" href="#!/users">Users</a>
</li>
</ul>
</section>
</nav>
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
2022-04-15 14:24:30 +00:00
import isMobile from 'ismobilejs'
2022-04-24 08:29:14 +00:00
import { defineAsyncComponent, ref, toRef } from 'vue'
2022-04-15 14:24:30 +00:00
import { eventBus } from '@/utils'
2022-04-15 17:00:08 +00:00
import { queueStore, sharedStore, songStore, userStore } from '@/stores'
2022-04-15 14:24:30 +00:00
2022-04-20 12:41:50 +00:00
const PlaylistList = defineAsyncComponent(() => import('@/components/playlist/PlaylistSidebarList.vue'))
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
const showing = ref(!isMobile.phone)
2022-04-24 08:29:14 +00:00
const currentView = ref<MainViewName>('Home')
const user = toRef(userStore.state, 'current')
const useYouTube = toRef(sharedStore.state, 'useYouTube')
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
const handleDrop = (event: DragEvent) => {
if (!event.dataTransfer?.getData('application/x-koel.text+plain')) {
return false
}
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
const songs = songStore.byIds(event.dataTransfer.getData('application/x-koel.text+plain').split(','))
songs.length && queueStore.queue(songs)
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
return false
}
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
eventBus.on('LOAD_MAIN_CONTENT', (view: MainViewName): void => {
currentView.value = view
// Hide the sidebar if on mobile
2022-04-24 08:29:14 +00:00
isMobile.phone && (showing.value = false)
2022-04-15 14:24:30 +00:00
})
2022-04-15 17:00:08 +00:00
/**
* Listen to sidebar:toggle event to show or hide the sidebar.
* This should only be triggered on a mobile device.
*/
eventBus.on('TOGGLE_SIDEBAR', () => (showing.value = !showing.value))
2022-04-15 14:24:30 +00:00
</script>
<style lang="scss">
#sidebar {
flex: 0 0 256px;
background-color: var(--color-bg-secondary);
padding: 2.05rem 0;
overflow: auto;
overflow-x: hidden;
-ms-overflow-style: -ms-autohiding-scrollbar;
> * + * {
margin-top: 2.25rem;
}
@media (hover: none) {
// Enable scroll with momentum on touch devices
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
a.droppable {
transform: scale(1.2);
transition: .3s;
transform-origin: center left;
color: var(--color-text-primary);
background-color: rgba(0, 0, 0, .3);
}
section {
h1 {
text-transform: uppercase;
letter-spacing: 1px;
padding: 0 16px;
margin-bottom: 12px;
i {
float: right;
}
}
a {
display: block;
height: 36px;
line-height: 36px;
padding: 0 12px 0 16px;
border-left: 4px solid transparent;
&.active, &:hover {
border-left-color: var(--color-highlight);
color: var(--color-text-primary);
background: rgba(255, 255, 255, .05);
box-shadow: 0 1px 0 rgba(0, 0, 0, .1);
}
&:active {
opacity: .5;
}
&:hover {
border-left-color: var(--color-highlight);
}
&::before {
width: 24px;
display: inline-block;
font-family: FontAwesome;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
&.home::before {
content: "\f015";
}
&.queue::before {
content: "\f0cb";
}
&.songs::before {
content: "\f001";
}
&.albums::before {
content: "\f152";
}
&.artists::before {
content: "\f130";
}
&.youtube::before {
content: "\f16a";
}
&.settings::before {
content: "\f013";
}
&.users::before {
content: "\f0c0";
}
&.upload::before {
content: "\f093";
}
}
}
2022-04-15 17:00:08 +00:00
@media only screen and (max-width: 667px) {
2022-04-15 14:24:30 +00:00
@include themed-background();
position: fixed;
height: calc(100vh - var(--header-height) + var(--footer-height));
width: 100%;
z-index: 99;
top: var(--header-height);
left: -100%;
transition: left .3s ease-in;
&.showing {
left: 0;
}
}
}
</style>