refactor: ♻️ rewrite player store to pinia
Some checks failed
repod / xml (push) Successful in 28s
repod / php (push) Successful in 1m3s
repod / nodejs (push) Failing after 58s
repod / release (push) Has been skipped

This commit is contained in:
Michel Roux 2024-08-09 00:58:25 +02:00
parent 04ed6b101a
commit 082161e177
4 changed files with 63 additions and 121 deletions

View File

@ -1,12 +1,13 @@
import { n, t } from '@nextcloud/l10n' import { n, t } from '@nextcloud/l10n'
import App from './App.vue' import App from './App.vue'
import { createApp } from 'vue' import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router.js' import router from './router.js'
import store from './store/main.js'
const Vue = createApp(App) const Vue = createApp(App)
const pinia = createPinia()
Vue.mixin({ methods: { t, n } }) Vue.mixin({ methods: { t, n } })
Vue.use(pinia)
Vue.use(router) Vue.use(router)
Vue.use(store)
Vue.mount('#content') Vue.mount('#content')

View File

@ -1,3 +0,0 @@
import Vue from 'vue'
export const EventBus = new Vue()

View File

@ -1,17 +0,0 @@
import Vuex, { Store } from 'vuex'
import Vue from 'vue'
import { player } from './player.js'
import { settings } from './settings.js'
import { subscriptions } from './subscriptions.js'
Vue.use(Vuex)
const store = new Store({
modules: {
player,
settings,
subscriptions,
},
})
export default store

View File

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