Fix dropdowns
This commit is contained in:
parent
232f0ff465
commit
a7f4df68ea
|
@ -14,6 +14,7 @@ import { computed, ref, watch, watchEffect, onMounted } from 'vue'
|
|||
import { useGettext } from 'vue3-gettext'
|
||||
import { useStore } from '~/store'
|
||||
import { setupDropdown } from '~/utils/fomantic'
|
||||
import { useCurrentElement } from '@vueuse/core'
|
||||
|
||||
interface Props {
|
||||
width: number
|
||||
|
@ -104,19 +105,14 @@ watch(languageSelection, (v) => {
|
|||
store.dispatch('ui/currentLanguage', v)
|
||||
})
|
||||
|
||||
watch(() => store.state.auth.authenticated, (authenticated) => {
|
||||
if (authenticated) {
|
||||
setupDropdown('.admin-dropdown')
|
||||
}
|
||||
|
||||
setupDropdown('.user-dropdown')
|
||||
}, { immediate: true })
|
||||
|
||||
watch(() => store.state.auth.availablePermissions, () => {
|
||||
const el = useCurrentElement()
|
||||
watchEffect(() => {
|
||||
if (store.state.auth.authenticated) {
|
||||
setupDropdown('.admin-dropdown')
|
||||
setupDropdown('.admin-dropdown', el.value)
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
setupDropdown('.user-dropdown', el.value)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
document.getElementById('fake-sidebar')?.classList.add('loaded')
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
import type { Track, Artist, Album, Playlist, Library, Channel, Actor } from '~/types'
|
||||
import type { PlayOptionsProps } from '~/composables/audio/usePlayOptions'
|
||||
|
||||
import { ref, computed, watch, nextTick } from 'vue'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
import usePlayOptions from '~/composables/audio/usePlayOptions'
|
||||
import useReport from '~/composables/moderation/useReport'
|
||||
import { useCurrentElement } from '@vueuse/core'
|
||||
import { setupDropdown, getDropdown } from '~/utils/fomantic'
|
||||
import { setupDropdown } from '~/utils/fomantic'
|
||||
|
||||
interface Props extends PlayOptionsProps {
|
||||
dropdownIconClasses?: string[]
|
||||
|
@ -63,8 +63,6 @@ const {
|
|||
|
||||
const { report, getReportableObjects } = useReport()
|
||||
|
||||
const clicked = ref(false)
|
||||
|
||||
const { $pgettext } = useGettext()
|
||||
const labels = computed(() => ({
|
||||
playNow: $pgettext('*/Queue/Dropdown/Button/Title', 'Play now'),
|
||||
|
@ -93,29 +91,31 @@ const title = computed(() => {
|
|||
if (props.track) {
|
||||
return $pgettext('*/Queue/Button/Title', 'This track is not available in any library you have access to')
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
|
||||
watch(clicked, async () => {
|
||||
await setupDropdown()
|
||||
|
||||
getDropdown().dropdown('show', function () {
|
||||
// little magic to ensure the menu is always visible in the viewport
|
||||
// By default, try to diplay it on the right if there is enough room
|
||||
const menu = getDropdown().find('.menu')
|
||||
const viewportOffset = menu.get(0)?.getBoundingClientRect() ?? { right: 0, left: 0 }
|
||||
const viewportWidth = document.documentElement.clientWidth
|
||||
const rightOverflow = viewportOffset.right - viewportWidth
|
||||
const leftOverflow = -viewportOffset.left
|
||||
let offset = 0
|
||||
if (rightOverflow > 0) {
|
||||
offset = -rightOverflow - 5
|
||||
menu.css({ cssText: `left: ${offset}px !important;` })
|
||||
} else if (leftOverflow > 0) {
|
||||
offset = leftOverflow + 5
|
||||
menu.css({ cssText: `right: -${offset}px !important;` })
|
||||
}
|
||||
})
|
||||
const el = useCurrentElement()
|
||||
const dropdown = ref()
|
||||
onMounted(() => {
|
||||
dropdown.value = setupDropdown('.ui.dropdown', el.value)
|
||||
})
|
||||
|
||||
const openMenu = () => {
|
||||
// little magic to ensure the menu is always visible in the viewport
|
||||
// By default, try to diplay it on the right if there is enough room
|
||||
const menu = dropdown.value.find('.menu')
|
||||
const viewportOffset = menu.get(0)?.getBoundingClientRect() ?? { right: 0, left: 0 }
|
||||
const viewportWidth = document.documentElement.clientWidth
|
||||
const rightOverflow = viewportOffset.right - viewportWidth
|
||||
const leftOverflow = -viewportOffset.left
|
||||
|
||||
if (rightOverflow > 0) {
|
||||
menu.css({ cssText: `left: ${-rightOverflow - 5}px !important;` })
|
||||
} else if (leftOverflow > 0) {
|
||||
menu.css({ cssText: `right: -${leftOverflow + 5}px !important;` })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -143,16 +143,13 @@ watch(clicked, async () => {
|
|||
<button
|
||||
v-if="!discrete && !iconOnly"
|
||||
:class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]"
|
||||
@click.stop.prevent="clicked = true"
|
||||
@click.stop.prevent="openMenu"
|
||||
>
|
||||
<i
|
||||
:class="dropdownIconClasses.concat(['icon'])"
|
||||
:title="title"
|
||||
/>
|
||||
<div
|
||||
v-if="clicked"
|
||||
class="menu"
|
||||
>
|
||||
<div class="menu">
|
||||
<button
|
||||
class="item basic"
|
||||
data-ref="enqueue"
|
||||
|
|
|
@ -7,5 +7,5 @@ export const install: InitModule = ({ app, store }) => {
|
|||
store.commit('ui/pageTitle', binding.value)
|
||||
})
|
||||
|
||||
app.directive('dropdown', setupDropdown)
|
||||
app.directive('dropdown', (element) => setupDropdown(element))
|
||||
}
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
/// <reference types="semantic-ui" />
|
||||
|
||||
import $ from 'jquery'
|
||||
import { tryOnMounted, useCurrentElement } from '@vueuse/core'
|
||||
|
||||
export const getDropdown = (selector = '.ui.dropdown'): JQuery => {
|
||||
const el = useCurrentElement()
|
||||
return $(el.value).find(selector)
|
||||
}
|
||||
|
||||
export const setupDropdown = (selector: string | HTMLElement = '.ui.dropdown') => tryOnMounted(() => {
|
||||
const el = useCurrentElement()
|
||||
export const setupDropdown = (selector: string | HTMLElement = '.ui.dropdown', el: Element = document.body) => {
|
||||
const $dropdown = typeof selector === 'string'
|
||||
? $(el.value).find(selector)
|
||||
? $(el).find(selector)
|
||||
: $(selector)
|
||||
|
||||
$dropdown.dropdown({
|
||||
|
@ -24,4 +17,6 @@ export const setupDropdown = (selector: string | HTMLElement = '.ui.dropdown') =
|
|||
$dropdown.dropdown('hide')
|
||||
}
|
||||
})
|
||||
}, false)
|
||||
|
||||
return $dropdown
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue