music.mpd refactor WIP
This commit is contained in:
parent
3eb7f01d38
commit
e127f2597c
60 changed files with 1098 additions and 167 deletions
2
platypush/backend/http/dist/index.html
vendored
2
platypush/backend/http/dist/index.html
vendored
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>platypush</title><link href="/static/css/chunk-24ff873d.64d9bc0b.css" rel="prefetch"><link href="/static/css/chunk-35b45d59.0c4a18da.css" rel="prefetch"><link href="/static/css/chunk-3d60f62e.2026dd4f.css" rel="prefetch"><link href="/static/css/chunk-45939517.e4a1ddf3.css" rel="prefetch"><link href="/static/css/chunk-4bbbb9a3.3108d379.css" rel="prefetch"><link href="/static/css/chunk-53360c78.c486a396.css" rel="prefetch"><link href="/static/css/chunk-545459d0.009b6a70.css" rel="prefetch"><link href="/static/css/chunk-62a3d08e.6cb54f10.css" rel="prefetch"><link href="/static/css/chunk-ba6439f0.48dc2d11.css" rel="prefetch"><link href="/static/css/chunk-d8561e02.b52f89a0.css" rel="prefetch"><link href="/static/css/chunk-e8078048.c6785c78.css" rel="prefetch"><link href="/static/js/chunk-24ff873d.f955ad3b.js" rel="prefetch"><link href="/static/js/chunk-2d2091df.b017f6d4.js" rel="prefetch"><link href="/static/js/chunk-2d21da1a.867fde19.js" rel="prefetch"><link href="/static/js/chunk-35b45d59.d541d43f.js" rel="prefetch"><link href="/static/js/chunk-3d60f62e.8cc48f2d.js" rel="prefetch"><link href="/static/js/chunk-45939517.38162e50.js" rel="prefetch"><link href="/static/js/chunk-4bbbb9a3.6f0e4975.js" rel="prefetch"><link href="/static/js/chunk-53360c78.54e2e626.js" rel="prefetch"><link href="/static/js/chunk-545459d0.aa1e42a3.js" rel="prefetch"><link href="/static/js/chunk-62a3d08e.8fc4fd3a.js" rel="prefetch"><link href="/static/js/chunk-ba6439f0.a6ca0191.js" rel="prefetch"><link href="/static/js/chunk-d8561e02.78e44394.js" rel="prefetch"><link href="/static/js/chunk-e8078048.e668de5f.js" rel="prefetch"><link href="/static/css/app.e87398b0.css" rel="preload" as="style"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="preload" as="style"><link href="/static/js/app.9c37c838.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.63de75fe.js" rel="preload" as="script"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="stylesheet"><link href="/static/css/app.e87398b0.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but platypush doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.63de75fe.js"></script><script src="/static/js/app.9c37c838.js"></script></body></html>
|
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>platypush</title><link href="/static/css/chunk-24ff873d.64d9bc0b.css" rel="prefetch"><link href="/static/css/chunk-3b44ec4e.0c4a18da.css" rel="prefetch"><link href="/static/css/chunk-45939517.e4a1ddf3.css" rel="prefetch"><link href="/static/css/chunk-4bbbb9a3.3108d379.css" rel="prefetch"><link href="/static/css/chunk-4c0b0f48.009b6a70.css" rel="prefetch"><link href="/static/css/chunk-4eeb8349.2026dd4f.css" rel="prefetch"><link href="/static/css/chunk-52804492.a64fd302.css" rel="prefetch"><link href="/static/css/chunk-53360c78.c486a396.css" rel="prefetch"><link href="/static/css/chunk-62a3d08e.6cb54f10.css" rel="prefetch"><link href="/static/css/chunk-d8561e02.b52f89a0.css" rel="prefetch"><link href="/static/css/chunk-e8078048.c6785c78.css" rel="prefetch"><link href="/static/js/chunk-24ff873d.691c883d.js" rel="prefetch"><link href="/static/js/chunk-2d2091df.1e51ae4c.js" rel="prefetch"><link href="/static/js/chunk-2d21da1a.6bb60047.js" rel="prefetch"><link href="/static/js/chunk-3b44ec4e.904c7e10.js" rel="prefetch"><link href="/static/js/chunk-45939517.c0034c6b.js" rel="prefetch"><link href="/static/js/chunk-4bbbb9a3.251fff37.js" rel="prefetch"><link href="/static/js/chunk-4c0b0f48.366980a2.js" rel="prefetch"><link href="/static/js/chunk-4eeb8349.5c94d58c.js" rel="prefetch"><link href="/static/js/chunk-52804492.1cbed362.js" rel="prefetch"><link href="/static/js/chunk-53360c78.51ee7c96.js" rel="prefetch"><link href="/static/js/chunk-62a3d08e.17d3c86d.js" rel="prefetch"><link href="/static/js/chunk-d8561e02.1e366cb3.js" rel="prefetch"><link href="/static/js/chunk-e8078048.ce29b8d4.js" rel="prefetch"><link href="/static/css/app.4868c461.css" rel="preload" as="style"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="preload" as="style"><link href="/static/js/app.ce952734.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.30e3a6cb.js" rel="preload" as="script"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="stylesheet"><link href="/static/css/app.4868c461.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but platypush doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.30e3a6cb.js"></script><script src="/static/js/app.ce952734.js"></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/app.ce952734.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/app.ce952734.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/app.ce952734.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/app.ce952734.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-24ff873d"],{"9e28":function(e,t,s){},b9a8:function(e,t,s){"use strict";s("cfdb")},c845:function(e,t,s){"use strict";s.r(t);var r=s("7a23"),a=Object(r["J"])("data-v-7358a82d");Object(r["u"])("data-v-7358a82d");var o={class:"image-carousel"},i={ref:"background",class:"background"},n={key:1,class:"row info-container"},h={class:"col-6 weather-container"},c={key:0},u={class:"col-6 date-time-container"};Object(r["s"])();var m=a((function(e,t,s,a,m,d){var f=Object(r["z"])("Loading"),l=Object(r["z"])("Weather"),w=Object(r["z"])("DateTime");return Object(r["r"])(),Object(r["e"])("div",o,[m.images.length?Object(r["f"])("",!0):(Object(r["r"])(),Object(r["e"])(f,{key:0})),Object(r["h"])("div",i,null,512),Object(r["h"])("img",{ref:"img",src:d.imgURL,alt:"Your carousel images",style:{display:m.images.length?"block":"none"}},null,12,["src"]),d._showDate||d._showTime?(Object(r["r"])(),Object(r["e"])("div",n,[Object(r["h"])("div",h,[d._showWeather?(Object(r["r"])(),Object(r["e"])(l,{key:1,"show-icon":d._showWeatherIcon,"show-summary":d._showWeatherSummary,"show-temperature":d._showTemperature,"icon-color":s.weatherIconColor,"icon-size":s.weatherIconSize,animate:d._animateWeatherIcon},null,8,["show-icon","show-summary","show-temperature","icon-color","icon-size","animate"])):(Object(r["r"])(),Object(r["e"])("span",c," "))]),Object(r["h"])("div",u,[d._showTime||d._showDate?(Object(r["r"])(),Object(r["e"])(w,{key:0,"show-date":d._showDate,"show-time":d._showTime,"show-seconds":d._showSeconds},null,8,["show-date","show-time","show-seconds"])):Object(r["f"])("",!0)])])):Object(r["f"])("",!0)])})),d=(s("a9e3"),s("96cf"),s("1da1")),f=s("3e54"),l=s("3a5e"),w=s("365a"),g=s("5b43"),b={name:"ImageCarousel",components:{Weather:g["default"],DateTime:w["default"],Loading:l["a"]},mixins:[f["a"]],props:{imgDir:{type:String,required:!0},refreshSeconds:{type:Number,default:15},showDate:{default:!1},showTime:{default:!1},showSeconds:{default:!1},showWeather:{default:!1},showTemperature:{default:!0},showWeatherIcon:{default:!0},showWeatherSummary:{default:!0},weatherIconColor:{type:String,default:"white"},weatherIconSize:{type:Number,default:70},animateWeatherIcon:{default:!0}},data:function(){return{images:[],currentImage:void 0,loading:!1}},computed:{imgURL:function(){var e=8008;return"backend.http"in this.$root.config&&"port"in this.$root.config["backend.http"]&&(e=this.$root.config["backend.http"].port),"//"+window.location.hostname+":"+e+this.currentImage},_showDate:function(){return this.parseBoolean(this.showDate)},_showTime:function(){return this.parseBoolean(this.showTime)},_showSeconds:function(){return this.parseBoolean(this.showSeconds)},_showTemperature:function(){return this.parseBoolean(this.showTemperature)},_showWeather:function(){return this.parseBoolean(this.showWeather)},_showWeatherIcon:function(){return this.parseBoolean(this.showWeatherIcon)},_showWeatherSummary:function(){return this.parseBoolean(this.showWeatherSummary)},_animateWeatherIcon:function(){return this.parseBoolean(this.animateWeatherIcon)}},methods:{refresh:function(){var e=this;return Object(d["a"])(regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){while(1)switch(t.prev=t.next){case 0:if(e.images.length){t.next=10;break}return e.loading=!0,t.prev=2,t.next=5,e.request("utils.search_web_directory",{directory:e.imgDir,extensions:[".jpg",".jpeg",".png"]});case 5:e.images=t.sent,e.shuffleImages();case 7:return t.prev=7,e.loading=!1,t.finish(7);case 10:e.images.length&&(e.currentImage=e.images.pop());case 11:case"end":return t.stop()}}),t,null,[[2,,7,10]])})))()},onNewImage:function(){if(this.$refs.img&&(this.$refs.background.style["background-image"]="url("+this.imgURL+")",this.$refs.img.style.width="auto",this.$refs.img.width>this.$refs.img.height)){var e=this.$refs.img.width/this.$refs.img.height;4/3<=e<=16/9&&(this.$refs.img.style.width="100%"),e<=4/3&&(this.$refs.img.style.height="100%")}},shuffleImages:function(){for(var e=this.images.length-1;e>0;e--){var t=Math.floor(Math.random()*(e+1)),s=this.images[e];this.images[e]=this.images[t],this.images[t]=s}}},mounted:function(){this.$refs.img.addEventListener("load",this.onNewImage),this.$refs.img.addEventListener("error",this.refresh),this.refresh(),setInterval(this.refresh,Math.round(1e3*this.refreshSeconds))}};s("b9a8"),s("d233");b.render=m,b.__scopeId="data-v-7358a82d";t["default"]=b},cfdb:function(e,t,s){},d233:function(e,t,s){"use strict";s("9e28")}}]);
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-24ff873d"],{"9e28":function(e,t,s){},b9a8:function(e,t,s){"use strict";s("cfdb")},c845:function(e,t,s){"use strict";s.r(t);var r=s("7a23"),a=Object(r["K"])("data-v-7358a82d");Object(r["u"])("data-v-7358a82d");var o={class:"image-carousel"},i={ref:"background",class:"background"},n={key:1,class:"row info-container"},h={class:"col-6 weather-container"},c={key:0},u={class:"col-6 date-time-container"};Object(r["s"])();var m=a((function(e,t,s,a,m,d){var f=Object(r["z"])("Loading"),l=Object(r["z"])("Weather"),w=Object(r["z"])("DateTime");return Object(r["r"])(),Object(r["e"])("div",o,[m.images.length?Object(r["f"])("",!0):(Object(r["r"])(),Object(r["e"])(f,{key:0})),Object(r["h"])("div",i,null,512),Object(r["h"])("img",{ref:"img",src:d.imgURL,alt:"Your carousel images",style:{display:m.images.length?"block":"none"}},null,12,["src"]),d._showDate||d._showTime?(Object(r["r"])(),Object(r["e"])("div",n,[Object(r["h"])("div",h,[d._showWeather?(Object(r["r"])(),Object(r["e"])(l,{key:1,"show-icon":d._showWeatherIcon,"show-summary":d._showWeatherSummary,"show-temperature":d._showTemperature,"icon-color":s.weatherIconColor,"icon-size":s.weatherIconSize,animate:d._animateWeatherIcon},null,8,["show-icon","show-summary","show-temperature","icon-color","icon-size","animate"])):(Object(r["r"])(),Object(r["e"])("span",c," "))]),Object(r["h"])("div",u,[d._showTime||d._showDate?(Object(r["r"])(),Object(r["e"])(w,{key:0,"show-date":d._showDate,"show-time":d._showTime,"show-seconds":d._showSeconds},null,8,["show-date","show-time","show-seconds"])):Object(r["f"])("",!0)])])):Object(r["f"])("",!0)])})),d=(s("a9e3"),s("96cf"),s("1da1")),f=s("3e54"),l=s("3a5e"),w=s("365a"),g=s("5b43"),b={name:"ImageCarousel",components:{Weather:g["default"],DateTime:w["default"],Loading:l["a"]},mixins:[f["a"]],props:{imgDir:{type:String,required:!0},refreshSeconds:{type:Number,default:15},showDate:{default:!1},showTime:{default:!1},showSeconds:{default:!1},showWeather:{default:!1},showTemperature:{default:!0},showWeatherIcon:{default:!0},showWeatherSummary:{default:!0},weatherIconColor:{type:String,default:"white"},weatherIconSize:{type:Number,default:70},animateWeatherIcon:{default:!0}},data:function(){return{images:[],currentImage:void 0,loading:!1}},computed:{imgURL:function(){var e=8008;return"backend.http"in this.$root.config&&"port"in this.$root.config["backend.http"]&&(e=this.$root.config["backend.http"].port),"//"+window.location.hostname+":"+e+this.currentImage},_showDate:function(){return this.parseBoolean(this.showDate)},_showTime:function(){return this.parseBoolean(this.showTime)},_showSeconds:function(){return this.parseBoolean(this.showSeconds)},_showTemperature:function(){return this.parseBoolean(this.showTemperature)},_showWeather:function(){return this.parseBoolean(this.showWeather)},_showWeatherIcon:function(){return this.parseBoolean(this.showWeatherIcon)},_showWeatherSummary:function(){return this.parseBoolean(this.showWeatherSummary)},_animateWeatherIcon:function(){return this.parseBoolean(this.animateWeatherIcon)}},methods:{refresh:function(){var e=this;return Object(d["a"])(regeneratorRuntime.mark((function t(){return regeneratorRuntime.wrap((function(t){while(1)switch(t.prev=t.next){case 0:if(e.images.length){t.next=10;break}return e.loading=!0,t.prev=2,t.next=5,e.request("utils.search_web_directory",{directory:e.imgDir,extensions:[".jpg",".jpeg",".png"]});case 5:e.images=t.sent,e.shuffleImages();case 7:return t.prev=7,e.loading=!1,t.finish(7);case 10:e.images.length&&(e.currentImage=e.images.pop());case 11:case"end":return t.stop()}}),t,null,[[2,,7,10]])})))()},onNewImage:function(){if(this.$refs.img&&(this.$refs.background.style["background-image"]="url("+this.imgURL+")",this.$refs.img.style.width="auto",this.$refs.img.width>this.$refs.img.height)){var e=this.$refs.img.width/this.$refs.img.height;4/3<=e<=16/9&&(this.$refs.img.style.width="100%"),e<=4/3&&(this.$refs.img.style.height="100%")}},shuffleImages:function(){for(var e=this.images.length-1;e>0;e--){var t=Math.floor(Math.random()*(e+1)),s=this.images[e];this.images[e]=this.images[t],this.images[t]=s}}},mounted:function(){this.$refs.img.addEventListener("load",this.onNewImage),this.$refs.img.addEventListener("error",this.refresh),this.refresh(),setInterval(this.refresh,Math.round(1e3*this.refreshSeconds))}};s("b9a8"),s("d233");b.render=m,b.__scopeId="data-v-7358a82d";t["default"]=b},cfdb:function(e,t,s){},d233:function(e,t,s){"use strict";s("9e28")}}]);
|
||||||
//# sourceMappingURL=chunk-24ff873d.f955ad3b.js.map
|
//# sourceMappingURL=chunk-24ff873d.691c883d.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/chunk-2d21da1a.6bb60047.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-2d21da1a.6bb60047.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/chunk-2d21da1a.6bb60047.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-2d21da1a.6bb60047.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-45939517"],{"1cb0":function(e,t,s){"use strict";s("5eaa")},"2e0b":function(e,t,s){"use strict";s("e458")},3737:function(e,t,s){"use strict";s.r(t);s("b64b");var a=s("7a23"),n=Object(a["J"])("data-v-d6e48dfa");Object(a["u"])("data-v-d6e48dfa");var r={class:"date-time-weather"},i={class:"row date-time-container"},o={class:"row weather-container"},c={class:"row sensors-container"},u={key:0,class:"row"},h={class:"col-3"},d=Object(a["h"])("div",{class:"col-6"}," ",-1),l={class:"col-3"};Object(a["s"])();var m=n((function(e,t,s,n,m,b){var f=Object(a["z"])("DateTime"),w=Object(a["z"])("Weather"),j=Object(a["z"])("Sensor");return Object(a["r"])(),Object(a["e"])("div",r,[Object(a["h"])("div",i,[b._showDate||b._showTime?(Object(a["r"])(),Object(a["e"])(f,{key:0,"show-date":b._showDate,"show-time":b._showTime,"show-seconds":b._showSeconds,animate:s.animate},null,8,["show-date","show-time","show-seconds","animate"])):Object(a["f"])("",!0)]),Object(a["h"])("div",o,[s.showWeather?(Object(a["r"])(),Object(a["e"])(w,{key:0,"show-summary":b._showSummary,animate:b._animate,"icon-size":s.iconSize,"refresh-seconds":s.weatherRefreshSeconds},null,8,["show-summary","animate","icon-size","refresh-seconds"])):Object(a["f"])("",!0)]),Object(a["h"])("div",c,[b._showSensors&&Object.keys(e.sensors).length?(Object(a["r"])(),Object(a["e"])("div",u,[Object(a["h"])("div",h,[null!=e.sensors.temperature?(Object(a["r"])(),Object(a["e"])(j,{key:0,"icon-class":"fas fa-thermometer-half",value:e.sensors.temperature,unit:"°"},null,8,["value"])):Object(a["f"])("",!0)]),d,Object(a["h"])("div",l,[null!=e.sensors.humidity?(Object(a["r"])(),Object(a["e"])(j,{key:0,"icon-class":"fas fa-tint",value:e.sensors.humidity,unit:"%"},null,8,["value"])):Object(a["f"])("",!0)])])):Object(a["f"])("",!0)])])})),b=(s("a9e3"),s("3e54")),f=s("365a"),w=s("5b43"),j=(s("b0c0"),Object(a["J"])("data-v-1efb373e"));Object(a["u"])("data-v-1efb373e");var O={class:"sensor"},p={key:0,class:"label-container col-6"},v={class:"value-container col-6"};Object(a["s"])();var y=j((function(e,t,s,n,r,i){return Object(a["r"])(),Object(a["e"])("div",O,[s.iconClass||s.name?(Object(a["r"])(),Object(a["e"])("div",p,[s.iconClass?(Object(a["r"])(),Object(a["e"])("i",{key:0,class:s.iconClass},null,2)):s.name?(Object(a["r"])(),Object(a["e"])("span",{key:1,textContent:Object(a["C"])(s.name)},null,8,["textContent"])):Object(a["f"])("",!0)])):Object(a["f"])("",!0),Object(a["h"])("div",v,[Object(a["h"])("span",{class:"value",textContent:Object(a["C"])(i._value)},null,8,["textContent"])])])})),S=(s("99af"),s("b680"),{name:"Sensor",props:{iconClass:{type:String,required:!1},name:{type:String,required:!1},value:{required:!1},unit:{type:String,required:!1},decimals:{type:Number,required:!1,default:1},isBoolean:{type:Boolean,required:!1,default:!1}},computed:{_value:function(){if(null==this.value)return"N/A";if(this.isBoolean)return this.parseBoolean(this.value);var e=parseFloat(this.value);return null!=this.decimals&&(e=e.toFixed(this.decimals)),this.unit&&(e="".concat(e).concat(this.unit)),e}}});s("2e0b");S.render=y,S.__scopeId="data-v-1efb373e";var _=S,q={name:"DateTimeWeather",mixins:[b["a"]],components:{Sensor:_,DateTime:f["default"],Weather:w["default"]},props:{animate:{required:!1,default:!0},iconSize:{type:Number,required:!1,default:50},showDate:{required:!1,default:!0},showTime:{required:!1,default:!0},showWeather:{required:!1,default:!0},showSummary:{required:!1,default:!0},showSensors:{required:!1,default:!0},showSeconds:{required:!1,default:!0},sensorTemperatureAttr:{type:String,required:!1,default:"temperature"},sensorHumidityAttr:{type:String,required:!1,default:"humidity"},weatherRefreshSeconds:{type:Number,required:!1,default:900}},computed:{_showDate:function(){return this.parseBoolean(this.showDate)},_showTime:function(){return this.parseBoolean(this.showTime)},_showSeconds:function(){return this.parseBoolean(this.showSeconds)},_showWeather:function(){return this.parseBoolean(this.showWeather)},_showSummary:function(){return this.parseBoolean(this.showSummary)},_showSensors:function(){return this.parseBoolean(this.showSensors)},_animate:function(){return this.parseBoolean(this.animate)}},data:function(){return{sensors:{}}},methods:{onSensorData:function(e){this.sensorTemperatureAttr in e.data&&(this.sensors.temperature=e.data.temperature),this.sensorHumidityAttr in e.data&&(this.sensors.humidity=e.data.humidity)}},mounted:function(){this.subscribe(this.onSensorData,null,"platypush.message.event.sensor.SensorDataChangeEvent")}};s("1cb0");q.render=m,q.__scopeId="data-v-d6e48dfa";t["default"]=q},"5eaa":function(e,t,s){},e458:function(e,t,s){}}]);
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-45939517"],{"1cb0":function(e,t,s){"use strict";s("5eaa")},"2e0b":function(e,t,s){"use strict";s("e458")},3737:function(e,t,s){"use strict";s.r(t);s("b64b");var a=s("7a23"),n=Object(a["K"])("data-v-d6e48dfa");Object(a["u"])("data-v-d6e48dfa");var r={class:"date-time-weather"},i={class:"row date-time-container"},o={class:"row weather-container"},c={class:"row sensors-container"},u={key:0,class:"row"},h={class:"col-3"},d=Object(a["h"])("div",{class:"col-6"}," ",-1),l={class:"col-3"};Object(a["s"])();var m=n((function(e,t,s,n,m,b){var f=Object(a["z"])("DateTime"),w=Object(a["z"])("Weather"),j=Object(a["z"])("Sensor");return Object(a["r"])(),Object(a["e"])("div",r,[Object(a["h"])("div",i,[b._showDate||b._showTime?(Object(a["r"])(),Object(a["e"])(f,{key:0,"show-date":b._showDate,"show-time":b._showTime,"show-seconds":b._showSeconds,animate:s.animate},null,8,["show-date","show-time","show-seconds","animate"])):Object(a["f"])("",!0)]),Object(a["h"])("div",o,[s.showWeather?(Object(a["r"])(),Object(a["e"])(w,{key:0,"show-summary":b._showSummary,animate:b._animate,"icon-size":s.iconSize,"refresh-seconds":s.weatherRefreshSeconds},null,8,["show-summary","animate","icon-size","refresh-seconds"])):Object(a["f"])("",!0)]),Object(a["h"])("div",c,[b._showSensors&&Object.keys(e.sensors).length?(Object(a["r"])(),Object(a["e"])("div",u,[Object(a["h"])("div",h,[null!=e.sensors.temperature?(Object(a["r"])(),Object(a["e"])(j,{key:0,"icon-class":"fas fa-thermometer-half",value:e.sensors.temperature,unit:"°"},null,8,["value"])):Object(a["f"])("",!0)]),d,Object(a["h"])("div",l,[null!=e.sensors.humidity?(Object(a["r"])(),Object(a["e"])(j,{key:0,"icon-class":"fas fa-tint",value:e.sensors.humidity,unit:"%"},null,8,["value"])):Object(a["f"])("",!0)])])):Object(a["f"])("",!0)])])})),b=(s("a9e3"),s("3e54")),f=s("365a"),w=s("5b43"),j=(s("b0c0"),Object(a["K"])("data-v-1efb373e"));Object(a["u"])("data-v-1efb373e");var O={class:"sensor"},p={key:0,class:"label-container col-6"},v={class:"value-container col-6"};Object(a["s"])();var y=j((function(e,t,s,n,r,i){return Object(a["r"])(),Object(a["e"])("div",O,[s.iconClass||s.name?(Object(a["r"])(),Object(a["e"])("div",p,[s.iconClass?(Object(a["r"])(),Object(a["e"])("i",{key:0,class:s.iconClass},null,2)):s.name?(Object(a["r"])(),Object(a["e"])("span",{key:1,textContent:Object(a["C"])(s.name)},null,8,["textContent"])):Object(a["f"])("",!0)])):Object(a["f"])("",!0),Object(a["h"])("div",v,[Object(a["h"])("span",{class:"value",textContent:Object(a["C"])(i._value)},null,8,["textContent"])])])})),S=(s("99af"),s("b680"),{name:"Sensor",props:{iconClass:{type:String,required:!1},name:{type:String,required:!1},value:{required:!1},unit:{type:String,required:!1},decimals:{type:Number,required:!1,default:1},isBoolean:{type:Boolean,required:!1,default:!1}},computed:{_value:function(){if(null==this.value)return"N/A";if(this.isBoolean)return this.parseBoolean(this.value);var e=parseFloat(this.value);return null!=this.decimals&&(e=e.toFixed(this.decimals)),this.unit&&(e="".concat(e).concat(this.unit)),e}}});s("2e0b");S.render=y,S.__scopeId="data-v-1efb373e";var _=S,q={name:"DateTimeWeather",mixins:[b["a"]],components:{Sensor:_,DateTime:f["default"],Weather:w["default"]},props:{animate:{required:!1,default:!0},iconSize:{type:Number,required:!1,default:50},showDate:{required:!1,default:!0},showTime:{required:!1,default:!0},showWeather:{required:!1,default:!0},showSummary:{required:!1,default:!0},showSensors:{required:!1,default:!0},showSeconds:{required:!1,default:!0},sensorTemperatureAttr:{type:String,required:!1,default:"temperature"},sensorHumidityAttr:{type:String,required:!1,default:"humidity"},weatherRefreshSeconds:{type:Number,required:!1,default:900}},computed:{_showDate:function(){return this.parseBoolean(this.showDate)},_showTime:function(){return this.parseBoolean(this.showTime)},_showSeconds:function(){return this.parseBoolean(this.showSeconds)},_showWeather:function(){return this.parseBoolean(this.showWeather)},_showSummary:function(){return this.parseBoolean(this.showSummary)},_showSensors:function(){return this.parseBoolean(this.showSensors)},_animate:function(){return this.parseBoolean(this.animate)}},data:function(){return{sensors:{}}},methods:{onSensorData:function(e){this.sensorTemperatureAttr in e.data&&(this.sensors.temperature=e.data.temperature),this.sensorHumidityAttr in e.data&&(this.sensors.humidity=e.data.humidity)}},mounted:function(){this.subscribe(this.onSensorData,null,"platypush.message.event.sensor.SensorDataChangeEvent")}};s("1cb0");q.render=m,q.__scopeId="data-v-d6e48dfa";t["default"]=q},"5eaa":function(e,t,s){},e458:function(e,t,s){}}]);
|
||||||
//# sourceMappingURL=chunk-45939517.38162e50.js.map
|
//# sourceMappingURL=chunk-45939517.c0034c6b.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-4bbbb9a3"],{"365a":function(e,t,n){"use strict";n.r(t);var o=n("7a23"),s=Object(o["J"])("data-v-4835dfb0");Object(o["u"])("data-v-4835dfb0");var a={class:"date-time"};Object(o["s"])();var i=s((function(e,t,n,s,i,r){return Object(o["r"])(),Object(o["e"])("div",a,[r._showDate?(Object(o["r"])(),Object(o["e"])("div",{key:0,class:"date",textContent:Object(o["C"])(e.formatDate(e.now))},null,8,["textContent"])):Object(o["f"])("",!0),r._showTime?(Object(o["r"])(),Object(o["e"])("div",{key:1,class:"time",textContent:Object(o["C"])(e.formatTime(e.now,r._showSeconds))},null,8,["textContent"])):Object(o["f"])("",!0)])})),r=n("3e54"),c={name:"DateTime",mixins:[r["a"]],props:{showDate:{required:!1,default:!0},showTime:{required:!1,default:!0},showSeconds:{required:!1,default:!0}},computed:{_showTime:function(){return this.parseBoolean(this.showTime)},_showDate:function(){return this.parseBoolean(this.showDate)},_showSeconds:function(){return this.parseBoolean(this.showSeconds)}},data:function(){return{now:new Date}},methods:{refreshTime:function(){this.now=new Date}},mounted:function(){this.refreshTime(),setInterval(this.refreshTime,1e3)}};n("a8ae");c.render=i,c.__scopeId="data-v-4835dfb0";t["default"]=c},"5e1e":function(e,t,n){},a8ae:function(e,t,n){"use strict";n("5e1e")}}]);
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-4bbbb9a3"],{"365a":function(e,t,n){"use strict";n.r(t);var o=n("7a23"),s=Object(o["K"])("data-v-4835dfb0");Object(o["u"])("data-v-4835dfb0");var a={class:"date-time"};Object(o["s"])();var i=s((function(e,t,n,s,i,r){return Object(o["r"])(),Object(o["e"])("div",a,[r._showDate?(Object(o["r"])(),Object(o["e"])("div",{key:0,class:"date",textContent:Object(o["C"])(e.formatDate(e.now))},null,8,["textContent"])):Object(o["f"])("",!0),r._showTime?(Object(o["r"])(),Object(o["e"])("div",{key:1,class:"time",textContent:Object(o["C"])(e.formatTime(e.now,r._showSeconds))},null,8,["textContent"])):Object(o["f"])("",!0)])})),r=n("3e54"),c={name:"DateTime",mixins:[r["a"]],props:{showDate:{required:!1,default:!0},showTime:{required:!1,default:!0},showSeconds:{required:!1,default:!0}},computed:{_showTime:function(){return this.parseBoolean(this.showTime)},_showDate:function(){return this.parseBoolean(this.showDate)},_showSeconds:function(){return this.parseBoolean(this.showSeconds)}},data:function(){return{now:new Date}},methods:{refreshTime:function(){this.now=new Date}},mounted:function(){this.refreshTime(),setInterval(this.refreshTime,1e3)}};n("a8ae");c.render=i,c.__scopeId="data-v-4835dfb0";t["default"]=c},"5e1e":function(e,t,n){},a8ae:function(e,t,n){"use strict";n("5e1e")}}]);
|
||||||
//# sourceMappingURL=chunk-4bbbb9a3.6f0e4975.js.map
|
//# sourceMappingURL=chunk-4bbbb9a3.251fff37.js.map
|
|
@ -1 +1 @@
|
||||||
{"version":3,"sources":["webpack:///./src/components/widgets/DateTime/Index.vue","webpack:///./src/components/widgets/DateTime/Index.vue?de64","webpack:///./src/components/widgets/DateTime/Index.vue?fa60"],"names":["class","_showDate","now","_showTime","_showSeconds","name","mixins","Utils","props","showDate","required","default","showTime","showSeconds","computed","this","parseBoolean","data","Date","methods","refreshTime","mounted","setInterval","render","__scopeId"],"mappings":"sNACOA,MAAM,a,wEAAX,eAGM,MAHN,EAGM,CAF6C,EAAAC,W,iBAAjD,eAA8D,O,MAAzDD,MAAM,O,YAAO,eAAwB,EAAN,WAAC,EAAAE,O,+CAC0B,EAAAC,W,iBAA/D,eAA4E,O,MAAvEH,MAAM,O,YAAO,eAAsC,EAApB,WAAC,EAAAE,IAAK,EAAAE,gB,gEAQ/B,GACbC,KAAM,WACNC,OAAQ,CAACC,EAAA,MACTC,MAAO,CAELC,SAAU,CACRC,UAAU,EACVC,SAAS,GAIXC,SAAU,CACRF,UAAU,EACVC,SAAS,GAIXE,YAAa,CACXH,UAAU,EACVC,SAAS,IAIbG,SAAU,CACRX,UADQ,WAEN,OAAOY,KAAKC,aAAaD,KAAKH,WAGhCX,UALQ,WAMN,OAAOc,KAAKC,aAAaD,KAAKN,WAGhCL,aATQ,WAUN,OAAOW,KAAKC,aAAaD,KAAKF,eAIlCI,KAAM,WACJ,MAAO,CACLf,IAAK,IAAIgB,OAIbC,QAAS,CACPC,YADO,WAELL,KAAKb,IAAM,IAAIgB,OAInBG,QAAS,WACPN,KAAKK,cACLE,YAAYP,KAAKK,YAAa,O,UCzDlC,EAAOG,OAAS,EAChB,EAAOC,UAAY,kBAEJ,gB,2DCRf","file":"static/js/chunk-4bbbb9a3.6f0e4975.js","sourcesContent":["<template>\n <div class=\"date-time\">\n <div class=\"date\" v-text=\"formatDate(now)\" v-if=\"_showDate\" />\n <div class=\"time\" v-text=\"formatTime(now, _showSeconds)\" v-if=\"_showTime\" />\n </div>\n</template>\n\n<script>\nimport Utils from \"@/Utils\";\n\n// Widget to show date and time\nexport default {\n name: 'DateTime',\n mixins: [Utils],\n props: {\n // If false then don't display the date.\n showDate: {\n required: false,\n default: true,\n },\n\n // If false then don't display the time.\n showTime: {\n required: false,\n default: true,\n },\n\n // If false then don't display the seconds.\n showSeconds: {\n required: false,\n default: true,\n },\n },\n\n computed: {\n _showTime() {\n return this.parseBoolean(this.showTime)\n },\n\n _showDate() {\n return this.parseBoolean(this.showDate)\n },\n\n _showSeconds() {\n return this.parseBoolean(this.showSeconds)\n },\n },\n\n data: function() {\n return {\n now: new Date(),\n };\n },\n\n methods: {\n refreshTime() {\n this.now = new Date()\n },\n },\n\n mounted: function() {\n this.refreshTime()\n setInterval(this.refreshTime, 1000)\n },\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.date-time {\n .date {\n font-size: 1.1em;\n }\n\n .time {\n font-size: 2em;\n }\n}\n</style>\n","import { render } from \"./Index.vue?vue&type=template&id=4835dfb0&scoped=true&bindings={\\\"showDate\\\":\\\"props\\\",\\\"showTime\\\":\\\"props\\\",\\\"showSeconds\\\":\\\"props\\\",\\\"_showTime\\\":\\\"options\\\",\\\"_showDate\\\":\\\"options\\\",\\\"_showSeconds\\\":\\\"options\\\",\\\"refreshTime\\\":\\\"options\\\"}\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\n\nimport \"./Index.vue?vue&type=style&index=0&id=4835dfb0&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-4835dfb0\"\n\nexport default script","export * from \"-!../../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Index.vue?vue&type=style&index=0&id=4835dfb0&lang=scss&scoped=true\""],"sourceRoot":""}
|
{"version":3,"sources":["webpack:///./src/components/widgets/DateTime/Index.vue","webpack:///./src/components/widgets/DateTime/Index.vue?de64","webpack:///./src/components/widgets/DateTime/Index.vue?fa60"],"names":["class","_showDate","now","_showTime","_showSeconds","name","mixins","Utils","props","showDate","required","default","showTime","showSeconds","computed","this","parseBoolean","data","Date","methods","refreshTime","mounted","setInterval","render","__scopeId"],"mappings":"sNACOA,MAAM,a,wEAAX,eAGM,MAHN,EAGM,CAF6C,EAAAC,W,iBAAjD,eAA8D,O,MAAzDD,MAAM,O,YAAO,eAAwB,EAAN,WAAC,EAAAE,O,+CAC0B,EAAAC,W,iBAA/D,eAA4E,O,MAAvEH,MAAM,O,YAAO,eAAsC,EAApB,WAAC,EAAAE,IAAK,EAAAE,gB,gEAQ/B,GACbC,KAAM,WACNC,OAAQ,CAACC,EAAA,MACTC,MAAO,CAELC,SAAU,CACRC,UAAU,EACVC,SAAS,GAIXC,SAAU,CACRF,UAAU,EACVC,SAAS,GAIXE,YAAa,CACXH,UAAU,EACVC,SAAS,IAIbG,SAAU,CACRX,UADQ,WAEN,OAAOY,KAAKC,aAAaD,KAAKH,WAGhCX,UALQ,WAMN,OAAOc,KAAKC,aAAaD,KAAKN,WAGhCL,aATQ,WAUN,OAAOW,KAAKC,aAAaD,KAAKF,eAIlCI,KAAM,WACJ,MAAO,CACLf,IAAK,IAAIgB,OAIbC,QAAS,CACPC,YADO,WAELL,KAAKb,IAAM,IAAIgB,OAInBG,QAAS,WACPN,KAAKK,cACLE,YAAYP,KAAKK,YAAa,O,UCzDlC,EAAOG,OAAS,EAChB,EAAOC,UAAY,kBAEJ,gB,2DCRf","file":"static/js/chunk-4bbbb9a3.251fff37.js","sourcesContent":["<template>\n <div class=\"date-time\">\n <div class=\"date\" v-text=\"formatDate(now)\" v-if=\"_showDate\" />\n <div class=\"time\" v-text=\"formatTime(now, _showSeconds)\" v-if=\"_showTime\" />\n </div>\n</template>\n\n<script>\nimport Utils from \"@/Utils\";\n\n// Widget to show date and time\nexport default {\n name: 'DateTime',\n mixins: [Utils],\n props: {\n // If false then don't display the date.\n showDate: {\n required: false,\n default: true,\n },\n\n // If false then don't display the time.\n showTime: {\n required: false,\n default: true,\n },\n\n // If false then don't display the seconds.\n showSeconds: {\n required: false,\n default: true,\n },\n },\n\n computed: {\n _showTime() {\n return this.parseBoolean(this.showTime)\n },\n\n _showDate() {\n return this.parseBoolean(this.showDate)\n },\n\n _showSeconds() {\n return this.parseBoolean(this.showSeconds)\n },\n },\n\n data: function() {\n return {\n now: new Date(),\n };\n },\n\n methods: {\n refreshTime() {\n this.now = new Date()\n },\n },\n\n mounted: function() {\n this.refreshTime()\n setInterval(this.refreshTime, 1000)\n },\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.date-time {\n .date {\n font-size: 1.1em;\n }\n\n .time {\n font-size: 2em;\n }\n}\n</style>\n","import { render } from \"./Index.vue?vue&type=template&id=4835dfb0&scoped=true&bindings={\\\"showDate\\\":\\\"props\\\",\\\"showTime\\\":\\\"props\\\",\\\"showSeconds\\\":\\\"props\\\",\\\"_showTime\\\":\\\"options\\\",\\\"_showDate\\\":\\\"options\\\",\\\"_showSeconds\\\":\\\"options\\\",\\\"refreshTime\\\":\\\"options\\\"}\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\n\nimport \"./Index.vue?vue&type=style&index=0&id=4835dfb0&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-4835dfb0\"\n\nexport default script","export * from \"-!../../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Index.vue?vue&type=style&index=0&id=4835dfb0&lang=scss&scoped=true\""],"sourceRoot":""}
|
2
platypush/backend/http/dist/static/js/chunk-4c0b0f48.366980a2.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-4c0b0f48.366980a2.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-4c0b0f48"],{"4de4":function(e,n,t){"use strict";var u=t("23e7"),o=t("b727").filter,r=t("1dde"),i=t("ae40"),a=r("filter"),c=i("filter");u({target:"Array",proto:!0,forced:!a||!c},{filter:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},8285:function(e,n,t){"use strict";var u=t("7a23"),o=Object(u["K"])("data-v-12a0983b"),r=o((function(e,n,t,o,r,i){return Object(u["r"])(),Object(u["e"])("label",null,[Object(u["h"])("input",{class:"slider",type:"range",min:t.range[0],max:t.range[1],value:t.value,disabled:t.disabled,onChange:n[1]||(n[1]=function(n){return e.$emit("input",n)}),onMouseup:n[2]||(n[2]=function(n){return e.$emit("mouseup",n)}),onInput:n[3]||(n[3]=function(n){return e.$emit("input",n)}),onMousedown:n[4]||(n[4]=function(n){return e.$emit("mousedown",n)}),onTouch:n[5]||(n[5]=function(n){return e.$emit("input",n)}),onTouchstart:n[6]||(n[6]=function(n){return e.$emit("mousedown",n)}),onTouchend:n[7]||(n[7]=function(n){return e.$emit("mouseup",n)})},null,40,["min","max","value","disabled"])])})),i=(t("a9e3"),{name:"Slider",emits:["input","mouseup","mousedown"],props:{value:{type:Number},disabled:{type:Boolean,default:!1},range:{type:Array,default:function(){return[0,100]}}}});t("ee52");i.render=r,i.__scopeId="data-v-12a0983b";n["a"]=i},e1773:function(e,n,t){},ee52:function(e,n,t){"use strict";t("e1773")}}]);
|
||||||
|
//# sourceMappingURL=chunk-4c0b0f48.366980a2.js.map
|
1
platypush/backend/http/dist/static/js/chunk-4c0b0f48.366980a2.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-4c0b0f48.366980a2.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/chunk-4eeb8349.5c94d58c.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-4eeb8349.5c94d58c.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/chunk-4eeb8349.5c94d58c.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-4eeb8349.5c94d58c.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/chunk-52804492.1cbed362.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-52804492.1cbed362.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/chunk-52804492.1cbed362.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-52804492.1cbed362.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,2 +0,0 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-545459d0"],{8285:function(e,n,u){"use strict";var t=u("7a23"),o=Object(t["J"])("data-v-12a0983b"),i=o((function(e,n,u,o,i,a){return Object(t["r"])(),Object(t["e"])("label",null,[Object(t["h"])("input",{class:"slider",type:"range",min:u.range[0],max:u.range[1],value:u.value,disabled:u.disabled,onChange:n[1]||(n[1]=function(n){return e.$emit("input",n)}),onMouseup:n[2]||(n[2]=function(n){return e.$emit("mouseup",n)}),onInput:n[3]||(n[3]=function(n){return e.$emit("input",n)}),onMousedown:n[4]||(n[4]=function(n){return e.$emit("mousedown",n)}),onTouch:n[5]||(n[5]=function(n){return e.$emit("input",n)}),onTouchstart:n[6]||(n[6]=function(n){return e.$emit("mousedown",n)}),onTouchend:n[7]||(n[7]=function(n){return e.$emit("mouseup",n)})},null,40,["min","max","value","disabled"])])})),a=(u("a9e3"),{name:"Slider",emits:["input","mouseup","mousedown"],props:{value:{type:Number},disabled:{type:Boolean,default:!1},range:{type:Array,default:function(){return[0,100]}}}});u("ee52");a.render=i,a.__scopeId="data-v-12a0983b";n["a"]=a},e1773:function(e,n,u){},ee52:function(e,n,u){"use strict";u("e1773")}}]);
|
|
||||||
//# sourceMappingURL=chunk-545459d0.aa1e42a3.js.map
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"sources":["webpack:///./src/components/elements/Slider.vue","webpack:///./src/components/elements/Slider.vue?7dba","webpack:///./src/components/elements/Slider.vue?5806"],"names":["class","type","min","range","max","value","disabled","$emit","$event","name","emits","props","Number","Boolean","default","Array","render","__scopeId"],"mappings":"uNACE,eAKQ,cAJN,eAGqF,SAH9EA,MAAM,SAASC,KAAK,QAASC,IAAK,EAAAC,MAAK,GAAMC,IAAK,EAAAD,MAAK,GAAME,MAAO,EAAAA,MAAQC,SAAU,EAAAA,SACrF,SAAM,+BAAE,EAAAC,MAAK,QAAUC,KAAU,UAAO,+BAAE,EAAAD,MAAK,UAAYC,KAAU,QAAK,+BAAE,EAAAD,MAAK,QAAUC,KAC3F,YAAS,+BAAE,EAAAD,MAAK,YAAcC,KAAU,QAAK,+BAAE,EAAAD,MAAK,QAAUC,KAC9D,aAAU,+BAAE,EAAAD,MAAK,YAAcC,KAAU,WAAQ,+BAAE,EAAAD,MAAK,UAAYC,M,+CAKjE,G,UAAA,CACbC,KAAM,SACNC,MAAO,CAAC,QAAS,UAAW,aAC5BC,MAAO,CACLN,MAAO,CACLJ,KAAMW,QAGRN,SAAU,CACRL,KAAMY,QACNC,SAAS,GAGXX,MAAO,CACLF,KAAMc,MACND,QAAS,iBAAM,CAAC,EAAG,U,UCpBzB,EAAOE,OAAS,EAChB,EAAOC,UAAY,kBAEJ,U,0DCRf","file":"static/js/chunk-545459d0.aa1e42a3.js","sourcesContent":["<template>\n <label>\n <input class=\"slider\" type=\"range\" :min=\"range[0]\" :max=\"range[1]\" :value=\"value\" :disabled=\"disabled\"\n @change=\"$emit('input', $event)\" @mouseup=\"$emit('mouseup', $event)\" @input=\"$emit('input', $event)\"\n @mousedown=\"$emit('mousedown', $event)\" @touch=\"$emit('input', $event)\"\n @touchstart=\"$emit('mousedown', $event)\" @touchend=\"$emit('mouseup', $event)\">\n </label>\n</template>\n\n<script>\nexport default {\n name: \"Slider\",\n emits: ['input', 'mouseup', 'mousedown'],\n props: {\n value: {\n type: Number,\n },\n\n disabled: {\n type: Boolean,\n default: false,\n },\n\n range: {\n type: Array,\n default: () => [0, 100],\n },\n },\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.slider {\n @include appearance(none);\n @include transition(opacity .2s);\n width: 100%;\n height: 1em;\n border-radius: 0.33em;\n background: $slider-bg;\n outline: none;\n\n @mixin slider-thumb {\n @include appearance(none);\n width: 1.5em;\n height: 1.5em;\n border-radius: 50%;\n border: 0;\n background: $slider-thumb-bg;\n cursor: pointer;\n }\n\n &::-webkit-slider-thumb { @include slider-thumb; }\n &::-moz-range-thumb { @include slider-thumb; }\n &::-moz-range-track { @include appearance(none); }\n\n &::-webkit-progress-value,\n &::-moz-range-progress {\n background: $slider-progress-bg;\n height: 1em;\n }\n\n &[disabled] {\n &::-webkit-progress-value,\n &::-moz-range-progress {\n background: none;\n }\n\n &::-webkit-slider-thumb,\n &::-moz-range-thumb {\n display: none;\n width: 0;\n }\n }\n}\n</style>","import { render } from \"./Slider.vue?vue&type=template&id=12a0983b&scoped=true&bindings={\\\"value\\\":\\\"props\\\",\\\"disabled\\\":\\\"props\\\",\\\"range\\\":\\\"props\\\"}\"\nimport script from \"./Slider.vue?vue&type=script&lang=js\"\nexport * from \"./Slider.vue?vue&type=script&lang=js\"\n\nimport \"./Slider.vue?vue&type=style&index=0&id=12a0983b&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-12a0983b\"\n\nexport default script","export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Slider.vue?vue&type=style&index=0&id=12a0983b&lang=scss&scoped=true\""],"sourceRoot":""}
|
|
|
@ -1,2 +1,2 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-62a3d08e"],{"2eb2":function(e,t,n){"use strict";n("8647")},"3c97":function(e,t,n){"use strict";n.r(t);n("fb6a");var a=n("7a23"),s=Object(a["J"])("data-v-bb595e58");Object(a["u"])("data-v-bb595e58");var r={class:"calendar"},c={key:1,class:"no-events"},i={key:2,class:"event upcoming-event"},o={class:"time"},d={key:3,class:"event-list"};Object(a["s"])();var u=s((function(e,t,n,s,u,b){var l=Object(a["z"])("Loading");return Object(a["r"])(),Object(a["e"])("div",r,[e.loading?(Object(a["r"])(),Object(a["e"])(l,{key:0})):e.events.length?e.events.length>0?(Object(a["r"])(),Object(a["e"])("div",i,[Object(a["h"])("div",{class:"date",textContent:Object(a["C"])(e.formatDate(e.events[0].start))},null,8,["textContent"]),Object(a["h"])("div",{class:"summary",textContent:Object(a["C"])(e.events[0].summary)},null,8,["textContent"]),Object(a["h"])("div",o,Object(a["C"])(e.formatTime(e.events[0].start,!1))+" - "+Object(a["C"])(e.formatTime(e.events[0].end,!1)),1)])):Object(a["f"])("",!0):(Object(a["r"])(),Object(a["e"])("div",c," No events found ")),e.events.length>1?(Object(a["r"])(),Object(a["e"])("div",d,[(Object(a["r"])(!0),Object(a["e"])(a["a"],null,Object(a["x"])(e.events.slice(1,n.maxEvents),(function(t){return Object(a["r"])(),Object(a["e"])("div",{class:"event",key:t.id},[Object(a["h"])("div",{class:"date col-2",textContent:Object(a["C"])(e.formatDate(t.start))},null,8,["textContent"]),Object(a["h"])("div",{class:"time col-2",textContent:Object(a["C"])(e.formatTime(t.start,!1))},null,8,["textContent"]),Object(a["h"])("div",{class:"summary col-8",textContent:Object(a["C"])(t.summary)},null,8,["textContent"])])})),128))])):Object(a["f"])("",!0)])})),b=(n("d81d"),n("a9e3"),n("b680"),n("96cf"),n("1da1")),l=n("3e54"),v=n("3a5e"),j={name:"Calendar",components:{Loading:v["a"]},mixins:[l["a"]],props:{maxEvents:{type:Number,required:!1,default:10},refreshSeconds:{type:Number,required:!1,default:600}},data:function(){return{events:[],loading:!1}},methods:{refresh:function(){var e=Object(b["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return this.loading=!0,e.prev=1,e.next=4,this.request("calendar.get_upcoming_events");case 4:this.events=e.sent.map((function(e){return e.start&&(e.start=new Date(e.start.dateTime||e.start.date)),e.end&&(e.end=new Date(e.end.dateTime||e.end.date)),e}));case 5:return e.prev=5,this.loading=!1,e.finish(5);case 8:case"end":return e.stop()}}),e,this,[[1,,5,8]])})));function t(){return e.apply(this,arguments)}return t}()},mounted:function(){this.refresh(),setInterval(this.refresh,parseInt((1e3*this.refreshSeconds).toFixed(0)))}};n("2eb2");j.render=u,j.__scopeId="data-v-bb595e58";t["default"]=j},8647:function(e,t,n){}}]);
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-62a3d08e"],{"2eb2":function(e,t,n){"use strict";n("8647")},"3c97":function(e,t,n){"use strict";n.r(t);n("fb6a");var a=n("7a23"),s=Object(a["K"])("data-v-bb595e58");Object(a["u"])("data-v-bb595e58");var r={class:"calendar"},c={key:1,class:"no-events"},i={key:2,class:"event upcoming-event"},o={class:"time"},d={key:3,class:"event-list"};Object(a["s"])();var u=s((function(e,t,n,s,u,b){var l=Object(a["z"])("Loading");return Object(a["r"])(),Object(a["e"])("div",r,[e.loading?(Object(a["r"])(),Object(a["e"])(l,{key:0})):e.events.length?e.events.length>0?(Object(a["r"])(),Object(a["e"])("div",i,[Object(a["h"])("div",{class:"date",textContent:Object(a["C"])(e.formatDate(e.events[0].start))},null,8,["textContent"]),Object(a["h"])("div",{class:"summary",textContent:Object(a["C"])(e.events[0].summary)},null,8,["textContent"]),Object(a["h"])("div",o,Object(a["C"])(e.formatTime(e.events[0].start,!1))+" - "+Object(a["C"])(e.formatTime(e.events[0].end,!1)),1)])):Object(a["f"])("",!0):(Object(a["r"])(),Object(a["e"])("div",c," No events found ")),e.events.length>1?(Object(a["r"])(),Object(a["e"])("div",d,[(Object(a["r"])(!0),Object(a["e"])(a["a"],null,Object(a["x"])(e.events.slice(1,n.maxEvents),(function(t){return Object(a["r"])(),Object(a["e"])("div",{class:"event",key:t.id},[Object(a["h"])("div",{class:"date col-2",textContent:Object(a["C"])(e.formatDate(t.start))},null,8,["textContent"]),Object(a["h"])("div",{class:"time col-2",textContent:Object(a["C"])(e.formatTime(t.start,!1))},null,8,["textContent"]),Object(a["h"])("div",{class:"summary col-8",textContent:Object(a["C"])(t.summary)},null,8,["textContent"])])})),128))])):Object(a["f"])("",!0)])})),b=(n("d81d"),n("a9e3"),n("b680"),n("96cf"),n("1da1")),l=n("3e54"),v=n("3a5e"),j={name:"Calendar",components:{Loading:v["a"]},mixins:[l["a"]],props:{maxEvents:{type:Number,required:!1,default:10},refreshSeconds:{type:Number,required:!1,default:600}},data:function(){return{events:[],loading:!1}},methods:{refresh:function(){var e=Object(b["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return this.loading=!0,e.prev=1,e.next=4,this.request("calendar.get_upcoming_events");case 4:this.events=e.sent.map((function(e){return e.start&&(e.start=new Date(e.start.dateTime||e.start.date)),e.end&&(e.end=new Date(e.end.dateTime||e.end.date)),e}));case 5:return e.prev=5,this.loading=!1,e.finish(5);case 8:case"end":return e.stop()}}),e,this,[[1,,5,8]])})));function t(){return e.apply(this,arguments)}return t}()},mounted:function(){this.refresh(),setInterval(this.refresh,parseInt((1e3*this.refreshSeconds).toFixed(0)))}};n("2eb2");j.render=u,j.__scopeId="data-v-bb595e58";t["default"]=j},8647:function(e,t,n){}}]);
|
||||||
//# sourceMappingURL=chunk-62a3d08e.8fc4fd3a.js.map
|
//# sourceMappingURL=chunk-62a3d08e.17d3c86d.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-d8561e02"],{"49c1":function(e,t,n){},"9e1b":function(e,t,n){"use strict";n("49c1")},dabe:function(e,t,n){"use strict";n.r(t);var i=n("7a23"),c=Object(i["J"])("data-v-3565b88b");Object(i["u"])("data-v-3565b88b");var o={class:"plugin"};Object(i["s"])();var a=c((function(e,t,n,c,a,r){var s=Object(i["z"])("Loading");return Object(i["r"])(),Object(i["e"])("div",o,[a.loading?(Object(i["r"])(),Object(i["e"])(s,{key:0})):a.component?(Object(i["r"])(),Object(i["e"])(Object(i["A"])(a.component),{key:1,config:a.config},null,8,["config"])):Object(i["f"])("",!0)])})),r=(n("a15b"),n("d81d"),n("fb6a"),n("d3b7"),n("ac1f"),n("1276"),n("96cf"),n("1da1")),s=n("3e54"),u=n("3a5e"),p={name:"Plugin",components:{Loading:u["a"]},mixins:[s["a"]],props:{pluginName:{type:String,required:!0}},data:function(){return{loading:!1,component:null,config:{}}},computed:{componentName:function(){return this.pluginName.split(".").map((function(e){return e[0].toUpperCase()+e.slice(1)})).join("")}},methods:{refresh:function(){var e=Object(r["a"])(regeneratorRuntime.mark((function e(){var t,c=this;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return this.loading=!0,e.prev=1,this.component=Object(i["i"])((function(){return n("0f0c")("./".concat(c.componentName,"/Index"))})),this.$options.components[this.componentName]=this.component,e.next=6,this.request("config.get_plugins");case 6:if(e.t2=t=e.sent,e.t1=null===e.t2,e.t1){e.next=10;break}e.t1=void 0===t;case 10:if(!e.t1){e.next=14;break}e.t3=void 0,e.next=15;break;case 14:e.t3=t[this.pluginName];case 15:if(e.t0=e.t3,e.t0){e.next=18;break}e.t0={};case 18:this.config=e.t0;case 19:return e.prev=19,this.loading=!1,e.finish(19);case 22:case"end":return e.stop()}}),e,this,[[1,,19,22]])})));function t(){return e.apply(this,arguments)}return t}()},mounted:function(){this.refresh()}};n("9e1b");p.render=a,p.__scopeId="data-v-3565b88b";t["default"]=p}}]);
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-d8561e02"],{"49c1":function(e,t,n){},"9e1b":function(e,t,n){"use strict";n("49c1")},dabe:function(e,t,n){"use strict";n.r(t);var i=n("7a23"),c=Object(i["K"])("data-v-3565b88b");Object(i["u"])("data-v-3565b88b");var o={class:"plugin"};Object(i["s"])();var a=c((function(e,t,n,c,a,r){var s=Object(i["z"])("Loading");return Object(i["r"])(),Object(i["e"])("div",o,[a.loading?(Object(i["r"])(),Object(i["e"])(s,{key:0})):a.component?(Object(i["r"])(),Object(i["e"])(Object(i["A"])(a.component),{key:1,config:a.config},null,8,["config"])):Object(i["f"])("",!0)])})),r=(n("a15b"),n("d81d"),n("fb6a"),n("d3b7"),n("ac1f"),n("1276"),n("96cf"),n("1da1")),s=n("3e54"),u=n("3a5e"),p={name:"Plugin",components:{Loading:u["a"]},mixins:[s["a"]],props:{pluginName:{type:String,required:!0}},data:function(){return{loading:!1,component:null,config:{}}},computed:{componentName:function(){return this.pluginName.split(".").map((function(e){return e[0].toUpperCase()+e.slice(1)})).join("")}},methods:{refresh:function(){var e=Object(r["a"])(regeneratorRuntime.mark((function e(){var t,c=this;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return this.loading=!0,e.prev=1,this.component=Object(i["i"])((function(){return n("0f0c")("./".concat(c.componentName,"/Index"))})),this.$options.components[this.componentName]=this.component,e.next=6,this.request("config.get_plugins");case 6:if(e.t2=t=e.sent,e.t1=null===e.t2,e.t1){e.next=10;break}e.t1=void 0===t;case 10:if(!e.t1){e.next=14;break}e.t3=void 0,e.next=15;break;case 14:e.t3=t[this.pluginName];case 15:if(e.t0=e.t3,e.t0){e.next=18;break}e.t0={};case 18:this.config=e.t0;case 19:return e.prev=19,this.loading=!1,e.finish(19);case 22:case"end":return e.stop()}}),e,this,[[1,,19,22]])})));function t(){return e.apply(this,arguments)}return t}()},mounted:function(){this.refresh()}};n("9e1b");p.render=a,p.__scopeId="data-v-3565b88b";t["default"]=p}}]);
|
||||||
//# sourceMappingURL=chunk-d8561e02.78e44394.js.map
|
//# sourceMappingURL=chunk-d8561e02.1e366cb3.js.map
|
|
@ -1 +1 @@
|
||||||
{"version":3,"sources":["webpack:///./src/components/widgets/Plugin/Index.vue?bbf0","webpack:///./src/components/widgets/Plugin/Index.vue","webpack:///./src/components/widgets/Plugin/Index.vue?fc8a"],"names":["class","loading","component","config","name","components","Loading","mixins","Utils","props","pluginName","type","String","required","data","computed","componentName","this","split","map","t","toUpperCase","slice","join","methods","refresh","$options","request","mounted","render","__scopeId"],"mappings":"2IAAA,W,sICCOA,MAAM,U,wGAAX,eAGM,MAHN,EAGM,CAFW,EAAAC,S,iBAAf,eAA0B,YAC6B,EAAAC,W,iBAAvD,eAAoE,eAApD,EAAAA,WAAS,C,MAAGC,OAAQ,EAAAA,Q,2JASzB,GACbC,KAAM,SACNC,WAAY,CAACC,UAAA,MACbC,OAAQ,CAACC,EAAA,MACTC,MAAO,CAELC,WAAY,CACVC,KAAMC,OACNC,UAAU,IAIdC,KAZa,WAaX,MAAO,CACLb,SAAS,EACTC,UAAW,KACXC,OAAQ,KAIZY,SAAU,CACRC,cADQ,WAEN,OAAOC,KAAKP,WAAWQ,MAAM,KAAKC,KAAI,SAACC,GAAD,OAAOA,EAAE,GAAGC,cAAgBD,EAAEE,MAAM,MAAIC,KAAK,MAIvFC,QAAS,CACPC,QAAS,WAAF,8CAAE,kHACPR,KAAKhB,SAAU,EADR,SAILgB,KAAKf,UAAY,gBAAqB,kBAAM,UAAO,YAAuB,EAAKc,cAAnC,cAC5CC,KAAKS,SAASrB,WAAWY,KAAKD,eAAiBC,KAAKf,UAL/C,SAMgBe,KAAKU,QAAQ,sBAN7B,0JAMS,EAA6CV,KAAKP,YAN3D,gDAM0E,GAN1E,QAMLO,KAAKd,OANA,8BAQLc,KAAKhB,SAAU,EARV,2EAAF,qDAAE,IAaX2B,QAAS,WACPX,KAAKQ,Y,UChDT,EAAOI,OAAS,EAChB,EAAOC,UAAY,kBAEJ","file":"static/js/chunk-d8561e02.78e44394.js","sourcesContent":["export * from \"-!../../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Index.vue?vue&type=style&index=0&id=3565b88b&lang=scss&scoped=true\"","<template>\n <div class=\"plugin\">\n <Loading v-if=\"loading\" />\n <component :is=\"component\" :config=\"config\" v-else-if=\"component\" />\n </div>\n</template>\n\n<script>\nimport Utils from \"@/Utils\";\nimport Loading from \"@/components/Loading\";\nimport {defineAsyncComponent} from \"vue\";\n\nexport default {\n name: \"Plugin\",\n components: {Loading},\n mixins: [Utils],\n props: {\n // Name of the plugin view to be loaded\n pluginName: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n loading: false,\n component: null,\n config: {},\n }\n },\n\n computed: {\n componentName() {\n return this.pluginName.split('.').map((t) => t[0].toUpperCase() + t.slice(1)).join('')\n },\n },\n\n methods: {\n refresh: async function() {\n this.loading = true\n\n try {\n this.component = defineAsyncComponent(() => import(`@/components/panels/${this.componentName}/Index`))\n this.$options.components[this.componentName] = this.component\n this.config = (await this.request('config.get_plugins'))?.[this.pluginName] || {}\n } finally {\n this.loading = false\n }\n },\n },\n\n mounted: function() {\n this.refresh()\n },\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.plugin {\n margin: -1em 0 0 -1em !important;\n padding: 0;\n width: calc(100% + 2em);\n height: calc(100% + 2em);\n}\n</style>\n","import { render } from \"./Index.vue?vue&type=template&id=3565b88b&scoped=true&bindings={\\\"pluginName\\\":\\\"props\\\",\\\"loading\\\":\\\"data\\\",\\\"component\\\":\\\"data\\\",\\\"config\\\":\\\"data\\\",\\\"componentName\\\":\\\"options\\\",\\\"refresh\\\":\\\"options\\\"}\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\n\nimport \"./Index.vue?vue&type=style&index=0&id=3565b88b&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-3565b88b\"\n\nexport default script"],"sourceRoot":""}
|
{"version":3,"sources":["webpack:///./src/components/widgets/Plugin/Index.vue?bbf0","webpack:///./src/components/widgets/Plugin/Index.vue","webpack:///./src/components/widgets/Plugin/Index.vue?fc8a"],"names":["class","loading","component","config","name","components","Loading","mixins","Utils","props","pluginName","type","String","required","data","computed","componentName","this","split","map","t","toUpperCase","slice","join","methods","refresh","$options","request","mounted","render","__scopeId"],"mappings":"2IAAA,W,sICCOA,MAAM,U,wGAAX,eAGM,MAHN,EAGM,CAFW,EAAAC,S,iBAAf,eAA0B,YAC6B,EAAAC,W,iBAAvD,eAAoE,eAApD,EAAAA,WAAS,C,MAAGC,OAAQ,EAAAA,Q,2JASzB,GACbC,KAAM,SACNC,WAAY,CAACC,UAAA,MACbC,OAAQ,CAACC,EAAA,MACTC,MAAO,CAELC,WAAY,CACVC,KAAMC,OACNC,UAAU,IAIdC,KAZa,WAaX,MAAO,CACLb,SAAS,EACTC,UAAW,KACXC,OAAQ,KAIZY,SAAU,CACRC,cADQ,WAEN,OAAOC,KAAKP,WAAWQ,MAAM,KAAKC,KAAI,SAACC,GAAD,OAAOA,EAAE,GAAGC,cAAgBD,EAAEE,MAAM,MAAIC,KAAK,MAIvFC,QAAS,CACPC,QAAS,WAAF,8CAAE,kHACPR,KAAKhB,SAAU,EADR,SAILgB,KAAKf,UAAY,gBAAqB,kBAAM,UAAO,YAAuB,EAAKc,cAAnC,cAC5CC,KAAKS,SAASrB,WAAWY,KAAKD,eAAiBC,KAAKf,UAL/C,SAMgBe,KAAKU,QAAQ,sBAN7B,0JAMS,EAA6CV,KAAKP,YAN3D,gDAM0E,GAN1E,QAMLO,KAAKd,OANA,8BAQLc,KAAKhB,SAAU,EARV,2EAAF,qDAAE,IAaX2B,QAAS,WACPX,KAAKQ,Y,UChDT,EAAOI,OAAS,EAChB,EAAOC,UAAY,kBAEJ","file":"static/js/chunk-d8561e02.1e366cb3.js","sourcesContent":["export * from \"-!../../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../../../../node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!../../../../node_modules/vue-loader-v16/dist/stylePostLoader.js!../../../../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../../../../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../../node_modules/vue-loader-v16/dist/index.js??ref--0-1!./Index.vue?vue&type=style&index=0&id=3565b88b&lang=scss&scoped=true\"","<template>\n <div class=\"plugin\">\n <Loading v-if=\"loading\" />\n <component :is=\"component\" :config=\"config\" v-else-if=\"component\" />\n </div>\n</template>\n\n<script>\nimport Utils from \"@/Utils\";\nimport Loading from \"@/components/Loading\";\nimport {defineAsyncComponent} from \"vue\";\n\nexport default {\n name: \"Plugin\",\n components: {Loading},\n mixins: [Utils],\n props: {\n // Name of the plugin view to be loaded\n pluginName: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n loading: false,\n component: null,\n config: {},\n }\n },\n\n computed: {\n componentName() {\n return this.pluginName.split('.').map((t) => t[0].toUpperCase() + t.slice(1)).join('')\n },\n },\n\n methods: {\n refresh: async function() {\n this.loading = true\n\n try {\n this.component = defineAsyncComponent(() => import(`@/components/panels/${this.componentName}/Index`))\n this.$options.components[this.componentName] = this.component\n this.config = (await this.request('config.get_plugins'))?.[this.pluginName] || {}\n } finally {\n this.loading = false\n }\n },\n },\n\n mounted: function() {\n this.refresh()\n },\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.plugin {\n margin: -1em 0 0 -1em !important;\n padding: 0;\n width: calc(100% + 2em);\n height: calc(100% + 2em);\n}\n</style>\n","import { render } from \"./Index.vue?vue&type=template&id=3565b88b&scoped=true&bindings={\\\"pluginName\\\":\\\"props\\\",\\\"loading\\\":\\\"data\\\",\\\"component\\\":\\\"data\\\",\\\"config\\\":\\\"data\\\",\\\"componentName\\\":\\\"options\\\",\\\"refresh\\\":\\\"options\\\"}\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\n\nimport \"./Index.vue?vue&type=style&index=0&id=3565b88b&lang=scss&scoped=true\"\nscript.render = render\nscript.__scopeId = \"data-v-3565b88b\"\n\nexport default script"],"sourceRoot":""}
|
|
@ -1,2 +1,2 @@
|
||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-e8078048"],{"3ddd":function(e,t,r){},a41f:function(e,t,r){"use strict";r("3ddd")},c306:function(e,t,r){"use strict";r.r(t);var n=r("7a23"),s=Object(n["J"])("data-v-919872a2");Object(n["u"])("data-v-919872a2");var i={class:"rss-news"},c={key:0,class:"article"};Object(n["s"])();var u=s((function(e,t,r,s,u,a){return Object(n["r"])(),Object(n["e"])("div",i,[e.currentArticle?(Object(n["r"])(),Object(n["e"])("div",c,[Object(n["h"])("div",{class:"source",textContent:Object(n["C"])(e.currentArticle.source)},null,8,["textContent"]),Object(n["h"])("div",{class:"title",textContent:Object(n["C"])(e.currentArticle.title)},null,8,["textContent"]),Object(n["h"])("div",{class:"published",textContent:Object(n["C"])(new Date(e.currentArticle.published).toDateString()+", "+new Date(e.currentArticle.published).toTimeString().substring(0,5))},null,8,["textContent"])])):Object(n["f"])("",!0)])})),a=(r("a9e3"),r("b680"),r("2909")),d=(r("96cf"),r("1da1")),l=r("3e54"),o={name:"RssNews",mixins:[l["a"]],props:{db:{type:String,required:!0},limit:{type:Number,required:!1,default:25},refreshSeconds:{type:Number,required:!1,default:15}},data:function(){return{articles:[],queue:[],currentArticle:void 0}},methods:{refresh:function(){var e=Object(d["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:if(this.queue.length){e.next=5;break}return e.next=3,this.request("db.select",{engine:this.db,query:"\n select s.title as source, e.title, e.summary,\n strftime('%Y-%m-%dT%H:%M:%fZ', e.published) as published\n from FeedEntry e join FeedSource s\n on e.source_id = s.id order by e.published desc limit ".concat(this.limit)});case 3:this.articles=e.sent,this.queue=Object(a["a"])(this.articles);case 5:if(this.queue.length){e.next=7;break}return e.abrupt("return");case 7:this.currentArticle=this.queue.pop();case 8:case"end":return e.stop()}}),e,this)})));function t(){return e.apply(this,arguments)}return t}()},mounted:function(){this.refresh(),setInterval(this.refresh,parseInt((1e3*this.refreshSeconds).toFixed(0)))}};r("a41f");o.render=u,o.__scopeId="data-v-919872a2";t["default"]=o}}]);
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-e8078048"],{"3ddd":function(e,t,r){},a41f:function(e,t,r){"use strict";r("3ddd")},c306:function(e,t,r){"use strict";r.r(t);var n=r("7a23"),s=Object(n["K"])("data-v-919872a2");Object(n["u"])("data-v-919872a2");var i={class:"rss-news"},c={key:0,class:"article"};Object(n["s"])();var u=s((function(e,t,r,s,u,a){return Object(n["r"])(),Object(n["e"])("div",i,[e.currentArticle?(Object(n["r"])(),Object(n["e"])("div",c,[Object(n["h"])("div",{class:"source",textContent:Object(n["C"])(e.currentArticle.source)},null,8,["textContent"]),Object(n["h"])("div",{class:"title",textContent:Object(n["C"])(e.currentArticle.title)},null,8,["textContent"]),Object(n["h"])("div",{class:"published",textContent:Object(n["C"])(new Date(e.currentArticle.published).toDateString()+", "+new Date(e.currentArticle.published).toTimeString().substring(0,5))},null,8,["textContent"])])):Object(n["f"])("",!0)])})),a=(r("a9e3"),r("b680"),r("2909")),d=(r("96cf"),r("1da1")),l=r("3e54"),o={name:"RssNews",mixins:[l["a"]],props:{db:{type:String,required:!0},limit:{type:Number,required:!1,default:25},refreshSeconds:{type:Number,required:!1,default:15}},data:function(){return{articles:[],queue:[],currentArticle:void 0}},methods:{refresh:function(){var e=Object(d["a"])(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:if(this.queue.length){e.next=5;break}return e.next=3,this.request("db.select",{engine:this.db,query:"\n select s.title as source, e.title, e.summary,\n strftime('%Y-%m-%dT%H:%M:%fZ', e.published) as published\n from FeedEntry e join FeedSource s\n on e.source_id = s.id order by e.published desc limit ".concat(this.limit)});case 3:this.articles=e.sent,this.queue=Object(a["a"])(this.articles);case 5:if(this.queue.length){e.next=7;break}return e.abrupt("return");case 7:this.currentArticle=this.queue.pop();case 8:case"end":return e.stop()}}),e,this)})));function t(){return e.apply(this,arguments)}return t}()},mounted:function(){this.refresh(),setInterval(this.refresh,parseInt((1e3*this.refreshSeconds).toFixed(0)))}};r("a41f");o.render=u,o.__scopeId="data-v-919872a2";t["default"]=o}}]);
|
||||||
//# sourceMappingURL=chunk-e8078048.e668de5f.js.map
|
//# sourceMappingURL=chunk-e8078048.ce29b8d4.js.map
|
File diff suppressed because one or more lines are too long
7
platypush/backend/http/dist/static/js/chunk-vendors.30e3a6cb.js
vendored
Normal file
7
platypush/backend/http/dist/static/js/chunk-vendors.30e3a6cb.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/chunk-vendors.30e3a6cb.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-vendors.30e3a6cb.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -53,7 +53,7 @@ export default {
|
||||||
async initConfig() {
|
async initConfig() {
|
||||||
this.config = await this.request('config.get')
|
this.config = await this.request('config.get')
|
||||||
this.userAuthenticated = true
|
this.userAuthenticated = true
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="modal-container fade-in" :id="id" :class="{hidden: !isVisible}" :style="{'--z-index': zIndex}" @click="close">
|
<div class="modal-container fade-in" :id="id" :class="{hidden: !isVisible}" :style="{'--z-index': zIndex}" @click="close">
|
||||||
<div class="modal" :style="{'--width': width, '--height': height}">
|
<div class="modal">
|
||||||
<div class="content" @click="$event.stopPropagation()">
|
<div class="content" :style="{'--width': width, '--height': height}" @click="$event.stopPropagation()">
|
||||||
<div class="header" v-text="title" v-if="title"></div>
|
<div class="header" v-text="title" v-if="title"></div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<slot @modal-close="close" />
|
<slot @modal-close="close" />
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "Modal",
|
name: "Modal",
|
||||||
|
emits: ['close', 'open'],
|
||||||
props: {
|
props: {
|
||||||
// Modal ID
|
// Modal ID
|
||||||
id: {
|
id: {
|
||||||
|
@ -86,6 +87,19 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
const self = this
|
||||||
|
const visibleHndl = (visible) => {
|
||||||
|
if (!visible)
|
||||||
|
self.$emit('close')
|
||||||
|
else
|
||||||
|
self.$emit('open')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$watch(() => this.visible, visibleHndl)
|
||||||
|
this.$watch(() => this.isVisible, visibleHndl)
|
||||||
|
},
|
||||||
|
|
||||||
updated() {
|
updated() {
|
||||||
this.prevVisible = this.isVisible
|
this.prevVisible = this.isVisible
|
||||||
if (this.isVisible) {
|
if (this.isVisible) {
|
||||||
|
@ -138,13 +152,13 @@ export default {
|
||||||
background: rgba(10,10,10,0.9);
|
background: rgba(10,10,10,0.9);
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.content {
|
||||||
--width: auto;
|
--width: auto;
|
||||||
--height: auto;
|
--height: auto;
|
||||||
width: var(--width);
|
width: var(--width);
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
background: $modal-body-bg;
|
background: $modal-body-bg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ export default {
|
||||||
|
|
||||||
onItemClick(name) {
|
onItemClick(name) {
|
||||||
this.$emit('select', name)
|
this.$emit('select', name)
|
||||||
if (this.isMobile())
|
|
||||||
this.collapsed = true
|
this.collapsed = true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -75,14 +75,11 @@ export default {
|
||||||
element.style.left = 0
|
element.style.left = 0
|
||||||
element.style.top = parseFloat(getComputedStyle(this.$refs.button).height) + 'px'
|
element.style.top = parseFloat(getComputedStyle(this.$refs.button).height) + 'px'
|
||||||
|
|
||||||
const maxOffset = 45
|
if (element.getBoundingClientRect().left > window.innerWidth/2)
|
||||||
const maxLeft = window.innerWidth - maxOffset
|
element.style.left = (-element.clientWidth + parseFloat(getComputedStyle(this.$refs.button).width)) + 'px'
|
||||||
const left = this.$refs.container.offsetLeft + element.offsetLeft
|
|
||||||
const width = element.clientWidth
|
|
||||||
|
|
||||||
if (left + width >= maxLeft) {
|
if (element.getBoundingClientRect().top > window.innerHeight/2)
|
||||||
element.style.left = -(parseFloat(getComputedStyle(this.$refs.button).width) + maxOffset) + 'px'
|
element.style.top = (-element.clientHeight + parseFloat(getComputedStyle(this.$refs.button).height)) + 'px'
|
||||||
}
|
|
||||||
}, 10)
|
}, 10)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<template>
|
||||||
|
<div class="form-footer">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "FormFooter"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.form-footer {
|
||||||
|
height: 5em;
|
||||||
|
padding: 1em;
|
||||||
|
text-align: right;
|
||||||
|
border-top: $default-border-2;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -12,24 +12,114 @@
|
||||||
|
|
||||||
<div class="view-container">
|
<div class="view-container">
|
||||||
<Playlist :tracks="tracks" :status="status" :loading="loading" v-if="selectedView === 'playing'"
|
<Playlist :tracks="tracks" :status="status" :loading="loading" v-if="selectedView === 'playing'"
|
||||||
@play="$emit('play', $event)" @clear="$emit('clear')" />
|
@play="$emit('play', $event)" @clear="$emit('clear')" @swap="$emit('swap-tracks', $event)"
|
||||||
|
@add="$emit('add-to-tracklist', $event)" @remove="$emit('remove-from-tracklist', $event)"
|
||||||
|
@move="$emit('tracklist-move', $event)" @save="$emit('tracklist-save', $event)"
|
||||||
|
@track-info="$emit('track-info', $event)" @add-to-playlist="openAddToPlaylist" />
|
||||||
|
|
||||||
|
<Playlists :playlists="playlists" :loading="loading" v-else-if="selectedView === 'playlists'"
|
||||||
|
:edited-playlist="editedPlaylist" :tracks="editedPlaylistTracks"
|
||||||
|
@play="$emit('play-playlist', $event)" @load="$emit('load-playlist', $event)"
|
||||||
|
@remove="$emit('remove-playlist', $event)" @playlist-edit="$emit('playlist-edit', $event)"
|
||||||
|
@load-track="$emit('add-to-tracklist-from-edited-playlist', $event)"
|
||||||
|
@remove-track="$emit('remove-from-playlist', $event)" @track-info="$emit('track-info', $event)"
|
||||||
|
@playlist-add="$emit('playlist-add', $event)" @add-to-playlist="openAddToPlaylist"
|
||||||
|
@track-move="$emit('playlist-track-move', $event)"/>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</MediaView>
|
</MediaView>
|
||||||
|
|
||||||
|
<div class="track-info-container">
|
||||||
|
<Modal title="Track info" ref="trackInfo">
|
||||||
|
<div class="track-info-content" v-if="trackInfo">
|
||||||
|
<div class="row file" v-if="trackInfo.file">
|
||||||
|
<div class="col-3 attr">File</div>
|
||||||
|
<div class="col-9 value" v-text="trackInfo.file" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row artist" v-if="trackInfo.artist">
|
||||||
|
<div class="col-3 attr">Artist</div>
|
||||||
|
<div class="col-9 value">
|
||||||
|
<a :href="$route.fullPath" v-text="trackInfo.artist"
|
||||||
|
@click.stop="$emit('search', {artist: trackInfo.artist})" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row track-title" v-if="trackInfo.title">
|
||||||
|
<div class="col-3 attr">Title</div>
|
||||||
|
<div class="col-9 value" v-text="trackInfo.title" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row album" v-if="trackInfo.album">
|
||||||
|
<div class="col-3 attr">Album</div>
|
||||||
|
<div class="col-9 value">
|
||||||
|
<a :href="$route.fullPath" v-text="trackInfo.album"
|
||||||
|
@click.stop="$emit('search', {album: trackInfo.album})" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row date" v-if="trackInfo.date">
|
||||||
|
<div class="col-3 attr">Date</div>
|
||||||
|
<div class="col-9 value" v-text="trackInfo.date" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row duration" v-if="trackInfo.time">
|
||||||
|
<div class="col-3 attr">Duration</div>
|
||||||
|
<div class="col-9 value" v-text="convertTime(trackInfo.time)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="playlists-modal-container">
|
||||||
|
<Modal title="Playlists" ref="playlistsModal" @close="addToPlaylistTrack = null"
|
||||||
|
@open="selectedPlaylists = [...Array(playlists.length).keys()].map(() => false)">
|
||||||
|
<div class="filter">
|
||||||
|
<label>
|
||||||
|
<input type="search" placeholder="Filter" v-model="playlistFilter">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="playlists">
|
||||||
|
<label class="row playlist"
|
||||||
|
:class="{hidden: playlistFilter?.length > 0 && playlist.name.toLowerCase().indexOf(playlistFilter.toLowerCase()) < 0}"
|
||||||
|
v-for="(playlist, i) in playlists" :key="i">
|
||||||
|
<input type="checkbox" :checked="selectedPlaylists[i]"
|
||||||
|
@change="selectedPlaylists[i] = $event.target.checked" />
|
||||||
|
<span class="name" v-text="playlist.name" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormFooter>
|
||||||
|
<button @click="addToPlaylist">
|
||||||
|
<i class="fa fa-plus" /> Add
|
||||||
|
</button>
|
||||||
|
</FormFooter>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import FormFooter from "@/components/elements/FormFooter";
|
||||||
|
import Loading from "@/components/Loading";
|
||||||
|
import Modal from "@/components/Modal";
|
||||||
|
import MediaUtils from "@/components/Media/Utils";
|
||||||
import MediaView from "@/components/Media/View";
|
import MediaView from "@/components/Media/View";
|
||||||
import Nav from "@/components/panels/Music/Nav";
|
import Nav from "@/components/panels/Music/Nav";
|
||||||
import Playlist from "@/components/panels/Music/Playlist";
|
import Playlist from "@/components/panels/Music/Playlist";
|
||||||
|
import Playlists from "@/components/panels/Music/Playlists";
|
||||||
import Utils from "@/Utils";
|
import Utils from "@/Utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Music",
|
name: "Music",
|
||||||
emits: ['play', 'pause', 'stop', 'clear', 'previous', 'next', 'set-volume', 'seek', 'consume', 'repeat', 'random',
|
emits: ['play', 'pause', 'stop', 'clear', 'previous', 'next', 'set-volume', 'seek', 'consume', 'repeat', 'random',
|
||||||
'status-update', 'playlist-update', 'new-playing-track'],
|
'status-update', 'playlist-update', 'new-playing-track', 'add-to-tracklist', 'remove-from-tracklist',
|
||||||
mixins: [Utils],
|
'swap-tracks', 'play-playlist', 'load-playlist', 'remove-playlist', 'tracklist-move', 'tracklist-save',
|
||||||
components: {Nav, MediaView, Playlist},
|
'add-to-tracklist-from-edited-playlist', 'remove-from-playlist', 'track-info', 'playlist-add', 'add-to-playlist',
|
||||||
|
'playlist-track-move'],
|
||||||
|
|
||||||
|
mixins: [Utils, MediaUtils],
|
||||||
|
components: {Loading, Modal, Nav, MediaView, Playlist, Playlists, FormFooter},
|
||||||
props: {
|
props: {
|
||||||
pluginName: {
|
pluginName: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -51,15 +141,36 @@ export default {
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
editedPlaylistTracks: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
|
playlists: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
status: {
|
status: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
editedPlaylist: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
|
||||||
|
trackInfo: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedView: 'playing',
|
selectedView: 'playing',
|
||||||
|
selectedPlaylists: [],
|
||||||
|
addToPlaylistTrack: null,
|
||||||
|
playlistFilter: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -92,13 +203,30 @@ export default {
|
||||||
return
|
return
|
||||||
|
|
||||||
this.notify({
|
this.notify({
|
||||||
title: event.track?.artist,
|
html: `<b>${event.track?.artist}</b><br>${event.track?.title}`,
|
||||||
text: event.track?.title,
|
image: {
|
||||||
iconClass: 'fa fa-play',
|
iconClass: 'fa fa-play',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
this.$emit('new-playing-track', event)
|
this.$emit('new-playing-track', event)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async openAddToPlaylist(track) {
|
||||||
|
this.addToPlaylistTrack = track
|
||||||
|
this.$refs.playlistsModal.isVisible = true
|
||||||
|
},
|
||||||
|
|
||||||
|
async addToPlaylist() {
|
||||||
|
this.$emit('add-to-playlist', {
|
||||||
|
track: this.addToPlaylistTrack,
|
||||||
|
playlists: [...Array(this.selectedPlaylists.length).keys()].filter((i) => this.selectedPlaylists[i])
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$refs.playlistsModal.isVisible = false
|
||||||
|
this.addToPlaylistTrack = null
|
||||||
|
this.playlistFilter = ''
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -118,8 +246,13 @@ export default {
|
||||||
this.subscribe(this.onPlaylistEvent, 'on-playlist-update',
|
this.subscribe(this.onPlaylistEvent, 'on-playlist-update',
|
||||||
'platypush.message.event.music.PlaylistChangeEvent')
|
'platypush.message.event.music.PlaylistChangeEvent')
|
||||||
|
|
||||||
this.subscribe(this.onPlaylistEvent, 'on-new-playing-track',
|
this.subscribe(this.onNewPlayingTrack, 'on-new-playing-track',
|
||||||
'platypush.message.event.music.NewPlayingTrackEvent')
|
'platypush.message.event.music.NewPlayingTrackEvent')
|
||||||
|
|
||||||
|
this.$watch(() => this.trackInfo, (info) => {
|
||||||
|
if (info != null)
|
||||||
|
this.$refs.trackInfo.isVisible = true
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
unmounted() {
|
unmounted() {
|
||||||
|
@ -142,8 +275,76 @@ main {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep button {
|
::v-deep(button) {
|
||||||
background: rgba(0, 0, 0, 0);
|
background: none;
|
||||||
|
padding: .5em .75em;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 0;
|
||||||
|
color: $default-hover-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(a) {
|
||||||
|
color: $default-fg;
|
||||||
|
opacity: 0.65;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.75;
|
||||||
|
border-bottom: 1px dotted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlists-modal-container {
|
||||||
|
::v-deep(.body) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.filter) {
|
||||||
|
padding: .33em;
|
||||||
|
background-color: $default-bg-6;
|
||||||
|
border-bottom: $default-border-2;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.playlists) {
|
||||||
|
overflow: auto;
|
||||||
|
padding: 1.5em;
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-info-container {
|
||||||
|
::v-deep(.body) {
|
||||||
|
height: 15em;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
@include until($tablet) {
|
||||||
|
width: 25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include from($tablet) {
|
||||||
|
width: 35em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,68 +3,84 @@
|
||||||
|
|
||||||
<div class="playlist fade-in" v-else>
|
<div class="playlist fade-in" v-else>
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
<MusicHeader>
|
<MusicHeader ref="header">
|
||||||
<div class="col-8 filter">
|
<div class="col-8 filter">
|
||||||
<label>
|
<label>
|
||||||
<input type="search" placeholder="Filter">
|
<input type="search" placeholder="Filter" v-model="filter">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-4 buttons">
|
<div class="col-4 buttons">
|
||||||
<button title="Add item" @click="$refs.addToPlaylistModal.visible = true">
|
<button title="Add track" @click="addTrack">
|
||||||
<i class="fa fa-plus"></i>
|
<i class="fa fa-plus"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Dropdown title="Actions" icon-class="fa fa-ellipsis-h">
|
<Dropdown title="Actions" icon-class="fa fa-ellipsis-h">
|
||||||
<DropdownItem text="Save as playlist" icon-class="fa fa-save" :disabled="!tracks?.length"
|
<DropdownItem text="Save as playlist" icon-class="fa fa-save" :disabled="!tracks?.length"
|
||||||
@click="$refs.savePlaylistModal.visible = true" />
|
@click="playlistSave" />
|
||||||
<DropdownItem text="Swap tracks" icon-class="fa fa-retweet" :disabled="tracks?.length !== 2 || !selectionMode" />
|
<DropdownItem text="Swap tracks" icon-class="fa fa-retweet" v-if="selectedTracks?.length === 2"
|
||||||
|
@click="$emit('swap', selectedTracks)" />
|
||||||
<DropdownItem :text="selectionMode ? 'End selection' : 'Start selection'" icon-class="far fa-check-square"
|
<DropdownItem :text="selectionMode ? 'End selection' : 'Start selection'" icon-class="far fa-check-square"
|
||||||
:disabled="!tracks?.length" @click="selectionMode = !selectionMode" />
|
:disabled="!tracks?.length" @click="selectionMode = !selectionMode" />
|
||||||
<DropdownItem :text="selectedTracks?.length === tracks?.length ? 'Unselect all' : 'Select all'"
|
<DropdownItem :text="selectedTracks?.length === tracks?.length ? 'Unselect all' : 'Select all'"
|
||||||
icon-class="fa fa-check-double" :disabled="!tracks?.length"
|
icon-class="fa fa-check-double" :disabled="!tracks?.length"
|
||||||
@click="selectedTracks = [...Array(tracks.length).keys()]" />
|
@click="selectedTracks = selectedTracks.length === tracks.length ? [] : [...Array(tracks.length).keys()]" />
|
||||||
|
<DropdownItem :text="'Remove track' + (selectedTracks.length > 1 ? 's' : '')"
|
||||||
|
icon-class="fa fa-trash" v-if="selectedTracks.length > 0"
|
||||||
|
@click="$emit('remove', [...(new Set(selectedTracks))])" />
|
||||||
<DropdownItem text="Clear playlist" icon-class="fa fa-ban" :disabled="!tracks?.length" @click="$emit('clear')" />
|
<DropdownItem text="Clear playlist" icon-class="fa fa-ban" :disabled="!tracks?.length" @click="$emit('clear')" />
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
</MusicHeader>
|
</MusicHeader>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="body">
|
<div class="body" ref="body">
|
||||||
<div class="no-content" v-if="!tracks?.length">
|
<div class="no-content" v-if="!tracks?.length">
|
||||||
No tracks are loaded
|
No tracks are loaded
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row track" v-for="(track, i) in tracks" :key="i" @dblclick="$emit('play', {pos: i})">
|
<div class="row track" @dragstart="onTrackDragStart(i)" @dragend="onTrackDragEnd(i)"
|
||||||
|
@dragover="onTrackDragOver(i)" draggable="true"
|
||||||
|
:class="{selected: selectedTracksSet.has(i), active: status?.playingPos === i, hidden: !displayedTracks.has(i)}"
|
||||||
|
v-for="(track, i) in tracks" :key="i" @click="onTrackClick($event, i)" @dblclick="$emit('play', {pos: i})">
|
||||||
<div class="col-10">
|
<div class="col-10">
|
||||||
<div class="title" v-text="track.title || '[No Title]'" />
|
<div class="title">
|
||||||
<div class="artist" v-text="track.artist || '[No Artist]'" />
|
{{ track.title || '[No Title]' }}
|
||||||
<div class="album" v-text="track.album" v-if="track.album" />
|
<div class="playing-icon" :class="{paused: status?.state === 'pause'}"
|
||||||
|
v-if="status?.playingPos === i && (status?.state === 'play' || status?.state === 'pause')">
|
||||||
|
<span v-for="i in [...Array(3).keys()]" :key="i" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="artist" v-if="track.artist">
|
||||||
|
<a :href="$route.fullPath" v-text="track.artist"
|
||||||
|
@click.stop="$emit('search', {artist: track.artist})" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="album" v-if="track.album">
|
||||||
|
<a :href="$route.fullPath" v-text="track.album"
|
||||||
|
@click.stop="$emit('search', {artist: track.album})" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-2 right-side">
|
<div class="col-2 right-side">
|
||||||
<span class="duration" v-text="convertTime(track.time)" />
|
<span class="duration" v-text="track.time ? convertTime(track.time) : '-:--'" />
|
||||||
|
|
||||||
<span class="actions">
|
<span class="actions">
|
||||||
<Dropdown title="Actions" icon-class="fa fa-ellipsis-h">
|
<Dropdown title="Actions" icon-class="fa fa-ellipsis-h">
|
||||||
<DropdownItem text="Play" icon-class="fa fa-play" @click="$emit('play', {pos: i})" />
|
<DropdownItem text="Play" icon-class="fa fa-play" @click="$emit('play', {pos: i})" />
|
||||||
<DropdownItem text="Add to playlist" icon-class="fa fa-list-ul" />
|
<DropdownItem text="Add to playlist" icon-class="fa fa-list-ul" @click="$emit('add-to-playlist', track)" />
|
||||||
|
<DropdownItem text="Remove" icon-class="fa fa-trash" @click="$emit('remove', [...(new Set([...selectedTracks, i]))])" />
|
||||||
|
<DropdownItem text="Track info" icon-class="fa fa-info" @click="$emit('track-info', tracks[i])" />
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal :visible="false" ref="addToPlaylistModal">
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<Modal :visible="false" ref="savePlaylistModal">
|
|
||||||
</Modal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Modal from "@/components/Modal";
|
|
||||||
import MusicHeader from "@/components/panels/Music/Header";
|
import MusicHeader from "@/components/panels/Music/Header";
|
||||||
import MediaUtils from "@/components/Media/Utils";
|
import MediaUtils from "@/components/Media/Utils";
|
||||||
import Dropdown from "@/components/elements/Dropdown";
|
import Dropdown from "@/components/elements/Dropdown";
|
||||||
|
@ -73,8 +89,8 @@ import DropdownItem from "@/components/elements/DropdownItem";
|
||||||
export default {
|
export default {
|
||||||
name: "Playlist",
|
name: "Playlist",
|
||||||
mixins: [MediaUtils],
|
mixins: [MediaUtils],
|
||||||
components: {DropdownItem, Dropdown, Modal, MusicHeader},
|
components: {DropdownItem, Dropdown, MusicHeader},
|
||||||
emits: ['play', 'clear', 'add-to-playlist'],
|
emits: ['play', 'clear', 'add', 'remove', 'swap', 'search', 'move', 'save', 'track-info'],
|
||||||
props: {
|
props: {
|
||||||
tracks: {
|
tracks: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -96,13 +112,126 @@ export default {
|
||||||
return {
|
return {
|
||||||
selectionMode: false,
|
selectionMode: false,
|
||||||
selectedTracks: [],
|
selectedTracks: [],
|
||||||
|
filter: '',
|
||||||
|
infoTrack: null,
|
||||||
|
sourcePos: null,
|
||||||
|
targetPos: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
selectedTracksSet() {
|
||||||
|
return new Set(this.selectedTracks)
|
||||||
|
},
|
||||||
|
|
||||||
|
displayedTracks() {
|
||||||
|
const positions = [...Array(this.tracks.length).keys()]
|
||||||
|
if (!this.filter?.length)
|
||||||
|
return new Set(positions)
|
||||||
|
|
||||||
|
const self = this
|
||||||
|
const filter = (self.filter || '').toLowerCase()
|
||||||
|
|
||||||
|
return new Set(
|
||||||
|
positions.filter((pos) => {
|
||||||
|
const track = this.tracks[pos]
|
||||||
|
return (track?.artist || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
|| (track?.title || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
|| (track?.album || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onTrackClick(event, pos) {
|
||||||
|
if (event.shiftKey) {
|
||||||
|
const selectedTracks = this.selectedTracks.sort()
|
||||||
|
if (!selectedTracks.length) {
|
||||||
|
this.selectedTracks = [pos]
|
||||||
|
} else if (pos < selectedTracks[0]) {
|
||||||
|
this.selectedTracks = [
|
||||||
|
...this.selectedTracks,
|
||||||
|
...[...Array(selectedTracks[0] - pos).keys()].map((i) => i + pos)
|
||||||
|
]
|
||||||
|
} else if (pos > selectedTracks[selectedTracks.length - 1]) {
|
||||||
|
this.selectedTracks = [
|
||||||
|
...this.selectedTracks,
|
||||||
|
...[...Array(pos - selectedTracks[selectedTracks.length - 1] + 1).keys()].
|
||||||
|
map((i) => i + selectedTracks[selectedTracks.length - 1])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const idx = this.selectedTracks.indexOf(pos)
|
||||||
|
if (this.selectionMode || event.ctrlKey) {
|
||||||
|
if (idx >= 0)
|
||||||
|
this.selectedTracks.splice(idx, 1)
|
||||||
|
else
|
||||||
|
this.selectedTracks.push(pos)
|
||||||
|
} else {
|
||||||
|
if (idx >= 0)
|
||||||
|
this.selectedTracks = []
|
||||||
|
else
|
||||||
|
this.selectedTracks = [pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addTrack() {
|
||||||
|
const track = prompt('Item path or URL')
|
||||||
|
if (!track?.length)
|
||||||
|
return
|
||||||
|
|
||||||
|
this.$emit('add', track)
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrackDragStart(track) {
|
||||||
|
this.sourcePos = track
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrackDragEnd() {
|
||||||
|
this.$refs.body.querySelectorAll('.track').forEach((track) => track.classList.remove('dragover'));
|
||||||
|
if (this.sourcePos == null || this.targetPos == null || this.sourcePos === this.targetPos)
|
||||||
|
return
|
||||||
|
|
||||||
|
this.$emit('move', {from: this.sourcePos, to: this.targetPos})
|
||||||
|
this.sourcePos = null
|
||||||
|
this.targetPos = null
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrackDragOver(track) {
|
||||||
|
this.targetPos = track
|
||||||
|
const tracks = this.$refs.body.querySelectorAll('.track')
|
||||||
|
tracks.forEach((track) => track.classList.remove('dragover'));
|
||||||
|
[...tracks][track].classList.add('dragover')
|
||||||
|
},
|
||||||
|
|
||||||
|
playlistSave() {
|
||||||
|
const name = prompt('Playlist name')
|
||||||
|
if (!name?.length)
|
||||||
|
return
|
||||||
|
|
||||||
|
this.$emit('save', name)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
const self = this
|
||||||
|
this.$watch(() => self.status?.playingPos, (pos) => {
|
||||||
|
if (pos == null)
|
||||||
|
return
|
||||||
|
|
||||||
|
const trackElement = [...self.$refs.body.querySelectorAll('.track')][pos]
|
||||||
|
const offset = trackElement.offsetTop - parseFloat(getComputedStyle(self.$refs.header.$el).height)
|
||||||
|
self.$refs.body.scrollTo(0, offset)
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import 'vars.scss';
|
@import 'vars.scss';
|
||||||
|
@import 'track.scss';
|
||||||
|
|
||||||
.playlist {
|
.playlist {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -135,72 +264,86 @@ export default {
|
||||||
.no-content {
|
.no-content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.track {
|
.playing-icon {
|
||||||
display: flex;
|
display: inline-block;
|
||||||
justify-content: center;
|
position: relative;
|
||||||
padding: .75em .25em .25em .25em;
|
margin-left: .75em;
|
||||||
box-shadow: 0 2.5px 2px -1px $default-shadow-color;
|
width: 1.5em;
|
||||||
cursor: pointer;
|
height: 1em;
|
||||||
|
|
||||||
&:hover {
|
@keyframes playing_bar {
|
||||||
background: $hover-bg;
|
0% {
|
||||||
|
height: 0
|
||||||
}
|
}
|
||||||
|
12.5% {
|
||||||
.title {
|
height: 75%
|
||||||
font-size: 1em;
|
|
||||||
font-weight: normal;
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
25% {
|
||||||
.artist, .album {
|
height: 100%
|
||||||
display: inline-flex;
|
|
||||||
opacity: 0.7;
|
|
||||||
font-size: .9em;
|
|
||||||
}
|
}
|
||||||
|
37.5% {
|
||||||
.artist {
|
height: 10%
|
||||||
margin-right: .25em;
|
|
||||||
}
|
}
|
||||||
|
50% {
|
||||||
.album {
|
height: 40%
|
||||||
@include until($tablet) {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
62.5% {
|
||||||
&::before {
|
height: 50%
|
||||||
content: "\2022";
|
}
|
||||||
margin-right: .25em;
|
75% {
|
||||||
|
height: 30%
|
||||||
|
}
|
||||||
|
87.5% {
|
||||||
|
height: 55%
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
height: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-side {
|
span {
|
||||||
display: flex;
|
@include animation(0.2s);
|
||||||
justify-content: right;
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: .25em;
|
||||||
|
height: 100%;
|
||||||
|
background: $default-hover-fg-2;
|
||||||
|
animation-name: playing_bar;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
|
||||||
|
&:nth-child(1){
|
||||||
|
left: 0;
|
||||||
|
animation-duration: 2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.duration,
|
&:nth-child(2){
|
||||||
.actions {
|
left: 6px;
|
||||||
display: inline-flex;
|
animation-duration: 4s;
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.duration {
|
&:nth-child(3){
|
||||||
font-size: .85em;
|
left: 12px;
|
||||||
opacity: .7;
|
animation-duration: 1s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
&.paused {
|
||||||
::v-deep button {
|
span {
|
||||||
opacity: .7;
|
animation-play-state: paused;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep button {
|
::v-deep(.track-info-content) {
|
||||||
background: none;
|
.attr {
|
||||||
padding: .5em .75em;
|
opacity: 0.75;
|
||||||
border: 0;
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,336 @@
|
||||||
|
<template>
|
||||||
|
<Loading v-if="loading" />
|
||||||
|
|
||||||
|
<div class="editor-container fade-in" v-else-if="editedPlaylist">
|
||||||
|
<div class="header-container">
|
||||||
|
<MusicHeader ref="header">
|
||||||
|
<button class="back-btn" title="Back" @click="$emit('playlist-edit', null)">
|
||||||
|
<i class="fas fa-arrow-left" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<label class="search-box">
|
||||||
|
<input type="search" placeholder="Filter" v-model="trackFilter">
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<button class="add-btn" title="Add track" @click="addTrack">
|
||||||
|
<i class="fas fa-plus" />
|
||||||
|
</button>
|
||||||
|
</MusicHeader>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="editor" ref="editor">
|
||||||
|
<div class="no-content" v-if="!tracks?.length">
|
||||||
|
No tracks found
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row track" draggable="true" v-for="(track, i) in tracks" :key="i"
|
||||||
|
:class="{selected: selectedTracksSet.has(i), active: status?.playingPos === i, hidden: !displayedTracks.has(i)}"
|
||||||
|
@dragstart="onTrackDragStart(i)" @dragend="onTrackDragEnd(i)" @dragover="onTrackDragOver(i)"
|
||||||
|
@click="onTrackClick($event, i)" @dblclick="$emit('load-track', {pos: i, play: true})">
|
||||||
|
<div class="col-10">
|
||||||
|
<div class="title">
|
||||||
|
{{ track.title || '[No Title]' }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="artist" v-if="track.artist">
|
||||||
|
<a :href="$route.fullPath" v-text="track.artist" @click.stop="$emit('search', {artist: track.artist})" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="album" v-if="track.album">
|
||||||
|
<a :href="$route.fullPath" v-text="track.album" @click.stop="$emit('search', {artist: track.album})" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-2 right-side">
|
||||||
|
<span class="duration" v-text="track.time ? convertTime(track.time) : '-:--'" />
|
||||||
|
|
||||||
|
<span class="actions">
|
||||||
|
<Dropdown title="Actions" icon-class="fa fa-ellipsis-h">
|
||||||
|
<DropdownItem text="Play" icon-class="fa fa-play" @click="$emit('load-track', {pos: i, play: true})" />
|
||||||
|
<DropdownItem text="Add to tracklist" icon-class="fa fa-plus" @click="$emit('load-track', {pos: i, play: false})" />
|
||||||
|
<DropdownItem text="Add to playlist" icon-class="fa fa-list-ul" @click="$emit('add-to-playlist', track)" />
|
||||||
|
<DropdownItem text="Remove" icon-class="fa fa-trash" @click="$emit('remove-track', [...(new Set([...selectedTracks, i]))])" />
|
||||||
|
<DropdownItem text="Show info" icon-class="fa fa-info" @click.stop="$emit('track-info', tracks[i])" />
|
||||||
|
</Dropdown>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="playlists fade-in" v-else>
|
||||||
|
<div class="header-container">
|
||||||
|
<MusicHeader ref="header">
|
||||||
|
<div class="col-8 filter">
|
||||||
|
<label>
|
||||||
|
<input type="search" placeholder="Filter" v-model="filter">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</MusicHeader>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="body" ref="body">
|
||||||
|
<div class="no-content" v-if="!playlists?.length">
|
||||||
|
No playlists found
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row playlist" :class="{hidden: !displayedPlaylists.has(i)}"
|
||||||
|
v-for="(playlist, i) in playlists" :key="i" @click="$emit('playlist-edit', i)"
|
||||||
|
@dblclick="$emit('load', i)">
|
||||||
|
<div class="col-10">
|
||||||
|
<div class="name" v-text="playlist.name || '[No Name]'" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-2 right-side">
|
||||||
|
<span class="actions">
|
||||||
|
<Dropdown title="Actions" icon-class="fa fa-ellipsis-h">
|
||||||
|
<DropdownItem text="Play" icon-class="fa fa-play" @click.stop="$emit('play', i)" />
|
||||||
|
<DropdownItem text="Load" icon-class="fa fa-list-ul" @click.stop="$emit('load', i)" />
|
||||||
|
<DropdownItem text="Edit" icon-class="fa fa-edit" @click.stop="$emit('playlist-edit', i)" />
|
||||||
|
<DropdownItem text="Remove" icon-class="fa fa-trash" @click.stop="$emit('remove', i)" />
|
||||||
|
</Dropdown>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MusicHeader from "@/components/panels/Music/Header";
|
||||||
|
import MediaUtils from "@/components/Media/Utils";
|
||||||
|
import Dropdown from "@/components/elements/Dropdown";
|
||||||
|
import DropdownItem from "@/components/elements/DropdownItem";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Playlists",
|
||||||
|
mixins: [MediaUtils],
|
||||||
|
components: {DropdownItem, Dropdown, MusicHeader},
|
||||||
|
emits: ['play', 'load', 'remove', 'playlist-edit', 'search', 'remove-track', 'load-track', 'track-info',
|
||||||
|
'playlist-add', 'add-to-playlist', 'track-move'],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
playlists: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
tracks: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
|
editedPlaylist: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedTracks: [],
|
||||||
|
filter: '',
|
||||||
|
trackFilter: '',
|
||||||
|
sourcePos: null,
|
||||||
|
targetPos: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
selectedTracksSet() {
|
||||||
|
return new Set(this.selectedTracks)
|
||||||
|
},
|
||||||
|
|
||||||
|
displayedPlaylists() {
|
||||||
|
const positions = [...Array(this.playlists.length).keys()]
|
||||||
|
if (!this.filter?.length)
|
||||||
|
return new Set(positions)
|
||||||
|
|
||||||
|
const self = this
|
||||||
|
const filter = (self.filter || '').toLowerCase()
|
||||||
|
|
||||||
|
return new Set(
|
||||||
|
positions.filter((pos) => {
|
||||||
|
const track = this.playlists[pos]
|
||||||
|
return (track?.name || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
displayedTracks() {
|
||||||
|
const positions = [...Array(this.tracks.length).keys()]
|
||||||
|
if (!this.trackFilter?.length)
|
||||||
|
return new Set(positions)
|
||||||
|
|
||||||
|
const self = this
|
||||||
|
const filter = (self.trackFilter || '').toLowerCase()
|
||||||
|
|
||||||
|
return new Set(
|
||||||
|
positions.filter((pos) => {
|
||||||
|
const track = this.tracks[pos]
|
||||||
|
return (track?.artist || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
|| (track?.title || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
|| (track?.album || '').toLowerCase().indexOf(filter) >= 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onTrackClick(event, pos) {
|
||||||
|
if (event.shiftKey) {
|
||||||
|
const selectedTracks = this.selectedTracks.sort()
|
||||||
|
if (!selectedTracks.length) {
|
||||||
|
this.selectedTracks = [pos]
|
||||||
|
} else if (pos < selectedTracks[0]) {
|
||||||
|
this.selectedTracks = [
|
||||||
|
...this.selectedTracks,
|
||||||
|
...[...Array(selectedTracks[0] - pos).keys()].map((i) => i + pos)
|
||||||
|
]
|
||||||
|
} else if (pos > selectedTracks[selectedTracks.length - 1]) {
|
||||||
|
this.selectedTracks = [
|
||||||
|
...this.selectedTracks,
|
||||||
|
...[...Array(pos - selectedTracks[selectedTracks.length - 1] + 1).keys()].
|
||||||
|
map((i) => i + selectedTracks[selectedTracks.length - 1])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const idx = this.selectedTracks.indexOf(pos)
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
if (idx >= 0)
|
||||||
|
this.selectedTracks.splice(idx, 1)
|
||||||
|
else
|
||||||
|
this.selectedTracks.push(pos)
|
||||||
|
} else {
|
||||||
|
if (idx >= 0)
|
||||||
|
this.selectedTracks = []
|
||||||
|
else
|
||||||
|
this.selectedTracks = [pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addTrack() {
|
||||||
|
const track = prompt('Track path or URL')
|
||||||
|
if (!track?.length)
|
||||||
|
return
|
||||||
|
|
||||||
|
this.$emit('playlist-add', track)
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrackDragStart(track) {
|
||||||
|
this.sourcePos = track
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrackDragEnd() {
|
||||||
|
this.$refs.editor.querySelectorAll('.track').forEach((track) => track.classList.remove('dragover'));
|
||||||
|
if (this.sourcePos == null || this.targetPos == null || this.sourcePos === this.targetPos)
|
||||||
|
return
|
||||||
|
|
||||||
|
this.$emit('track-move', {from: this.sourcePos, to: this.targetPos, playlist: this.editedPlaylist})
|
||||||
|
this.sourcePos = null
|
||||||
|
this.targetPos = null
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrackDragOver(track) {
|
||||||
|
this.targetPos = track
|
||||||
|
const tracks = this.$refs.editor.querySelectorAll('.track')
|
||||||
|
tracks.forEach((track) => track.classList.remove('dragover'));
|
||||||
|
[...tracks][track].classList.add('dragover')
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import 'vars.scss';
|
||||||
|
@import 'track.scss';
|
||||||
|
|
||||||
|
.playlists {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
.filter {
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
height: calc(100% - #{$music-header-height});
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-content {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlist {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: .75em .25em .25em .25em;
|
||||||
|
box-shadow: 0 2.5px 2px -1px $default-shadow-color;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: $active-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background: $selected-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-side {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.header) {
|
||||||
|
.back-btn {
|
||||||
|
padding-left: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-btn {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
input {
|
||||||
|
width: 65%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - #{$music-header-height});
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,78 @@
|
||||||
|
.track {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: .75em .25em .25em .25em;
|
||||||
|
box-shadow: 0 2.5px 2px -1px $default-shadow-color;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: $active-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background: $selected-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.dragover {
|
||||||
|
border-top: 2px solid $default-hover-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title, .artist, .album, .duration {
|
||||||
|
&::selection {
|
||||||
|
background: rgba(0, 0, 0, 0) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist, .album {
|
||||||
|
display: inline-flex;
|
||||||
|
opacity: 0.7;
|
||||||
|
font-size: .9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artist {
|
||||||
|
margin-right: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album {
|
||||||
|
@include until($tablet) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "\2022";
|
||||||
|
margin-right: .25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-side {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration,
|
||||||
|
.actions {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.duration {
|
||||||
|
font-size: .85em;
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
::v-deep(button) {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<Loading v-if="loading" />
|
<Loading v-if="loading" />
|
||||||
<MusicPlugin plugin-name="music.mpd" :loading="loading" :config="config" :tracks="tracks" :status="status"
|
<MusicPlugin plugin-name="music.mpd" :loading="loading" :config="config" :tracks="tracks" :status="status"
|
||||||
@play="play" @pause="pause" @stop="stop" @previous="previous" @next="next" @clear="clear"
|
:playlists="playlists" :edited-playlist="editedPlaylist" :edited-playlist-tracks="editedPlaylistTracks"
|
||||||
@set-volume="setVolume" @seek="seek" @consume="consume" @random="random" @repeat="repeat"
|
:track-info="trackInfo" @play="play" @pause="pause" @stop="stop" @previous="previous" @next="next"
|
||||||
@status-update="refreshStatus(true)" @playlist-update="refreshTracks(true)"
|
@clear="clear" @set-volume="setVolume" @seek="seek" @consume="consume" @random="random" @repeat="repeat"
|
||||||
@new-playing-track="refreshStatus(true)" />
|
@status-update="refreshStatus(true)" @playlist-update="refresh(true)"
|
||||||
|
@new-playing-track="refreshStatus(true)" @remove-from-tracklist="removeFromTracklist"
|
||||||
|
@add-to-tracklist="addToTracklist" @swap-tracks="swapTracks" @load-playlist="loadPlaylist"
|
||||||
|
@play-playlist="playPlaylist" @remove-playlist="removePlaylist" @tracklist-move="moveTracklistTracks"
|
||||||
|
@tracklist-save="saveToPlaylist" @playlist-edit="playlistEditChanged"
|
||||||
|
@add-to-tracklist-from-edited-playlist="addToTracklistFromEditedPlaylist"
|
||||||
|
@remove-from-playlist="removeFromPlaylist" @track-info="trackInfo = $event" @playlist-add="playlistAdd"
|
||||||
|
@add-to-playlist="addToPlaylist" @playlist-track-move="playlistTrackMove" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -27,7 +34,11 @@ export default {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
tracks: [],
|
tracks: [],
|
||||||
|
playlists: [],
|
||||||
status: {},
|
status: {},
|
||||||
|
editedPlaylist: null,
|
||||||
|
editedPlaylistTracks: [],
|
||||||
|
trackInfo: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -85,12 +96,32 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async refreshPlaylists(background) {
|
||||||
|
if (!background)
|
||||||
|
this.loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.playlists = (await this.request('music.mpd.listplaylists')).map((playlist) => {
|
||||||
|
return {
|
||||||
|
name: playlist.playlist,
|
||||||
|
lastModified: playlist['last-modified'],
|
||||||
|
}
|
||||||
|
}).sort((a, b) => a.name.localeCompare(b.name))
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async refresh(background) {
|
async refresh(background) {
|
||||||
if (!background)
|
if (!background)
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.all([this.refreshTracks(background), this.refreshStatus(background)])
|
await Promise.all([
|
||||||
|
this.refreshTracks(background),
|
||||||
|
this.refreshStatus(background),
|
||||||
|
this.refreshPlaylists(background),
|
||||||
|
])
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
|
@ -145,19 +176,125 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
async repeat(value) {
|
async repeat(value) {
|
||||||
await this.request('music.mpd.repeat', {value: value})
|
await this.request('music.mpd.repeat', {value: parseInt(+value)})
|
||||||
await this.refreshStatus(true)
|
await this.refreshStatus(true)
|
||||||
},
|
},
|
||||||
|
|
||||||
async random(value) {
|
async random(value) {
|
||||||
await this.request('music.mpd.random', {value: value})
|
await this.request('music.mpd.random', {value: parseInt(+value)})
|
||||||
await this.refreshStatus(true)
|
await this.refreshStatus(true)
|
||||||
},
|
},
|
||||||
|
|
||||||
async consume(value) {
|
async consume(value) {
|
||||||
await this.request('music.mpd.consume', {value: value})
|
await this.request('music.mpd.consume', {value: parseInt(+value)})
|
||||||
await this.refreshStatus(true)
|
await this.refreshStatus(true)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async addToTracklist(resource) {
|
||||||
|
await this.request('music.mpd.add', {resource: resource})
|
||||||
|
await this.refresh(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async addToTracklistFromEditedPlaylist(event) {
|
||||||
|
const track = this.editedPlaylistTracks[event.pos]
|
||||||
|
if (!track)
|
||||||
|
return
|
||||||
|
|
||||||
|
await this.request('music.mpd.add', {resource: track.file})
|
||||||
|
await this.refresh(true)
|
||||||
|
|
||||||
|
if (event.play)
|
||||||
|
await this.request('music.mpd.play_pos', {pos: this.tracks.length-1})
|
||||||
|
},
|
||||||
|
|
||||||
|
async removeFromPlaylist(positions) {
|
||||||
|
await this.request('music.mpd.playlistdelete',
|
||||||
|
{pos: positions, name: this.playlists[this.editedPlaylist].name})
|
||||||
|
await this.playlistEditChanged(this.editedPlaylist)
|
||||||
|
},
|
||||||
|
|
||||||
|
async removeFromTracklist(positions) {
|
||||||
|
await this.request('music.mpd.delete', {positions: positions.sort()})
|
||||||
|
await this.refresh(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async swapTracks(positions) {
|
||||||
|
await this.request('music.mpd.move', {from_pos: positions[0], to_pos: positions[1]})
|
||||||
|
await this.refresh(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async playPlaylist(position) {
|
||||||
|
await this._loadPlaylist(position, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadPlaylist(position) {
|
||||||
|
await this._loadPlaylist(position, false)
|
||||||
|
},
|
||||||
|
|
||||||
|
async _loadPlaylist(position, play) {
|
||||||
|
const playlist = this.playlists[position]
|
||||||
|
await this.request('music.mpd.load', {playlist: playlist.name, play: play})
|
||||||
|
await this.refresh(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async removePlaylist(position) {
|
||||||
|
const playlist = this.playlists[position]
|
||||||
|
if (!confirm(`Are you REALLY sure that you want to remove the playlist ${playlist.name}?`))
|
||||||
|
return
|
||||||
|
|
||||||
|
await this.request('music.mpd.rm', {playlist: playlist.name})
|
||||||
|
await this.refreshPlaylists(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async saveToPlaylist(name) {
|
||||||
|
await this.request('music.mpd.save', {name: name})
|
||||||
|
await this.refreshPlaylists(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async moveTracklistTracks(event) {
|
||||||
|
await this.request('music.mpd.move', {from_pos: event.from, to_pos: event.to})
|
||||||
|
await this.refreshTracks(true)
|
||||||
|
},
|
||||||
|
|
||||||
|
async playlistAdd(track) {
|
||||||
|
await this.request('music.mpd.playlistadd', {uri: track, name: this.playlists[this.editedPlaylist].name})
|
||||||
|
await this.playlistEditChanged(this.editedPlaylist)
|
||||||
|
},
|
||||||
|
|
||||||
|
async playlistEditChanged(playlist) {
|
||||||
|
this.editedPlaylist = playlist
|
||||||
|
if (playlist == null)
|
||||||
|
return
|
||||||
|
|
||||||
|
this.loading = true
|
||||||
|
try {
|
||||||
|
this.editedPlaylistTracks = await this.request('music.mpd.listplaylistinfo',
|
||||||
|
{name: this.playlists[playlist].name})
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async addToPlaylist(event) {
|
||||||
|
await Promise.all(event.playlists.map(async (playlistIdx) => {
|
||||||
|
await this.request('music.mpd.playlistadd', {
|
||||||
|
uri: event.track.file,
|
||||||
|
name: this.playlists[playlistIdx].name
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.playlistEditChanged(playlistIdx)
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
|
||||||
|
async playlistTrackMove(event) {
|
||||||
|
await this.request('music.mpd.playlistmove', {
|
||||||
|
name: this.playlists[event.playlist].name,
|
||||||
|
from_pos: event.from,
|
||||||
|
to_pos: event.to,
|
||||||
|
})
|
||||||
|
|
||||||
|
await this.playlistEditChanged(event.playlist)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -6,6 +6,7 @@ $default-bg-4: #f1f3f2 !default;
|
||||||
$default-bg-5: #edf0ee !default;
|
$default-bg-5: #edf0ee !default;
|
||||||
$default-bg-6: #e4eae8 !default;
|
$default-bg-6: #e4eae8 !default;
|
||||||
$default-bg-7: #e4e4e4 !default;
|
$default-bg-7: #e4e4e4 !default;
|
||||||
|
$default-fg: black !default;
|
||||||
|
|
||||||
//// Notifications
|
//// Notifications
|
||||||
$notification-bg: rgba(185, 255, 193, 0.9) !default;
|
$notification-bg: rgba(185, 255, 193, 0.9) !default;
|
||||||
|
@ -68,6 +69,7 @@ $active-glow-bg-2: #9cdfb0 !default;
|
||||||
$default-hover-fg: #35b870 !default;
|
$default-hover-fg: #35b870 !default;
|
||||||
$default-hover-fg-2: #38cf80 !default;
|
$default-hover-fg-2: #38cf80 !default;
|
||||||
$hover-bg: #bef6da !default;
|
$hover-bg: #bef6da !default;
|
||||||
|
$active-bg: #8fefb7 !default;
|
||||||
|
|
||||||
/// Navigator
|
/// Navigator
|
||||||
$nav-bg: #002626 !default;
|
$nav-bg: #002626 !default;
|
||||||
|
|
|
@ -645,7 +645,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
if isinstance(pos, int):
|
if isinstance(pos, int):
|
||||||
pos = [pos]
|
pos = [pos]
|
||||||
|
|
||||||
for p in pos:
|
for p in sorted(pos, reverse=True):
|
||||||
self._exec('playlistdelete', name, p)
|
self._exec('playlistdelete', name, p)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|
Loading…
Reference in a new issue