mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-02 16:08:31 +00:00
Added nice following tooltips to the sidebar. Shift-clicking emotes in the menu works now. Fixed color code bugs on non-ember. Fixed DDoS prevention nonsense.
This commit is contained in:
parent
08ad23ec02
commit
9ece18ec0f
12 changed files with 737 additions and 421 deletions
279
script.js
279
script.js
|
@ -549,8 +549,8 @@ FFZ.prototype.setup_colors = function() {
|
|||
this._update_colors();
|
||||
|
||||
// Events for rebuilding colors.
|
||||
var Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings');
|
||||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && App.__container__.lookup('controller:settings');
|
||||
|
||||
if ( Layout )
|
||||
Layout.addObserver("isTheatreMode", this._update_colors.bind(this, true));
|
||||
|
@ -989,8 +989,8 @@ FFZ.prototype._rebuild_colors = function() {
|
|||
|
||||
FFZ.prototype._update_colors = function(darkness_only) {
|
||||
// Update the lines. ALL of them.
|
||||
var Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings'),
|
||||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && App.__container__.lookup('controller:settings'),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||
|
||||
|
@ -1242,6 +1242,8 @@ module.exports = {
|
|||
CAMERA: '<svg class="svg-camera" height="16px" version="1.1" viewBox="0 0 36 36" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" d="M24,20v6H4V10h20v6l8-6v16L24,20z"/></svg>',
|
||||
INVITE: '<svg class="svg-plus" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,9h-3v3h-2V9H7V7h3V4h2v3h3V9z M9,6H6v4h2h1v3h4l0,0l0,0v1h-3H4H1v-1l3-3h2L4,8V2h6v1H9V6z" fill-rule="evenodd"></path></svg>',
|
||||
|
||||
LIVE: '<svg class="svg-glyph_live_small" height="16px" version="1.1" viewbox="0 0 16 16" width="13px" x="0px" y="0px"><path clip-rule="evenodd" d="M11,14H5H2v-1l3-3h2L5,8V2h6v6l-2,2h2l3,3v1H11z" fill-rule="evenodd"></path></svg>',
|
||||
|
||||
EYE: '<svg class="svg-glyph_views ffz-svg svg-eye" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M11,13H5L1,9V8V7l4-4h6l4,4v1v1L11,13z M8,5C6.344,5,5,6.343,5,8c0,1.656,1.344,3,3,3c1.657,0,3-1.344,3-3C11,6.343,9.657,5,8,5z M8,9C7.447,9,7,8.552,7,8s0.447-1,1-1s1,0.448,1,1S8.553,9,8,9z" fill-rule="evenodd"></path></svg>',
|
||||
CLOCK: '<svg class="svg-glyph_views ffz-svg svg-clock" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" fill="#888888" d="M8,15c-3.866,0-7-3.134-7-7s3.134-7,7-7s7,3.134,7,7 S11.866,15,8,15z M8,3C5.238,3,3,5.238,3,8s2.238,5,5,5s5-2.238,5-5S10.762,3,8,3z M7.293,8.707L7,8l1-4l0.902,3.607L11,11 L7.293,8.707z"/></svg>',
|
||||
GEAR: '<svg class="svg-gear" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,7v2h-2.115c-0.125,0.615-0.354,1.215-0.713,1.758l1.484,1.484l-1.414,1.414l-1.484-1.484C10.215,12.531,9.615,12.76,9,12.885V15H7v-2.12c-0.614-0.126-1.21-0.356-1.751-0.714l-1.491,1.49l-1.414-1.414l1.491-1.49C3.477,10.211,3.247,9.613,3.12,9H1V7h2.116C3.24,6.384,3.469,5.785,3.829,5.242L2.343,3.757l1.414-1.414l1.485,1.485C5.785,3.469,6.384,3.24,7,3.115V1h2v2.12c0.613,0.126,1.211,0.356,1.752,0.714l1.49-1.491l1.414,1.414l-1.49,1.492C12.523,5.79,12.754,6.387,12.88,7H15z M8,6C6.896,6,6,6.896,6,8s0.896,2,2,2s2-0.896,2-2S9.104,6,8,6z" fill-rule="evenodd"></path></svg>',
|
||||
|
@ -7243,22 +7245,8 @@ FFZ.prototype._emote_menu_enumerator = function() {
|
|||
if ( emote.hidden )
|
||||
continue;
|
||||
|
||||
// TODO: Stop having to calculate this here.
|
||||
var title = set.title, badge = set.icon || null;
|
||||
if ( ! title ) {
|
||||
if ( set.id === "global" )
|
||||
title = "FrankerFaceZ Global Emotes";
|
||||
|
||||
else if ( set.id == "globalevent" )
|
||||
title = "FrankerFaceZ Event Emotes";
|
||||
|
||||
else if ( this.feature_friday && set.id == this.feature_friday.set )
|
||||
title = "FrankerFaceZ " + this.feature_friday.title + ": " + this.feature_friday.display_name;
|
||||
|
||||
else
|
||||
title = "FrankerFaceZ Set: " + FFZ.get_capitalization(set.id);
|
||||
} else
|
||||
title = "FrankerFaceZ: " + title;
|
||||
var title = "FrankerFaceZ " + set.title,
|
||||
badge = set.icon || '//cdn.frankerfacez.com/script/devicon.png';
|
||||
|
||||
emotes.push({text: emote.name, url: emote.urls[1],
|
||||
hidden: false, channel: title, badge: badge});
|
||||
|
@ -7291,7 +7279,7 @@ FFZ.get = function() { return FFZ.instance; }
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 8,
|
||||
major: 3, minor: 5, revision: 10,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
@ -8147,6 +8135,7 @@ var FFZ = window.FrankerFaceZ;
|
|||
|
||||
FFZ.prototype._ws_open = false;
|
||||
FFZ.prototype._ws_delay = 0;
|
||||
FFZ.prototype._ws_last_iframe = 0;
|
||||
|
||||
FFZ.ws_commands = {};
|
||||
FFZ.ws_on_close = [];
|
||||
|
@ -8156,6 +8145,22 @@ FFZ.ws_on_close = [];
|
|||
// Socket Creation
|
||||
// ----------------
|
||||
|
||||
FFZ.prototype.ws_iframe = function() {
|
||||
this._ws_last_iframe = Date.now();
|
||||
var ifr = document.createElement('iframe'),
|
||||
f = this;
|
||||
|
||||
ifr.src = 'http://catbag.frankerfacez.com';
|
||||
ifr.style.visibility = 'hidden';
|
||||
document.body.appendChild(ifr);
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(ifr);
|
||||
if ( ! f._ws_open )
|
||||
f.ws_create();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.ws_create = function() {
|
||||
var f = this, ws;
|
||||
|
||||
|
@ -8175,6 +8180,7 @@ FFZ.prototype.ws_create = function() {
|
|||
ws.onopen = function(e) {
|
||||
f._ws_open = true;
|
||||
f._ws_delay = 0;
|
||||
f._ws_last_iframe = Date.now();
|
||||
f.log("Socket connected.");
|
||||
|
||||
// Check for incognito. We don't want to do a hello in incognito mode.
|
||||
|
@ -8251,6 +8257,12 @@ FFZ.prototype.ws_create = function() {
|
|||
}
|
||||
}
|
||||
|
||||
if ( f._ws_delay > 10000 ) {
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
if ( Date.now() - f._ws_last_iframe > 1800000 && !(ua.indexOf('chrome') === -1 && ua.indexOf('safari') !== -1) )
|
||||
return f.ws_iframe();
|
||||
}
|
||||
|
||||
// We never ever want to not have a socket.
|
||||
if ( f._ws_delay < 60000 )
|
||||
f._ws_delay += (Math.floor(Math.random()*10) + 5) * 1000;
|
||||
|
@ -9630,7 +9642,8 @@ FFZ.prototype._load_dark_css = function() {
|
|||
}
|
||||
},{"../constants":4}],24:[function(require,module,exports){
|
||||
var FFZ = window.FrankerFaceZ,
|
||||
utils = require('../utils');
|
||||
utils = require('../utils'),
|
||||
constants = require('../constants');
|
||||
|
||||
|
||||
|
||||
|
@ -9683,11 +9696,17 @@ FFZ.prototype.setup_following_count = function(has_ember) {
|
|||
return this.log("Unable to find Live Streams collection.");
|
||||
|
||||
Live.addObserver('total', function() { f._draw_following_count(this.get('total')); });
|
||||
Live.addObserver('content.length', function() { f._draw_following_channels(this.get('content'), this.get('total')); })
|
||||
|
||||
Live.load();
|
||||
|
||||
var total = Live.get('total');
|
||||
if ( typeof total === "number" )
|
||||
var total = Live.get('total'),
|
||||
streams = Live.get('content');
|
||||
if ( typeof total === "number" ) {
|
||||
this._draw_following_count(total);
|
||||
if ( streams && streams.length )
|
||||
this._draw_following_channels(streams, total);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -9723,15 +9742,84 @@ FFZ.prototype._update_following_count = function() {
|
|||
if ( Live )
|
||||
Live.load();
|
||||
else
|
||||
Twitch.api && Twitch.api.get("streams/followed", {limit:1, offset:0}, {version:3})
|
||||
Twitch.api && Twitch.api.get("streams/followed", {limit:5, offset:0}, {version:3})
|
||||
.done(function(data) {
|
||||
f._draw_following_count(data._total);
|
||||
f._draw_following_channels(data.streams, data._total);
|
||||
}).fail(function() {
|
||||
f._draw_following_count();
|
||||
f._draw_following_channels();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._draw_following_channels = function(streams, total) {
|
||||
// First, build the data.
|
||||
var tooltip = 'Following';
|
||||
|
||||
if ( streams && streams.length ) {
|
||||
var c = 0;
|
||||
for(var i=0, l = streams.length; i < l; i++) {
|
||||
var stream = streams[i];
|
||||
if ( ! stream || ! stream.channel )
|
||||
continue;
|
||||
|
||||
c += 1;
|
||||
if ( c > 5 ) {
|
||||
var ttl = total || streams.length;
|
||||
tooltip += '<hr><span>And ' + utils.number_commas(ttl - 5) + ' more...</span>';
|
||||
break;
|
||||
}
|
||||
|
||||
tooltip += (i > 0 ? '<br>' : '<hr>') + '<span class="viewers">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span><b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br><span class="playing">' + (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing') + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Small
|
||||
var small_following = jQuery('#small_nav ul.game_filters li[data-name="following"] a');
|
||||
if ( small_following && small_following.length ) {
|
||||
var data = small_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.gravity = function() { return this.parentElement.getAttribute('data-name') === 'following' ? 'nw': 'w'; };
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
small_following.tipsy({html: true, className: 'ffz-wide-tip', gravity: 'nw'});
|
||||
|
||||
small_following.attr('title', tooltip);
|
||||
}
|
||||
|
||||
|
||||
// Large
|
||||
var large_following = jQuery('#large_nav #nav_personal li[data-name="following"] a');
|
||||
if ( large_following && large_following.length ) {
|
||||
var data = large_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
large_following.tipsy({html:true, className: 'ffz-wide-tip'});
|
||||
|
||||
large_following.attr('title', tooltip);
|
||||
}
|
||||
|
||||
|
||||
// Heading
|
||||
var head_following = jQuery('#header_actions #header_following');
|
||||
if ( head_following && head_following.length ) {
|
||||
var data = head_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
head_following.tipsy({html: true, className: 'ffz-wide-tip'});
|
||||
|
||||
head_following.attr('title', tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._draw_following_count = function(count) {
|
||||
// Small
|
||||
var small_following = document.querySelector('#small_nav ul.game_filters li[data-name="following"] a');
|
||||
|
@ -9785,7 +9873,7 @@ FFZ.prototype._draw_following_count = function(count) {
|
|||
}
|
||||
}
|
||||
}
|
||||
},{"../utils":34}],25:[function(require,module,exports){
|
||||
},{"../constants":4,"../utils":34}],25:[function(require,module,exports){
|
||||
var FFZ = window.FrankerFaceZ,
|
||||
utils = require('../utils'),
|
||||
|
||||
|
@ -10231,14 +10319,30 @@ var FFZ = window.FrankerFaceZ,
|
|||
TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/",
|
||||
|
||||
fix_menu_position = function(container) {
|
||||
var swapped = document.body.classList.contains('ffz-sidebar-swap');
|
||||
|
||||
var bounds = container.getBoundingClientRect(),
|
||||
left = parseInt(container.style.left || '0'),
|
||||
right = bounds.left + container.scrollWidth;
|
||||
right = bounds.left + container.scrollWidth,
|
||||
moved = !!container.style.left;
|
||||
|
||||
if ( swapped ) {
|
||||
if ( bounds.left < 20 ) {
|
||||
container.style.left = '';
|
||||
moved = false;
|
||||
} else if ( right > document.body.clientWidth )
|
||||
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
|
||||
|
||||
} else {
|
||||
if ( bounds.left < 0 )
|
||||
container.style.left = (left - bounds.left) + 'px';
|
||||
else if ( right > document.body.clientWidth )
|
||||
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
|
||||
else if ( right > (document.body.clientWidth - 20) ) {
|
||||
container.style.left = '';
|
||||
moved = false;
|
||||
}
|
||||
}
|
||||
|
||||
container.classList.toggle('ui-moved', moved);
|
||||
};
|
||||
|
||||
|
||||
|
@ -10447,7 +10551,31 @@ FFZ.prototype.build_ui_popup = function(view) {
|
|||
|
||||
var heading = document.createElement('li');
|
||||
heading.className = 'title';
|
||||
heading.innerHTML = "<span>" + (constants.DEBUG ? "[DEV] " : "") + "FrankerFaceZ</span>";
|
||||
heading.innerHTML = '<span class="title">Franker' + (constants.DEBUG ? 'Dev' : 'Face') + 'Z</span>';
|
||||
|
||||
// Close Button
|
||||
var close_btn = document.createElement('span'),
|
||||
f = this;
|
||||
|
||||
close_btn.className = 'ffz-handle ffz-close-button';
|
||||
heading.insertBefore(close_btn, heading.firstChild);
|
||||
|
||||
var can_close = false;
|
||||
close_btn.addEventListener('mousedown', function() {
|
||||
var popup = f._popup;
|
||||
can_close = popup && popup.id === "ffz-chat-menu" && popup.style.left;
|
||||
});
|
||||
|
||||
close_btn.addEventListener('click', function() {
|
||||
var popup = f._popup;
|
||||
if ( can_close && popup ) {
|
||||
popup.parentElement.removeChild(popup);
|
||||
delete f._popup;
|
||||
f._popup_kill && f._popup_kill();
|
||||
delete f._popup_kill;
|
||||
}
|
||||
});
|
||||
|
||||
menu.appendChild(heading);
|
||||
|
||||
// Draggable
|
||||
|
@ -10554,7 +10682,8 @@ FFZ.menu_pages.channel = {
|
|||
// Get the current room.
|
||||
var room_id = view.get('controller.currentRoom.id'),
|
||||
room = this.rooms[room_id],
|
||||
has_product = false;
|
||||
has_product = false,
|
||||
f = this;
|
||||
|
||||
// Check for a product.
|
||||
if ( this.settings.replace_twitch_menu ) {
|
||||
|
@ -10577,7 +10706,6 @@ FFZ.menu_pages.channel = {
|
|||
// See if we've loaded. If we haven't loaded the ticket yet
|
||||
// then try loading it, and then re-render the menu.
|
||||
if ( tickets && ! is_subscribed && ! is_loaded ) {
|
||||
var f = this;
|
||||
tickets.addObserver('isLoaded', function() {
|
||||
setTimeout(function(){
|
||||
if ( inner.getAttribute('data-page') !== 'channel' )
|
||||
|
@ -10621,8 +10749,17 @@ FFZ.menu_pages.channel = {
|
|||
s.style.width = emote.width + "px";
|
||||
s.style.height = emote.height + "px";
|
||||
s.title = emote.regex;
|
||||
if ( can_use )
|
||||
s.addEventListener('click', this._add_emote.bind(this, view, emote.regex));
|
||||
|
||||
s.addEventListener('click', function(can_use, id, code, e) {
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else if ( can_use )
|
||||
this._add_emote(view, code);
|
||||
else
|
||||
return;
|
||||
e.preventDefault();
|
||||
}.bind(this, can_use, emote.id, emote.regex));
|
||||
|
||||
grid.appendChild(s);
|
||||
c++;
|
||||
}
|
||||
|
@ -10701,7 +10838,7 @@ FFZ.menu_pages.channel = {
|
|||
// --------------------
|
||||
|
||||
FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub_text) {
|
||||
var grid = document.createElement('div'), c = 0;
|
||||
var grid = document.createElement('div'), c = 0, f = this;
|
||||
grid.className = 'emoticon-grid';
|
||||
|
||||
if ( header != null ) {
|
||||
|
@ -10775,7 +10912,14 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
|
|||
s.style.height = emote.height + "px";
|
||||
s.title = this._emote_tooltip(emote);
|
||||
|
||||
s.addEventListener('click', this._add_emote.bind(this, view, emote.name));
|
||||
s.addEventListener('click', function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.name));
|
||||
|
||||
grid.appendChild(s);
|
||||
}
|
||||
|
||||
|
@ -10936,53 +11080,10 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
render: function(view, container) {
|
||||
var tmi = view.get('controller.currentRoom.tmiSession'),
|
||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'],
|
||||
needed_sets = [];
|
||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'];
|
||||
|
||||
for(var set_id in twitch_sets)
|
||||
if ( twitch_sets.hasOwnProperty(set_id) && ! this._twitch_set_to_channel.hasOwnProperty(set_id) )
|
||||
needed_sets.push(set_id);
|
||||
|
||||
if ( ! needed_sets.length )
|
||||
// We don't have to do async stuff anymore cause we pre-load data~!
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(this)(view, container, twitch_sets);
|
||||
|
||||
var f = this,
|
||||
fail = function() {
|
||||
if ( ! needed_sets.length )
|
||||
return;
|
||||
|
||||
needed_sets = [];
|
||||
var ts = {};
|
||||
for(var set_id in twitch_sets)
|
||||
if ( f._twitch_set_to_channel[set_id] )
|
||||
ts[set_id] = twitch_sets[set_id];
|
||||
else
|
||||
ts[set_id] = []; //"twitch_unknown";
|
||||
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(f)(view, container, ts);
|
||||
};
|
||||
|
||||
if ( ! this.ws_send("twitch_sets", needed_sets, function(success, data) {
|
||||
if ( ! needed_sets.length )
|
||||
return;
|
||||
|
||||
needed_sets = [];
|
||||
if ( success ) {
|
||||
for(var set_id in data) {
|
||||
if ( ! data.hasOwnProperty(set_id) )
|
||||
continue;
|
||||
|
||||
f._twitch_set_to_channel[set_id] = data[set_id];
|
||||
}
|
||||
|
||||
localStorage.ffzTwitchSets = JSON.stringify(f._twitch_set_to_channel);
|
||||
return FFZ.menu_pages.my_emotes.draw_menu.bind(f)(view, container, twitch_sets);
|
||||
} else
|
||||
fail();
|
||||
}) )
|
||||
fail()
|
||||
else
|
||||
setTimeout(fail, 2000);
|
||||
},
|
||||
|
||||
toggle_section: function(heading) {
|
||||
|
@ -11125,7 +11226,13 @@ FFZ.menu_pages.myemotes = {
|
|||
}
|
||||
|
||||
em.title = code;
|
||||
em.addEventListener("click", this._add_emote.bind(this, view, code));
|
||||
em.addEventListener("click", function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.code));
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
@ -11190,7 +11297,13 @@ FFZ.menu_pages.myemotes = {
|
|||
em.style.width = emote.width + "px";
|
||||
|
||||
em.title = this._emote_tooltip(emote);
|
||||
em.addEventListener("click", this._add_emote.bind(this, view, emote.name));
|
||||
em.addEventListener("click", function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.name));
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
|
16
script.min.js
vendored
16
script.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -120,8 +120,8 @@ FFZ.prototype.setup_colors = function() {
|
|||
this._update_colors();
|
||||
|
||||
// Events for rebuilding colors.
|
||||
var Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings');
|
||||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && App.__container__.lookup('controller:settings');
|
||||
|
||||
if ( Layout )
|
||||
Layout.addObserver("isTheatreMode", this._update_colors.bind(this, true));
|
||||
|
@ -560,8 +560,8 @@ FFZ.prototype._rebuild_colors = function() {
|
|||
|
||||
FFZ.prototype._update_colors = function(darkness_only) {
|
||||
// Update the lines. ALL of them.
|
||||
var Layout = App.__container__.lookup('controller:layout'),
|
||||
Settings = App.__container__.lookup('controller:settings'),
|
||||
var Layout = window.App && App.__container__.lookup('controller:layout'),
|
||||
Settings = window.App && App.__container__.lookup('controller:settings'),
|
||||
|
||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('model.darkMode'));
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ module.exports = {
|
|||
CAMERA: '<svg class="svg-camera" height="16px" version="1.1" viewBox="0 0 36 36" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" d="M24,20v6H4V10h20v6l8-6v16L24,20z"/></svg>',
|
||||
INVITE: '<svg class="svg-plus" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,9h-3v3h-2V9H7V7h3V4h2v3h3V9z M9,6H6v4h2h1v3h4l0,0l0,0v1h-3H4H1v-1l3-3h2L4,8V2h6v1H9V6z" fill-rule="evenodd"></path></svg>',
|
||||
|
||||
LIVE: '<svg class="svg-glyph_live_small" height="16px" version="1.1" viewbox="0 0 16 16" width="13px" x="0px" y="0px"><path clip-rule="evenodd" d="M11,14H5H2v-1l3-3h2L5,8V2h6v6l-2,2h2l3,3v1H11z" fill-rule="evenodd"></path></svg>',
|
||||
|
||||
EYE: '<svg class="svg-glyph_views ffz-svg svg-eye" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M11,13H5L1,9V8V7l4-4h6l4,4v1v1L11,13z M8,5C6.344,5,5,6.343,5,8c0,1.656,1.344,3,3,3c1.657,0,3-1.344,3-3C11,6.343,9.657,5,8,5z M8,9C7.447,9,7,8.552,7,8s0.447-1,1-1s1,0.448,1,1S8.553,9,8,9z" fill-rule="evenodd"></path></svg>',
|
||||
CLOCK: '<svg class="svg-glyph_views ffz-svg svg-clock" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" fill="#888888" d="M8,15c-3.866,0-7-3.134-7-7s3.134-7,7-7s7,3.134,7,7 S11.866,15,8,15z M8,3C5.238,3,3,5.238,3,8s2.238,5,5,5s5-2.238,5-5S10.762,3,8,3z M7.293,8.707L7,8l1-4l0.902,3.607L11,11 L7.293,8.707z"/></svg>',
|
||||
GEAR: '<svg class="svg-gear" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,7v2h-2.115c-0.125,0.615-0.354,1.215-0.713,1.758l1.484,1.484l-1.414,1.414l-1.484-1.484C10.215,12.531,9.615,12.76,9,12.885V15H7v-2.12c-0.614-0.126-1.21-0.356-1.751-0.714l-1.491,1.49l-1.414-1.414l1.491-1.49C3.477,10.211,3.247,9.613,3.12,9H1V7h2.116C3.24,6.384,3.469,5.785,3.829,5.242L2.343,3.757l1.414-1.414l1.485,1.485C5.785,3.469,6.384,3.24,7,3.115V1h2v2.12c0.613,0.126,1.211,0.356,1.752,0.714l1.49-1.491l1.414,1.414l-1.49,1.492C12.523,5.79,12.754,6.387,12.88,7H15z M8,6C6.896,6,6,6.896,6,8s0.896,2,2,2s2-0.896,2-2S9.104,6,8,6z" fill-rule="evenodd"></path></svg>',
|
||||
|
|
|
@ -49,22 +49,8 @@ FFZ.prototype._emote_menu_enumerator = function() {
|
|||
if ( emote.hidden )
|
||||
continue;
|
||||
|
||||
// TODO: Stop having to calculate this here.
|
||||
var title = set.title, badge = set.icon || null;
|
||||
if ( ! title ) {
|
||||
if ( set.id === "global" )
|
||||
title = "FrankerFaceZ Global Emotes";
|
||||
|
||||
else if ( set.id == "globalevent" )
|
||||
title = "FrankerFaceZ Event Emotes";
|
||||
|
||||
else if ( this.feature_friday && set.id == this.feature_friday.set )
|
||||
title = "FrankerFaceZ " + this.feature_friday.title + ": " + this.feature_friday.display_name;
|
||||
|
||||
else
|
||||
title = "FrankerFaceZ Set: " + FFZ.get_capitalization(set.id);
|
||||
} else
|
||||
title = "FrankerFaceZ: " + title;
|
||||
var title = "FrankerFaceZ " + set.title,
|
||||
badge = set.icon || '//cdn.frankerfacez.com/script/devicon.png';
|
||||
|
||||
emotes.push({text: emote.name, url: emote.urls[1],
|
||||
hidden: false, channel: title, badge: badge});
|
||||
|
|
|
@ -21,7 +21,7 @@ FFZ.get = function() { return FFZ.instance; }
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 8,
|
||||
major: 3, minor: 5, revision: 10,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ var FFZ = window.FrankerFaceZ;
|
|||
|
||||
FFZ.prototype._ws_open = false;
|
||||
FFZ.prototype._ws_delay = 0;
|
||||
FFZ.prototype._ws_last_iframe = 0;
|
||||
|
||||
FFZ.ws_commands = {};
|
||||
FFZ.ws_on_close = [];
|
||||
|
@ -11,6 +12,22 @@ FFZ.ws_on_close = [];
|
|||
// Socket Creation
|
||||
// ----------------
|
||||
|
||||
FFZ.prototype.ws_iframe = function() {
|
||||
this._ws_last_iframe = Date.now();
|
||||
var ifr = document.createElement('iframe'),
|
||||
f = this;
|
||||
|
||||
ifr.src = 'http://catbag.frankerfacez.com';
|
||||
ifr.style.visibility = 'hidden';
|
||||
document.body.appendChild(ifr);
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(ifr);
|
||||
if ( ! f._ws_open )
|
||||
f.ws_create();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.ws_create = function() {
|
||||
var f = this, ws;
|
||||
|
||||
|
@ -30,6 +47,7 @@ FFZ.prototype.ws_create = function() {
|
|||
ws.onopen = function(e) {
|
||||
f._ws_open = true;
|
||||
f._ws_delay = 0;
|
||||
f._ws_last_iframe = Date.now();
|
||||
f.log("Socket connected.");
|
||||
|
||||
// Check for incognito. We don't want to do a hello in incognito mode.
|
||||
|
@ -106,6 +124,12 @@ FFZ.prototype.ws_create = function() {
|
|||
}
|
||||
}
|
||||
|
||||
if ( f._ws_delay > 10000 ) {
|
||||
var ua = navigator.userAgent.toLowerCase();
|
||||
if ( Date.now() - f._ws_last_iframe > 1800000 && !(ua.indexOf('chrome') === -1 && ua.indexOf('safari') !== -1) )
|
||||
return f.ws_iframe();
|
||||
}
|
||||
|
||||
// We never ever want to not have a socket.
|
||||
if ( f._ws_delay < 60000 )
|
||||
f._ws_delay += (Math.floor(Math.random()*10) + 5) * 1000;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
var FFZ = window.FrankerFaceZ,
|
||||
utils = require('../utils');
|
||||
utils = require('../utils'),
|
||||
constants = require('../constants');
|
||||
|
||||
|
||||
|
||||
|
@ -52,11 +53,17 @@ FFZ.prototype.setup_following_count = function(has_ember) {
|
|||
return this.log("Unable to find Live Streams collection.");
|
||||
|
||||
Live.addObserver('total', function() { f._draw_following_count(this.get('total')); });
|
||||
Live.addObserver('content.length', function() { f._draw_following_channels(this.get('content'), this.get('total')); })
|
||||
|
||||
Live.load();
|
||||
|
||||
var total = Live.get('total');
|
||||
if ( typeof total === "number" )
|
||||
var total = Live.get('total'),
|
||||
streams = Live.get('content');
|
||||
if ( typeof total === "number" ) {
|
||||
this._draw_following_count(total);
|
||||
if ( streams && streams.length )
|
||||
this._draw_following_channels(streams, total);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,15 +99,84 @@ FFZ.prototype._update_following_count = function() {
|
|||
if ( Live )
|
||||
Live.load();
|
||||
else
|
||||
Twitch.api && Twitch.api.get("streams/followed", {limit:1, offset:0}, {version:3})
|
||||
Twitch.api && Twitch.api.get("streams/followed", {limit:5, offset:0}, {version:3})
|
||||
.done(function(data) {
|
||||
f._draw_following_count(data._total);
|
||||
f._draw_following_channels(data.streams, data._total);
|
||||
}).fail(function() {
|
||||
f._draw_following_count();
|
||||
f._draw_following_channels();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._draw_following_channels = function(streams, total) {
|
||||
// First, build the data.
|
||||
var tooltip = 'Following';
|
||||
|
||||
if ( streams && streams.length ) {
|
||||
var c = 0;
|
||||
for(var i=0, l = streams.length; i < l; i++) {
|
||||
var stream = streams[i];
|
||||
if ( ! stream || ! stream.channel )
|
||||
continue;
|
||||
|
||||
c += 1;
|
||||
if ( c > 5 ) {
|
||||
var ttl = total || streams.length;
|
||||
tooltip += '<hr><span>And ' + utils.number_commas(ttl - 5) + ' more...</span>';
|
||||
break;
|
||||
}
|
||||
|
||||
tooltip += (i > 0 ? '<br>' : '<hr>') + '<span class="viewers">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span><b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br><span class="playing">' + (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing') + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Small
|
||||
var small_following = jQuery('#small_nav ul.game_filters li[data-name="following"] a');
|
||||
if ( small_following && small_following.length ) {
|
||||
var data = small_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.gravity = function() { return this.parentElement.getAttribute('data-name') === 'following' ? 'nw': 'w'; };
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
small_following.tipsy({html: true, className: 'ffz-wide-tip', gravity: 'nw'});
|
||||
|
||||
small_following.attr('title', tooltip);
|
||||
}
|
||||
|
||||
|
||||
// Large
|
||||
var large_following = jQuery('#large_nav #nav_personal li[data-name="following"] a');
|
||||
if ( large_following && large_following.length ) {
|
||||
var data = large_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
large_following.tipsy({html:true, className: 'ffz-wide-tip'});
|
||||
|
||||
large_following.attr('title', tooltip);
|
||||
}
|
||||
|
||||
|
||||
// Heading
|
||||
var head_following = jQuery('#header_actions #header_following');
|
||||
if ( head_following && head_following.length ) {
|
||||
var data = head_following.data('tipsy');
|
||||
if ( data && data.options ) {
|
||||
data.options.html = true;
|
||||
data.options.className = 'ffz-wide-tip';
|
||||
} else
|
||||
head_following.tipsy({html: true, className: 'ffz-wide-tip'});
|
||||
|
||||
head_following.attr('title', tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._draw_following_count = function(count) {
|
||||
// Small
|
||||
var small_following = document.querySelector('#small_nav ul.game_filters li[data-name="following"] a');
|
||||
|
|
|
@ -5,14 +5,30 @@ var FFZ = window.FrankerFaceZ,
|
|||
TWITCH_BASE = "http://static-cdn.jtvnw.net/emoticons/v1/",
|
||||
|
||||
fix_menu_position = function(container) {
|
||||
var swapped = document.body.classList.contains('ffz-sidebar-swap');
|
||||
|
||||
var bounds = container.getBoundingClientRect(),
|
||||
left = parseInt(container.style.left || '0'),
|
||||
right = bounds.left + container.scrollWidth;
|
||||
right = bounds.left + container.scrollWidth,
|
||||
moved = !!container.style.left;
|
||||
|
||||
if ( swapped ) {
|
||||
if ( bounds.left < 20 ) {
|
||||
container.style.left = '';
|
||||
moved = false;
|
||||
} else if ( right > document.body.clientWidth )
|
||||
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
|
||||
|
||||
} else {
|
||||
if ( bounds.left < 0 )
|
||||
container.style.left = (left - bounds.left) + 'px';
|
||||
else if ( right > document.body.clientWidth )
|
||||
container.style.left = (left - (right - document.body.clientWidth)) + 'px';
|
||||
else if ( right > (document.body.clientWidth - 20) ) {
|
||||
container.style.left = '';
|
||||
moved = false;
|
||||
}
|
||||
}
|
||||
|
||||
container.classList.toggle('ui-moved', moved);
|
||||
};
|
||||
|
||||
|
||||
|
@ -221,7 +237,31 @@ FFZ.prototype.build_ui_popup = function(view) {
|
|||
|
||||
var heading = document.createElement('li');
|
||||
heading.className = 'title';
|
||||
heading.innerHTML = "<span>" + (constants.DEBUG ? "[DEV] " : "") + "FrankerFaceZ</span>";
|
||||
heading.innerHTML = '<span class="title">Franker' + (constants.DEBUG ? 'Dev' : 'Face') + 'Z</span>';
|
||||
|
||||
// Close Button
|
||||
var close_btn = document.createElement('span'),
|
||||
f = this;
|
||||
|
||||
close_btn.className = 'ffz-handle ffz-close-button';
|
||||
heading.insertBefore(close_btn, heading.firstChild);
|
||||
|
||||
var can_close = false;
|
||||
close_btn.addEventListener('mousedown', function() {
|
||||
var popup = f._popup;
|
||||
can_close = popup && popup.id === "ffz-chat-menu" && popup.style.left;
|
||||
});
|
||||
|
||||
close_btn.addEventListener('click', function() {
|
||||
var popup = f._popup;
|
||||
if ( can_close && popup ) {
|
||||
popup.parentElement.removeChild(popup);
|
||||
delete f._popup;
|
||||
f._popup_kill && f._popup_kill();
|
||||
delete f._popup_kill;
|
||||
}
|
||||
});
|
||||
|
||||
menu.appendChild(heading);
|
||||
|
||||
// Draggable
|
||||
|
@ -328,7 +368,8 @@ FFZ.menu_pages.channel = {
|
|||
// Get the current room.
|
||||
var room_id = view.get('controller.currentRoom.id'),
|
||||
room = this.rooms[room_id],
|
||||
has_product = false;
|
||||
has_product = false,
|
||||
f = this;
|
||||
|
||||
// Check for a product.
|
||||
if ( this.settings.replace_twitch_menu ) {
|
||||
|
@ -351,7 +392,6 @@ FFZ.menu_pages.channel = {
|
|||
// See if we've loaded. If we haven't loaded the ticket yet
|
||||
// then try loading it, and then re-render the menu.
|
||||
if ( tickets && ! is_subscribed && ! is_loaded ) {
|
||||
var f = this;
|
||||
tickets.addObserver('isLoaded', function() {
|
||||
setTimeout(function(){
|
||||
if ( inner.getAttribute('data-page') !== 'channel' )
|
||||
|
@ -395,8 +435,17 @@ FFZ.menu_pages.channel = {
|
|||
s.style.width = emote.width + "px";
|
||||
s.style.height = emote.height + "px";
|
||||
s.title = emote.regex;
|
||||
if ( can_use )
|
||||
s.addEventListener('click', this._add_emote.bind(this, view, emote.regex));
|
||||
|
||||
s.addEventListener('click', function(can_use, id, code, e) {
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else if ( can_use )
|
||||
this._add_emote(view, code);
|
||||
else
|
||||
return;
|
||||
e.preventDefault();
|
||||
}.bind(this, can_use, emote.id, emote.regex));
|
||||
|
||||
grid.appendChild(s);
|
||||
c++;
|
||||
}
|
||||
|
@ -475,7 +524,7 @@ FFZ.menu_pages.channel = {
|
|||
// --------------------
|
||||
|
||||
FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub_text) {
|
||||
var grid = document.createElement('div'), c = 0;
|
||||
var grid = document.createElement('div'), c = 0, f = this;
|
||||
grid.className = 'emoticon-grid';
|
||||
|
||||
if ( header != null ) {
|
||||
|
@ -549,7 +598,14 @@ FFZ.prototype._emotes_for_sets = function(parent, view, sets, header, image, sub
|
|||
s.style.height = emote.height + "px";
|
||||
s.title = this._emote_tooltip(emote);
|
||||
|
||||
s.addEventListener('click', this._add_emote.bind(this, view, emote.name));
|
||||
s.addEventListener('click', function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.name));
|
||||
|
||||
grid.appendChild(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,53 +79,10 @@ FFZ.menu_pages.myemotes = {
|
|||
|
||||
render: function(view, container) {
|
||||
var tmi = view.get('controller.currentRoom.tmiSession'),
|
||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'],
|
||||
needed_sets = [];
|
||||
twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'];
|
||||
|
||||
for(var set_id in twitch_sets)
|
||||
if ( twitch_sets.hasOwnProperty(set_id) && ! this._twitch_set_to_channel.hasOwnProperty(set_id) )
|
||||
needed_sets.push(set_id);
|
||||
|
||||
if ( ! needed_sets.length )
|
||||
// We don't have to do async stuff anymore cause we pre-load data~!
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(this)(view, container, twitch_sets);
|
||||
|
||||
var f = this,
|
||||
fail = function() {
|
||||
if ( ! needed_sets.length )
|
||||
return;
|
||||
|
||||
needed_sets = [];
|
||||
var ts = {};
|
||||
for(var set_id in twitch_sets)
|
||||
if ( f._twitch_set_to_channel[set_id] )
|
||||
ts[set_id] = twitch_sets[set_id];
|
||||
else
|
||||
ts[set_id] = []; //"twitch_unknown";
|
||||
|
||||
return FFZ.menu_pages.myemotes.draw_menu.bind(f)(view, container, ts);
|
||||
};
|
||||
|
||||
if ( ! this.ws_send("twitch_sets", needed_sets, function(success, data) {
|
||||
if ( ! needed_sets.length )
|
||||
return;
|
||||
|
||||
needed_sets = [];
|
||||
if ( success ) {
|
||||
for(var set_id in data) {
|
||||
if ( ! data.hasOwnProperty(set_id) )
|
||||
continue;
|
||||
|
||||
f._twitch_set_to_channel[set_id] = data[set_id];
|
||||
}
|
||||
|
||||
localStorage.ffzTwitchSets = JSON.stringify(f._twitch_set_to_channel);
|
||||
return FFZ.menu_pages.my_emotes.draw_menu.bind(f)(view, container, twitch_sets);
|
||||
} else
|
||||
fail();
|
||||
}) )
|
||||
fail()
|
||||
else
|
||||
setTimeout(fail, 2000);
|
||||
},
|
||||
|
||||
toggle_section: function(heading) {
|
||||
|
@ -268,7 +225,13 @@ FFZ.menu_pages.myemotes = {
|
|||
}
|
||||
|
||||
em.title = code;
|
||||
em.addEventListener("click", this._add_emote.bind(this, view, code));
|
||||
em.addEventListener("click", function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://twitchemotes.com/emote/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.code));
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
@ -333,7 +296,13 @@ FFZ.menu_pages.myemotes = {
|
|||
em.style.width = emote.width + "px";
|
||||
|
||||
em.title = this._emote_tooltip(emote);
|
||||
em.addEventListener("click", this._add_emote.bind(this, view, emote.name));
|
||||
em.addEventListener("click", function(id, code, e) {
|
||||
e.preventDefault();
|
||||
if ( (e.shiftKey || e.shiftLeft) && f.settings.clickable_emoticons )
|
||||
window.open("https://www.frankerfacez.com/emoticons/" + id);
|
||||
else
|
||||
this._add_emote(view, code);
|
||||
}.bind(this, emote.id, emote.name));
|
||||
menu.appendChild(em);
|
||||
}
|
||||
|
||||
|
|
98
style.css
98
style.css
|
@ -579,12 +579,85 @@ body:not(.ffz-minimal-chat):not(.ffz-menu-replace) .emoticon-selector-toggle + s
|
|||
float: left;
|
||||
}
|
||||
|
||||
.ffz-ui-popup ul.menu li.title > span {
|
||||
display: block;
|
||||
padding: 10px 20px;
|
||||
line-height: 16px;
|
||||
span.ffz-handle {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 26px;
|
||||
width: 14px;
|
||||
transition: width 500ms;
|
||||
}
|
||||
|
||||
span.ffz-handle:before,
|
||||
span.ffz-handle:after {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 5px;
|
||||
content: "";
|
||||
height: 14px;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 4px;
|
||||
transition: transform 500ms, left 500ms, border-color 500ms, border-width 500ms, height 500ms;
|
||||
}
|
||||
|
||||
span.ffz-handle:after { left: 8px }
|
||||
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle { width: 24px; cursor: pointer; }
|
||||
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:after {
|
||||
left: 11px;
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:before { transform: rotate(45deg); }
|
||||
.ffz-ui-popup.ui-moved span.ffz-handle:after { transform: rotate(-45deg); }
|
||||
|
||||
.app-main.theatre span.ffz-handle:before,
|
||||
.chat-container.dark span.ffz-handle:before,
|
||||
.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,
|
||||
.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 {
|
||||
border-color: #666;
|
||||
}
|
||||
|
||||
.app-main.theatre .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.chat-container.dark .ffz-ui-popup.ui-moved span.ffz-handle:before,
|
||||
.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,
|
||||
.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 {
|
||||
border-color: #d3d3d3;
|
||||
}
|
||||
|
||||
|
||||
.ffz-ui-popup ul.menu li.title > span.ffz-handle {
|
||||
float: left;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.ffz-ui-popup ul.menu li.title > span.title {
|
||||
display: block;
|
||||
margin-left: 24px;
|
||||
padding: 10px 20px 10px 0;
|
||||
line-height: 16px;
|
||||
transition: margin-left 500ms;
|
||||
}
|
||||
|
||||
.ffz-ui-popup.ui-moved ul.menu li.title > span.title { margin-left: 34px; }
|
||||
|
||||
.ffz-ui-popup ul.menu a {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
|
@ -1006,6 +1079,23 @@ body:not(.ffz-chat-purge-icon) .ember-chat .mod-icons .purge { display: none; }
|
|||
|
||||
/* Emoticon Tooltips */
|
||||
|
||||
.ffz-wide-tip .tipsy-inner {
|
||||
max-width: 600px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ffz-wide-tip span.viewers {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ffz-wide-tip span.viewers svg {
|
||||
float: left;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
.ffz-wide-tip svg path { fill: #fff; }
|
||||
.ffz-wide-tip span.playing { opacity: 0.7; }
|
||||
|
||||
.tipsy .tipsy-inner {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue