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

143 lines
4.1 KiB
Vue
Raw Normal View History

<template>
<nav
:class="{ collapsed: !expanded, 'tmp-showing': tmpShowing, showing: mobileShowing }"
class="group left-0 top-0 flex flex-col fixed h-full w-full md:relative md:w-k-sidebar-width z-[999] md:z-10"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
>
<section class="btn-collapse-block flex md:hidden items-center border-b border-b-white/5 h-k-header-height px-6">
<div class="bg-white/5 rounded-full">
<ExtraDrawerButton @click.prevent="collapseSidebar">
<Icon :icon="faTimes" fixed-width />
</ExtraDrawerButton>
</div>
</section>
<section class="home-search-block p-6 flex gap-2">
<HomeButton />
<SearchForm class="flex-1" />
</section>
<section v-koel-overflow-fade class="pt-2 pb-10 overflow-y-auto space-y-8">
<SidebarYourMusicSection />
<SidebarPlaylistsSection />
<SidebarManageSection v-if="showManageSection" />
</section>
<section v-if="!isPlus && isAdmin" class="p-6 flex-1 flex flex-col-reverse">
<BtnUpgradeToPlus />
</section>
<SidebarToggleButton
class="opacity-0 no-hover:hidden group-hover:opacity-100 transition"
v-model="expanded"
:class="expanded || 'opacity-100'"
/>
</nav>
</template>
<script lang="ts" setup>
import { faTimes } from '@fortawesome/free-solid-svg-icons'
2024-04-04 22:20:42 +00:00
import { computed, ref, watch } from 'vue'
import { eventBus } from '@/utils'
2024-04-23 21:01:27 +00:00
import { useAuthorization, useKoelPlus, useLocalStorage, useRouter, useUpload } from '@/composables'
2024-04-04 22:20:42 +00:00
import BtnUpgradeToPlus from '@/components/koel-plus/BtnUpgradeToPlus.vue'
import ExtraDrawerButton from '@/components/layout/main-wrapper/extra-drawer/ExtraDrawerButton.vue'
import HomeButton from '@/components/layout/main-wrapper/sidebar/HomeButton.vue'
import SearchForm from '@/components/ui/SearchForm.vue'
2024-04-04 22:20:42 +00:00
import SidebarManageSection from './SidebarManageSection.vue'
import SidebarPlaylistsSection from './SidebarPlaylistsSection.vue'
2024-04-04 22:20:42 +00:00
import SidebarToggleButton from '@/components/layout/main-wrapper/sidebar/SidebarToggleButton.vue'
import SidebarYourMusicSection from './SidebarYourLibrarySection.vue'
const { onRouteChanged } = useRouter()
const { isAdmin } = useAuthorization()
2024-01-04 11:35:36 +00:00
const { allowsUpload } = useUpload()
const { isPlus } = useKoelPlus()
2024-03-15 15:09:50 +00:00
const { get: lsGet, set: lsSet } = useLocalStorage()
const mobileShowing = ref(false)
2024-04-04 22:20:42 +00:00
const expanded = ref(!lsGet('sidebar-collapsed', false))
2024-05-19 05:49:42 +00:00
2024-04-04 22:20:42 +00:00
watch(expanded, value => lsSet('sidebar-collapsed', !value))
2024-01-04 11:35:36 +00:00
const showManageSection = computed(() => isAdmin.value || allowsUpload.value)
2024-03-15 15:09:50 +00:00
let tmpShowingHandler: number | undefined
const tmpShowing = ref(false)
const onMouseEnter = () => {
2024-04-04 22:20:42 +00:00
if (expanded.value) return;
2024-03-15 15:09:50 +00:00
tmpShowingHandler = window.setTimeout(() => {
2024-04-04 22:20:42 +00:00
if (expanded.value) return
2024-03-15 15:09:50 +00:00
tmpShowing.value = true
}, 500)
}
const onMouseLeave = (e: MouseEvent) => {
if (!e.relatedTarget) {
return
}
if (tmpShowingHandler) {
clearTimeout(tmpShowingHandler)
tmpShowingHandler = undefined
}
tmpShowing.value = false
}
onRouteChanged(_ => (mobileShowing.value = false))
const collapseSidebar = () => (mobileShowing.value = false)
/**
* Listen to toggle sidebar event to show or hide the sidebar.
* This should only be triggered on a mobile device.
*/
2024-06-16 15:40:33 +00:00
eventBus.on('TOGGLE_SIDEBAR', () => (mobileShowing.value = !mobileShowing.value))
</script>
2024-04-04 20:13:35 +00:00
<style lang="postcss" scoped>
2024-04-04 22:20:42 +00:00
@import '@/../css/partials/mixins.pcss';
nav {
2024-04-04 22:20:42 +00:00
@apply bg-k-bg-secondary;
-ms-overflow-style: -ms-autohiding-scrollbar;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
2024-03-15 15:09:50 +00:00
&.collapsed {
2024-04-04 22:20:42 +00:00
@apply w-[24px] transition-[width] duration-200;
2024-03-15 15:09:50 +00:00
> *:not(.btn-toggle) {
2024-04-04 22:20:42 +00:00
@apply hidden;
2024-03-15 15:09:50 +00:00
}
&.tmp-showing {
@apply fixed h-screen bg-k-bg-primary w-k-sidebar-width shadow-2xl z-[999];
2024-03-15 15:09:50 +00:00
> *:not(.btn-toggle, .btn-collapse-block) {
2024-04-04 22:20:42 +00:00
@apply block;
2024-03-15 15:09:50 +00:00
}
2024-05-19 05:49:42 +00:00
> .home-search-block {
@apply flex;
}
2024-03-15 15:09:50 +00:00
}
}
@media screen and (max-width: 768px) {
2024-04-04 22:20:42 +00:00
@mixin themed-background;
2024-04-04 20:13:35 +00:00
transform: translateX(-100vw);
transition: transform .2s ease-in-out;
&.showing {
transform: translateX(0);
}
}
}
</style>