import axios from '@nextcloud/axios' import { decodeUrl } from '../utils/url.js' import { formatEpisodeTimestamp } from '../utils/time.js' import { generateUrl } from '@nextcloud/router' import router from '../router.js' import store from './main.js' const audio = new Audio() audio.ondurationchange = () => store.commit('player/duration', audio.duration) audio.onended = () => store.dispatch('player/stop') audio.onloadeddata = () => store.commit('player/loaded', true) audio.onplay = () => store.commit('player/paused', false) audio.onpause = () => store.commit('player/paused', true) audio.onratechange = () => store.commit('player/rate', audio.playbackRate) audio.onseeked = () => store.commit('player/currentTime', audio.currentTime) audio.ontimeupdate = () => store.commit('player/currentTime', audio.currentTime) audio.onvolumechange = () => store.commit('player/volume', audio.volume) export const player = { namespaced: true, state: { currentTime: null, duration: null, episode: null, loaded: false, paused: null, podcastUrl: null, volume: 1, rate: 1, started: 0, }, mutations: { action: (state, action) => { state.episode.action = action if (action && action.position && action.position < action.total) { audio.currentTime = action.position state.started = audio.currentTime } }, currentTime: (state, currentTime) => { state.currentTime = currentTime }, duration: (state, duration) => { state.duration = duration }, episode: (state, episode) => { state.episode = episode if (episode) { state.podcastUrl = decodeUrl(router.currentRoute.params.url) audio.src = episode.url audio.load() audio.play() if (episode.action && episode.action.position && episode.action.position < episode.action.total) { audio.currentTime = episode.action.position state.started = audio.currentTime } } else { state.loaded = false state.podcastUrl = null audio.src = '' } }, loaded: (state, loaded) => { state.loaded = loaded }, paused: (state, paused) => { state.paused = paused }, volume: (state, volume) => { state.volume = volume }, rate: (state, rate) => { state.rate = rate }, started: (state, started) => { state.started = started }, }, actions: { load: async (context, episode) => { context.commit('episode', episode) try { const action = await axios.get(generateUrl('/apps/repod/episodes/action?url={url}', { url: episode.url })) context.commit('action', action.data) } catch {} }, pause: (context) => { audio.pause() context.dispatch('time') }, play: (context) => { audio.play() context.commit('started', audio.currentTime) }, seek: (context, currentTime) => { audio.currentTime = currentTime context.dispatch('time') }, stop: (context) => { context.dispatch('pause') context.commit('episode', null) }, time: async (context) => axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [{ podcast: context.state.podcastUrl, episode: context.state.episode.url, guid: context.state.episode.guid, action: 'play', timestamp: formatEpisodeTimestamp(new Date()), started: Math.round(context.state.started), position: Math.round(audio.currentTime), total: Math.round(audio.duration), }]), volume: (_, volume) => { audio.volume = volume }, rate: (_, rate) => { audio.playbackRate = rate }, }, } setInterval(() => { if (player.state.paused === false) { store.dispatch('player/time') } }, 40000)