Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • petre/nextcloud-app-podcast
  • onny/nextcloud-app-podcast
2 results
Show changes
Showing
with 1471 additions and 643 deletions
/*
* @copyright Copyright (c) 2020 Jonas Heinrich <onny@project-insanity.org>
* @copyright Copyright (c) 2021 Jonas Heinrich <onny@project-insanity.org>
*
* @author Jonas Heinrich <onny@project-insanity.org>
*
......@@ -22,7 +22,7 @@
import Vue from 'vue'
import router from './router'
import store from './store'
import store from './store/main'
import Dashboard from './components/Dashboard.vue'
import { translate, translatePlural } from '@nextcloud/l10n'
......
/*
* @copyright Copyright (c) 2020 Jonas Heinrich <onny@project-insanity.org>
* @copyright Copyright (c) 2021 Jonas Heinrich <onny@project-insanity.org>
*
* @author Jonas Heinrich <onny@project-insanity.org>
*
......@@ -22,22 +22,22 @@
import Vue from 'vue'
import router from './router'
import store from './store'
import store from './store/main'
import { translate, translatePlural } from '@nextcloud/l10n'
import App from './App'
import VueResizeObserver from 'vue-resize-observer'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)
Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = window.OC
Vue.prototype.OCA = window.OCA
Vue.prototype.$apiUrl = 'https://api.fyyd.de/0.2'
Vue.prototype.$version = '0.0.1'
Vue.use(VueResizeObserver)
Vue.prototype.$version = '0.3.1'
export default new Vue({
el: '#content',
......
/*
* @copyright Copyright (c) 2020 Jonas Heinrich <onny@project-insanity.org>
* @copyright Copyright (c) 2021 Jonas Heinrich <onny@project-insanity.org>
*
* @author Jonas Heinrich <onny@project-insanity.org>
*
......@@ -23,33 +23,32 @@
import Vue from 'vue'
import Router from 'vue-router'
import { generateUrl } from '@nextcloud/router'
import axios from '@nextcloud/axios'
import Main from './components/Main'
import Library from './views/Library'
import BrowseAll from './views/BrowseAll'
import Show from './views/Show'
import Episode from './views/Episode'
import Browse from './views/Browse'
import BrowseAll from './views/BrowseAll'
import NotImplemented from './views/NotImplemented'
import store from './store.js'
import BrowseEmpty from './views/placeholder/Browse'
import Listening from './views/Listening'
Vue.use(Router)
const requesttoken = axios.defaults.headers.requesttoken
const router = new Router({
base: generateUrl('/apps/podcast/'),
linkActiveClass: 'active',
routes: [
{
path: '/',
redirect: '/listening',
},
{
path: '/listening',
component: BrowseEmpty,
component: Listening,
name: 'LISTENING',
},
{
path: '/library',
component: NotImplemented,
component: Library,
name: 'LIBRARY',
},
{
......@@ -58,9 +57,14 @@ const router = new Router({
name: 'BROWSE',
},
{
path: '/browse/hot',
path: '/browse/:category',
component: BrowseAll,
name: 'BROWSE',
name: 'BROWSE_CATEGORY',
},
{
path: '/browse/category/:categoryId',
component: BrowseAll,
name: 'BROWSE_CATEGORYID',
},
{
path: '/browse/show/:id',
......@@ -74,32 +78,7 @@ const router = new Router({
name: 'EPISODE',
props: {},
},
{
path: '/search/:query',
component: Main,
name: 'SEARCH',
props: {},
},
],
})
router.beforeEach((to, from, next) => {
if (to.name) {
store.dispatch('setMenuState', to.name)
next()
} else {
axios.defaults.headers.requesttoken = requesttoken
axios
.get(generateUrl('/apps/podcast/settings/menuState'))
.then(async response => {
const {
data: { menuState: value },
} = response
next({ name: value })
})
}
})
export default router
/*
* @copyright Copyright (c) 2021 Jonas Heinrich <onny@project-insanity.org>
*
* @author Jonas Heinrich <onny@project-insanity.org>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
export class EpisodeApi {
url(url) {
url = `/apps/podcast/api${url}`
return generateUrl(url)
}
addEpisode(episode) {
episode = {
id: episode.id,
imgURL: episode.imgURL,
title: episode.title,
pubdate: episode.pubdate,
duration: episode.duration,
playtime: 0,
lastplayed: Date.now(),
enclosure: episode.enclosure,
description: episode.description.substring(0, 100), // Trim string description, because of MySQL max length field
podcast_id: episode.podcast_id,
}
return axios.post(this.url('/episodes'), episode)
.then(
(response) => {
return Promise.resolve(response.data)
},
(err) => {
return Promise.reject(err)
}
)
.catch((err) => {
return Promise.reject(err)
})
}
removeEpisode(episode) {
return axios.delete(this.url(`/episodes/${episode.id}`))
.then(
(response) => {
return Promise.resolve(response.data)
},
(err) => {
return Promise.reject(err)
}
)
.catch((err) => {
return Promise.reject(err)
})
}
queryEpisodes(podcastId = null, page = 0, sortBy = 'lastplayed') {
let params = {}
if (podcastId) {
params = {
podcast_id: podcastId,
count: 20,
page,
}
} else {
params = {
count: 20,
page,
sortBy,
}
}
return axios.get(this.url('/episodes'), {
params,
})
.then(
(response) => {
return Promise.resolve(response.data)
},
(err) => {
return Promise.reject(err)
}
)
.catch((err) => {
return Promise.reject(err)
})
}
queryEpisode(episodeId) {
return axios.get(this.url('/episodes'), {
params: {
episode_id: episodeId,
},
})
.then(
(response) => {
return Promise.resolve(response.data)
},
(err) => {
return Promise.reject(err)
}
)
.catch((err) => {
return Promise.reject(err)
})
}
updateEpisode({ episode, playtime } = {}) {
episode = {
id: episode.id,
imgURL: episode.imgURL,
title: episode.title,
pubdate: episode.pubdate,
duration: episode.duration,
playtime,
lastplayed: Date.now(),
enclosure: episode.enclosure,
description: episode.description.substring(0, 100), // Trim string description, because of MySQL max length field
podcast_id: episode.podcast_id,
}
return axios.put(this.url(`/episodes/${episode.id}`), episode)
.then(
(response) => {
return Promise.resolve(response.data)
},
(err) => {
return Promise.reject(err)
}
)
.catch((err) => {
return Promise.reject(err)
})
}
}
/*
* @copyright Copyright (c) 2021 Jonas Heinrich <onny@project-insanity.org>
*
* @author Jonas Heinrich <onny@project-insanity.org>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { Howl, Howler } from 'howler'
import store from './../store/main.js'
let audioPlayer = null
export class Player {
load(src) {
if (audioPlayer !== null) {
audioPlayer.fade(store.getters.getVolume, 0, 500)
Howler.unload()
} else {
this.updateSeek()
}
audioPlayer = new Howl({
src,
html5: true,
volume: store.getters.getVolume,
onLoad() {
store.dispatch('setBuffering', true)
},
onplay() {
store.dispatch('setPlaying', true)
store.dispatch('setBuffering', false)
store.dispatch('setPausing', false)
},
onpause() {
store.dispatch('setPlaying', false)
store.dispatch('setPausing', true)
store.dispatch('setBuffering', false)
},
onend() {
store.dispatch('setPlaying', false)
},
})
audioPlayer.unload()
}
play() {
audioPlayer.play()
audioPlayer.fade(0, store.getters.getVolume, 500)
}
pause() {
audioPlayer.pause()
}
resume() {
audioPlayer.play()
}
seek(startTime) {
audioPlayer.seek(startTime)
}
volume(volume) {
if (audioPlayer !== null) {
audioPlayer.volume(volume)
}
}
state() {
return audioPlayer
}
getSeek() {
return audioPlayer.seek()
}
updateSeek() {
const vm = this
setTimeout(function() {
if (audioPlayer !== null) {
if (audioPlayer.state() === 'loaded') {
const seek = audioPlayer.seek()
store.dispatch('setSeek', seek)
store.dispatch('storePlaybacktime', seek)
}
vm.updateSeek()
}
}, 1000)
}
}
This diff is collapsed.
import { Howl, Howler } from 'howler'
import { showError } from '@nextcloud/dialogs'
export let audioPlayer
audioPlayer = null
export function doPlay(episode) {
const vm = this
vm.$store.dispatch('isBuffering', true)
if (audioPlayer !== null) {
audioPlayer.fade(vm.player.volume, 0, 500)
}
vm.$store.dispatch('setTitle', episode.title)
Howler.unload()
audioPlayer = new Howl({
src: episode.enclosure,
html5: true,
volume: vm.player.volume,
onplay() {
vm.$store.dispatch('isPlaying', true)
vm.$store.dispatch('isBuffering', false)
},
onpause() {
vm.$store.dispatch('isPlaying', false)
vm.$store.dispatch('isBuffering', false)
},
onend() {
showError(t('podcast', 'Lost connection to podcast station, retrying ...'))
vm.$store.dispatch('isPlaying', false)
vm.$store.dispatch('isBuffering', true)
},
})
audioPlayer.unload()
audioPlayer.play()
audioPlayer.fade(0, vm.player.volume, 500)
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.