chore: only lazyload components when necessary

This commit is contained in:
Phan An 2022-07-07 20:05:46 +02:00
parent f5608d0058
commit 718bad9771
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
53 changed files with 161 additions and 178 deletions

View file

@ -58,12 +58,12 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, toRef, toRefs } from 'vue'
import { computed, toRef, toRefs } from 'vue'
import { defaultCover, eventBus, pluralize, secondsToHis, startDragging } from '@/utils'
import { albumStore, artistStore, commonStore, songStore } from '@/stores'
import { downloadService, playbackService } from '@/services'
const AlbumThumbnail = defineAsyncComponent(() => import('@/components/ui/AlbumArtistThumbnail.vue'))
import AlbumThumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
const props = withDefaults(defineProps<{ album: Album, layout?: ArtistAlbumCardLayout }>(), { layout: 'full' })
const { album, layout } = toRefs(props)

View file

@ -2,7 +2,7 @@
<article :class="mode" class="album-info" data-testid="album-info">
<h1 class="name">
<span>{{ album.name }}</span>
<button :title="`Play all songs in ${album.name}`" class="control play" @click.prevent="play">
<button :title="`Play all songs in ${album.name}`" class="control play" type="button" @click.prevent="play">
<i class="fa fa-play"/>
</button>
</h1>

View file

@ -56,12 +56,12 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, toRef, toRefs } from 'vue'
import { computed, toRef, toRefs } from 'vue'
import { eventBus, pluralize, startDragging } from '@/utils'
import { artistStore, commonStore, songStore } from '@/stores'
import { downloadService, playbackService } from '@/services'
const ArtistThumbnail = defineAsyncComponent(() => import('@/components/ui/AlbumArtistThumbnail.vue'))
import ArtistThumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
const props = withDefaults(defineProps<{ artist: Artist, layout?: ArtistAlbumCardLayout }>(), { layout: 'full' })
const { artist, layout } = toRefs(props)

View file

@ -2,7 +2,7 @@
<article :class="mode" class="artist-info" data-testid="artist-info">
<h1 class="name">
<span>{{ artist.name }}</span>
<button :title="`Play all songs by ${artist.name}`" class="play control" @click.prevent="play">
<button :title="`Play all songs by ${artist.name}`" class="play control" type="button" @click.prevent="play">
<i class="fa fa-play"/>
</button>
</h1>

View file

@ -10,17 +10,17 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, ref } from 'vue'
import { ref } from 'vue'
import { userStore } from '@/stores'
import { isDemo } from '@/utils'
import Btn from '@/components/ui/Btn.vue'
const DEMO_ACCOUNT = {
email: 'demo@koel.dev',
password: 'demo'
}
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const url = ref('')
const email = ref(isDemo ? DEMO_ACCOUNT.email : '')
const password = ref(isDemo ? DEMO_ACCOUNT.password : '')

View file

@ -8,6 +8,7 @@
aria-controls="extraPanelLyrics"
data-testid="extra-tab-lyrics"
role="tab"
type="button"
@click.prevent="currentTab = 'Lyrics'"
>
Lyrics
@ -18,6 +19,7 @@
aria-controls="extraPanelArtist"
data-testid="extra-tab-artist"
role="tab"
type="button"
@click.prevent="currentTab = 'Artist'"
>
Artist
@ -28,6 +30,7 @@
aria-controls="extraPanelAlbum"
data-testid="extra-tab-album"
role="tab"
type="button"
@click.prevent="currentTab = 'Album'"
>
Album
@ -40,6 +43,7 @@
data-testid="extra-tab-youtube"
role="tab"
title="YouTube"
type="button"
@click.prevent="currentTab = 'YouTube'"
>
<i class="fa fa-youtube-play"></i>
@ -93,19 +97,19 @@
<script lang="ts" setup>
import isMobile from 'ismobilejs'
import { defineAsyncComponent, ref, toRef, watch } from 'vue'
import { ref, toRef, watch } from 'vue'
import { $, eventBus } from '@/utils'
import { albumStore, artistStore, preferenceStore as preferences } from '@/stores'
import { useThirdPartyServices } from '@/composables'
import LyricsPane from '@/components/ui/LyricsPane.vue'
import ArtistInfo from '@/components/artist/ArtistInfo.vue'
import AlbumInfo from '@/components/album/AlbumInfo.vue'
import YouTubeVideoList from '@/components/ui/YouTubeVideoList.vue'
type Tab = 'Lyrics' | 'Artist' | 'Album' | 'YouTube'
const defaultTab: Tab = 'Lyrics'
const LyricsPane = defineAsyncComponent(() => import('@/components/ui/LyricsPane.vue'))
const ArtistInfo = defineAsyncComponent(() => import('@/components/artist/ArtistInfo.vue'))
const AlbumInfo = defineAsyncComponent(() => import('@/components/album/AlbumInfo.vue'))
const YouTubeVideoList = defineAsyncComponent(() => import('@/components/ui/YouTubeVideoList.vue'))
const song = ref<Song | null>(null)
const showing = toRef(preferences.state, 'showExtraPanel')
const currentTab = ref<Tab>(defaultTab)

