diff --git a/dark.css b/dark.css index 3acd3273..206842e6 100644 --- a/dark.css +++ b/dark.css @@ -92,11 +92,12 @@ /* main column */ body.ffz-dark, +.ffz-dark .app-main, .ffz-dark div#mantle_skin, .ffz-dark div#main_col { background:rgb(16,16,16); color:rgb(195,195,195)!important; - border-right:1px solid rgb(0,0,0)!important; + border-right: 0 !important; /*1px solid rgb(0,0,0)!important;*/ } .ffz-dark.ffz-portrait div#left_col .column, @@ -291,7 +292,8 @@ body.ffz-dark, .ffz-dark .warp__item > a { color: #d5d4d9 !important } .ffz-dark .warp__item--toggled a.js-language-select, -.ffz-dark .warm__item--toggled > a { color: #eae9ec !important } +.ffz-dark .warp__item > a:hover, +.ffz-dark .warp__item--toggled > a { color: #eae9ec !important } .ffz-dark .exit-theatre > a { color: #000 !important; } diff --git a/src/ember/directory.js b/src/ember/directory.js index 032388be..dd0f3d78 100644 --- a/src/ember/directory.js +++ b/src/ember/directory.js @@ -9,68 +9,6 @@ var FFZ = window.FrankerFaceZ, // Settings // -------------------- -FFZ.settings_info.sidebar_followed_games = { - type: "select", - options: { - 0: "Disabled", - 5: "Normal (5)", - 10: "Large (10)", - 999: "No Limit" - }, - - value: 5, - process_value: function(val) { - if ( typeof val === "string" ) - return parseInt(val) || 0; - return val; - }, - - category: "Appearance", - no_mobile: true, - - name: "Sidebar Followed Games", - help: "Display this number of followed games on the sidebar.", - - on_update: function(val) { - var controller = utils.ember_lookup('controller:games-following'); - if ( controller ) - controller.set('ffz_sidebar_games', val); - } - } - - -FFZ.settings_info.sidebar_hide_recommended_channels = { - type: "boolean", - value: true, - - category: "Appearance", - no_mobile: true, - - name: "Sidebar Recommended Channels", - help: "Display the Recommended Channels section on the sidebar.", - - on_update: function(val) { - document.body.classList.toggle('ffz-hide-recommended-channels', !val); - } - }; - - -FFZ.settings_info.sidebar_hide_recommended_friends = { - type: "boolean", - value: true, - - category: "Appearance", - no_mobile: true, - - name: "Sidebar Recommended Friends", - help: "Display the Recommended Friends section on the sidebar.", - - on_update: function(val) { - document.body.classList.toggle('ffz-hide-recommended-friends', !val); - } - }; - - /*FFZ.settings_info.directory_creative_all_tags = { type: "boolean", value: false, @@ -259,29 +197,6 @@ FFZ._image_cache = {}; FFZ.prototype.setup_directory = function() { document.body.classList.toggle('ffz-creative-tags', this.settings.directory_creative_all_tags); document.body.classList.toggle('ffz-creative-showcase', this.settings.directory_creative_showcase); - document.body.classList.toggle('ffz-hide-recommended-channels', !this.settings.sidebar_hide_recommended_channels); - document.body.classList.toggle('ffz-hide-recommended-friends', !this.settings.sidebar_hide_recommended_friends); - - var GamesFollowing = utils.ember_lookup('controller:games-following'), - f = this; - - if ( GamesFollowing ) { - this.log("Hooking the Ember games-following controller."); - GamesFollowing.reopen({ - ffz_sidebar_games: this.settings.sidebar_followed_games, - - sidePanelFollowing: function() { - var content = this.get('liveFollowing.sortedContent'), - limit = this.get('ffz_sidebar_games'); - - return limit === 999 ? content : _.first(content, limit); - }.property("liveFollowing.@each", "ffz_sidebar_games") - }); - - Ember.propertyDidChange(GamesFollowing, 'sidePanelFollowing'); - } else - this.error("Unable to load the Ember games-following controller."); - this.log("Attempting to modify the Following collection."); this._modify_following(); diff --git a/src/ember/following.js b/src/ember/following.js index acee365e..1d25dd71 100644 --- a/src/ember/following.js +++ b/src/ember/following.js @@ -181,7 +181,7 @@ FFZ.prototype._modify_display_followed_item = function(component) { user = f.get_user(), mine = user && user.login && user.login === channel_id, - big_cache = is_following ? f._following_cache : f._follower_cache; + big_cache = is_following ? f._following_cache : f._follower_cache, user_cache = big_cache[channel_id] = big_cache[channel_id] || {}, user_id = this.get('followed.id'), diff --git a/src/ember/layout.js b/src/ember/layout.js index 8696d20f..ce862e7b 100644 --- a/src/ember/layout.js +++ b/src/ember/layout.js @@ -58,7 +58,7 @@ FFZ.settings_info.swap_sidebars = { type: "boolean", value: false, - category: "Appearance", + category: "Sidebar", no_mobile: true, no_bttv: true, diff --git a/src/ember/room.js b/src/ember/room.js index 7d979f60..e8764b7b 100644 --- a/src/ember/room.js +++ b/src/ember/room.js @@ -236,7 +236,7 @@ FFZ.prototype._modify_rview = function(view) { } else if ( btn ) { btn.classList.toggle('ffz-waiting', (room && room.get('slowWait') || 0)); - btn.classList.toggle('ffz-banned', (room && room.get('ffz_banned'))); + btn.classList.toggle('ffz-banned', (room && room.get('ffz_banned') || false)); } var badge, id, info, vis_count = 0; @@ -840,6 +840,8 @@ FFZ.prototype._modify_room = function(room) { slowWaiting: false, slow: 0, + ffz_banned: false, + mru_list: [], updateWait: function(value, was_banned) { diff --git a/src/ember/sidebar.js b/src/ember/sidebar.js new file mode 100644 index 00000000..f32da134 --- /dev/null +++ b/src/ember/sidebar.js @@ -0,0 +1,238 @@ +var FFZ = window.FrankerFaceZ, + utils = require('../utils'), + constants = require('../constants'), + + PRESENCE_SERVICE = 'service:ember-twitch-presence@presence', + was_invisible = false; + + +// -------------------- +// Settings +// -------------------- + +FFZ.settings_info.sidebar_followed_games = { + type: "select", + options: { + 0: "Disabled", + 5: "Normal (5)", + 10: "Large (10)", + 999: "No Limit" + }, + + value: 5, + process_value: function(val) { + if ( typeof val === "string" ) + return parseInt(val) || 0; + return val; + }, + + category: "Sidebar", + no_mobile: true, + + name: "Followed Games", + help: "Display this number of followed games on the sidebar.", + + on_update: function(val) { + var controller = utils.ember_lookup('controller:games-following'); + if ( controller ) + controller.set('ffz_sidebar_games', val); + } +}; + + +FFZ.settings_info.sidebar_hide_recommended_channels = { + type: "boolean", + value: false, + + category: "Sidebar", + no_mobile: true, + + name: "Hide Recommended Channels", + help: "Hide the Recommended Channels section from the sidebar.", + + on_update: utils.toggle_cls('ffz-hide-recommended-channels') +}; + + +FFZ.settings_info.sidebar_hide_recommended_friends = { + type: "boolean", + value: false, + + category: "Sidebar", + no_mobile: true, + + name: "Hide Recommended Friends", + help: "Hide the Recommended Friends section from the sidebar.", + + on_update: utils.toggle_cls('ffz-hide-recommended-friends') +}; + + +FFZ.settings_info.sidebar_hide_friends_collapsed = { + type: "boolean", + value: true, + + category: "Sidebar", + no_mobile: false, + + name: "Hide Friends when Collapsed", + help: "Hide your friends from the sidebar when it's collapsed.", + + on_update: utils.toggle_cls('ffz-hide-friends-collapsed') +}; + + +FFZ.settings_info.sidebar_hide_more_at_twitch = { + type: "boolean", + value: false, + + category: "Sidebar", + no_mobile: true, + + name: "Hide More at Twitch", + help: "Hide the More at Twitch section from the sidebar.", + + on_update: utils.toggle_cls('ffz-hide-more-at-twitch') +}; + + +FFZ.settings_info.sidebar_disable_friends = { + type: "boolean", + value: false, + + category: "Sidebar", + no_mobile: true, + + name: "Disable Friends", + help: "Hide the Friends UI entirely and set you as Invisible.", + + on_update: function(val) { + utils.toggle_cls('ffz-hide-friends')(val); + var presence = utils.ember_lookup(PRESENCE_SERVICE); + if ( presence ) { + if ( val ) + presence.setInvisible && presence.setInvisible(); + else if ( ! was_invisible ) + presence.setOnline && presence.setOnline(); + } + } +}; + + +FFZ.settings_info.sidebar_start_open = { + type: "boolean", + value: false, + + category: "Sidebar", + no_mobile: true, + + name: "Automatically Open Drawer", + help: "Open the drawer at the bottom of the sidebar by default when the page is loaded." +}; + + +// -------------------- +// Initialization +// -------------------- + +FFZ.prototype.setup_sidebar = function() { + // CSS to Hide Stuff + utils.toggle_cls('ffz-hide-recommended-channels')(this.settings.sidebar_hide_recommended_channels); + utils.toggle_cls('ffz-hide-recommended-friends')(this.settings.sidebar_hide_recommended_friends); + utils.toggle_cls('ffz-hide-friends-collapsed')(this.settings.sidebar_hide_friends_collapsed); + utils.toggle_cls('ffz-hide-more-at-twitch')(this.settings.sidebar_hide_more_at_twitch); + utils.toggle_cls('ffz-hide-friends')(this.settings.sidebar_disable_friends); + + if ( this.settings.sidebar_disable_friends ) { + try { + var presence = utils.ember_lookup(PRESENCE_SERVICE); + if ( presence ) { + was_invisible = presence.get('isInvisible') || false; + presence.setInvisible && presence.setInvisible(); + } + } catch(err) { + window.dumberror = err; + this.error("Setting Friends Visibility", err); + } + } + + // Sidebar Followed Games + var GamesFollowing = utils.ember_lookup('controller:games-following'), + f = this; + + if ( GamesFollowing ) { + this.log("Hooking the Ember games-following controller."); + GamesFollowing.reopen({ + ffz_sidebar_games: this.settings.sidebar_followed_games, + + sidePanelFollowing: function() { + var content = this.get('liveFollowing.sortedContent'), + limit = this.get('ffz_sidebar_games'); + + return limit === 999 ? content : _.first(content, limit); + }.property("liveFollowing.@each", "ffz_sidebar_games") + }); + + Ember.propertyDidChange(GamesFollowing, 'sidePanelFollowing'); + } else + this.error("Unable to load the Ember games-following controller.", null); + + + // Navigation Controller + var NavController = utils.ember_lookup('controller:navigation'); + if ( NavController ) { + // Open Drawer by Default + if ( this.settings.sidebar_start_open ) + NavController.set('isDrawerOpen', true); + + } else + this.error("Unable to load the Ember navigation controller.", null); + + /* + var NavView = this._modify_navigation(utils.ember_resolve('component:new-navigation')), + views = utils.ember_views(), + + el = document.querySelector('nav#js-warp'), + view = el && views[el.parentElement.id]; + + if ( view ) { + try { + if ( ! view.ffzInit ) + this._modify_navigation(view); + view.ffzInit(); + } catch(err) { + this.error("Sidebar Setup", err); + } + }*/ +} + + +/*FFZ.prototype._modify_navigation = function(component) { + var f = this, + mutator = { + didInsertElement: function() { + this.ffzInit(); + }, + + ffzInit: function() { + f._nav = this; + f.log("Got New Navigation", this); + + var el = this.get("element"); + + if ( f.settings.sidebar_start_open ) { + + } + + } + }; + + if ( component ) + component.reopen(mutator); + else if ( window.App && App.__deprecatedInstance__ ) { + component = Ember.Component.extend(mutator); + App.__deprecatedInstance__.registry.register('component:new-navigation', component); + } + + return component; +}*/ \ No newline at end of file diff --git a/src/main.js b/src/main.js index 5c2b5103..ba4ad188 100644 --- a/src/main.js +++ b/src/main.js @@ -5,7 +5,9 @@ // The Constructor // ---------------- -var FFZ = window.FrankerFaceZ = function() { +var DOG = '░░░░░░░░░░░░▒▒▒▒\n░░░░░░░░░░░░▒▒░░░░▒▒\n░░░░░░░░░░▒▒░░████▄░▒\n░░░▄▄▄░░░▒▒░░░▀▀▀▀░░▒░░░░▄▄▄ \n░▄█████░▒▒▒▒░░░░░░░▒▒▒░░█████▄ \n ▄██████░▒▒▒▒▒░░░░▒▒▒▄▄▒▄░██████ \n ████████▒░██░▒░░░▒▒▒▀▀▒████████ \n ▀███████▒▒▒▒▒░░░░▒▒▒▒▒███████▀ \n ░░░▀▀████▒▒▒▒░░░░▒▒▒▄████▀▀\n ░░░░░░░▀░░▀▀▀▄▄▄█▄▀▀▀░░▀', + + FFZ = window.FrankerFaceZ = function() { FFZ.instance = this; // Logging @@ -19,8 +21,9 @@ var FFZ = window.FrankerFaceZ = function() { if ( ! event.error ) return; - var has_stack = event.error && event.error.stack; - t.log("JavaScript Error: " + event.message + " [" + event.filename + ":" + event.lineno + ":" + event.colno + "]", has_stack ? event.error.stack : undefined, false, has_stack); + //var has_stack = event.error && event.error.stack; + t.error("Uncaught JavaScript Error", event.error); + //t.log("JavaScript Error: " + event.message + " [" + event.filename + ":" + event.lineno + ":" + event.colno + "]", has_stack ? event.error.stack : undefined, false, has_stack); }); // Get things started. @@ -36,7 +39,7 @@ FFZ.msg_commands = {}; // Version var VER = FFZ.version_info = { - major: 3, minor: 5, revision: 169, + major: 3, minor: 5, revision: 172, toString: function() { return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || ""); } @@ -52,32 +55,38 @@ FFZ.prototype.log = function(msg, data, to_json, log_json) { this._log_data.push(msg + ((!to_json && log_json) ? " -- " + JSON.stringify(data) : "")); if ( data !== undefined && console.groupCollapsed && console.dir ) { - console.groupCollapsed("FFZ: " + msg); - if ( navigator.userAgent.indexOf("Firefox/") !== -1 ) + console.groupCollapsed("%cFFZ:%c " + msg, "color:#755000; font-weight: bold", "color:black; font-weight: normal"); + if ( typeof data === "string" || navigator.userAgent.indexOf("Firefox/") !== -1 ) console.log(data); else console.dir(data); - console.groupEnd("FFZ: " + msg); + console.groupEnd("%cFFZ:%c " + msg, "color:#755000; font-weight: bold", "color:black; font-weight: normal"); } else - console.log("FFZ: " + msg); + console.log("%cFFZ:%c " + msg, "color:#755000; font-weight: bold", "color:black; font-weight: normal"); } -FFZ.prototype.error = function(msg, data, to_json, log_json) { - msg = "Error: " + msg + (to_json ? " -- " + JSON.stringify(data) : ""); +FFZ.prototype.error = function(msg, error, to_json, log_json) { + var data = error && error.stack || error; + msg = "Error: " + msg + " [" + error + "]" + (to_json ? " -- " + JSON.stringify(data) : ""); this._log_data.push(msg + ((!to_json && log_json) ? " -- " + JSON.stringify(data) : "")); + if ( data === undefined ) { + var err = new Error(); + data = err.stack; + } + if ( data !== undefined && console.groupCollapsed && console.dir ) { - console.groupCollapsed("FFZ " + msg); - if ( navigator.userAgent.indexOf("Firefox/") !== -1 ) + console.groupCollapsed("%cFFZ " + msg, "color:red"); + if ( typeof data === "string" || navigator.userAgent.indexOf("Firefox/") !== -1 ) console.log(data); else console.dir(data); - console.groupEnd("FFZ " + msg); + console.groupEnd("%cFFZ " + msg, "color:red"); } else - console.assert(false, "FFZ " + msg); + console.log("%cFFZ " + msg, "color:red"); } @@ -155,6 +164,7 @@ require('./ember/chat-input'); require('./ember/directory'); require('./ember/following'); require('./ember/feed-card'); +require('./ember/sidebar'); require('./debug'); @@ -253,7 +263,7 @@ FFZ.prototype.init_settings_transfer = function() { 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); - this.log("Initializing FrankerFaceZ version " + FFZ.version_info); + this.log("Initializing FrankerFaceZ version " + FFZ.version_info, DOG); this.users = {}; this.is_dashboard = false; @@ -277,7 +287,7 @@ FFZ.prototype.init_player = function(delay) { FFZ.prototype.init_normal = function(delay, no_socket) { var start = (window.performance && performance.now) ? performance.now() : Date.now(); this.log("Found non-Ember Twitch after " + (delay||0) + " ms at: " + location); - this.log("Initializing FrankerFaceZ version " + FFZ.version_info); + this.log("Initializing FrankerFaceZ version " + FFZ.version_info, DOG); this.users = {}; this.is_dashboard = false; @@ -301,6 +311,7 @@ FFZ.prototype.init_normal = function(delay, no_socket) { this.setup_colors(); this.setup_emoticons(); this.setup_badges(); + this.setup_sidebar(); this.setup_notifications(); this.setup_following_count(false); @@ -322,7 +333,7 @@ FFZ.prototype.is_dashboard = false; FFZ.prototype.init_dashboard = function(delay) { var start = (window.performance && performance.now) ? performance.now() : Date.now(); this.log("Found Twitch Dashboard after " + (delay||0) + " ms at: " + location); - this.log("Initializing FrankerFaceZ version " + FFZ.version_info); + this.log("Initializing FrankerFaceZ version " + FFZ.version_info, DOG); var match = location.pathname.match(/\/([^\/]+)/); this.dashboard_channel = match && match[1] || undefined; @@ -371,7 +382,7 @@ FFZ.prototype.init_dashboard = function(delay) { FFZ.prototype.init_ember = function(delay) { var start = (window.performance && performance.now) ? performance.now() : Date.now(); this.log("Found Twitch application after " + (delay||0) + " ms at: " + location); - this.log("Initializing FrankerFaceZ version " + FFZ.version_info); + this.log("Initializing FrankerFaceZ version " + FFZ.version_info, DOG); this.users = {}; this.is_dashboard = false; @@ -420,6 +431,7 @@ FFZ.prototype.init_ember = function(delay) { this.setup_directory(); this.setup_profile_following(); this.setup_feed_cards(); + this.setup_sidebar(); //this.setup_teams(); diff --git a/src/tokenize.js b/src/tokenize.js index ce84b58d..b724c0f0 100644 --- a/src/tokenize.js +++ b/src/tokenize.js @@ -794,7 +794,7 @@ FFZ.prototype.render_tokens = function(tokens, render_links, warn_links) { // Creative Tags // --------------------- -FFZ.prototype.tokenize_ctags = function(tokens) { +FFZ.prototype.tokenize_ctags = function(tokens, tags_only) { "use strict"; if ( typeof tokens === "string" ) @@ -812,7 +812,7 @@ FFZ.prototype.tokenize_ctags = function(tokens) { if ( token.type === "text" ) token = token.text; else { - new_tokens.push(token); + ! tags_only && new_tokens.push(token); continue; } @@ -824,7 +824,7 @@ FFZ.prototype.tokenize_ctags = function(tokens) { tag = segment.substr(1).toLowerCase(); if ( segment.charAt(0) === '#' && banned_tags.indexOf(tag) === -1 ) { if ( text.length ) { - new_tokens.push({type: "text", text: text.join(' ') + ' '}); + ! tags_only && new_tokens.push({type: "text", text: text.join(' ') + ' '}); text = []; } @@ -834,7 +834,7 @@ FFZ.prototype.tokenize_ctags = function(tokens) { text.push(segment); } - if ( text.length > 1 || (text.length === 1 && text[0] !== '') ) + if ( ! tags_only && (text.length > 1 || (text.length === 1 && text[0] !== '')) ) new_tokens.push({type: "text", text: text.join(' ')}); } diff --git a/src/ui/following-count.js b/src/ui/following-count.js index 75ba6c65..eae293d7 100644 --- a/src/ui/following-count.js +++ b/src/ui/following-count.js @@ -34,8 +34,8 @@ FFZ.settings_info.following_count = { no_mobile: true, - category: "Appearance", - name: "Sidebar Following Data", + category: "Sidebar", + name: "Following Data", help: "Display the number of live channels you're following on the sidebar, and list the channels in a tooltip.", on_update: function(val) { @@ -218,13 +218,14 @@ FFZ.prototype._build_following_tooltip = function(el) { now = Date.now() - (this._ws_server_offset || 0), uptime = up_since && Math.floor((now - up_since.getTime()) / 1000) || 0, minutes = Math.floor(uptime / 60) % 60, - hours = Math.floor(uptime / 3600); + hours = Math.floor(uptime / 3600), + tags = stream.channel.game === 'Creative' && this.tokenize_ctags(stream.channel.status, true); tooltip += (i === 0 ? '
' : '') + (uptime > 0 ? '' + constants.CLOCK + ' ' + (hours > 0 ? hours + 'h' : '') + minutes + 'm' : '') + '' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '' + '' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '
' + - '' + (stream.channel.game === 'Creative' ? 'Being Creative' : (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing')) + ''; + '' + (stream.channel.game === 'Creative' ? 'Being Creative' : (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing')) + (tags ? ' | ' + _.pluck(tags, "text").join(" ") : '') + ''; } } else { c++; // is a terrible programming language @@ -322,7 +323,7 @@ FFZ.prototype._draw_following_count = function(count) { continue; if ( this.has_bttv || ! this.settings.following_count ) { - container.removeChild(badge); + badge && container.removeChild(badge); continue; } else if ( ! badge ) { diff --git a/src/utils.js b/src/utils.js index 31e0e0e1..0ad37808 100644 --- a/src/utils.js +++ b/src/utils.js @@ -489,5 +489,10 @@ module.exports = FFZ.utils = { if ( content ) out.innerHTML = content; return out; + }, + + toggle_cls: function(cls) { + var cl = document.body.classList; + return cl.toggle.bind(cl, cls); } } \ No newline at end of file diff --git a/style.css b/style.css index 7ac74f16..00083a14 100644 --- a/style.css +++ b/style.css @@ -4,11 +4,10 @@ body > div.tipsy { opacity: 1 !important; } body > div.tipsy .tipsy-inner { background-color: rgba(0,0,0,0.8); } body > div.tipsy .tipsy-arrow { opacity: 0.8; } - +.ffz-flip .drawer__item--brick .warp__logo, +.ffz-flip .drawer__item--xs .warp__glitch, .ffz-flip { - -ms-transform: rotate(180deg); - -webkit-transform: rotate(180deg); - transform: rotate(180deg); + transform: scale(-1); } .ffz-ui-toggle { @@ -19,6 +18,9 @@ body > div.tipsy .tipsy-arrow { opacity: 0.8; } cursor: pointer; } +.ffz-hide-friends nav .friend-list, +.ffz-hide-friends .warp__status .js-presence-indicator, +.ffz-hide-more-at-twitch nav .tse-content > .warp__list:last-of-type, .ffz-hide-recommended-friends .recommended-friends, .ffz-hide-recommended-channels .js-recommended-channels, .ffz-hide-recent-past-broadcast .recent-past-broadcast, @@ -113,12 +115,6 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic .ffz-ui-toggle.live { animation: ffzfade 8s linear infinite; - -webkit-animation: ffzfade 8s linear infinite; -} - -@-webkit-keyframes ffzfade { - from, to { opacity: 1; } - 50% { opacity: 0.75; } } @keyframes ffzfade { @@ -126,6 +122,20 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic 50% { opacity: 0.75; } } +.drawer__item--brick .warp__logo:hover { + animation: ffzflipwobble 4s infinite; +} + +@keyframes ffzflipwobble { + 0%,30% { transform: none } + 36% { transform: rotate(185deg) } + 38% { transform: rotate(175deg) } + 40%,90% { transform: rotate(180deg) } + 96% { transform: rotate(365deg) } + 98% { transform: rotate(355deg) } + 100% { transform: rotate(360deg) } +} + .ember-chat .chat-menu.ffz-ui-popup { padding: 0 } @@ -153,8 +163,6 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic width: 0px; height: 0px; border-radius: 999px; - -moz-border-radius: 999px; - -webkit-border-radius: 999px; top: 50%; left: 50%; z-index: 1 @@ -174,16 +182,10 @@ body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emotic .ffz-ui-popup .button.live:before { animation: expand 1500ms infinite ease-in; - -moz-animation: expand 1500ms infinite ease-in; - -webkit-animation: expand 1500ms infinite ease-in; - -o-animation: expand 1500ms infinite ease-in } .ffz-ui-popup .button.live:after { animation: expand 1500ms infinite 750ms ease-in; - -moz-animation: expand 1500ms infinite 750ms ease-in; - -webkit-animation: expand 1500ms infinite 750ms ease-in; - -o-animation: expand 1500ms infinite 750ms ease-in } #dash_main #stats .stat.dark#ffz_count svg path { fill: #cacaca; } @@ -1440,17 +1442,9 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator { background-image: url("//cdn.frankerfacez.com/script/spinner-dark.png"); margin: 50px auto; - -webkit-animation: ffz-rotateplane 1.2s infinite linear; animation: ffz-rotateplane 1.2s infinite linear; } -@-webkit-keyframes ffz-rotateplane { - 0% { -webkit-transform: perspective(120px) rotateY(90deg) } - 25% { -webkit-transform: perspective(120px) rotateY(180deg) } - 75% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } - 100% { -webkit-transform: perspective(120px) rotateY(90deg) rotateX(180deg) } -} - @keyframes ffz-rotateplane { 0% { transform: perspective(120px) rotateY(90deg) } 25% { transform: perspective(120px) rotateY(180deg) } @@ -2710,6 +2704,7 @@ body:not(.ffz-tags-on-channel) .tw-title--tall { height: 60px } .ffz-suggestions .suggestion div, .ffz-suggestions .suggestion span { + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @@ -2763,4 +2758,6 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 } /* New Sidebar */ +.ffz-hide-friends-collapsed .drawer--summary.closed .friend-list { display: none } + .warp__anchor { height: 5.5rem } \ No newline at end of file