forked from platypush/platypush
music.mpd refactor WIP
This commit is contained in:
parent
3eb7f01d38
commit
e127f2597c
|
@ -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
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-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
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
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":""}
|
|
@ -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
|
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 +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
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
|
@ -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 {
|
||||||
--width: auto;
|
|
||||||
--height: auto;
|
|
||||||
width: var(--width);
|
|
||||||
height: var(--height);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
--width: auto;
|
||||||
|
--height: auto;
|
||||||
|
width: var(--width);
|
||||||
|
height: var(--height);
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
background: $modal-body-bg;
|
background: $modal-body-bg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,7 @@ 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% {
|
||||||
|
height: 75%
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
37.5% {
|
||||||
|
height: 10%
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
height: 40%
|
||||||
|
}
|
||||||
|
62.5% {
|
||||||
|
height: 50%
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
height: 30%
|
||||||
|
}
|
||||||
|
87.5% {
|
||||||
|
height: 55%
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
@include animation(0.2s);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
&:nth-child(2){
|
||||||
font-size: 1em;
|
left: 6px;
|
||||||
font-weight: normal;
|
animation-duration: 4s;
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.artist, .album {
|
&:nth-child(3){
|
||||||
display: inline-flex;
|
left: 12px;
|
||||||
opacity: 0.7;
|
animation-duration: 1s;
|
||||||
font-size: .9em;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.artist {
|
&.paused {
|
||||||
margin-right: .25em;
|
span {
|
||||||
}
|
animation-play-state: paused;
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::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 New Issue