funkwhale/front/src/LegacyLayout.vue

107 lines
3.3 KiB
Vue

<script setup lang="ts">
import { useIntervalFn, useStyleTag, useToggle, useWindowSize } from '@vueuse/core'
import { computed, defineAsyncComponent, nextTick, onMounted } from 'vue'
import { useQueue } from '~/composables/audio/queue'
import { useStore } from '~/store'
import { useI18n } from 'vue-i18n'
import onKeyboardShortcut from '~/composables/onKeyboardShortcut'
const { t } = useI18n()
const ChannelUploadModal = defineAsyncComponent(() => import('~/components/channels/UploadModal.vue'))
const PlaylistModal = defineAsyncComponent(() => import('~/components/playlists/PlaylistModal.vue'))
const FilterModal = defineAsyncComponent(() => import('~/components/moderation/FilterModal.vue'))
const ReportModal = defineAsyncComponent(() => import('~/components/moderation/ReportModal.vue'))
const ServiceMessages = defineAsyncComponent(() => import('~/components/ServiceMessages.vue'))
const ShortcutsModal = defineAsyncComponent(() => import('~/components/ShortcutsModal.vue'))
const AudioPlayer = defineAsyncComponent(() => import('~/components/audio/Player.vue'))
const Sidebar = defineAsyncComponent(() => import('~/components/Sidebar.vue'))
const Queue = defineAsyncComponent(() => import('~/components/Queue.vue'))
const store = useStore()
// Tracks
const { tracks } = useQueue()
// Fake content
onMounted(async () => {
await nextTick()
document.getElementById('fake-content')?.classList.add('loaded')
})
// Styles
const customStylesheets = computed(() => {
return store.state.instance.frontSettings.additionalStylesheets ?? []
})
useStyleTag(computed(() => store.state.instance.settings.ui.custom_css.value))
// Time ago
useIntervalFn(() => {
// used to redraw ago dates every minute
store.commit('ui/computeLastDate')
}, 1000 * 60)
// Shortcuts
const [showShortcutsModal, toggleShortcutsModal] = useToggle(false)
onKeyboardShortcut('h', () => toggleShortcutsModal())
const { width } = useWindowSize()
</script>
<template>
<div
:key="store.state.instance.instanceUrl"
:class="{
'has-bottom-player': tracks.length > 0,
'queue-focused': store.state.ui.queueFocused
}"
>
<!-- here, we display custom stylesheets, if any -->
<link
v-for="url in customStylesheets"
:key="url"
rel="stylesheet"
property="stylesheet"
:href="url"
>
<sidebar
:width="width"
@show:shortcuts-modal="toggleShortcutsModal"
/>
<service-messages />
<transition name="queue">
<queue v-show="store.state.ui.queueFocused" />
</transition>
<router-view v-slot="{ Component }">
<template v-if="Component">
<keep-alive :max="1">
<Suspense>
<component :is="Component" />
<template #fallback>
<!-- TODO (wvffle): Add loader -->
{{ t('App.loading') }}
</template>
</Suspense>
</keep-alive>
</template>
<template v-else>
<!-- Display a proper 404 page or error message -->
<h1>404 - Page Not Found</h1>
</template>
</router-view>
<audio-player />
<playlist-modal v-if="store.state.auth.authenticated" />
<channel-upload-modal v-if="store.state.auth.authenticated" />
<filter-modal v-if="store.state.auth.authenticated" />
<report-modal />
<shortcuts-modal v-model:show="showShortcutsModal" />
</div>
</template>