mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-02 17:18:31 +00:00
3.5.182. I forgot to commit a bit again. D: Removed FFZ from two-factor auth dialogs / pages. Added option to always expand the player volume slider. Revamped ban notices to be nicer. Status indicator for emoteonly-mode. Fixed /ffz reload command. Update to the latest FileSaver.js. Make high contrast compatible with BTTV. Conversations fixes. Better BTTV dark theme detection.
This commit is contained in:
parent
6cf5ddc734
commit
4af0c3480c
19 changed files with 378 additions and 262 deletions
7
dark.css
7
dark.css
|
@ -156,11 +156,16 @@ body.ffz-dark,
|
|||
border-color: #32323e !important;
|
||||
}
|
||||
|
||||
.ffz-dark .twitch_subwindow_container.two-factor-auth .card,
|
||||
.ffz-dark .card#passport_modal {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.ffz-dark .balloon,
|
||||
.ffz-dark .balloon:after,
|
||||
.ffz-dark .conversation-settings-menu,
|
||||
.ffz-dark .ember-chat .chat-interface .ffz-ui-popup.emoticon-selector .emoticon-selector-box,
|
||||
.ffz-dark .card:not(#passport_modal),
|
||||
.ffz-dark .twitch_subwindow_container:not(.two-factor-auth) .card:not(#passport_modal),
|
||||
.ffz-dark #flyout .content,
|
||||
.ffz-dark .whatisthis,
|
||||
.ffz-dark .ui-menu,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* FileSaver.js
|
||||
* A saveAs() FileSaver implementation.
|
||||
* 1.1.20150716
|
||||
* 1.1.20160328
|
||||
*
|
||||
* By Eli Grey, http://eligrey.com
|
||||
* License: X11/MIT
|
||||
* License: MIT
|
||||
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
|
@ -30,6 +30,7 @@ var saveAs = saveAs || (function(view) {
|
|||
var event = new MouseEvent("click");
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
, is_safari = /Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
|
||||
, webkit_req_fs = view.webkitRequestFileSystem
|
||||
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
|
||||
, throw_outside = function(ex) {
|
||||
|
@ -39,10 +40,8 @@ var saveAs = saveAs || (function(view) {
|
|||
}
|
||||
, force_saveable_type = "application/octet-stream"
|
||||
, fs_min_size = 0
|
||||
// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
|
||||
// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
|
||||
// for the reasoning behind the timeout and revocation flow
|
||||
, arbitrary_revoke_timeout = 500 // in ms
|
||||
// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
|
||||
, arbitrary_revoke_timeout = 1000 * 40 // in ms
|
||||
, revoke = function(file) {
|
||||
var revoker = function() {
|
||||
if (typeof file === "string") { // file is an object URL
|
||||
|
@ -51,11 +50,23 @@ var saveAs = saveAs || (function(view) {
|
|||
file.remove();
|
||||
}
|
||||
};
|
||||
if (view.chrome) {
|
||||
revoker();
|
||||
} else {
|
||||
setTimeout(revoker, arbitrary_revoke_timeout);
|
||||
/* // Take note W3C:
|
||||
var
|
||||
uri = typeof file === "string" ? file : file.toURL()
|
||||
, revoker = function(evt) {
|
||||
// idealy DownloadFinishedEvent.data would be the URL requested
|
||||
if (evt.data === uri) {
|
||||
if (typeof file === "string") { // file is an object URL
|
||||
get_URL().revokeObjectURL(file);
|
||||
} else { // file is a File
|
||||
file.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
view.addEventListener("downloadfinished", revoker);
|
||||
*/
|
||||
setTimeout(revoker, arbitrary_revoke_timeout);
|
||||
}
|
||||
, dispatch = function(filesaver, event_types, event) {
|
||||
event_types = [].concat(event_types);
|
||||
|
@ -94,6 +105,19 @@ var saveAs = saveAs || (function(view) {
|
|||
}
|
||||
// on any filesys errors revert to saving with object URLs
|
||||
, fs_error = function() {
|
||||
if (target_view && is_safari && typeof FileReader !== "undefined") {
|
||||
// Safari doesn't allow downloading of blob urls
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
var base64Data = reader.result;
|
||||
target_view.location.href = "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/));
|
||||
filesaver.readyState = filesaver.DONE;
|
||||
dispatch_all();
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
filesaver.readyState = filesaver.INIT;
|
||||
return;
|
||||
}
|
||||
// don't create more object URLs than needed
|
||||
if (blob_changed || !object_url) {
|
||||
object_url = get_URL().createObjectURL(blob);
|
||||
|
@ -102,7 +126,7 @@ var saveAs = saveAs || (function(view) {
|
|||
target_view.location.href = object_url;
|
||||
} else {
|
||||
var new_tab = view.open(object_url, "_blank");
|
||||
if (new_tab == undefined && typeof safari !== "undefined") {
|
||||
if (new_tab === undefined && is_safari) {
|
||||
//Apple do not allow window.open, see http://bit.ly/1kZffRI
|
||||
view.location.href = object_url
|
||||
}
|
||||
|
@ -127,9 +151,9 @@ var saveAs = saveAs || (function(view) {
|
|||
}
|
||||
if (can_use_save_link) {
|
||||
object_url = get_URL().createObjectURL(blob);
|
||||
save_link.href = object_url;
|
||||
save_link.download = name;
|
||||
setTimeout(function() {
|
||||
save_link.href = object_url;
|
||||
save_link.download = name;
|
||||
click(save_link);
|
||||
dispatch_all();
|
||||
revoke(object_url);
|
||||
|
@ -249,8 +273,8 @@ var saveAs = saveAs || (function(view) {
|
|||
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports.saveAs = saveAs;
|
||||
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
|
||||
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
|
||||
define([], function() {
|
||||
return saveAs;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -414,7 +414,8 @@ FFZ.prototype.load_badges = function(callback, tries) {
|
|||
jQuery.getJSON(constants.API_SERVER + "v1/badges")
|
||||
.done(function(data) {
|
||||
var badge_total = 0,
|
||||
badge_count = 0;
|
||||
badge_count = 0,
|
||||
badge_data = {};
|
||||
|
||||
for(var i=0; i < data.badges.length; i++) {
|
||||
var badge = data.badges[i];
|
||||
|
@ -430,6 +431,8 @@ FFZ.prototype.load_badges = function(callback, tries) {
|
|||
var badge = f.badges[badge_id],
|
||||
users = data.users[badge_id];
|
||||
|
||||
badge_data[badge.name] = users.length;
|
||||
|
||||
for(var i=0; i < users.length; i++) {
|
||||
var user = users[i],
|
||||
ud = f.users[user] = f.users[user] || {},
|
||||
|
@ -451,7 +454,7 @@ FFZ.prototype.load_badges = function(callback, tries) {
|
|||
|
||||
|
||||
f.log("Loaded " + utils.number_commas(badge_count) + " total badges across " + badge_total + " types.");
|
||||
typeof callback === "function" && callback(true);
|
||||
typeof callback === "function" && callback(true, badge_count, badge_total, badge_data);
|
||||
|
||||
}).fail(function(data) {
|
||||
if ( data.status === 404 )
|
||||
|
|
|
@ -26,14 +26,8 @@ FFZ.ffz_commands.reload = function(room, args) {
|
|||
|
||||
// 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);
|
||||
f.load_badges(function(success, badge_count, badge_total, badge_data) {
|
||||
done(success ? [badge_count, badge_total, badge_data] : [0, 0, {}]);
|
||||
});
|
||||
}));
|
||||
|
||||
|
@ -52,19 +46,32 @@ FFZ.ffz_commands.reload = function(room, args) {
|
|||
|
||||
// Do it!
|
||||
Promise.all(promises).then(function(results) {
|
||||
var success = 0,
|
||||
bots = results[0],
|
||||
donors = results[1],
|
||||
total = results.length - 2;
|
||||
try {
|
||||
var success = 0,
|
||||
badge_count = results[0][0],
|
||||
badge_total = results[0][1],
|
||||
badges = results[0][2],
|
||||
total = results.length - 1,
|
||||
badge_string = [];
|
||||
|
||||
if ( results.length > 2 ) {
|
||||
for(var i=2; i < results.length; i++) {
|
||||
if ( results[i] )
|
||||
success++;
|
||||
if ( results.length > 1 ) {
|
||||
for(var i=1; 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) + ".");
|
||||
for(var key in badges) {
|
||||
if ( badges.hasOwnProperty(key) )
|
||||
badge_string.push(key + ': ' + badges[key])
|
||||
}
|
||||
|
||||
f.room_message(room, "Loaded " + utils.number_commas(badge_count) + " badge" + utils.pluralize(badge_count) + " across " + utils.number_commas(badge_total) + " badge type" + utils.pluralize(badge_total) + (badge_string.length ? " (" + badge_string.join(", ") + ")" : "") + ". Successfully reloaded " + utils.number_commas(success) + " of " + utils.number_commas(total) + " emoticon set" + utils.pluralize(total) + ".");
|
||||
|
||||
} catch(err) {
|
||||
f.room_message(room, "An error occured running the command.");
|
||||
f.error("Error Running FFZ Reload", err);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -71,34 +71,34 @@ FFZ.prototype.setup_conversations = function() {
|
|||
document.body.classList.toggle('ffz-minimize-conversations', this.settings.minimize_conversations);
|
||||
document.body.classList.toggle('ffz-theatre-conversations', this.settings.hide_conversations_in_theatre);
|
||||
|
||||
var ConvWindow = utils.ember_resolve('component:conversation-window');
|
||||
var ConvWindow = utils.ember_resolve('component:twitch-conversations/conversation-window');
|
||||
if ( ConvWindow ) {
|
||||
this.log("Hooking the Ember Conversation Window component.");
|
||||
this._modify_conversation_window(ConvWindow);
|
||||
try { ConvWindow.create().destroy() }
|
||||
catch(err) { }
|
||||
} else
|
||||
this.log("Unable to resolve: component:conversation-window");
|
||||
this.log("Unable to resolve: component:twitch-conversations/conversation-window");
|
||||
|
||||
|
||||
var ConvSettings = utils.ember_resolve('component:conversation-settings-menu');
|
||||
var ConvSettings = utils.ember_resolve('component:twitch-conversations/conversation-settings-menu');
|
||||
if ( ConvSettings ) {
|
||||
this.log("Hooking the Ember Conversation Settings Menu component.");
|
||||
this._modify_conversation_menu(ConvSettings);
|
||||
try { ConvSettings.create().destroy() }
|
||||
catch(err) { }
|
||||
} else
|
||||
this.log("Unable to resolve: component:conversation-settings-menu");
|
||||
this.log("Unable to resolve: component:twitch-conversations/conversation-settings-menu");
|
||||
|
||||
|
||||
var ConvLine = utils.ember_resolve('component:conversation-line');
|
||||
var ConvLine = utils.ember_resolve('component:twitch-conversations/conversation-line');
|
||||
if ( ConvLine ) {
|
||||
this.log("Hooking the Ember Conversation Line component.");
|
||||
this._modify_conversation_line(ConvLine);
|
||||
try { ConvLine.create().destroy() }
|
||||
catch(err) { }
|
||||
} else
|
||||
this.log("Unable to resolve: component:conversation-line");
|
||||
this.log("Unable to resolve: component:twitch-conversations/conversation-line");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -221,14 +221,11 @@ FFZ.prototype.setup_directory = function() {
|
|||
} else
|
||||
this.log("Unable to locate the Ember component:creative-preview");
|
||||
|
||||
var CSGOChannel = utils.ember_resolve('view:cs-go-channel');
|
||||
if ( CSGOChannel ) {
|
||||
this._modify_directory_live(CSGOChannel, true);
|
||||
try {
|
||||
CSGOChannel.create().destroy();
|
||||
} catch(err) { }
|
||||
} else
|
||||
this.log("Unable to locate the Ember view:cs-go-channel");
|
||||
var CSGOChannel = utils.ember_resolve('component:csgo-channel-preview');
|
||||
CSGOChannel = this._modify_directory_live(CSGOChannel, true, 'component:csgo-channel-preview');
|
||||
try {
|
||||
CSGOChannel.create().destroy();
|
||||
} catch(err) { }
|
||||
|
||||
var HostView = utils.ember_resolve('component:host-preview');
|
||||
HostView = this._modify_directory_host(HostView);
|
||||
|
@ -478,11 +475,11 @@ FFZ.prototype._modify_game_follow = function(component) {
|
|||
}
|
||||
|
||||
|
||||
FFZ.prototype._modify_directory_live = function(dir, is_csgo) {
|
||||
FFZ.prototype._modify_directory_live = function(dir, is_csgo, component_name) {
|
||||
var f = this,
|
||||
pref = is_csgo ? 'context.model.' : 'stream.';
|
||||
pref = is_csgo ? 'channel.' : 'stream.';
|
||||
|
||||
dir.reopen({
|
||||
var mutator = {
|
||||
didInsertElement: function() {
|
||||
this._super();
|
||||
this.ffzInit();
|
||||
|
@ -503,8 +500,7 @@ FFZ.prototype._modify_directory_live = function(dir, is_csgo) {
|
|||
el.classList.toggle('ffz-game-banned', f.settings.banned_games.indexOf(game && game.toLowerCase()) !== -1);
|
||||
el.classList.toggle('ffz-game-spoilered', f.settings.spoiler_games.indexOf(game && game.toLowerCase()) !== -1);
|
||||
|
||||
// CSGO doesn't provide the actual uptime information...
|
||||
if ( !is_csgo && f.settings.stream_uptime && f.settings.stream_uptime < 3 && cap ) {
|
||||
if (f.settings.stream_uptime && f.settings.stream_uptime < 3 && cap ) {
|
||||
var t_el = this._ffz_uptime = document.createElement('div');
|
||||
t_el.className = 'overlay_info length live';
|
||||
|
||||
|
@ -591,7 +587,16 @@ FFZ.prototype._modify_directory_live = function(dir, is_csgo) {
|
|||
this._ffz_uptime.innerHTML = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if ( dir )
|
||||
dir.reopen(mutator);
|
||||
else {
|
||||
dir = Ember.Component.extend(mutator);
|
||||
App.__deprecatedInstance__.registry.register(component_name, dir);
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -371,7 +371,6 @@ FFZ.settings_info.high_contrast_chat = {
|
|||
value: '222',
|
||||
|
||||
category: "Chat Appearance",
|
||||
no_bttv: true,
|
||||
|
||||
name: "High Contrast",
|
||||
help: "Display chat using white and black for maximum contrast. This is suitable for capturing and chroma keying chat to display on stream.",
|
||||
|
@ -385,9 +384,9 @@ FFZ.settings_info.high_contrast_chat = {
|
|||
},
|
||||
|
||||
on_update: function(val) {
|
||||
this.toggle_style('chat-hc-text', !this.has_bttv && val[2] === '1');
|
||||
this.toggle_style('chat-hc-bold', !this.has_bttv && val[1] === '1');
|
||||
this.toggle_style('chat-hc-background', !this.has_bttv && val[0] === '1');
|
||||
this.toggle_style('chat-hc-text', val[2] === '1');
|
||||
this.toggle_style('chat-hc-bold', val[1] === '1');
|
||||
this.toggle_style('chat-hc-background', val[0] === '1');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -588,9 +587,9 @@ FFZ.prototype.setup_line = function() {
|
|||
this.toggle_style('chat-separator-3d-inset', !this.has_bttv && this.settings.chat_separators === 3);
|
||||
this.toggle_style('chat-separator-wide', !this.has_bttv && this.settings.chat_separators === 4);
|
||||
|
||||
this.toggle_style('chat-hc-text', !this.has_bttv && this.settings.high_contrast_chat[2] === '1');
|
||||
this.toggle_style('chat-hc-bold', !this.has_bttv && this.settings.high_contrast_chat[1] === '1');
|
||||
this.toggle_style('chat-hc-background', !this.has_bttv && this.settings.high_contrast_chat[0] === '1');
|
||||
this.toggle_style('chat-hc-text', this.settings.high_contrast_chat[2] === '1');
|
||||
this.toggle_style('chat-hc-bold', this.settings.high_contrast_chat[1] === '1');
|
||||
this.toggle_style('chat-hc-background', this.settings.high_contrast_chat[0] === '1');
|
||||
|
||||
this._last_row = {};
|
||||
|
||||
|
|
|
@ -18,18 +18,18 @@ FFZ.settings_info.player_stats = {
|
|||
help: "Display your current stream latency (how far behind the broadcast you are) under the player, with a few useful statistics in a tooltip.",
|
||||
|
||||
on_update: function(val) {
|
||||
for(var key in this.players) {
|
||||
var player = this.players[key];
|
||||
if ( player && player.player && player.player.ffzSetStatsEnabled )
|
||||
player.player.ffzSetStatsEnabled(val || player.player.ffz_stats);
|
||||
}
|
||||
|
||||
if ( ! this._cindex )
|
||||
return;
|
||||
|
||||
this._cindex.ffzUpdatePlayerStats();
|
||||
for(var key in this.players) {
|
||||
var player = this.players[key];
|
||||
if ( player && player.player && player.player.ffzSetStatsEnabled )
|
||||
player.player.ffzSetStatsEnabled(val || player.player.ffz_stats);
|
||||
}
|
||||
};
|
||||
|
||||
if ( ! this._cindex )
|
||||
return;
|
||||
|
||||
this._cindex.ffzUpdatePlayerStats();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
FFZ.settings_info.classic_player = {
|
||||
|
@ -37,18 +37,32 @@ FFZ.settings_info.classic_player = {
|
|||
value: false,
|
||||
no_mobile: true,
|
||||
|
||||
category: "Appearance",
|
||||
category: "Player",
|
||||
|
||||
name: "Classic Player",
|
||||
help: "Alter the appearance of the player to resemble the older Twitch player with always visible controls.",
|
||||
|
||||
on_update: function(val) {
|
||||
document.body.classList.toggle('ffz-classic-player', val);
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
if ( Layout )
|
||||
Layout.set('PLAYER_CONTROLS_HEIGHT', val ? 32 : 0);
|
||||
}
|
||||
};
|
||||
utils.toggle_cls('ffz-classic-player')(val);
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
if ( Layout )
|
||||
Layout.set('PLAYER_CONTROLS_HEIGHT', val ? 32 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
FFZ.settings_info.player_volume_bar = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
no_mobile: true,
|
||||
|
||||
category: "Player",
|
||||
|
||||
name: "Volume Always Expanded",
|
||||
help: "Keep the volume slider expanded even when not hovering over it with the mouse.",
|
||||
|
||||
on_update: utils.toggle_cls('ffz-player-volume')
|
||||
};
|
||||
|
||||
|
||||
// ---------------
|
||||
|
@ -56,7 +70,9 @@ FFZ.settings_info.classic_player = {
|
|||
// ---------------
|
||||
|
||||
FFZ.prototype.setup_player = function() {
|
||||
document.body.classList.toggle('ffz-classic-player', this.settings.classic_player);
|
||||
utils.toggle_cls('ffz-player-volume')(this.settings.player_volume_bar);
|
||||
utils.toggle_cls('ffz-classic-player')(this.settings.classic_player);
|
||||
|
||||
var Layout = utils.ember_lookup('controller:layout');
|
||||
if ( Layout )
|
||||
Layout.set('PLAYER_CONTROLS_HEIGHT', this.settings.classic_player ? 32 : 0);
|
||||
|
@ -164,10 +180,6 @@ FFZ.prototype._modify_player = function(player) {
|
|||
var stats = this.$('.player .js-playback-stats');
|
||||
stats.draggable({cancel: 'li', containment: 'parent'});
|
||||
|
||||
/*// Give the player time to do stuff before we change this
|
||||
// text. It's a bit weird otherwise.
|
||||
setTimeout(function(){stats.children('.js-stats-toggle').html(constants.CLOSE);},500);*/
|
||||
|
||||
|
||||
// Only set up the stats hooks if we need stats.
|
||||
var has_video = false;
|
||||
|
|
|
@ -6,6 +6,7 @@ var FFZ = window.FrankerFaceZ,
|
|||
|
||||
STATUS_BADGES = [
|
||||
["r9k", "r9k", "This room is in R9K-mode."],
|
||||
["emote", "emoteOnly", "This room is in Twitch emoticons only mode. Emoticons added by extensions are not available in this mode."],
|
||||
["sub", "subsOnly", "This room is in subscribers-only mode."],
|
||||
["slow", "slow", function(room) { return "This room is in slow mode. You may send messages every " + utils.number_commas(room && room.get('slow') || 120) + " seconds." }],
|
||||
["ban", "ffz_banned", "You have been banned from talking in this room."],
|
||||
|
@ -245,6 +246,9 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
id = 'ffz-stat-' + info[0];
|
||||
badge = cont.querySelector('#' + id);
|
||||
visible = typeof info[1] === "function" ? info[1].call(f, room) : room && room.get(info[1]);
|
||||
if ( typeof visible === "string" )
|
||||
visible = visible === "1";
|
||||
|
||||
if ( ! badge ) {
|
||||
badge = utils.createElement('span', 'ffz room-state stat float-right', info[0].charAt(0).toUpperCase() + '<span>' + info[0].substr(1).toUpperCase() + '</span>');
|
||||
badge.id = id;
|
||||
|
@ -972,17 +976,17 @@ FFZ.prototype._modify_room = function(room) {
|
|||
var t = this;
|
||||
|
||||
if ( user ) {
|
||||
var duration = undefined,
|
||||
var duration = Infinity,
|
||||
reason = undefined,
|
||||
current_user = f.get_user(),
|
||||
is_me = current_user && current_user.login === user;
|
||||
|
||||
|
||||
// Read the ban duration and reason from the message tags.
|
||||
if ( tags && tags['ban-duration'] )
|
||||
duration = parseInt(tags['ban-duration']);
|
||||
else if ( tags && ! tags.hasOwnProperty('ban-duration') )
|
||||
duration = true;
|
||||
|
||||
if ( isNaN(duration) )
|
||||
duration = Infinity;
|
||||
|
||||
if ( tags && tags['ban-reason'] && (is_me || t.get('isModeratorOrHigher')) )
|
||||
reason = tags['ban-reason'];
|
||||
|
@ -1046,44 +1050,98 @@ FFZ.prototype._modify_room = function(room) {
|
|||
}
|
||||
|
||||
|
||||
// Look up the User's Last Ban
|
||||
// TODO: STUFF and THINGS
|
||||
var room = f.rooms && f.rooms[t.get('id')],
|
||||
ban_history, last_ban, identical_ban;
|
||||
// Now we need to see about displaying a ban notice.
|
||||
if ( ! disable_log ) {
|
||||
// Look up the user's last ban.
|
||||
var show_notice = is_me || this.ffzShouldDisplayNotice(),
|
||||
show_reason = is_me || this.get('isModeratorOrHigher'),
|
||||
room = f.rooms && f.rooms[t.get('id')],
|
||||
now = new Date,
|
||||
end_time = now + (duration * 1000),
|
||||
ban_history, last_ban;
|
||||
|
||||
if ( room ) {
|
||||
var now = Date.now();
|
||||
ban_history = room.ban_history = room.ban_history || {};
|
||||
last_ban = ban_history[user];
|
||||
identical_ban = (now - last_ban[2] >= 1000*(typeof last_ban[0] === "number" ? Math.min(last_ban[0], 10) : 10));
|
||||
ban_history[user] = [duration, reason, now];
|
||||
}
|
||||
if ( room ) {
|
||||
ban_history = room.ban_history = room.ban_history || {};
|
||||
last_ban = ban_history[user];
|
||||
|
||||
// Only overwrite a ban in the last 15 seconds.
|
||||
if ( ! last_ban || Math.abs(now - last_ban.date) > 15000 )
|
||||
last_ban = null;
|
||||
}
|
||||
|
||||
// Display a notice in chat.
|
||||
var message = (is_me ? "You have" : FFZ.get_capitalization(user) + " has") + " been " + (isFinite(duration) ? "timed out for " + utils.duration_string(duration, true) : "banned");
|
||||
|
||||
if ( show_notice ) {
|
||||
if ( ! last_ban ) {
|
||||
var msg = {
|
||||
style: "admin",
|
||||
date: now,
|
||||
ffz_ban_target: user,
|
||||
reasons: reason ? [reason] : [],
|
||||
durations: [duration],
|
||||
end_time: end_time,
|
||||
timeouts: 1,
|
||||
message: message + (show_reason && reason ? ' with reason: ' + reason : '.')
|
||||
};
|
||||
|
||||
if ( ban_history )
|
||||
ban_history[user] = msg;
|
||||
|
||||
this.addMessage(msg);
|
||||
|
||||
} else {
|
||||
if ( reason && last_ban.reasons.indexOf(reason) === -1 )
|
||||
last_ban.reasons.push(reason);
|
||||
|
||||
if ( last_ban.durations.indexOf(duration) === -1 )
|
||||
last_ban.durations.push(duration);
|
||||
|
||||
last_ban.end_time = end_time;
|
||||
last_ban.timeouts++;
|
||||
|
||||
last_ban.message = message + ' ' + utils.number_commas(last_ban.timeouts) + ' times' + (!show_reason || last_ban.reasons.length === 0 ? '.' : ' with reason' + utils.pluralize(last_ban.reasons.length) + ': ' + last_ban.reasons.join(', '));
|
||||
last_ban.cachedTokens = [{type: "text", text: last_ban.message}];
|
||||
|
||||
// Now that we've reset the tokens, if there's a line for this,
|
||||
if ( last_ban._line )
|
||||
Ember.propertyDidChange(last_ban._line, 'tokenizedMessage');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Show a Notice
|
||||
var message = (is_me ? 'You have' : FFZ.get_capitalization(user) + ' has') + ' been ' + (duration === undefined ? 'timed out' : duration === true ? 'banned' : 'timed out for ' + utils.number_commas(duration) + utils.pluralize(' second'));
|
||||
if ( ! identical_ban && ! disable_log && (is_me || this.ffzShouldDisplayNotice()) )
|
||||
this.addTmiMessage(message + (reason ? ' with reason: ' + reason : '.'));
|
||||
// Mod Card History
|
||||
if ( room && f.settings.mod_card_history ) {
|
||||
var chat_history = room.user_history = room.user_history || {},
|
||||
user_history = room.user_history[user] = room.user_history[user] || [],
|
||||
last_ban = user_history.length > 0 ? user_history[user_history.length-1] : null;
|
||||
|
||||
if ( ! last_ban || ! last_ban.is_delete || Math.abs(now - last_ban.date) > 15000 )
|
||||
last_ban = null;
|
||||
|
||||
// Mod Card History
|
||||
if ( room && f.settings.mod_card_history && ! disable_log ) {
|
||||
var chat_history = room.user_history = room.user_history || {},
|
||||
user_history = room.user_history[user] = room.user_history[user] || [],
|
||||
if ( last_ban )
|
||||
last_ban.cachedTokens = [message + ' ' + utils.number_commas(last_ban.timeouts) + ' times' + (last_ban.reasons.length === 0 ? '.' : ' with reason' + utils.pluralize(last_ban.reasons.length) + ': ' + last_ban.reasons.join(', '))];
|
||||
else {
|
||||
user_history.push({
|
||||
from: 'jtv',
|
||||
is_delete: true,
|
||||
style: 'admin',
|
||||
date: now,
|
||||
ffz_ban_target: user,
|
||||
reasons: reason ? [reason] : [],
|
||||
durations: [duration],
|
||||
end_time: end_time,
|
||||
timeouts: 1,
|
||||
cachedTokens: message + (reason ? ' with reason: ' + reason : '.')
|
||||
})
|
||||
|
||||
has_delete = false,
|
||||
last = user_history.length > 0 ? user_history[user_history.length-1] : null;
|
||||
|
||||
has_delete = last !== null && last.is_delete;
|
||||
if ( has_delete && (identical_ban || (! last.has_reason && ! reason)) ) {
|
||||
last.cachedTokens = [message + ' ' + utils.number_commas(++last.deleted_times) + ' times' + (reason ? ' with reason: ' + utils.sanitize(reason) : '.')];
|
||||
} else {
|
||||
user_history.push({from: 'jtv', is_delete: true, style: 'admin', cachedTokens: [message + (reason ? ' with reason: ' + utils.sanitize(reason) : '.')], has_reason: reason !== undefined, deleted_times: 1, date: new Date()});
|
||||
while ( user_history.length > 20 )
|
||||
user_history.shift();
|
||||
while ( user_history.length > 20 )
|
||||
user_history.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if ( f.settings.prevent_clear )
|
||||
this.addTmiMessage("A moderator's attempt to clear chat was ignored.");
|
||||
|
@ -1321,7 +1379,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
// Report this message to the dashboard.
|
||||
if ( window !== window.parent && parent.postMessage && msg.from && msg.from !== "jtv" && msg.from !== "twitchnotify" )
|
||||
parent.postMessage({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, location.protocol + "//www.twitch.tv/");
|
||||
parent.postMessage({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, "*"); //location.protocol + "//www.twitch.tv/");
|
||||
|
||||
// Add the message.
|
||||
return this._super(msg);
|
||||
|
@ -1438,7 +1496,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
f._cindex.ffzUpdateChatters();
|
||||
|
||||
if ( window !== window.parent && parent.postMessage )
|
||||
parent.postMessage({from_ffz: true, command: 'chatter_count', data: Object.keys(this.get('ffz_chatters') || {}).length}, location.protocol + "//www.twitch.tv/");
|
||||
parent.postMessage({from_ffz: true, command: 'chatter_count', data: Object.keys(this.get('ffz_chatters') || {}).length}, "*"); //location.protocol + "//www.twitch.tv/");
|
||||
},
|
||||
|
||||
|
||||
|
@ -1446,37 +1504,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
var tmi = this.get('tmiRoom'),
|
||||
room = this;
|
||||
|
||||
// Re-bind clearChat
|
||||
Ember.run.next(function(){
|
||||
tmi = room.get('tmiRoom');
|
||||
if ( ! tmi || room.get('ffz_clearchat_patch') )
|
||||
return;
|
||||
|
||||
var func = function(user, tags) { room.clearMessages(user, tags) };
|
||||
if ( room && room._callbacks ) {
|
||||
for(var i=0; i < room._callbacks.length; i++) {
|
||||
var cb = room._callbacks[i];
|
||||
if ( cb && cb.eventName === "clearchat" ) {
|
||||
room._callbacks.splice(i, 1);
|
||||
tmi.off("clearchat", cb.callback);
|
||||
}
|
||||
}
|
||||
|
||||
room._callbacks.push({
|
||||
emitter: tmi,
|
||||
eventName: "clearchat",
|
||||
callback: func
|
||||
});
|
||||
} else {
|
||||
f.log("Room Not Fully Initialized -- Expect Double Timeouts", room);
|
||||
tmi.off("clearchat");
|
||||
}
|
||||
|
||||
tmi.on("clearchat", func);
|
||||
room.set('ffz_clearchat_patch', true);
|
||||
});
|
||||
|
||||
if ( this.get('ffz_is_patched') || ! this.get('tmiRoom') )
|
||||
if ( this.get('ffz_is_patched') || ! tmi )
|
||||
return;
|
||||
|
||||
if ( f.settings.chatter_count )
|
||||
|
|
|
@ -49,7 +49,16 @@ FFZ.prototype.setup_bttv = function(delay) {
|
|||
}
|
||||
|
||||
document.body.classList.add('ffz-bttv');
|
||||
document.body.classList.toggle('ffz-bttv-dark', BetterTTV.settings.get('darkenedMode'));
|
||||
|
||||
var last_dark = BetterTTV.settings.get('darkenedMode');
|
||||
document.body.classList.toggle('ffz-bttv-dark', last_dark);
|
||||
setInterval(function() {
|
||||
var new_dark = BetterTTV.settings.get('darkenedMode');
|
||||
if ( new_dark !== last_dark ) {
|
||||
document.body.classList.toggle('ffz-bttv-dark', new_dark);
|
||||
last_dark = new_dark;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
// Disable Chat Tabs
|
||||
if ( this._chatv ) {
|
||||
|
@ -82,9 +91,9 @@ FFZ.prototype.setup_bttv = function(delay) {
|
|||
this.toggle_style('chat-separator-3d-inset');
|
||||
this.toggle_style('chat-separator-wide');
|
||||
|
||||
this.toggle_style('chat-hc-text');
|
||||
/*this.toggle_style('chat-hc-text');
|
||||
this.toggle_style('chat-hc-bold');
|
||||
this.toggle_style('chat-hc-background');
|
||||
this.toggle_style('chat-hc-background');*/
|
||||
|
||||
this.toggle_style('chat-colors-gray');
|
||||
this.toggle_style('badges-transparent');
|
||||
|
|
33
src/main.js
33
src/main.js
|
@ -37,7 +37,7 @@ FFZ.msg_commands = {};
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 176,
|
||||
major: 3, minor: 5, revision: 182,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
@ -172,6 +172,7 @@ require('./ext/emote_menu');
|
|||
|
||||
require('./featurefriday');
|
||||
|
||||
//require('./ui/chatpane');
|
||||
require('./ui/popups');
|
||||
require('./ui/styles');
|
||||
require('./ui/dark');
|
||||
|
@ -201,32 +202,24 @@ FFZ.prototype.initialize = function(increment, delay) {
|
|||
// Make sure that FrankerFaceZ doesn't start setting itself up until the
|
||||
// Twitch ember application is ready.
|
||||
|
||||
// Pages we don't want to interact with at all.
|
||||
if ( location.hostname === 'passport.twitch.tv' || /^\/user\/two_factor/.test(location.pathname) ) {
|
||||
this.log("Found authentication sub-page. Not initializing.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for the player
|
||||
if ( location.hostname === 'player.twitch.tv' ) {
|
||||
this.init_player(delay);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Check for the transfer page.
|
||||
if ( location.pathname === "/crossdomain/transfer" ) {
|
||||
if ( location.hash.indexOf("ffz-settings-transfer") !== -1 )
|
||||
this.init_settings_transfer();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for special non-ember pages.
|
||||
if ( /^\/(?:$|search$|user\/|p\/|settings|m\/|messages?\/)/.test(location.pathname) ) {
|
||||
this.init_normal(delay);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( location.hostname === 'passport' && /^\/(?:authorize)/.test(location.pathname) ) {
|
||||
this.log("Running on passport!");
|
||||
this.init_normal(delay, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for the dashboard.
|
||||
if ( /\/[^\/]+\/dashboard/.test(location.pathname) && !/bookmarks$/.test(location.pathname) ) {
|
||||
this.init_dashboard(delay);
|
||||
|
@ -248,16 +241,6 @@ FFZ.prototype.initialize = function(increment, delay) {
|
|||
}
|
||||
|
||||
|
||||
FFZ.prototype.init_settings_transfer = function() {
|
||||
this.log("This is the HTTP Transfer URL. Building a settings backup and posting it to our parent.");
|
||||
this.load_settings();
|
||||
try { this.setup_line(); } catch(err) { }
|
||||
var msg = {from_ffz: true, command: "http_settings", data: this._get_settings_object()};
|
||||
window.opener.postMessage(msg, "https://www.twitch.tv");
|
||||
window.close();
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.init_player = function(delay) {
|
||||
var start = (window.performance && performance.now) ? performance.now() : Date.now();
|
||||
this.log("Found Twitch Player after " + (delay||0) + " ms at: " + location);
|
||||
|
|
|
@ -72,15 +72,6 @@ FFZ.prototype.load_settings = function() {
|
|||
// Backup and Restore
|
||||
// --------------------
|
||||
|
||||
FFZ.prototype._settings_open_http_window = function() {
|
||||
window.open("http://www.twitch.tv/crossdomain/transfer#ffz-settings-transfer", "_ffz_settings");
|
||||
}
|
||||
|
||||
FFZ.msg_commands.http_settings = function(data) {
|
||||
this._load_settings_file(data);
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.reset_settings = function() {
|
||||
if ( ! confirm(this.tr('Are you sure you wish to reset FrankerFaceZ?\n\nThis will force the tab to refresh.')) )
|
||||
return;
|
||||
|
@ -472,10 +463,6 @@ FFZ.menu_pages.settings = {
|
|||
backup_link = createElement('a'),
|
||||
backup_help = createElement('span'),
|
||||
|
||||
http_para = createElement('p'),
|
||||
http_link = createElement('a'),
|
||||
http_help = createElement('span'),
|
||||
|
||||
restore_para = createElement('p'),
|
||||
restore_input = createElement('input'),
|
||||
restore_link = createElement('a'),
|
||||
|
@ -526,20 +513,6 @@ FFZ.menu_pages.settings = {
|
|||
restore_para.appendChild(restore_help);
|
||||
restore_cont.appendChild(restore_para);
|
||||
|
||||
http_para.className = 'clearfix option';
|
||||
http_link.href = '#';
|
||||
http_link.innerHTML = 'Import from HTTP';
|
||||
http_link.addEventListener('click', this._settings_open_http_window.bind(this));
|
||||
|
||||
http_help.className = 'help';
|
||||
http_help.innerHTML = 'Load your settings from HTTP into HTTPS. (This briefly opens a new window.)';
|
||||
|
||||
http_para.appendChild(http_link);
|
||||
http_para.appendChild(http_help);
|
||||
|
||||
if ( location.protocol === "https:" )
|
||||
restore_cont.appendChild(http_para);
|
||||
|
||||
reset_cont.className = 'chat-menu-content';
|
||||
reset_head.className = 'heading';
|
||||
reset_head.innerHTML = this.tr('Reset Settings');
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/* High-Contrast Background */
|
||||
body.ffz-bttv .chat-container,
|
||||
body.ffz-bttv .ember-chat.roomMode,
|
||||
body.ffz-bttv .chat-messages,
|
||||
.chat-container,
|
||||
.ember-chat-container {
|
||||
background-color: #fff !important;
|
||||
|
@ -6,6 +9,9 @@
|
|||
|
||||
|
||||
/* Dark: High-Contrast Background */
|
||||
body.ffz-bttv-dark .chat-messages,
|
||||
body.ffz-bttv-dark .chat-header,
|
||||
body.ffz-bttv-dark .chat-interface,
|
||||
.theatre .chat-container,
|
||||
.theatre .ember-chat-container,
|
||||
.chat-container.dark,
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/* High-Contrast Text */
|
||||
body.ffz-bttv .chat-line .message,
|
||||
body.ffz-bttv .chat-line .timestamp,
|
||||
|
||||
.chat-container,
|
||||
.ember-chat-container {
|
||||
color: #000 !important;
|
||||
|
@ -12,6 +15,10 @@
|
|||
.ember-chat-container.dark,
|
||||
.ember-chat-container.force-dark,
|
||||
|
||||
body.ffz-bttv-dark .chat-container,
|
||||
body.ffz-bttv-dark .chat-line .message,
|
||||
body.ffz-bttv-dark .chat-line .timestamp,
|
||||
|
||||
.ffz-dark .ember-chat-container.dark .chat-line,
|
||||
.ffz-dark .chat-container.dark .chat-line
|
||||
{
|
||||
|
|
|
@ -147,13 +147,18 @@ FFZ.prototype.setup_tokenization = function() {
|
|||
|
||||
this.load_twitch_emote_data();
|
||||
|
||||
helpers = window.require && window.require("ember-twitch-chat/helpers/chat-line-helpers");
|
||||
try {
|
||||
helpers = window.require && window.require("ember-twitch-chat/helpers/chat-line-helpers");
|
||||
} catch(err) { }
|
||||
|
||||
if ( ! helpers )
|
||||
return this.log("Unable to get chat helper functions.");
|
||||
|
||||
conv_helpers = window.require && window.require("ember-twitch-conversations/helpers/conversation-line-helpers");
|
||||
if ( ! conv_helpers )
|
||||
this.log("Unable to get conversation helper functions.");
|
||||
try {
|
||||
conv_helpers = window.require && window.require("web-client/helpers/twitch-conversations/conversation-line-helpers");
|
||||
} catch(err) {
|
||||
this.error("Unable to get conversation helper functions.", err);
|
||||
}
|
||||
|
||||
this.log("Hooking Ember chat line helpers.");
|
||||
|
||||
|
|
|
@ -208,17 +208,13 @@ FFZ.prototype.build_ui_popup = function(view) {
|
|||
// Start building the DOM.
|
||||
var container = document.createElement('div'),
|
||||
inner = document.createElement('div'),
|
||||
menu = document.createElement('ul'),
|
||||
|
||||
dark = (this.has_bttv ? BetterTTV.settings.get('darkenedMode') : false);
|
||||
menu = document.createElement('ul');
|
||||
|
||||
container.className = 'emoticon-selector chat-menu ffz-ui-popup';
|
||||
container.id = 'ffz-chat-menu';
|
||||
inner.className = 'emoticon-selector-box dropmenu';
|
||||
container.appendChild(inner);
|
||||
|
||||
container.classList.toggle('dark', dark);
|
||||
|
||||
// Stuff
|
||||
//jQuery(inner).find('.html-tooltip').tipsy({live: true, html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 's')});
|
||||
//jQuery(inner).find('.ffz-tooltip').tipsy({live: true, html: true, title: this.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
|
||||
|
|
|
@ -28,7 +28,6 @@ FFZ.prototype.update_ui_link = function(link) {
|
|||
room = this.rooms[room_id],
|
||||
has_emotes = false,
|
||||
|
||||
dark = (this.has_bttv ? BetterTTV.settings.get('darkenedMode') : false),
|
||||
blue = (this.has_bttv ? BetterTTV.settings.get('showBlueButtons') : false),
|
||||
live = (this.feature_friday && this.feature_friday.live);
|
||||
|
||||
|
@ -42,7 +41,6 @@ FFZ.prototype.update_ui_link = function(link) {
|
|||
|
||||
link.classList.toggle('no-emotes', ! has_emotes);
|
||||
link.classList.toggle('live', live);
|
||||
link.classList.toggle('dark', dark);
|
||||
link.classList.toggle('blue', blue);
|
||||
//link.classList.toggle('news', this._has_news);
|
||||
}
|
17
src/utils.js
17
src/utils.js
|
@ -216,10 +216,15 @@ var sanitize_el = document.createElement('span'),
|
|||
if ( ! window.App )
|
||||
return;
|
||||
|
||||
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.lookup )
|
||||
return App.__deprecatedInstance__.registry.lookup(thing);
|
||||
if ( App.__container__ && App.__container__.lookup )
|
||||
return App.__container__.lookup(thing);
|
||||
try {
|
||||
if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.lookup )
|
||||
return App.__deprecatedInstance__.registry.lookup(thing);
|
||||
if ( App.__container__ && App.__container__.lookup )
|
||||
return App.__container__.lookup(thing);
|
||||
} catch(err) {
|
||||
FrankerFaceZ.get().error("There was an error looking up an Ember instance: " + thing, err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -432,8 +437,8 @@ module.exports = FFZ.utils = {
|
|||
return (days||'') + ((!no_hours || days || hours) ? ((days && hours < 10 ? "0" : "") + hours + ':') : '') + (minutes < 10 ? "0" : "") + minutes + (no_seconds ? "" : (":" + (seconds < 10 ? "0" : "") + seconds));
|
||||
},
|
||||
|
||||
duration_string: function(val) {
|
||||
if ( val === 1 )
|
||||
duration_string: function(val, no_purge) {
|
||||
if ( ! no_purge && val === 1 )
|
||||
return 'Purge';
|
||||
|
||||
if ( DURATIONS[val] )
|
||||
|
|
127
style.css
127
style.css
|
@ -53,12 +53,12 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic
|
|||
.ember-chat-container.dark .ffz-ui-toggle svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle svg.svg-emoticons path,
|
||||
.ffz-ui-toggle.dark svg.svg-emoticons path { fill: #888; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle svg.svg-emoticons path { fill: #888; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle:hover svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle:hover svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle:hover svg.svg-emoticons path,
|
||||
.ffz-ui-toggle.dark:hover svg.svg-emoticons path { fill: #777; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle:hover svg.svg-emoticons path { fill: #777; }
|
||||
|
||||
|
||||
.ffz-ui-toggle.no-emotes svg.svg-emoticons path { fill: rgba(80,0,0,0.2); }
|
||||
|
@ -73,44 +73,44 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic
|
|||
.ember-chat-container.dark .ffz-ui-toggle.news svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.news svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.news svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.news svg.svg-emoticons path,
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.news svg.svg-emoticons path,
|
||||
.ffz-ui-toggle.news svg.svg-emoticons path { fill: rgba(117, 80, 0, 0.5); }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.news:hover svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.news:hover svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.news:hover svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.news:hover svg.svg-emoticons path,
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.news:hover svg.svg-emoticons path,
|
||||
.ffz-ui-toggle.news:hover svg.svg-emoticons path { fill: rgba(117, 80, 0, 0.8); }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.no-emotes svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.no-emotes svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.no-emotes svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.no-emotes svg.svg-emoticons path { fill: #453434; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.no-emotes svg.svg-emoticons path { fill: #453434; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.no-emotes:hover svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.no-emotes:hover svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.no-emotes:hover svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.no-emotes:hover svg.svg-emoticons path { fill: #543f3f; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.no-emotes:hover svg.svg-emoticons path { fill: #543f3f; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.live svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.live svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.live svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.live svg.svg-emoticons path { fill: #513c78; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.live svg.svg-emoticons path { fill: #513c78; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.live:hover svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.live:hover svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.live:hover svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.live:hover svg.svg-emoticons path { fill: #5b4487; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.live:hover svg.svg-emoticons path { fill: #5b4487; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.blue.live svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.blue.live svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.blue.live svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.blue.live svg.svg-emoticons path { fill: #3c4e78; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.blue.live svg.svg-emoticons path { fill: #3c4e78; }
|
||||
|
||||
.ember-chat-container.dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path,
|
||||
.app-main.theatre .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path,
|
||||
.chat-container.dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path,
|
||||
.ember-chat .chat-interface .textarea-contain .ffz-ui-toggle.dark.blue.live:hover svg.svg-emoticons path { fill: #445887; }
|
||||
body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill: #445887; }
|
||||
|
||||
|
||||
.ffz-ui-toggle.live {
|
||||
|
@ -741,7 +741,7 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic
|
|||
.chat-container.force-dark .ffz-ui-popup ul.menu,
|
||||
.ember-chat-container.dark .ffz-ui-popup ul.menu,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup ul.menu,
|
||||
.ffz-ui-popup.dark ul.menu {
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu {
|
||||
background-color: #282828;
|
||||
}
|
||||
|
||||
|
@ -766,7 +766,7 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic
|
|||
.chat-container.force-dark .ffz-ui-popup ul.sub-menu,
|
||||
.ember-chat-container.dark .ffz-ui-popup ul.sub-menu,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup ul.sub-menu,
|
||||
.ffz-ui-popup.dark ul.sub-menu {
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.sub-menu {
|
||||
background-color: #181818;
|
||||
}
|
||||
|
||||
|
@ -780,7 +780,7 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic
|
|||
.chat-container.force-dark .ffz-ui-popup ul.sub-menu a,
|
||||
.ember-chat-container.dark .ffz-ui-popup ul.sub-menu a,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup ul.sub-menu a,
|
||||
.ffz-ui-popup.dark ul.sub-menu a {
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.sub-menu a {
|
||||
color: #d3d3d3 !important;
|
||||
}
|
||||
|
||||
|
@ -822,13 +822,13 @@ span.ffz-handle:after { left: 8px }
|
|||
.chat-container.force-dark span.ffz-handle:before,
|
||||
.ember-chat-container.dark span.ffz-handle:before,
|
||||
.ember-chat-container.force-dark span.ffz-handle:before,
|
||||
.ffz-ui-popup.dark span.ffz-handle:before,
|
||||
body.ffz-bttv-dark .ffz-ui-popup span.ffz-handle:before,
|
||||
.app-main.theatre span.ffz-handle:after,
|
||||
.chat-container.dark span.ffz-handle:after,
|
||||
.chat-container.force-dark span.ffz-handle:after,
|
||||
.ember-chat-container.dark span.ffz-handle:after,
|
||||
.ember-chat-container.force-dark span.ffz-handle:after,
|
||||
.ffz-ui-popup.dark span.ffz-handle:after {
|
||||
body.ffz-bttv-dark .ffz-ui-popup span.ffz-handle:after {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
|
@ -837,13 +837,13 @@ span.ffz-handle:after { left: 8px }
|
|||
.chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ember-chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ffz-ui-popup.ui-moved.dark span.ffz-handle:before,
|
||||
body.ffz-bttv-dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.app-main.theatre .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.ember-chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.ember-chat-container.force-dark .ffz-ui-popup.ui-moved span.ffz-handle:after,
|
||||
.ffz-ui-popup.ui-moved.dark span.ffz-handle:after {
|
||||
body.ffz-bttv-dark .ffz-ui-popup.ui-moved span.ffz-handle:after {
|
||||
border-color: #d3d3d3;
|
||||
}
|
||||
|
||||
|
@ -878,9 +878,9 @@ span.ffz-handle:after { left: 8px }
|
|||
border-right: 1px solid rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.ffz-ui-popup.dark ul.menu { border-top-color: rgba(255,255,255,0.1) }
|
||||
.ffz-ui-popup.dark ul.menu a { border-left-color: rgba(255,255,255,0.1) }
|
||||
.ffz-ui-popup.dark ul.sub-menu a { border-right-color: rgba(255,255,255,0.1) }
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu { border-top-color: rgba(255,255,255,0.1) }
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu a { border-left-color: rgba(255,255,255,0.1) }
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.sub-menu a { border-right-color: rgba(255,255,255,0.1) }
|
||||
|
||||
.ffz-ui-popup ul.menu li.active {
|
||||
background-color: #fff;
|
||||
|
@ -904,7 +904,7 @@ span.ffz-handle:after { left: 8px }
|
|||
.ember-chat-container.dark .chat-interface .ffz-ui-popup ul.menu li.active,
|
||||
.ember-chat-container.force-dark .chat-interface .ffz-ui-popup ul.menu li.active,
|
||||
.app-main.theatre .chat-container .chat-interface .ffz-ui-popup ul.menu li.active,
|
||||
.ffz-ui-popup.dark ul.menu li.active {
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu li.active {
|
||||
background-color: rgb(16,16,16);
|
||||
}
|
||||
|
||||
|
@ -913,7 +913,7 @@ span.ffz-handle:after { left: 8px }
|
|||
.ember-chat-container.dark .chat-interface .ffz-ui-popup ul.menu li.active a,
|
||||
.ember-chat-container.force-dark .chat-interface .ffz-ui-popup ul.menu li.active a,
|
||||
.app-main.theatre .chat-container .chat-interface .ffz-ui-popup ul.menu li.active a,
|
||||
.ffz-ui-popup.dark ul.menu li.active a {
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu li.active a {
|
||||
border-top-color: rgb(16,16,16);
|
||||
}
|
||||
|
||||
|
@ -922,7 +922,7 @@ span.ffz-handle:after { left: 8px }
|
|||
.ember-chat-container.dark .chat-interface .ffz-ui-popup ul.menu li.active.has-sub-menu,
|
||||
.ember-chat-container.force-dark .chat-interface .ffz-ui-popup ul.menu li.active.has-sub-menu,
|
||||
.app-main.theatre .chat-container .chat-interface .ffz-ui-popup ul.menu li.active.has-sub-menu,
|
||||
.ffz-ui-popup.dark ul.menu li.active.has-sub-menu {
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu li.active.has-sub-menu {
|
||||
background-color: #181818;
|
||||
}
|
||||
|
||||
|
@ -931,7 +931,7 @@ span.ffz-handle:after { left: 8px }
|
|||
.ember-chat-container.dark .chat-interface .ffz-ui-popup ul.menu li.active.has-sub-menu a,
|
||||
.ember-chat-container.force-dark .chat-interface .ffz-ui-popup ul.menu li.active.has-sub-menu a,
|
||||
.app-main.theatre .chat-container .chat-interface .ffz-ui-popup ul.menu li.active.has-sub-menu a,
|
||||
.ffz-ui-popup.dark ul.menu li.active.has-sub-menu a {
|
||||
body.ffz-bttv-dark .ffz-ui-popup li.active.has-sub-menu a {
|
||||
border-top-color: #181818;
|
||||
}
|
||||
|
||||
|
@ -940,7 +940,7 @@ span.ffz-handle:after { left: 8px }
|
|||
.ember-chat-container.dark .chat-interface .ffz-ui-popup a,
|
||||
.ember-chat-container.force-dark .chat-interface .ffz-ui-popup a,
|
||||
.app-main.theatre .chat-container .chat-interface .ffz-ui-popup a,
|
||||
.ffz-ui-popup.dark .ffz-ui-menu-page a { color: #fff; }
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page a { color: #fff; }
|
||||
|
||||
|
||||
.chat-container.dark .chat-interface .ffz-ui-popup ul.menu svg path,
|
||||
|
@ -949,7 +949,7 @@ span.ffz-handle:after { left: 8px }
|
|||
.ember-chat-container.force-dark .chat-interface .ffz-ui-popup ul.menu svg path,
|
||||
.app-main.theatre .chat-container .chat-interface .ffz-ui-popup ul.menu svg path,
|
||||
.ffz-dark .ffz-ui-popup ul.menu svg path,
|
||||
.ffz-ui-popup.dark ul.menu svg path { fill: #d3d3d3; }
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu svg path { fill: #d3d3d3; }
|
||||
|
||||
.ffz-ui-popup ul.menu svg path { fill: #333; }
|
||||
|
||||
|
@ -970,24 +970,24 @@ span.ffz-handle:after { left: 8px }
|
|||
padding-top: 8px !important;
|
||||
}
|
||||
|
||||
.ffz-ui-popup.dark .emoticon-grid .heading,
|
||||
.ffz-ui-popup.dark li.title { color: #fff; }
|
||||
.ffz-ui-popup.dark .ffz-ui-menu-page { background-color: #101010; }
|
||||
body.ffz-bttv-dark .ffz-ui-popup .emoticon-grid .heading,
|
||||
body.ffz-bttv-dark .ffz-ui-popup li.title { color: #fff; }
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page { background-color: #101010; }
|
||||
.ffz-bttv .ffz-ui-popup .chat-menu-content p a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ffz-bttv .ffz-ui-popup.dark ul.menu,
|
||||
.ffz-bttv .ffz-ui-popup.dark .ffz-ui-menu-page { margin: 0 }
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu,
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page { margin: 0 }
|
||||
|
||||
.ffz-ui-popup.dark .ffz-ui-menu-page .chat-menu-content .heading,
|
||||
.ffz-ui-popup.dark .ffz-ui-menu-page .emoticon-grid .heading {
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page .chat-menu-content .heading,
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page .emoticon-grid .heading {
|
||||
border-color: rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
.ffz-ui-popup.dark ul.menu:not(.sub-menu),
|
||||
.ffz-ui-popup.dark .ffz-ui-menu-page { border: 1px solid rgba(255,255,255,0.1) }
|
||||
.ffz-ui-popup.dark .ffz-ui-menu-page { border-bottom: none }
|
||||
body.ffz-bttv-dark .ffz-ui-popup ul.menu:not(.sub-menu),
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page { border: 1px solid rgba(255,255,255,0.1) }
|
||||
body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page { border-bottom: none }
|
||||
|
||||
.ffz-bttv .emoticon.emoji { padding-top: 0 }
|
||||
|
||||
|
@ -1186,7 +1186,8 @@ img.channel_background[src="null"] { display: none; }
|
|||
|
||||
.ffz-moderation-card {
|
||||
border: 2px solid #cbcbcb;
|
||||
max-width: 340px;
|
||||
max-width: 350px;
|
||||
min-width: 325px;
|
||||
}
|
||||
|
||||
.ember-chat .ffz-moderation-card .close-button {
|
||||
|
@ -2300,6 +2301,48 @@ li[data-name="following"] a {
|
|||
max-height: 90px;
|
||||
}
|
||||
|
||||
/* Player Captions *\/
|
||||
|
||||
.ffz-dark .player-modal__content,
|
||||
.theatre .player-modal__content {
|
||||
background: #101010;
|
||||
color: #ccc;
|
||||
box-shadow: 0 1px 1px rgba(255,255,255,.1);
|
||||
}
|
||||
|
||||
.ffz-dark .player-modal__header,
|
||||
.theatre .player-modal__header {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.ffz-dark .player-modal__content label,
|
||||
.theatre .player-modal__content label {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.ffz-dark .cc-font-size,
|
||||
.theatre .cc-font-size {
|
||||
background-color: #101010;
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.ffz-dark .cc-color-palette__square:not(:hover),
|
||||
.theatre .cc-color-palette__square:not(:hover),
|
||||
|
||||
.ffz-dark .cc-edge-palette__square:not(:hover),
|
||||
.theatre .cc-edge-palette__square:not(:hover),
|
||||
|
||||
.ffz-dark .cc-preset-square:not(:hover):not(.js-cc-preset-selected),
|
||||
.theatre .cc-preset-square:not(:hover):not(.js-cc-preset-selected) {
|
||||
border-color: #101010;
|
||||
}
|
||||
|
||||
.ffz-dark label.cc-edge-palette__square,
|
||||
.theatre label.cc-edge-palette__square { color: #fff }*/
|
||||
|
||||
|
||||
/* Classic Player */
|
||||
|
||||
.ffz-classic-player .player .player-video {
|
||||
|
@ -2376,6 +2419,7 @@ li[data-name="following"] a {
|
|||
.ffz-classic-player .player .player-button svg { fill: #aeaeae; }
|
||||
.ffz-classic-player .player .player-seek .player-seek__time { color: #ddd; }
|
||||
|
||||
.ffz-player-volume .player .player-volume__slider-container,
|
||||
.ffz-classic-player .player .player-volume__slider-container {
|
||||
width: auto;
|
||||
}
|
||||
|
@ -2401,6 +2445,8 @@ li[data-name="following"] a {
|
|||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.player-button--close { top: 0 }
|
||||
|
||||
/* Directory Logos */
|
||||
|
||||
.item .meta .title a a,
|
||||
|
@ -2797,4 +2843,9 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
|
||||
.ffz-hide-friends-collapsed .drawer--summary.closed .friend-list { display: none }
|
||||
|
||||
.warp__anchor { height: 5.5rem }
|
||||
.warp__anchor { height: 5.5rem }
|
||||
|
||||
|
||||
/* Chat Pane Overhaul */
|
||||
|
||||
.ember-chat.ffz-chat-pane .chat-messages { bottom: 0 }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue