You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
741 lines
24 KiB
741 lines
24 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>{{.title}} - PodGrab</title>
|
|
{{template "commoncss" .}}
|
|
<link rel="stylesheet" href="/webassets/vue-multiselect.min.css">
|
|
|
|
<style>
|
|
img {
|
|
display: none;
|
|
}
|
|
|
|
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5 {
|
|
margin-bottom: 1rem;
|
|
}
|
|
h4 {
|
|
font-size: 2rem;
|
|
}
|
|
|
|
h5 {
|
|
font-size: 1.5rem;
|
|
}
|
|
p {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
hr {
|
|
margin-top: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.podcastItem .button {
|
|
padding: 0 15px;
|
|
}
|
|
|
|
.IsPlayed-true {
|
|
color: #555555;
|
|
}
|
|
|
|
/* Larger than tablet */
|
|
@media (min-width: 750px) {
|
|
img {
|
|
display: block;
|
|
}
|
|
}
|
|
.button-enqueue{
|
|
display: none;
|
|
}
|
|
body.playerExists .button-enqueue{
|
|
display: inline-block;
|
|
|
|
[v-cloak] {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
{{template "navbar" .}}
|
|
|
|
<br />{{$setting := .setting}}
|
|
|
|
<div id="app" v-cloak>
|
|
|
|
<button @click="toggleFilters()" class="u-full-width">
|
|
<span v-show="!showFilters">Show Filters</span>
|
|
<span v-show="showFilters">Hide Filters</span>
|
|
</button>
|
|
<form @submit.prevent="submitFilters()" v-show="showFilters">
|
|
<div class="row">
|
|
<input class="columns five" type="search" @input="searchQueryUpated()" v-model="filter.q" placeholder="Search">
|
|
<div class="columns three"> <vue-multiselect v-model="selectedSorting" :options="sortOptions" :searchable="false"
|
|
:multiple="false" :close-on-select="true" :clear-on-select="true" :allow-empty="false" :show-labels="false"
|
|
placeholder="Sort By" label="Label" track-by="Value" :preselect-first="true">
|
|
</vue-multiselect></div>
|
|
<div class="columns one"> <vue-multiselect :show-pointer="false" v-model="filter.count" :options="pagingOptions" :searchable="false" :allow-empty="false" :close-on-select="true" :show-labels="false" placeholder="Pick a value"></vue-multiselect>
|
|
</div>
|
|
|
|
<div class="columns three"> <vue-multiselect v-model="selectedPlayedStatus" :options="playedStatusOptions" :searchable="false"
|
|
:multiple="false" :close-on-select="true" :clear-on-select="true" :allow-empty="false" :show-labels="false"
|
|
placeholder="Sort By" label="Label" track-by="Value" :preselect-first="true">
|
|
</vue-multiselect></div>
|
|
|
|
|
|
</div>
|
|
<div class="row">
|
|
<vue-multiselect class="columns three" v-model="selectedPodcasts" :options="podcasts" :show-labels="false"
|
|
:multiple="true" :close-on-select="false" :clear-on-select="false"
|
|
:preserve-search="true" placeholder="Podcasts" label="Title" track-by="ID" :preselect-first="false">
|
|
<template slot="selection" slot-scope="{ values, search, isOpen }">
|
|
<span class="multiselect__single" v-if="values.length && !isOpen">${ values.length } options selected</span>
|
|
</template>
|
|
</vue-multiselect>
|
|
<vue-multiselect class="columns three" v-model="selectedTags" :show-labels="false" :options="tags" :multiple="true" :close-on-select="false" :clear-on-select="false" :preserve-search="true" placeholder="Tags" label="Label" track-by="ID" :preselect-first="false">
|
|
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">${ values.length } options selected</span></template>
|
|
</vue-multiselect>
|
|
<div class="columns three"> <vue-multiselect v-model="selectedDownloadStatus" :options="downloadStatusOptions" :searchable="false"
|
|
:multiple="false" :close-on-select="true" :clear-on-select="true" :allow-empty="false" :show-labels="false"
|
|
placeholder="Sort By" label="Label" track-by="Value" :preselect-first="true">
|
|
</vue-multiselect></div>
|
|
<div class="columns three">
|
|
<a title="Play items in this page" v-if="podcastItems.length" class="button" @click="playPage()"><i class="fas fa-play"></i></a>
|
|
<a title="Enqueue items in this page" v-if="podcastItems.length" class="button button-enqueue" @click="enqueuePage()"><i class="fas fa-plus"></i></a>
|
|
<a title="Reset Filters" class="button" @click="resetFilters()"><i class="fas fa-undo"></i></a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</form>
|
|
<hr>
|
|
|
|
|
|
<template v-for="item in podcastItems" >
|
|
<div class="podcasts row podcastItem" >
|
|
<div class="columns two">
|
|
<img
|
|
onerror="onImageError(this)"
|
|
class="u-full-width"
|
|
:src=" getEpisodeImage(item)"
|
|
v-bind:alt="item.Title"
|
|
lazy="lazy"
|
|
/>
|
|
</div>
|
|
<div class="columns ten">
|
|
<div class="row">
|
|
<div class="columns eight">
|
|
<h4>
|
|
<i
|
|
v-if="item.IsPlayed"
|
|
title="Played"
|
|
style="color: green"
|
|
class="fas fa-check-circle"
|
|
></i>
|
|
${item.Title} <template v-if="item.Podcast && item.Podcast.Title"> // ${item.Podcast.Title}</template>
|
|
</h4>
|
|
</div>
|
|
<div class="columns three">
|
|
<small :title="item.PubDate">${getRelativeDate(item.PubDate)}</small
|
|
>
|
|
</div>
|
|
<div class="columns one">
|
|
<small> ${getFormattedDuration(item.Duration)}</small>
|
|
</div>
|
|
</div>
|
|
<p class="useMore">${item.Summary }</p>
|
|
|
|
<a
|
|
v-if="item.IsPlayed"
|
|
class="button button"
|
|
title="Mark as not listened"
|
|
@click="changePlayedStatus(item)"
|
|
><i class="fas fa-envelope"></i
|
|
></a>
|
|
|
|
<a
|
|
v-if="!item.IsPlayed"
|
|
class="button button"
|
|
title="Mark as listened"
|
|
@click="changePlayedStatus(item)"
|
|
><i class="fas fa-envelope-open"></i
|
|
></a>
|
|
<a
|
|
v-if="!isBookmarked(item)"
|
|
class="button button"
|
|
title="Bookmark Episode"
|
|
@click="changeBookmarkStatus(item)"
|
|
><i class="far fa-bookmark"></i
|
|
></a>
|
|
|
|
<a
|
|
v-if="isBookmarked(item)"
|
|
class="button button"
|
|
title="Remove Bookmark"
|
|
@click="changeBookmarkStatus(item)"
|
|
><i class="fas fa-bookmark"></i
|
|
></a>
|
|
|
|
<a
|
|
v-if="item.DownloadPath"
|
|
class="button"
|
|
:href="downloadFromServer(item)"
|
|
download
|
|
title="Download episode file"
|
|
><i class="fas fa-download"></i
|
|
></a>
|
|
<a
|
|
v-if="item.DownloadPath"
|
|
class="button button"
|
|
@click="deleteFile(item)"
|
|
title="Delete Podcast Episode File"
|
|
><i class="fas fa-trash"></i
|
|
></a>
|
|
<a
|
|
v-if="settings.AutoDownload && !item.DownloadPath"
|
|
class="button button"
|
|
@click="downloadToDisk(item)"
|
|
title="Download to server"
|
|
download
|
|
><i class="fas fa-cloud-download-alt"></i
|
|
></a>
|
|
<a
|
|
v-if="!settings.AutoDownload && !item.DownloadPath && item.DownloadStatus===3"
|
|
class="button button"
|
|
@click="downloadToDisk(item)"
|
|
title="Download to server"
|
|
download
|
|
><i class="fas fa-cloud-download-alt"></i
|
|
></a>
|
|
<a
|
|
class="button button"
|
|
@click="openPlayer(item)"
|
|
title="Play Episode"
|
|
><i class="fas fa-play"></i
|
|
></a>
|
|
<a
|
|
class="button button-enqueue"
|
|
@click="enqueueEpisode(item)"
|
|
title="Add Episode to existing player playlist"
|
|
><i class="fas fa-plus"></i
|
|
></a>
|
|
</div> <div class="columns one"></div>
|
|
</div>
|
|
<hr />
|
|
</template>
|
|
<p v-if="podcastItems.length===0">Nothing to see here! Maybe try changing the filter criteria.</p>
|
|
|
|
|
|
|
|
<div class="row" v-if="podcastItems.length">
|
|
<div class="columns twelve" style="text-align: center">
|
|
|
|
<a v-if="filter.previousPage"
|
|
@click=" goToPage(1)"
|
|
class="button"
|
|
>First</a
|
|
>
|
|
|
|
<a v-if="filter.previousPage"
|
|
@click="goToPreviousPage()"
|
|
class="button"
|
|
>Previous</a
|
|
>
|
|
|
|
|
|
<select name="page" id="pageDdl" v-model="filter.page" >
|
|
<option :key="index" v-for="index in filter.totalPages" >${index}</option>
|
|
</select>
|
|
|
|
<a
|
|
v-if="filter.nextPage"
|
|
class="button"
|
|
@click="goToNextPage()"
|
|
>Next</a
|
|
>
|
|
|
|
|
|
<a
|
|
v-if="filter.totalPages>filter.page"
|
|
class="button"
|
|
@click=" goToPage(filter.totalPages)"
|
|
>Last</a
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{template "scripts"}}
|
|
<script src="/webassets/luxon.min.js"></script>
|
|
<script src="/webassets/vue-multiselect.min.js"></script>
|
|
|
|
|
|
<script>
|
|
Vue.component('vue-multiselect', window.VueMultiselect.default)
|
|
|
|
var app = new Vue({
|
|
delimiters: ["${", "}"],
|
|
el: "#app",
|
|
computed:{
|
|
page(){
|
|
return this.filter.page;
|
|
},
|
|
count(){
|
|
return this.filter.count;
|
|
}
|
|
},
|
|
watch:{
|
|
|
|
page(newPage,oldPage){
|
|
if(newPage==oldPage){
|
|
return;
|
|
}
|
|
if(newPage==1){
|
|
this.filter.previousPage=0;
|
|
}else{
|
|
this.filter.previousPage=newPage-1;
|
|
}
|
|
if(newPage==this.filter.totalPages){
|
|
this.filter.nextPage=0;
|
|
}else{
|
|
this.filter.nextPage=newPage+1;
|
|
}
|
|
this.getData()
|
|
|
|
},
|
|
count(current,old){
|
|
this.getData()
|
|
},
|
|
showFilters(current,old){
|
|
|
|
if(localStorage){
|
|
localStorage.showFilters=current
|
|
}
|
|
|
|
},
|
|
|
|
selectedPodcasts(current,old){
|
|
var arr=[];
|
|
for (let index = 0; index < current.length; index++) {
|
|
const element = current[index];
|
|
arr.push(element.ID);
|
|
}
|
|
this.filter['podcastIds']=arr;
|
|
this.submitFilters()
|
|
},
|
|
selectedTags(current,old){
|
|
var arr=[];
|
|
for (let index = 0; index < current.length; index++) {
|
|
const element = current[index];
|
|
arr.push(element.ID);
|
|
}
|
|
this.filter['tagIds']=arr;
|
|
this.submitFilters()
|
|
},
|
|
selectedSorting(current,old){
|
|
this.filter.sorting=current.Value;
|
|
this.submitFilters()
|
|
},
|
|
selectedDownloadStatus(current,old){
|
|
this.filter.isDownloaded=current.Value;
|
|
this.submitFilters()
|
|
},
|
|
selectedPlayedStatus(current,old){
|
|
this.filter.isPlayed=current.Value;
|
|
this.submitFilters()
|
|
},
|
|
},
|
|
mounted(){
|
|
if(localStorage && localStorage.episodesFilter){
|
|
this.filter=JSON.parse(localStorage.episodesFilter);
|
|
}
|
|
if(localStorage && localStorage.showFilters){
|
|
this.showFilters=JSON.parse(localStorage.showFilters);
|
|
}
|
|
|
|
if(this.filter.podcastIds!=null){
|
|
var selectedPodcasts=[];
|
|
for(var i=0;i<this.podcasts.length;i++){
|
|
for(var j=0;j<this.filter.podcastIds.length;j++){
|
|
if(this.filter.podcastIds[j]===this.podcasts[i].ID){
|
|
selectedPodcasts.push( this.podcasts[i])
|
|
}
|
|
}
|
|
}
|
|
this.selectedPodcasts=selectedPodcasts
|
|
}
|
|
|
|
if(this.filter.tagIds!=null){
|
|
|
|
var selectedTags=[];
|
|
for(var i=0;i<this.tags.length;i++){
|
|
for(var j=0;j<this.filter.tagIds.length;j++){
|
|
if(this.filter.tagIds[j]===this.tags[i].ID){
|
|
selectedTags.push( this.tags[i])
|
|
}
|
|
}
|
|
}
|
|
this.selectedTags=selectedTags
|
|
}
|
|
for(var i=0;i<this.sortOptions.length;i++){
|
|
if(this.sortOptions[i].Value===this.filter.sorting){
|
|
this.selectedSorting=this.sortOptions[i]
|
|
}
|
|
}
|
|
|
|
for(var i=0;i<this.downloadStatusOptions.length;i++){
|
|
if(this.downloadStatusOptions[i].Value===this.filter.isDownloaded.toString()){
|
|
this.selectedDownloadStatus=this.downloadStatusOptions[i]
|
|
}
|
|
}
|
|
|
|
for(var i=0;i<this.playedStatusOptions.length;i++){
|
|
if(this.playedStatusOptions[i].Value===this.filter.isPlayed.toString()){
|
|
this.selectedPlayedStatus=this.playedStatusOptions[i]
|
|
}
|
|
}
|
|
|
|
this.getData()
|
|
|
|
|
|
},
|
|
methods:{
|
|
getRelativeDate(dt){
|
|
return luxon.DateTime.fromISO(dt).toRelative()
|
|
},
|
|
getFormattedDuration(duration){
|
|
var obj=luxon.Duration.fromObject({seconds:duration}).shiftTo("hours","minutes","seconds").toObject();
|
|
str="";
|
|
if(obj.hours>0){
|
|
str+=obj.hours+":"
|
|
}
|
|
str+=obj.minutes+":"+obj.seconds;
|
|
return str;
|
|
},
|
|
getEpisodeImage(item){
|
|
return "/podcastitems/"+item.ID+"/image"
|
|
},
|
|
downloadFromServer(item){
|
|
return "/podcastitems/"+item.ID+"/file"
|
|
},
|
|
changePlayedStatus(item){
|
|
changePlayedStatus(item.ID,!item.IsPlayed,()=>item.IsPlayed=!item.IsPlayed)
|
|
},
|
|
goToPreviousPage(pageNumber){
|
|
this.filter.page=this.filter.previousPage;
|
|
},
|
|
goToNextPage(pageNumber){
|
|
this.filter.page=this.filter.nextPage;
|
|
},
|
|
goToPage(pageNumber){
|
|
this.filter.page=pageNumber;
|
|
},
|
|
changeBookmarkStatus(item){
|
|
isBookmarked= this.isBookmarked(item);
|
|
|
|
var self=this;
|
|
changeBookmarkStatus(item.ID,!isBookmarked,function(){
|
|
if(isBookmarked){
|
|
item.BookmarkDate=self.nildate
|
|
}else{
|
|
item.BookmarkDate="new Date().toDateString()"
|
|
}
|
|
})
|
|
},
|
|
|
|
isBookmarked(item){
|
|
return item.BookmarkDate!==this.nildate
|
|
},
|
|
deleteFile(item){
|
|
deleteFile(item.ID)
|
|
},
|
|
downloadToDisk(item){
|
|
downloadToDisk(item.ID)
|
|
},
|
|
openPlayer(item){
|
|
openPlayer([item.ID])
|
|
},
|
|
enqueueEpisode(item){
|
|
enqueueEpisode([item.ID])
|
|
},
|
|
searchQueryUpated(){
|
|
var self=this;
|
|
|
|
clearTimeout(this.debounce)
|
|
this.debounce = setTimeout(() => {
|
|
self.filter.page=1
|
|
self.getData()
|
|
}, 600)
|
|
},
|
|
saveFilter(data){
|
|
if(localStorage){
|
|
localStorage.episodesFilter=JSON.stringify(data);
|
|
}
|
|
},
|
|
submitFilters(){
|
|
this.filter.page=1;
|
|
this.getData();
|
|
|
|
},
|
|
toggleFilters(){
|
|
this.showFilters=!this.showFilters
|
|
},
|
|
playPage(){
|
|
var itemIds=[];
|
|
for(var i=0;i<this.podcastItems.length;i++){
|
|
itemIds.push(this.podcastItems[i].ID)
|
|
}
|
|
openPlayer(itemIds)
|
|
},
|
|
enqueuePage(){
|
|
var itemIds=[];
|
|
for(var i=0;i<this.podcastItems.length;i++){
|
|
itemIds.push(this.podcastItems[i].ID)
|
|
}
|
|
enqueueEpisode(itemIds)
|
|
},
|
|
updateUrl(){
|
|
var url= new URL(window.top.location.href);
|
|
var copy= Vue.util.extend({},this.filter);
|
|
delete copy.totalPages
|
|
delete copy.totalCount
|
|
delete copy.nextPage
|
|
delete copy.previousPage
|
|
url.search=new URLSearchParams(copy);
|
|
history.pushState(null,null,url.href)
|
|
},
|
|
resetFilters(){
|
|
this.filter.q="";
|
|
this.selectedPodcasts=[];
|
|
this.selectedTags=[];
|
|
this.selectedDownloadStatus=this.downloadStatusOptions[0];
|
|
this.selectedPlayedStatus=this.playedStatusOptions[0];
|
|
},
|
|
removeStartingSlash(url){
|
|
if(url[0]==='/'){
|
|
return url
|
|
}
|
|
return "/"+url
|
|
},
|
|
getData(){
|
|
var self=this;
|
|
axios
|
|
.get("/podcastitems",{params:this.filter})
|
|
.then(function (response) {
|
|
self.podcastItems= response.data.podcastItems;
|
|
self.filter=response.data.filter;
|
|
self.saveFilter(self.filter);
|
|
self.updateUrl();
|
|
setPageTitle("Episodes ("+self.filter.totalCount+")")
|
|
})
|
|
.catch(function (error) {
|
|
if (error.response && error.response.data && error.response.data.message) {
|
|
Vue.toasted.show(error.response.data.message, {
|
|
theme: "bubble",
|
|
type: "error",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
}
|
|
})
|
|
.then(function () {});
|
|
}
|
|
},
|
|
data: {
|
|
socket:null,
|
|
debouce:null,
|
|
nildate:"0001-01-01T00:00:00Z",
|
|
playerExists:false,
|
|
isMobile:false,
|
|
sortOrder:"dateAdded-asc",
|
|
selectedSorting:"release_desc",
|
|
selectedPodcasts:[],
|
|
selectedTags:[],
|
|
selectedDownloadStatus:"",
|
|
selectedPlayedStatus:"",
|
|
showFilters:localStorage && localStorage.showFilters && JSON.parse(localStorage.showFilters),
|
|
|
|
{{ $len := len .podcastItems}}
|
|
podcastItems: {{if gt $len 0}} {{ .podcastItems }} {{else}} [] {{end}},
|
|
settings:{{.setting}},
|
|
filter:{{.filter}},
|
|
podcasts:{{.podcasts}},
|
|
tags:{{.tags}},
|
|
sortOptions:{{.sortOptions}},
|
|
pagingOptions:[10,20,50,100],
|
|
downloadStatusOptions:[{"Label":"All","Value":"nil"},{"Label":"Downloaded Only","Value":"true"},{"Label":"Not Downloaded","Value":"false"}],
|
|
playedStatusOptions:[{"Label":"All","Value":"nil"},{"Label":"Played Only","Value":"true"},{"Label":"Unplayed only","Value":"false"}],
|
|
}})
|
|
</script>
|
|
|
|
<script>
|
|
function debounce(func, wait, immediate) {
|
|
var timeout;
|
|
return function() {
|
|
var context = this, args = arguments;
|
|
var later = function() {
|
|
timeout = null;
|
|
if (!immediate) func.apply(context, args);
|
|
};
|
|
var callNow = immediate && !timeout;
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(later, wait);
|
|
if (callNow) func.apply(context, args);
|
|
};
|
|
};
|
|
function downloadToDisk(id) {
|
|
axios
|
|
.get("/podcastitems/" + id + "/download")
|
|
.then(function (response) {
|
|
Vue.toasted.show("Podcast download enqueued.", {
|
|
theme: "bubble",
|
|
type: "info",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
var row = document.getElementById("podcast-" + id);
|
|
row.remove();
|
|
})
|
|
.catch(function (error) {
|
|
if (error.response && error.response.data && error.response.data.message) {
|
|
Vue.toasted.show(error.response.data.message, {
|
|
theme: "bubble",
|
|
type: "error",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
}
|
|
})
|
|
.then(function () {});
|
|
return false;
|
|
}
|
|
function deleteFile(id) {
|
|
axios
|
|
.get("/podcastitems/" + id + "/delete")
|
|
.then(function (response) {
|
|
Vue.toasted.show("Podcast file deleted.", {
|
|
theme: "bubble",
|
|
type: "success",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
var row = document.getElementById("podcast-" + id);
|
|
row.remove();
|
|
})
|
|
.catch(function (error) {
|
|
if (error.response && error.response.data && error.response.data.message) {
|
|
Vue.toasted.show(error.response.data.message, {
|
|
theme: "bubble",
|
|
type: "error",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
}
|
|
})
|
|
.then(function () {});
|
|
return false;
|
|
}
|
|
function changePlayedStatus(id, status,success) {
|
|
var endpoint = status ? "markPlayed" : "markUnplayed";
|
|
axios
|
|
.get("/podcastitems/" + id + "/" + endpoint, {
|
|
isPlayed: status,
|
|
})
|
|
.then(function (response) {
|
|
Vue.toasted.show("Podcast played status updated.", {
|
|
theme: "bubble",
|
|
type: "info",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
if(success){
|
|
success();
|
|
}
|
|
})
|
|
.catch(function (error) {
|
|
if (error.response && error.response.data && error.response.data.message) {
|
|
|
|
Vue.toasted.show(error.response.data.message, {
|
|
theme: "bubble",
|
|
type: "error",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
}
|
|
})
|
|
.then(function () {});
|
|
return false;
|
|
}
|
|
function changeBookmarkStatus(id, status,success) {
|
|
var endpoint = status ? "bookmark" : "unbookmark";
|
|
axios
|
|
.get("/podcastitems/" + id + "/" + endpoint, {
|
|
isPlayed: status,
|
|
})
|
|
.then(function (response) {
|
|
msg= status?"Bookmark Added": "Bookmark removed";
|
|
Vue.toasted.show(msg, {
|
|
theme: "bubble",
|
|
type: "info",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
if(success){
|
|
success()
|
|
}
|
|
})
|
|
.catch(function (error) {
|
|
if (error.response && error.response.data && error.response.data.message) {
|
|
Vue.toasted.show(error.response.data.message, {
|
|
theme: "bubble",
|
|
type: "error",
|
|
position: "top-right",
|
|
duration: 5000,
|
|
});
|
|
}
|
|
})
|
|
.then(function () {});
|
|
return false;
|
|
}
|
|
|
|
</script>
|
|
<script>
|
|
|
|
const socket= getWebsocketConnection(function(event){
|
|
const message= getWebsocketMessage("Register","Home")
|
|
socket.send(message);
|
|
},function(x){
|
|
const msg= JSON.parse(x.data)
|
|
if(msg.messageType=="NoPlayer"){
|
|
document.body.classList.remove("playerExists")
|
|
}
|
|
if(msg.messageType=="PlayerExists"){
|
|
document.body.classList.add("playerExists")
|
|
}
|
|
});
|
|
function enqueueEpisode(ids){
|
|
if(!socket){
|
|
return
|
|
}
|
|
socket.send(getWebsocketMessage("Enqueue",`{"itemIds":${JSON.stringify(ids)}}`))
|
|
}
|
|
function enquePodcast(id){
|
|
if(!socket){
|
|
return
|
|
}
|
|
socket.send(getWebsocketMessage("Enqueue",`{"podcastId":"${id}"}`))
|
|
}
|
|
function playPodcast(id){
|
|
openPlayer("",id)
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|