Server Greeting Refactor (#1034)

Refactors the Server Greeting datum to do majority of the processing clientside. No longer will we be holding massive spans of text in memory, and looking over them for shits and giggles.
This commit is contained in:
skull132
2016-11-06 13:59:22 +02:00
committed by GitHub
parent dae995ba04
commit 0b6120c1ac
7 changed files with 167 additions and 113 deletions

View File

@@ -14,6 +14,8 @@
#define OUTDATED_MEMO 2
#define OUTDATED_NOTE 4
#define JS_SANITIZE(msg) list2params(list(json_encode(msg)))
/datum/server_greeting
// Hashes to figure out if we need to display the greeting message.
// These correspond to motd_hash and memo_hash on /datum/preferences for each client.
@@ -21,24 +23,19 @@
var/memo_hash = ""
// The stored strings of general subcomponents.
var/motd = ""
var/memo_list[] = list()
var/memo = ""
var/motd = "<center>No new announcements to showcase.</center>"
var/raw_data_user = ""
var/raw_data_staff = ""
// The near-final string to be displayed.
// Only one placeholder remains: <!--notifications-->.
var/user_data = ""
var/staff_data = ""
var/memo_list[] = list()
var/memo = "<center>No memos have been posted.</center>"
// Cached outdated information.
var/list/client_cache = list()
/datum/server_greeting/New()
..()
load_from_file()
prepare_data()
/*
* Populates variables from save file, and loads the raw HTML data.
* Needs to be called at least once for successful initialization.
@@ -52,51 +49,33 @@
if (F["memo"])
F["memo"] >> memo_list
raw_data_staff = file2text('html/templates/welcome_screen.html')
// This is a lazy way, but it disables the user from being able to see the memo button.
var/staff_button = "<li role=\"presentation\" id=\"memo-tab\"><a href=\"#memo\" aria-controls=\"memo\" role=\"tab\" data-toggle=\"tab\">Staff Memos</a></li>"
raw_data_user = replacetextEx(raw_data_staff, staff_button, "")
update_data()
/*
* Generates hashes, placeholders, and reparses var/memo.
* Then updates staff_data and user_data with the new contents.
* To be called after load_from_file or update_value.
* A helper to regenerate the hashes for all data fields.
* As well as to reparse the staff memo list.
* Separated for the sake of avoiding the duplication of code.
*/
/datum/server_greeting/proc/prepare_data()
if (!motd)
motd = "<center>No new announcements to showcase.</center>"
motd_hash = ""
else
/datum/server_greeting/proc/update_data()
if (motd)
motd_hash = md5(motd)
memo = ""
else
motd = initial(motd)
motd_hash = ""
if (memo_list.len)
memo = ""
for (var/ckey in memo_list)
var/data = {"
<p><b>[ckey]</b> wrote on [memo_list[ckey]["date"]]:<br>
[memo_list[ckey]["content"]]</p>
"}
var/data = {"<p><b>[ckey]</b> wrote on [memo_list[ckey]["date"]]:<br>
[memo_list[ckey]["content"]]</p>"}
memo += data
memo_hash = md5(memo)
else
memo = "<center>No memos have been posted.</center>"
memo = initial(memo)
memo_hash = ""
var/html_one = raw_data_staff
html_one = replacetextEx(html_one, "<!--motd-->", motd)
html_one = replacetextEx(html_one, "<!--memo-->", memo)
staff_data = html_one
var/html_two = raw_data_user
html_two = replacetextEx(html_two, "<!--motd-->", motd)
user_data = html_two
return
/*
* Helper to update the MoTD or memo contents.
* Args:
@@ -113,7 +92,6 @@
switch (change)
if ("motd")
motd = new_value
motd_hash = md5(new_value)
if ("memo_write")
memo_list[new_value[1]] = list("date" = time2text(world.realtime, "DD-MMM-YYYY"), "content" = new_value[2])
@@ -131,7 +109,7 @@
F["motd"] << motd
F["memo"] << memo_list
prepare_data()
update_data()
return 1
@@ -142,10 +120,13 @@
* Returns:
* - int
*/
/datum/server_greeting/proc/find_outdated_info(var/client/user)
/datum/server_greeting/proc/find_outdated_info(var/client/user, var/force_eval = 0)
if (!user || !user.prefs)
return 0
if (!force_eval && !isnull(client_cache[user]))
return client_cache[user]
var/outdated_info = 0
if (motd_hash && user.prefs.motd_hash != motd_hash)
@@ -157,53 +138,88 @@
if (user.prefs.notifications.len)
outdated_info |= OUTDATED_NOTE
client_cache[user] = outdated_info
return outdated_info
/*
* Composes the final message and displays it to the user.
* Also clears the user's notifications, should he have any.
* A proc used to open the server greeting window for a user.
* Args:
* - var/user client
* - var/outdated_info int
*/
/datum/server_greeting/proc/display_to_client(var/client/user, var/outdated_info = 0)
/datum/server_greeting/proc/display_to_client(var/client/user)
if (!user)
return
var/notifications = "<div class=\"row\"><div class=\"alert alert-info\">You do not have any notifications to show.</div></div>"
var/list/outdated_tabs = list()
user << browse('html/templates/welcome_screen.html', "window=greeting;size=640x500")
/*
* Sends data to the JS controllers used in the server greeting.
* Also updates the user's preferences, if any of the hashes were out of date.
* Args:
* - var/user client
* - var/outdated_info int
*/
/datum/server_greeting/proc/send_to_javascript(var/client/user)
if (!user)
return
// This is fine now, because it uses cached information.
var/outdated_info = server_greeting.find_outdated_info(user)
var/save_prefs = 0
var/list/data = list("div" = "", "content" = "", "update" = 1)
if (outdated_info & OUTDATED_NOTE)
outdated_tabs += "#note-tab"
user << output("#note-placeholder", "greeting.browser:RemoveElement")
data["div"] = "#note"
data["update"] = 1
notifications = ""
for (var/datum/client_notification/a in user.prefs.notifications)
notifications += a.get_html()
data["content"] = a.get_html()
user << output(JS_SANITIZE(data), "greeting.browser:AddContent")
if (!user.holder)
user << output("#memo-tab", "greeting.browser:RemoveElement")
else
if (outdated_info & OUTDATED_MEMO)
outdated_tabs += "#memo-tab"
data["update"] = 1
user.prefs.memo_hash = memo_hash
save_prefs = 1
else
data["update"] = 0
data["div"] = "#memo"
data["content"] = memo
user << output(JS_SANITIZE(data), "greeting.browser:AddContent")
if (outdated_info & OUTDATED_MOTD)
outdated_tabs += "#motd-tab"
data["update"] = 1
user.prefs.motd_hash = motd_hash
save_prefs = 1
else
data["update"] = 0
var/data = user_data
if (user.holder)
data = staff_data
data = replacetextEx(data, "<!--note-->", notifications)
if (outdated_tabs.len)
var/tab_string = json_encode(outdated_tabs)
data = replacetextEx(data, "var updated_tabs = \[\]", "var updated_tabs = [tab_string]")
user << browse(data, "window=welcome_screen;size=640x500")
data["div"] = "#motd"
data["content"] = motd
user << output(JS_SANITIZE(data), "greeting.browser:AddContent")
if (save_prefs)
user.prefs.handle_preferences_save(user)
/*
* Basically the Topic proc for the greeting datum.
*/
/datum/server_greeting/proc/handle_call(var/href_list, var/client/C)
if (!href_list || !href_list["command"] || !C)
return
switch (href_list["command"])
if ("request_data")
send_to_javascript(C)
#undef OUTDATED_NOTE
#undef OUTDATED_MEMO
#undef OUTDATED_MOTD

View File

@@ -55,8 +55,6 @@
cmd_admin_discord_pm(href_list["discord_msg"])
return
//Logs all hrefs
if(config && config.log_hrefs && href_logfile)
href_logfile << "<small>[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
@@ -178,6 +176,10 @@
var/DBQuery/query = dbcon.NewQuery("INSERT INTO ss13_stats_ie (ckey, IsIE, IsEdge, EdgeHtmlVersion, TrueVersion, ActingVersion, CompatibilityMode, DateUpdated) VALUES (_ckey, _IsIE, _IsEdge, _EdgeHtmlVersion, _TrueVersion, _ActingVersion, _CompatibilityMode, NOW()) ON DUPLICATE KEY UPDATE IsIE = VALUES(IsIe), IsEdge = VALUES(IsEdge), EdgeHtmlVersion = VALUES(EdgeHtmlVersion), TrueVersion = VALUES(TrueVersion), ActingVersion = VALUES(ActingVersion), CompatibilityMode = VALUES(CompatibilityMode), DateUpdated = NOW()")
query.Execute(data)
if ("greeting")
if (server_greeting)
server_greeting.handle_call(href_list, src)
return
// Antag contest shit
@@ -294,10 +296,9 @@
send_resources()
nanomanager.send_resources(src)
var/outdated_greeting_info = server_greeting.find_outdated_info(src)
if (outdated_greeting_info)
server_greeting.display_to_client(src, outdated_greeting_info)
// Server greeting shenanigans.
if (server_greeting.find_outdated_info(src, 1))
server_greeting.display_to_client(src)
// Check code/modules/admin/verbs/antag-ooc.dm for definition
add_aooc_if_necessary()
@@ -421,10 +422,7 @@
'html/images/talisman.png',
'html/bootstrap/css/bootstrap.min.css',
'html/bootstrap/js/bootstrap.min.js',
'html/bootstrap/js/html5shiv.min.js',
'html/bootstrap/js/respond.min.js',
'html/jquery/jquery-2.0.0.min.js',
'html/iestats/json2.min.js',
'html/iestats/ie-truth.min.js',
'icons/pda_icons/pda_atmos.png',
'icons/pda_icons/pda_back.png',
@@ -586,4 +584,7 @@
set name = "Open Greeting"
set category = "OOC"
server_greeting.display_to_client(src, server_greeting.find_outdated_info(src))
// Update the information just in case.
server_greeting.find_outdated_info(src, 1)
server_greeting.display_to_client(src)

View File

@@ -61,13 +61,13 @@
* Returns the HTML required to display this alert.
*/
/datum/client_notification/proc/get_html()
var/html = "<div class=\"row\">[note_wrapper[1]]\n"
var/html = "<div class=\"row\">[note_wrapper[1]]"
if (!persistent)
html += "<a href=\"#\" class=\"close\" data-dismiss=\"alert\" aria-label=\"close\">&times;</a>\n"
html += "<a href=\"#\" class=\"close\" data-dismiss=\"alert\" aria-label=\"close\">&times;</a>"
html += note_text
html += "\n[note_wrapper[2]]</div>"
html += "[note_wrapper[2]]</div>"
return html

View File

@@ -1,4 +0,0 @@
/**
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);

View File

@@ -1,5 +0,0 @@
/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
* */
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);

View File

@@ -1 +0,0 @@
"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(a){return a<10?"0"+a:a}function this_value(){return this.valueOf()}function quote(a){return rx_escapable.lastIndex=0,rx_escapable.test(a)?'"'+a.replace(rx_escapable,function(a){var b=meta[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,h,g=gap,i=b[a];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(a)),"function"==typeof rep&&(i=rep.call(b,a,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,h=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,c=0;c<f;c+=1)h[c]=str(c,i)||"null";return e=0===h.length?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&"object"==typeof rep)for(f=rep.length,c=0;c<f;c+=1)"string"==typeof rep[c]&&(d=rep[c],e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=0===h.length?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(a,b,c){var d;if(gap="",indent="","number"==typeof c)for(d=0;d<c;d+=1)indent+=" ";else"string"==typeof c&&(indent=c);if(rep=b,b&&"function"!=typeof b&&("object"!=typeof b||"number"!=typeof b.length))throw new Error("JSON.stringify");return str("",{"":a})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&"object"==typeof e)for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),void 0!==d?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();

View File

@@ -2,7 +2,7 @@
<html>
<head>
<title>Aurorastation Welcome Screen</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="X-UA-Compatible" content="IE=11">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap -->
<link href="bootstrap.min.css" rel="stylesheet" media="screen">
@@ -46,9 +46,9 @@
</ul>
</p>
</div>
<div role="tabpanel" class="tab-pane" id="motd"><!--motd--></div>
<div role="tabpanel" class="tab-pane" id="memo"><!--memo--></div>
<div role="tabpanel" class="tab-pane" id="note"><!--note--></div>
<div role="tabpanel" class="tab-pane" id="motd"><div class="row"></div></div>
<div role="tabpanel" class="tab-pane" id="memo"></div>
<div role="tabpanel" class="tab-pane" id="note"><div class="alert alert-info" id="note-placeholder">You do not have any notifications to show.</div></div>
</div>
</div>
</div>
@@ -56,28 +56,72 @@
<script src="jquery-2.0.0.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="html5shiv.min.js"></script>
<script src="respond.min.js"></script>
<script src="json2.min.js"></script>
<script src="ie-truth.min.js"></script>
<script>
<script type="text/javascript">
// IE statistics function.
function analyzeIe() {
var ieStats = IeVersion();
window.location = "?JSlink=logie&ie_data=" + JSON.stringify(ieStats);
if (ieStats._TrueVersion < 9) {
alert("It appears that you have an IE version lower than 9! Some of our menus no longer support this! Please look into updating.");
} else if (ieStats._TrueVersion < 11) {
alert("It appears that you have an IE version lower than 11! While this shouldn't pose any immediate issues, it may be worth looking to update.");
}
}
// Dynamic content entry controller.
function AddContent(data) {
var obj;
try {
obj = JSON.parse(data);
}
catch(err) {
return;
}
if (obj.length < 2) {
return;
}
gotReply = true;
$(obj.div).append($(obj.content));
if (obj.update == 1 && !$(obj.div + '-tab').hasClass('updated')) {
$(obj.div + '-tab').addClass('updated');
}
}
// Function to remove a tab. Specifically, the admin one.
function RemoveElement(el) {
$(el).remove();
}
var loopIter = 0;
var gotReply = false;
// This loop repeats itself 10 times as it attempts to fetch Topic information.
// It's here to prevent a full null-route by spam protection. It'll just query until it finds something.
function RequestLoop() {
setTimeout(function () {
loopIter++;
if (!gotReply) {
window.location = '?JSlink=greeting;command=request_data';
} else {
return;
}
if (loopIter < 10 && !gotReply) {
RequestLoop();
} else {
alert("The Greeting Window timed out. If this happens regularly, please submit a Github issue.");
}
}, 500)
}
// DOM ready function.
$(document).ready(function () {
// Deal with updating the tabs if any need an updated marker.
var updated_tabs = [];
if (updated_tabs.length > 0) {
var changes_needed = updated_tabs.length;
for (var i = 0; i < changes_needed; i++) {
$(updated_tabs[i]).addClass('updated');
}
}
// Handle tabs (mostly bootstrap).
$('#myTab a').click(function (e) {
e.preventDefault();
@@ -101,8 +145,11 @@
window.location = command;
});
// Get the browser stats.
// Call the IE analyzer and warn the user if they're horribly out of date.
analyzeIe();
// Tell the server that we're ready, and awaiting data.
RequestLoop();
});
</script>