mirror of
https://github.com/SuperBFG7/ympd
synced 2024-12-23 09:30:26 +00:00
fix crash when seeking without song, new slider
This commit is contained in:
parent
13b921553f
commit
cd865b2cef
@ -7,18 +7,18 @@ body {
|
|||||||
padding: 40px 15px;
|
padding: 40px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider.slider-horizontal {
|
#volumeslider {
|
||||||
height: 15px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider.slider-horizontal .slider-track {
|
#volumeslider .progress {
|
||||||
height: 10px;
|
margin-bottom: 0;
|
||||||
margin-top: -6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress {
|
#volume-icon {
|
||||||
margin-top: 0px;
|
float: left;
|
||||||
margin-bottom: 0px;
|
margin-right: 10px;
|
||||||
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#counter {
|
#counter {
|
||||||
@ -29,5 +29,44 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn-group-hover {
|
.btn-group-hover {
|
||||||
opacity: 0;
|
opacity: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:active,
|
||||||
|
.btn.active {
|
||||||
|
background-image: none;
|
||||||
|
outline: 0;
|
||||||
|
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||||
|
color: #428bca;
|
||||||
|
background-color: #fdfdfd;
|
||||||
|
border-color: #adadad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#salamisandwich td:nth-child(3), th:nth-child(3) {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Positioning */
|
||||||
|
.notifications.top-right {
|
||||||
|
right: 10px;
|
||||||
|
top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notification Element */
|
||||||
|
.notifications > div {
|
||||||
|
position: relative;
|
||||||
|
z-index: 9999;
|
||||||
|
margin: 5px 0px;
|
||||||
}
|
}
|
@ -12,7 +12,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.slider.slider-horizontal {
|
.slider.slider-horizontal {
|
||||||
width: 210px;
|
width: 100%;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
.slider.slider-horizontal .slider-track {
|
.slider.slider-horizontal .slider-track {
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
<link href="css/bootstrap.css" rel="stylesheet">
|
<link href="css/bootstrap.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Custom styles for this template -->
|
<!-- Custom styles for this template -->
|
||||||
<link href="css/slider.css" rel="stylesheet">
|
|
||||||
<link href="css/mpd.css" rel="stylesheet">
|
<link href="css/mpd.css" rel="stylesheet">
|
||||||
<link href="assets/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
|
<link href="assets/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
|
||||||
|
|
||||||
@ -40,7 +39,7 @@
|
|||||||
<ul id="nav_links" class="nav navbar-nav">
|
<ul id="nav_links" class="nav navbar-nav">
|
||||||
<li id="playlist"><a href="#/">Playlist</a></li>
|
<li id="playlist"><a href="#/">Playlist</a></li>
|
||||||
<li id="browse"><a href="#/browse/">Browse database</a></li>
|
<li id="browse"><a href="#/browse/">Browse database</a></li>
|
||||||
<li><a href="#" data-toggle="modal" data-target="#about">About</a></li>
|
<li><a href="#" data-toggle="modal" data-target="#about" onclick="getVersion();">About</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="btn-toolbar navbar-btn navbar-right" role="toolbar">
|
<div class="btn-toolbar navbar-btn navbar-right" role="toolbar">
|
||||||
@ -48,6 +47,9 @@
|
|||||||
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_NEXT');">
|
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_NEXT');">
|
||||||
<span class="glyphicon glyphicon-backward"></span>
|
<span class="glyphicon glyphicon-backward"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_STOP');">
|
||||||
|
<span id="stop-icon" class="glyphicon glyphicon-stop"></span>
|
||||||
|
</button>
|
||||||
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_PAUSE');">
|
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_PAUSE');">
|
||||||
<span id="play-icon" class="glyphicon glyphicon-pause"></span>
|
<span id="play-icon" class="glyphicon glyphicon-pause"></span>
|
||||||
</button>
|
</button>
|
||||||
@ -58,8 +60,7 @@
|
|||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<div class="btn btn-toolbar btn-default">
|
<div class="btn btn-toolbar btn-default">
|
||||||
<span id="volume-icon" class="glyphicon glyphicon-volume-up"></span>
|
<span id="volume-icon" class="glyphicon glyphicon-volume-up"></span>
|
||||||
|
<div id="volumeslider"></div>
|
||||||
<input type="text" class="span2" value="0" data-slider-min="0" data-slider-max="100" data-slider-step="5" id="volumeslider" data-slider-tooltip="hide">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -71,7 +72,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-md-10 col-xs-12">
|
<div class="col-md-10 col-xs-12">
|
||||||
<div id="alert" class="alert hide"></div>
|
<div class="notifications top-right"></div>
|
||||||
|
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<!-- Default panel contents -->
|
<!-- Default panel contents -->
|
||||||
@ -87,10 +88,9 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<p id="counter" class="text pull-right"> </p>
|
<p id="counter" class="text pull-right"> </p>
|
||||||
|
|
||||||
<div class="progress progress-striped active">
|
<div id="progressbar"></div>
|
||||||
<div id="progressbar" class="progress-bar navbar-left" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div><!-- /.panel-body -->
|
</div><!-- /.panel-body -->
|
||||||
|
|
||||||
<ol id="breadcrump" class="breadcrumb">
|
<ol id="breadcrump" class="breadcrumb">
|
||||||
@ -112,7 +112,7 @@
|
|||||||
</div><!-- /.col-md-10 -->
|
</div><!-- /.col-md-10 -->
|
||||||
|
|
||||||
<div class="col-md-2 col-xs-12" >
|
<div class="col-md-2 col-xs-12" >
|
||||||
<div data-spy="affix" data-offset-bottom="10">
|
<div class="btn-toolbar">
|
||||||
<div class="btn-group-vertical btn-block btn-group-lg" data-toggle="buttons">
|
<div class="btn-group-vertical btn-block btn-group-lg" data-toggle="buttons">
|
||||||
<button id="btnrandom" type="button" class="btn btn-default">
|
<button id="btnrandom" type="button" class="btn btn-default">
|
||||||
<span class="glyphicon glyphicon-random"></span> Random
|
<span class="glyphicon glyphicon-random"></span> Random
|
||||||
@ -128,13 +128,15 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" class="btn btn-block btn-default btn-lg dropdown-toggle" data-toggle="dropdown">
|
<div class="btn-group-vertical btn-block btn-group-lg">
|
||||||
<span class="glyphicon glyphicon-wrench"></span> Options <span class="caret"></span>
|
<button type="button" class="btn btn-default" onclick="updateDB();">
|
||||||
</button>
|
<span class="glyphicon glyphicon-refresh"></span> Update DB
|
||||||
<ul class="dropdown-menu">
|
</button>
|
||||||
<li><a href="#/" onclick="updateDB();"><span class="glyphicon glyphicon-refresh"></span> Update Database</a></li>
|
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_RM_ALL');">
|
||||||
<li><a href="#/" onclick="socket.send('MPD_API_RM_ALL');"><span class="glyphicon glyphicon-trash"></span> Clear queue</a></li>
|
<span class="glyphicon glyphicon-trash"></span> Clear queue
|
||||||
</ul>
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /.col-md-2 -->
|
</div><!-- /.col-md-2 -->
|
||||||
</div><!-- /.row -->
|
</div><!-- /.row -->
|
||||||
@ -150,9 +152,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<h4><span class="glyphicon glyphicon-play-circle"></span> ympd <small>MPD Web GUI - written in C, utilizing Websockets and Bootstrap/JS</small></h4>
|
<h4><span class="glyphicon glyphicon-play-circle"></span> ympd <small>MPD Web GUI - written in C, utilizing Websockets and Bootstrap/JS</small></h4>
|
||||||
<br/>
|
<p>
|
||||||
<span class="glyphicon glyphicon-play-circle"></span> ympd is a lightweight MPD (Music Player Daemon) web client that runs without a dedicated werbserver or interpreters like PHP, NodeJS or Ruby. It's tuned for minimal resource usage and requires only very litte dependencies.
|
ympd is a lightweight MPD (Music Player Daemon) web client that runs without a dedicated werbserver or interpreters like PHP, NodeJS or Ruby. It's tuned for minimal resource usage and requires only very litte dependencies.</p>
|
||||||
<h5><span class="glyphicon glyphicon-play-circle"></span> ympd uses following excellent software:</h5>
|
<p class="text-muted">
|
||||||
|
ympd <span id="ympd_version"></span><br/>
|
||||||
|
libmpdclient <span id="mpd_version"></span><br/>
|
||||||
|
</p>
|
||||||
|
<h5>ympd uses following excellent software:</h5>
|
||||||
<h6><a href="http://libwebsockets.org">libWebSockets</a> <small>LGPL2.1 + static link exception</small></h6>
|
<h6><a href="http://libwebsockets.org">libWebSockets</a> <small>LGPL2.1 + static link exception</small></h6>
|
||||||
<h6><a href="http://www.musicpd.org/libs/libmpdclient/">libMPDClient</a> <small>BSD License</small></h6>
|
<h6><a href="http://www.musicpd.org/libs/libmpdclient/">libMPDClient</a> <small>BSD License</small></h6>
|
||||||
<br/>
|
<br/>
|
||||||
@ -162,7 +168,7 @@
|
|||||||
<strong>Andrew Karpow</strong><br>
|
<strong>Andrew Karpow</strong><br>
|
||||||
<a href="mailto:andy@ympd.org">andy@ympd.org</a><br/>
|
<a href="mailto:andy@ympd.org">andy@ympd.org</a><br/>
|
||||||
<a href="http://www.ympd.org">www.ympd.org</a><br/>
|
<a href="http://www.ympd.org">www.ympd.org</a><br/>
|
||||||
XMPP: <a href="xmpp:andy@jabber.ccc.de?subscribe">andy_@jabber.ccc.de</a>
|
XMPP: <a href="xmpp:andy_@jabber.ccc.de?subscribe">andy_@jabber.ccc.de</a>
|
||||||
</address>
|
</address>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
@ -179,7 +185,8 @@
|
|||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
<script src="js/jquery-1.10.2.min.js"></script>
|
<script src="js/jquery-1.10.2.min.js"></script>
|
||||||
<script src="js/bootstrap.min.js"></script>
|
<script src="js/bootstrap.min.js"></script>
|
||||||
<script src="js/bootstrap-slider.js"></script>
|
<script src="js/bootstrap-notify.js"></script>
|
||||||
|
<script src="js/boostrap-slider.js"></script>
|
||||||
<script src="js/sammy.js"></script>
|
<script src="js/sammy.js"></script>
|
||||||
<script src="js/mpd.js"></script>
|
<script src="js/mpd.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
585
htdocs/js/bootstrap-notify.js
vendored
Normal file
585
htdocs/js/bootstrap-notify.js
vendored
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
/** Notify.js - v0.3.1 - 2013/07/05
|
||||||
|
* http://notifyjs.com/
|
||||||
|
* Copyright (c) 2013 Jaime Pillora - MIT
|
||||||
|
*/
|
||||||
|
(function(window,document,$,undefined) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Notification, addStyle, blankFieldName, coreStyle, createElem, defaults, encode, find, findFields, getAnchorElement, getStyle, globalAnchors, hAligns, incr, inherit, insertCSS, mainPositions, opposites, parsePosition, pluginClassName, pluginName, pluginOptions, positions, realign, stylePrefixes, styles, vAligns,
|
||||||
|
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||||
|
|
||||||
|
pluginName = 'notify';
|
||||||
|
|
||||||
|
pluginClassName = pluginName + 'js';
|
||||||
|
|
||||||
|
blankFieldName = pluginName + "!blank";
|
||||||
|
|
||||||
|
positions = {
|
||||||
|
t: 'top',
|
||||||
|
m: 'middle',
|
||||||
|
b: 'bottom',
|
||||||
|
l: 'left',
|
||||||
|
c: 'center',
|
||||||
|
r: 'right'
|
||||||
|
};
|
||||||
|
|
||||||
|
hAligns = ['l', 'c', 'r'];
|
||||||
|
|
||||||
|
vAligns = ['t', 'm', 'b'];
|
||||||
|
|
||||||
|
mainPositions = ['t', 'b', 'l', 'r'];
|
||||||
|
|
||||||
|
opposites = {
|
||||||
|
t: 'b',
|
||||||
|
m: null,
|
||||||
|
b: 't',
|
||||||
|
l: 'r',
|
||||||
|
c: null,
|
||||||
|
r: 'l'
|
||||||
|
};
|
||||||
|
|
||||||
|
parsePosition = function(str) {
|
||||||
|
var pos;
|
||||||
|
pos = [];
|
||||||
|
$.each(str.split(/\W+/), function(i, word) {
|
||||||
|
var w;
|
||||||
|
w = word.toLowerCase().charAt(0);
|
||||||
|
if (positions[w]) {
|
||||||
|
return pos.push(w);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
styles = {};
|
||||||
|
|
||||||
|
coreStyle = {
|
||||||
|
name: 'core',
|
||||||
|
html: "<div class=\"" + pluginClassName + "-wrapper\">\n <div class=\"" + pluginClassName + "-arrow\"></div>\n <div class=\"" + pluginClassName + "-container\"></div>\n</div>",
|
||||||
|
css: "." + pluginClassName + "-corner {\n position: fixed;\n margin: 5px;\n z-index: 1050;\n}\n\n." + pluginClassName + "-corner ." + pluginClassName + "-wrapper,\n." + pluginClassName + "-corner ." + pluginClassName + "-container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n margin: 3px;\n}\n\n." + pluginClassName + "-wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n}\n\n." + pluginClassName + "-container {\n display: none;\n z-index: 1;\n position: absolute;\n cursor: pointer;\n}\n\n[data-notify-text],[data-notify-html] {\n position: relative;\n}\n\n." + pluginClassName + "-arrow {\n position: absolute;\n z-index: 2;\n width: 0;\n height: 0;\n}"
|
||||||
|
};
|
||||||
|
|
||||||
|
stylePrefixes = {
|
||||||
|
"border-radius": ["-webkit-", "-moz-"]
|
||||||
|
};
|
||||||
|
|
||||||
|
getStyle = function(name) {
|
||||||
|
return styles[name];
|
||||||
|
};
|
||||||
|
|
||||||
|
addStyle = function(name, def) {
|
||||||
|
var cssText, elem, fields, _ref;
|
||||||
|
if (!name) {
|
||||||
|
throw "Missing Style name";
|
||||||
|
}
|
||||||
|
if (!def) {
|
||||||
|
throw "Missing Style definition";
|
||||||
|
}
|
||||||
|
if (!def.html) {
|
||||||
|
throw "Missing Style HTML";
|
||||||
|
}
|
||||||
|
if ((_ref = styles[name]) != null ? _ref.cssElem : void 0) {
|
||||||
|
if (window.console) {
|
||||||
|
console.warn("" + pluginName + ": overwriting style '" + name + "'");
|
||||||
|
}
|
||||||
|
styles[name].cssElem.remove();
|
||||||
|
}
|
||||||
|
def.name = name;
|
||||||
|
styles[name] = def;
|
||||||
|
cssText = "";
|
||||||
|
if (def.classes) {
|
||||||
|
$.each(def.classes, function(className, props) {
|
||||||
|
cssText += "." + pluginClassName + "-" + def.name + "-" + className + " {\n";
|
||||||
|
$.each(props, function(name, val) {
|
||||||
|
if (stylePrefixes[name]) {
|
||||||
|
$.each(stylePrefixes[name], function(i, prefix) {
|
||||||
|
return cssText += " " + prefix + name + ": " + val + ";\n";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cssText += " " + name + ": " + val + ";\n";
|
||||||
|
});
|
||||||
|
return cssText += "}\n";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (def.css) {
|
||||||
|
cssText += "/* styles for " + def.name + " */\n" + def.css;
|
||||||
|
}
|
||||||
|
if (cssText) {
|
||||||
|
def.cssElem = insertCSS(cssText);
|
||||||
|
def.cssElem.attr('id', "notify-" + def.name);
|
||||||
|
}
|
||||||
|
fields = {};
|
||||||
|
elem = $(def.html);
|
||||||
|
findFields('html', elem, fields);
|
||||||
|
findFields('text', elem, fields);
|
||||||
|
return def.fields = fields;
|
||||||
|
};
|
||||||
|
|
||||||
|
insertCSS = function(cssText) {
|
||||||
|
var elem;
|
||||||
|
elem = createElem("style");
|
||||||
|
elem.attr('type', 'text/css');
|
||||||
|
$("head").append(elem);
|
||||||
|
try {
|
||||||
|
elem.html(cssText);
|
||||||
|
} catch (e) {
|
||||||
|
elem[0].styleSheet.cssText = cssText;
|
||||||
|
}
|
||||||
|
return elem;
|
||||||
|
};
|
||||||
|
|
||||||
|
findFields = function(type, elem, fields) {
|
||||||
|
var attr;
|
||||||
|
if (type !== 'html') {
|
||||||
|
type = 'text';
|
||||||
|
}
|
||||||
|
attr = "data-notify-" + type;
|
||||||
|
return find(elem, "[" + attr + "]").each(function() {
|
||||||
|
var name;
|
||||||
|
name = $(this).attr(attr);
|
||||||
|
if (!name) {
|
||||||
|
name = blankFieldName;
|
||||||
|
}
|
||||||
|
return fields[name] = type;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
find = function(elem, selector) {
|
||||||
|
if (elem.is(selector)) {
|
||||||
|
return elem;
|
||||||
|
} else {
|
||||||
|
return elem.find(selector);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pluginOptions = {
|
||||||
|
clickToHide: true,
|
||||||
|
autoHide: true,
|
||||||
|
autoHideDelay: 5000,
|
||||||
|
arrowShow: true,
|
||||||
|
arrowSize: 5,
|
||||||
|
breakNewLines: true,
|
||||||
|
elementPosition: 'bottom',
|
||||||
|
globalPosition: 'top right',
|
||||||
|
style: 'bootstrap',
|
||||||
|
className: 'error',
|
||||||
|
showAnimation: 'slideDown',
|
||||||
|
showDuration: 400,
|
||||||
|
hideAnimation: 'slideUp',
|
||||||
|
hideDuration: 200,
|
||||||
|
gap: 5
|
||||||
|
};
|
||||||
|
|
||||||
|
inherit = function(a, b) {
|
||||||
|
var F;
|
||||||
|
F = function() {};
|
||||||
|
F.prototype = a;
|
||||||
|
return $.extend(true, new F(), b);
|
||||||
|
};
|
||||||
|
|
||||||
|
defaults = function(opts) {
|
||||||
|
return $.extend(pluginOptions, opts);
|
||||||
|
};
|
||||||
|
|
||||||
|
createElem = function(tag) {
|
||||||
|
return $("<" + tag + "></" + tag + ">");
|
||||||
|
};
|
||||||
|
|
||||||
|
globalAnchors = {};
|
||||||
|
|
||||||
|
getAnchorElement = function(element) {
|
||||||
|
var radios;
|
||||||
|
if (element.is('[type=radio]')) {
|
||||||
|
radios = element.parents('form:first').find('[type=radio]').filter(function(i, e) {
|
||||||
|
return $(e).attr('name') === element.attr('name');
|
||||||
|
});
|
||||||
|
element = radios.first();
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
incr = function(obj, pos, val) {
|
||||||
|
var opp, temp;
|
||||||
|
if (typeof val === 'string') {
|
||||||
|
val = parseInt(val, 10);
|
||||||
|
} else if (typeof val !== 'number') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isNaN(val)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
opp = positions[opposites[pos.charAt(0)]];
|
||||||
|
temp = pos;
|
||||||
|
if (obj[opp] !== undefined) {
|
||||||
|
pos = positions[opp.charAt(0)];
|
||||||
|
val = -val;
|
||||||
|
}
|
||||||
|
if (obj[pos] === undefined) {
|
||||||
|
obj[pos] = val;
|
||||||
|
} else {
|
||||||
|
obj[pos] += val;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
realign = function(alignment, inner, outer) {
|
||||||
|
if (alignment === 'l' || alignment === 't') {
|
||||||
|
return 0;
|
||||||
|
} else if (alignment === 'c' || alignment === 'm') {
|
||||||
|
return outer / 2 - inner / 2;
|
||||||
|
} else if (alignment === 'r' || alignment === 'b') {
|
||||||
|
return outer - inner;
|
||||||
|
}
|
||||||
|
throw "Invalid alignment";
|
||||||
|
};
|
||||||
|
|
||||||
|
encode = function(text) {
|
||||||
|
encode.e = encode.e || createElem("div");
|
||||||
|
return encode.e.text(text).html();
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification = (function() {
|
||||||
|
|
||||||
|
function Notification(elem, data, options) {
|
||||||
|
if (typeof options === 'string') {
|
||||||
|
options = {
|
||||||
|
className: options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});
|
||||||
|
this.loadHTML();
|
||||||
|
this.wrapper = $(coreStyle.html);
|
||||||
|
this.wrapper.data(pluginClassName, this);
|
||||||
|
this.arrow = this.wrapper.find("." + pluginClassName + "-arrow");
|
||||||
|
this.container = this.wrapper.find("." + pluginClassName + "-container");
|
||||||
|
this.container.append(this.userContainer);
|
||||||
|
if (elem && elem.length) {
|
||||||
|
this.elementType = elem.attr('type');
|
||||||
|
this.originalElement = elem;
|
||||||
|
this.elem = getAnchorElement(elem);
|
||||||
|
this.elem.data(pluginClassName, this);
|
||||||
|
this.elem.before(this.wrapper);
|
||||||
|
}
|
||||||
|
this.container.hide();
|
||||||
|
this.run(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification.prototype.loadHTML = function() {
|
||||||
|
var style;
|
||||||
|
style = this.getStyle();
|
||||||
|
this.userContainer = $(style.html);
|
||||||
|
return this.userFields = style.fields;
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.show = function(show, userCallback) {
|
||||||
|
var args, callback, elems, fn, hidden,
|
||||||
|
_this = this;
|
||||||
|
callback = function() {
|
||||||
|
if (!show && !_this.elem) {
|
||||||
|
_this.destroy();
|
||||||
|
}
|
||||||
|
if (userCallback) {
|
||||||
|
return userCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
hidden = this.container.parent().parents(':hidden').length > 0;
|
||||||
|
elems = this.container.add(this.arrow);
|
||||||
|
args = [];
|
||||||
|
if (hidden && show) {
|
||||||
|
fn = 'show';
|
||||||
|
} else if (hidden && !show) {
|
||||||
|
fn = 'hide';
|
||||||
|
} else if (!hidden && show) {
|
||||||
|
fn = this.options.showAnimation;
|
||||||
|
args.push(this.options.showDuration);
|
||||||
|
} else if (!hidden && !show) {
|
||||||
|
fn = this.options.hideAnimation;
|
||||||
|
args.push(this.options.hideDuration);
|
||||||
|
} else {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
args.push(callback);
|
||||||
|
return elems[fn].apply(elems, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.setGlobalPosition = function() {
|
||||||
|
var align, anchor, css, key, main, pAlign, pMain, position;
|
||||||
|
position = this.getPosition();
|
||||||
|
pMain = position[0], pAlign = position[1];
|
||||||
|
main = positions[pMain];
|
||||||
|
align = positions[pAlign];
|
||||||
|
key = pMain + "|" + pAlign;
|
||||||
|
anchor = globalAnchors[key];
|
||||||
|
if (!anchor) {
|
||||||
|
anchor = globalAnchors[key] = createElem("div");
|
||||||
|
css = {};
|
||||||
|
css[main] = 0;
|
||||||
|
if (align === 'middle') {
|
||||||
|
css.top = '45%';
|
||||||
|
} else if (align === 'center') {
|
||||||
|
css.left = '45%';
|
||||||
|
} else {
|
||||||
|
css[align] = 0;
|
||||||
|
}
|
||||||
|
anchor.css(css).addClass("" + pluginClassName + "-corner");
|
||||||
|
$("body").append(anchor);
|
||||||
|
}
|
||||||
|
return anchor.prepend(this.wrapper);
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.setElementPosition = function() {
|
||||||
|
var arrowColor, arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, gap, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, pos, posFull, position, wrapPos, _i, _j, _len, _len1, _ref;
|
||||||
|
position = this.getPosition();
|
||||||
|
pMain = position[0], pAlign = position[1], pArrow = position[2];
|
||||||
|
elemPos = this.elem.position();
|
||||||
|
elemH = this.elem.outerHeight();
|
||||||
|
elemW = this.elem.outerWidth();
|
||||||
|
elemIH = this.elem.innerHeight();
|
||||||
|
elemIW = this.elem.innerWidth();
|
||||||
|
wrapPos = this.wrapper.position();
|
||||||
|
contH = this.container.height();
|
||||||
|
contW = this.container.width();
|
||||||
|
mainFull = positions[pMain];
|
||||||
|
opp = opposites[pMain];
|
||||||
|
oppFull = positions[opp];
|
||||||
|
css = {};
|
||||||
|
css[oppFull] = pMain === 'b' ? elemH : pMain === 'r' ? elemW : 0;
|
||||||
|
incr(css, 'top', elemPos.top - wrapPos.top);
|
||||||
|
incr(css, 'left', elemPos.left - wrapPos.left);
|
||||||
|
_ref = ['top', 'left'];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
pos = _ref[_i];
|
||||||
|
margin = parseInt(this.elem.css("margin-" + pos), 10);
|
||||||
|
if (margin) {
|
||||||
|
incr(css, pos, margin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gap = Math.max(0, this.options.gap - (this.options.arrowShow ? arrowSize : 0));
|
||||||
|
incr(css, oppFull, gap);
|
||||||
|
if (!this.options.arrowShow) {
|
||||||
|
this.arrow.hide();
|
||||||
|
} else {
|
||||||
|
arrowSize = this.options.arrowSize;
|
||||||
|
arrowCss = $.extend({}, css);
|
||||||
|
arrowColor = this.userContainer.css("border-color") || this.userContainer.css("background-color") || 'white';
|
||||||
|
for (_j = 0, _len1 = mainPositions.length; _j < _len1; _j++) {
|
||||||
|
pos = mainPositions[_j];
|
||||||
|
posFull = positions[pos];
|
||||||
|
if (pos === opp) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
color = posFull === mainFull ? arrowColor : 'transparent';
|
||||||
|
arrowCss["border-" + posFull] = "" + arrowSize + "px solid " + color;
|
||||||
|
}
|
||||||
|
incr(css, positions[opp], arrowSize);
|
||||||
|
if (__indexOf.call(mainPositions, pAlign) >= 0) {
|
||||||
|
incr(arrowCss, positions[pAlign], arrowSize * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (__indexOf.call(vAligns, pMain) >= 0) {
|
||||||
|
incr(css, 'left', realign(pAlign, contW, elemW));
|
||||||
|
if (arrowCss) {
|
||||||
|
incr(arrowCss, 'left', realign(pAlign, arrowSize, elemIW));
|
||||||
|
}
|
||||||
|
} else if (__indexOf.call(hAligns, pMain) >= 0) {
|
||||||
|
incr(css, 'top', realign(pAlign, contH, elemH));
|
||||||
|
if (arrowCss) {
|
||||||
|
incr(arrowCss, 'top', realign(pAlign, arrowSize, elemIH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.container.is(":visible")) {
|
||||||
|
css.display = 'block';
|
||||||
|
}
|
||||||
|
this.container.removeAttr('style').css(css);
|
||||||
|
if (arrowCss) {
|
||||||
|
return this.arrow.removeAttr('style').css(arrowCss);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.getPosition = function() {
|
||||||
|
var pos, text, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
|
||||||
|
text = this.options.position || (this.elem ? this.options.elementPosition : this.options.globalPosition);
|
||||||
|
pos = parsePosition(text);
|
||||||
|
if (pos.length === 0) {
|
||||||
|
pos[0] = 'b';
|
||||||
|
}
|
||||||
|
if (_ref = pos[0], __indexOf.call(mainPositions, _ref) < 0) {
|
||||||
|
throw "Must be one of [" + mainPositions + "]";
|
||||||
|
}
|
||||||
|
if (pos.length === 1 || ((_ref1 = pos[0], __indexOf.call(vAligns, _ref1) >= 0) && (_ref2 = pos[1], __indexOf.call(hAligns, _ref2) < 0)) || ((_ref3 = pos[0], __indexOf.call(hAligns, _ref3) >= 0) && (_ref4 = pos[1], __indexOf.call(vAligns, _ref4) < 0))) {
|
||||||
|
pos[1] = (_ref5 = pos[0], __indexOf.call(hAligns, _ref5) >= 0) ? 'm' : 'l';
|
||||||
|
}
|
||||||
|
if (pos.length === 2) {
|
||||||
|
pos[2] = pos[1];
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.getStyle = function(name) {
|
||||||
|
var style;
|
||||||
|
if (!name) {
|
||||||
|
name = this.options.style;
|
||||||
|
}
|
||||||
|
if (!name) {
|
||||||
|
name = 'default';
|
||||||
|
}
|
||||||
|
style = styles[name];
|
||||||
|
if (!style) {
|
||||||
|
throw "Missing style: " + name;
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.updateClasses = function() {
|
||||||
|
var classes, style;
|
||||||
|
classes = ['base'];
|
||||||
|
if ($.isArray(this.options.className)) {
|
||||||
|
classes = classes.concat(this.options.className);
|
||||||
|
} else if (this.options.className) {
|
||||||
|
classes.push(this.options.className);
|
||||||
|
}
|
||||||
|
style = this.getStyle();
|
||||||
|
classes = $.map(classes, function(n) {
|
||||||
|
return "" + pluginClassName + "-" + style.name + "-" + n;
|
||||||
|
}).join(' ');
|
||||||
|
return this.userContainer.attr('class', classes);
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.run = function(data, options) {
|
||||||
|
var d, datas, name, type, value,
|
||||||
|
_this = this;
|
||||||
|
if ($.isPlainObject(options)) {
|
||||||
|
$.extend(this.options, options);
|
||||||
|
} else if ($.type(options) === 'string') {
|
||||||
|
this.options.color = options;
|
||||||
|
}
|
||||||
|
if (this.container && !data) {
|
||||||
|
this.show(false);
|
||||||
|
return;
|
||||||
|
} else if (!this.container && !data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
datas = {};
|
||||||
|
if ($.isPlainObject(data)) {
|
||||||
|
datas = data;
|
||||||
|
} else {
|
||||||
|
datas[blankFieldName] = data;
|
||||||
|
}
|
||||||
|
for (name in datas) {
|
||||||
|
d = datas[name];
|
||||||
|
type = this.userFields[name];
|
||||||
|
if (!type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (type === 'text') {
|
||||||
|
d = encode(d);
|
||||||
|
if (this.options.breakNewLines) {
|
||||||
|
d = d.replace(/\n/g, '<br/>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = name === blankFieldName ? '' : '=' + name;
|
||||||
|
find(this.userContainer, "[data-notify-" + type + value + "]").html(d);
|
||||||
|
}
|
||||||
|
this.updateClasses();
|
||||||
|
if (this.elem) {
|
||||||
|
this.setElementPosition();
|
||||||
|
} else {
|
||||||
|
this.setGlobalPosition();
|
||||||
|
}
|
||||||
|
this.show(true);
|
||||||
|
if (this.options.autoHide) {
|
||||||
|
clearTimeout(this.autohideTimer);
|
||||||
|
return this.autohideTimer = setTimeout(function() {
|
||||||
|
return _this.show(false);
|
||||||
|
}, this.options.autoHideDelay);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Notification.prototype.destroy = function() {
|
||||||
|
return this.wrapper.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
return Notification;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
$[pluginName] = function(elem, data, options) {
|
||||||
|
if ((elem && elem.nodeName) || elem.jquery) {
|
||||||
|
$(elem)[pluginName](data, options);
|
||||||
|
} else {
|
||||||
|
options = data;
|
||||||
|
data = elem;
|
||||||
|
new Notification(null, data, options);
|
||||||
|
}
|
||||||
|
return elem;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn[pluginName] = function(data, options) {
|
||||||
|
$(this).each(function() {
|
||||||
|
var inst;
|
||||||
|
inst = getAnchorElement($(this)).data(pluginClassName);
|
||||||
|
if (inst) {
|
||||||
|
return inst.run(data, options);
|
||||||
|
} else {
|
||||||
|
return new Notification($(this), data, options);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend($[pluginName], {
|
||||||
|
defaults: defaults,
|
||||||
|
addStyle: addStyle,
|
||||||
|
pluginOptions: pluginOptions,
|
||||||
|
getStyle: getStyle,
|
||||||
|
insertCSS: insertCSS
|
||||||
|
});
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
insertCSS(coreStyle.css).attr('id', 'core-notify');
|
||||||
|
return $(document).on('click notify-hide', "." + pluginClassName + "-wrapper", function(e) {
|
||||||
|
var inst;
|
||||||
|
inst = $(this).data(pluginClassName);
|
||||||
|
if (inst && (inst.options.clickToHide || e.type === 'notify-hide')) {
|
||||||
|
return inst.show(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}(window,document,jQuery));
|
||||||
|
|
||||||
|
$.notify.addStyle("bootstrap", {
|
||||||
|
html: "<div>\n<span data-notify-text></span>\n</div>",
|
||||||
|
classes: {
|
||||||
|
base: {
|
||||||
|
"font-weight": "bold",
|
||||||
|
"padding": "8px 15px 8px 14px",
|
||||||
|
"text-shadow": "0 1px 0 rgba(255, 255, 255, 0.5)",
|
||||||
|
"background-color": "#fcf8e3",
|
||||||
|
"border": "1px solid #fbeed5",
|
||||||
|
"border-radius": "4px",
|
||||||
|
"white-space": "nowrap",
|
||||||
|
"padding-left": "25px",
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
"color": "#B94A48",
|
||||||
|
"background-color": "#F2DEDE",
|
||||||
|
"border-color": "#EED3D7",
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
"color": "#468847",
|
||||||
|
"background-color": "#DFF0D8",
|
||||||
|
"border-color": "#D6E9C6",
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
"color": "#3A87AD",
|
||||||
|
"background-color": "#D9EDF7",
|
||||||
|
"border-color": "#BCE8F1",
|
||||||
|
},
|
||||||
|
warn: {
|
||||||
|
"color": "#C09853",
|
||||||
|
"background-color": "#FCF8E3",
|
||||||
|
"border-color": "#FBEED5",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
483
htdocs/js/bootstrap-slider.js
vendored
483
htdocs/js/bootstrap-slider.js
vendored
@ -1,388 +1,139 @@
|
|||||||
/* =========================================================
|
(function($){
|
||||||
* bootstrap-slider.js v2.0.0
|
|
||||||
* http://www.eyecon.ro/bootstrap-slider
|
|
||||||
* =========================================================
|
|
||||||
* Copyright 2012 Stefan Petre
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* ========================================================= */
|
|
||||||
|
|
||||||
!function( $ ) {
|
function slider(options){
|
||||||
|
if(typeof options === 'number'){
|
||||||
|
options = $.extend(
|
||||||
|
{
|
||||||
|
origVal:options
|
||||||
|
},
|
||||||
|
defaults,
|
||||||
|
{
|
||||||
|
val:(( options < 0 ) ? 0 : ( (options > 100 ) ? 100 : options))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (options === "get"){
|
||||||
|
var vals = [];
|
||||||
|
|
||||||
var Slider = function(element, options) {
|
$(this).each(function() {
|
||||||
this.element = $(element);
|
vals.push($(this).data("sliderValue"));
|
||||||
this.picker = $('<div class="slider">'+
|
});
|
||||||
'<div class="slider-track">'+
|
return vals;
|
||||||
'<div class="slider-selection"></div>'+
|
}
|
||||||
'<div class="slider-handle"></div>'+
|
else if(typeof options === 'object'){
|
||||||
'<div class="slider-handle"></div>'+
|
options = $.extend({origVal:options.val,origBarColor:options.barColor},defaults,options);
|
||||||
'</div>'+
|
}
|
||||||
'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'+
|
|
||||||
'</div>')
|
|
||||||
.insertBefore(this.element)
|
|
||||||
.append(this.element);
|
|
||||||
this.id = this.element.data('slider-id')||options.id;
|
|
||||||
if (this.id) {
|
|
||||||
this.picker[0].id = this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof Modernizr !== 'undefined' && Modernizr.touch) {
|
return $(this).each (function() {
|
||||||
this.touchCapable = true;
|
var self=$(this);
|
||||||
}
|
|
||||||
|
|
||||||
var tooltip = this.element.data('slider-tooltip')||options.tooltip;
|
if(self.hasClass("slider-wrapper-jq")){
|
||||||
|
if(self.data("dragSlider") === "true")
|
||||||
|
return;
|
||||||
|
if(typeof options.origVal !== "undefined")
|
||||||
|
self.slider._setValue.call(self,options.val,null,true);
|
||||||
|
if(typeof options.origBarColor !== "undefined")
|
||||||
|
self.find('.progress-bar').css("background-color",options.barColor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.tooltip = this.picker.find('.tooltip');
|
self.addClass("slider-wrapper-jq")
|
||||||
this.tooltipInner = this.tooltip.find('div.tooltip-inner');
|
.append($("<div class='progress' style='position:relative;left:0'/>")
|
||||||
|
.append("<div class='progress-bar' style='position:width: 30%;background-color: "+
|
||||||
|
options.barColor+"; -webkit-transition:none; transition:none;' />")
|
||||||
|
.append("<div class='btn btn-default ' style='position:absolute;height:100%;padding:6px 10px;margin-left:-10px;vertical-align: top'>"));
|
||||||
|
|
||||||
this.orientation = this.element.data('slider-orientation')||options.orientation;
|
self.find('.progress').on('mousedown', function(evt){
|
||||||
switch(this.orientation) {
|
self.data("dragSlider","true")
|
||||||
case 'vertical':
|
.data("startPoint",evt.pageX)
|
||||||
this.picker.addClass('slider-vertical');
|
.data("endPoint",evt.pageX);
|
||||||
this.stylePos = 'top';
|
|
||||||
this.mousePos = 'pageY';
|
|
||||||
this.sizePos = 'offsetHeight';
|
|
||||||
this.tooltip.addClass('right')[0].style.left = '100%';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.picker
|
|
||||||
.addClass('slider-horizontal')
|
|
||||||
.css('width', this.element.outerWidth());
|
|
||||||
this.orientation = 'horizontal';
|
|
||||||
this.stylePos = 'left';
|
|
||||||
this.mousePos = 'pageX';
|
|
||||||
this.sizePos = 'offsetWidth';
|
|
||||||
this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.min = this.element.data('slider-min')||options.min;
|
if(!$(evt.target).hasClass("btn")){
|
||||||
this.max = this.element.data('slider-max')||options.max;
|
self.slider._setWidthFromEvent.call(self,evt.pageX,null,true);
|
||||||
this.step = this.element.data('slider-step')||options.step;
|
}
|
||||||
this.value = this.element.data('slider-value')||options.value;
|
else{
|
||||||
if (this.value[1]) {
|
self.data("btnTarget","true");
|
||||||
this.range = true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.selection = this.element.data('slider-selection')||options.selection;
|
evt.preventDefault();
|
||||||
this.selectionEl = this.picker.find('.slider-selection');
|
evt.stopPropagation();
|
||||||
if (this.selection === 'none') {
|
});
|
||||||
this.selectionEl.addClass('hide');
|
|
||||||
}
|
|
||||||
this.selectionElStyle = this.selectionEl[0].style;
|
|
||||||
|
|
||||||
|
$(window).on('mouseup', function(evt){
|
||||||
|
if(self.data("dragSlider")==="true"){
|
||||||
|
if(!(self.data("btnTarget") === "true" && self.data("startPoint") === self.data("endPoint") )){
|
||||||
|
self.slider._setWidthFromEvent.call(self,evt.pageX);
|
||||||
|
}
|
||||||
|
|
||||||
this.handle1 = this.picker.find('.slider-handle:first');
|
self.removeData("dragSlider")
|
||||||
this.handle1Stype = this.handle1[0].style;
|
.removeData("btnTarget")
|
||||||
this.handle2 = this.picker.find('.slider-handle:last');
|
.removeData("startPoint")
|
||||||
this.handle2Stype = this.handle2[0].style;
|
.removeData("endPoint");
|
||||||
|
}
|
||||||
|
}).on('mousemove',function(evt){
|
||||||
|
if(self.data("dragSlider")==="true"){
|
||||||
|
self.slider._setWidthFromEvent.call(self,evt.pageX,null,true);
|
||||||
|
self.data("endPoint",evt.pageX);
|
||||||
|
evt.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var handle = this.element.data('slider-handle')||options.handle;
|
self.slider._setValue.call(self,options.val);
|
||||||
switch(handle) {
|
});
|
||||||
case 'round':
|
|
||||||
this.handle1.addClass('round');
|
|
||||||
this.handle2.addClass('round');
|
|
||||||
break
|
|
||||||
case 'triangle':
|
|
||||||
this.handle1.addClass('triangle');
|
|
||||||
this.handle2.addClass('triangle');
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.range) {
|
}
|
||||||
this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0]));
|
|
||||||
this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1]));
|
|
||||||
} else {
|
|
||||||
this.value = [ Math.max(this.min, Math.min(this.max, this.value))];
|
|
||||||
this.handle2.addClass('hide');
|
|
||||||
if (this.selection == 'after') {
|
|
||||||
this.value[1] = this.max;
|
|
||||||
} else {
|
|
||||||
this.value[1] = this.min;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.diff = this.max - this.min;
|
|
||||||
this.percentage = [
|
|
||||||
(this.value[0]-this.min)*100/this.diff,
|
|
||||||
(this.value[1]-this.min)*100/this.diff,
|
|
||||||
this.step*100/this.diff
|
|
||||||
];
|
|
||||||
|
|
||||||
this.offset = this.picker.offset();
|
var defaults={
|
||||||
this.size = this.picker[0][this.sizePos];
|
val:50,
|
||||||
|
barColor:"#428bca"
|
||||||
|
},
|
||||||
|
_setWidthFromEvent = function(pageX,reqVals,supress) {
|
||||||
|
if(!reqVals){
|
||||||
|
reqVals = this.slider._getRequiredValues.call(this);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
reqVals = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.formater = options.formater;
|
var width = pageX - reqVals.pbar.offset().left,
|
||||||
|
perc = ((100.0*width) / (reqVals.progw));
|
||||||
|
|
||||||
this.layout();
|
return this.slider._setValue.call(this,perc,reqVals,supress);
|
||||||
|
},
|
||||||
|
_setValue = function (val,reqVals,supress) {
|
||||||
|
if(!reqVals){
|
||||||
|
reqVals = this.slider._getRequiredValues.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.touchCapable) {
|
val = ((val<0)?0:((val>100)?100:val));
|
||||||
// Touch: Bind touch events:
|
var adjVal= ((val*(100-reqVals.pbutp)/100) + (reqVals.pbutp/2));
|
||||||
this.picker.on({
|
|
||||||
touchstart: $.proxy(this.mousedown, this)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.picker.on({
|
|
||||||
mousedown: $.proxy(this.mousedown, this)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tooltip === 'show') {
|
this.data("sliderValue",val);
|
||||||
this.picker.on({
|
reqVals.pbar.css({width:adjVal+"%"});
|
||||||
mouseenter: $.proxy(this.showTooltip, this),
|
this.find('div.btn').css('left',adjVal+"%");
|
||||||
mouseleave: $.proxy(this.hideTooltip, this)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.tooltip.addClass('hide');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Slider.prototype = {
|
if(supress !== true){
|
||||||
constructor: Slider,
|
this.trigger("slider.newValue",{val:Math.round(val)});
|
||||||
|
}
|
||||||
|
|
||||||
over: false,
|
return val;
|
||||||
inDrag: false,
|
},
|
||||||
|
_getRequiredValues = function(){
|
||||||
|
var pbar=this.find('.progress-bar'),
|
||||||
|
progw=this.children('.progress').get(0).clientWidth,
|
||||||
|
pbutp=((this.find('div.btn').get(0).clientWidth*100.0)/progw);
|
||||||
|
|
||||||
showTooltip: function(){
|
return {
|
||||||
this.tooltip.addClass('in');
|
pbar:pbar,
|
||||||
//var left = Math.round(this.percent*this.width);
|
progw:progw,
|
||||||
//this.tooltip.css('left', left - this.tooltip.outerWidth()/2);
|
pbutp:pbutp
|
||||||
this.over = true;
|
};
|
||||||
},
|
};
|
||||||
|
|
||||||
hideTooltip: function(){
|
$.fn.slider = slider;
|
||||||
if (this.inDrag === false) {
|
$.fn.slider.defaults = defaults;
|
||||||
this.tooltip.removeClass('in');
|
$.fn.slider._getRequiredValues = _getRequiredValues ;
|
||||||
}
|
$.fn.slider._setWidthFromEvent = _setWidthFromEvent;
|
||||||
this.over = false;
|
$.fn.slider._setValue = _setValue;
|
||||||
},
|
|
||||||
|
|
||||||
layout: function(){
|
})(jQuery);
|
||||||
this.handle1Stype[this.stylePos] = this.percentage[0]+'%';
|
|
||||||
this.handle2Stype[this.stylePos] = this.percentage[1]+'%';
|
|
||||||
if (this.orientation == 'vertical') {
|
|
||||||
this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%';
|
|
||||||
this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%';
|
|
||||||
} else {
|
|
||||||
this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%';
|
|
||||||
this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%';
|
|
||||||
}
|
|
||||||
if (this.range) {
|
|
||||||
this.tooltipInner.text(
|
|
||||||
this.formater(this.value[0]) +
|
|
||||||
' : ' +
|
|
||||||
this.formater(this.value[1])
|
|
||||||
);
|
|
||||||
this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px';
|
|
||||||
} else {
|
|
||||||
this.tooltipInner.text(
|
|
||||||
this.formater(this.value[0])
|
|
||||||
);
|
|
||||||
this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mousedown: function(ev) {
|
|
||||||
|
|
||||||
// Touch: Get the original event:
|
|
||||||
if (this.touchCapable && ev.type === 'touchstart') {
|
|
||||||
ev = ev.originalEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.offset = this.picker.offset();
|
|
||||||
this.size = this.picker[0][this.sizePos];
|
|
||||||
|
|
||||||
var percentage = this.getPercentage(ev);
|
|
||||||
|
|
||||||
if (this.range) {
|
|
||||||
var diff1 = Math.abs(this.percentage[0] - percentage);
|
|
||||||
var diff2 = Math.abs(this.percentage[1] - percentage);
|
|
||||||
this.dragged = (diff1 < diff2) ? 0 : 1;
|
|
||||||
} else {
|
|
||||||
this.dragged = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.percentage[this.dragged] = percentage;
|
|
||||||
this.layout();
|
|
||||||
|
|
||||||
if (this.touchCapable) {
|
|
||||||
// Touch: Bind touch events:
|
|
||||||
$(document).on({
|
|
||||||
touchmove: $.proxy(this.mousemove, this),
|
|
||||||
touchend: $.proxy(this.mouseup, this)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$(document).on({
|
|
||||||
mousemove: $.proxy(this.mousemove, this),
|
|
||||||
mouseup: $.proxy(this.mouseup, this)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inDrag = true;
|
|
||||||
var val = this.calculateValue();
|
|
||||||
this.element.trigger({
|
|
||||||
type: 'slideStart',
|
|
||||||
value: val
|
|
||||||
}).trigger({
|
|
||||||
type: 'slide',
|
|
||||||
value: val
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
mousemove: function(ev) {
|
|
||||||
|
|
||||||
// Touch: Get the original event:
|
|
||||||
if (this.touchCapable && ev.type === 'touchmove') {
|
|
||||||
ev = ev.originalEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
var percentage = this.getPercentage(ev);
|
|
||||||
if (this.range) {
|
|
||||||
if (this.dragged === 0 && this.percentage[1] < percentage) {
|
|
||||||
this.percentage[0] = this.percentage[1];
|
|
||||||
this.dragged = 1;
|
|
||||||
} else if (this.dragged === 1 && this.percentage[0] > percentage) {
|
|
||||||
this.percentage[1] = this.percentage[0];
|
|
||||||
this.dragged = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.percentage[this.dragged] = percentage;
|
|
||||||
this.layout();
|
|
||||||
var val = this.calculateValue();
|
|
||||||
this.element
|
|
||||||
.trigger({
|
|
||||||
type: 'slide',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
.data('value', val)
|
|
||||||
.prop('value', val);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
mouseup: function(ev) {
|
|
||||||
if (this.touchCapable) {
|
|
||||||
// Touch: Bind touch events:
|
|
||||||
$(document).off({
|
|
||||||
touchmove: this.mousemove,
|
|
||||||
touchend: this.mouseup
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$(document).off({
|
|
||||||
mousemove: this.mousemove,
|
|
||||||
mouseup: this.mouseup
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inDrag = false;
|
|
||||||
if (this.over == false) {
|
|
||||||
this.hideTooltip();
|
|
||||||
}
|
|
||||||
this.element;
|
|
||||||
var val = this.calculateValue();
|
|
||||||
this.element
|
|
||||||
.trigger({
|
|
||||||
type: 'slideStop',
|
|
||||||
value: val
|
|
||||||
})
|
|
||||||
.data('value', val)
|
|
||||||
.prop('value', val);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
calculateValue: function() {
|
|
||||||
var val;
|
|
||||||
if (this.range) {
|
|
||||||
val = [
|
|
||||||
(this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step),
|
|
||||||
(this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step)
|
|
||||||
];
|
|
||||||
this.value = val;
|
|
||||||
} else {
|
|
||||||
val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step);
|
|
||||||
this.value = [val, this.value[1]];
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
},
|
|
||||||
|
|
||||||
getPercentage: function(ev) {
|
|
||||||
if (this.touchCapable) {
|
|
||||||
ev = ev.touches[0];
|
|
||||||
}
|
|
||||||
var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size;
|
|
||||||
percentage = Math.round(percentage/this.percentage[2])*this.percentage[2];
|
|
||||||
return Math.max(0, Math.min(100, percentage));
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue: function() {
|
|
||||||
if (this.range) {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
return this.value[0];
|
|
||||||
},
|
|
||||||
|
|
||||||
setValue: function(val) {
|
|
||||||
this.value = val;
|
|
||||||
|
|
||||||
if (this.range) {
|
|
||||||
this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0]));
|
|
||||||
this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1]));
|
|
||||||
} else {
|
|
||||||
this.value = [ Math.max(this.min, Math.min(this.max, this.value))];
|
|
||||||
this.handle2.addClass('hide');
|
|
||||||
if (this.selection == 'after') {
|
|
||||||
this.value[1] = this.max;
|
|
||||||
} else {
|
|
||||||
this.value[1] = this.min;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.diff = this.max - this.min;
|
|
||||||
this.percentage = [
|
|
||||||
(this.value[0]-this.min)*100/this.diff,
|
|
||||||
(this.value[1]-this.min)*100/this.diff,
|
|
||||||
this.step*100/this.diff
|
|
||||||
];
|
|
||||||
this.layout();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.slider = function ( option, val ) {
|
|
||||||
return this.each(function () {
|
|
||||||
var $this = $(this),
|
|
||||||
data = $this.data('slider'),
|
|
||||||
options = typeof option === 'object' && option;
|
|
||||||
if (!data) {
|
|
||||||
$this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options))));
|
|
||||||
}
|
|
||||||
if (typeof option == 'string') {
|
|
||||||
data[option](val);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.slider.defaults = {
|
|
||||||
min: 0,
|
|
||||||
max: 10,
|
|
||||||
step: 1,
|
|
||||||
orientation: 'horizontal',
|
|
||||||
value: 5,
|
|
||||||
selection: 'before',
|
|
||||||
tooltip: 'show',
|
|
||||||
handle: 'round',
|
|
||||||
formater: function(value) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.slider.Constructor = Slider;
|
|
||||||
|
|
||||||
}( window.jQuery );
|
|
||||||
|
@ -1,268 +0,0 @@
|
|||||||
/**
|
|
||||||
* simplePagination.js v1.6
|
|
||||||
* A simple jQuery pagination plugin.
|
|
||||||
* http://flaviusmatis.github.com/simplePagination.js/
|
|
||||||
*
|
|
||||||
* Copyright 2012, Flavius Matis
|
|
||||||
* Released under the MIT license.
|
|
||||||
* http://flaviusmatis.github.com/license.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function($){
|
|
||||||
|
|
||||||
var methods = {
|
|
||||||
init: function(options) {
|
|
||||||
var o = $.extend({
|
|
||||||
items: 1,
|
|
||||||
itemsOnPage: 1,
|
|
||||||
pages: 0,
|
|
||||||
displayedPages: 5,
|
|
||||||
edges: 2,
|
|
||||||
currentPage: 1,
|
|
||||||
hrefTextPrefix: '#page-',
|
|
||||||
hrefTextSuffix: '',
|
|
||||||
prevText: 'Prev',
|
|
||||||
nextText: 'Next',
|
|
||||||
ellipseText: '…',
|
|
||||||
cssStyle: 'light-theme',
|
|
||||||
labelMap: [],
|
|
||||||
selectOnClick: true,
|
|
||||||
onPageClick: function(pageNumber, event) {
|
|
||||||
// Callback triggered when a page is clicked
|
|
||||||
// Page number is given as an optional parameter
|
|
||||||
},
|
|
||||||
onInit: function() {
|
|
||||||
// Callback triggered immediately after initialization
|
|
||||||
}
|
|
||||||
}, options || {});
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
o.pages = o.pages ? o.pages : Math.ceil(o.items / o.itemsOnPage) ? Math.ceil(o.items / o.itemsOnPage) : 1;
|
|
||||||
o.currentPage = o.currentPage - 1;
|
|
||||||
o.halfDisplayed = o.displayedPages / 2;
|
|
||||||
|
|
||||||
this.each(function() {
|
|
||||||
self.addClass(o.cssStyle + ' simple-pagination').data('pagination', o);
|
|
||||||
methods._draw.call(self);
|
|
||||||
});
|
|
||||||
|
|
||||||
o.onInit();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
selectPage: function(page) {
|
|
||||||
methods._selectPage.call(this, page - 1);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
prevPage: function() {
|
|
||||||
var o = this.data('pagination');
|
|
||||||
if (o.currentPage > 0) {
|
|
||||||
methods._selectPage.call(this, o.currentPage - 1);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
nextPage: function() {
|
|
||||||
var o = this.data('pagination');
|
|
||||||
if (o.currentPage < o.pages - 1) {
|
|
||||||
methods._selectPage.call(this, o.currentPage + 1);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
getPagesCount: function() {
|
|
||||||
return this.data('pagination').pages;
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurrentPage: function () {
|
|
||||||
return this.data('pagination').currentPage + 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function(){
|
|
||||||
this.empty();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
drawPage: function (page) {
|
|
||||||
var o = this.data('pagination');
|
|
||||||
o.currentPage = page - 1;
|
|
||||||
this.data('pagination', o);
|
|
||||||
methods._draw.call(this);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
redraw: function(){
|
|
||||||
methods._draw.call(this);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
disable: function(){
|
|
||||||
var o = this.data('pagination');
|
|
||||||
o.disabled = true;
|
|
||||||
this.data('pagination', o);
|
|
||||||
methods._draw.call(this);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
enable: function(){
|
|
||||||
var o = this.data('pagination');
|
|
||||||
o.disabled = false;
|
|
||||||
this.data('pagination', o);
|
|
||||||
methods._draw.call(this);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateItems: function (newItems) {
|
|
||||||
var o = this.data('pagination');
|
|
||||||
o.items = newItems;
|
|
||||||
o.pages = methods._getPages(o);
|
|
||||||
this.data('pagination', o);
|
|
||||||
methods._draw.call(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
updateItemsOnPage: function (itemsOnPage) {
|
|
||||||
var o = this.data('pagination');
|
|
||||||
o.itemsOnPage = itemsOnPage;
|
|
||||||
o.pages = methods._getPages(o);
|
|
||||||
this.data('pagination', o);
|
|
||||||
methods._selectPage.call(this, 0);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
_draw: function() {
|
|
||||||
var o = this.data('pagination'),
|
|
||||||
interval = methods._getInterval(o),
|
|
||||||
i,
|
|
||||||
tagName;
|
|
||||||
|
|
||||||
methods.destroy.call(this);
|
|
||||||
|
|
||||||
tagName = (typeof this.prop === 'function') ? this.prop('tagName') : this.attr('tagName');
|
|
||||||
|
|
||||||
var $panel = tagName === 'UL' ? this : $('<ul></ul>').appendTo(this);
|
|
||||||
|
|
||||||
// Generate Prev link
|
|
||||||
if (o.prevText) {
|
|
||||||
methods._appendItem.call(this, o.currentPage - 1, {text: o.prevText, classes: 'prev'});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate start edges
|
|
||||||
if (interval.start > 0 && o.edges > 0) {
|
|
||||||
var end = Math.min(o.edges, interval.start);
|
|
||||||
for (i = 0; i < end; i++) {
|
|
||||||
methods._appendItem.call(this, i);
|
|
||||||
}
|
|
||||||
if (o.edges < interval.start && (interval.start - o.edges != 1)) {
|
|
||||||
$panel.append('<li class="disabled"><span class="ellipse">' + o.ellipseText + '</span></li>');
|
|
||||||
} else if (interval.start - o.edges == 1) {
|
|
||||||
methods._appendItem.call(this, o.edges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate interval links
|
|
||||||
for (i = interval.start; i < interval.end; i++) {
|
|
||||||
methods._appendItem.call(this, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate end edges
|
|
||||||
if (interval.end < o.pages && o.edges > 0) {
|
|
||||||
if (o.pages - o.edges > interval.end && (o.pages - o.edges - interval.end != 1)) {
|
|
||||||
$panel.append('<li class="disabled"><span class="ellipse">' + o.ellipseText + '</span></li>');
|
|
||||||
} else if (o.pages - o.edges - interval.end == 1) {
|
|
||||||
methods._appendItem.call(this, interval.end++);
|
|
||||||
}
|
|
||||||
var begin = Math.max(o.pages - o.edges, interval.end);
|
|
||||||
for (i = begin; i < o.pages; i++) {
|
|
||||||
methods._appendItem.call(this, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate Next link
|
|
||||||
if (o.nextText) {
|
|
||||||
methods._appendItem.call(this, o.currentPage + 1, {text: o.nextText, classes: 'next'});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPages: function(o) {
|
|
||||||
var pages = Math.ceil(o.items / o.itemsOnPage);
|
|
||||||
return pages || 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getInterval: function(o) {
|
|
||||||
return {
|
|
||||||
start: Math.ceil(o.currentPage > o.halfDisplayed ? Math.max(Math.min(o.currentPage - o.halfDisplayed, (o.pages - o.displayedPages)), 0) : 0),
|
|
||||||
end: Math.ceil(o.currentPage > o.halfDisplayed ? Math.min(o.currentPage + o.halfDisplayed, o.pages) : Math.min(o.displayedPages, o.pages))
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendItem: function(pageIndex, opts) {
|
|
||||||
var self = this, options, $link, o = self.data('pagination'), $linkWrapper = $('<li></li>'), $ul = self.find('ul');
|
|
||||||
|
|
||||||
pageIndex = pageIndex < 0 ? 0 : (pageIndex < o.pages ? pageIndex : o.pages - 1);
|
|
||||||
|
|
||||||
options = {
|
|
||||||
text: pageIndex + 1,
|
|
||||||
classes: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
if (o.labelMap.length && o.labelMap[pageIndex]) {
|
|
||||||
options.text = o.labelMap[pageIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
options = $.extend(options, opts || {});
|
|
||||||
|
|
||||||
if (pageIndex == o.currentPage || o.disabled) {
|
|
||||||
if (o.disabled) {
|
|
||||||
$linkWrapper.addClass('disabled');
|
|
||||||
} else {
|
|
||||||
$linkWrapper.addClass('active');
|
|
||||||
}
|
|
||||||
$link = $('<span class="current">' + (options.text) + '</span>');
|
|
||||||
} else {
|
|
||||||
$link = $('<a href="' + o.hrefTextPrefix + (pageIndex + 1) + o.hrefTextSuffix + '" class="page-link">' + (options.text) + '</a>');
|
|
||||||
$link.click(function(event){
|
|
||||||
return methods._selectPage.call(self, pageIndex, event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.classes) {
|
|
||||||
$link.addClass(options.classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
$linkWrapper.append($link);
|
|
||||||
|
|
||||||
if ($ul.length) {
|
|
||||||
$ul.append($linkWrapper);
|
|
||||||
} else {
|
|
||||||
self.append($linkWrapper);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_selectPage: function(pageIndex, event) {
|
|
||||||
var o = this.data('pagination');
|
|
||||||
o.currentPage = pageIndex;
|
|
||||||
if (o.selectOnClick) {
|
|
||||||
methods._draw.call(this);
|
|
||||||
}
|
|
||||||
return o.onPageClick(pageIndex + 1, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.pagination = function(method) {
|
|
||||||
|
|
||||||
// Method calling logic
|
|
||||||
if (methods[method] && method.charAt(0) != '_') {
|
|
||||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
||||||
} else if (typeof method === 'object' || !method) {
|
|
||||||
return methods.init.apply(this, arguments);
|
|
||||||
} else {
|
|
||||||
$.error('Method ' + method + ' does not exist on jQuery.pagination');
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery);
|
|
615
htdocs/js/mpd.js
615
htdocs/js/mpd.js
@ -1,371 +1,386 @@
|
|||||||
var socket;
|
var socket;
|
||||||
var last_state;
|
var last_state;
|
||||||
var current_app;
|
var current_app;
|
||||||
var is_firefox;
|
var current_song = new Object();
|
||||||
|
|
||||||
$('#volumeslider').slider().on('slide', function(event) {
|
|
||||||
socket.send("MPD_API_SET_VOLUME,"+event.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
var app = $.sammy(function() {
|
var app = $.sammy(function() {
|
||||||
this.before('/', function(e, data) {
|
this.before('/', function(e, data) {
|
||||||
socket.send("MPD_API_GET_TRACK_INFO");
|
socket.send("MPD_API_GET_TRACK_INFO");
|
||||||
$('#nav_links > li').removeClass('active');
|
$('#nav_links > li').removeClass('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get('#/', function() {
|
this.get('#/', function() {
|
||||||
current_app = 'playlist';
|
current_app = 'playlist';
|
||||||
$('#breadcrump').addClass('hide');
|
$('#breadcrump').addClass('hide');
|
||||||
$('#salamisandwich').find("tr:gt(0)").remove();
|
$('#salamisandwich').find("tr:gt(0)").remove();
|
||||||
//if(is_firefox)
|
$.get( "/api/get_playlist", socket.onmessage);
|
||||||
$.get( "/api/get_playlist", socket.onmessage);
|
|
||||||
//else
|
|
||||||
// socket.send("MPD_API_GET_PLAYLIST");
|
|
||||||
|
|
||||||
$('#panel-heading').text("Playlist");
|
$('#panel-heading').text("Playlist");
|
||||||
$('#playlist').addClass('active');
|
$('#playlist').addClass('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get(/\#\/browse\/(.*)/, function() {
|
this.get(/\#\/browse\/(.*)/, function() {
|
||||||
current_app = 'browse';
|
current_app = 'browse';
|
||||||
$('#breadcrump').removeClass('hide').empty();
|
$('#breadcrump').removeClass('hide').empty().append("<li><a href=\"#/browse/\">root</a></li>");
|
||||||
$('#salamisandwich').find("tr:gt(0)").remove();
|
$('#salamisandwich').find("tr:gt(0)").remove();
|
||||||
var path = this.params['splat'];
|
var path = this.params['splat'][0];
|
||||||
if(path == '')
|
|
||||||
path = "/";
|
|
||||||
|
|
||||||
//if(is_firefox)
|
$.get( "/api/get_browse/" + encodeURIComponent(path), socket.onmessage);
|
||||||
$.get( "/api/get_browse/" + encodeURIComponent(path), socket.onmessage);
|
|
||||||
//else
|
|
||||||
// socket.send("MPD_API_GET_BROWSE,"+path);
|
|
||||||
|
|
||||||
$('#panel-heading').text("Browse database: "+path+"");
|
$('#panel-heading').text("Browse database: "+path+"");
|
||||||
var path_array = path[0].split('/');
|
var path_array = path.split('/');
|
||||||
var full_path = "";
|
var full_path = "";
|
||||||
$.each(path_array, function(index, chunk) {
|
$.each(path_array, function(index, chunk) {
|
||||||
if(path_array.length - 1 == index) {
|
if(path_array.length - 1 == index) {
|
||||||
$('#breadcrump').append("<li class=\"active\">"+ chunk + "</li>");
|
$('#breadcrump').append("<li class=\"active\">"+ chunk + "</li>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
full_path = full_path + chunk;
|
full_path = full_path + chunk;
|
||||||
$('#breadcrump').append("<li><a href=\"#/browse/" + full_path + "\">"+chunk+"</a></li>");
|
$('#breadcrump').append("<li><a href=\"#/browse/" + full_path + "\">"+chunk+"</a></li>");
|
||||||
full_path += "/";
|
full_path += "/";
|
||||||
});
|
});
|
||||||
$('#browse').addClass('active');
|
$('#browse').addClass('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get("/", function(context) {
|
this.get("/", function(context) {
|
||||||
context.redirect("#/");
|
context.redirect("#/");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
is_firefox = true;
|
webSocketConnect();
|
||||||
webSocketConnect();
|
$("#volumeslider").slider(0);
|
||||||
|
$("#volumeslider").on('slider.newValue', function(evt,data){
|
||||||
|
socket.send("MPD_API_SET_VOLUME,"+data.val);
|
||||||
|
});
|
||||||
|
$('#progressbar').slider(0);
|
||||||
|
$("#progressbar").on('slider.newValue', function(evt,data){
|
||||||
|
if(current_song) {
|
||||||
|
var seekVal = Math.ceil(current_song.totalTime*(data.val/100));
|
||||||
|
socket.send("MPD_API_SET_SEEK,"+current_song.currentSongId+","+seekVal);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function webSocketConnect() {
|
function webSocketConnect() {
|
||||||
if (typeof MozWebSocket != "undefined") {
|
if (typeof MozWebSocket != "undefined") {
|
||||||
socket = new MozWebSocket(get_appropriate_ws_url(), "ympd-client");
|
socket = new MozWebSocket(get_appropriate_ws_url(), "ympd-client");
|
||||||
} else {
|
} else {
|
||||||
socket = new WebSocket(get_appropriate_ws_url(), "ympd-client");
|
socket = new WebSocket(get_appropriate_ws_url(), "ympd-client");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
socket.onopen = function() {
|
socket.onopen = function() {
|
||||||
console.log("Connected");
|
$('.top-right').notify({
|
||||||
app.run();
|
message:{text:"Connected"},
|
||||||
|
fadeOut: { enabled: true, delay: 1000 }
|
||||||
|
}).show();
|
||||||
|
|
||||||
/* Push Initial state on first visit */
|
app.run();
|
||||||
//$(window).trigger("statechange")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
socket.onmessage =function got_packet(msg) {
|
socket.onmessage =function got_packet(msg) {
|
||||||
console.log(typeof msg);
|
if(msg instanceof MessageEvent) {
|
||||||
if(msg instanceof MessageEvent) {
|
if(msg.data === last_state)
|
||||||
if(msg.data === last_state)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
var obj = JSON.parse(msg.data);
|
var obj = JSON.parse(msg.data);
|
||||||
} else {
|
} else {
|
||||||
var obj = msg;
|
var obj = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (obj.type) {
|
switch (obj.type) {
|
||||||
case "playlist":
|
case "playlist":
|
||||||
if(current_app !== 'playlist')
|
if(current_app !== 'playlist')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
$('#salamisandwich > tbody').empty();
|
$('#salamisandwich > tbody').empty();
|
||||||
for (var song in obj.data) {
|
for (var song in obj.data) {
|
||||||
var minutes = Math.floor(obj.data[song].duration / 60);
|
var minutes = Math.floor(obj.data[song].duration / 60);
|
||||||
var seconds = obj.data[song].duration - minutes * 60;
|
var seconds = obj.data[song].duration - minutes * 60;
|
||||||
|
|
||||||
$('#salamisandwich > tbody').append(
|
$('#salamisandwich > tbody').append(
|
||||||
"<tr trackid=\"" + obj.data[song].id + "\"><td>" + obj.data[song].pos + "</td>" +
|
"<tr trackid=\"" + obj.data[song].id + "\"><td>" + obj.data[song].pos + "</td>" +
|
||||||
"<td>"+ obj.data[song].title +"</td>" +
|
"<td>"+ obj.data[song].title +"</td>" +
|
||||||
"<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +
|
"<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +
|
||||||
"</td></tr>");
|
"</td></tr>");
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#salamisandwich > tbody > tr').on({
|
$('#salamisandwich > tbody > tr').on({
|
||||||
mouseover: function(){
|
mouseover: function(){
|
||||||
if($(this).children().last().has("a").length == 0)
|
if($(this).children().last().has("a").length == 0)
|
||||||
$(this).children().last().append(
|
$(this).children().last().append(
|
||||||
"<a class=\"pull-right btn-group-hover\" href=\"#/\" " +
|
"<a class=\"pull-right btn-group-hover\" href=\"#/\" " +
|
||||||
"onclick=\"socket.send('MPD_API_RM_TRACK," + $(this).attr("trackid") +"'); $(this).parents('tr').remove();\">" +
|
"onclick=\"socket.send('MPD_API_RM_TRACK," + $(this).attr("trackid") +"'); $(this).parents('tr').remove();\">" +
|
||||||
"<span class=\"glyphicon glyphicon-trash\"></span></a>")
|
"<span class=\"glyphicon glyphicon-trash\"></span></a>")
|
||||||
.find('a').fadeTo('fast',1);
|
.find('a').fadeTo('fast',1);
|
||||||
},
|
},
|
||||||
click: function() {
|
click: function() {
|
||||||
$('#salamisandwich > tbody > tr').removeClass('active');
|
$('#salamisandwich > tbody > tr').removeClass('active');
|
||||||
socket.send('MPD_API_PLAY_TRACK,'+$(this).attr('trackid'));
|
socket.send('MPD_API_PLAY_TRACK,'+$(this).attr('trackid'));
|
||||||
$(this).addClass('active');
|
$(this).addClass('active');
|
||||||
},
|
},
|
||||||
mouseleave: function(){
|
mouseleave: function(){
|
||||||
$(this).children().last().find("a").stop().remove();
|
$(this).children().last().find("a").stop().remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
|
||||||
case "browse":
|
|
||||||
//if(state.data.state !== 'nav_browse')
|
|
||||||
// break;
|
|
||||||
if(current_app !== 'browse')
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (var item in obj.data) {
|
|
||||||
switch(obj.data[item].type) {
|
|
||||||
case "directory":
|
|
||||||
$('#salamisandwich > tbody').append(
|
|
||||||
"<tr uri=\"" + obj.data[item].dir + "\">" +
|
|
||||||
"<td><span class=\"glyphicon glyphicon-folder-open\"></span></td>" +
|
|
||||||
"<td><a href=\"#/browse/"+ obj.data[item].dir +"\">" + basename(obj.data[item].dir) +"</a></td>" +
|
|
||||||
"<td></td></tr>");
|
|
||||||
break;
|
|
||||||
case "song":
|
|
||||||
var minutes = Math.floor(obj.data[item].duration / 60);
|
|
||||||
var seconds = obj.data[item].duration - minutes * 60;
|
|
||||||
|
|
||||||
$('#salamisandwich > tbody').append(
|
|
||||||
"<tr uri=\"" + obj.data[item].uri + "\">" +
|
|
||||||
"<td><span class=\"glyphicon glyphicon-music\"></span></td>" +
|
|
||||||
"<td>" + obj.data[item].title +"</td>" +
|
|
||||||
"<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +"</td></tr>");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "playlist":
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#salamisandwich > tbody > tr').on({
|
|
||||||
mouseover: function(){
|
|
||||||
if($(this).children().last().has("a").length == 0)
|
|
||||||
if($(this).attr("uri").length > 0)
|
|
||||||
$(this).children().last().append(
|
|
||||||
"<a role=\"button\" class=\"pull-right btn-group-hover\" " +
|
|
||||||
"onclick=\"socket.send('MPD_API_ADD_TRACK," + $(this).attr("uri") +"'); $(this).parents('tr').addClass('active');\">" +
|
|
||||||
"<span class=\"glyphicon glyphicon-plus\"></span></a>")
|
|
||||||
.find('a').fadeTo('fast',1);
|
|
||||||
},
|
|
||||||
mouseleave: function(){
|
|
||||||
$(this).children().last().find("a").stop().remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "state":
|
|
||||||
if(JSON.stringify(obj) === JSON.stringify(last_state))
|
|
||||||
break;
|
|
||||||
|
|
||||||
var total_minutes = Math.floor(obj.data.totalTime / 60);
|
|
||||||
var total_seconds = obj.data.totalTime - total_minutes * 60;
|
|
||||||
|
|
||||||
var elapsed_minutes = Math.floor(obj.data.elapsedTime / 60);
|
|
||||||
var elapsed_seconds = obj.data.elapsedTime - elapsed_minutes * 60;
|
|
||||||
|
|
||||||
$('#volumeslider').slider('setValue', obj.data.volume);
|
|
||||||
var progress = Math.floor(100*obj.data.elapsedTime/obj.data.totalTime) + "%";
|
|
||||||
$('#progressbar').width(progress);
|
|
||||||
|
|
||||||
$('#counter')
|
|
||||||
.text(elapsed_minutes + ":" +
|
|
||||||
(elapsed_seconds < 10 ? '0' : '') + elapsed_seconds + " / " +
|
|
||||||
total_minutes + ":" + (total_seconds < 10 ? '0' : '') + total_seconds);
|
|
||||||
|
|
||||||
$('#salamisandwich > tbody > tr').removeClass('active').css("font-weight", "");
|
|
||||||
$('#salamisandwich > tbody > tr[trackid='+obj.data.currentsongid+']').addClass('active').css("font-weight", "bold");
|
|
||||||
|
|
||||||
if(obj.data.random)
|
|
||||||
$('#btnrandom').addClass("active")
|
|
||||||
else
|
|
||||||
$('#btnrandom').removeClass("active");
|
|
||||||
|
|
||||||
if(obj.data.consume)
|
|
||||||
$('#btnconsume').addClass("active")
|
|
||||||
else
|
|
||||||
$('#btnconsume').removeClass("active");
|
|
||||||
|
|
||||||
if(obj.data.single)
|
|
||||||
$('#btnsingle').addClass("active")
|
|
||||||
else
|
|
||||||
$('#btnsingle').removeClass("active");
|
|
||||||
|
|
||||||
if(obj.data.repeat)
|
|
||||||
$('#btnrepeat').addClass("active")
|
|
||||||
else
|
|
||||||
$('#btnrepeat').removeClass("active");
|
|
||||||
|
|
||||||
if(last_state && (obj.data.state !== last_state.data.state))
|
|
||||||
updatePlayIcon(obj.data.state);
|
|
||||||
if(last_state && (obj.data.volume !== last_state.data.volume))
|
|
||||||
updateVolumeIcon(obj.data.volume);
|
|
||||||
|
|
||||||
if(obj.data.elapsedTime <= 1)
|
|
||||||
socket.send("MPD_API_GET_TRACK_INFO");
|
|
||||||
|
|
||||||
$('#alert').addClass("hide");
|
|
||||||
last_state = obj;
|
|
||||||
break;
|
|
||||||
case "disconnected":
|
|
||||||
$('#alert')
|
|
||||||
.text("Server lost connection to MPD Host.")
|
|
||||||
.removeClass("hide alert-info")
|
|
||||||
.addClass("alert-danger");
|
|
||||||
break;
|
break;
|
||||||
|
case "browse":
|
||||||
|
if(current_app !== 'browse')
|
||||||
|
break;
|
||||||
|
|
||||||
case "current_song":
|
for (var item in obj.data) {
|
||||||
$('#currenttrack').text(" " + obj.data.title);
|
switch(obj.data[item].type) {
|
||||||
if(obj.data.album)
|
case "directory":
|
||||||
$('#album').text(obj.data.album);
|
$('#salamisandwich > tbody').append(
|
||||||
if(obj.data.artist)
|
"<tr uri=\"" + obj.data[item].dir + "\" class=\"dir\">" +
|
||||||
$('#artist').text(obj.data.artist);
|
"<td><span class=\"glyphicon glyphicon-folder-open\"></span></td>" +
|
||||||
default:
|
"<td><a>" + basename(obj.data[item].dir) + "</a></td>" +
|
||||||
break;
|
"<td></td></tr>");
|
||||||
}
|
break;
|
||||||
|
case "song":
|
||||||
|
var minutes = Math.floor(obj.data[item].duration / 60);
|
||||||
|
var seconds = obj.data[item].duration - minutes * 60;
|
||||||
|
|
||||||
|
$('#salamisandwich > tbody').append(
|
||||||
|
"<tr uri=\"" + obj.data[item].uri + "\" class=\"song\">" +
|
||||||
|
"<td><span class=\"glyphicon glyphicon-music\"></span></td>" +
|
||||||
|
"<td>" + obj.data[item].title +"</td>" +
|
||||||
|
"<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +"</td></tr>");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "playlist":
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#salamisandwich > tbody > tr').on({
|
||||||
|
mouseenter: function(){
|
||||||
|
if($(this).is(".dir")) {
|
||||||
|
$(this).children().last().append(
|
||||||
|
"<a role=\"button\" class=\"pull-right btn-group-hover\">" +
|
||||||
|
"Add Directory <span class=\"glyphicon glyphicon-plus\"></span></a>")
|
||||||
|
.find('a').click(function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
socket.send("MPD_API_ADD_TRACK," + $(this).parents("tr").attr("uri"));
|
||||||
|
$('.top-right').notify({
|
||||||
|
message:{
|
||||||
|
text:"Added " + $('td:nth-child(2)', $(this).parents("tr")).text() + " to playlist "
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
}).fadeTo('fast',1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
click: function() {
|
||||||
|
if($(this).is(".song")) {
|
||||||
|
socket.send("MPD_API_ADD_TRACK," + $(this).attr("uri"));
|
||||||
|
$('.top-right').notify({
|
||||||
|
message:{
|
||||||
|
text:"Added " + $('td:nth-child(2)', this).text() + " to playlist "
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
|
||||||
|
} else
|
||||||
|
app.setLocation("#/browse/"+$(this).attr("uri"));
|
||||||
|
},
|
||||||
|
mouseleave: function(){
|
||||||
|
$(this).children().last().find("a").stop().remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "state":
|
||||||
|
updatePlayIcon(obj.data.state);
|
||||||
|
updateVolumeIcon(obj.data.volume);
|
||||||
|
|
||||||
|
if(JSON.stringify(obj) === JSON.stringify(last_state))
|
||||||
|
break;
|
||||||
|
|
||||||
|
current_song.totalTime = obj.data.totalTime;
|
||||||
|
current_song.currentSongId = obj.data.currentsongid;
|
||||||
|
var total_minutes = Math.floor(obj.data.totalTime / 60);
|
||||||
|
var total_seconds = obj.data.totalTime - total_minutes * 60;
|
||||||
|
|
||||||
|
var elapsed_minutes = Math.floor(obj.data.elapsedTime / 60);
|
||||||
|
var elapsed_seconds = obj.data.elapsedTime - elapsed_minutes * 60;
|
||||||
|
|
||||||
|
$('#volumeslider').slider(obj.data.volume);
|
||||||
|
var progress = Math.floor(100*obj.data.elapsedTime/obj.data.totalTime);
|
||||||
|
$('#progressbar').slider(progress);
|
||||||
|
|
||||||
|
$('#counter')
|
||||||
|
.text(elapsed_minutes + ":" +
|
||||||
|
(elapsed_seconds < 10 ? '0' : '') + elapsed_seconds + " / " +
|
||||||
|
total_minutes + ":" + (total_seconds < 10 ? '0' : '') + total_seconds);
|
||||||
|
|
||||||
|
$('#salamisandwich > tbody > tr').removeClass('active').css("font-weight", "");
|
||||||
|
$('#salamisandwich > tbody > tr[trackid='+obj.data.currentsongid+']').addClass('active').css("font-weight", "bold");
|
||||||
|
|
||||||
|
if(obj.data.random)
|
||||||
|
$('#btnrandom').addClass("active")
|
||||||
|
else
|
||||||
|
$('#btnrandom').removeClass("active");
|
||||||
|
|
||||||
|
if(obj.data.consume)
|
||||||
|
$('#btnconsume').addClass("active")
|
||||||
|
else
|
||||||
|
$('#btnconsume').removeClass("active");
|
||||||
|
|
||||||
|
if(obj.data.single)
|
||||||
|
$('#btnsingle').addClass("active")
|
||||||
|
else
|
||||||
|
$('#btnsingle').removeClass("active");
|
||||||
|
|
||||||
|
if(obj.data.repeat)
|
||||||
|
$('#btnrepeat').addClass("active")
|
||||||
|
else
|
||||||
|
$('#btnrepeat').removeClass("active");
|
||||||
|
|
||||||
|
if(obj.data.elapsedTime <= 1)
|
||||||
|
socket.send("MPD_API_GET_TRACK_INFO");
|
||||||
|
|
||||||
|
last_state = obj;
|
||||||
|
break;
|
||||||
|
case "disconnected":
|
||||||
|
if($('.top-right').has('div').length == 0)
|
||||||
|
$('.top-right').notify({
|
||||||
|
message:{text:"ympd lost connection to MPD "},
|
||||||
|
type: "danger",
|
||||||
|
fadeOut: { enabled: true, delay: 1000 },
|
||||||
|
}).show();
|
||||||
|
break;
|
||||||
|
case "update_playlist":
|
||||||
|
if(current_app === 'playlist')
|
||||||
|
$.get( "/api/get_playlist", socket.onmessage);
|
||||||
|
break;
|
||||||
|
case "current_song":
|
||||||
|
$('#currenttrack').text(" " + obj.data.title);
|
||||||
|
if(obj.data.album)
|
||||||
|
$('#album').text(obj.data.album);
|
||||||
|
if(obj.data.artist)
|
||||||
|
$('#artist').text(obj.data.artist);
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
$('.top-right').notify({
|
||||||
|
message:{text: obj.data},
|
||||||
|
type: "danger",
|
||||||
|
}).show();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
socket.onclose = function(){
|
socket.onclose = function(){
|
||||||
console.log("Disconnected");
|
console.log("Disconnected");
|
||||||
|
$('.top-right').notify({
|
||||||
|
message:{text:"Connection to ympd lost, retrying in 3 seconds "},
|
||||||
|
type: "danger",
|
||||||
|
onClose: function () {
|
||||||
|
webSocketConnect();
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
|
||||||
var seconds = 5;
|
} catch(exception) {
|
||||||
var tm = setInterval(disconnectAlert,1000);
|
alert('<p>Error' + exception);
|
||||||
|
}
|
||||||
function disconnectAlert() {
|
|
||||||
$('#alert')
|
|
||||||
.text("Connection to MPD lost, retrying in " + seconds + " seconds")
|
|
||||||
.removeClass("hide alert-info")
|
|
||||||
.addClass("alert-danger");
|
|
||||||
|
|
||||||
if(seconds-- <= 0) {
|
|
||||||
webSocketConnect();
|
|
||||||
seconds = 5;
|
|
||||||
$('#alert').addClass("hide");
|
|
||||||
clearInterval(tm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(exception) {
|
|
||||||
alert('<p>Error' + exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_appropriate_ws_url()
|
function get_appropriate_ws_url()
|
||||||
{
|
{
|
||||||
var pcol;
|
var pcol;
|
||||||
var u = document.URL;
|
var u = document.URL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/* We open the websocket encrypted if this page came on an
|
/* We open the websocket encrypted if this page came on an
|
||||||
/* https:// url itself, otherwise unencrypted
|
/* https:// url itself, otherwise unencrypted
|
||||||
/*/
|
/*/
|
||||||
|
|
||||||
if (u.substring(0, 5) == "https") {
|
if (u.substring(0, 5) == "https") {
|
||||||
pcol = "wss://";
|
pcol = "wss://";
|
||||||
u = u.substr(8);
|
u = u.substr(8);
|
||||||
} else {
|
} else {
|
||||||
pcol = "ws://";
|
pcol = "ws://";
|
||||||
if (u.substring(0, 4) == "http")
|
if (u.substring(0, 4) == "http")
|
||||||
u = u.substr(7);
|
u = u.substr(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
u = u.split('/');
|
u = u.split('/');
|
||||||
|
|
||||||
return pcol + u[0];
|
return pcol + u[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateVolumeIcon = function(volume)
|
var updateVolumeIcon = function(volume)
|
||||||
{
|
{
|
||||||
$("#volume-icon").removeClass("glyphicon-volume-off");
|
$("#volume-icon").removeClass("glyphicon-volume-off");
|
||||||
$("#volume-icon").removeClass("glyphicon-volume-up");
|
$("#volume-icon").removeClass("glyphicon-volume-up");
|
||||||
$("#volume-icon").removeClass("glyphicon-volume-down");
|
$("#volume-icon").removeClass("glyphicon-volume-down");
|
||||||
|
|
||||||
if(volume == 0) {
|
if(volume == 0) {
|
||||||
$("#volume-icon").addClass("glyphicon-volume-off");
|
$("#volume-icon").addClass("glyphicon-volume-off");
|
||||||
} else if (volume < 50) {
|
} else if (volume < 50) {
|
||||||
$("#volume-icon").addClass("glyphicon-volume-down");
|
$("#volume-icon").addClass("glyphicon-volume-down");
|
||||||
} else {
|
} else {
|
||||||
$("#volume-icon").addClass("glyphicon-volume-up");
|
$("#volume-icon").addClass("glyphicon-volume-up");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var updatePlayIcon = function(state)
|
var updatePlayIcon = function(state)
|
||||||
{
|
{
|
||||||
$("#play-icon").removeClass("glyphicon-play")
|
$("#play-icon").removeClass("glyphicon-play")
|
||||||
.removeClass("glyphicon-pause")
|
.removeClass("glyphicon-pause");
|
||||||
.removeClass("glyphicon-stop");
|
$('#track-icon').removeClass("glyphicon-play")
|
||||||
$('#track-icon').removeClass("glyphicon-play")
|
.removeClass("glyphicon-pause")
|
||||||
.removeClass("glyphicon-pause")
|
.removeClass("glyphicon-stop");
|
||||||
.removeClass("glyphicon-stop");
|
|
||||||
|
|
||||||
if(state == 1) {
|
if(state == 1) { // stop
|
||||||
$("#play-icon").addClass("glyphicon-stop");
|
$("#play-icon").addClass("glyphicon-play");
|
||||||
$('#track-icon').addClass("glyphicon-stop");
|
$('#track-icon').addClass("glyphicon-stop");
|
||||||
} else if(state == 2) {
|
} else if(state == 2) { // pause
|
||||||
$("#play-icon").addClass("glyphicon-pause");
|
$("#play-icon").addClass("glyphicon-pause");
|
||||||
$('#track-icon').addClass("glyphicon-play");
|
$('#track-icon').addClass("glyphicon-play");
|
||||||
} else {
|
} else { // play
|
||||||
$("#play-icon").addClass("glyphicon-play");
|
$("#play-icon").addClass("glyphicon-play");
|
||||||
$('#track-icon').addClass("glyphicon-pause");
|
$('#track-icon').addClass("glyphicon-pause");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDB()
|
function updateDB()
|
||||||
{
|
{
|
||||||
socket.send('MPD_API_UPDATE_DB');
|
socket.send('MPD_API_UPDATE_DB');
|
||||||
|
$('.top-right').notify({
|
||||||
$('#alert')
|
message:{text:"Updating MPD Database... "}
|
||||||
.text("Updating MPD Database...")
|
}).show();
|
||||||
.removeClass("hide alert-danger")
|
|
||||||
.addClass("alert-info");
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
$('#alert').addClass("hide");
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function basename(path) {
|
function basename(path) {
|
||||||
return path.split('/').reverse()[0];
|
return path.split('/').reverse()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#btnrandom').on('click', function (e) {
|
$('#btnrandom').on('click', function (e) {
|
||||||
socket.send("MPD_API_TOGGLE_RANDOM," + ($(this).hasClass('active') ? 0 : 1));
|
socket.send("MPD_API_TOGGLE_RANDOM," + ($(this).hasClass('active') ? 0 : 1));
|
||||||
|
|
||||||
});
|
});
|
||||||
$('#btnconsume').on('click', function (e) {
|
$('#btnconsume').on('click', function (e) {
|
||||||
socket.send("MPD_API_TOGGLE_CONSUME," + ($(this).hasClass('active') ? 0 : 1));
|
socket.send("MPD_API_TOGGLE_CONSUME," + ($(this).hasClass('active') ? 0 : 1));
|
||||||
|
|
||||||
});
|
});
|
||||||
$('#btnsingle').on('click', function (e) {
|
$('#btnsingle').on('click', function (e) {
|
||||||
socket.send("MPD_API_TOGGLE_SINGLE," + ($(this).hasClass('active') ? 0 : 1));
|
socket.send("MPD_API_TOGGLE_SINGLE," + ($(this).hasClass('active') ? 0 : 1));
|
||||||
});
|
});
|
||||||
$('#btnrepeat').on('click', function (e) {
|
$('#btnrepeat').on('click', function (e) {
|
||||||
socket.send("MPD_API_TOGGLE_REPEAT," + ($(this).hasClass('active') ? 0 : 1));
|
socket.send("MPD_API_TOGGLE_REPEAT," + ($(this).hasClass('active') ? 0 : 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getVersion()
|
||||||
|
{
|
||||||
|
$.get( "/api/get_version", function(response) {
|
||||||
|
$('#ympd_version').text(response.data.ympd_version);
|
||||||
|
$('#mpd_version').text(response.data.mpd_version);
|
||||||
|
});
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <mpd/client.h>
|
#include <mpd/client.h>
|
||||||
|
|
||||||
@ -10,6 +11,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
char *resource_path = LOCAL_RESOURCE_PATH;
|
char *resource_path = LOCAL_RESOURCE_PATH;
|
||||||
|
extern enum mpd_conn_states mpd_conn_state;
|
||||||
|
|
||||||
struct serveable {
|
struct serveable {
|
||||||
const char *urlpath;
|
const char *urlpath;
|
||||||
@ -25,6 +27,7 @@ static const struct serveable whitelist[] = {
|
|||||||
{ "/js/mpd.js", "text/javascript" },
|
{ "/js/mpd.js", "text/javascript" },
|
||||||
{ "/js/jquery-1.10.2.min.js", "text/javascript" },
|
{ "/js/jquery-1.10.2.min.js", "text/javascript" },
|
||||||
{ "/js/bootstrap-slider.js", "text/javascript" },
|
{ "/js/bootstrap-slider.js", "text/javascript" },
|
||||||
|
{ "/js/bootstrap-notify.js", "text/javascript" },
|
||||||
{ "/js/sammy.js", "text/javascript" },
|
{ "/js/sammy.js", "text/javascript" },
|
||||||
|
|
||||||
{ "/fonts/glyphicons-halflings-regular.woff", "application/x-font-woff"},
|
{ "/fonts/glyphicons-halflings-regular.woff", "application/x-font-woff"},
|
||||||
@ -38,6 +41,11 @@ static const struct serveable whitelist[] = {
|
|||||||
{ "/index.html", "text/html" },
|
{ "/index.html", "text/html" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char http_header[] = "HTTP/1.0 200 OK\x0d\x0a"
|
||||||
|
"Server: libwebsockets\x0d\x0a"
|
||||||
|
"Content-Type: application/json\x0d\x0a"
|
||||||
|
"Content-Length: 000000\x0d\x0a\x0d\x0a";
|
||||||
|
|
||||||
/* Converts a hex character to its integer value */
|
/* Converts a hex character to its integer value */
|
||||||
char from_hex(char ch) {
|
char from_hex(char ch) {
|
||||||
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
||||||
@ -70,34 +78,37 @@ int callback_http(struct libwebsocket_context *context,
|
|||||||
void *in, size_t len)
|
void *in, size_t len)
|
||||||
{
|
{
|
||||||
char *response_buffer, *p;
|
char *response_buffer, *p;
|
||||||
size_t n, response_size;
|
char buf[64];
|
||||||
|
size_t n, response_size = 0;
|
||||||
|
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case LWS_CALLBACK_HTTP:
|
case LWS_CALLBACK_HTTP:
|
||||||
if(in && strncmp((const char *)in, "/api/", 5) == 0)
|
if(in && strncmp((const char *)in, "/api/", 5) == 0)
|
||||||
{
|
{
|
||||||
response_buffer = (char *)malloc(MAX_SIZE + 100);
|
|
||||||
p = response_buffer;
|
p = (char *)malloc(MAX_SIZE + 100);
|
||||||
|
memcpy(p, http_header, sizeof(http_header) - 1);
|
||||||
|
response_buffer = p + sizeof(http_header) - 1;
|
||||||
|
|
||||||
/* put content length and payload to buffer */
|
/* put content length and payload to buffer */
|
||||||
if(strncmp((const char *)in, "/api/get_browse", 15) == 0)
|
if(mpd_conn_state != MPD_CONNECTED) {}
|
||||||
|
else if(strncmp((const char *)in, "/api/get_browse", 15) == 0)
|
||||||
{
|
{
|
||||||
char *url;
|
char *url;
|
||||||
if(sscanf(in, "/api/get_browse/%m[^\t\n]", &url))
|
if(sscanf(in, "/api/get_browse/%m[^\t\n]", &url) == 1)
|
||||||
{
|
{
|
||||||
char *url_decoded = url_decode(url);
|
char *url_decoded = url_decode(url);
|
||||||
printf("searching for %s", url_decoded);
|
response_size = mpd_put_browse(response_buffer, url_decoded);
|
||||||
response_size = mpd_put_browse(response_buffer + 98, url_decoded);
|
|
||||||
free(url_decoded);
|
free(url_decoded);
|
||||||
free(url);
|
free(url);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
response_size = mpd_put_browse(response_buffer + 98, "/");
|
response_size = mpd_put_browse(response_buffer, "/");
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(strncmp((const char *)in, "/api/get_playlist", 17) == 0)
|
else if(strncmp((const char *)in, "/api/get_playlist", 17) == 0)
|
||||||
response_size = mpd_put_playlist(response_buffer + 98);
|
response_size = mpd_put_playlist(response_buffer);
|
||||||
else if(strncmp((const char *)in, "/api/version", 17) == 0)
|
else if(strncmp((const char *)in, "/api/get_version", 16) == 0)
|
||||||
response_size = snprintf(response_buffer, MAX_SIZE,
|
response_size = snprintf(response_buffer, MAX_SIZE,
|
||||||
"{\"type\":\"version\",\"data\":{"
|
"{\"type\":\"version\",\"data\":{"
|
||||||
"\"ympd_version\":\"%d.%d.%d\","
|
"\"ympd_version\":\"%d.%d.%d\","
|
||||||
@ -106,24 +117,15 @@ int callback_http(struct libwebsocket_context *context,
|
|||||||
YMPD_VERSION_MAJOR, YMPD_VERSION_MINOR, YMPD_VERSION_PATCH,
|
YMPD_VERSION_MAJOR, YMPD_VERSION_MINOR, YMPD_VERSION_PATCH,
|
||||||
LIBMPDCLIENT_MAJOR_VERSION, LIBMPDCLIENT_MINOR_VERSION,
|
LIBMPDCLIENT_MAJOR_VERSION, LIBMPDCLIENT_MINOR_VERSION,
|
||||||
LIBMPDCLIENT_PATCH_VERSION);
|
LIBMPDCLIENT_PATCH_VERSION);
|
||||||
else
|
|
||||||
{
|
|
||||||
/* invalid request, close connection */
|
|
||||||
free(response_buffer);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
p += response_size + sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
|
|
||||||
"Server: libwebsockets\x0d\x0a"
|
|
||||||
"Content-Type: application/json\x0d\x0a"
|
|
||||||
"Content-Length: %6lu\x0d\x0a\x0d\x0a",
|
|
||||||
response_size
|
|
||||||
);
|
|
||||||
response_buffer[98] = '{';
|
|
||||||
|
|
||||||
n = libwebsocket_write(wsi, (unsigned char *)response_buffer,
|
/* Copy size to content-length field */
|
||||||
p - response_buffer, LWS_WRITE_HTTP);
|
sprintf(buf, "%6lu", response_size);
|
||||||
|
memcpy(p + sizeof(http_header) - 11, buf, 6);
|
||||||
|
|
||||||
free(response_buffer);
|
n = libwebsocket_write(wsi, (unsigned char *)p,
|
||||||
|
sizeof(http_header) - 1 + response_size, LWS_WRITE_HTTP);
|
||||||
|
|
||||||
|
free(p);
|
||||||
/*
|
/*
|
||||||
* book us a LWS_CALLBACK_HTTP_WRITEABLE callback
|
* book us a LWS_CALLBACK_HTTP_WRITEABLE callback
|
||||||
*/
|
*/
|
||||||
|
@ -41,12 +41,21 @@ int callback_ympd(struct libwebsocket_context *context,
|
|||||||
}
|
}
|
||||||
p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
|
p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
|
||||||
|
|
||||||
if(mpd_conn_state != MPD_CONNECTED) {
|
if(pss->do_send & DO_SEND_ERROR) {
|
||||||
|
n = snprintf(p, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}",
|
||||||
|
mpd_connection_get_error_message(conn));
|
||||||
|
pss->do_send &= ~DO_SEND_ERROR;
|
||||||
|
|
||||||
|
/* Try to recover error */
|
||||||
|
if (!mpd_connection_clear_error(conn))
|
||||||
|
mpd_conn_state = MPD_FAILURE;
|
||||||
|
}
|
||||||
|
else if(mpd_conn_state != MPD_CONNECTED) {
|
||||||
n = snprintf(p, MAX_SIZE, "{\"type\":\"disconnected\"}");
|
n = snprintf(p, MAX_SIZE, "{\"type\":\"disconnected\"}");
|
||||||
}
|
}
|
||||||
//else if((pss->queue_version != queue_version) || (pss->do_send & DO_SEND_PLAYLIST)) {
|
else if((pss->queue_version != queue_version) || (pss->do_send & DO_SEND_PLAYLIST)) {
|
||||||
else if(pss->do_send & DO_SEND_PLAYLIST) {
|
/*n = mpd_put_playlist(p);*/
|
||||||
n = mpd_put_playlist(p);
|
n = snprintf(p, MAX_SIZE, "{\"type\":\"update_playlist\"}");
|
||||||
pss->queue_version = queue_version;
|
pss->queue_version = queue_version;
|
||||||
pss->do_send &= ~DO_SEND_PLAYLIST;
|
pss->do_send &= ~DO_SEND_PLAYLIST;
|
||||||
}
|
}
|
||||||
@ -78,25 +87,20 @@ int callback_ympd(struct libwebsocket_context *context,
|
|||||||
pss->do_send |= DO_SEND_PLAYLIST;
|
pss->do_send |= DO_SEND_PLAYLIST;
|
||||||
else if(!strcmp((const char *)in, MPD_API_GET_TRACK_INFO))
|
else if(!strcmp((const char *)in, MPD_API_GET_TRACK_INFO))
|
||||||
pss->do_send |= DO_SEND_TRACK_INFO;
|
pss->do_send |= DO_SEND_TRACK_INFO;
|
||||||
else if(!strcmp((const char *)in, MPD_API_UPDATE_DB)) {
|
else if(!strcmp((const char *)in, MPD_API_UPDATE_DB))
|
||||||
mpd_send_update(conn, NULL);
|
mpd_run_update(conn, NULL);
|
||||||
mpd_response_finish(conn);
|
else if(!strcmp((const char *)in, MPD_API_SET_PAUSE))
|
||||||
}
|
mpd_run_toggle_pause(conn);
|
||||||
else if(!strcmp((const char *)in, MPD_API_SET_PAUSE)) {
|
else if(!strcmp((const char *)in, MPD_API_SET_PREV))
|
||||||
mpd_send_toggle_pause(conn);
|
mpd_run_previous(conn);
|
||||||
mpd_response_finish(conn);
|
else if(!strcmp((const char *)in, MPD_API_SET_NEXT))
|
||||||
}
|
mpd_run_next(conn);
|
||||||
else if(!strcmp((const char *)in, MPD_API_SET_PREV)) {
|
else if(!strcmp((const char *)in, MPD_API_SET_PLAY))
|
||||||
mpd_send_previous(conn);
|
mpd_run_play(conn);
|
||||||
mpd_response_finish(conn);
|
else if(!strcmp((const char *)in, MPD_API_SET_STOP))
|
||||||
}
|
mpd_run_stop(conn);
|
||||||
else if(!strcmp((const char *)in, MPD_API_SET_NEXT)) {
|
else if(!strcmp((const char *)in, MPD_API_RM_ALL))
|
||||||
mpd_send_next(conn);
|
|
||||||
mpd_response_finish(conn);
|
|
||||||
}
|
|
||||||
else if(!strcmp((const char *)in, MPD_API_RM_ALL)) {
|
|
||||||
mpd_run_clear(conn);
|
mpd_run_clear(conn);
|
||||||
}
|
|
||||||
else if(!strncmp((const char *)in, MPD_API_RM_TRACK, sizeof(MPD_API_RM_TRACK)-1)) {
|
else if(!strncmp((const char *)in, MPD_API_RM_TRACK, sizeof(MPD_API_RM_TRACK)-1)) {
|
||||||
unsigned id;
|
unsigned id;
|
||||||
if(sscanf(in, "MPD_API_RM_TRACK,%u", &id))
|
if(sscanf(in, "MPD_API_RM_TRACK,%u", &id))
|
||||||
@ -129,9 +133,15 @@ int callback_ympd(struct libwebsocket_context *context,
|
|||||||
}
|
}
|
||||||
else if(!strncmp((const char *)in, MPD_API_SET_VOLUME, sizeof(MPD_API_SET_VOLUME)-1)) {
|
else if(!strncmp((const char *)in, MPD_API_SET_VOLUME, sizeof(MPD_API_SET_VOLUME)-1)) {
|
||||||
unsigned int volume;
|
unsigned int volume;
|
||||||
if(sscanf(in, "MPD_API_SET_VOLUME,%ud", &volume) && volume < 100)
|
if(sscanf(in, "MPD_API_SET_VOLUME,%ud", &volume) && volume <= 100)
|
||||||
mpd_run_set_volume(conn, volume);
|
mpd_run_set_volume(conn, volume);
|
||||||
}
|
}
|
||||||
|
else if(!strncmp((const char *)in, MPD_API_SET_SEEK, sizeof(MPD_API_SET_SEEK)-1)) {
|
||||||
|
unsigned int seek, songid;
|
||||||
|
if(sscanf(in, "MPD_API_SET_SEEK,%u,%u", &songid, &seek)) {
|
||||||
|
mpd_run_seek_id(conn, songid, seek);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(!strncmp((const char *)in, MPD_API_GET_BROWSE, sizeof(MPD_API_GET_BROWSE)-1)) {
|
else if(!strncmp((const char *)in, MPD_API_GET_BROWSE, sizeof(MPD_API_GET_BROWSE)-1)) {
|
||||||
char *dir;
|
char *dir;
|
||||||
if(sscanf(in, "MPD_API_GET_BROWSE,%m[^\t\n]", &dir) && dir != NULL) {
|
if(sscanf(in, "MPD_API_GET_BROWSE,%m[^\t\n]", &dir) && dir != NULL) {
|
||||||
@ -146,6 +156,10 @@ int callback_ympd(struct libwebsocket_context *context,
|
|||||||
free(uri);
|
free(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
|
||||||
|
pss->do_send |= DO_SEND_ERROR;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -283,8 +297,12 @@ int mpd_put_playlist(char *buffer)
|
|||||||
|
|
||||||
if (!mpd_send_list_queue_meta(conn)) {
|
if (!mpd_send_list_queue_meta(conn)) {
|
||||||
lwsl_err("MPD mpd_send_list_queue_meta: %s\n", mpd_connection_get_error_message(conn));
|
lwsl_err("MPD mpd_send_list_queue_meta: %s\n", mpd_connection_get_error_message(conn));
|
||||||
mpd_conn_state = MPD_FAILURE;
|
cur += snprintf(cur, end - cur, "{\"type\":\"error\",\"data\":\"%s\"}",
|
||||||
return 0;
|
mpd_connection_get_error_message(conn));
|
||||||
|
|
||||||
|
if (!mpd_connection_clear_error(conn))
|
||||||
|
mpd_conn_state = MPD_FAILURE;
|
||||||
|
return cur - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur += snprintf(cur, end - cur, "{\"type\": \"playlist\", \"data\": [ ");
|
cur += snprintf(cur, end - cur, "{\"type\": \"playlist\", \"data\": [ ");
|
||||||
@ -319,8 +337,12 @@ int mpd_put_browse(char *buffer, char *path)
|
|||||||
|
|
||||||
if (!mpd_send_list_meta(conn, path)) {
|
if (!mpd_send_list_meta(conn, path)) {
|
||||||
lwsl_err("MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(conn));
|
lwsl_err("MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(conn));
|
||||||
mpd_conn_state = MPD_FAILURE;
|
cur += snprintf(cur, end - cur, "{\"type\":\"error\",\"data\":\"%s\"}",
|
||||||
return 0;
|
mpd_connection_get_error_message(conn));
|
||||||
|
|
||||||
|
if (!mpd_connection_clear_error(conn))
|
||||||
|
mpd_conn_state = MPD_FAILURE;
|
||||||
|
return cur - buffer;
|
||||||
}
|
}
|
||||||
cur += snprintf(cur, end - cur, "{\"type\":\"browse\",\"data\":[ ");
|
cur += snprintf(cur, end - cur, "{\"type\":\"browse\",\"data\":[ ");
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#define DO_SEND_PLAYLIST (1 << 1)
|
#define DO_SEND_PLAYLIST (1 << 1)
|
||||||
#define DO_SEND_TRACK_INFO (1 << 2)
|
#define DO_SEND_TRACK_INFO (1 << 2)
|
||||||
#define DO_SEND_BROWSE (1 << 3)
|
#define DO_SEND_BROWSE (1 << 3)
|
||||||
|
#define DO_SEND_ERROR (1 << 4)
|
||||||
|
|
||||||
|
|
||||||
#define MPD_API_GET_SEEK "MPD_API_GET_SEEK"
|
#define MPD_API_GET_SEEK "MPD_API_GET_SEEK"
|
||||||
#define MPD_API_GET_PLAYLIST "MPD_API_GET_PLAYLIST"
|
#define MPD_API_GET_PLAYLIST "MPD_API_GET_PLAYLIST"
|
||||||
|
Loading…
Reference in New Issue
Block a user