2022-06-10 10:47:46 +00:00
|
|
|
import { orderBy } from 'lodash'
|
2022-07-07 18:05:46 +00:00
|
|
|
import isMobile from 'ismobilejs'
|
|
|
|
import { computed, provide, reactive, Ref, ref } from 'vue'
|
2022-04-24 08:50:45 +00:00
|
|
|
import { playbackService } from '@/services'
|
2022-04-25 16:38:33 +00:00
|
|
|
import { queueStore, songStore } from '@/stores'
|
|
|
|
import router from '@/router'
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-07-05 15:09:20 +00:00
|
|
|
import {
|
|
|
|
SelectedSongsKey,
|
|
|
|
SongListConfigKey,
|
|
|
|
SongListSortFieldKey,
|
|
|
|
SongListSortOrderKey,
|
|
|
|
SongListTypeKey,
|
|
|
|
SongsKey
|
|
|
|
} from '@/symbols'
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-07-07 18:05:46 +00:00
|
|
|
import ControlsToggle from '@/components/ui/ScreenControlsToggle.vue'
|
|
|
|
import SongList from '@/components/song/SongList.vue'
|
|
|
|
import SongListControls from '@/components/song/SongListControls.vue'
|
|
|
|
|
2022-06-10 10:47:46 +00:00
|
|
|
export const useSongList = (
|
|
|
|
songs: Ref<Song[]>,
|
|
|
|
type: SongListType,
|
|
|
|
config: Partial<SongListConfig> = {}
|
|
|
|
) => {
|
2022-04-23 21:24:02 +00:00
|
|
|
const songList = ref<InstanceType<typeof SongList>>()
|
2022-04-15 14:24:30 +00:00
|
|
|
|
2022-04-23 21:24:02 +00:00
|
|
|
const isPhone = isMobile.phone
|
2022-04-15 14:24:30 +00:00
|
|
|
const selectedSongs = ref<Song[]>([])
|
|
|
|
const showingControls = ref(false)
|
|
|
|
|
2022-04-23 21:24:02 +00:00
|
|
|
const duration = computed(() => 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-24 08:50:45 +00:00
|
|
|
const playAll = (shuffle: boolean) => playbackService.queueAndPlay(getSongsToPlay(), shuffle)
|
|
|
|
const playSelected = (shuffle: boolean) => playbackService.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])
|
2022-04-24 08:50:45 +00:00
|
|
|
await playbackService.play(selectedSongs.value[0])
|
2022-04-21 18:12:11 +00:00
|
|
|
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) {
|
2022-04-24 08:50:45 +00:00
|
|
|
await playbackService.play(selectedSongs.value[0])
|
2022-04-21 18:12:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
router.go('/queue')
|
|
|
|
}
|
|
|
|
|
2022-07-05 15:09:20 +00:00
|
|
|
const sortField = ref<SongListSortField | null>(((): SongListSortField | null => {
|
|
|
|
if (type === 'album' || type === 'artist') return 'track'
|
|
|
|
if (type === 'search-results') return null
|
|
|
|
return config.sortable ? 'title' : null
|
|
|
|
})())
|
2022-06-10 10:47:46 +00:00
|
|
|
|
2022-07-05 15:09:20 +00:00
|
|
|
const sortOrder = ref<SortOrder>('asc')
|
2022-06-10 10:47:46 +00:00
|
|
|
|
2022-07-05 15:09:20 +00:00
|
|
|
const sort = (by: SongListSortField | null = sortField.value, order: SortOrder = sortOrder.value) => {
|
|
|
|
if (!by) return
|
|
|
|
|
|
|
|
sortField.value = by
|
|
|
|
sortOrder.value = order
|
|
|
|
|
|
|
|
let sortFields: SongListSortField[] = [by]
|
|
|
|
|
|
|
|
if (by === 'track') {
|
2022-06-10 10:47:46 +00:00
|
|
|
sortFields.push('disc', 'title')
|
2022-07-05 15:09:20 +00:00
|
|
|
} else if (by === 'album_name') {
|
2022-06-10 10:47:46 +00:00
|
|
|
sortFields.push('artist_name', 'track', 'disc', 'title')
|
2022-07-05 15:09:20 +00:00
|
|
|
} else if (by === 'artist_name') {
|
2022-06-10 10:47:46 +00:00
|
|
|
sortFields.push('album_name', 'track', 'disc', 'title')
|
|
|
|
}
|
|
|
|
|
2022-07-05 15:09:20 +00:00
|
|
|
songs.value = orderBy(songs.value, sortFields, order)
|
2022-06-10 10:47:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
provide(SongListTypeKey, type)
|
|
|
|
provide(SongsKey, songs)
|
|
|
|
provide(SelectedSongsKey, selectedSongs)
|
|
|
|
provide(SongListConfigKey, reactive(config))
|
2022-07-05 15:09:20 +00:00
|
|
|
provide(SongListSortFieldKey, sortField)
|
|
|
|
provide(SongListSortOrderKey, sortOrder)
|
2022-06-10 10:47:46 +00:00
|
|
|
|
2022-04-15 14:24:30 +00:00
|
|
|
return {
|
|
|
|
SongList,
|
|
|
|
SongListControls,
|
2022-06-10 10:47:46 +00:00
|
|
|
ControlsToggle,
|
2022-04-21 16:06:45 +00:00
|
|
|
songs,
|
2022-07-05 15:09:20 +00:00
|
|
|
sortField,
|
|
|
|
sortOrder,
|
2022-04-23 21:24:02 +00:00
|
|
|
duration,
|
2022-04-15 14:24:30 +00:00
|
|
|
songList,
|
|
|
|
selectedSongs,
|
|
|
|
showingControls,
|
|
|
|
isPhone,
|
2022-04-21 18:12:11 +00:00
|
|
|
onPressEnter,
|
2022-04-15 14:24:30 +00:00
|
|
|
playAll,
|
|
|
|
playSelected,
|
2022-06-10 10:47:46 +00:00
|
|
|
toggleControls,
|
|
|
|
sort
|
2022-04-15 14:24:30 +00:00
|
|
|
}
|
|
|
|
}
|