View file

@ -49,12 +49,12 @@
<script lang="ts" setup>
import isMobile from 'ismobilejs'
import { defineAsyncComponent, ref } from 'vue'
import { ref } from 'vue'
import { eventBus, resolveSongsFromDragEvent } from '@/utils'
import { queueStore } from '@/stores'
import { useAuthorization, useThirdPartyServices } from '@/composables'
const PlaylistList = defineAsyncComponent(() => import('@/components/playlist/PlaylistSidebarList.vue'))
import PlaylistList from '@/components/playlist/PlaylistSidebarList.vue'
const showing = ref(!isMobile.phone)
const currentView = ref<MainViewName>('Home')

View file

@ -45,11 +45,10 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { isDemo } from '@/utils'
import { useNewVersionNotification } from '@/composables'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import Btn from '@/components/ui/Btn.vue'
const {
shouldNotifyNewVersion,

View file

@ -6,9 +6,11 @@
and/or
<a href="https://opencollective.com/koel" rel="noopener" target="_blank">OpenCollective</a>.
</p>
<button data-testid="hide-support-koel" @click.prevent="close">Hide</button>
<button data-testid="hide-support-koel" type="button" @click.prevent="close">Hide</button>
<span class="sep"></span>
<button data-testid="stop-support-koel-bugging" @click.prevent="stopBugging">Don't bug me again</button>
<button data-testid="stop-support-koel-bugging" @click.prevent="stopBugging" type="button">
Don't bug me again
</button>
</div>
</template>

View file

@ -39,13 +39,13 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, nextTick, ref, toRef } from 'vue'
import { nextTick, ref, toRef } from 'vue'
import { favoriteStore, playlistStore } from '@/stores'
import router from '@/router'
import { alerts } from '@/utils'
const PlaylistSidebarItem = defineAsyncComponent(() => import('@/components/playlist/PlaylistSidebarItem.vue'))
const ContextMenu = defineAsyncComponent(() => import('@/components/playlist/CreateNewPlaylistContextMenu.vue'))
import PlaylistSidebarItem from '@/components/playlist/PlaylistSidebarItem.vue'
import ContextMenu from '@/components/playlist/CreateNewPlaylistContextMenu.vue'
const contextMenu = ref<InstanceType<typeof ContextMenu>>()

View file

@ -50,11 +50,11 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, onMounted, ref } from 'vue'
import { onMounted, ref } from 'vue'
import { UpdateCurrentProfileData, userStore } from '@/stores'
import { alerts, isDemo, parseValidationError } from '@/utils'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import Btn from '@/components/ui/Btn.vue'
const profile = ref<UpdateCurrentProfileData>({} as unknown as UpdateCurrentProfileData)

View file

@ -10,10 +10,11 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import { themeStore } from '@/stores'
const ThemeCard = defineAsyncComponent(() => import('@/components/profile-preferences/ThemeCard.vue'))
import ThemeCard from '@/components/profile-preferences/ThemeCard.vue'
const themes = toRef(themeStore.state, 'themes')
const setTheme = (theme: Theme) => themeStore.setTheme(theme)

View file

@ -15,14 +15,14 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, toRef, watch } from 'vue'
import { computed, ref, toRef, watch } from 'vue'
import { eventBus } from '@/utils'
import { albumStore, preferenceStore as preferences } from '@/stores'
import { useInfiniteScroll } from '@/composables'
const AlbumCard = defineAsyncComponent(() => import('@/components/album/AlbumCard.vue'))
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ViewModeSwitch = defineAsyncComponent(() => import('@/components/ui/ViewModeSwitch.vue'))
import AlbumCard from '@/components/album/AlbumCard.vue'
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ViewModeSwitch from '@/components/ui/ViewModeSwitch.vue'
const viewMode = ref<ArtistAlbumViewMode>('thumbnails')
const albums = toRef(albumStore.state, 'albums')

View file

@ -62,9 +62,9 @@ import { downloadService } from '@/services'
import { useSongList } from '@/composables'
import router from '@/router'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
const AlbumInfo = defineAsyncComponent(() => import('@/components/album/AlbumInfo.vue'))
const SoundBar = defineAsyncComponent(() => import('@/components/ui/SoundBar.vue'))
const AlbumThumbnail = defineAsyncComponent(() => import('@/components/ui/AlbumArtistThumbnail.vue'))
const CloseModalBtn = defineAsyncComponent(() => import('@/components/ui/BtnCloseModal.vue'))

View file

@ -22,14 +22,14 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, toRef } from 'vue'
import { computed, ref, toRef } from 'vue'
import { eventBus, pluralize, secondsToHis } from '@/utils'
import { commonStore, queueStore, songStore } from '@/stores'
import { playbackService } from '@/services'
import { useSongList } from '@/composables'
import router from '@/router'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
const totalSongCount = toRef(commonStore.state, 'song_count')
const totalDuration = computed(() => secondsToHis(commonStore.state.song_length))

View file

@ -15,14 +15,14 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, toRef, watch } from 'vue'
import { computed, ref, toRef, watch } from 'vue'
import { eventBus } from '@/utils'
import { artistStore, preferenceStore as preferences } from '@/stores'
import { useInfiniteScroll } from '@/composables'
const ArtistCard = defineAsyncComponent(() => import('@/components/artist/ArtistCard.vue'))
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ViewModeSwitch = defineAsyncComponent(() => import('@/components/ui/ViewModeSwitch.vue'))
import ArtistCard from '@/components/artist/ArtistCard.vue'
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ViewModeSwitch from '@/components/ui/ViewModeSwitch.vue'
const viewMode = ref<ArtistAlbumViewMode>('thumbnails')
const artists = toRef(artistStore.state, 'artists')

View file

@ -64,6 +64,9 @@ import { downloadService } from '@/services'
import { useSongList, useThirdPartyServices } from '@/composables'
import router from '@/router'
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ArtistThumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
const props = defineProps<{ artist: Artist }>()
const { artist } = toRefs(props)
@ -84,10 +87,7 @@ const {
toggleControls
} = useSongList(artistSongs, 'artist', { columns: ['track', 'title', 'album', 'length'] })
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ArtistInfo = defineAsyncComponent(() => import('@/components/artist/ArtistInfo.vue'))
const SoundBar = defineAsyncComponent(() => import('@/components/ui/SoundBar.vue'))
const ArtistThumbnail = defineAsyncComponent(() => import('@/components/ui/AlbumArtistThumbnail.vue'))
const CloseModalBtn = defineAsyncComponent(() => import('@/components/ui/BtnCloseModal.vue'))
const { useLastfm } = useThirdPartyServices()

View file

@ -54,10 +54,10 @@ import { eventBus, pluralize } from '@/utils'
import { commonStore, favoriteStore } from '@/stores'
import { downloadService } from '@/services'
import { useSongList } from '@/composables'
import { defineAsyncComponent, nextTick, toRef } from 'vue'
import { nextTick, toRef } from 'vue'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
const {
SongList,

View file

@ -23,7 +23,7 @@
<script lang="ts" setup>
import { sample } from 'lodash'
import { computed, defineAsyncComponent } from 'vue'
import { computed } from 'vue'
import { eventBus, noop } from '@/utils'
import { overviewStore, userStore } from '@/stores'
@ -35,9 +35,7 @@ import RecentlyAddedAlbums from '@/components/screens/home/RecentlyAddedAlbums.v
import RecentlyAddedSongs from '@/components/screens/home/RecentlyAddedSongs.vue'
import MostPlayedArtists from '@/components/screens/home/MostPlayedArtists.vue'
import MostPlayedAlbum from '@/components/screens/home/MostPlayedAlbum.vue'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
const { ToTopButton, scrolling } = useInfiniteScroll(() => noop())

View file

@ -56,14 +56,14 @@
<script lang="ts" setup>
import { difference } from 'lodash'
import { defineAsyncComponent, ref, toRef } from 'vue'
import { ref, toRef } from 'vue'
import { alerts, eventBus, pluralize } from '@/utils'
import { commonStore, playlistStore, songStore } from '@/stores'
import { downloadService } from '@/services'
import { useSongList } from '@/composables'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
const playlist = ref<Playlist>()
const playlistSongs = ref<Song[]>([])

View file

@ -4,22 +4,19 @@
<div class="main-scroll-wrap">
<ProfileForm/>
<Themes/>
<Preferences/>
<ThemeList/>
<PreferencesForm/>
<LastfmIntegration/>
</div>
</section>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ProfileForm = defineAsyncComponent(() => import('@/components/profile-preferences/ProfileForm.vue'))
const LastfmIntegration = defineAsyncComponent(() => import('@/components/profile-preferences/LastfmIntegration.vue'))
const Preferences = defineAsyncComponent(() => import('@/components/profile-preferences/PreferencesForm.vue'))
const Themes = defineAsyncComponent(() => import('@/components/profile-preferences/ThemeList.vue'))
</script>
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ProfileForm from '@/components/profile-preferences/ProfileForm.vue'
import LastfmIntegration from '@/components/profile-preferences/LastfmIntegration.vue'
import PreferencesForm from '@/components/profile-preferences/PreferencesForm.vue'
import ThemeList from '@/components/profile-preferences/ThemeList.vue'</script>
<style lang="scss">
#profileWrapper {

View file

@ -44,14 +44,14 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, toRef } from 'vue'
import { computed, toRef } from 'vue'
import { pluralize } from '@/utils'
import { commonStore, queueStore } from '@/stores'
import { playbackService } from '@/services'
import { useSongList } from '@/composables'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
const controlConfig: Partial<SongListControlsConfig> = { clearQueue: true }

View file

@ -33,10 +33,10 @@
import { eventBus, pluralize } from '@/utils'
import { recentlyPlayedStore } from '@/stores'
import { useSongList } from '@/composables'
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
const {
SongList,

View file

@ -29,13 +29,13 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref } from 'vue'
import { computed, ref } from 'vue'
import { settingStore } from '@/stores'
import { alerts, forceReloadWindow, hideOverlay, parseValidationError, showOverlay } from '@/utils'
import router from '@/router'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import Btn from '@/components/ui/Btn.vue'
const mediaPath = ref(settingStore.state.media_path)
const originalMediaPath = mediaPath.value

View file

@ -67,12 +67,12 @@ import { acceptedMediaTypes, UploadFile } from '@/config'
import { uploadService } from '@/services'
import { useAuthorization } from '@/composables'
import UploadItem from '@/components/ui/upload/UploadItem.vue'
import BtnGroup from '@/components/ui/BtnGroup.vue'
import Btn from '@/components/ui/Btn.vue'
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
const BtnGroup = defineAsyncComponent(() => import('@/components/ui/BtnGroup.vue'))
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const UploadItem = defineAsyncComponent(() => import('@/components/ui/upload/UploadItem.vue'))
const acceptAttribute = acceptedMediaTypes.join(',')

View file

@ -25,15 +25,15 @@
<script lang="ts" setup>
import isMobile from 'ismobilejs'
import { defineAsyncComponent, onMounted, ref, toRef } from 'vue'
import { userStore } from '@/stores'
import { eventBus } from '@/utils'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ControlsToggle = defineAsyncComponent(() => import('@/components/ui/ScreenControlsToggle.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ControlsToggle from '@/components/ui/ScreenControlsToggle.vue'
import UserCard from '@/components/user/UserCard.vue'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const BtnGroup = defineAsyncComponent(() => import('@/components/ui/BtnGroup.vue'))
const UserCard = defineAsyncComponent(() => import('@/components/user/UserCard.vue'))
const users = toRef(userStore.state, 'users')
const isPhone = isMobile.phone

View file

@ -16,16 +16,15 @@
<script lang="ts" setup>
import createYouTubePlayer from 'youtube-player'
import { defineAsyncComponent, ref } from 'vue'
import { ref } from 'vue'
import type { YouTubePlayer } from 'youtube-player/dist/types'
import { eventBus, use } from '@/utils'
import { playbackService } from '@/services'
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
let player: YouTubePlayer | null = null
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
const title = ref('YouTube Video')
const getPlayer = () => {

View file

@ -10,14 +10,10 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import { overviewStore } from '@/stores'
const AlbumCard = defineAsyncComponent(() => import('@/components/album/AlbumCard.vue'))
import AlbumCard from '@/components/album/AlbumCard.vue'
const albums = toRef(overviewStore.state, 'mostPlayedAlbums')
</script>
<style scoped>
</style>

View file

@ -10,9 +10,10 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import { overviewStore } from '@/stores'
const ArtistCard = defineAsyncComponent(() => import('@/components/artist/ArtistCard.vue'))
import ArtistCard from '@/components/artist/ArtistCard.vue'
const artists = toRef(overviewStore.state, 'mostPlayedArtists')
</script>

View file

@ -11,10 +11,10 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import { overviewStore } from '@/stores'
const SongCard = defineAsyncComponent(() => import('@/components/song/SongCard.vue'))
import SongCard from '@/components/song/SongCard.vue'
const songs = toRef(overviewStore.state, 'mostPlayedSongs')
</script>

View file

@ -10,10 +10,10 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import { overviewStore } from '@/stores'
const AlbumCard = defineAsyncComponent(() => import('@/components/album/AlbumCard.vue'))
import AlbumCard from '@/components/album/AlbumCard.vue'
const albums = toRef(overviewStore.state, 'recentlyAddedAlbums')
</script>

View file

@ -10,10 +10,10 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import { overviewStore } from '@/stores'
const SongCard = defineAsyncComponent(() => import('@/components/song/SongCard.vue'))
import SongCard from '@/components/song/SongCard.vue'
const songs = toRef(overviewStore.state, 'recentlyAddedSongs')
</script>

View file

@ -27,13 +27,12 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, toRef } from 'vue'
import { toRef } from 'vue'
import router from '@/router'
import { recentlyPlayedStore } from '@/stores'
import Btn from '@/components/ui/Btn.vue'
const SongCard = defineAsyncComponent(() => import('@/components/song/SongCard.vue'))
import SongCard from '@/components/song/SongCard.vue'
const songs = toRef(recentlyPlayedStore.excerptState, 'songs')

View file

@ -22,7 +22,9 @@
</Btn>
</h1>
<ul v-if="excerpt.songs.length">
<li is="vue:SongCard" v-for="song in excerpt.songs" :key="song.id" :song="song"/>
<li v-for="song in excerpt.songs" :key="song.id">
<SongCard :song="song"/>
</li>
</ul>
<p v-else>None found.</p>
</section>
@ -60,17 +62,17 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, ref, toRef } from 'vue'
import { ref, toRef } from 'vue'
import { eventBus } from '@/utils'
import { searchStore } from '@/stores'
import router from '@/router'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
const ScreenEmptyState = defineAsyncComponent(() => import('@/components/ui/ScreenEmptyState.vue'))
const SongCard = defineAsyncComponent(() => import('@/components/song/SongCard.vue'))
const ArtistCard = defineAsyncComponent(() => import('@/components/artist/ArtistCard.vue'))
const AlbumCard = defineAsyncComponent(() => import('@/components/album/AlbumCard.vue'))
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
import ScreenEmptyState from '@/components/ui/ScreenEmptyState.vue'
import ArtistCard from '@/components/artist/ArtistCard.vue'
import AlbumCard from '@/components/album/AlbumCard.vue'
import Btn from '@/components/ui/Btn.vue'
import SongCard from '@/components/song/SongCard.vue'
const excerpt = toRef(searchStore.state, 'excerpt')
const q = ref('')

View file

@ -22,12 +22,12 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, toRef, toRefs } from 'vue'
import { computed, toRef, toRefs } from 'vue'
import { searchStore } from '@/stores'
import { useSongList } from '@/composables'
import { pluralize } from '@/utils'
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
const props = defineProps<{ q: string }>()
const { q } = toRefs(props)

View file

@ -75,13 +75,13 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, nextTick, ref, toRef, toRefs, watch } from 'vue'
import { computed, nextTick, ref, toRef, toRefs, watch } from 'vue'
import { alerts, pluralize } from '@/utils'
import { playlistStore, queueStore } from '@/stores'
import { useSongMenuMethods } from '@/composables'
import router from '@/router'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import Btn from '@/components/ui/Btn.vue'
const props = defineProps<{ songs: Song[], showing: Boolean, config: AddToMenuConfig }>()
const { songs, showing, config } = toRefs(props)

View file

@ -132,19 +132,18 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, reactive, ref, toRefs } from 'vue'
import { computed, reactive, ref, toRefs } from 'vue'
import { isEqual } from 'lodash'
import { alerts, arrayify, defaultCover, pluralize } from '@/utils'
import { songStore } from '@/stores'
import Btn from '@/components/ui/Btn.vue'
import SoundBar from '@/components/ui/SoundBar.vue'
type EditFormData = Pick<Song, 'title' | 'album_name' | 'artist_name' | 'album_artist_name' | 'lyrics' | 'track' | 'disc'>
type TabName = 'details' | 'lyrics'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const SoundBar = defineAsyncComponent(() => import('@/components/ui/SoundBar.vue'))
const props = withDefaults(defineProps<{ songs: Song[], initialTab: TabName }>(), { initialTab: 'details' })
const { songs, initialTab } = toRefs(props)

View file

@ -85,7 +85,7 @@
<script lang="ts" setup>
import isMobile from 'ismobilejs'
import { findIndex } from 'lodash'
import { computed, defineAsyncComponent, inject, nextTick, onMounted, ref, watch } from 'vue'
import { computed, inject, nextTick, onMounted, ref, watch } from 'vue'
import { $, eventBus, startDragging } from '@/utils'
import {
SelectedSongsKey,
@ -96,8 +96,8 @@ import {
SongsKey
} from '@/symbols'
const VirtualScroller = defineAsyncComponent(() => import('@/components/ui/VirtualScroller.vue'))
const SongListItem = defineAsyncComponent(() => import('@/components/song/SongListItem.vue'))
import VirtualScroller from '@/components/ui/VirtualScroller.vue'
import SongListItem from '@/components/song/SongListItem.vue'
const emit = defineEmits(['press:enter', 'press:delete', 'reorder', 'sort', 'scrolled-to-end'])

View file

@ -85,12 +85,12 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, inject, nextTick, onMounted, onUnmounted, ref, toRefs } from 'vue'
import { computed, inject, nextTick, onMounted, onUnmounted, ref, toRefs } from 'vue'
import { SelectedSongsKey, SongsKey } from '@/symbols'
const AddToMenu = defineAsyncComponent(() => import('./AddToMenu.vue'))
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const BtnGroup = defineAsyncComponent(() => import('@/components/ui/BtnGroup.vue'))
import AddToMenu from '@/components/song/AddToMenu.vue'
import Btn from '@/components/ui/Btn.vue'
import BtnGroup from '@/components/ui/BtnGroup.vue'
const props = withDefaults(defineProps<{ config?: Partial<SongListControlsConfig> }>(), { config: () => ({}) })
const { config } = toRefs(props)

View file

