LSP:
+ added status to protocol tab + added ID to streams tab + added sorting to streams tab * minor bugfixes
This commit is contained in:
parent
f0ab171a8b
commit
a90b3d5139
8 changed files with 935 additions and 692 deletions
|
@ -136,7 +136,8 @@
|
||||||
"statistics": {}
|
"statistics": {}
|
||||||
}, d);
|
}, d);
|
||||||
|
|
||||||
console.log('[651] RECV', ret);
|
//IE breaks if the console isn't opened, so keep commented when committing
|
||||||
|
//console.log('[651] RECV', ret);
|
||||||
|
|
||||||
if(callback)
|
if(callback)
|
||||||
{
|
{
|
||||||
|
@ -312,7 +313,8 @@
|
||||||
delete data.log; // don't send the logs back to the server
|
delete data.log; // don't send the logs back to the server
|
||||||
delete data.statistics; // same goes for the stats
|
delete data.statistics; // same goes for the stats
|
||||||
|
|
||||||
console.log('[763] SEND', data);
|
//IE breaks if the console isn't opened, so keep commented when committing
|
||||||
|
//console.log('[763] SEND', data);
|
||||||
|
|
||||||
$.ajax(
|
$.ajax(
|
||||||
{
|
{
|
||||||
|
@ -334,7 +336,8 @@
|
||||||
{
|
{
|
||||||
$('#shield').remove(); // remove loading display
|
$('#shield').remove(); // remove loading display
|
||||||
|
|
||||||
console.log('[785] RECV', d);
|
//IE breaks if the console isn't opened, so keep commented when committing
|
||||||
|
//console.log('[785] RECV', d);
|
||||||
|
|
||||||
if(d && d['authorize'] && d['authorize']['challenge'])
|
if(d && d['authorize'] && d['authorize']['challenge'])
|
||||||
{
|
{
|
||||||
|
|
BIN
lsp/graphics/sort.png
Normal file
BIN
lsp/graphics/sort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 317 B |
BIN
lsp/graphics/sort_asc.png
Normal file
BIN
lsp/graphics/sort_asc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 292 B |
BIN
lsp/graphics/sort_desc.png
Normal file
BIN
lsp/graphics/sort_desc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 308 B |
270
lsp/main.js
270
lsp/main.js
|
@ -70,15 +70,16 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// used on the overview and streams page. cleared when switching to another 'tab'.
|
// used on the overview and streams page. cleared when switching to another 'tab'.
|
||||||
var sinterval = null;
|
var sinterval = null;
|
||||||
|
|
||||||
|
// and this one is used on the protocols page.
|
||||||
|
var pinterval = null;
|
||||||
|
|
||||||
// what kind of streams should be displayed? Format is [recorded, live];
|
// what kind of streams should be displayed? Format is [recorded, live];
|
||||||
var streamsdisplay = [true, true];
|
var streamsdisplay = [true, true];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a certain page. It contains a (giant) switch-statement, that builds a page depending on the tab requested
|
* Display a certain page. It contains a (giant) switch-statement, that builds a page depending on the tab requested
|
||||||
* @param name the name of the tab
|
* @param name the name of the tab
|
||||||
|
@ -89,6 +90,7 @@
|
||||||
// clear page and refresh interval
|
// clear page and refresh interval
|
||||||
$('#page').html('');
|
$('#page').html('');
|
||||||
clearInterval(sinterval);
|
clearInterval(sinterval);
|
||||||
|
clearInterval(pinterval);
|
||||||
|
|
||||||
switch(name)
|
switch(name)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +136,7 @@
|
||||||
}else{
|
}else{
|
||||||
setHeaderState('disconnected');
|
setHeaderState('disconnected');
|
||||||
$('#header-host').text('');
|
$('#header-host').text('');
|
||||||
|
$('#page').append($('<p>').text(errorstr));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).text('login');
|
}).text('login');
|
||||||
|
@ -167,9 +170,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'overview':
|
case 'overview':
|
||||||
|
|
||||||
$('#page').append(
|
$('#page').append(
|
||||||
|
@ -217,7 +217,6 @@
|
||||||
|
|
||||||
showStats();
|
showStats();
|
||||||
|
|
||||||
|
|
||||||
$('#editserver').append(
|
$('#editserver').append(
|
||||||
$('<button>').attr('class', 'floatright').click(function()
|
$('<button>').attr('class', 'floatright').click(function()
|
||||||
{
|
{
|
||||||
|
@ -234,7 +233,6 @@
|
||||||
}).text( 'save' )
|
}).text( 'save' )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
var forcesave = $('<div>').attr('id', 'forcesave');
|
var forcesave = $('<div>').attr('id', 'forcesave');
|
||||||
|
|
||||||
forcesave.append(
|
forcesave.append(
|
||||||
|
@ -254,32 +252,35 @@
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'protocols':
|
case 'protocols':
|
||||||
|
|
||||||
$table = $('<table>');
|
$table = $('<table>');
|
||||||
$table.html("<thead><th>Protocol</th><th>Settings</th><th></th></thead>");
|
$table.html("<thead><th>Protocol</th><th>Status</th><th>Settings</th><th></th></thead>");
|
||||||
$tbody = $('<tbody>');
|
$tbody = $('<tbody>');
|
||||||
|
|
||||||
var tr, i, protocol,
|
var tr, i, protocol,
|
||||||
len = (settings.settings.config.protocols ? settings.settings.config.protocols.length : 0);
|
len = (settings.settings.config.protocols ? settings.settings.config.protocols.length : 0);
|
||||||
|
|
||||||
$tbody.html('');
|
$tbody.html('');
|
||||||
|
pids = [];
|
||||||
|
|
||||||
for(i = 0; i < len; i++)
|
for(i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
protocol = settings.settings.config.protocols[i]; // local copy
|
protocol = settings.settings.config.protocols[i]; // local copy
|
||||||
|
pids.push(i);
|
||||||
|
|
||||||
tr = $('<tr>').attr('id', 'protocol-' + i);
|
tr = $('<tr>').attr('id', 'protocol-' + i);
|
||||||
|
|
||||||
tr.append( $('<td>').text( protocol.connector ) );
|
tr.append( $('<td>').text( protocol.connector ) );
|
||||||
|
|
||||||
|
tr.append( $('<td>').html( formatStatus( protocol.online ) ) );
|
||||||
|
|
||||||
s = "";
|
s = "";
|
||||||
for (option in protocol) {
|
for (option in protocol)
|
||||||
if ((option != 'connector') && (option != 'online')) {
|
{
|
||||||
u =
|
if ((option != 'connector') && (option != 'online'))
|
||||||
s += option+': '+((protocol[option] == '') ? 'default' : protocol[option] )+', ';
|
{
|
||||||
|
s += option+': '+((protocol[option] == '') || (protocol[option] == 0) ? 'default' : protocol[option] )+', ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = s.slice(0,-2);
|
s = s.slice(0,-2);
|
||||||
|
@ -294,8 +295,9 @@
|
||||||
{
|
{
|
||||||
if(confirmDelete('Are you sure you want to delete this protocol?') == true)
|
if(confirmDelete('Are you sure you want to delete this protocol?') == true)
|
||||||
{
|
{
|
||||||
var id = $(this).parent().parent().attr('id').replace('protocol-', '');
|
var id = Number($(this).parent().parent().attr('id').replace('protocol-', ''));
|
||||||
settings.settings.config.protocols.splice(id, 1);
|
var pid = pids.indexOf(id);
|
||||||
|
settings.settings.config.protocols.splice(pid, 1);
|
||||||
$(this).parent().parent().remove();
|
$(this).parent().parent().remove();
|
||||||
loadSettings();
|
loadSettings();
|
||||||
}
|
}
|
||||||
|
@ -314,22 +316,82 @@
|
||||||
}).text('add new')
|
}).text('add new')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function refreshProtocolStatus()
|
||||||
|
{
|
||||||
|
getData(function(data)
|
||||||
|
{
|
||||||
|
protocol = data.config.protocols;
|
||||||
|
for (index in protocol)
|
||||||
|
{
|
||||||
|
var row = $('#protocol-' + index);
|
||||||
|
var status = protocol[index].online;
|
||||||
|
|
||||||
|
$(row.children()[1]).html( formatStatus(status) );
|
||||||
|
|
||||||
|
if (status == undefined)
|
||||||
|
{
|
||||||
|
setTimeout(function()
|
||||||
|
{
|
||||||
|
refreshProtocolStatus();
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pinterval = setInterval(function()
|
||||||
|
{
|
||||||
|
refreshProtocolStatus();
|
||||||
|
},10000);
|
||||||
|
refreshProtocolStatus();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'editprotocol':
|
case 'editprotocol':
|
||||||
if (streamname != 'new') { currentdata = settings.settings.config.protocols[streamname]; }
|
if (streamname != 'new')
|
||||||
|
{
|
||||||
|
currentdata = settings.settings.config.protocols[streamname];
|
||||||
|
}
|
||||||
|
|
||||||
currentconnectors = [];
|
currentconnectors = [];
|
||||||
for (var index in settings.settings.config.protocols) { //build a list of the current connectors to see if the dependencies are already configured
|
// build a list of the current connectors to see if the dependencies are already configured
|
||||||
|
for (var index in settings.settings.config.protocols)
|
||||||
|
{
|
||||||
currentconnectors.push(settings.settings.config.protocols[index].connector);
|
currentconnectors.push(settings.settings.config.protocols[index].connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildProtocolParameterFields(data,required)
|
||||||
|
{
|
||||||
|
for (fieldname in data)
|
||||||
|
{
|
||||||
|
switch(data[fieldname].type)
|
||||||
|
{
|
||||||
|
case 'str':
|
||||||
|
var inputType = 'text'
|
||||||
|
break;
|
||||||
|
case 'uint':
|
||||||
|
var inputType = 'number'
|
||||||
|
var func = 'uint'
|
||||||
|
break;
|
||||||
|
case 'int':
|
||||||
|
var inputType = 'number'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$i = $('<input>').attr('type',inputType).attr('id','protocol-parameter-'+fieldname);
|
||||||
|
if (func == 'uint')
|
||||||
|
{
|
||||||
|
$i.addClass('uint');
|
||||||
|
}
|
||||||
|
if (required)
|
||||||
|
{
|
||||||
|
$i.addClass('required');
|
||||||
|
}
|
||||||
|
$protocolfields.append(
|
||||||
|
$('<label>').text(data[fieldname].name).attr('title',data[fieldname].help).append($i)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function buildProtocolFields(selectedProtocol)
|
function buildProtocolFields(selectedProtocol)
|
||||||
{
|
{
|
||||||
data = settings.settings.capabilities.connectors[selectedProtocol];
|
data = settings.settings.capabilities.connectors[selectedProtocol];
|
||||||
|
@ -343,10 +405,10 @@
|
||||||
for (var index in deps)
|
for (var index in deps)
|
||||||
{
|
{
|
||||||
t = deps[index];
|
t = deps[index];
|
||||||
if ($.inArray(deps[index],currentconnectors) < 0) {
|
if ($.inArray(deps[index],currentconnectors) < 0)
|
||||||
|
{
|
||||||
$u = $('<span>').text(' (Not yet configured!)').addClass('red');
|
$u = $('<span>').text(' (Not yet configured!)').addClass('red');
|
||||||
}
|
}else{
|
||||||
else {
|
|
||||||
$u = $('<span>').text(' (Configured)').addClass('green');
|
$u = $('<span>').text(' (Configured)').addClass('green');
|
||||||
}
|
}
|
||||||
$s.append($('<li>').text(t).append($u));
|
$s.append($('<li>').text(t).append($u));
|
||||||
|
@ -359,67 +421,20 @@
|
||||||
if (typeof data.required != 'undefined')
|
if (typeof data.required != 'undefined')
|
||||||
{
|
{
|
||||||
$protocolfields.append( $('<p>').text('Required parameters') );
|
$protocolfields.append( $('<p>').text('Required parameters') );
|
||||||
for(fieldname in data.required)
|
buildProtocolParameterFields(data.required,true);
|
||||||
{
|
|
||||||
switch (data.required[fieldname].type)
|
|
||||||
{
|
|
||||||
case 'str':
|
|
||||||
var inputType = 'text'
|
|
||||||
break;
|
|
||||||
case 'uint':
|
|
||||||
var inputType = 'number'
|
|
||||||
var func = 'uint'
|
|
||||||
break;
|
|
||||||
case 'int':
|
|
||||||
var inputType = 'number'
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$i = $('<input>').attr('type',inputType).attr('id','protocol-parameter-'+fieldname).addClass('required');
|
|
||||||
if (func == 'uint') {
|
|
||||||
$i.addClass('uint');
|
|
||||||
}
|
|
||||||
$protocolfields.append(
|
|
||||||
$('<label>').text(data.required[fieldname].name).attr('title',data.required[fieldname].help).append($i)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (typeof data.optional != 'undefined')
|
if (typeof data.optional != 'undefined')
|
||||||
{
|
{
|
||||||
$protocolfields.append( $('<p>').text('Optional parameters') );
|
$protocolfields.append( $('<p>').text('Optional parameters') );
|
||||||
for(fieldname in data.optional)
|
buildProtocolParameterFields(data.optional,false);
|
||||||
{
|
|
||||||
switch (data.optional[fieldname].type)
|
|
||||||
{
|
|
||||||
case 'str':
|
|
||||||
var inputType = 'text'
|
|
||||||
break;
|
|
||||||
case 'uint':
|
|
||||||
var inputType = 'number'
|
|
||||||
var func = 'uint'
|
|
||||||
break;
|
|
||||||
case 'int':
|
|
||||||
var inputType = 'number'
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$i = $('<input>').attr('type',inputType).attr('id','protocol-parameter-'+fieldname);
|
|
||||||
if (func == 'uint') {
|
|
||||||
$i.addClass('uint');
|
|
||||||
}
|
|
||||||
$protocolfields.append(
|
|
||||||
$('<label>').text(data.optional[fieldname].name).attr('title',data.optional[fieldname].help).append($i)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$('#protocolfields').html($protocolfields);
|
$('#protocolfields').html($protocolfields);
|
||||||
if (streamname != 'new') {
|
if (streamname != 'new')
|
||||||
for (fieldname in currentdata) {
|
{
|
||||||
if ((fieldname != 'connector') && (fieldname != 'online')) {
|
for (fieldname in currentdata)
|
||||||
|
{
|
||||||
|
if ((fieldname != 'connector') && (fieldname != 'online'))
|
||||||
|
{
|
||||||
$('#protocol-parameter-'+fieldname).val(currentdata[fieldname]);
|
$('#protocol-parameter-'+fieldname).val(currentdata[fieldname]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,8 +458,7 @@
|
||||||
$selectprotocol.append(
|
$selectprotocol.append(
|
||||||
$('<option>').attr('value', protocol).attr('selected','selected').text(protocol)
|
$('<option>').attr('value', protocol).attr('selected','selected').text(protocol)
|
||||||
);
|
);
|
||||||
}
|
}else{
|
||||||
else {
|
|
||||||
$selectprotocol.append(
|
$selectprotocol.append(
|
||||||
$('<option>').attr('value', protocol).text(protocol)
|
$('<option>').attr('value', protocol).text(protocol)
|
||||||
);
|
);
|
||||||
|
@ -458,7 +472,6 @@
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
$('#page').append( $div );
|
$('#page').append( $div );
|
||||||
$('#editprotocol').append( $('<div>').attr('id','protocoldesc') );
|
$('#editprotocol').append( $('<div>').attr('id','protocoldesc') );
|
||||||
$('#editprotocol').append( $('<div>').attr('id', 'protocolfields') );
|
$('#editprotocol').append( $('<div>').attr('id', 'protocolfields') );
|
||||||
|
@ -472,18 +485,26 @@
|
||||||
$('<button>').text('save').addClass('floatright').click(function()
|
$('<button>').text('save').addClass('floatright').click(function()
|
||||||
{
|
{
|
||||||
error = false;
|
error = false;
|
||||||
$('input.required').each(function(){ //check if all required fields have contents
|
//check if all required fields have contents
|
||||||
if ($(this).val() == '') {
|
$('input.required').each(function()
|
||||||
|
{
|
||||||
|
if ($(this).val() == '')
|
||||||
|
{
|
||||||
$(this).focus();
|
$(this).focus();
|
||||||
$(this).parent().addClass('red');
|
$(this).parent().addClass('red');
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('input[type="number"]').each(function(){ //turn all numbers into integers
|
//turn all numbers into integers
|
||||||
|
$('input[type="number"]').each(function()
|
||||||
|
{
|
||||||
$(this).val(Math.floor($(this).val()));
|
$(this).val(Math.floor($(this).val()));
|
||||||
});
|
});
|
||||||
$('input.uint').each(function(){ //check if all uints are actually uints
|
//check if all uints are actually uints
|
||||||
if ($(this).val() < 0) {
|
$('input.uint').each(function()
|
||||||
|
{
|
||||||
|
if ($(this).val() < 0)
|
||||||
|
{
|
||||||
$(this).focus();
|
$(this).focus();
|
||||||
$(this).parent().addClass('red');
|
$(this).parent().addClass('red');
|
||||||
error = true;
|
error = true;
|
||||||
|
@ -500,13 +521,13 @@
|
||||||
{
|
{
|
||||||
connector: connectorval
|
connector: connectorval
|
||||||
};
|
};
|
||||||
|
|
||||||
$('input').each(function(){
|
$('input').each(function(){
|
||||||
newprotocol[$(this).attr('id').split('-')[2]] = $(this).val();;
|
newprotocol[$(this).attr('id').split('-')[2]] = $(this).val();;
|
||||||
});
|
});
|
||||||
if (streamname == 'new') {
|
if (streamname == 'new') {
|
||||||
settings.settings.config.protocols.push(newprotocol);
|
settings.settings.config.protocols.push(newprotocol);
|
||||||
}
|
}else{
|
||||||
else {
|
|
||||||
settings.settings.config.protocols[streamname] = newprotocol;
|
settings.settings.config.protocols[streamname] = newprotocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,17 +542,8 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'streams':
|
case 'streams':
|
||||||
|
|
||||||
// the filter element containr
|
// the filter element containr
|
||||||
|
@ -578,7 +590,6 @@
|
||||||
|
|
||||||
filterTable();
|
filterTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
$div.append(
|
$div.append(
|
||||||
$('<label>').attr('for', 'stream-filter-recorded').text('recorded').append(
|
$('<label>').attr('for', 'stream-filter-recorded').text('recorded').append(
|
||||||
$('<input>').attr('type', 'checkbox').attr('id', 'stream-filter-recorded').attr('checked', streamsdisplay[0])
|
$('<input>').attr('type', 'checkbox').attr('id', 'stream-filter-recorded').attr('checked', streamsdisplay[0])
|
||||||
|
@ -595,7 +606,6 @@
|
||||||
filterOn(event, this);
|
filterOn(event, this);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
$('#page').append($div);
|
$('#page').append($div);
|
||||||
|
|
||||||
// refresh every streams' data (status and viewer count)
|
// refresh every streams' data (status and viewer count)
|
||||||
|
@ -610,9 +620,9 @@
|
||||||
var row = $('#stream-' + stream);
|
var row = $('#stream-' + stream);
|
||||||
var status = streams[stream][0];
|
var status = streams[stream][0];
|
||||||
|
|
||||||
$(row.children()[3]).html( formatStatus(status) );
|
$(row.children()[4]).html( formatStatus(status) );
|
||||||
|
|
||||||
$(row.children()[4]).text(streams[stream][1]);
|
$(row.children()[5]).text(streams[stream][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -626,7 +636,7 @@
|
||||||
refreshStreams();
|
refreshStreams();
|
||||||
|
|
||||||
$table = $('<table>');
|
$table = $('<table>');
|
||||||
$table.html("<thead><th>Type</th><th>Embed</th><th>Name</th><th>Status</th><th>Viewers</th><th>Edit</th></thead>");
|
$table.html("<thead><th class=sort-type-int>Id</th><th class=sort-type-string>Type</th><th>Embed</th><th class='sort-type-string sortdesc'>Name</th><th class=sort-type-string>Status</th><th class=sort-type-int>Viewers</th><th>Edit</th></thead>");
|
||||||
$tbody = $('<tbody>');
|
$tbody = $('<tbody>');
|
||||||
|
|
||||||
var stream, cstr, $tr;
|
var stream, cstr, $tr;
|
||||||
|
@ -639,6 +649,8 @@
|
||||||
|
|
||||||
$tr = $('<tr>').attr('id', 'stream-' + stream);
|
$tr = $('<tr>').attr('id', 'stream-' + stream);
|
||||||
|
|
||||||
|
$tr.append( $('<td>').text( cstr.sid ) );
|
||||||
|
|
||||||
$tr.append( $('<td>').text( TypeofResource( cstr.channel.URL ) ) );
|
$tr.append( $('<td>').text( TypeofResource( cstr.channel.URL ) ) );
|
||||||
|
|
||||||
$tr.append( $('<td>').append( $('<button>').text('embed').click(function()
|
$tr.append( $('<td>').append( $('<button>').text('embed').click(function()
|
||||||
|
@ -676,9 +688,19 @@
|
||||||
}) ) ); // end function, end click, end append, end append.
|
}) ) ); // end function, end click, end append, end append.
|
||||||
|
|
||||||
$tbody.append($tr);
|
$tbody.append($tr);
|
||||||
|
|
||||||
|
//quickly re-check if the streams are online now
|
||||||
|
if (cstr.online == undefined)
|
||||||
|
{
|
||||||
|
setTimeout(function()
|
||||||
|
{
|
||||||
|
refreshStreams();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$table.append($tbody);
|
$table.append($tbody).addClass('sortable');
|
||||||
|
$table.stupidtable();
|
||||||
$('#page').append($table);
|
$('#page').append($table);
|
||||||
|
|
||||||
// on page load, also filter with the (users' defined) stream filter
|
// on page load, also filter with the (users' defined) stream filter
|
||||||
|
@ -693,12 +715,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'editstream':
|
case 'editstream':
|
||||||
|
|
||||||
var sdata, title;
|
var sdata, title;
|
||||||
|
@ -767,7 +783,6 @@
|
||||||
$('#stream-edit-preset-label').show();
|
$('#stream-edit-preset-label').show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$('#editserver').append(
|
$('#editserver').append(
|
||||||
$('<button>').attr('class', 'floatright').click(function()
|
$('<button>').attr('class', 'floatright').click(function()
|
||||||
{
|
{
|
||||||
|
@ -806,6 +821,16 @@
|
||||||
if(streamname == 'new')
|
if(streamname == 'new')
|
||||||
{
|
{
|
||||||
streamname = newname;
|
streamname = newname;
|
||||||
|
sdata.sid = 0;
|
||||||
|
for (strm in settings.settings.streams)
|
||||||
|
{
|
||||||
|
sdata.sid = Math.max(sdata.sid,settings.settings.streams[strm].sid);
|
||||||
|
}
|
||||||
|
sdata.sid += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sdata.sid = settings.settings.streams[streamname].sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!settings.settings.streams)
|
if(!settings.settings.streams)
|
||||||
|
@ -827,10 +852,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'embed':
|
case 'embed':
|
||||||
|
|
||||||
if(isThereAHTTPConnector())
|
if(isThereAHTTPConnector())
|
||||||
|
@ -851,8 +872,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'preview':
|
case 'preview':
|
||||||
|
|
||||||
var embed = 'http://' + parseURL(settings.server).host + ':' + getHTTPControllerPort() + '/embed_' + streamname + '.js';
|
var embed = 'http://' + parseURL(settings.server).host + ':' + getHTTPControllerPort() + '/embed_' + streamname + '.js';
|
||||||
|
@ -866,10 +885,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'limits':
|
case 'limits':
|
||||||
$table = $('<table>');
|
$table = $('<table>');
|
||||||
$table.html("<thead><th>Type</th><th>Hard/soft</th><th>Value</th><th>applies to</th><th>Action</th></thead>");
|
$table.html("<thead><th>Type</th><th>Hard/soft</th><th>Value</th><th>applies to</th><th>Action</th></thead>");
|
||||||
|
@ -905,7 +920,6 @@
|
||||||
tr.append( $('<td>').text( limit.type ) );
|
tr.append( $('<td>').text( limit.type ) );
|
||||||
tr.append( $('<td>').text( limit.val ) );
|
tr.append( $('<td>').text( limit.val ) );
|
||||||
|
|
||||||
|
|
||||||
if(limit.appliesto)
|
if(limit.appliesto)
|
||||||
{
|
{
|
||||||
tr.append( $('<td>').text( settings.settings.streams[limit.appliesto].name ).attr('id', 'limit-at-' + limit.appliesto + '-' + limit.appliesi) );
|
tr.append( $('<td>').text( settings.settings.streams[limit.appliesto].name ).attr('id', 'limit-at-' + limit.appliesto + '-' + limit.appliesi) );
|
||||||
|
@ -1002,8 +1016,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'logs':
|
case 'logs':
|
||||||
$table = $('<table>');
|
$table = $('<table>');
|
||||||
$table.html("<thead><th>Date<span class='theadinfo'>(MM/DD/YYYY)</span></th><th>Type</th><th>Message</th></thead>");
|
$table.html("<thead><th>Date<span class='theadinfo'>(MM/DD/YYYY)</span></th><th>Type</th><th>Message</th></thead>");
|
||||||
|
@ -1055,8 +1067,6 @@
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 'disconnect':
|
case 'disconnect':
|
||||||
showTab('login');
|
showTab('login');
|
||||||
setHeaderState('disconnected');
|
setHeaderState('disconnected');
|
||||||
|
@ -1074,10 +1084,8 @@
|
||||||
settings: {}
|
settings: {}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
|
|
||||||
//placeholder for older browsers
|
//placeholder for older browsers
|
||||||
$('input[placeholder]').placeholder();
|
$('input[placeholder]').placeholder();
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<script src='md5.js'></script>
|
<script src='md5.js'></script>
|
||||||
<script src='main.js'></script>
|
<script src='main.js'></script>
|
||||||
<script src='functions.js'></script>
|
<script src='functions.js'></script>
|
||||||
|
<script src='tablesort.js'></script>
|
||||||
|
|
||||||
<link rel='stylesheet' href='style.css' />
|
<link rel='stylesheet' href='style.css' />
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ button
|
||||||
background-color: #505050;
|
background-color: #505050;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
margin: 0 2px 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -345,6 +346,20 @@ td
|
||||||
width: auto;
|
width: auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
.sortable th.sort-type-string, .sortable th.sort-type-int, .sortable th.sort-type-float
|
||||||
|
{
|
||||||
|
background: transparent url('graphics/sort.png') no-repeat 5px 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable th.sortasc
|
||||||
|
{
|
||||||
|
background-image: url('graphics/sort_asc.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable th.sortdesc
|
||||||
|
{
|
||||||
|
background-image: url('graphics/sort_desc.png');
|
||||||
|
}
|
||||||
#protocoldesc p
|
#protocoldesc p
|
||||||
{
|
{
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
216
lsp/tablesort.js
Normal file
216
lsp/tablesort.js
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
// Stupid jQuery table plugin.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//http://joequery.github.com/Stupid-Table-Plugin/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Call on a table
|
||||||
|
// sortFns: Sort functions for your datatypes.
|
||||||
|
(function($){
|
||||||
|
$.fn.stupidtable = function(sortFns){
|
||||||
|
var table = this; sortFns = sortFns || {};
|
||||||
|
|
||||||
|
// ==================================================== //
|
||||||
|
// Utility functions //
|
||||||
|
// ==================================================== //
|
||||||
|
|
||||||
|
// Merge sort functions with some default sort functions.
|
||||||
|
sortFns = $.extend({}, {
|
||||||
|
"int":function(a,b){ return parseInt(a, 10) - parseInt(b, 10); },
|
||||||
|
"float":function(a,b){ return parseFloat(a) - parseFloat(b); },
|
||||||
|
"string":function(a,b){ if (a<b) return -1; if (a>b) return +1; return 0;}
|
||||||
|
}, sortFns);
|
||||||
|
|
||||||
|
// Array comparison. See http://stackoverflow.com/a/8618383
|
||||||
|
var arrays_equal = function(a,b) { return !!a && !!b && !(a<b || b<a);}
|
||||||
|
|
||||||
|
// Return the resulting indexes of a sort so we can apply
|
||||||
|
// this result elsewhere. This returns an array of index numbers.
|
||||||
|
// return[0] = x means "arr's 0th element is now at x"
|
||||||
|
var sort_map = function(arr, sort_function){
|
||||||
|
var sorted = arr.slice(0).sort(sort_function);
|
||||||
|
var map = [];
|
||||||
|
var index = 0;
|
||||||
|
for(var i=0; i<arr.length; i++){
|
||||||
|
index = $.inArray(arr[i], sorted);
|
||||||
|
|
||||||
|
// If this index is already in the map, look for the next index.
|
||||||
|
// This handles the case of duplicate entries.
|
||||||
|
while($.inArray(index, map) != -1){
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
map.push(index);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply a sort map to the array.
|
||||||
|
var apply_sort_map = function(arr, map){
|
||||||
|
var clone = arr.slice(0);
|
||||||
|
for(var i=0; i<map.length; i++){
|
||||||
|
newIndex = map[i];
|
||||||
|
clone[newIndex] = arr[i];
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if array is sorted, false otherwise.
|
||||||
|
// Checks for both ascending and descending
|
||||||
|
var is_sorted_array = function(arr, sort_function){
|
||||||
|
var clone = arr.slice(0);
|
||||||
|
var reversed = arr.slice(0).reverse();
|
||||||
|
var sorted = arr.slice(0).sort(sort_function);
|
||||||
|
|
||||||
|
// Check if the array is sorted in either direction.
|
||||||
|
return arrays_equal(clone, sorted) || arrays_equal(reversed, sorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var what_order_sorted = function(data, sf, isa)
|
||||||
|
{
|
||||||
|
var tmp = [data[0], data[data.length - 1]];
|
||||||
|
|
||||||
|
tmp.sort(sf);
|
||||||
|
|
||||||
|
if(data[0] == tmp[0] || !isa)
|
||||||
|
{
|
||||||
|
return 'desc';
|
||||||
|
}else{
|
||||||
|
return 'asc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==================================================== //
|
||||||
|
// Begin execution! //
|
||||||
|
// ==================================================== //
|
||||||
|
// Do sorting when THs are clicked
|
||||||
|
|
||||||
|
table.delegate("th", "click", function(){
|
||||||
|
|
||||||
|
if($(this).text().replace(/ /g, '') == '')
|
||||||
|
{
|
||||||
|
// empty header, don't allow sorting
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var trs = table.find("tbody tr");
|
||||||
|
var i = $(this).index();
|
||||||
|
var classes = $(this).attr("class");
|
||||||
|
var type = null;
|
||||||
|
|
||||||
|
if (classes){
|
||||||
|
classes = classes.split(/\s+/);
|
||||||
|
|
||||||
|
for(var j=0; j<classes.length; j++){
|
||||||
|
if(classes[j].search("sort-type-") != -1){
|
||||||
|
type = classes[j].replace('sort-', '');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(type){
|
||||||
|
type = type.split('-')[1];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
type = "string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Don't attempt to sort if no data type
|
||||||
|
//if(!type){return false;}
|
||||||
|
|
||||||
|
|
||||||
|
var sortMethod = sortFns[type];
|
||||||
|
|
||||||
|
|
||||||
|
// Gather the elements for this column
|
||||||
|
column = [];
|
||||||
|
|
||||||
|
// Push either the value of the 'data-order-by' attribute if specified
|
||||||
|
// or just the text() value in this column to column[] for comparison.
|
||||||
|
trs.each(function(index,tr){
|
||||||
|
var e = $(tr).children().eq(i);
|
||||||
|
var order_by = e.attr('data-order-by') || e.text();
|
||||||
|
column.push(order_by);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// If the column is already sorted, just reverse the order. The sort
|
||||||
|
// map is just reversing the indexes.
|
||||||
|
if(is_sorted_array(column, sortMethod)){
|
||||||
|
column.reverse();
|
||||||
|
var theMap = [];
|
||||||
|
for(var i=column.length-1; i>=0; i--){
|
||||||
|
theMap.push(i);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// Get a sort map and apply to all rows
|
||||||
|
theMap = sort_map(column, sortMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// remove old sort classes (on this and other columns)
|
||||||
|
$(this).parent().find('th').each(function()
|
||||||
|
{
|
||||||
|
$(this).removeClass('sortasc sortdesc');
|
||||||
|
});
|
||||||
|
|
||||||
|
// what order are we sorting in?
|
||||||
|
var whatorder = what_order_sorted(column, sortMethod, is_sorted_array(column, sortMethod));
|
||||||
|
|
||||||
|
// set new sort class
|
||||||
|
$(this).addClass(whatorder == 'asc' ? 'sortasc' : 'sortdesc');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var sortedTRs = $(apply_sort_map(trs, theMap));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Replace the content of tbody with the sortedTRs. Strangely (and
|
||||||
|
// conveniently!) enough, .append accomplishes this for us.
|
||||||
|
table.find("tbody").append(sortedTRs);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// remove th icon if no header text
|
||||||
|
$(this).find('th').each(function()
|
||||||
|
{
|
||||||
|
var hv = $(this).text().replace(/ /g, '');
|
||||||
|
|
||||||
|
if(hv == '')
|
||||||
|
{
|
||||||
|
$(this).css('background', 'transparent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
})(jQuery);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$('table.sortable').each(function()
|
||||||
|
{
|
||||||
|
var rows = $(this).find('tbody tr').length;
|
||||||
|
|
||||||
|
if(rows > 1)
|
||||||
|
{
|
||||||
|
$(this).stupidtable();
|
||||||
|
}else{
|
||||||
|
$(this).removeClass('sortable');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue