diff --git a/dark.css b/dark.css index 2cdd6884..0b762196 100644 --- a/dark.css +++ b/dark.css @@ -149,6 +149,8 @@ body.ffz-dark, border-color: #32323e !important; } +.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), @@ -173,6 +175,8 @@ body.ffz-dark, box-shadow: rgba(255,255,255,0.2) 0 0 0 1px inset; } +.ffz-dark .balloon:after { box-shadow: none } + .ffz-dark .st-autocomplete-sidebar .label, .ffz-dark .st-autocomplete-small .label, .ffz-dark .st-autocomplete .label, @@ -1113,113 +1117,44 @@ body.ffz-dark, } -/*.ffz-dark .ignore-cta { - background-color: #333; - box-shadow: 0 3px 0 #000; +/* Activity Feeds */ + +.ffz-dark .pill { background-color: rgba(255,255,255,0.2) } + +.ffz-dark .activity-list-end svg { fill: #474747 } + +.ffz-dark .activity-meta:before { background-color: #474747 } + +.ffz-dark .activity-react__like:hover { + border-color: #d5d5d5; + background-color: #242424; } -.ffz-dark .ignore-cta .conversation-system-message { - color: #ccc; +.ffz-dark .activity-react__like svg.endorse-icon #head__base { fill: #fff } + +.ffz-dark .activity-create__actions { + background-color: #191919; + box-shadow: 0 -1px 0 #474747; } -.ffz-dark .conversations-list-icon { - background: #19191f; - color: #8c8c9c; - border-color: #19191f +.ffz-dark .activity-create, +.ffz-dark .activity-react__like { + border-color: #474747; + color: #fff !important; + background-color: #191919; } -.ffz-dark .conversations-list-icon:hover { - color: #fff +.ffz-dark .activity-meta:before, +.ffz-dark .activity-card { + border-color: #474747; } -.ffz-dark .conversations-list { - background: #19191f; - border: 1px solid #32323e; - color: #fff +.ffz-dark .activity-card__status { + background-color: #191919; } -.ffz-dark .conversations-list:after { - border-color: rgba(25,25,31,0); - border-top-color: #19191f; - border-width: 10px; - margin-left: -10px +.ffz-dark .activity-meta { + box-shadow: inset 0 -1px 0 #474747; } -.ffz-dark .conversations-list:before { - right: 9px; - border-color: rgba(50,50,62,0); - border-top-color: #32323e -} - -.ffz-dark .conversations-list .conversations-list-header { - background: #121218; - border-bottom: 1px solid #32323e; - color: #fff -} - -.ffz-dark .conversations-list .conversation-preview-line { - color: #8c8c9c -} - -.ffz-dark .conversations-list .conversations-list-item { - border-bottom: 1px solid #32323e -} - -.ffz-dark .conversations-list .conversations-list-item:hover { - background-color: #121218; -} - -.ffz-dark .conversation-window { - background: #19191f; - box-shadow: none; - color: #8c8c9c; -} - -.ffz-dark .conversations-list-icon, -.ffz-dark .conversation-window { - border: 1px solid rgba(255,255,255,0.2); - border-bottom: none; -} - -.ffz-dark .conversation-header { - background: #121217; - box-shadow: none; -} - -.ffz-dark .conversation-window:not(.collapsed) .conversation-header { - border-bottom: 1px solid rgba(255,255,255,0.2); -} - -.ffz-dark .conversation-input-bar textarea { - border-color: rgba(255,255,255,0.1); - background-color: rgba(255,255,255,0.05); - color: #b6b6b6 -} - -.ffz-dark .conversation-input-actions .button, -.ffz-dark .conversation-input-actions .follow-button:not(.ember-follow) .follow { - background-color: #444 -} - -.ffz-dark .conversation-window.has-focus .conversation-header { - background-color: #121217 -} - -.ffz-dark .conversation-window.has-focus .conversation-header-name { - color: #fff -} - -.ffz-dark .conversation-window.has-focus .conversation-input-bar textarea:focus { - border-color: rgba(255,255,255,0.2) -} - -.ffz-dark .conversation-window.has-focus .conversation-input-actions .button, -.ffz-dark .conversation-window.has-focus .conversation-input-actions .follow-button:not(.ember-follow) .follow { - background-color: #6441a5 -} - -.ffz-dark .conversation-window .timestamp-line span, -.ffz-dark .conversation-window .new-message-divider span { background: transparent; } - -.ffz-dark .conversation-window .timestamp-line:after, -.ffz-dark .conversation-window .new-message-divider:after { display: none; }*/ \ No newline at end of file +.ffz-dark a.balloon__link:hover { color: #fff !important } \ No newline at end of file diff --git a/src/ember/channel.js b/src/ember/channel.js index 9351c6e1..24a2ec31 100644 --- a/src/ember/channel.js +++ b/src/ember/channel.js @@ -224,6 +224,23 @@ FFZ.prototype._modify_cindex = function(view) { opts.options.gravity = utils.tooltip_placement(constants.TOOLTIP_DISTANCE, opts.options.gravity || 'n'); + /*if ( id === 'memeathon' ) { + var sb = document.createElement('a'); + sb.className = 'action button js-sub-button primary subscribe-button meme-sub-button'; + sb.id = 'meme-scribe'; + sb.innerHTML = 'Subscribe$599.99'; + + var actions = el.querySelector('.channel-actions'); + if ( actions ) { + var c = actions.querySelector('.notification-controls') || actions.querySelector('.follow-button'); + if ( c ) + actions.insertBefore(sb, c.nextSibling); + else + actions.appendChild(sb); + } + }*/ + + this.ffzFixTitle(); this.ffzUpdateUptime(); this.ffzUpdateChatters(); diff --git a/src/ember/chatview.js b/src/ember/chatview.js index 80833f0d..c90599b6 100644 --- a/src/ember/chatview.js +++ b/src/ember/chatview.js @@ -514,6 +514,11 @@ FFZ.prototype._modify_cview = function(view) { ffzInit: function() { f._chatv = this; + var room_id = this.get('controller.currentRoom.id'), + el = this.get('element'); + + el && el.setAttribute('data-room', room_id || ""); + this.$('.textarea-contain').append(f.build_ui_link(this)); this.$('.chat-messages').find('.html-tooltip').tipsy({live: true, html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')}); this.$('.chat-messages').find('.ffz-tooltip').tipsy({live: true, html: true, title: f.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')}); @@ -589,6 +594,7 @@ FFZ.prototype._modify_cview = function(view) { var room = this.get('controller.currentRoom'), room_id = room && room.get('id'), + el = this.get('element'), was_unread = room_id && this.ffz_unread[room_id], update_height = false; @@ -597,6 +603,7 @@ FFZ.prototype._modify_cview = function(view) { room.ffz_last_view = Date.now(); } + el && el.setAttribute('data-room', room_id || ""); if ( room && room._ffz_tab ) { var was_hidden = room._ffz_tab.classList.contains('hidden'), diff --git a/src/emoticons.js b/src/emoticons.js index 0e261442..d7c15adb 100644 --- a/src/emoticons.js +++ b/src/emoticons.js @@ -413,6 +413,8 @@ FFZ.prototype._load_set_json = function(set_id, callback, data) { if ( this._inputv ) Ember.propertyDidChange(this._inputv, 'ffz_emoticons'); + this.rerender_feed_cards(); + if ( callback ) callback(true, data); } \ No newline at end of file diff --git a/src/ext/betterttv.js b/src/ext/betterttv.js index 9a389ade..943f1467 100644 --- a/src/ext/betterttv.js +++ b/src/ext/betterttv.js @@ -49,6 +49,7 @@ FFZ.prototype.setup_bttv = function(delay) { } document.body.classList.add('ffz-bttv'); + document.body.classList.toggle('ffz-bttv-dark', BetterTTV.settings.get('darkenedMode')); // Disable Chat Tabs if ( this._chatv ) { diff --git a/src/main.js b/src/main.js index 81f0f253..b862ec78 100644 --- a/src/main.js +++ b/src/main.js @@ -35,7 +35,7 @@ FFZ.msg_commands = {}; // Version var VER = FFZ.version_info = { - major: 3, minor: 5, revision: 151, + major: 3, minor: 5, revision: 152, toString: function() { return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || ""); } @@ -153,6 +153,7 @@ require('./ember/chat-input'); //require('./ember/teams'); require('./ember/directory'); require('./ember/following'); +require('./ember/feed-card'); require('./debug'); @@ -180,6 +181,7 @@ require('./ui/about_page'); require('./commands'); require('./ext/api'); +//require('./memes'); // --------------- @@ -415,6 +417,7 @@ FFZ.prototype.init_ember = function(delay) { this.setup_chat_input(); this.setup_directory(); this.setup_profile_following(); + this.setup_feed_cards(); //this.setup_teams(); @@ -433,6 +436,8 @@ FFZ.prototype.init_ember = function(delay) { this.find_bttv(10); this.find_emote_menu(10); + //this.setup_memes(); + //this.check_news(); this.check_ff(); this.refresh_chat(); diff --git a/src/tokenize.js b/src/tokenize.js index e2e83134..9b5a15a8 100644 --- a/src/tokenize.js +++ b/src/tokenize.js @@ -622,115 +622,162 @@ FFZ.prototype.tokenize_line = function(user, room, message, no_emotes, no_emoji) } +FFZ.prototype.tokenize_feed_body = function(message, emotes, user_id) { + "use strict"; + + if ( typeof message === "string" ) + message = [{type: "text", text: message}]; + + if ( helpers && helpers.linkifyMessage ) + message = helpers.linkifyMessage(message); + + if ( helpers && helpers.emoticonizeMessage ) + message = helpers.emoticonizeMessage(message, emotes); + + // Tokenize Lines + var tokens = [], token; + + for(var i = 0; i < message.length; i++) { + token = message[i]; + if ( ! token ) + continue; + + if ( typeof token !== "string" ) + if ( token.type === "text" ) + token = token.text; + else { + tokens.push(token); + continue; + } + + var segments = token.split(/\n/g); + while(segments.length) { + tokens.push({type: "text", text: segments.shift()}); + if ( segments.length ) + tokens.push({type: "raw", html: "

