mirror of
https://github.com/koel/koel
synced 2024-11-24 13:13:05 +00:00
fix: sidebar menu collapse/expand on mobile
This commit is contained in:
parent
b994f2dc94
commit
bb47d5fb3b
4 changed files with 53 additions and 39 deletions
|
@ -10,7 +10,9 @@
|
|||
py-0 px-6 h-k-header-height"
|
||||
>
|
||||
<div class="btn-group">
|
||||
<SidebarMenuToggleButton />
|
||||
<ExtraDrawerButton @click.prevent="expandSidebar">
|
||||
<Icon :icon="faBars" fixed-width />
|
||||
</ExtraDrawerButton>
|
||||
<ExtraDrawerTabHeader v-if="songPlaying" v-model="activeTab" />
|
||||
</div>
|
||||
|
||||
|
@ -70,16 +72,17 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import isMobile from 'ismobilejs'
|
||||
import { faBars } from '@fortawesome/free-solid-svg-icons'
|
||||
import { computed, defineAsyncComponent, onMounted, ref, Ref, watch } from 'vue'
|
||||
import { albumStore, artistStore, preferenceStore } from '@/stores'
|
||||
import { useErrorHandler, useThirdPartyServices } from '@/composables'
|
||||
import { isSong, requireInjection } from '@/utils'
|
||||
import { eventBus, isSong, requireInjection } from '@/utils'
|
||||
import { CurrentPlayableKey } from '@/symbols'
|
||||
|
||||
import ProfileAvatar from '@/components/ui/ProfileAvatar.vue'
|
||||
import SidebarMenuToggleButton from '@/components/ui/SidebarMenuToggleButton.vue'
|
||||
import AboutKoelButton from '@/components/layout/main-wrapper/extra-drawer/AboutKoelButton.vue'
|
||||
import LogoutButton from '@/components/layout/main-wrapper/extra-drawer/LogoutButton.vue'
|
||||
import ExtraDrawerButton from '@/components/layout/main-wrapper/extra-drawer/ExtraDrawerButton.vue'
|
||||
|
||||
const LyricsPane = defineAsyncComponent(() => import('@/components/ui/LyricsPane.vue'))
|
||||
const ArtistInfo = defineAsyncComponent(() => import('@/components/artist/ArtistInfo.vue'))
|
||||
|
@ -119,6 +122,7 @@ watch(playable, song => {
|
|||
watch(activeTab, tab => (preferenceStore.active_extra_panel_tab = tab))
|
||||
|
||||
const onProfileLinkClick = () => isMobile.any && (activeTab.value = null)
|
||||
const expandSidebar = () => eventBus.emit('TOGGLE_SIDEBAR')
|
||||
|
||||
onMounted(() => isMobile.any || (activeTab.value = preferenceStore.active_extra_panel_tab))
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
exports[`renders without a current song 1`] = `
|
||||
<aside data-v-847f0b60="" class="fixed sm:relative top-0 w-screen md:w-auto flex flex-col md:flex-row-reverse z-[2] text-k-text-secondary">
|
||||
<div data-v-847f0b60="" class="controls flex md:flex-col justify-between items-center md:w-[64px] md:py-6 tw:px-0 bg-black/5 md:border-l border-solid md:border-l-white/5 md:border-b-0 md:shadow-none z-[2] w-screen flex-row border-b border-b-white/5 border-l-0 shadow-xl py-0 px-6 h-k-header-height">
|
||||
<div data-v-847f0b60="" class="btn-group"><button data-v-5e31283f="" data-v-847f0b60="" class="relative flex items-center justify-center h-[42px] aspect-square rounded-full bg-none md:bg-black/30 text-xl opacity-70 transition-opacity duration-200 ease-in-out text-current cursor-pointer hover:active-state active:scale-90 block md:hidden" type="button"><br data-testid="Icon" icon="[object Object]" fixed-width=""></button>
|
||||
<div data-v-847f0b60="" class="btn-group"><button data-v-5e31283f="" data-v-847f0b60="" class="relative flex items-center justify-center h-[42px] aspect-square rounded-full bg-none md:bg-black/30 text-xl opacity-70 transition-opacity duration-200 ease-in-out text-current cursor-pointer hover:active-state active:scale-90" type="button"><br data-v-847f0b60="" data-testid="Icon" icon="[object Object]" fixed-width=""></button>
|
||||
<!--v-if-->
|
||||
</div>
|
||||
<div data-v-847f0b60="" class="btn-group"><button data-v-5e31283f="" data-v-847f0b60="" class="relative flex items-center justify-center h-[42px] aspect-square rounded-full bg-none md:bg-black/30 text-xl opacity-70 transition-opacity duration-200 ease-in-out text-current cursor-pointer hover:active-state active:scale-90" type="button" title="About Koel"><br data-testid="Icon" icon="[object Object]">
|
||||
|
|
|
@ -1,45 +1,55 @@
|
|||
<template>
|
||||
<nav
|
||||
:class="{ collapsed: !expanded, 'tmp-showing': tmpShowing, showing: mobileShowing }"
|
||||
class="group flex flex-col fixed md:relative w-full md:w-k-sidebar-width z-10"
|
||||
@mouseenter="onMouseEnter"
|
||||
@mouseleave="onMouseLeave"
|
||||
>
|
||||
<section class="home-search-block p-6 flex gap-2">
|
||||
<HomeButton />
|
||||
<SearchForm class="flex-1" />
|
||||
</section>
|
||||
<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 v-koel-overflow-fade class="pt-2 pb-10 overflow-y-auto space-y-8">
|
||||
<SidebarYourMusicSection />
|
||||
<SidebarPlaylistsSection />
|
||||
<SidebarManageSection v-if="showManageSection" />
|
||||
</section>
|
||||
<section class="home-search-block p-6 flex gap-2">
|
||||
<HomeButton />
|
||||
<SearchForm class="flex-1" />
|
||||
</section>
|
||||
|
||||
<section v-if="!isPlus && isAdmin" class="p-6 flex-1 flex flex-col-reverse">
|
||||
<BtnUpgradeToPlus />
|
||||
</section>
|
||||
<section v-koel-overflow-fade class="pt-2 pb-10 overflow-y-auto space-y-8">
|
||||
<SidebarYourMusicSection />
|
||||
<SidebarPlaylistsSection />
|
||||
<SidebarManageSection v-if="showManageSection" />
|
||||
</section>
|
||||
|
||||
<SidebarToggleButton
|
||||
class="opacity-0 no-hover:hidden group-hover:opacity-100 transition"
|
||||
v-model="expanded"
|
||||
:class="expanded || 'opacity-100'"
|
||||
/>
|
||||
</nav>
|
||||
<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'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { eventBus } from '@/utils'
|
||||
import { useAuthorization, useKoelPlus, useLocalStorage, useRouter, useUpload } from '@/composables'
|
||||
|
||||
import SidebarPlaylistsSection from './SidebarPlaylistsSection.vue'
|
||||
import SearchForm from '@/components/ui/SearchForm.vue'
|
||||
import BtnUpgradeToPlus from '@/components/koel-plus/BtnUpgradeToPlus.vue'
|
||||
import SidebarYourMusicSection from './SidebarYourLibrarySection.vue'
|
||||
import SidebarManageSection from './SidebarManageSection.vue'
|
||||
import SidebarToggleButton from '@/components/layout/main-wrapper/sidebar/SidebarToggleButton.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'
|
||||
import SidebarManageSection from './SidebarManageSection.vue'
|
||||
import SidebarPlaylistsSection from './SidebarPlaylistsSection.vue'
|
||||
import SidebarToggleButton from '@/components/layout/main-wrapper/sidebar/SidebarToggleButton.vue'
|
||||
import SidebarYourMusicSection from './SidebarYourLibrarySection.vue'
|
||||
|
||||
const { onRouteChanged } = useRouter()
|
||||
const { isAdmin } = useAuthorization()
|
||||
|
@ -81,6 +91,8 @@ const onMouseLeave = (e: MouseEvent) => {
|
|||
|
||||
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.
|
||||
|
@ -104,9 +116,9 @@ nav {
|
|||
}
|
||||
|
||||
&.tmp-showing {
|
||||
@apply absolute h-screen z-50 bg-k-bg-primary w-k-sidebar-width shadow-2xl;
|
||||
@apply fixed h-screen bg-k-bg-primary w-k-sidebar-width shadow-2xl z-[999];
|
||||
|
||||
> *:not(.btn-toggle) {
|
||||
> *:not(.btn-toggle, .btn-collapse-block) {
|
||||
@apply block;
|
||||
}
|
||||
|
||||
|
@ -118,11 +130,9 @@ nav {
|
|||
|
||||
@media screen and (max-width: 768px) {
|
||||
@mixin themed-background;
|
||||
z-index: 999;
|
||||
|
||||
transform: translateX(-100vw);
|
||||
transition: transform .2s ease-in-out;
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
&.showing {
|
||||
transform: translateX(0);
|
||||
|
|
|
@ -20,8 +20,8 @@ new class extends UnitTestCase {
|
|||
expect(screen.getByTestId('sidebar-item').classList.contains('current')).toBe(true)
|
||||
})
|
||||
|
||||
it ('emits the sidebar toggle event when clicked', async () => {
|
||||
const mock = this.mock(eventBus, 'emit')
|
||||
it('emits the sidebar toggle event when clicked', async () => {
|
||||
const mock = this.mock(eventBus, 'emit')
|
||||
this.renderComponent()
|
||||
await this.user.click(screen.getByTestId('sidebar-item'))
|
||||
|
||||
|
|
Loading…
Reference in a new issue