import { Howl, Howler } from 'howler' import axios from 'axios' import helper from '@/includes/helper' export default { state: { currentSong: {}, sound: {}, seek: '0:00', duration: '0:00', playerProgress: '0%', playlist: [], current_playlist: [], my_playlist: [], favorite_playlist: [], playlist_id: 0, history_group: [], index: 0, volume: 0.5, tab: 'now', cursor_favorite: null, cursor_loaded: null, local_current_playlist: JSON.parse(window.localStorage.getItem('local_current_playlist')), local_current_playlist_song: JSON.parse(window.localStorage.getItem('local_current_playlist_song')), local_current_playlist_id: parseInt(window.localStorage.getItem('local_current_playlist_id'), 10), }, getters: { playing: (state) => { if (state.sound.playing) { return state.sound.playing() } return false }, count_playlist: (state) => { return state.playlist.length }, volume_step: (state) => { if (localStorage.volume_player) { return localStorage.volume_player } return state.volume }, tab_now: (state) => { return state.tab === 'now' }, lastFavID: (state) => { return state.favorite_playlist[state.favorite_playlist.length - 1]?.id }, lastLoadedID: (state) => { return state.my_playlist[state.my_playlist.length - 1]?.id }, }, mutations: { saveStorageCurrentPlaylist(state, [music, playlist, playlist_id]) { state.local_current_playlist = playlist state.local_current_playlist_song = music state.local_current_playlist_id = playlist_id window.localStorage.setItem('local_current_playlist', JSON.stringify(playlist)) window.localStorage.setItem('local_current_playlist_song', JSON.stringify(music)) window.localStorage.setItem('local_current_playlist_id', playlist_id) }, // resetPlaylistNow(state, payload) { // state.cursor_favorite = null; // state.current_playlist = playlist; // state.favorite_playlist = []; // }, resetPlaylistNow(state) { state.playlist = state.current_playlist state.cursor_favorite = null state.cursor_loaded = null state.favorite_playlist = [] state.my_playlist = [] }, putCursor(state, payload) { if (state.tab === 'favorite') { state.cursor_favorite = payload } if (state.tab === 'loaded') { state.cursor_loaded = payload } }, savePagination(state, payload) { if (state.tab === 'favorite') { for (const prop in payload) { state.favorite_playlist.push(payload[prop]) } } if (state.tab === 'loaded') { for (const prop in payload) { state.my_playlist.push(payload[prop]) } } }, clearPlaylist(state) { state.playlist = [] }, replaceTabName(state, payload) { state.tab = payload if (payload === 'now') { state.playlist_id = state.local_current_playlist_id } else { state.playlist_id = 0 } }, replacePlaylist(state, payload) { state.playlist = payload }, saveMyPlaylist(state, payload) { state.my_playlist = payload }, saveFavoritePlaylist(state, payload) { state.favorite_playlist = payload }, onlyPlay(state) { if (state.sound instanceof Howl) { state.currentSong.playing = true state.sound.play() } }, onlyStop(state) { if (state.sound instanceof Howl) { state.currentSong.playing = false state.sound.pause() } }, togglePlayMusic(state) { if (state.sound instanceof Howl) { if (state.sound.playing()) { state.currentSong.playing = false state.sound.pause() } else { state.currentSong.playing = true state.sound.play() } } else { state.sound = new Howl(state.sound) state.currentSong.playing = true Howler.volume(state.volume) state.sound.play() } }, initVolume(state) { Howler.volume(state.volume) }, updateVolume(state, payload) { state.volume = payload localStorage.volume_player = payload if (state.sound instanceof Howl) { Howler.volume(payload) } }, updatePosition(state) { state.seek = helper.formatTime(state.sound.seek()) state.duration = helper.formatTime(state.sound.duration()) state.playerProgress = `${(state.sound.seek() / state.sound.duration()) * 100}%` }, currentPlaylistLoad(state, [music, playlist, playlist_id]) { playlist.forEach((track) => { track.playing = false }) music.playing = true state.playlist = playlist state.playlist_id = playlist_id state.index = playlist.findIndex(track => track.id === music.id) state.current_playlist = playlist }, howlReplace(state, [howl, music]) { if (state.sound instanceof Howl) { state.sound.unload() } state.sound = howl state.currentSong = music state.index = state.playlist.findIndex(track => track.id === music.id) }, }, actions: { tabName({ state, commit }, payload) { commit('replaceTabName', payload) if (payload === 'favorite') { if (state.favorite_playlist.length) { commit('replacePlaylist', state.favorite_playlist) } } if (payload === 'loaded') { if (state.my_playlist.length) { commit('replacePlaylist', state.my_playlist) } } if (payload === 'now') { if (state.current_playlist.length) { commit('replacePlaylist', state.current_playlist) } } }, initLoadedPlaylist({ state, commit }) { if (state.my_playlist.length > 0) { return } return new Promise(resolve => { commit('clearPlaylist') axios.get('/loaded-playlist').then(response => response.data) .then(playlist => { commit('putCursor', playlist.cursor) commit('saveMyPlaylist', playlist.collection) commit('replacePlaylist', playlist.collection) commit('initVolume') resolve(playlist) }) .catch(() => { //commit(mutationTypes.getArticleFailure) }) }) }, initFavoritedPlaylist({ state, commit }) { if (state.favorite_playlist.length > 0) { return Promise.resolve() } return new Promise(resolve => { commit('clearPlaylist') axios.get('/favorited-playlist').then(response => response.data) .then(playlist => { commit('putCursor', playlist.cursor) commit('saveFavoritePlaylist', playlist.collection) commit('replacePlaylist', playlist.collection) commit('initVolume') resolve(playlist) }) .catch(() => { //commit(mutationTypes.getArticleFailure) }) }) }, paginationFavPlaylist({ state, commit }) { if (state.cursor_favorite === null) { return Promise.resolve(null) } return new Promise(resolve => { const url = `/favorited-playlist?cursor=${state.cursor_favorite}` axios.get(url).then(response => response.data) .then(playlist => { commit('putCursor', playlist.cursor) commit('savePagination', playlist.collection) resolve(playlist) }) .catch(() => { //commit(mutationTypes.getArticleFailure) }) }) }, paginationLoadedPlaylist({ state, commit }) { if (state.cursor_loaded === null) { return Promise.resolve(null) } return new Promise(resolve => { const url = `/loaded-playlist?cursor=${state.cursor_loaded}` axios.get(url).then(response => response.data) .then(playlist => { commit('putCursor', playlist.cursor) commit('savePagination', playlist.collection) resolve(playlist) }) .catch(() => { //commit(mutationTypes.getArticleFailure) }) }) }, async loadExsitPlaylist({ state, commit, dispatch }) { if (state.local_current_playlist_id) { //dispatch('instanceHowl', state.local_current_playlist_song); dispatch('instanceHowlLazy', state.local_current_playlist_song) commit('currentPlaylistLoad', [ state.local_current_playlist_song, state.local_current_playlist, state.local_current_playlist_id ]) } }, async skipToIndexByMusic({ state, commit, dispatch }, payload) { commit('onlyStop') dispatch('instanceHowl', payload) commit('onlyPlay') if (state.tab === 'now') { commit('saveStorageCurrentPlaylist', [payload, state.playlist, state.playlist_id]) } }, async defaultPlaylistReset({ commit }) { commit('replaceTabName', 'now') commit('resetPlaylistNow') }, async newCurrentPlaylist({ commit, dispatch }, [music, playlist, playlist_id]) { commit('replaceTabName', 'now') commit('onlyStop') dispatch('instanceHowl', music) commit('currentPlaylistLoad', [music, playlist, playlist_id]) commit('initVolume') commit('onlyPlay') commit('saveStorageCurrentPlaylist', [music, playlist, playlist_id]) }, async instanceHowlLazy({ dispatch, commit }, payload) { let objectHowl = { src: [payload.url], html5: true, onend: () => { dispatch('skipTrack', 'next') }, onplay: () => { requestAnimationFrame(() => { dispatch('progress') }) }, } commit('howlReplace', [objectHowl, payload]) }, async instanceHowl({ dispatch, commit }, payload) { let objectHowl = { src: [payload.url], html5: true, //preload: false, onend: () => { dispatch('skipTrack', 'next') }, onplay: () => { requestAnimationFrame(() => { dispatch('progress') }) }, } objectHowl = new Howl(objectHowl) commit('howlReplace', [objectHowl, payload]) }, async skipTrack({ state, dispatch }, payload) { if (!state.playlist.length) { return } let index = 0 if (payload === 'next') { index = state.index + 1 if (index >= state.playlist.length) { index = 0 } } else { index = state.index - 1 if (index < 0) { index = state.playlist.length - 1 } } dispatch('skipToIndexByMusic', state.playlist[index]) }, async changeVolume({ commit }, payload) { commit('updateVolume', payload) }, async toggleAudio({ state, commit }) { // if (!state.sound.playing) { // return; // } commit('togglePlayMusic') }, progress({ commit, state, dispatch }) { commit('updatePosition') if (state.sound.playing()) { requestAnimationFrame(() => { dispatch('progress') }) } }, updateSeek({ state, dispatch }, payload) { if (!state.sound.playing) { return } const { x, width } = payload.currentTarget.getBoundingClientRect() // Document = 2000, Timeline = 1000, Click = 500, Distance = 500 const clickX = payload.clientX - x const percentage = clickX / width const seconds = state.sound.duration() * percentage state.sound.seek(seconds) state.sound.once('seek', () => { dispatch('progress') }) }, }, }