2024-09-14 16:54:56 +02:00
|
|
|
import type { EpisodeActionInterface, EpisodeInterface } from '../utils/types.ts'
|
2023-08-29 00:47:22 +02:00
|
|
|
import axios from '@nextcloud/axios'
|
2024-08-09 00:58:25 +02:00
|
|
|
import { defineStore } from 'pinia'
|
2024-09-14 16:54:56 +02:00
|
|
|
import { formatEpisodeTimestamp } from '../utils/time.ts'
|
2023-08-29 00:47:22 +02:00
|
|
|
import { generateUrl } from '@nextcloud/router'
|
2024-10-24 00:23:25 +02:00
|
|
|
import { showError } from '../utils/toast.ts'
|
|
|
|
import { t } from '@nextcloud/l10n'
|
2023-08-29 00:47:22 +02:00
|
|
|
|
|
|
|
const audio = new Audio()
|
|
|
|
|
2024-08-09 00:58:25 +02:00
|
|
|
export const usePlayer = defineStore('player', {
|
|
|
|
state: () => ({
|
2024-09-13 08:56:04 +02:00
|
|
|
currentTime: null as number | null,
|
|
|
|
duration: null as number | null,
|
|
|
|
episode: null as EpisodeInterface | null,
|
2023-08-29 00:47:22 +02:00
|
|
|
loaded: false,
|
2024-09-13 08:56:04 +02:00
|
|
|
paused: true,
|
2024-10-24 00:23:25 +02:00
|
|
|
playCount: 0,
|
2024-09-13 08:56:04 +02:00
|
|
|
podcastUrl: null as string | null,
|
2023-08-29 11:43:17 +02:00
|
|
|
volume: 1,
|
2024-01-16 22:12:07 +01:00
|
|
|
rate: 1,
|
2024-01-16 23:13:07 +01:00
|
|
|
started: 0,
|
2024-08-09 00:58:25 +02:00
|
|
|
}),
|
|
|
|
actions: {
|
2024-08-09 22:51:32 +02:00
|
|
|
init() {
|
2024-08-09 16:50:24 +02:00
|
|
|
audio.ondurationchange = () => (this.duration = audio.duration)
|
|
|
|
audio.onended = () => this.stop()
|
|
|
|
audio.onloadeddata = () => (this.loaded = true)
|
|
|
|
audio.onpause = () => this.pause()
|
|
|
|
audio.onplay = () => this.play()
|
|
|
|
audio.onratechange = () => (this.rate = audio.playbackRate)
|
|
|
|
audio.onseeked = () => (this.currentTime = audio.currentTime)
|
|
|
|
audio.ontimeupdate = () => (this.currentTime = audio.currentTime)
|
|
|
|
audio.onvolumechange = () => (this.volume = audio.volume)
|
2024-10-24 00:23:25 +02:00
|
|
|
|
2024-10-24 00:46:04 +02:00
|
|
|
setInterval(this.act, 40000)
|
|
|
|
setInterval(this.conflict, 1000)
|
2024-10-24 00:23:25 +02:00
|
|
|
},
|
2024-10-24 00:46:04 +02:00
|
|
|
act() {
|
|
|
|
if (this.paused === false) {
|
|
|
|
this.time()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
conflict() {
|
2024-10-24 00:23:25 +02:00
|
|
|
this.playCount = 0
|
2024-08-09 16:50:24 +02:00
|
|
|
},
|
2024-09-13 08:56:04 +02:00
|
|
|
async load(episode: EpisodeInterface | null, podcastUrl?: string) {
|
2024-08-09 00:58:25 +02:00
|
|
|
this.episode = episode
|
2024-09-13 08:56:04 +02:00
|
|
|
this.podcastUrl = podcastUrl || null
|
2023-08-29 00:47:22 +02:00
|
|
|
|
2024-09-13 08:56:04 +02:00
|
|
|
if (this.episode?.url) {
|
2024-08-09 00:58:25 +02:00
|
|
|
audio.src = this.episode.url
|
2023-08-29 00:47:22 +02:00
|
|
|
audio.load()
|
2024-08-09 00:58:25 +02:00
|
|
|
|
|
|
|
try {
|
2024-09-13 16:33:48 +02:00
|
|
|
const action = await axios.get<EpisodeActionInterface>(
|
2024-08-09 00:58:25 +02:00
|
|
|
generateUrl('/apps/repod/episodes/action?url={url}', {
|
|
|
|
url: this.episode.url,
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
|
2024-09-02 10:51:21 +02:00
|
|
|
this.episode.action = action.data
|
2024-08-09 00:58:25 +02:00
|
|
|
} catch {}
|
2023-08-29 12:07:23 +02:00
|
|
|
|
2024-04-30 00:48:47 +02:00
|
|
|
if (
|
2024-09-02 10:51:21 +02:00
|
|
|
this.episode.action &&
|
2024-08-09 00:58:25 +02:00
|
|
|
this.episode.action.position < this.episode.action.total
|
2024-04-30 00:48:47 +02:00
|
|
|
) {
|
2024-08-09 00:58:25 +02:00
|
|
|
audio.currentTime = this.episode.action.position
|
|
|
|
this.started = audio.currentTime
|
2023-08-29 12:07:23 +02:00
|
|
|
}
|
2024-08-09 00:58:25 +02:00
|
|
|
|
|
|
|
audio.play()
|
2023-08-29 00:47:22 +02:00
|
|
|
} else {
|
2024-08-09 00:58:25 +02:00
|
|
|
this.loaded = false
|
|
|
|
this.podcastUrl = null
|
2023-08-29 00:47:22 +02:00
|
|
|
audio.src = ''
|
|
|
|
}
|
|
|
|
},
|
2024-08-09 22:51:32 +02:00
|
|
|
pause() {
|
2023-08-29 00:47:22 +02:00
|
|
|
audio.pause()
|
2024-08-09 00:58:25 +02:00
|
|
|
this.paused = true
|
2024-08-16 23:50:36 +02:00
|
|
|
this.time()
|
2023-08-29 00:47:22 +02:00
|
|
|
},
|
2024-08-09 22:51:32 +02:00
|
|
|
play() {
|
2024-10-24 00:23:25 +02:00
|
|
|
this.playCount++
|
2024-10-24 00:40:44 +02:00
|
|
|
|
2024-10-24 00:23:25 +02:00
|
|
|
if (this.playCount > 10) {
|
|
|
|
showError(t('repod', 'A browser extension conflict with RePod'))
|
|
|
|
} else {
|
|
|
|
audio.play()
|
|
|
|
this.paused = false
|
|
|
|
this.started = audio.currentTime
|
|
|
|
}
|
2024-01-16 22:36:01 +01:00
|
|
|
},
|
2024-09-13 08:56:04 +02:00
|
|
|
seek(currentTime: number) {
|
2023-08-29 00:47:22 +02:00
|
|
|
audio.currentTime = currentTime
|
2024-08-09 00:58:25 +02:00
|
|
|
this.time()
|
2023-08-29 00:47:22 +02:00
|
|
|
},
|
2024-08-09 22:51:32 +02:00
|
|
|
stop() {
|
2024-08-09 00:58:25 +02:00
|
|
|
this.pause()
|
|
|
|
this.episode = null
|
2023-08-29 00:47:22 +02:00
|
|
|
},
|
2024-08-09 22:51:32 +02:00
|
|
|
time() {
|
2024-09-13 08:56:04 +02:00
|
|
|
if (!this.podcastUrl || !this.episode?.url) {
|
|
|
|
return
|
2024-03-05 10:37:16 +01:00
|
|
|
}
|
2024-09-13 08:56:04 +02:00
|
|
|
|
2024-09-14 16:54:56 +02:00
|
|
|
this.episode.action = {
|
|
|
|
podcast: this.podcastUrl,
|
|
|
|
episode: this.episode.url,
|
|
|
|
guid: this.episode.guid,
|
|
|
|
action: 'play',
|
|
|
|
timestamp: formatEpisodeTimestamp(new Date()),
|
|
|
|
started: Math.round(this.started),
|
|
|
|
position: Math.round(audio.currentTime),
|
|
|
|
total: Math.round(audio.duration),
|
2024-09-13 08:56:04 +02:00
|
|
|
}
|
|
|
|
|
2024-04-30 00:48:47 +02:00
|
|
|
axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [
|
2024-08-09 00:58:25 +02:00
|
|
|
this.episode.action,
|
2024-04-30 00:48:47 +02:00
|
|
|
])
|
2024-03-05 10:37:16 +01:00
|
|
|
},
|
2024-09-13 08:56:04 +02:00
|
|
|
setVolume(volume: number) {
|
2023-08-29 00:47:22 +02:00
|
|
|
audio.volume = volume
|
|
|
|
},
|
2024-09-13 08:56:04 +02:00
|
|
|
setRate(rate: number) {
|
2024-01-16 22:12:07 +01:00
|
|
|
audio.playbackRate = rate
|
|
|
|
},
|
2023-08-29 00:47:22 +02:00
|
|
|
},
|
2024-08-09 00:58:25 +02:00
|
|
|
})
|