mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
236 lines
6.0 KiB
JavaScript
236 lines
6.0 KiB
JavaScript
// NanoUpdate handles data from the server and uses it to render templates
|
|
NanoUpdate = function ()
|
|
{
|
|
// _isInitialised is set to true when all of this ui's templates have been processed/rendered
|
|
var _isInitialised = false;
|
|
|
|
// the array of template names to use for this ui
|
|
var _templates = null;
|
|
// the data for this ui
|
|
var _data = null;
|
|
// new data which arrives before _isInitialised is true is stored here for processing later
|
|
var _earlyUpdateData = null;
|
|
|
|
// this is an array of callbacks which are called when new data arrives, before it is processed
|
|
var _beforeUpdateCallbacks = [];
|
|
// this is an array of callbacks which are called when new data arrives, before it is processed
|
|
var _afterUpdateCallbacks = [];
|
|
|
|
// _canClick is used to disable clicks for a short period after each click (to avoid mis-clicks)
|
|
var _canClick = true;
|
|
|
|
// the init function is called when the ui has loaded
|
|
// this function sets up the templates and base functionality
|
|
var init = function ()
|
|
{
|
|
$('#uiNoJavaScript').html('Loading...');
|
|
|
|
// this callback is triggered after new data is processed
|
|
// it updates the status/visibility icon and adds click event handling to buttons/links
|
|
NanoUpdate.addAfterUpdateCallback(function (updateData) {
|
|
var uiStatusClass;
|
|
if (updateData['ui']['status'] == 2)
|
|
{
|
|
uiStatusClass = 'icon24 uiStatusGood';
|
|
$('.linkActive').removeClass('inactive');
|
|
}
|
|
else if (updateData['ui']['status'] == 1)
|
|
{
|
|
uiStatusClass = 'icon24 uiStatusAverage';
|
|
$('.linkActive').addClass('inactive');
|
|
}
|
|
else
|
|
{
|
|
uiStatusClass = 'icon24 uiStatusBad'
|
|
$('.linkActive').addClass('inactive');
|
|
}
|
|
$('#uiStatusIcon').attr('class', uiStatusClass);
|
|
|
|
$('.linkActive').stopTime('linkPending');
|
|
$('.linkActive').removeClass('linkPending');
|
|
|
|
$('.linkActive').off('click');
|
|
$('.linkActive').on('click', function (event) {
|
|
event.preventDefault();
|
|
var href = $(this).data('href');
|
|
if (href != null && _canClick)
|
|
{
|
|
_canClick = false;
|
|
$('body').oneTime(300, 'enableClick', function () {
|
|
_canClick = true;
|
|
});
|
|
if (updateData['ui']['status'] == 2)
|
|
{
|
|
$(this).oneTime(300, 'linkPending', function () {
|
|
$(this).addClass('linkPending');
|
|
});
|
|
}
|
|
window.location.href = href;
|
|
}
|
|
});
|
|
});
|
|
|
|
// We store initialData and templateData in the body tag, it's as good a place as any
|
|
var body = $('body');
|
|
var templateData = body.data('templateData');
|
|
var initialData = body.data('initialData');
|
|
|
|
if (templateData == null || !initialData == null)
|
|
{
|
|
alert('Error: Initial data did not load correctly.');
|
|
}
|
|
|
|
// we count the number of templates for this ui so that we know when they've all been rendered
|
|
var templateCount = 0;
|
|
for (var key in templateData)
|
|
{
|
|
if (templateData.hasOwnProperty(key))
|
|
{
|
|
templateCount++;
|
|
}
|
|
}
|
|
|
|
if (!templateCount)
|
|
{
|
|
alert('ERROR: No templates listed!');
|
|
}
|
|
|
|
// load markup for each template and register it
|
|
for (var key in templateData)
|
|
{
|
|
if (templateData.hasOwnProperty(key))
|
|
{
|
|
$.when($.get(templateData[key]))
|
|
.done(function(templateMarkup) {
|
|
if (_templates == null)
|
|
{
|
|
_templates = {};
|
|
}
|
|
|
|
templateMarkup = templateMarkup.replace(/ +\) *\}\}/g, ')}}');
|
|
|
|
templateMarkup += '<div class="clearBoth"></div>'
|
|
|
|
try
|
|
{
|
|
_templates[key] = $.templates(key, templateMarkup);
|
|
|
|
templateCount--;
|
|
|
|
if (templateCount <= 0)
|
|
{
|
|
if (_earlyUpdateData !== null) // Newer data has already arrived, so update
|
|
{
|
|
renderTemplates(_earlyUpdateData);
|
|
}
|
|
else
|
|
{
|
|
renderTemplates(initialData);
|
|
}
|
|
_isInitialised = true;
|
|
$('#uiNoJavaScript').hide();
|
|
}
|
|
|
|
executeCallbacks(_afterUpdateCallbacks, _data);
|
|
}
|
|
catch(error)
|
|
{
|
|
alert('ERROR: An error occurred while loading the UI: ' + error.message);
|
|
return;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
// Receive update data from the server
|
|
var receiveUpdateData = function (jsonString)
|
|
{
|
|
var updateData;
|
|
try
|
|
{
|
|
// parse the JSON string from the server into a JSON object
|
|
updateData = jQuery.parseJSON(jsonString);
|
|
}
|
|
catch (error)
|
|
{
|
|
alert(error.Message);
|
|
return;
|
|
}
|
|
|
|
|
|
if (_isInitialised) // all templates have been registered, so render them
|
|
{
|
|
executeCallbacks(_beforeUpdateCallbacks, updateData);
|
|
|
|
renderTemplates(updateData);
|
|
|
|
executeCallbacks(_afterUpdateCallbacks, updateData);
|
|
}
|
|
else
|
|
{
|
|
_earlyUpdateData = updateData; // all templates have not been registered. We set _earlyUpdateData which will be applied after the template is loaded with the initial data
|
|
}
|
|
};
|
|
|
|
// This function renders the template with the latest data
|
|
// It has to be done recursively as each piece of data is observed individually and needs to be updated individually
|
|
var renderTemplates = function (data)
|
|
{
|
|
if (!_templates.hasOwnProperty("main"))
|
|
{
|
|
alert('Error: Main template not found.');
|
|
}
|
|
|
|
_data = data;
|
|
|
|
try
|
|
{
|
|
$("#mainTemplate").html(_templates["main"].render(_data));
|
|
}
|
|
catch(error)
|
|
{
|
|
alert('ERROR: An error occurred while rendering the UI: ' + error.message);
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Execute all callbacks in the callbacks array/object provided, updateData is passed to them for processing
|
|
var executeCallbacks = function (callbacks, updateData)
|
|
{
|
|
for (var index in callbacks)
|
|
{
|
|
callbacks[index].call(this, updateData);
|
|
}
|
|
|
|
return updateData;
|
|
};
|
|
|
|
return {
|
|
init: function ()
|
|
{
|
|
init();
|
|
},
|
|
isInitialised: function ()
|
|
{
|
|
return _isInitialised;
|
|
},
|
|
receiveUpdateData: function (jsonString)
|
|
{
|
|
receiveUpdateData(jsonString);
|
|
},
|
|
addBeforeUpdateCallback: function (callbackFunction)
|
|
{
|
|
_beforeUpdateCallbacks.push(callbackFunction);
|
|
},
|
|
addAfterUpdateCallback: function (callbackFunction)
|
|
{
|
|
_afterUpdateCallbacks.push(callbackFunction);
|
|
}
|
|
};
|
|
} ();
|
|
|
|
$(document).ready(function()
|
|
{
|
|
NanoUpdate.init();
|
|
}); |