@ -1,19 +1,9 @@
<template>
<span class="btn-group">
<slot>
<Btn green>Foo</Btn>
<Btn orange>Bar</Btn>
<Btn red>Baz</Btn>
</slot>
<slot></slot>
</span>
</template>
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
</script>
<style lang="scss">
.btn-group {
display: flex;

View file

@ -11,11 +11,11 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, onMounted, ref } from 'vue'
import { onMounted, ref } from 'vue'
import initVisualizer from '@/utils/visualizer'
import { eventBus } from '@/utils'
const CloseModalBtn = defineAsyncComponent(() => import('@/components/ui/BtnCloseModal.vue'))
import CloseModalBtn from '@/components/ui/BtnCloseModal.vue'
const el = ref<HTMLElement>()
const isFullscreen = ref(false)

View file

@ -45,13 +45,13 @@
<script lang="ts" setup>
import { isEqual } from 'lodash'
import { defineAsyncComponent, reactive, ref } from 'vue'
import { reactive, ref } from 'vue'
import { CreateUserData, userStore } from '@/stores'
import { alerts, parseValidationError } from '@/utils'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const SoundBar = defineAsyncComponent(() => import('@/components/ui/SoundBar.vue'))
const TooltipIcon = defineAsyncComponent(() => import('@/components/ui/TooltipIcon.vue'))
import Btn from '@/components/ui/Btn.vue'
import SoundBar from '@/components/ui/SoundBar.vue'
import TooltipIcon from '@/components/ui/TooltipIcon.vue'
const loading = ref(false)

View file

@ -25,13 +25,13 @@
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, toRefs } from 'vue'
import { computed, ref, toRefs } from 'vue'
import { userStore } from '@/stores'
import { alerts } from '@/utils'
import { useAuthorization } from '@/composables'
import router from '@/router'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
import Btn from '@/components/ui/Btn.vue'
const props = defineProps<{ user: User }>()
const { user } = toRefs(props)

View file

@ -44,13 +44,13 @@
<script lang="ts" setup>
import { isEqual } from 'lodash'
import { defineAsyncComponent, reactive, ref, toRefs } from 'vue'
import { reactive, ref, toRefs } from 'vue'
import { alerts, parseValidationError } from '@/utils'
import { UpdateUserData, userStore } from '@/stores'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
const SoundBar = defineAsyncComponent(() => import('@/components/ui/SoundBar.vue'))
const TooltipIcon = defineAsyncComponent(() => import('@/components/ui/TooltipIcon.vue'))
import Btn from '@/components/ui/Btn.vue'
import SoundBar from '@/components/ui/SoundBar.vue'
import TooltipIcon from '@/components/ui/TooltipIcon.vue'
const props = defineProps<{ user: User }>()
const { user } = toRefs(props)

View file