"}); + } + } + + tokens = this.tokenize_emotes(user_id, user_id, tokens) + + if ( this.settings.parse_emoji ) + tokens = this.tokenize_emoji(tokens); + + return tokens; +} + + +FFZ.prototype.render_token = function(render_links, warn_links, token) { + if ( ! token ) + return ""; + + if ( token.hidden ) + return ""; + + else if ( token.type === "raw" ) + return token.html; + + else if ( token.type === "emoticon" ) { + var src = token.imgSrc, srcset, cls, extra; + if ( token.ffzEmote ) { + var emote_set = this.emote_sets && this.emote_sets[token.ffzEmoteSet], + emote = emote_set && emote_set.emoticons && emote_set.emoticons[token.ffzEmote]; + + srcset = emote ? emote.srcSet : token.srcSet; + //extra = (emote ? ` data-ffz-emote="${emote.id}"` : '') + (emote_set ? ` data-ffz-set="${emote_set.id}"` : ''); + extra = (emote ? ' data-ffz-emote="' + emote.id + '"' : '') + (emote_set ? ' data-ffz-set="' + emote_set.id + '"' : '') + + } else if ( token.ffzEmoji ) { + var setting = this.settings.parse_emoji; + if ( setting === 0 || (setting === 1 && ! token.tw) || (setting === 2 && ! token.noto) || (setting === 3 && ! token.one) ) + return token.altText; + + src = setting === 3 ? token.one_src : (setting === 2 ? token.noto_src : token.tw_src); + //extra = ` data-ffz-emoji="${token.ffzEmoji}" height="18px"`; + extra = ' data-ffz-emoji="' + token.ffzEmoji + '" height="18px"'; + cls = ' emoji'; + + } else { + var id = FFZ.src_to_id(src), + replacement = this.settings.replace_bad_emotes && constants.EMOTE_REPLACEMENTS[id]; + + //extra = ` data-emote="${id}" onerror="FrankerFaceZ._emote_mirror_swap(this)"`; + extra = ' data-emote="' + id + '" onerror="FrankerFaceZ._emote_mirror_swap(this)"'; + + if ( replacement ) { + src = constants.EMOTE_REPLACEMENT_BASE + replacement; + srcset = ''; + } else + srcset = utils.build_srcset(id); + } + + //return `${utils.quote_attr(token.altText)}`; + return '' + utils.quote_attr(token.altText) + ''; + } + + else if ( token.type === "link" ) { + var text = token.title || (token.isLong && '') || (token.isDeleted && '') || (warn_links && '') || token.text; + + if ( ! render_links && render_links !== undefined ) + return utils.sanitize(text); + + var href = token.link || token.text, + cls = ''; + + if ( token.isMailTo ) { + // E-Mail Link + cls = 'email-link'; + href = 'mailto:' + href; + + } else { + // Web Link + cls = 'chat-link'; + + if ( this.settings.link_info ) { + if (!( this._link_data && this._link_data[href] )) { + this._link_data = this._link_data || {}; + this._link_data[href] = true; + this.ws_send("get_link", href, load_link_data.bind(this, href)); + } + } + } + + // Deleted Links + var actual_href = href; + if ( token.isDeleted ) { + cls = 'deleted-link ' + cls; + href = '#'; + + } else if ( warn_links ) { + cls = 'warn-link deleted-link ' + cls; + href = '#'; + } + + //return `${utils.sanitize(text)}`; + return '' + utils.sanitize(text) + ''; + } + + else if ( token.type === "deleted" ) + return '×××'; + //return `×××`; + + else if ( token.type === "mention" ) + return '' + utils.sanitize(token.user) + ''; + //return `${utils.sanitize(token.user)}`; + + else if ( token.deletedLink || token.text ) + return utils.sanitize(token.text); + + else if ( typeof token !== "string" ) + return '[invalid token]'; + //return `[invalid token]`; + + return utils.sanitize(token); +} + + FFZ.prototype.render_tokens = function(tokens, render_links, warn_links) { - var f = this; - return _.map(tokens, function(token) { - if ( ! token ) - return ""; - - if ( token.hidden ) - return ""; - - else if ( token.type === "raw" ) - return token.html; - - else if ( token.type === "emoticon" ) { - var src = token.imgSrc, srcset, cls, extra; - if ( token.ffzEmote ) { - var emote_set = f.emote_sets && f.emote_sets[token.ffzEmoteSet], - emote = emote_set && emote_set.emoticons && emote_set.emoticons[token.ffzEmote]; - - srcset = emote ? emote.srcSet : token.srcSet; - //extra = (emote ? ` data-ffz-emote="${emote.id}"` : '') + (emote_set ? ` data-ffz-set="${emote_set.id}"` : ''); - extra = (emote ? ' data-ffz-emote="' + emote.id + '"' : '') + (emote_set ? ' data-ffz-set="' + emote_set.id + '"' : '') - - } else if ( token.ffzEmoji ) { - var setting = f.settings.parse_emoji; - if ( setting === 0 || (setting === 1 && ! token.tw) || (setting === 2 && ! token.noto) || (setting === 3 && ! token.one) ) - return token.altText; - - src = setting === 3 ? token.one_src : (setting === 2 ? token.noto_src : token.tw_src); - //extra = ` data-ffz-emoji="${token.ffzEmoji}" height="18px"`; - extra = ' data-ffz-emoji="' + token.ffzEmoji + '" height="18px"'; - cls = ' emoji'; - - } else { - var id = FFZ.src_to_id(src), - replacement = f.settings.replace_bad_emotes && constants.EMOTE_REPLACEMENTS[id]; - - //extra = ` data-emote="${id}" onerror="FrankerFaceZ._emote_mirror_swap(this)"`; - extra = ' data-emote="' + id + '" onerror="FrankerFaceZ._emote_mirror_swap(this)"'; - - if ( replacement ) { - src = constants.EMOTE_REPLACEMENT_BASE + replacement; - srcset = ''; - } else - srcset = utils.build_srcset(id); - } - - //return `${utils.quote_attr(token.altText)}`; - return '' + utils.quote_attr(token.altText) + ''; - } - - else if ( token.type === "link" ) { - var text = token.title || (token.isLong && '') || (token.isDeleted && '') || (warn_links && '') || token.text; - - if ( ! render_links && render_links !== undefined ) - return utils.sanitize(text); - - var href = token.link || token.text, - cls = ''; - - if ( token.isMailTo ) { - // E-Mail Link - cls = 'email-link'; - href = 'mailto:' + href; - - } else { - // Web Link - cls = 'chat-link'; - - if ( f.settings.link_info ) { - if (!( f._link_data && f._link_data[href] )) { - f._link_data = f._link_data || {}; - f._link_data[href] = true; - f.ws_send("get_link", href, load_link_data.bind(f, href)); - } - } - } - - // Deleted Links - var actual_href = href; - if ( token.isDeleted ) { - cls = 'deleted-link ' + cls; - href = '#'; - - } else if ( warn_links ) { - cls = 'warn-link deleted-link ' + cls; - href = '#'; - } - - //return `${utils.sanitize(text)}`; - return '' + utils.sanitize(text) + ''; - } - - else if ( token.type === "deleted" ) - return '×××'; - //return `×××`; - - else if ( token.type === "mention" ) - return '' + utils.sanitize(token.user) + ''; - //return `${utils.sanitize(token.user)}`; - - else if ( token.deletedLink || token.text ) - return utils.sanitize(token.text); - - else if ( typeof token !== "string" ) - return '[invalid token]'; - //return `[invalid token]`; - - return utils.sanitize(token); - }).join(""); + return _.map(tokens, this.render_token.bind(this, render_links, warn_links)).join(""); } diff --git a/src/ui/my_emotes.js b/src/ui/my_emotes.js index 0a4e1f63..aac547fd 100644 --- a/src/ui/my_emotes.js +++ b/src/ui/my_emotes.js @@ -93,9 +93,9 @@ FFZ.menu_pages.myemotes = { name: "My Emoticons", icon: constants.EMOTE, - visible: function(view) { + has_sets: function(view) { var user = this.get_user(), - tmi = view.get('controller.currentRoom.tmiSession'), + tmi = view && view.get('controller.currentRoom.tmiSession'), ffz_sets = user && this.users[user.login] && this.users[user.login].sets || [], twitch_sets = (tmi && tmi.getEmotes() || {'emoticon_sets': {}})['emoticon_sets'], @@ -104,7 +104,11 @@ FFZ.menu_pages.myemotes = { if ( sk && ! this.settings.global_emotes_in_menu && sk.indexOf('0') !== -1 ) sk.removeObject('0'); - return ffz_sets.length || (sk && sk.length) || this.settings.emoji_in_menu; + return ffz_sets.length || (sk && sk.length); + }, + + visible: function(view) { + return this.settings.emoji_in_menu || FFZ.menu_pages.myemotes.has_sets.apply(this, view); }, default_page: function() { @@ -134,6 +138,10 @@ FFZ.menu_pages.myemotes = { name: "All Emoticons", sort_order: 2, + visible: function(view) { + return FFZ.menu_pages.myemotes.has_sets.apply(this, view); + }, + render: function(view, container) { FFZ.menu_pages.myemotes.render_lists.call(this, view, container, false); } diff --git a/style.css b/style.css index 3a9283bb..fb67f826 100644 --- a/style.css +++ b/style.css @@ -2724,8 +2724,9 @@ body:not(.ffz-creative-showcase) .creative-hero, } -/* Dank * / +/* Dank */ +.big-memes.ffz-channel[data-channel="memeathon"]:after, .streams .ember-view[data-channel="memeathon"] .stream .thumb:after { content: ""; position: absolute; @@ -2735,4 +2736,75 @@ body:not(.ffz-creative-showcase) .creative-hero, background-size: contain; background-position: bottom right; pointer-events: none; -} \ No newline at end of file +} + +.big-memes.ffz-channel[data-channel="memeathon"]:after { background-size: 50% } + +.ffz-channel[data-channel="memeathon"] { + margin-top: -30px; + padding-top: 30px; + background-image: linear-gradient(rgba(255,255,255,0.5) 0%, rgba(255,255,255,0.8) 1080px), + url("https://static-cdn.jtvnw.net/jtv_user_pictures/memeathon-channel_offline_image-806e8ad012b1e372-1920x1080.png"); +} + +.ffz-bttv-dark .ffz-channel[data-channel="memeathon"], +.ffz-dark .ffz-channel[data-channel="memeathon"] { + background-image: linear-gradient(rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.85) 1080px), + url("https://static-cdn.jtvnw.net/jtv_user_pictures/memeathon-channel_offline_image-806e8ad012b1e372-1920x1080.png"); +} + +.ember-chat[data-room="memeathon"] { + background-position: left center; + background-image: linear-gradient(rgba(242,242,242,0.9) 0%, rgba(242,242,242,0.9) 1%), + url("https://static-cdn.jtvnw.net/jtv_user_pictures/memeathon-channel_offline_image-806e8ad012b1e372-1920x1080.png"); +} + +.ffz-bttv-dark .ember-chat[data-room="memeathon"], +.theatre .ember-chat[data-room="memeathon"], +.dark .ember-chat[data-room="memeathon"], +.force-dark .ember-chat[data-room="memeathon"] { + background-image: linear-gradient(rgba(25,25,25,0.95) 0%, rgba(25,25,25,0.95) 1%), + url("https://static-cdn.jtvnw.net/jtv_user_pictures/memeathon-channel_offline_image-806e8ad012b1e372-1920x1080.png"); +} + +.ffz-channel[data-channel="memeathon"] #broadcast-meta .title { + text-shadow: 1px 0 0 #fff, -1px 0 0 #fff, 0 1px 0 #fff, 0 -1px 0 #fff; +} + +.theatre .ffz-channel[data-channel="memeathon"] #broadcast-meta .title, +.ffz-dark .ffz-channel[data-channel="memeathon"] #broadcast-meta .title { text-shadow: none; } + +.ffz-channel[data-channel="memeathon"] #broadcast-meta, +.ffz-channel[data-channel="memeathon"] #broadcast-meta .title { + transform: scaleX(-1); +} + +.ffz-channel[data-channel="memeathon"] #broadcast-meta .profile-photo { + transform: scaleX(-1) rotate(12deg); +} + +.player[data-channel="memeathon"] .player-loading-spinner { + background: url("//cdn.frankerfacez.com/script/lanking.png") no-repeat; + width: 188px; + height: 188px; + border: none; + animation: loading-spin 1.5s infinite linear; +} + +/* Allow Zalgo */ +.chat-line[data-room="memeathon"] { overflow: visible !important } + +/* Tilted * / +.tilted.ember-chat[data-room="memeathon"] { transform: rotate(2deg); } + +/* Comic Sans * / +.comic-sans.chat-line[data-room="memeathon"] { font-family: "Comic Sans MS"; } + +/* BILLY MAYS * / +.billy-mays.chat-line[data-room="memeathon"] { text-transform: uppercase; } + +/* Upside Down * / +.upside-down.chat-line[data-room="memeathon"] { transform: scale(-1) } + +/* Big Emotes * / +.big-emotes.chat-line[data-room="memeathon"] .emoticon { zoom: 2 } \ No newline at end of file