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: [], history_playlist: [], playlist_id: 0, history_group: [], index: 0, volume: 0.5, tab: 'now', 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' }, }, 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); }, 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; }, 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(); } } }, 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 === '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('saveMyPlaylist', playlist); commit('replacePlaylist', playlist); commit('initVolume'); resolve(playlist) }) .catch(() => { //commit(mutationTypes.getArticleFailure) }) }) }, async loadExsitPlaylist({ state, commit, dispatch }) { if(state.local_current_playlist_id){ dispatch('instanceHowl', 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 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 instanceHowl({dispatch, commit}, payload){ let objectHowl = {}; objectHowl = new Howl({ src: [payload.url], html5: true, onend: () => { dispatch('skipTrack', 'next'); } }); objectHowl.on('play', () => { requestAnimationFrame(() => { dispatch('progress'); }); }); 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'); }); }, }, };