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 ? '