2015-01-20 01:53:18 -05:00
|
|
|
var FFZ = window.FrankerFaceZ,
|
|
|
|
constants = require('./constants');
|
|
|
|
|
2015-02-08 02:01:09 -05:00
|
|
|
|
2015-07-31 17:44:20 -04:00
|
|
|
var sanitize_el = document.createElement('span'),
|
|
|
|
|
|
|
|
sanitize = function(msg) {
|
|
|
|
sanitize_el.textContent = msg;
|
|
|
|
return sanitize_el.innerHTML;
|
|
|
|
},
|
2015-10-17 18:05:44 -04:00
|
|
|
|
2015-10-27 14:25:13 -04:00
|
|
|
escape_regex = RegExp.escape || function(str) {
|
|
|
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
|
|
},
|
|
|
|
|
2015-07-31 17:44:20 -04:00
|
|
|
R_QUOTE = /"/g,
|
|
|
|
R_SQUOTE = /'/g,
|
|
|
|
R_AMP = /&/g,
|
|
|
|
R_LT = /</g,
|
|
|
|
R_GT = />/g,
|
2015-10-17 18:05:44 -04:00
|
|
|
|
|
|
|
DURATIONS = {},
|
|
|
|
|
2015-07-31 17:44:20 -04:00
|
|
|
quote_attr = function(msg) {
|
|
|
|
return msg.replace(R_AMP, "&").replace(R_QUOTE, """).replace(R_SQUOTE, "'").replace(R_LT, "<").replace(R_GT, ">");
|
|
|
|
},
|
2015-02-08 02:01:09 -05:00
|
|
|
|
2015-11-19 02:45:56 -05:00
|
|
|
HUMAN_NUMBERS = [
|
|
|
|
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
|
|
|
|
],
|
|
|
|
|
|
|
|
number_commas = function(x) {
|
|
|
|
var parts = x.toString().split(".");
|
|
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
|
|
return parts.join(".");
|
|
|
|
},
|
|
|
|
|
2015-06-10 18:46:04 -04:00
|
|
|
pluralize = function(value, singular, plural) {
|
|
|
|
plural = plural || 's';
|
|
|
|
singular = singular || '';
|
|
|
|
return value === 1 ? singular : plural;
|
|
|
|
},
|
|
|
|
|
2015-02-08 02:01:09 -05:00
|
|
|
place_string = function(num) {
|
|
|
|
if ( num == 1 ) return '1st';
|
|
|
|
else if ( num == 2 ) return '2nd';
|
|
|
|
else if ( num == 3 ) return '3rd';
|
|
|
|
else if ( num == null ) return '---';
|
|
|
|
return num + "th";
|
2015-02-10 01:34:23 -05:00
|
|
|
},
|
|
|
|
|
2015-03-15 21:24:22 -04:00
|
|
|
date_regex = /^(\d{4}|\+\d{6})(?:-?(\d{2})(?:-?(\d{2})(?:T(\d{2})(?::?(\d{2})(?::?(\d{2})(?:(?:\.|,)(\d{1,}))?)?)?(Z|([\-+])(\d{2})(?::?(\d{2}))?)?)?)?)?$/,
|
|
|
|
|
|
|
|
parse_date = function(str) {
|
2015-11-07 22:56:15 -05:00
|
|
|
if ( typeof str === "number" )
|
|
|
|
return new Date(str);
|
|
|
|
|
2015-03-15 21:24:22 -04:00
|
|
|
var parts = str.match(date_regex);
|
|
|
|
if ( ! parts )
|
|
|
|
return null;
|
|
|
|
|
2015-06-10 18:46:04 -04:00
|
|
|
parts[7] = (parts[7] && parts[7].length) ? parts[7].substr(0, 3) : 0;
|
|
|
|
|
|
|
|
var unix = Date.UTC(parts[1], parts[2] - 1, parts[3], parts[4], parts[5], parts[6], parts[7]);
|
2015-03-15 21:24:22 -04:00
|
|
|
|
|
|
|
// Check Offset
|
|
|
|
if ( parts[9] ) {
|
|
|
|
var offset = (parts[9] == "-" ? 1 : -1) * 60000 * (60*parts[10] + 1*parts[11]);
|
|
|
|
unix += offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Date(unix);
|
2015-07-04 17:06:36 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
|
2015-11-19 02:45:56 -05:00
|
|
|
uncompressEmotes = function(value) {
|
|
|
|
var output = {},
|
|
|
|
emotes = value.split("/"),
|
|
|
|
i = emotes.length;
|
|
|
|
|
|
|
|
while(i--) {
|
|
|
|
var parts = emotes[i].split(":");
|
|
|
|
if ( parts.length !== 3 )
|
|
|
|
return {};
|
|
|
|
|
|
|
|
var emote_id = parts[0],
|
|
|
|
length = parseInt(parts[1]),
|
|
|
|
positions = parts[2].split(","),
|
|
|
|
indices = output[emote_id] = output[emote_id] || [];
|
|
|
|
|
|
|
|
for(var j=0, jl = positions.length; j < jl; j++) {
|
|
|
|
var start = parseInt(positions[j]),
|
|
|
|
end = start + length;
|
|
|
|
|
|
|
|
for(var x=0, xl = indices.length; x < xl; x++) {
|
|
|
|
if ( start < indices[x][0] )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
indices.splice(x, 0, [start, end]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
},
|
|
|
|
|
2015-07-04 17:06:36 -04:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
// This code borrowed from the twemoji project, with tweaks.
|
|
|
|
UFE0Fg = /\uFE0F/g,
|
|
|
|
U200D = String.fromCharCode(0x200D),
|
|
|
|
|
2015-07-04 17:06:36 -04:00
|
|
|
EMOJI_CODEPOINTS = {},
|
2016-03-23 19:28:22 -04:00
|
|
|
emoji_to_codepoint = function(surrogates, sep) {
|
|
|
|
if ( EMOJI_CODEPOINTS[surrogates] && EMOJI_CODEPOINTS[surrogates][sep] )
|
|
|
|
return EMOJI_CODEPOINTS[surrogates][sep];
|
|
|
|
|
|
|
|
var input = surrogates.indexOf(U200D) === -1 ? surrogates.replace(UFE0Fg, '') : surrogates,
|
|
|
|
out = [],
|
|
|
|
c = 0, p = 0, i = 0;
|
|
|
|
|
|
|
|
while (i < input.length) {
|
|
|
|
c = input.charCodeAt(i++);
|
|
|
|
if ( p ) {
|
|
|
|
out.push((0x10000 + ((p - 0xD800) << 10) + (c - 0xDC00)).toString(16));
|
|
|
|
p = 0;
|
|
|
|
} else if ( 0xD800 <= c && c <= 0xDBFF )
|
|
|
|
p = c;
|
|
|
|
else
|
|
|
|
out.push(c.toString(16));
|
|
|
|
}
|
|
|
|
|
|
|
|
var retval = EMOJI_CODEPOINTS[surrogates] = out.join('-');
|
|
|
|
return retval;
|
|
|
|
},
|
2015-07-04 17:06:36 -04:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
codepoint_to_emoji = function(codepoint) {
|
|
|
|
var code = typeof codepoint === 'string' ? parseInt(codepoint, 16) : codepoint;
|
|
|
|
if ( code < 0x10000 )
|
|
|
|
return String.fromCharCode(code);
|
|
|
|
code -= 0x10000;
|
|
|
|
return String.fromCharCode(
|
|
|
|
0xD800 + (code >> 10),
|
|
|
|
0xDC00 + (code & 0x3FF)
|
|
|
|
)
|
|
|
|
},
|
2015-07-04 17:06:36 -04:00
|
|
|
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
// Twitch Emote Helpers
|
2015-11-14 23:52:49 -05:00
|
|
|
|
|
|
|
SRCSETS = {},
|
|
|
|
build_srcset = function(id) {
|
|
|
|
if ( SRCSETS[id] )
|
|
|
|
return SRCSETS[id];
|
2016-03-23 19:28:22 -04:00
|
|
|
var out = SRCSETS[id] = constants.TWITCH_BASE + id + "/1.0 1x, " + constants.TWITCH_BASE + id + "/2.0 2x";
|
2015-11-14 23:52:49 -05:00
|
|
|
return out;
|
|
|
|
},
|
|
|
|
|
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
// Twitch API
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
api_call = function(method, url, data, options, token) {
|
|
|
|
options = options || {};
|
|
|
|
var headers = options.headers = options.headers || {};
|
|
|
|
headers['Client-ID'] = constants.CLIENT_ID;
|
|
|
|
if ( token )
|
|
|
|
headers.Authorization = 'OAuth ' + token;
|
|
|
|
return Twitch.api[method].call(this, url, data, options);
|
|
|
|
},
|
2015-11-14 23:52:49 -05:00
|
|
|
|
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
// Dialogs
|
|
|
|
show_modal = function(contents, on_close, width) {
|
|
|
|
var container = document.createElement('div'),
|
|
|
|
subwindow = document.createElement('div'),
|
|
|
|
card = document.createElement('div'),
|
|
|
|
close_button = document.createElement('div'),
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
closer = function() { container.parentElement.removeChild(container) };
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
container.className = 'twitch_subwindow_container';
|
|
|
|
container.id = 'ffz-modal-container';
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
subwindow.className = 'twitch_subwindow ffz-subwindow';
|
|
|
|
subwindow.style.width = '100%';
|
|
|
|
subwindow.style.maxWidth = (width||420) + 'px';
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
card.className = 'card';
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
close_button.className = 'modal-close-button';
|
|
|
|
close_button.innerHTML = constants.CLOSE;
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
close_button.addEventListener('click', function() {
|
|
|
|
closer();
|
|
|
|
if ( on_close )
|
|
|
|
on_close(false);
|
|
|
|
});
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
container.appendChild(subwindow);
|
|
|
|
subwindow.appendChild(card);
|
|
|
|
subwindow.appendChild(close_button);
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
card.appendChild(contents);
|
|
|
|
|
|
|
|
var el = document.querySelector('app-main');
|
|
|
|
|
|
|
|
if ( el )
|
|
|
|
el.parentElement.insertBefore(container, el.nextSibling);
|
|
|
|
else
|
|
|
|
document.body.appendChild(container);
|
|
|
|
|
|
|
|
return closer;
|
|
|
|
},
|
2015-11-14 23:52:49 -05:00
|
|
|
|
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
ember_lookup = function(thing) {
|
|
|
|
if ( ! window.App )
|
|
|
|
return;
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 20:23:04 -04:00
|
|
|
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.lookup )
|
2016-03-23 19:28:22 -04:00
|
|
|
return App.__deprecatedInstance__.registry.lookup(thing);
|
|
|
|
if ( App.__container__ && App.__container__.lookup )
|
|
|
|
return App.__container__.lookup(thing);
|
|
|
|
};
|
2015-11-14 23:52:49 -05:00
|
|
|
|
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
module.exports = FFZ.utils = {
|
|
|
|
ember_views: function() {
|
|
|
|
return ember_lookup('-view-registry:main') || {};
|
|
|
|
},
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
ember_lookup: ember_lookup,
|
2015-02-08 02:01:09 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
ember_resolve: function(thing) {
|
|
|
|
if ( ! window.App )
|
|
|
|
return;
|
|
|
|
|
2016-03-23 20:23:04 -04:00
|
|
|
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.resolve )
|
2016-03-23 19:28:22 -04:00
|
|
|
return App.__deprecatedInstance__.registry.resolve(thing);
|
|
|
|
if ( App.__container__ && App.__container__.resolve )
|
|
|
|
return App.__container__.resolve(thing);
|
|
|
|
},
|
2015-02-10 01:34:23 -05:00
|
|
|
|
2015-11-14 23:52:49 -05:00
|
|
|
build_srcset: build_srcset,
|
2016-03-23 19:28:22 -04:00
|
|
|
/*build_tooltip: build_tooltip,
|
|
|
|
load_emote_data: load_emote_data,*/
|
|
|
|
|
|
|
|
api: {
|
|
|
|
del: function(u,d,o,t) { return api_call('del', u,d,o,t); },
|
|
|
|
get: function(u,d,o,t) { return api_call('get', u,d,o,t); },
|
|
|
|
post: function(u,d,o,t) { return api_call('post', u,d,o,t); },
|
|
|
|
put: function(u,d,o,t) { return api_call('put', u,d,o,t); }
|
|
|
|
},
|
|
|
|
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
show_modal: show_modal,
|
|
|
|
prompt: function(title, description, old_value, callback, width) {
|
|
|
|
var contents = document.createElement('div'),
|
|
|
|
heading = document.createElement('div'),
|
|
|
|
form = document.createElement('form'),
|
|
|
|
input, close_btn, okay_btn;
|
|
|
|
|
|
|
|
contents.className = 'text-content';
|
|
|
|
heading.className = 'content-header';
|
|
|
|
heading.innerHTML = '<h4>' + title + '</h4>';
|
|
|
|
|
|
|
|
form.innerHTML = '<div class="item">' + (description ? '<p>' + description + '</p>' : '') + '<input type="text"></div><div class="buttons"><a class="js-subwindow-close button"><span>Cancel</span></a><button class="button primary" type="submit"><span>OK</span></button></div>';
|
|
|
|
|
|
|
|
contents.appendChild(heading);
|
|
|
|
contents.appendChild(form);
|
|
|
|
|
|
|
|
input = form.querySelector('input');
|
|
|
|
close_btn = form.querySelector('.js-subwindow-close');
|
|
|
|
okay_btn = form.querySelector('.button.primary');
|
|
|
|
|
|
|
|
if ( old_value !== undefined )
|
|
|
|
input.value = old_value;
|
|
|
|
|
|
|
|
var closer,
|
|
|
|
cb = function(success) {
|
|
|
|
closer();
|
|
|
|
if ( ! callback )
|
|
|
|
return;
|
|
|
|
|
|
|
|
callback(success ? input.value : null);
|
|
|
|
};
|
|
|
|
|
|
|
|
closer = show_modal(contents, cb, width);
|
|
|
|
|
|
|
|
form.addEventListener('submit', function(e) { e.preventDefault(); cb(true); return false });
|
|
|
|
okay_btn.addEventListener('click', function(e) { e.preventDefault(); cb(true); return false });
|
|
|
|
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
last_minute: function() {
|
|
|
|
var now = new Date();
|
|
|
|
if ( now.getSeconds() >= 30 )
|
|
|
|
now.setMinutes(now.getMinutes()+1);
|
|
|
|
|
|
|
|
now.setSeconds(0);
|
|
|
|
now.setMilliseconds(0);
|
|
|
|
return now.getTime();
|
|
|
|
},
|
|
|
|
|
|
|
|
maybe_chart: function(series, point, render, force) {
|
|
|
|
var len = series.data.length;
|
|
|
|
if ( force || point.y !== null || (len > 0 && series.data[len-1].y !== null) ) {
|
|
|
|
series.addPoint(point, render);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
2015-11-14 23:52:49 -05:00
|
|
|
|
2015-01-20 01:53:18 -05:00
|
|
|
update_css: function(element, id, css) {
|
|
|
|
var all = element.innerHTML,
|
|
|
|
start = "/*BEGIN " + id + "*/",
|
|
|
|
end = "/*END " + id + "*/",
|
|
|
|
s_ind = all.indexOf(start),
|
|
|
|
e_ind = all.indexOf(end),
|
|
|
|
found = s_ind !== -1 && e_ind !== -1 && e_ind > s_ind;
|
|
|
|
|
|
|
|
if ( !found && !css )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( found )
|
|
|
|
all = all.substr(0, s_ind) + all.substr(e_ind + end.length);
|
|
|
|
|
|
|
|
if ( css )
|
|
|
|
all += start + css + end;
|
|
|
|
|
|
|
|
element.innerHTML = all;
|
|
|
|
},
|
|
|
|
|
2015-07-04 17:06:36 -04:00
|
|
|
|
2015-11-14 23:52:49 -05:00
|
|
|
tooltip_placement: function(margin, prefer) {
|
|
|
|
return function() {
|
2016-03-23 19:28:22 -04:00
|
|
|
var pref = prefer;
|
|
|
|
if ( typeof pref === "function" )
|
|
|
|
pref = pref.call(this);
|
|
|
|
|
|
|
|
var dir = {ns: pref[0], ew: (pref.length > 1 ? pref[1] : false)},
|
2015-11-14 23:52:49 -05:00
|
|
|
$this = $(this),
|
|
|
|
half_width = $this.width() / 2,
|
|
|
|
half_height = $this.height() / 2,
|
|
|
|
boundTop = $(document).scrollTop() + half_height + (margin*2),
|
|
|
|
boundLeft = $(document).scrollLeft() + half_width + margin;
|
|
|
|
|
|
|
|
if ($this.offset().top < boundTop) dir.ns = 'n';
|
|
|
|
if ($this.offset().left < boundLeft) dir.ew = 'w';
|
|
|
|
if ($(window).width() + $(document).scrollLeft() - ($this.offset().left + half_width) < margin) dir.ew = 'e';
|
|
|
|
if ($(window).height() + $(document).scrollTop() - ($this.offset().top + half_height) < (2*margin)) dir.ns = 's';
|
|
|
|
|
|
|
|
return dir.ns + (dir.ew ? dir.ew : '');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2015-11-19 02:45:56 -05:00
|
|
|
uncompressEmotes: uncompressEmotes,
|
2015-07-04 17:06:36 -04:00
|
|
|
|
|
|
|
emoji_to_codepoint: emoji_to_codepoint,
|
2016-03-23 19:28:22 -04:00
|
|
|
codepoint_to_emoji: codepoint_to_emoji,
|
2015-07-04 17:06:36 -04:00
|
|
|
|
2015-03-15 21:24:22 -04:00
|
|
|
parse_date: parse_date,
|
|
|
|
|
2015-11-19 02:45:56 -05:00
|
|
|
number_commas: number_commas,
|
2015-02-08 02:01:09 -05:00
|
|
|
|
|
|
|
place_string: place_string,
|
2015-02-10 01:34:23 -05:00
|
|
|
|
2015-02-08 02:01:09 -05:00
|
|
|
placement: function(entrant) {
|
|
|
|
if ( entrant.state == "forfeit" ) return "Forfeit";
|
|
|
|
else if ( entrant.state == "dq" ) return "DQed";
|
|
|
|
else if ( entrant.place ) return place_string(entrant.place);
|
|
|
|
return "";
|
|
|
|
},
|
|
|
|
|
2015-07-31 17:44:20 -04:00
|
|
|
sanitize: sanitize,
|
|
|
|
quote_attr: quote_attr,
|
2015-02-08 02:01:09 -05:00
|
|
|
|
2015-05-17 19:02:57 -04:00
|
|
|
date_string: function(date) {
|
|
|
|
return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
|
|
|
|
},
|
|
|
|
|
2015-06-10 18:46:04 -04:00
|
|
|
pluralize: pluralize,
|
|
|
|
|
2015-11-19 02:45:56 -05:00
|
|
|
human_number: function(value) {
|
|
|
|
return HUMAN_NUMBERS[value] || number_commas(value);
|
|
|
|
},
|
|
|
|
|
2015-07-13 21:52:44 -04:00
|
|
|
human_time: function(elapsed, factor) {
|
|
|
|
factor = factor || 1;
|
2015-06-10 18:46:04 -04:00
|
|
|
elapsed = Math.floor(elapsed);
|
|
|
|
|
2015-07-13 21:52:44 -04:00
|
|
|
var years = Math.floor((elapsed*factor) / 31536000) / factor;
|
|
|
|
if ( years >= 1 )
|
2015-06-10 18:46:04 -04:00
|
|
|
return years + ' year' + pluralize(years);
|
|
|
|
|
|
|
|
var days = Math.floor((elapsed %= 31536000) / 86400);
|
2015-07-13 21:52:44 -04:00
|
|
|
if ( days >= 1 )
|
2015-06-10 18:46:04 -04:00
|
|
|
return days + ' day' + pluralize(days);
|
|
|
|
|
|
|
|
var hours = Math.floor((elapsed %= 86400) / 3600);
|
2015-07-13 21:52:44 -04:00
|
|
|
if ( hours >= 1 )
|
2015-06-10 18:46:04 -04:00
|
|
|
return hours + ' hour' + pluralize(hours);
|
|
|
|
|
|
|
|
var minutes = Math.floor((elapsed %= 3600) / 60);
|
2015-07-13 21:52:44 -04:00
|
|
|
if ( minutes >= 1 )
|
2015-06-10 18:46:04 -04:00
|
|
|
return minutes + ' minute' + pluralize(minutes);
|
|
|
|
|
|
|
|
var seconds = elapsed % 60;
|
2015-07-13 21:52:44 -04:00
|
|
|
if ( seconds >= 1 )
|
2015-06-10 18:46:04 -04:00
|
|
|
return seconds + ' second' + pluralize(seconds);
|
|
|
|
|
|
|
|
return 'less than a second';
|
|
|
|
},
|
|
|
|
|
2015-10-17 18:05:44 -04:00
|
|
|
time_to_string: function(elapsed, separate_days, days_only, no_hours, no_seconds) {
|
2015-02-08 02:01:09 -05:00
|
|
|
var seconds = elapsed % 60,
|
|
|
|
minutes = Math.floor(elapsed / 60),
|
2015-05-17 19:02:57 -04:00
|
|
|
hours = Math.floor(minutes / 60),
|
2016-03-23 19:28:22 -04:00
|
|
|
days = null;
|
2015-02-08 02:01:09 -05:00
|
|
|
|
|
|
|
minutes = minutes % 60;
|
|
|
|
|
2015-05-17 19:02:57 -04:00
|
|
|
if ( separate_days ) {
|
|
|
|
days = Math.floor(hours / 24);
|
|
|
|
hours = hours % 24;
|
|
|
|
if ( days_only && days > 0 )
|
|
|
|
return days + " days";
|
|
|
|
|
|
|
|
days = ( days > 0 ) ? days + " days, " : "";
|
|
|
|
}
|
|
|
|
|
2016-03-23 19:28:22 -04:00
|
|
|
return (days||'') + ((!no_hours || days || hours) ? ((days && hours < 10 ? "0" : "") + hours + ':') : '') + (minutes < 10 ? "0" : "") + minutes + (no_seconds ? "" : (":" + (seconds < 10 ? "0" : "") + seconds));
|
2015-10-17 18:05:44 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
duration_string: function(val) {
|
|
|
|
if ( val === 1 )
|
|
|
|
return 'Purge';
|
|
|
|
|
|
|
|
if ( DURATIONS[val] )
|
|
|
|
return DURATIONS[val];
|
|
|
|
|
|
|
|
var weeks, days, hours, minutes, seconds;
|
|
|
|
|
|
|
|
weeks = Math.floor(val / 604800);
|
|
|
|
seconds = val % 604800;
|
|
|
|
|
|
|
|
days = Math.floor(seconds / 86400);
|
|
|
|
seconds %= 86400;
|
|
|
|
|
|
|
|
hours = Math.floor(seconds / 3600);
|
|
|
|
seconds %= 3600;
|
|
|
|
|
|
|
|
minutes = Math.floor(seconds / 60);
|
|
|
|
seconds %= 60;
|
|
|
|
|
|
|
|
var out = DURATIONS[val] = (weeks ? weeks + 'w' : '') + ((days || (weeks && (hours || minutes || seconds))) ? days + 'd' : '') + ((hours || ((weeks || days) && (minutes || seconds))) ? hours + 'h' : '') + ((minutes || ((weeks || days || hours) && seconds)) ? minutes + 'm' : '') + (seconds ? seconds + 's' : '');
|
|
|
|
return out;
|
2015-07-13 21:52:44 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
format_unread: function(count) {
|
|
|
|
if ( count < 1 )
|
|
|
|
return "";
|
|
|
|
|
|
|
|
else if ( count >= 99 )
|
|
|
|
return "99+";
|
|
|
|
|
|
|
|
return "" + count;
|
2015-10-27 14:25:13 -04:00
|
|
|
},
|
|
|
|
|
2016-05-06 02:23:12 -04:00
|
|
|
format_size: function(bits) {
|
|
|
|
if(Math.abs(bits) < 1024)
|
|
|
|
return bits + ' b';
|
|
|
|
|
|
|
|
var units = ['Kb','Mb','Gb','Tb','Pb','Eb','Zb','Yb'],
|
|
|
|
u = -1;
|
|
|
|
do {
|
|
|
|
bits /= 1024;
|
|
|
|
++u;
|
|
|
|
} while(Math.abs(bits) >= 1024 && u < units.length - 1);
|
|
|
|
return bits.toFixed(1) + ' ' + units[u];
|
|
|
|
},
|
|
|
|
|
2016-04-16 17:45:25 -04:00
|
|
|
escape_regex: escape_regex,
|
|
|
|
|
|
|
|
createElement: function(tag, className, content) {
|
|
|
|
var out = document.createElement(tag);
|
|
|
|
if ( className )
|
|
|
|
out.className = className;
|
|
|
|
if ( content )
|
|
|
|
out.innerHTML = content;
|
|
|
|
return out;
|
2016-05-12 00:11:50 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
toggle_cls: function(cls) {
|
2016-05-12 16:06:26 -04:00
|
|
|
return function(val) {
|
|
|
|
document.body.classList.toggle(cls, val);
|
|
|
|
}
|
2016-04-16 17:45:25 -04:00
|
|
|
}
|
2015-01-12 17:58:07 -05:00
|
|
|
}
|