function MessagePanel(el) {
this.el = el;
this.render();
this.initClearButton();
}
MessagePanel.prototype.supportsMessage = function(message) {
return false;
};
MessagePanel.prototype.render = function() {
};
MessagePanel.prototype.pushMessage = function(message) {
};
// automatic clearing is not enabled by default. call this method from the constructor to enable
MessagePanel.prototype.initClearTimer = function() {
var me = this;
if (me.removalInterval) clearInterval(me.removalInterval);
me.removalInterval = setInterval(function () {
me.clearMessages(1000);
}, 15000);
};
MessagePanel.prototype.clearMessages = function(toRemain) {
var $elements = $(this.el).find('tbody tr');
// limit to 1000 entries in the list since browsers get laggy at some point
var toRemove = $elements.length - toRemain;
if (toRemove <= 0) return;
$elements.slice(0, toRemove).remove();
};
MessagePanel.prototype.initClearButton = function() {
var me = this;
me.clearButton = $(
'
'
));
};
PageMessagePanel.prototype.pushMessage = function(msg) {
var html_escape = function(input) {
return $('').text(input).html()
};
// Get color from the message, default to white
var color = msg.hasOwnProperty('color')? msg.color : "#FFF";
// Append message header (address, time, etc)
var $b = $(this.el).find('tbody');
$b.append($(
'
' +
'
' + msg.address + '
' +
'
' + msg.mode + msg.baud + '
' +
'
' + msg.timestamp + '
' +
'
'
).css('background-color', color).css('color', '#000'));
// Append message body (text)
if (msg.hasOwnProperty('message')) {
$b.append($(
'
' +
html_escape(msg.message) +
'
'
));
}
// Jump list to the last received message
$b.scrollTop($b[0].scrollHeight);
};
$.fn.pageMessagePanel = function() {
if (!this.data('panel')) {
this.data('panel', new PageMessagePanel(this));
}
return this.data('panel');
};
HfdlMessagePanel = function(el) {
MessagePanel.call(this, el);
this.initClearTimer();
this.flight_url = null;
}
HfdlMessagePanel.prototype = new MessagePanel();
HfdlMessagePanel.prototype.supportsMessage = function(message) {
return message['mode'] === 'HFDL';
};
HfdlMessagePanel.prototype.setFlightUrl = function(url) {
this.flight_url = url;
};
HfdlMessagePanel.prototype.linkify = function(id) {
var url = null;
// Do not linkify empty strings
if (id.len<=0) return id;
// 6 hexadecimal digits are an ICAO aircraft ID, not linkifying
if (id.match(new RegExp('^[0-9A-F]{6}$'))) return id;
// Everything else is a flight ID
url = this.flight_url;
// Must have valid lookup URL
if ((url == null) || (url == ''))
return id;
else
return '' + id + '';
};
HfdlMessagePanel.prototype.render = function() {
$(this.el).append($(
'
' +
'
' +
'
Time
' +
'
Flight
' +
'
Aircraft
' +
'
Data
' +
'
' +
'' +
'
'
));
};
HfdlMessagePanel.prototype.pushMessage = function(msg) {
var color = msg.hasOwnProperty('color')? msg.color : '#00000000';
var aircraft = msg.hasOwnProperty('aircraft')? msg.aircraft : '';
var flight = msg.hasOwnProperty('flight')? msg.flight : '';
var tstamp =
msg.hasOwnProperty('msgtime')?
'' + msg.time + '' :
msg.hasOwnProperty('time')?
msg.time : '';
var data =
msg.hasOwnProperty('lat') && msg.hasOwnProperty('lon')?
'@ ' + msg.lat + ', ' + msg.lon :
msg.hasOwnProperty('type')?
msg.type : '';
// Append report
var $b = $(this.el).find('tbody');
$b.append($(
'
' +
'
' + tstamp + '
' +
'
' + this.linkify(flight) + '
' +
'
' + this.linkify(aircraft) + '
' +
'
' + data + '
' +
'
'
).css('background-color', color).css('color', '#000'));
// Append messsage if present
if (msg.hasOwnProperty('message') && (msg.message.length>0)) {
$b.append($(
'
' + msg.message + '
'
))
}
// Jump list to the last received message
$b.scrollTop($b[0].scrollHeight);
};
$.fn.hfdlMessagePanel = function() {
if (!this.data('panel')) {
this.data('panel', new HfdlMessagePanel(this));
}
return this.data('panel');
};
IsmMessagePanel = function(el) {
MessagePanel.call(this, el);
this.initClearTimer();
// These are basic message attributes
this.basicInfo = ['mode', 'id', 'model', 'time', 'color'];
}
IsmMessagePanel.prototype = new MessagePanel();
IsmMessagePanel.prototype.supportsMessage = function(message) {
return message['mode'] === 'ISM';
};
IsmMessagePanel.prototype.render = function() {
$(this.el).append($(
'
'
);
};
IsmMessagePanel.prototype.pushMessage = function(msg) {
// Get basic information, assume white color if missing
var address = msg.hasOwnProperty('id')? msg.id : "???";
var device = msg.hasOwnProperty('model')? msg.model : "";
var tstamp = msg.hasOwnProperty('time')? msg.time : "";
var color = msg.hasOwnProperty('color')? msg.color : "#FFF";
// Append message header (address, time, etc)
var $b = $(this.el).find('tbody');
$b.append($(
'
' +
'
' + address + '
' +
'
' + device + '
' +
'
' + tstamp + '
' +
'
'
).css('background-color', color).css('color', '#000'));
// Append attributes in pairs, skip basic information
var last = null;
for (var key in msg) {
if (this.basicInfo.indexOf(key) < 0) {
var cell = this.formatAttr(msg, key);
if (!last) {
last = cell;
} else {
$b.append($('
' + last + cell + '
'));
last = null;
}
}
}
// Last row
if (last) $b.append($('
' + last + '
'));
// Jump list to the last received message
$b.scrollTop($b[0].scrollHeight);
};
$.fn.ismMessagePanel = function() {
if (!this.data('panel')) {
this.data('panel', new IsmMessagePanel(this));
}
return this.data('panel');
};
SstvMessagePanel = function(el) {
MessagePanel.call(this, el);
this.initClearTimer();
}
SstvMessagePanel.prototype = new MessagePanel();
SstvMessagePanel.prototype.supportsMessage = function(message) {
return message['mode'] === 'SSTV';
};
SstvMessagePanel.prototype.render = function() {
$(this.el).append($(
'
' +
'
' +
'
TV
' +
'
' +
'' +
'
'
));
};
SstvMessagePanel.prototype.pushMessage = function(msg) {
var $b = $(this.el).find('tbody');
if(msg.hasOwnProperty('message')) {
// Append a new debug message text
// See service log for debug output instead
// $b.append($('
' + msg.message + '
'));
// $b.scrollTop($b[0].scrollHeight);
}
else if(msg.width>0 && msg.height>0 && !msg.hasOwnProperty('line')) {
var f = msg.frequency>0? ' at ' + Math.floor(msg.frequency/1000) + 'kHz' : '';
var h = '
'));
$b.scrollTop($b[0].scrollHeight);
// Save canvas context and dimensions for future use
this.ctx = $(this.el).find('canvas').get(-1).getContext("2d");
this.width = msg.width;
this.height = msg.height;
}
else if(msg.width>0 && msg.height>0 && msg.line>=0 && msg.hasOwnProperty('pixels')) {
// Will copy pixels to img
var pixels = atob(msg.pixels);
var img = this.ctx.createImageData(msg.width, 1);
// Convert BMP BGR pixels into HTML RGBA pixels
for (var x = 0; x < msg.width; x++) {
img.data[x*4 + 0] = pixels.charCodeAt(x*3 + 2);
img.data[x*4 + 1] = pixels.charCodeAt(x*3 + 1);
img.data[x*4 + 2] = pixels.charCodeAt(x*3 + 0);
img.data[x*4 + 3] = 0xFF;
}
// Render scanline
this.ctx.putImageData(img, 0, msg.line);
}
};
$.fn.sstvMessagePanel = function() {
if (!this.data('panel')) {
this.data('panel', new SstvMessagePanel(this));
}
return this.data('panel');
};
FaxMessagePanel = function(el) {
MessagePanel.call(this, el);
this.initClearTimer();
}
FaxMessagePanel.prototype = new MessagePanel();
FaxMessagePanel.prototype.supportsMessage = function(message) {
return message['mode'] === 'Fax';
};
FaxMessagePanel.prototype.render = function() {
$(this.el).append($(
'
' +
'
' +
'
Fax
' +
'
' +
'' +
'
'
));
};
FaxMessagePanel.prototype.pushMessage = function(msg) {
var $b = $(this.el).find('tbody');
if(msg.hasOwnProperty('message')) {
// Append a new debug message text
// See service log for debug output instead
// $b.append($('
' + msg.message + '
'));
// $b.scrollTop($b[0].scrollHeight);
}
else if(msg.width>0 && msg.height>0 && !msg.hasOwnProperty('line')) {
var f = msg.frequency>0? ' at ' + Math.floor(msg.frequency/1000) + 'kHz' : '';
var h = '