@ -1,9 +1,9 @@
import { defineAsyncComponent, reactive, ref } from 'vue'
import { reactive, ref } from 'vue'
import ContextMenuBase from '@/components/ui/ContextMenuBase.vue'
export type ContextMenuContext = Record<string, any>
export const useContextMenu = () => {
const ContextMenuBase = defineAsyncComponent(() => import('@/components/ui/ContextMenuBase.vue'))
const base = ref<InstanceType<typeof ContextMenuBase>>()
const context = reactive<ContextMenuContext>({})

View file

@ -1,8 +1,7 @@
import { defineAsyncComponent, ref } from 'vue'
import { ref } from 'vue'
import ToTopButton from '@/components/ui/BtnScrollToTop.vue'
export const useInfiniteScroll = (loadMore: Closure) => {
const ToTopButton = defineAsyncComponent(() => import('@/components/ui/BtnScrollToTop.vue'))
const scroller = ref<HTMLElement>()
const scrolling = ({ target }: { target: HTMLElement }) => {

View file

@ -1,7 +1,7 @@
import { useAuthorization } from '@/composables/useAuthorization'
import compareVersions from 'compare-versions'
import { commonStore } from '@/stores'
import { computed, toRef } from 'vue'
import { commonStore } from '@/stores'
import { useAuthorization } from '@/composables/useAuthorization'
export const useNewVersionNotification = () => {
const { isAdmin } = useAuthorization()

View file

@ -1,14 +1,10 @@
import { computed, provide, reactive, Ref, ref } from 'vue'
import isMobile from 'ismobilejs'
import { orderBy } from 'lodash'
import isMobile from 'ismobilejs'
import { computed, provide, reactive, Ref, ref } from 'vue'
import { playbackService } from '@/services'
import { queueStore, songStore } from '@/stores'
import router from '@/router'
import ControlsToggle from '@/components/ui/ScreenControlsToggle.vue'
import SongList from '@/components/song/SongList.vue'
import SongListControls from '@/components/song/SongListControls.vue'
import {
SelectedSongsKey,
SongListConfigKey,
@ -18,6 +14,10 @@ import {
SongsKey
} from '@/symbols'
import ControlsToggle from '@/components/ui/ScreenControlsToggle.vue'
import SongList from '@/components/song/SongList.vue'
import SongListControls from '@/components/song/SongListControls.vue'
export const useSongList = (
songs: Ref<Song[]>,
type: SongListType,

View file

@ -59,7 +59,7 @@
</template>
<div class="login-wrapper" v-else>
<login-form @loggedin="onUserLoggedIn"/>
<LoginForm @loggedin="onUserLoggedIn"/>
</div>
</div>
</template>
@ -70,12 +70,11 @@ import { authService, socketService } from '@/services'
import { preferenceStore, userStore } from '@/stores'
import { computed, defineAsyncComponent, nextTick, onMounted, ref, toRef, watch } from 'vue'
import LoginForm from '@/components/auth/LoginForm.vue'
const MAX_RETRIES = 10
const DEFAULT_VOLUME = 7
const AlbumArtOverlay = defineAsyncComponent(() => import('@/components/ui/AlbumArtOverlay.vue'))
const LoginForm = defineAsyncComponent(() => import('@/components/auth/LoginForm.vue'))
const volumeSlider = ref<SliderElement>()
const authenticated = ref(false)

View file

@ -1,9 +1,7 @@
import { shuffle, throttle } from 'lodash'
import plyr from 'plyr'
import { nextTick } from 'vue'
import isMobile from 'ismobilejs'
import { eventBus, isAudioContextSupported } from '@/utils'
import plyr from 'plyr'
import { shuffle, throttle } from 'lodash'
import { nextTick } from 'vue'
import {
commonStore,
@ -14,6 +12,7 @@ import {
userStore
} from '@/stores'
import { eventBus, isAudioContextSupported } from '@/utils'
import { audioService, socketService } from '@/services'
import router from '@/router'

View file

@ -7,7 +7,7 @@ export const socketService = {
pusher: null as Pusher.Pusher | null,
channel: null as Pusher.Channel | null,
async init (): Promise<void> {
async init () {
return new Promise(resolve => {
if (!window.PUSHER_APP_KEY) {
return resolve()
@ -31,12 +31,12 @@ export const socketService = {
},
broadcast (eventName: string, data: any = {}) {
this.channel && this.channel.trigger(`client-${eventName}.${userStore.current.id}`, data)
this.channel?.trigger(`client-${eventName}.${userStore.current.id}`, data)
return this
},
listen (eventName: string, cb: Closure) {
this.channel && this.channel.bind(`client-${eventName}.${userStore.current.id}`, data => cb(data))
this.channel?.bind(`client-${eventName}.${userStore.current.id}`, data => cb(data))
return this
}
}

View file

@ -4,11 +4,11 @@ import router from '@/router'
interface YouTubeSearchResult {
nextPageToken: string
items: Array<Record<string, any>>
items: Record<string, any>[]
}
export const youTubeService = {
searchVideosRelatedToSong: async (song: Song, nextPageToken: string): Promise<YouTubeSearchResult> => {
searchVideosRelatedToSong: async (song: Song, nextPageToken: string) => {
return await httpService.get<YouTubeSearchResult>(`youtube/search/song/${song.id}?pageToken=${nextPageToken}`)
},

View file

@ -1,5 +1,4 @@
import { arrayify } from '@/utils/helpers'
import { pluralize } from '@/utils/formatters'
import { arrayify, pluralize } from '@/utils'
import { albumStore, artistStore, songStore } from '@/stores'
const createGhostDragImage = (event: DragEvent, text: string): void => {