2022-04-15 14:24:30 +00:00
|
|
|
/**
|
|
|
|
* Add necessary functionalities into a view that contains a song-list component.
|
|
|
|
*/
|
2022-04-21 16:06:45 +00:00
|
|
|
import { ComponentInternalInstance, getCurrentInstance, reactive, Ref, ref, watchEffect } from 'vue'
|
2022-04-15 14:24:30 +00:00
|
|
|
import isMobile from 'ismobilejs'
|
|
|
|
|
|
|
|
import { playback } from '@/services'
|
|
|
|
import { eventBus } from '@/utils'
|
|
|
|
|
2022-04-21 16:06:45 +00:00
|
|
|
import ControlsToggler from '@/components/ui/ScreenControlsToggler.vue'
|
|
|
|
import SongList from '@/components/song/SongList.vue'
|
|
|
|
import SongListControls from '@/components/song/SongListControls.vue'
|
2022-04-21 18:12:11 +00:00
|
|
|
import { queueStore, songStore } from '@/stores'
|
|
|
|
import router from '@/router'
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-04-21 16:06:45 +00:00
|
|
|
export const useSongList = (songs: Ref<Song[]>, controlsConfig: Partial<SongListControlsConfig> = {}) => {
|
2022-04-20 09:37:22 +00:00
|
|
|
const songList = ref<InstanceType<typeof SongList>>()
|
2022-04-21 16:06:45 +00:00
|
|
|
const vm = getCurrentInstance()
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-04-15 17:00:08 +00:00
|
|
|
const meta = reactive<SongListMeta>({
|
2022-04-15 14:24:30 +00:00
|
|
|
songCount: 0,
|
|
|
|
totalLength: '00:00'
|
|
|
|
})
|
|
|
|
|
|
|
|
const selectedSongs = ref<Song[]>([])
|
|
|
|
const showingControls = ref(false)
|
2022-04-15 17:00:08 +00:00
|
|
|
const songListControlConfig = reactive(controlsConfig)
|
2022-04-15 14:24:30 +00:00
|
|
|
const isPhone = isMobile.phone
|
|
|
|
|
|
|
|
watchEffect(() => {
|
2022-04-21 16:06:45 +00:00
|
|
|
if (!songs.value.length) {
|
2022-04-15 14:24:30 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-04-21 16:06:45 +00:00
|
|
|
meta.songCount = songs.value.length
|
|
|
|
meta.totalLength = songStore.getFormattedLength(songs.value)
|
2022-04-15 14:24:30 +00:00
|
|
|
})
|
|
|
|
|
2022-04-20 09:37:22 +00:00
|
|
|
const getSongsToPlay = (): Song[] => songList.value.getAllSongsWithSort()
|
2022-04-21 18:12:11 +00:00
|
|
|
const playAll = (shuffle: boolean) => playback.queueAndPlay(getSongsToPlay(), shuffle)
|
|
|
|
const playSelected = (shuffle: boolean) => playback.queueAndPlay(selectedSongs.value, shuffle)
|
2022-04-15 14:24:30 +00:00
|
|
|
const toggleControls = () => (showingControls.value = !showingControls.value)
|
|
|
|
|
2022-04-21 18:12:11 +00:00
|
|
|
const onPressEnter = async (event: KeyboardEvent) => {
|
|
|
|
if (selectedSongs.value.length === 1) {
|
|
|
|
queueStore.queueIfNotQueued(selectedSongs.value[0])
|
|
|
|
await playback.play(selectedSongs.value[0])
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// • Only Enter: Queue songs to bottom
|
|
|
|
// • Shift+Enter: Queues song to top
|
|
|
|
// • Cmd/Ctrl+Enter: Queues song to bottom and play the first selected song
|
|
|
|
// • Cmd/Ctrl+Shift+Enter: Queue songs to top and play the first queued song
|
|
|
|
event.shiftKey ? queueStore.queueToTop(selectedSongs.value) : queueStore.queue(selectedSongs.value)
|
|
|
|
|
|
|
|
if (event.ctrlKey || event.metaKey) {
|
|
|
|
await playback.play(selectedSongs.value[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
router.go('/queue')
|
|
|
|
}
|
|
|
|
|
2022-04-15 14:24:30 +00:00
|
|
|
eventBus.on({
|
2022-04-15 17:00:08 +00:00
|
|
|
SET_SELECTED_SONGS (songs: Song[], target: ComponentInternalInstance) {
|
2022-04-21 16:06:45 +00:00
|
|
|
target === vm && (selectedSongs.value = songs)
|
2022-04-15 14:24:30 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return {
|
|
|
|
SongList,
|
|
|
|
SongListControls,
|
|
|
|
ControlsToggler,
|
2022-04-21 16:06:45 +00:00
|
|
|
songs,
|
2022-04-15 14:24:30 +00:00
|
|
|
songList,
|
|
|
|
meta,
|
|
|
|
selectedSongs,
|
|
|
|
showingControls,
|
|
|
|
songListControlConfig,
|
|
|
|
isPhone,
|
2022-04-21 18:12:11 +00:00
|
|
|
onPressEnter,
|
2022-04-15 14:24:30 +00:00
|
|
|
playAll,
|
|
|
|
playSelected,
|
|
|
|
toggleControls
|
|
|
|
}
|
|
|
|
}
|