mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 05:15:54 +00:00
Merge branch 'master' into socketdev
This commit is contained in:
commit
2fd1817627
30 changed files with 898 additions and 139 deletions
6
dark.css
6
dark.css
|
@ -117,6 +117,12 @@
|
||||||
border-right:1px solid rgb(0,0,0)!important;
|
border-right:1px solid rgb(0,0,0)!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark.ffz-portrait div#left_col .column,
|
||||||
|
.ffz-dark.ffz-portrait div#main_col {
|
||||||
|
border-right: none !important;
|
||||||
|
border-bottom: 1px solid rgb(0,0,0) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* stream title */
|
/* stream title */
|
||||||
.ffz-dark span.real_title{
|
.ffz-dark span.real_title{
|
||||||
|
|
|
@ -430,38 +430,38 @@ FFZ.prototype._legacy_add_donors = function() {
|
||||||
this._legacy_load_donors();
|
this._legacy_load_donors();
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.prototype._legacy_load_bots = function(tries) {
|
FFZ.prototype._legacy_load_bots = function(callback, tries) {
|
||||||
jQuery.ajax(constants.SERVER + "script/bots.txt", {context: this})
|
jQuery.ajax(constants.SERVER + "script/bots.txt", {context: this})
|
||||||
.done(function(data) {
|
.done(function(data) {
|
||||||
this._legacy_parse_badges(data, 0, 2, "Bot (By: {})");
|
this._legacy_parse_badges(callback, data, 0, 2, "Bot (By: {})");
|
||||||
|
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
if ( data.status == 404 )
|
if ( data.status == 404 )
|
||||||
return;
|
return typeof callback === "function" && callback(false, 0);
|
||||||
|
|
||||||
tries = (tries || 0) + 1;
|
tries = (tries || 0) + 1;
|
||||||
if ( tries < 10 )
|
if ( tries < 10 )
|
||||||
this._legacy_load_bots(tries);
|
this._legacy_load_bots(callback, tries);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.prototype._legacy_load_donors = function(tries) {
|
FFZ.prototype._legacy_load_donors = function(callback, tries) {
|
||||||
jQuery.ajax(constants.SERVER + "script/donors.txt", {context: this})
|
jQuery.ajax(constants.SERVER + "script/donors.txt", {context: this})
|
||||||
.done(function(data) {
|
.done(function(data) {
|
||||||
this._legacy_parse_badges(data, 1, 1);
|
this._legacy_parse_badges(callback, data, 1, 1);
|
||||||
|
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
if ( data.status == 404 )
|
if ( data.status == 404 )
|
||||||
return;
|
return typeof callback === "function" && callback(false, 0);
|
||||||
|
|
||||||
tries = (tries || 0) + 1;
|
tries = (tries || 0) + 1;
|
||||||
if ( tries < 10 )
|
if ( tries < 10 )
|
||||||
return this._legacy_load_donors(tries);
|
return this._legacy_load_donors(callback, tries);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype._legacy_parse_badges = function(data, slot, badge_id, title_template) {
|
FFZ.prototype._legacy_parse_badges = function(callback, data, slot, badge_id, title_template) {
|
||||||
var title = this.badges[badge_id].title,
|
var title = this.badges[badge_id].title,
|
||||||
count = 0;
|
count = 0;
|
||||||
ds = null;
|
ds = null;
|
||||||
|
@ -491,4 +491,8 @@ FFZ.prototype._legacy_parse_badges = function(data, slot, badge_id, title_templa
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log('Added "' + title + '" badge to ' + utils.number_commas(count) + " users.");
|
this.log('Added "' + title + '" badge to ' + utils.number_commas(count) + " users.");
|
||||||
|
if ( callback )
|
||||||
|
callback(true, count);
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
var FFZ = window.FrankerFaceZ;
|
var FFZ = window.FrankerFaceZ,
|
||||||
|
utils = require('./utils');
|
||||||
|
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
|
@ -15,6 +16,59 @@ FFZ.ffz_commands.log = function(room, args) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Data Reload
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
FFZ.ffz_commands.reload = function(room, args) {
|
||||||
|
var f = this,
|
||||||
|
promises = [];
|
||||||
|
|
||||||
|
// Badge Information
|
||||||
|
promises.push(new Promise(function(done, fail) {
|
||||||
|
f._legacy_load_bots(function(success, count) {
|
||||||
|
done(count || 0);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
promises.push(new Promise(function(done, fail) {
|
||||||
|
f._legacy_load_donors(function(success, count) {
|
||||||
|
done(count || 0);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
// Emote Sets
|
||||||
|
for(var set_id in this.emote_sets) {
|
||||||
|
var es = this.emote_sets[set_id];
|
||||||
|
if ( es.hasOwnProperty('source_ext') )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
promises.push(new Promise(function(done, fail) {
|
||||||
|
f.load_set(set_id, done);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Do it!
|
||||||
|
Promise.all(promises).then(function(results) {
|
||||||
|
var success = 0,
|
||||||
|
bots = results[0],
|
||||||
|
donors = results[1],
|
||||||
|
total = results.length - 2;
|
||||||
|
|
||||||
|
if ( results.length > 2 ) {
|
||||||
|
for(var i=2; i < results.length; i++) {
|
||||||
|
if ( results[i] )
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.room_message(room, "Loaded " + utils.number_commas(bots) + " new bot badge" + utils.pluralize(bots) + " and " + utils.number_commas(donors) + " new donor badge" + utils.pluralize(donors) + ". Successfully reloaded " + utils.number_commas(success) + " of " + utils.number_commas(total) + " emoticon set" + utils.pluralize(total) + ".");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Mass Moderation
|
// Mass Moderation
|
||||||
// -----------------
|
// -----------------
|
||||||
|
@ -75,7 +129,7 @@ FFZ.ffz_commands.massmod.help = "Usage: /ffz massmod <list, of, users>\nBroadcas
|
||||||
|
|
||||||
/*FFZ.ffz_commands.massunban = function(room, args) {
|
/*FFZ.ffz_commands.massunban = function(room, args) {
|
||||||
args = args.join(" ").trim();
|
args = args.join(" ").trim();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}*/
|
}*/
|
|
@ -27,6 +27,7 @@ module.exports = {
|
||||||
"\\:-?[\\\\/]": ":-/",
|
"\\:-?[\\\\/]": ":-/",
|
||||||
"\\;-?\\)": ";-)",
|
"\\;-?\\)": ";-)",
|
||||||
"R-?\\)": "R-)",
|
"R-?\\)": "R-)",
|
||||||
|
"[oO](_|\\.)[oO]": "O.o",
|
||||||
"[o|O](_|\\.)[o|O]": "O.o",
|
"[o|O](_|\\.)[o|O]": "O.o",
|
||||||
"\\:-?D": ":-D",
|
"\\:-?D": ":-D",
|
||||||
"\\:-?(o|O)": ":-O",
|
"\\:-?(o|O)": ":-O",
|
||||||
|
@ -34,6 +35,8 @@ module.exports = {
|
||||||
"Gr(a|e)yFace": "GrayFace"
|
"Gr(a|e)yFace": "GrayFace"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
EMOTE_MIRROR_BASE: SERVER + "twitch-emote-mirror/",
|
||||||
|
|
||||||
EMOTE_REPLACEMENT_BASE: SERVER + "script/replacements/",
|
EMOTE_REPLACEMENT_BASE: SERVER + "script/replacements/",
|
||||||
EMOTE_REPLACEMENTS: {
|
EMOTE_REPLACEMENTS: {
|
||||||
15: "15-JKanStyle.png",
|
15: "15-JKanStyle.png",
|
||||||
|
|
|
@ -456,10 +456,9 @@ FFZ.prototype._modify_cindex = function(view) {
|
||||||
el = stat_el && stat_el.querySelector('span'),
|
el = stat_el && stat_el.querySelector('span'),
|
||||||
|
|
||||||
player_cont = f.players && f.players[channel_id],
|
player_cont = f.players && f.players[channel_id],
|
||||||
player = player_cont && player_cont.player,
|
player = player_cont && player_cont.ffz_player,
|
||||||
stats = player && player.stats;
|
stats = player && player.stats;
|
||||||
|
|
||||||
|
|
||||||
if ( ! container || ! f.settings.player_stats || ! stats || stats.hlsLatencyBroadcaster === 'NaN' || stats.hlsLatencyBroadcaster === NaN ) {
|
if ( ! container || ! f.settings.player_stats || ! stats || stats.hlsLatencyBroadcaster === 'NaN' || stats.hlsLatencyBroadcaster === NaN ) {
|
||||||
if ( stat_el )
|
if ( stat_el )
|
||||||
stat_el.parentElement.removeChild(stat_el);
|
stat_el.parentElement.removeChild(stat_el);
|
||||||
|
@ -509,7 +508,7 @@ FFZ.prototype._modify_cindex = function(view) {
|
||||||
el = stat_el && stat_el.querySelector('span'),
|
el = stat_el && stat_el.querySelector('span'),
|
||||||
|
|
||||||
player_cont = f.players && f.players[hosted_id],
|
player_cont = f.players && f.players[hosted_id],
|
||||||
player = player_cont && player_cont.player,
|
player = player_cont && player_cont.ffz_player,
|
||||||
stats = player && player.stats;
|
stats = player && player.stats;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,7 @@ FFZ.prototype.setup_chatview = function() {
|
||||||
this.blurRoom();
|
this.blurRoom();
|
||||||
|
|
||||||
// Don't destroy it if it's the user's room.
|
// Don't destroy it if it's the user's room.
|
||||||
if ( room && user && user.login === room_id )
|
if ( room && user && user.login !== room_id )
|
||||||
room.destroy();
|
room.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,6 @@ FFZ.prototype._modify_directory_video = function(dir) {
|
||||||
dir.reopen({
|
dir.reopen({
|
||||||
didInsertElement: function() {
|
didInsertElement: function() {
|
||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
f.log("New Video View", this);
|
|
||||||
window.v = this;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,48 @@ var FFZ = window.FrankerFaceZ;
|
||||||
// Settings
|
// Settings
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
||||||
|
FFZ.settings_info.portrait_mode = {
|
||||||
|
type: "select",
|
||||||
|
options: {
|
||||||
|
0: "Disabled",
|
||||||
|
1: "Automatic (Use Window Aspect Ratio)",
|
||||||
|
2: "Always On",
|
||||||
|
3: "Automatic (Video Below)",
|
||||||
|
4: "Always On (Video Below)"
|
||||||
|
},
|
||||||
|
|
||||||
|
value: 0,
|
||||||
|
|
||||||
|
process_value: function(val) {
|
||||||
|
if ( val === false )
|
||||||
|
return 0;
|
||||||
|
if ( val === true )
|
||||||
|
return 1;
|
||||||
|
if ( typeof val === "string" )
|
||||||
|
return parseInt(val) || 0;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
category: "Appearance",
|
||||||
|
no_mobile: true,
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
name: "Portrait Mode (Chat Below Video)",
|
||||||
|
help: "Display the right sidebar beneath (or above) the video player for viewing in portrait orientations.",
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
if ( this.has_bttv )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var Layout = window.App && App.__container__.lookup('controller:layout');
|
||||||
|
if ( ! Layout )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Layout.set('rawPortraitMode', val);
|
||||||
|
this._fix_menu_position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FFZ.settings_info.swap_sidebars = {
|
FFZ.settings_info.swap_sidebars = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
@ -94,6 +136,7 @@ FFZ.prototype.setup_layout = function() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
document.body.classList.toggle("ffz-sidebar-swap", this.settings.swap_sidebars);
|
document.body.classList.toggle("ffz-sidebar-swap", this.settings.swap_sidebars);
|
||||||
|
document.body.classList.toggle("ffz-portrait", this.settings.portrait_mode);
|
||||||
|
|
||||||
this.log("Creating layout style element.");
|
this.log("Creating layout style element.");
|
||||||
var s = this._layout_style = document.createElement('style');
|
var s = this._layout_style = document.createElement('style');
|
||||||
|
@ -109,20 +152,47 @@ FFZ.prototype.setup_layout = function() {
|
||||||
|
|
||||||
Layout.reopen({
|
Layout.reopen({
|
||||||
rightColumnWidth: 340,
|
rightColumnWidth: 340,
|
||||||
|
rawPortraitMode: 0,
|
||||||
|
|
||||||
|
portraitVideoBelow: false,
|
||||||
|
|
||||||
|
portraitMode: function() {
|
||||||
|
var raw = this.get("rawPortraitMode");
|
||||||
|
this.set('portraitVideoBelow', raw === 3 || raw === 4);
|
||||||
|
|
||||||
|
if ( raw === 0 )
|
||||||
|
return false;
|
||||||
|
if ( raw === 2 || raw === 4 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Not sure if I should be adding some other value to offset the ratio. What feels best?
|
||||||
|
var ratio = this.get("windowWidth") / (this.get("windowHeight") + 120 + 60);
|
||||||
|
return ratio < 1;
|
||||||
|
|
||||||
|
}.property("rawPortraitMode", "windowHeight", "windowWidth"),
|
||||||
|
|
||||||
isTooSmallForRightColumn: function() {
|
isTooSmallForRightColumn: function() {
|
||||||
return this.get("windowWidth") < (1090 - this.get('rightColumnWidth'))
|
if ( ! f.has_bttv && this.get('portraitMode') ) {
|
||||||
}.property("windowWidth", "rightColumnWidth"),
|
var size = this.get('playerSize'),
|
||||||
|
height = size[1];
|
||||||
|
|
||||||
|
// Make sure we have at least a bit of room for the chat.
|
||||||
|
return this.get("windowHeight") < (height + 120 + 60 + 100);
|
||||||
|
|
||||||
|
} else
|
||||||
|
return this.get("windowWidth") < (1090 - this.get('rightColumnWidth'))
|
||||||
|
|
||||||
|
}.property("windowWidth", "rightColumnWidth", "playerSize", "windowHeight"),
|
||||||
|
|
||||||
contentWidth: function() {
|
contentWidth: function() {
|
||||||
var left_width = this.get("isLeftColumnClosed") ? 50 : 240,
|
var left_width = this.get("isLeftColumnClosed") ? 50 : 240,
|
||||||
right_width = this.get("isRightColumnClosed") ? 0 : this.get("rightColumnWidth");
|
right_width = ! f.has_bttv && this.get('portraitMode') ? 0 : this.get("isRightColumnClosed") ? 0 : this.get("rightColumnWidth");
|
||||||
|
|
||||||
return this.get("windowWidth") - left_width - right_width - 60;
|
return this.get("windowWidth") - left_width - right_width - 60;
|
||||||
|
|
||||||
}.property("windowWidth", "isRightColumnClosed", "isLeftColumnClosed", "rightColumnWidth"),
|
}.property("windowWidth", "portraitMode", "isRightColumnClosed", "isLeftColumnClosed", "rightColumnWidth"),
|
||||||
|
|
||||||
playerStyle: function() {
|
playerSize: function() {
|
||||||
var h = this.get('windowHeight'),
|
var h = this.get('windowHeight'),
|
||||||
c = this.get('PLAYER_CONTROLS_HEIGHT'),
|
c = this.get('PLAYER_CONTROLS_HEIGHT'),
|
||||||
r = this.get('contentWidth'),
|
r = this.get('contentWidth'),
|
||||||
|
@ -135,8 +205,17 @@ FFZ.prototype.setup_layout = function() {
|
||||||
o = Math.floor(Math.min(i, d)),
|
o = Math.floor(Math.min(i, d)),
|
||||||
s = Math.floor(Math.min(i, c));
|
s = Math.floor(Math.min(i, c));
|
||||||
|
|
||||||
return "<style>.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + l + "px !important;height:" + o + "px !important} .dynamic-target-player,.dynamic-target-player object, .dynamic-target-player video{width:" + l + "px !important;height:" + s + "px !important}</style><style>.dynamic-player .player object{width:100% !important; height:100% !important}</style>";
|
return [l, o, s];
|
||||||
}.property("contentWidth", "windowHeight", "PLAYER_CONTROLS_HEIGHT"),
|
}.property("contentWidth", "windowHeight", "portraitMode", "PLAYER_CONTROLS_HEIGHT"),
|
||||||
|
|
||||||
|
playerStyle: function() {
|
||||||
|
var size = this.get('playerSize'),
|
||||||
|
width = size[0],
|
||||||
|
height = size[1],
|
||||||
|
host_height = size[2];
|
||||||
|
|
||||||
|
return "<style>.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .dynamic-target-player,.dynamic-target-player object, .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object{width:100% !important; height:100% !important}</style>";
|
||||||
|
}.property("playerSize"),
|
||||||
|
|
||||||
/*ffzUpdateWidth: _.throttle(function() {
|
/*ffzUpdateWidth: _.throttle(function() {
|
||||||
var rc = document.querySelector('#right_close');
|
var rc = document.querySelector('#right_close');
|
||||||
|
@ -161,11 +240,70 @@ FFZ.prototype.setup_layout = function() {
|
||||||
}, 200),*/
|
}, 200),*/
|
||||||
|
|
||||||
ffzUpdateCss: function() {
|
ffzUpdateCss: function() {
|
||||||
var width = this.get('rightColumnWidth');
|
// TODO: Fix this mess of duplicate code.
|
||||||
|
var out = '';
|
||||||
|
|
||||||
f._layout_style.innerHTML = '#main_col.expandRight #right_close { left: none !important; } #right_col { width: ' + width + 'px; } body:not(.ffz-sidebar-swap) #main_col:not(.expandRight) { margin-right: ' + width + 'px; } body.ffz-sidebar-swap #main_col:not(.expandRight) { margin-left: ' + width + 'px; }';
|
if ( ! f.has_bttv ) {
|
||||||
|
if ( this.get('portraitMode') ) {
|
||||||
|
var size = this.get('playerSize'),
|
||||||
|
height = size[1],
|
||||||
|
top = height + 120 + 60;
|
||||||
|
|
||||||
}.observes("rightColumnWidth"),
|
if ( this.get('portraitVideoBelow') ) {
|
||||||
|
var wh = this.get("windowHeight"),
|
||||||
|
mch = wh - top;
|
||||||
|
|
||||||
|
out = (this.get('isRightColumnClosed') ? '' : 'body[data-current-path^="user."] #left_col, ') +
|
||||||
|
'body[data-current-path^="user."]:not(.ffz-sidebar-swap) #main_col:not(.expandRight) { margin-right: 0 !important; top: ' + mch + 'px; height: ' + top + 'px; }' +
|
||||||
|
'body[data-current-path^="user."].ffz-sidebar-swap #main_col:not(.expandRight) { margin-left: 0 !important; top: ' + mch + 'px; height: ' + top + 'px; }' +
|
||||||
|
'body[data-current-path^="user."] #right_col { width: 100%; height: ' + mch + 'px; left: 0; }';
|
||||||
|
} else
|
||||||
|
out = (this.get('isRightColumnClosed') ? '' : 'body[data-current-path^="user."] #left_col, ') +
|
||||||
|
'body[data-current-path^="user."]:not(.ffz-sidebar-swap) #main_col:not(.expandRight) { margin-right: 0 !important; height: ' + top + 'px; }' +
|
||||||
|
'body[data-current-path^="user."].ffz-sidebar-swap #main_col:not(.expandRight) { margin-left: 0 !important; height: ' + top + 'px; }' +
|
||||||
|
'body[data-current-path^="user."] #right_col { width: 100%; top: ' + top + 'px; left: 0; }';
|
||||||
|
|
||||||
|
// Theatre Mode Portrait
|
||||||
|
if ( true ) { //this.get('theaterPortraitMode') ) {
|
||||||
|
// Recalculate the player height, not including the title or anything special.
|
||||||
|
var width = this.get("windowWidth"),
|
||||||
|
wh = this.get("windowHeight"),
|
||||||
|
height = (9 * width / 16);
|
||||||
|
|
||||||
|
height = Math.floor(Math.max(wh * 0.1, Math.min(wh - 300, height)));
|
||||||
|
|
||||||
|
if ( this.get('portraitVideoBelow') ) {
|
||||||
|
var mch = this.get("windowHeight") - height;
|
||||||
|
|
||||||
|
out += (this.get('isRightColumnClosed') ? '' : 'body[data-current-path^="user."] .app-main.theatre #left_col, ') +
|
||||||
|
'body[data-current-path^="user."]:not(.ffz-sidebar-swap) .app-main.theatre #main_col:not(.expandRight) { margin-right: 0 !important; top: ' + mch + 'px; height: ' + height + 'px; }' +
|
||||||
|
'body[data-current-path^="user."].ffz-sidebar-swap .app-main.theatre #main_col:not(.expandRight) { margin-left: 0 !important; top: ' + mch + 'px; height: ' + height + 'px; }' +
|
||||||
|
'body[data-current-path^="user."] .app-main.theatre #right_col { width: 100%; height: ' + mch + 'px; left: 0; }';
|
||||||
|
} else
|
||||||
|
out += 'body[data-current-path^="user."]:not(.ffz-sidebar-swap) .app-main.theatre #main_col:not(.expandRight) { margin-right: 0 !important; height: ' + height + 'px; }' +
|
||||||
|
'body[data-current-path^="user."].ffz-sidebar-swap .app-main.theatre #main_col:not(.expandRight) { margin-left: 0 !important; height: ' + height + 'px; }' +
|
||||||
|
'body[data-current-path^="user."] .app-main.theatre #right_col { width: 100%; top: ' + height + 'px; left: 0; }';
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
var width = this.get('rightColumnWidth');
|
||||||
|
|
||||||
|
out = '#main_col.expandRight #right_close { left: none !important; }' +
|
||||||
|
'#right_col { width: ' + width + 'px; }' +
|
||||||
|
'body:not(.ffz-sidebar-swap) #main_col:not(.expandRight) { margin-right: ' + width + 'px; }' +
|
||||||
|
'body.ffz-sidebar-swap #main_col:not(.expandRight) { margin-left: ' + width + 'px; }';
|
||||||
|
}
|
||||||
|
|
||||||
|
f._layout_style.innerHTML = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
}.observes("isRightColumnClosed", "playerSize", "rightColumnWidth", "portraitMode", "windowHeight", "windowWidth"),
|
||||||
|
|
||||||
|
ffzUpdatePortraitCSS: function() {
|
||||||
|
var portrait = this.get("portraitMode");
|
||||||
|
document.body.classList.toggle("ffz-portrait", ! f.has_bttv && portrait);
|
||||||
|
|
||||||
|
}.observes("portraitMode"),
|
||||||
|
|
||||||
ffzFixTabs: function() {
|
ffzFixTabs: function() {
|
||||||
if ( f.settings.group_tabs && f._chatv && f._chatv._ffz_tabs ) {
|
if ( f.settings.group_tabs && f._chatv && f._chatv._ffz_tabs ) {
|
||||||
|
@ -173,7 +311,7 @@ FFZ.prototype.setup_layout = function() {
|
||||||
f._chatv && f._chatv.$('.chat-room').css('top', f._chatv._ffz_tabs.offsetHeight + "px");
|
f._chatv && f._chatv.$('.chat-room').css('top', f._chatv._ffz_tabs.offsetHeight + "px");
|
||||||
},0);
|
},0);
|
||||||
}
|
}
|
||||||
}.observes("isRightColumnClosed", "rightColumnWidth")
|
}.observes("isRightColumnClosed", "rightColumnWidth", "portraitMode", "playerSize")
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -191,5 +329,9 @@ FFZ.prototype.setup_layout = function() {
|
||||||
|
|
||||||
// Force the layout to update.
|
// Force the layout to update.
|
||||||
Layout.set('rightColumnWidth', this.settings.right_column_width);
|
Layout.set('rightColumnWidth', this.settings.right_column_width);
|
||||||
|
Layout.set('rawPortraitMode', this.settings.portrait_mode);
|
||||||
|
|
||||||
|
// Force re-calculation of everything.
|
||||||
Ember.propertyDidChange(Layout, 'contentWidth');
|
Ember.propertyDidChange(Layout, 'contentWidth');
|
||||||
|
Ember.propertyDidChange(Layout, 'windowHeight');
|
||||||
}
|
}
|
|
@ -666,7 +666,22 @@ FFZ.prototype._modify_line = function(component) {
|
||||||
window.open("https://twitchemotes.com/emote/" + eid);
|
window.open("https://twitchemotes.com/emote/" + eid);
|
||||||
else {
|
else {
|
||||||
eid = e.target.getAttribute("data-ffz-emote");
|
eid = e.target.getAttribute("data-ffz-emote");
|
||||||
window.open("https://www.frankerfacez.com/emoticons/" + eid);
|
var es = e.target.getAttribute("data-ffz-set"),
|
||||||
|
set = es && f.emote_sets[es],
|
||||||
|
url;
|
||||||
|
|
||||||
|
if ( ! set )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( set.hasOwnProperty('source_ext') ) {
|
||||||
|
var api = f._apis[set.source_ext];
|
||||||
|
if ( api && api.emote_url_generator )
|
||||||
|
url = api.emote_url_generator(set.source_id, eid);
|
||||||
|
} else
|
||||||
|
url = "https://www.frankerfacez.com/emoticons/" + eid;
|
||||||
|
|
||||||
|
if ( url )
|
||||||
|
window.open(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -448,6 +448,10 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
is_mod = controller.get('cardInfo.isModeratorOrHigher'),
|
is_mod = controller.get('cardInfo.isModeratorOrHigher'),
|
||||||
|
|
||||||
|
chat = window.App && App.__container__.lookup('controller:chat'),
|
||||||
|
user = f.get_user(),
|
||||||
|
is_broadcaster = user && chat && chat.get('currentRoom.id') === user.login,
|
||||||
|
|
||||||
user_id = controller.get('cardInfo.user.id'),
|
user_id = controller.get('cardInfo.user.id'),
|
||||||
alias = f.aliases[user_id];
|
alias = f.aliases[user_id];
|
||||||
|
|
||||||
|
@ -633,9 +637,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
// More Fixing Other Buttons
|
// More Fixing Other Buttons
|
||||||
var op_btn = el.querySelector('button.mod');
|
var op_btn = el.querySelector('button.mod');
|
||||||
if ( op_btn ) {
|
if ( op_btn ) {
|
||||||
var is_owner = controller.get('cardInfo.isChannelOwner'),
|
var can_op = is_broadcaster || (user && user.is_admin) || (user && user.is_staff);
|
||||||
user = ffz.get_user();
|
|
||||||
can_op = is_owner || (user && user.is_admin) || (user && user.is_staff);
|
|
||||||
|
|
||||||
if ( ! can_op )
|
if ( ! can_op )
|
||||||
op_btn.parentElement.removeChild(op_btn);
|
op_btn.parentElement.removeChild(op_btn);
|
||||||
|
|
|
@ -84,7 +84,9 @@ FFZ.prototype.setup_player = function() {
|
||||||
try {
|
try {
|
||||||
this._modify_player(view);
|
this._modify_player(view);
|
||||||
view.ffzInit();
|
view.ffzInit();
|
||||||
if ( view.get('player') )
|
|
||||||
|
var tp2 = window.require("web-client/components/twitch-player2");
|
||||||
|
if ( tp2 && tp2.getPlayer && tp2.getPlayer() )
|
||||||
view.ffzPostPlayer();
|
view.ffzPostPlayer();
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
@ -150,13 +152,18 @@ FFZ.prototype._modify_player = function(player) {
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzPostPlayer: function() {
|
ffzPostPlayer: function() {
|
||||||
var player = this.get('player');
|
var player = this.get('ffz_player') || this.get('player');
|
||||||
if ( ! player )
|
if ( ! player ) {
|
||||||
return;
|
var tp2 = window.require("web-client/components/twitch-player2");
|
||||||
|
if ( ! tp2 || ! tp2.getPlayer )
|
||||||
|
return;
|
||||||
|
|
||||||
// Subscribe to the qualities event.
|
player = tp2.getPlayer();
|
||||||
//player.addEventListener('qualitieschange', this.ffzQualitiesUpdated.bind(this));
|
if ( ! player )
|
||||||
//this.ffzQualitiesUpdated();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('ffz_player', player);
|
||||||
|
|
||||||
// Only set up the stats hooks if we need stats.
|
// Only set up the stats hooks if we need stats.
|
||||||
if ( ! player.getVideo() )
|
if ( ! player.getVideo() )
|
||||||
|
@ -167,7 +174,7 @@ FFZ.prototype._modify_player = function(player) {
|
||||||
if ( this.get('ffzStatsInitialized') )
|
if ( this.get('ffzStatsInitialized') )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var player = this.get('player');
|
var player = this.get('ffz_player');
|
||||||
if ( ! player )
|
if ( ! player )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -175,7 +182,13 @@ FFZ.prototype._modify_player = function(player) {
|
||||||
|
|
||||||
// Make it so stats can no longer be disabled if we want them.
|
// Make it so stats can no longer be disabled if we want them.
|
||||||
player.ffzSetStatsEnabled = player.setStatsEnabled;
|
player.ffzSetStatsEnabled = player.setStatsEnabled;
|
||||||
player.ffz_stats = player.getStatsEnabled();
|
try {
|
||||||
|
player.ffz_stats = player.getStatsEnabled();
|
||||||
|
} catch(err) {
|
||||||
|
// Assume stats are off.
|
||||||
|
f.log("player ffzInitStats: getStatsEnabled still doesn't work: " + err);
|
||||||
|
player.ffz_stats = false;
|
||||||
|
}
|
||||||
|
|
||||||
var t = this;
|
var t = this;
|
||||||
|
|
||||||
|
@ -208,7 +221,7 @@ FFZ.prototype._modify_player = function(player) {
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzSetQuality: function(q) {
|
ffzSetQuality: function(q) {
|
||||||
var player = this.get('player');
|
var player = this.get('ffz_player');
|
||||||
if ( ! player )
|
if ( ! player )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -222,7 +235,7 @@ FFZ.prototype._modify_player = function(player) {
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzGetQualities: function() {
|
ffzGetQualities: function() {
|
||||||
var player = this.get('player');
|
var player = this.get('ffz_player');
|
||||||
if ( ! player )
|
if ( ! player )
|
||||||
return [];
|
return [];
|
||||||
return player.getQualities();
|
return player.getQualities();
|
||||||
|
|
|
@ -567,7 +567,7 @@ FFZ.prototype.add_room = function(id, room) {
|
||||||
this.log("Adding Room: " + id);
|
this.log("Adding Room: " + id);
|
||||||
|
|
||||||
// Create a basic data table for this room.
|
// Create a basic data table for this room.
|
||||||
var data = this.rooms[id] = {id: id, room: room, menu_sets: [], sets: [], css: null, needs_history: false};
|
var data = this.rooms[id] = {id: id, room: room, sets: [], ext_sets: [], css: null, needs_history: false};
|
||||||
|
|
||||||
if ( this.follow_sets && this.follow_sets[id] ) {
|
if ( this.follow_sets && this.follow_sets[id] ) {
|
||||||
data.extra_sets = this.follow_sets[id];
|
data.extra_sets = this.follow_sets[id];
|
||||||
|
@ -602,8 +602,14 @@ FFZ.prototype.add_room = function(id, room) {
|
||||||
// Why don't we set the scrollback length, too?
|
// Why don't we set the scrollback length, too?
|
||||||
room.set('messageBufferSize', this.settings.scrollback_length + ((this._roomv && !this._roomv.get('stuckToBottom') && this._roomv.get('controller.model.id') === id) ? 150 : 0));
|
room.set('messageBufferSize', this.settings.scrollback_length + ((this._roomv && !this._roomv.get('stuckToBottom') && this._roomv.get('controller.model.id') === id) ? 150 : 0));
|
||||||
|
|
||||||
// For now, we use the legacy function to grab the .css file.
|
// Load the room's data from the API.
|
||||||
this.load_room(id);
|
this.load_room(id);
|
||||||
|
|
||||||
|
// Announce this room to any extension callback functions.
|
||||||
|
for(var api_id in this._apis) {
|
||||||
|
var api = this._apis[api_id];
|
||||||
|
api._room_callbacks(id, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,22 @@ var FFZ = window.FrankerFaceZ;
|
||||||
|
|
||||||
FFZ.prototype.setup_router = function() {
|
FFZ.prototype.setup_router = function() {
|
||||||
this.log("Hooking the Ember router.");
|
this.log("Hooking the Ember router.");
|
||||||
|
if ( ! window.App )
|
||||||
|
return;
|
||||||
|
|
||||||
var f = this;
|
var f = this,
|
||||||
App.__container__.lookup('router:main').reopen({
|
Router = App.__container__.lookup('router:main');
|
||||||
ffzTransition: function() {
|
|
||||||
try {
|
if ( Router )
|
||||||
f.track_page();
|
Router.reopen({
|
||||||
} catch(err) {
|
ffzTransition: function() {
|
||||||
f.error("ffzTransition: " + err);
|
try {
|
||||||
}
|
document.body.setAttribute('data-current-path', App.get('currentPath'));
|
||||||
}.on('didTransition')
|
} catch(err) {
|
||||||
});
|
f.error("ffzTransition: " + err);
|
||||||
|
}
|
||||||
|
}.on('didTransition')
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.setAttribute('data-current-path', App.get('currentPath'));
|
||||||
}
|
}
|
|
@ -1,6 +1,20 @@
|
||||||
var FFZ = window.FrankerFaceZ;
|
var FFZ = window.FrankerFaceZ;
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// Settings
|
||||||
|
// --------------------
|
||||||
|
|
||||||
|
FFZ.settings_info.sort_viewers = {
|
||||||
|
type: "boolean",
|
||||||
|
value: true,
|
||||||
|
|
||||||
|
category: "Chat Appearance",
|
||||||
|
name: "Sort Viewer List",
|
||||||
|
help: "Make sure the viewer list is alphabetically sorted and place the Broadcaster in their own category."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
// Initialization
|
// Initialization
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@ -19,6 +33,9 @@ FFZ.prototype._modify_viewers = function(controller) {
|
||||||
controller.reopen({
|
controller.reopen({
|
||||||
lines: function() {
|
lines: function() {
|
||||||
var viewers = this._super();
|
var viewers = this._super();
|
||||||
|
if ( ! f.settings.sort_viewers )
|
||||||
|
return viewers;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var categories = [],
|
var categories = [],
|
||||||
data = {},
|
data = {},
|
||||||
|
|
|
@ -5,7 +5,7 @@ var FFZ = window.FrankerFaceZ,
|
||||||
utils = require('./utils'),
|
utils = require('./utils'),
|
||||||
|
|
||||||
|
|
||||||
check_margins = function(margins, height) {
|
/*check_margins = function(margins, height) {
|
||||||
var mlist = margins.split(/ +/);
|
var mlist = margins.split(/ +/);
|
||||||
if ( mlist.length != 2 )
|
if ( mlist.length != 2 )
|
||||||
return margins;
|
return margins;
|
||||||
|
@ -36,19 +36,17 @@ var FFZ = window.FrankerFaceZ,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ".ffz-emote-" + emote.id + ' { background-image: url("' + emote.urls[1] + '"); height: ' + emote.height + "px; width: " + emote.width + "px; margin: " + margin + (srcset ? '; ' + srcset : '') + (emote.css ? "; " + emote.css : "") + "}\n";
|
return ".ffz-emote-" + emote.id + ' { background-image: url("' + emote.urls[1] + '"); height: ' + emote.height + "px; width: " + emote.width + "px; margin: " + margin + (srcset ? '; ' + srcset : '') + (emote.css ? "; " + emote.css : "") + "}\n";
|
||||||
},
|
},*/
|
||||||
|
|
||||||
|
|
||||||
build_new_css = function(emote) {
|
build_css = function(emote) {
|
||||||
if ( ! emote.margins && ! emote.css )
|
if ( ! emote.margins && ! emote.css )
|
||||||
return build_legacy_css(emote);
|
return ""; //build_legacy_css(emote);
|
||||||
|
|
||||||
return build_legacy_css(emote) + 'img[src="' + emote.urls[1] + '"] { ' + (emote.margins ? "margin: " + emote.margins + ";" : "") + (emote.css || "") + " }\n";
|
return /*build_legacy_css(emote) +*/ 'img[src="' + emote.urls[1] + '"] { ' + (emote.margins ? "margin: " + emote.margins + ";" : "") + (emote.css || "") + " }\n";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
build_css = build_new_css,
|
|
||||||
|
|
||||||
from_code_point = function(cp) {
|
from_code_point = function(cp) {
|
||||||
var code = typeof cp === "string" ? parseInt(cp, 16) : cp;
|
var code = typeof cp === "string" ? parseInt(cp, 16) : cp;
|
||||||
if ( code < 0x10000)
|
if ( code < 0x10000)
|
||||||
|
@ -94,6 +92,27 @@ FFZ.prototype.setup_emoticons = function() {
|
||||||
|
|
||||||
this.log("Watching Twitch emoticon parser to ensure it loads.");
|
this.log("Watching Twitch emoticon parser to ensure it loads.");
|
||||||
this._twitch_emote_check = setTimeout(this.check_twitch_emotes.bind(this), 10000);
|
this._twitch_emote_check = setTimeout(this.check_twitch_emotes.bind(this), 10000);
|
||||||
|
|
||||||
|
|
||||||
|
if ( this._apis ) {
|
||||||
|
for(var api_id in this._apis) {
|
||||||
|
var api = this._apis[api_id];
|
||||||
|
for(var es_id in api.emote_sets)
|
||||||
|
this.emote_sets[es_id] = api.emote_sets[es_id];
|
||||||
|
|
||||||
|
for(var i=0; i < api.global_sets.length; i++) {
|
||||||
|
var es_id = api.global_sets[i];
|
||||||
|
if ( this.global_sets.indexOf(es_id) === -1 )
|
||||||
|
this.global_sets.push(es_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i < api.default_sets.length; i++) {
|
||||||
|
var es_id = api.default_sets[i];
|
||||||
|
if ( this.default_sets.indexOf(es_id) === -1 )
|
||||||
|
this.default_sets.push(es_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,7 +192,7 @@ FFZ.prototype.getEmotes = function(user_id, room_id) {
|
||||||
var user = this.users && this.users[user_id],
|
var user = this.users && this.users[user_id],
|
||||||
room = this.rooms && this.rooms[room_id];
|
room = this.rooms && this.rooms[room_id];
|
||||||
|
|
||||||
return _.union(user && user.sets || [], room && room.set && [room.set] || [], room && room.extra_sets || [], this.default_sets);
|
return _.union(user && user.sets || [], room && room.set && [room.set] || [], room && room.extra_sets || [], room && room.ext_sets || [], this.default_sets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,9 +224,10 @@ FFZ.prototype._emote_tooltip = function(emote) {
|
||||||
|
|
||||||
var set = this.emote_sets[emote.set_id],
|
var set = this.emote_sets[emote.set_id],
|
||||||
owner = emote.owner,
|
owner = emote.owner,
|
||||||
title = set && set.title || "Global";
|
title = set && set.title || "Global",
|
||||||
|
source = set && set.source || "FFZ";
|
||||||
|
|
||||||
emote._tooltip = "Emoticon: " + (emote.hidden ? "???" : emote.name) + "\nFFZ " + title + (owner ? "\nBy: " + owner.display_name : "");
|
emote._tooltip = "Emoticon: " + (emote.hidden ? "???" : emote.name) + "\n" + source + " " + title + (owner ? "\nBy: " + owner.display_name : "");
|
||||||
return emote._tooltip;
|
return emote._tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +359,12 @@ FFZ.prototype.unload_set = function(set_id) {
|
||||||
|
|
||||||
utils.update_css(this._emote_style, set_id, null);
|
utils.update_css(this._emote_style, set_id, null);
|
||||||
delete this.emote_sets[set_id];
|
delete this.emote_sets[set_id];
|
||||||
|
|
||||||
|
if ( set.hasOwnProperty('source_ext') ) {
|
||||||
|
var api = this._apis[set.source_ext];
|
||||||
|
if ( api && api.emote_sets && api.emote_sets[set_id] )
|
||||||
|
api.emote_sets[set_id] = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,7 +390,7 @@ FFZ.prototype._load_set_json = function(set_id, callback, data) {
|
||||||
for(var i=0; i < ems.length; i++) {
|
for(var i=0; i < ems.length; i++) {
|
||||||
var emote = ems[i];
|
var emote = ems[i];
|
||||||
|
|
||||||
emote.klass = "ffz-emote-" + emote.id;
|
//emote.klass = "ffz-emote-" + emote.id;
|
||||||
emote.set_id = set_id;
|
emote.set_id = set_id;
|
||||||
|
|
||||||
emote.srcSet = emote.urls[1] + " 1x";
|
emote.srcSet = emote.urls[1] + " 1x";
|
||||||
|
@ -374,9 +400,9 @@ FFZ.prototype._load_set_json = function(set_id, callback, data) {
|
||||||
emote.srcSet += ", " + emote.urls[4] + " 4x";
|
emote.srcSet += ", " + emote.urls[4] + " 4x";
|
||||||
|
|
||||||
if ( emote.name[emote.name.length-1] === "!" )
|
if ( emote.name[emote.name.length-1] === "!" )
|
||||||
emote.regex = new RegExp("(^|\\W|\\b)(" + emote.name + ")(?=\\W|$)", "g");
|
emote.regex = new RegExp("(^|\\W|\\b)(" + utils.escape_regex(emote.name) + ")(?=\\W|$)", "g");
|
||||||
else
|
else
|
||||||
emote.regex = new RegExp("(^|\\W|\\b)(" + emote.name + ")\\b", "g");
|
emote.regex = new RegExp("(^|\\W|\\b)(" + utils.escape_regex(emote.name) + ")\\b", "g");
|
||||||
|
|
||||||
output_css += build_css(emote);
|
output_css += build_css(emote);
|
||||||
data.count++;
|
data.count++;
|
||||||
|
|
401
src/ext/api.js
Normal file
401
src/ext/api.js
Normal file
|
@ -0,0 +1,401 @@
|
||||||
|
var FFZ = window.FrankerFaceZ,
|
||||||
|
utils = require('../utils'),
|
||||||
|
|
||||||
|
|
||||||
|
build_css = function(emote) {
|
||||||
|
if ( ! emote.margins && ! emote.css )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return 'img[src="' + emote.urls[1] + '"]{' + (emote.margins ? 'margin:' + emote.margins + ';' : '') + (emote.css || "") + '}'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// API Constructor
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
var API = FFZ.API = function(instance, name, icon) {
|
||||||
|
this.ffz = instance || FFZ.get();
|
||||||
|
|
||||||
|
// Check for a known API!
|
||||||
|
if ( name ) {
|
||||||
|
for(var id in this.ffz._known_apis) {
|
||||||
|
if ( this.ffz._known_apis[id] === name ) {
|
||||||
|
this.id = id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! this.id ) {
|
||||||
|
var i = 0;
|
||||||
|
while( ! this.id ) {
|
||||||
|
if ( ! this.ffz._known_apis.hasOwnProperty(i) ) {
|
||||||
|
this.id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( name ) {
|
||||||
|
this.ffz._known_apis[this.id] = name;
|
||||||
|
localStorage.ffz_known_apis = JSON.stringify(this.ffz._known_apis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.ffz._apis[this.id] = this;
|
||||||
|
|
||||||
|
this.emote_sets = {};
|
||||||
|
this.global_sets = [];
|
||||||
|
this.default_sets = [];
|
||||||
|
|
||||||
|
this.on_room_callbacks = [];
|
||||||
|
|
||||||
|
this.name = name || ("Extension#" + this.id);
|
||||||
|
this.icon = icon || null;
|
||||||
|
|
||||||
|
this.ffz.log('Registered New Extension #' + this.id + ': ' + this.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.prototype.api = function(name, icon) {
|
||||||
|
// Load the known APIs list.
|
||||||
|
if ( ! this._known_apis ) {
|
||||||
|
this._known_apis = {};
|
||||||
|
if ( localStorage.hasOwnProperty('ffz_known_apis') )
|
||||||
|
try {
|
||||||
|
this._known_apis = JSON.parse(localStorage.ffz_known_apis);
|
||||||
|
} catch(err) {
|
||||||
|
this.log("Error loading Known APIs: " + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new API(this, name, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.log = function(msg, data, to_json, log_json) {
|
||||||
|
this.ffz.log('Ext "' + this.name + '": ' + msg, data, to_json, log_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Set Loading
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
API.prototype._load_set = function(real_id, set_id, data) {
|
||||||
|
if ( ! data )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for an existing set to copy the users.
|
||||||
|
var users = [];
|
||||||
|
if ( this.emote_sets[real_id] && this.emote_sets[real_id].users )
|
||||||
|
users = this.emote_sets[real_id].users;
|
||||||
|
|
||||||
|
var set = {
|
||||||
|
source: this.name,
|
||||||
|
source_ext: this.id,
|
||||||
|
source_id: set_id,
|
||||||
|
users: users,
|
||||||
|
count: 0,
|
||||||
|
emoticons: {},
|
||||||
|
_type: data._type || 0,
|
||||||
|
css: data.css || null,
|
||||||
|
description: data.description || null,
|
||||||
|
icon: data.icon || this.icon || null,
|
||||||
|
id: real_id,
|
||||||
|
title: data.title || "Global Emoticons",
|
||||||
|
};
|
||||||
|
|
||||||
|
this.emote_sets[real_id] = set;
|
||||||
|
|
||||||
|
if ( this.ffz.emote_sets )
|
||||||
|
this.ffz.emote_sets[real_id] = set;
|
||||||
|
|
||||||
|
var output_css = "",
|
||||||
|
ems = data.emoticons,
|
||||||
|
emoticons = set.emoticons;
|
||||||
|
|
||||||
|
for(var i=0; i < ems.length; i++) {
|
||||||
|
var emote = ems[i],
|
||||||
|
new_emote = {urls: {}},
|
||||||
|
id = emote.id || (this.name + '-' + set_id + '-' + i);
|
||||||
|
|
||||||
|
if ( ! emote.name )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
new_emote.id = id;
|
||||||
|
new_emote.set_id = real_id;
|
||||||
|
new_emote.name = emote.name;
|
||||||
|
|
||||||
|
new_emote.width = emote.width;
|
||||||
|
new_emote.height = emote.height;
|
||||||
|
|
||||||
|
new_emote.hidden = emote.hidden;
|
||||||
|
new_emote.owner = emote.owner;
|
||||||
|
|
||||||
|
new_emote.css = emote.css;
|
||||||
|
new_emote.margins = emote.margins;
|
||||||
|
|
||||||
|
new_emote.srcSet = emote.urls[1] + ' 1x';
|
||||||
|
new_emote.urls[1] = emote.urls[1];
|
||||||
|
|
||||||
|
if ( emote.urls[2] ) {
|
||||||
|
new_emote.urls[2] = emote.urls[2];
|
||||||
|
new_emote.srcSet += ', ' + emote.urls[2] + ' 2x';
|
||||||
|
}
|
||||||
|
if ( emote.urls[3] ) {
|
||||||
|
new_emote.urls[3] = emote.urls[3];
|
||||||
|
new_emote.srcSet += ', ' + emote.urls[3] + ' 3x';
|
||||||
|
}
|
||||||
|
if ( emote.urls[4] ) {
|
||||||
|
new_emote.urls[4] = emote.urls[4];
|
||||||
|
new_emote.srcSet += ', ' + emote.urls[4] + ' 4x';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( emote.regex )
|
||||||
|
new_emote.regex = emote.regex;
|
||||||
|
else if ( typeof emote.name !== "string" )
|
||||||
|
new_emote.regex = emote.name;
|
||||||
|
else
|
||||||
|
new_emote.regex = new RegExp("(^|\\W|\\b)(" + utils.escape_regex(emote.name) + ")(?=\\W|$)", "g");
|
||||||
|
|
||||||
|
output_css += build_css(new_emote);
|
||||||
|
set.count++;
|
||||||
|
emoticons[id] = new_emote;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.update_css(this.ffz._emote_style, real_id, output_css + (set.css || ""));
|
||||||
|
|
||||||
|
if ( this.ffz._cindex )
|
||||||
|
this.ffz._cindex.ffzFixTitle();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.ffz.update_ui_link();
|
||||||
|
} catch(err) { }
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------
|
||||||
|
// Loading / Unloading Sets
|
||||||
|
// -------------------------
|
||||||
|
|
||||||
|
API.prototype.load_set = function(id, emote_set) {
|
||||||
|
var exact_id = this.id + '-' + id;
|
||||||
|
|
||||||
|
emote_set.title = emote_set.title || "Global Emoticons";
|
||||||
|
emote_set._type = emote_set._type || 0;
|
||||||
|
|
||||||
|
emote_set = this._load_set(exact_id, id, emote_set);
|
||||||
|
this.log("Loaded Emoticon Set #" + id + ": " + emote_set.title + " (" + emote_set.count + " emotes)", emote_set);
|
||||||
|
return emote_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.unload_set = function(id) {
|
||||||
|
var exact_id = this.id + '-' + id,
|
||||||
|
emote_set = this.emote_sets[exact_id];
|
||||||
|
|
||||||
|
if ( ! emote_set )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// First, let's unregister it as a global.
|
||||||
|
this.unregister_global_set(id);
|
||||||
|
|
||||||
|
|
||||||
|
// Now, remove the set data.
|
||||||
|
utils.update_css(this.ffz._emote_style, exact_id, null);
|
||||||
|
|
||||||
|
this.emote_sets[exact_id] = undefined;
|
||||||
|
if ( this.ffz.emote_sets )
|
||||||
|
this.ffz.emote_sets[exact_id] = undefined;
|
||||||
|
|
||||||
|
|
||||||
|
// Remove from all its Rooms
|
||||||
|
if ( emote_set.users ) {
|
||||||
|
for(var i=0; i < emote_set.users.length; i++) {
|
||||||
|
var room_id = emote_set.users[i],
|
||||||
|
room = this.ffz.rooms && this.ffz.rooms[room_id];
|
||||||
|
|
||||||
|
if ( ! room )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ind = room.ext_sets.indexOf(exact_id);
|
||||||
|
if ( ind !== -1 )
|
||||||
|
room.ext_sets.splice(ind,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
emote_set.users = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.get_set = function(id) {
|
||||||
|
var exact_id = this.id + '-' + id;
|
||||||
|
return this.emote_sets[exact_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Global Emote Sets
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
API.prototype.register_global_set = function(id, emote_set) {
|
||||||
|
var exact_id = this.id + '-' + id;
|
||||||
|
|
||||||
|
if ( emote_set ) {
|
||||||
|
// If a set was provided, load it.
|
||||||
|
emote_set = this.load_set(id, emote_set);
|
||||||
|
} else
|
||||||
|
emote_set = this.emote_sets[exact_id];
|
||||||
|
|
||||||
|
if ( ! emote_set )
|
||||||
|
throw new Error("Invalid set ID");
|
||||||
|
|
||||||
|
|
||||||
|
// Make sure the set is still available with FFZ.
|
||||||
|
if ( ! this.ffz.emote_sets[exact_id] )
|
||||||
|
this.ffz.emote_sets[exact_id] = emote_set;
|
||||||
|
|
||||||
|
|
||||||
|
// It's a valid set if we get here, so make it global.
|
||||||
|
if ( this.global_sets.indexOf(exact_id) === -1 )
|
||||||
|
this.global_sets.push(exact_id);
|
||||||
|
|
||||||
|
if ( this.default_sets.indexOf(exact_id) === -1 )
|
||||||
|
this.default_sets.push(exact_id);
|
||||||
|
|
||||||
|
if ( this.ffz.global_sets && this.ffz.global_sets.indexOf(exact_id) === -1 )
|
||||||
|
this.ffz.global_sets.push(exact_id);
|
||||||
|
|
||||||
|
if ( this.ffz.default_sets && this.ffz.default_sets.indexOf(exact_id) === -1 )
|
||||||
|
this.ffz.default_sets.push(exact_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.unregister_global_set = function(id) {
|
||||||
|
var exact_id = this.id + '-' + id,
|
||||||
|
emote_set = this.emote_sets[exact_id];
|
||||||
|
|
||||||
|
if ( ! emote_set )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove the set from global sets.
|
||||||
|
var ind = this.global_sets.indexOf(exact_id);
|
||||||
|
if ( ind !== -1 )
|
||||||
|
this.global_sets.splice(ind,1);
|
||||||
|
|
||||||
|
ind = this.default_sets.indexOf(exact_id);
|
||||||
|
if ( ind !== -1 )
|
||||||
|
this.default_sets.splice(ind,1);
|
||||||
|
|
||||||
|
ind = this.ffz.global_sets ? this.ffz.global_sets.indexOf(exact_id) : -1;
|
||||||
|
if ( ind !== -1 )
|
||||||
|
this.ffz.global_sets.splice(ind,1);
|
||||||
|
|
||||||
|
ind = this.ffz.default_sets ? this.ffz.default_sets.indexOf(exact_id) : -1;
|
||||||
|
if ( ind !== -1 )
|
||||||
|
this.ffz.default_sets.splice(ind,1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
// Per-Channel Emote Sets
|
||||||
|
// -----------------------
|
||||||
|
|
||||||
|
API.prototype.register_room_set = function(room_id, id, emote_set) {
|
||||||
|
var exact_id = this.id + '-' + id,
|
||||||
|
room = this.ffz.rooms && this.ffz.rooms[room_id];
|
||||||
|
|
||||||
|
if ( ! room )
|
||||||
|
throw new Error("Room not loaded");
|
||||||
|
|
||||||
|
if ( emote_set ) {
|
||||||
|
// If a set was provided, load it.
|
||||||
|
emote_set.title = emote_set.title || "Channel: " + (room.display_name || room_id);
|
||||||
|
emote_set._type = emote_set._type || 1;
|
||||||
|
|
||||||
|
emote_set = this.load_set(id, emote_set);
|
||||||
|
} else
|
||||||
|
emote_set = this.emote_sets[exact_id];
|
||||||
|
|
||||||
|
if ( ! emote_set )
|
||||||
|
throw new Error("Invalid set ID");
|
||||||
|
|
||||||
|
// Make sure the set is still available with FFZ.
|
||||||
|
if ( ! this.ffz.emote_sets[exact_id] )
|
||||||
|
this.ffz.emote_sets[exact_id] = emote_set;
|
||||||
|
|
||||||
|
// Register it on the room.
|
||||||
|
room.ext_sets.push(exact_id);
|
||||||
|
emote_set.users.push(room_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.unregister_room_set = function(room_id, id) {
|
||||||
|
var exact_id = this.id + '-' + id,
|
||||||
|
emote_set = this.emote_sets[exact_id],
|
||||||
|
room = this.ffz.rooms && this.ffz.rooms[room_id];
|
||||||
|
|
||||||
|
if ( ! emote_set || ! room )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ind = room.ext_sets.indexOf(exact_id);
|
||||||
|
if ( ind !== -1 )
|
||||||
|
room.ext_sets.splice(ind,1);
|
||||||
|
|
||||||
|
ind = emote_set.users.indexOf(room_id);
|
||||||
|
if ( ind !== -1 )
|
||||||
|
emote_set.users.splice(ind,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
// Channel Callbacks
|
||||||
|
// -----------------------
|
||||||
|
|
||||||
|
API.prototype._room_callbacks = function(room_id, room, specific_func) {
|
||||||
|
var callback = this.register_room_set.bind(this, room_id);
|
||||||
|
|
||||||
|
if ( specific_func ) {
|
||||||
|
try {
|
||||||
|
specific_func(room_id, callback);
|
||||||
|
} catch(err) {
|
||||||
|
this.log("Error in On-Room Callback: " + err);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for(var i=0; i < this.on_room_callbacks.length; i++) {
|
||||||
|
var cb = this.on_room_callbacks[i];
|
||||||
|
try {
|
||||||
|
cb(room_id, callback);
|
||||||
|
} catch(err) {
|
||||||
|
this.log("Error in On-Room Callback: " + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.register_on_room_callback = function(callback, dont_iterate) {
|
||||||
|
this.on_room_callbacks.push(callback);
|
||||||
|
|
||||||
|
// Call this for all current rooms.
|
||||||
|
if ( ! dont_iterate && this.ffz.rooms ) {
|
||||||
|
for(var room_id in this.ffz.rooms)
|
||||||
|
this._room_callbacks(room_id, this.ffz.rooms[room_id], callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API.prototype.unregister_on_room_callback = function(callback) {
|
||||||
|
var ind = this.on_room_callbacks.indexOf(callback);
|
||||||
|
if ( ind !== -1 )
|
||||||
|
this.on_room_callbacks.splice(ind, 1);
|
||||||
|
}
|
|
@ -69,6 +69,7 @@ FFZ.prototype.setup_bttv = function(delay) {
|
||||||
document.body.classList.remove("ffz-chat-separator-wide");
|
document.body.classList.remove("ffz-chat-separator-wide");
|
||||||
document.body.classList.remove("ffz-chat-separator-3d-inset");
|
document.body.classList.remove("ffz-chat-separator-3d-inset");
|
||||||
document.body.classList.remove("ffz-sidebar-swap");
|
document.body.classList.remove("ffz-sidebar-swap");
|
||||||
|
document.body.classList.remove("ffz-portrait");
|
||||||
document.body.classList.remove("ffz-flip-dashboard");
|
document.body.classList.remove("ffz-flip-dashboard");
|
||||||
document.body.classList.remove("ffz-transparent-badges");
|
document.body.classList.remove("ffz-transparent-badges");
|
||||||
document.body.classList.remove("ffz-high-contrast-chat-text");
|
document.body.classList.remove("ffz-high-contrast-chat-text");
|
||||||
|
|
|
@ -49,7 +49,7 @@ FFZ.prototype._emote_menu_enumerator = function() {
|
||||||
if ( emote.hidden )
|
if ( emote.hidden )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var title = "FrankerFaceZ " + set.title,
|
var title = (set.source || "FrankerFaceZ") + " " + set.title,
|
||||||
badge = set.icon || '//cdn.frankerfacez.com/script/devicon.png';
|
badge = set.icon || '//cdn.frankerfacez.com/script/devicon.png';
|
||||||
|
|
||||||
emotes.push({text: emote.name, url: emote.urls[1],
|
emotes.push({text: emote.name, url: emote.urls[1],
|
||||||
|
|
|
@ -17,7 +17,7 @@ FFZ.prototype.check_ff = function(tries) {
|
||||||
if ( ! tries )
|
if ( ! tries )
|
||||||
this.log("Checking for Feature Friday data...");
|
this.log("Checking for Feature Friday data...");
|
||||||
|
|
||||||
jQuery.ajax(constants.SERVER + "script/event.json", {dataType: "json", context: this})
|
jQuery.ajax(constants.SERVER + "script/event.json?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info), {dataType: "json", context: this})
|
||||||
.done(function(data) {
|
.done(function(data) {
|
||||||
return this._load_ff(data);
|
return this._load_ff(data);
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
|
@ -44,7 +44,7 @@ FFZ.ws_commands.reload_ff = function() {
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
||||||
FFZ.prototype._feature_friday_ui = function(room_id, parent, view) {
|
FFZ.prototype._feature_friday_ui = function(room_id, parent, view) {
|
||||||
if ( ! this.feature_friday || this.feature_friday.channel == room_id )
|
if ( ! this.feature_friday || this.feature_friday.channel === room_id )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._emotes_for_sets(parent, view, [this.feature_friday.set], this.feature_friday.title, this.feature_friday.icon, "FrankerFaceZ");
|
this._emotes_for_sets(parent, view, [this.feature_friday.set], this.feature_friday.title, this.feature_friday.icon, "FrankerFaceZ");
|
||||||
|
@ -52,7 +52,7 @@ FFZ.prototype._feature_friday_ui = function(room_id, parent, view) {
|
||||||
// Before we add the button, make sure the channel isn't the
|
// Before we add the button, make sure the channel isn't the
|
||||||
// current channel.
|
// current channel.
|
||||||
var Channel = App.__container__.lookup('controller:channel');
|
var Channel = App.__container__.lookup('controller:channel');
|
||||||
if ( Channel && Channel.get('id') == this.feature_friday.channel )
|
if ( ! this.feature_friday.channel || (Channel && Channel.get('id') === this.feature_friday.channel) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,13 +98,14 @@ FFZ.prototype._load_ff = function(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's no data, just leave.
|
// If there's no data, just leave.
|
||||||
if ( ! data || ! data.set || ! data.channel )
|
if ( ! data || ! data.set )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We have our data! Set it up.
|
// We have our data! Set it up.
|
||||||
this.feature_friday = {set: data.set, channel: data.channel, live: false,
|
this.feature_friday = {set: data.set, channel: data.channel, live: false,
|
||||||
title: data.title || "Feature Friday",
|
title: data.title || "Feature Friday",
|
||||||
display_name: FFZ.get_capitalization(data.channel, this._update_ff_name.bind(this))};
|
icon: data.icon,
|
||||||
|
display_name: data.channel ? FFZ.get_capitalization(data.channel, this._update_ff_name.bind(this)) : data.title || "Feature Friday"};
|
||||||
|
|
||||||
// Add the set.
|
// Add the set.
|
||||||
this.global_sets.push(data.set);
|
this.global_sets.push(data.set);
|
||||||
|
@ -117,7 +118,7 @@ FFZ.prototype._load_ff = function(data) {
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype._update_ff_live = function() {
|
FFZ.prototype._update_ff_live = function() {
|
||||||
if ( ! this.feature_friday )
|
if ( ! this.feature_friday || ! this.feature_friday.channel )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var f = this;
|
var f = this;
|
||||||
|
|
|
@ -10,6 +10,7 @@ var FFZ = window.FrankerFaceZ = function() {
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
this._log_data = [];
|
this._log_data = [];
|
||||||
|
this._apis = {};
|
||||||
|
|
||||||
// Get things started.
|
// Get things started.
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
@ -21,7 +22,7 @@ FFZ.get = function() { return FFZ.instance; }
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
var VER = FFZ.version_info = {
|
var VER = FFZ.version_info = {
|
||||||
major: 3, minor: 5, revision: 30,
|
major: 3, minor: 5, revision: 42,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,7 @@ require('./tokenize');
|
||||||
//require('./filtering');
|
//require('./filtering');
|
||||||
|
|
||||||
|
|
||||||
// Analytics: require('./ember/router');
|
require('./ember/router');
|
||||||
require('./ember/channel');
|
require('./ember/channel');
|
||||||
require('./ember/player');
|
require('./ember/player');
|
||||||
require('./ember/room');
|
require('./ember/room');
|
||||||
|
@ -149,6 +150,7 @@ require('./ui/my_emotes');
|
||||||
require('./ui/about_page');
|
require('./ui/about_page');
|
||||||
|
|
||||||
require('./commands');
|
require('./commands');
|
||||||
|
require('./ext/api');
|
||||||
|
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
|
@ -322,7 +324,7 @@ FFZ.prototype.init_ember = function(delay) {
|
||||||
this.setup_emoticons();
|
this.setup_emoticons();
|
||||||
this.setup_badges();
|
this.setup_badges();
|
||||||
|
|
||||||
//this.setup_router();
|
this.setup_router();
|
||||||
this.setup_colors();
|
this.setup_colors();
|
||||||
this.setup_tokenization();
|
this.setup_tokenization();
|
||||||
//this.setup_filtering();
|
//this.setup_filtering();
|
||||||
|
|
|
@ -53,32 +53,18 @@ FFZ.prototype.load_settings = function() {
|
||||||
// Build a settings object.
|
// Build a settings object.
|
||||||
this.settings = {};
|
this.settings = {};
|
||||||
|
|
||||||
for(var key in FFZ.settings_info) {
|
|
||||||
if ( ! FFZ.settings_info.hasOwnProperty(key) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var info = FFZ.settings_info[key],
|
|
||||||
ls_key = info.storage_key || make_ls(key),
|
|
||||||
val = info.hasOwnProperty("value") ? info.value : undefined;
|
|
||||||
|
|
||||||
if ( localStorage.hasOwnProperty(ls_key) ) {
|
|
||||||
try {
|
|
||||||
val = JSON.parse(localStorage.getItem(ls_key));
|
|
||||||
} catch(err) {
|
|
||||||
this.log('Error loading value for "' + key + '": ' + err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( info.process_value )
|
|
||||||
val = info.process_value.bind(this)(val);
|
|
||||||
|
|
||||||
this.settings[key] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
this.settings.get = this._setting_get.bind(this);
|
this.settings.get = this._setting_get.bind(this);
|
||||||
this.settings.set = this._setting_set.bind(this);
|
this.settings.set = this._setting_set.bind(this);
|
||||||
this.settings.del = this._setting_del.bind(this);
|
this.settings.del = this._setting_del.bind(this);
|
||||||
|
this.settings.load = this._setting_load.bind(this);
|
||||||
|
|
||||||
|
for(var key in FFZ.settings_info) {
|
||||||
|
if ( ! FFZ.settings_info.hasOwnProperty(key) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this._setting_load(key);
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for Changes
|
// Listen for Changes
|
||||||
window.addEventListener("storage", this._setting_update.bind(this), false);
|
window.addEventListener("storage", this._setting_update.bind(this), false);
|
||||||
|
@ -825,7 +811,31 @@ FFZ.prototype._setting_update = function(e) {
|
||||||
// Settings Access
|
// Settings Access
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
||||||
|
FFZ.prototype._setting_load = function(key, default_value) {
|
||||||
|
var info = FFZ.settings_info[key],
|
||||||
|
ls_key = info && info.storage_key || make_ls(key),
|
||||||
|
val = default_value || (info && info.hasOwnProperty("value") ? info.value : undefined);
|
||||||
|
|
||||||
|
if ( localStorage.hasOwnProperty(ls_key) ) {
|
||||||
|
try {
|
||||||
|
val = JSON.parse(localStorage.getItem(ls_key));
|
||||||
|
} catch(err) {
|
||||||
|
this.log('Error loading value for "' + key + '": ' + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( info && info.process_value )
|
||||||
|
val = info.process_value.bind(this)(val);
|
||||||
|
|
||||||
|
this.settings[key] = val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype._setting_get = function(key) {
|
FFZ.prototype._setting_get = function(key) {
|
||||||
|
if ( ! this.settings.hasOwnProperty(key) && FFZ.settings_info[key] )
|
||||||
|
this._setting_load(key);
|
||||||
|
|
||||||
return this.settings[key];
|
return this.settings[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ FFZ.prototype.ws_iframe = function() {
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype.ws_create = function() {
|
FFZ.prototype.ws_create = function() {
|
||||||
|
// Disable sockets for now.
|
||||||
|
return;
|
||||||
|
|
||||||
var f = this, ws;
|
var f = this, ws;
|
||||||
|
|
||||||
this._ws_last_req = 0;
|
this._ws_last_req = 0;
|
||||||
|
|
|
@ -240,6 +240,24 @@ FFZ.src_to_id = function(src) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FFZ._emote_mirror_swap = function(img) {
|
||||||
|
var src, attempts = parseInt(img.getAttribute('data-alt-attempts')) || 0;
|
||||||
|
if ( attempts > 3 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
img.setAttribute('data-alt-attempts', attempts + 1);
|
||||||
|
var id = img.getAttribute('data-emote');
|
||||||
|
|
||||||
|
if ( img.src.substr(0, TWITCH_BASE.length) === TWITCH_BASE ) {
|
||||||
|
img.src = constants.EMOTE_MIRROR_BASE + id + ".png";
|
||||||
|
img.srcset = "";
|
||||||
|
} else {
|
||||||
|
img.src = TWITCH_BASE + id + "/1.0";
|
||||||
|
img.srcset = build_srcset(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
// Settings
|
// Settings
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
@ -543,7 +561,7 @@ FFZ.prototype.render_tokens = function(tokens, render_links) {
|
||||||
|
|
||||||
tooltip = emote ? utils.sanitize(f._emote_tooltip(emote)) : token.altText;
|
tooltip = emote ? utils.sanitize(f._emote_tooltip(emote)) : token.altText;
|
||||||
srcset = emote ? emote.srcSet : token.srcSet;
|
srcset = emote ? emote.srcSet : token.srcSet;
|
||||||
extra = ' data-ffz-emote="' + emote.id + '"';
|
extra = (emote ? ' data-ffz-emote="' + emote.id + '"' : '') + (emote_set ? ' data-ffz-set="' + emote_set.id + '"' : '');
|
||||||
|
|
||||||
} else if ( token.ffzEmoji ) {
|
} else if ( token.ffzEmoji ) {
|
||||||
var eid = token.ffzEmoji,
|
var eid = token.ffzEmoji,
|
||||||
|
@ -582,7 +600,9 @@ FFZ.prototype.render_tokens = function(tokens, render_links) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extra = ' data-emote="' + id + '"';
|
var mirror_url = utils.quote_attr(constants.EMOTE_MIRROR_BASE + id + '.png');
|
||||||
|
|
||||||
|
extra = ' data-emote="' + id + '" onerror="FrankerFaceZ._emote_mirror_swap(this)"';
|
||||||
|
|
||||||
if ( ! constants.EMOTE_REPLACEMENTS[id] )
|
if ( ! constants.EMOTE_REPLACEMENTS[id] )
|
||||||
srcset = build_srcset(id);
|
srcset = build_srcset(id);
|
||||||
|
|
|
@ -211,5 +211,6 @@ FFZ.prototype._load_dark_css = function() {
|
||||||
s.id = "ffz-dark-css";
|
s.id = "ffz-dark-css";
|
||||||
s.setAttribute('rel', 'stylesheet');
|
s.setAttribute('rel', 'stylesheet');
|
||||||
s.setAttribute('href', constants.SERVER + "script/dark.css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
s.setAttribute('href', constants.SERVER + "script/dark.css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||||
|
s.onerror = "this.href = this.href + '_';"
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ var FFZ = window.FrankerFaceZ,
|
||||||
TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/",
|
TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/",
|
||||||
|
|
||||||
fix_menu_position = function(container) {
|
fix_menu_position = function(container) {
|
||||||
var swapped = document.body.classList.contains('ffz-sidebar-swap');
|
var swapped = document.body.classList.contains('ffz-sidebar-swap') && ! document.body.classList.contains('ffz-portrait');
|
||||||
|
|
||||||
var bounds = container.getBoundingClientRect(),
|
var bounds = container.getBoundingClientRect(),
|
||||||
left = parseInt(container.style.left || '0'),
|
left = parseInt(container.style.left || '0'),
|
||||||
|
@ -419,8 +419,11 @@ FFZ.menu_pages.channel = {
|
||||||
|
|
||||||
grid.className = "emoticon-grid";
|
grid.className = "emoticon-grid";
|
||||||
header.className = "heading";
|
header.className = "heading";
|
||||||
if ( icon )
|
if ( icon ) {
|
||||||
header.style.backgroundImage = 'url("' + icon + '")';
|
header.style.backgroundImage = 'url("' + icon + '")';
|
||||||
|
if ( icon.indexOf('.svg') !== -1 )
|
||||||
|
header.style.backgroundSize = '18px';
|
||||||
|
}
|
||||||
|
|
||||||
header.innerHTML = '<span class="right">Twitch</span>Subscriber Emoticons';
|
header.innerHTML = '<span class="right">Twitch</span>Subscriber Emoticons';
|
||||||
grid.appendChild(header);
|
grid.appendChild(header);
|
||||||
|
@ -507,7 +510,7 @@ FFZ.menu_pages.channel = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have extra sets?
|
// Do we have extra sets?
|
||||||
var extra_sets = room && room.extra_sets || [];
|
var extra_sets = _.union(room && room.extra_sets || [], room && room.ext_sets || [], []);
|
||||||
|
|
||||||
// Basic Emote Sets
|
// Basic Emote Sets
|
||||||
this._emotes_for_sets(inner, view, room && room.set && [room.set] || [], (this.feature_friday || has_product || extra_sets.length ) ? "Channel Emoticons" : null, "http://cdn.frankerfacez.com/script/devicon.png", "FrankerFaceZ");
|
this._emotes_for_sets(inner, view, room && room.set && [room.set] || [], (this.feature_friday || has_product || extra_sets.length ) ? "Channel Emoticons" : null, "http://cdn.frankerfacez.com/script/devicon.png", "FrankerFaceZ");
|
||||||
|
@ -515,9 +518,9 @@ FFZ.menu_pages.channel = {
|
||||||
for(var i=0; i < extra_sets.length; i++) {
|
for(var i=0; i < extra_sets.length; i++) {
|
||||||
// Look up the set name.
|
// Look up the set name.
|
||||||
var set = this.emote_sets[extra_sets[i]],
|
var set = this.emote_sets[extra_sets[i]],
|
||||||
name = set ? "Featured " + set.title : "Featured Channel";
|
name = set ? (set.hasOwnProperty('source_ext') ? "" : "Featured ") + set.title : "Featured Channel";
|
||||||
|
|
||||||
this._emotes_for_sets(inner, view, [extra_sets[i]], name, "http://cdn.frankerfacez.com/script/devicon.png", "FrankerFaceZ");
|
this._emotes_for_sets(inner, view, [extra_sets[i]], name, set.icon || "//cdn.frankerfacez.com/script/devicon.png", set.source || "FrankerFaceZ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feature Friday!
|
// Feature Friday!
|
||||||
|
@ -550,8 +553,11 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
|
||||||
|
|
||||||
el_header.appendChild(document.createTextNode(header));
|
el_header.appendChild(document.createTextNode(header));
|
||||||
|
|
||||||
if ( image )
|
if ( image ) {
|
||||||
el_header.style.backgroundImage = 'url("' + image + '")';
|
el_header.style.backgroundImage = 'url("' + image + '")';
|
||||||
|
if ( image.indexOf('.svg') !== -1 )
|
||||||
|
el_header.style.backgroundSize = '18px';
|
||||||
|
}
|
||||||
|
|
||||||
grid.appendChild(el_header);
|
grid.appendChild(el_header);
|
||||||
}
|
}
|
||||||
|
@ -610,9 +616,17 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
|
||||||
|
|
||||||
s.addEventListener('click', function(id, code, e) {
|
s.addEventListener('click', function(id, code, e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons ) {
|
||||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
var url;
|
||||||
else
|
if ( set.hasOwnProperty('source_ext') ) {
|
||||||
|
var api = f._apis[set.source_ext];
|
||||||
|
if ( api && api.emote_url_generator )
|
||||||
|
url = api.emote_url_generator(set.source_id, id);
|
||||||
|
} else
|
||||||
|
url = "https://www.frankerfacez.com/emoticons/" + id;
|
||||||
|
if ( url )
|
||||||
|
window.open(url);
|
||||||
|
} else
|
||||||
this._add_emote(view, code);
|
this._add_emote(view, code);
|
||||||
}.bind(this, emote.id, emote.name));
|
}.bind(this, emote.id, emote.name));
|
||||||
|
|
||||||
|
|
|
@ -269,17 +269,23 @@ FFZ.menu_pages.myemotes = {
|
||||||
var heading = document.createElement('div'),
|
var heading = document.createElement('div'),
|
||||||
menu = document.createElement('div'),
|
menu = document.createElement('div'),
|
||||||
f = this,
|
f = this,
|
||||||
emotes = [];
|
emotes = [],
|
||||||
|
|
||||||
|
menu_id = set.hasOwnProperty('source_ext') ? 'ffz-ext-' + set.source_ext + '-' + set.source_id : 'ffz-' + set.id,
|
||||||
|
icon = set.icon || (set.hasOwnProperty('source_ext') && '//cdn.frankerfacez.com/emoji/tw-1f4ac.svg') || '//cdn.frankerfacez.com/script/devicon.png';
|
||||||
|
|
||||||
heading.className = 'heading';
|
heading.className = 'heading';
|
||||||
heading.innerHTML = '<span class="right">FrankerFaceZ</span>' + set.title;
|
heading.innerHTML = '<span class="right">' + (utils.sanitize(set.source) || 'FrankerFaceZ') + '</span>' + set.title;
|
||||||
heading.style.backgroundImage = 'url("' + (set.icon || '//cdn.frankerfacez.com/script/devicon.png') + '")';
|
|
||||||
|
heading.style.backgroundImage = 'url("' + icon + '")';
|
||||||
|
if ( icon.indexOf('.svg') !== -1 )
|
||||||
|
heading.style.backgroundSize = "18px";
|
||||||
|
|
||||||
menu.className = 'emoticon-grid collapsable';
|
menu.className = 'emoticon-grid collapsable';
|
||||||
menu.appendChild(heading);
|
menu.appendChild(heading);
|
||||||
|
|
||||||
menu.setAttribute('data-set', 'ffz-' + set.id);
|
menu.setAttribute('data-set', menu_id);
|
||||||
menu.classList.toggle('collapsed', this.settings.emote_menu_collapsed.indexOf('ffz-' + set.id) !== -1);
|
menu.classList.toggle('collapsed', this.settings.emote_menu_collapsed.indexOf(menu_id) !== -1);
|
||||||
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this); });
|
heading.addEventListener('click', function() { FFZ.menu_pages.myemotes.toggle_section.bind(f)(this); });
|
||||||
|
|
||||||
for(var emote_id in set.emoticons)
|
for(var emote_id in set.emoticons)
|
||||||
|
@ -325,9 +331,18 @@ FFZ.menu_pages.myemotes = {
|
||||||
em.title = this._emote_tooltip(emote);
|
em.title = this._emote_tooltip(emote);
|
||||||
em.addEventListener("click", function(id, code, e) {
|
em.addEventListener("click", function(id, code, e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons ) {
|
||||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
var url;
|
||||||
else
|
if ( set.hasOwnProperty('source_ext') ) {
|
||||||
|
var api = f._apis[set.source_ext];
|
||||||
|
if ( api && api.emote_url_generator )
|
||||||
|
url = api.emote_url_generator(set.source_id, id);
|
||||||
|
} else
|
||||||
|
url = "https://www.frankerfacez.com/emoticons/" + id;
|
||||||
|
|
||||||
|
if ( url )
|
||||||
|
window.open(url);
|
||||||
|
} else
|
||||||
this._add_emote(view, code);
|
this._add_emote(view, code);
|
||||||
}.bind(this, emote.id, emote.name));
|
}.bind(this, emote.id, emote.name));
|
||||||
menu.appendChild(em);
|
menu.appendChild(em);
|
||||||
|
@ -381,14 +396,14 @@ FFZ.menu_pages.myemotes = {
|
||||||
var an = a[0], bn = b[0];
|
var an = a[0], bn = b[0];
|
||||||
if ( an === "turbo" || an === "--turbo-faces--" )
|
if ( an === "turbo" || an === "--turbo-faces--" )
|
||||||
an = "zza|" + an;
|
an = "zza|" + an;
|
||||||
else if ( an === "global" || an === "global emoticons" || an === "--global--" )
|
else if ( an === "global" || (an && an.substr(0,16) === "global emoticons") || an === "--global--" )
|
||||||
an = "zzy|" + an;
|
an = "zzy|" + an;
|
||||||
else if ( an === "emoji" )
|
else if ( an === "emoji" )
|
||||||
an = "zzz|" + an;
|
an = "zzz|" + an;
|
||||||
|
|
||||||
if ( bn === "turbo" || bn === "--turbo-faces--" )
|
if ( bn === "turbo" || bn === "--turbo-faces--" )
|
||||||
bn = "zza|" + bn;
|
bn = "zza|" + bn;
|
||||||
else if ( bn === "global" || bn === "global emoticons" || bn === "--global--" )
|
else if ( bn === "global" || (bn && bn.substr(0,16) === "global emoticons") || bn === "--global--" )
|
||||||
bn = "zzy|" + bn;
|
bn = "zzy|" + bn;
|
||||||
else if ( bn === "emoji" )
|
else if ( bn === "emoji" )
|
||||||
bn = "zzz|" + bn;
|
bn = "zzz|" + bn;
|
||||||
|
|
|
@ -8,18 +8,6 @@ var FFZ = window.FrankerFaceZ;
|
||||||
FFZ.prototype.setup_notifications = function() {
|
FFZ.prototype.setup_notifications = function() {
|
||||||
this.log("Adding event handler for window focus.");
|
this.log("Adding event handler for window focus.");
|
||||||
window.addEventListener("focus", this.clear_notifications.bind(this));
|
window.addEventListener("focus", this.clear_notifications.bind(this));
|
||||||
|
|
||||||
// Firefox update warning.
|
|
||||||
if ( navigator.userAgent.toLowerCase().indexOf('firefox/') !== -1 ) {
|
|
||||||
if ( localStorage.hasOwnProperty('ffz_mozilla_sign_warning') )
|
|
||||||
return;
|
|
||||||
|
|
||||||
localStorage.ffz_mozilla_sign_warning = true;
|
|
||||||
var f = this;
|
|
||||||
setTimeout(function() {
|
|
||||||
f.show_message('Firefox users please re-download the add-on from <a href="https://www.frankerfacez.com/" target="_new">https://www.frankerfacez.com/</a> to ensure that it continues to function after the upgrade to Firefox 41. You should see version 1.56 in your add-ons listing.');
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ FFZ.prototype.setup_css = function() {
|
||||||
s.id = "ffz-ui-css";
|
s.id = "ffz-ui-css";
|
||||||
s.setAttribute('rel', 'stylesheet');
|
s.setAttribute('rel', 'stylesheet');
|
||||||
s.setAttribute('href', constants.SERVER + "script/style.css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
s.setAttribute('href', constants.SERVER + "script/style.css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||||
|
s.onerror = "this.href = this.href + '_';"
|
||||||
|
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
|
|
||||||
if ( window.jQuery && jQuery.noty )
|
if ( window.jQuery && jQuery.noty )
|
||||||
|
|
|
@ -9,6 +9,10 @@ var sanitize_el = document.createElement('span'),
|
||||||
return sanitize_el.innerHTML;
|
return sanitize_el.innerHTML;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
escape_regex = RegExp.escape || function(str) {
|
||||||
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
|
},
|
||||||
|
|
||||||
R_QUOTE = /"/g,
|
R_QUOTE = /"/g,
|
||||||
R_SQUOTE = /'/g,
|
R_SQUOTE = /'/g,
|
||||||
R_AMP = /&/g,
|
R_AMP = /&/g,
|
||||||
|
@ -311,5 +315,7 @@ module.exports = {
|
||||||
return "99+";
|
return "99+";
|
||||||
|
|
||||||
return "" + count;
|
return "" + count;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
escape_regex: escape_regex
|
||||||
}
|
}
|
|
@ -1673,7 +1673,11 @@ body.ffz-minimal-chat-input .ember-chat .chat-interface .textarea-contain textar
|
||||||
|
|
||||||
/* Swap Sidebars */
|
/* Swap Sidebars */
|
||||||
|
|
||||||
.ffz-sidebar-swap .ember-chat .chat-interface .emoticon-selector {
|
body[data-current-path^="user."].ffz-portrait #right_close { transform: rotate(90deg); }
|
||||||
|
body[data-current-path^="user."].ffz-portrait .archives-contain .more-archives { width: 100%; }
|
||||||
|
|
||||||
|
body:not([data-current-path^="user."]) .ffz-sidebar-swap .ember-chat .chat-interface .emoticon-selector,
|
||||||
|
.ffz-sidebar-swap:not(.ffz-portrait) .ember-chat .chat-interface .emoticon-selector {
|
||||||
right: auto;
|
right: auto;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
}
|
}
|
||||||
|
@ -1688,7 +1692,7 @@ body.ffz-minimal-chat-input .ember-chat .chat-interface .textarea-contain textar
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-sidebar-swap #right_close,
|
.ffz-sidebar-swap:not(.ffz-portrait) #right_close,
|
||||||
.ffz-sidebar-swap #left_close {
|
.ffz-sidebar-swap #left_close {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue