mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-25 03:58:30 +00:00
3.5.217. Well, this commit is a bit late. Look at changelog.html for details on each version's changes.
This commit is contained in:
parent
2f7dc1d8d3
commit
8cfef363f1
22 changed files with 634 additions and 191 deletions
38
dark.css
38
dark.css
|
@ -67,7 +67,7 @@
|
||||||
color:rgb(222,222,222)!important;
|
color:rgb(222,222,222)!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .moderation-card .button:not(.glyph-only):hover {
|
.ffz-dark .moderation-card .button:not(.button--icon-only):hover {
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,10 +204,16 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
.ffz-dark .ffz-ui-popup.emoticon-selector .emoticon-selector-box { border: none }
|
.ffz-dark .ffz-ui-popup.emoticon-selector .emoticon-selector-box { border: none }
|
||||||
|
|
||||||
.ffz-dark .balloon--up:after { box-shadow: 1px 1px 0 rgba(255,255,255,0.2) }
|
.ffz-dark .balloon--up:after { box-shadow: 1px 1px 0 rgba(255,255,255,0.2) }
|
||||||
|
.ffz-dark .balloon--right.balloon--down:after,
|
||||||
.ffz-dark .balloon--down:after { box-shadow: -1px -1px 0 rgba(255,255,255,0.2) }
|
.ffz-dark .balloon--down:after { box-shadow: -1px -1px 0 rgba(255,255,255,0.2) }
|
||||||
.ffz-dark .balloon--left:after { box-shadow: 1px -1px 0 rgba(255,255,255,0.2) }
|
.ffz-dark .balloon--left:after { box-shadow: 1px -1px 0 rgba(255,255,255,0.2) }
|
||||||
.ffz-dark .balloon--right:after { box-shadow: -1px 1px 0 rgba(255,255,255,0.2) }
|
.ffz-dark .balloon--right:after { box-shadow: -1px 1px 0 rgba(255,255,255,0.2) }
|
||||||
|
|
||||||
|
.ffz-dark .balloon__footer {
|
||||||
|
background-color: rgb(25,25,25);
|
||||||
|
border: 1px solid rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.ffz-dark .player-menu__header { color: #c3c3c3 }
|
.ffz-dark .player-menu__header { color: #c3c3c3 }
|
||||||
.ffz-dark .player-menu__section { border-bottom-color: rgba(255,255,255,0.2) }
|
.ffz-dark .player-menu__section { border-bottom-color: rgba(255,255,255,0.2) }
|
||||||
|
@ -349,15 +355,17 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
background-color: #25252a;
|
background-color: #25252a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .button:not(.button--status):not(.primary) {
|
.ffz-dark .message-button,
|
||||||
|
.ffz-dark .button--text,
|
||||||
|
.ffz-dark .button.ffz-no-bg {
|
||||||
color: #a68ed2;
|
color: #a68ed2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .button.glyph-only svg path {
|
.ffz-dark .button.button--icon-only svg path {
|
||||||
fill: #a68ed2;
|
fill: #a68ed2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .button.glyph-only:hover svg path {
|
.ffz-dark .button.button--icon-only:hover svg path {
|
||||||
fill: #fff;
|
fill: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,10 +573,6 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
.ffz-dark .toggle-darkmode { display: none; }
|
.ffz-dark .toggle-darkmode { display: none; }
|
||||||
|
|
||||||
/* Chat Text Contrast */
|
/* Chat Text Contrast */
|
||||||
.ffz-dark .ember-chat-container.dark .chat-line,
|
|
||||||
.ffz-dark .chat-container.dark .chat-line {
|
|
||||||
color: #acacbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ffz-dark .ember-chat .chat-settings .chat-colors .chat-colors-swatch:hover,
|
.ffz-dark .ember-chat .chat-settings .chat-colors .chat-colors-swatch:hover,
|
||||||
.ffz-dark .ember-chat .chat-settings .chat-colors .chat-colors-switch.selected {
|
.ffz-dark .ember-chat .chat-settings .chat-colors .chat-colors-switch.selected {
|
||||||
|
@ -956,6 +960,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
.ffz-dark #mantle_skin ul.vtabs li .not_linked,
|
.ffz-dark #mantle_skin ul.vtabs li .not_linked,
|
||||||
.ffz-dark #mantle_skin ul.vtabs li.selected a,
|
.ffz-dark #mantle_skin ul.vtabs li.selected a,
|
||||||
.ffz-dark #mantle_skin ul.submenu li a:hover,
|
.ffz-dark #mantle_skin ul.submenu li a:hover,
|
||||||
|
.ffz-dark .sort-contain .sort-options li a:hover,
|
||||||
.ffz-dark #mantle_skin ul.submenu .active a {
|
.ffz-dark #mantle_skin ul.submenu .active a {
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
@ -1128,8 +1133,8 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
fill: rgba(255,255,255,0.5);
|
fill: rgba(255,255,255,0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .conversation-input-bar .emoticon-selector-box .emote-set {
|
.ffz-dark .emoticon-selector-box .emote-set {
|
||||||
border-color: #323232;
|
border-color: #323232 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .conversation-input-bar .emoticon-selector-box .emoticon-grid {
|
.ffz-dark .conversation-input-bar .emoticon-selector-box .emoticon-grid {
|
||||||
|
@ -1203,28 +1208,26 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
|
|
||||||
.ffz-dark .activity-list-end svg { fill: #474747 }
|
.ffz-dark .activity-list-end svg { fill: #474747 }
|
||||||
|
|
||||||
.ffz-dark .activity-meta:before { background-color: #474747 }
|
.ffz-dark .activity-meta-divider:before { background-color: #474747 }
|
||||||
|
|
||||||
.ffz-dark .activity-react__item:hover {
|
.ffz-dark .activity-button:hover {
|
||||||
border-color: #d5d5d5;
|
border-color: #d5d5d5;
|
||||||
background-color: #242424;
|
background-color: #242424;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .activity-react__item svg.endorse-icon #head__base { fill: #fff }
|
|
||||||
|
|
||||||
.ffz-dark .activity-create__actions {
|
.ffz-dark .activity-create__actions {
|
||||||
background-color: #191919;
|
background-color: #191919;
|
||||||
box-shadow: 0 -1px 0 #474747;
|
box-shadow: 0 -1px 0 #474747;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .activity-create,
|
.ffz-dark .activity-create,
|
||||||
.ffz-dark .activity-react__item {
|
.ffz-dark .activity-button {
|
||||||
border-color: #474747;
|
border-color: #474747;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
background-color: #191919;
|
background-color: #191919;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .activity-meta:before,
|
.ffz-dark .activity-meta-divider:before,
|
||||||
.ffz-dark .activity-card {
|
.ffz-dark .activity-card {
|
||||||
border-color: #474747;
|
border-color: #474747;
|
||||||
}
|
}
|
||||||
|
@ -1233,11 +1236,12 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
background-color: #191919;
|
background-color: #191919;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .activity-meta {
|
.ffz-dark .activity-meta-divider {
|
||||||
box-shadow: inset 0 -1px 0 #474747;
|
box-shadow: inset 0 -1px 0 #474747;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark a.balloon__link:hover { color: #fff !important }
|
.ffz-dark a.balloon__link:hover { color: #fff !important }
|
||||||
|
.ffz-dark .activity-meta__name { color: #ccc }
|
||||||
|
|
||||||
|
|
||||||
/* Search Panel */
|
/* Search Panel */
|
||||||
|
|
|
@ -128,8 +128,8 @@ FFZ.settings_info.sub_notice_badges = {
|
||||||
value: false,
|
value: false,
|
||||||
|
|
||||||
category: "Chat Appearance",
|
category: "Chat Appearance",
|
||||||
name: "Subscriber Notice Badges",
|
name: "Old-Style Subscriber Notice Badges",
|
||||||
help: "Display a subscriber badge on chat messages about new subscribers.",
|
help: "Display a subscriber badge on old-style chat messages about new subscribers.",
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
this.toggle_style('badges-sub-notice', ! val);
|
this.toggle_style('badges-sub-notice', ! val);
|
||||||
|
@ -348,8 +348,16 @@ FFZ.prototype.get_line_badges = function(msg) {
|
||||||
globals = badgeCollection && badgeCollection.global || {},
|
globals = badgeCollection && badgeCollection.global || {},
|
||||||
channel = badgeCollection && badgeCollection.channel || {};
|
channel = badgeCollection && badgeCollection.channel || {};
|
||||||
|
|
||||||
|
// Whisper Chat Lines have a non-associative array for some reason.
|
||||||
|
if ( Array.isArray(badge_tag) ) {
|
||||||
|
var val = badge_tag;
|
||||||
|
badge_tag = {};
|
||||||
|
for(var i=0; i < val.length; i++)
|
||||||
|
badge_tag[val[i].id] = val[i].version;
|
||||||
|
}
|
||||||
|
|
||||||
// VoD Chat lines don't have the badges pre-parsed for some reason.
|
// VoD Chat lines don't have the badges pre-parsed for some reason.
|
||||||
if ( typeof badge_tag === 'string' ) {
|
else if ( typeof badge_tag === 'string' ) {
|
||||||
var val = badge_tag.split(',');
|
var val = badge_tag.split(',');
|
||||||
badge_tag = {};
|
badge_tag = {};
|
||||||
for(var i=0; i < val.length; i++) {
|
for(var i=0; i < val.length; i++) {
|
||||||
|
@ -367,20 +375,6 @@ FFZ.prototype.get_line_badges = function(msg) {
|
||||||
var versions = channel[badge] || globals[badge],
|
var versions = channel[badge] || globals[badge],
|
||||||
binfo = versions && versions.versions && versions.versions[version];
|
binfo = versions && versions.versions && versions.versions[version];
|
||||||
|
|
||||||
if ( from === 'sirstendec' && badge === 'turbo' && globals.warcraft ) {
|
|
||||||
badge = 'warcraft';
|
|
||||||
version = 'protoss';
|
|
||||||
binfo = {
|
|
||||||
click_action: 'visit_url',
|
|
||||||
click_url: 'https://www.youtube.com/watch?v=dpBM2FIHprM',
|
|
||||||
description: 'My life for Aiur!',
|
|
||||||
title: 'Protoss',
|
|
||||||
image_url_1x: 'https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/1.png',
|
|
||||||
image_url_2x: 'https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/2.png',
|
|
||||||
image_url_3x: 'https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/4.png'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( hidden_badges.indexOf(badge) !== -1 )
|
if ( hidden_badges.indexOf(badge) !== -1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -456,7 +450,7 @@ FFZ.prototype.render_badges = function(badges) {
|
||||||
if ( badge.click_url )
|
if ( badge.click_url )
|
||||||
klass += ' click_url';
|
klass += ' click_url';
|
||||||
|
|
||||||
out.push('<div class="badge float-left tooltip ' + utils.quote_attr(klass) + '"' + (badge.click_url ? ' data-url="' + utils.quote_attr(badge.click_url) + '"' : '') + (css ? ' style="' + utils.quote_attr(css) + '"' : '') + ' title="' + utils.quote_attr(badge.title) + '"></div>');
|
out.push('<div class="badge float-left html-tooltip ' + utils.quote_attr(klass) + '"' + (badge.click_url ? ' data-url="' + utils.quote_attr(badge.click_url) + '"' : '') + (css ? ' style="' + utils.quote_attr(css) + '"' : '') + ' title="' + utils.quote_attr(badge.title) + '"></div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.join("");
|
return out.join("");
|
||||||
|
|
|
@ -46,12 +46,12 @@ FFZ.settings_info.fix_color = {
|
||||||
},
|
},
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
this.toggle_style('chat-colors-gray', !this.has_bttv && val === '-1');
|
this.toggle_style('chat-colors-gray', !this.has_bttv && val === '-1');
|
||||||
|
|
||||||
if ( ! this.has_bttv && val !== '-1' )
|
if ( ! this.has_bttv && val !== '-1' )
|
||||||
this._rebuild_colors();
|
this._rebuild_colors();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.luv_contrast = {
|
FFZ.settings_info.luv_contrast = {
|
||||||
|
|
|
@ -3,6 +3,10 @@ var SVGPATH = 'm120.95 1.74c4.08-0.09 8.33-0.84 12.21 0.82 3.61 1.8 7 4.16 11.01
|
||||||
DEBUG = localStorage.ffzDebugMode == "true" && document.body.classList.contains('ffz-dev'),
|
DEBUG = localStorage.ffzDebugMode == "true" && document.body.classList.contains('ffz-dev'),
|
||||||
SERVER = DEBUG ? "//localhost:8000/" : "https://cdn.frankerfacez.com/",
|
SERVER = DEBUG ? "//localhost:8000/" : "https://cdn.frankerfacez.com/",
|
||||||
|
|
||||||
|
IS_OSX = navigator.platform ? navigator.platform.indexOf('Mac') !== -1 : /OS X/.test(navigator.userAgent),
|
||||||
|
|
||||||
|
IS_WIN = navigator.platform ? navigator.platform.indexOf('Win') !== -1 : /Windows/.test(navigator.userAgent),
|
||||||
|
|
||||||
SEPARATORS = "[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]",
|
SEPARATORS = "[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]",
|
||||||
SPLITTER = new RegExp(SEPARATORS + "*," + SEPARATORS + "*"),
|
SPLITTER = new RegExp(SEPARATORS + "*," + SEPARATORS + "*"),
|
||||||
|
|
||||||
|
@ -15,7 +19,9 @@ module.exports = FrankerFaceZ.constants = {
|
||||||
DEBUG: DEBUG,
|
DEBUG: DEBUG,
|
||||||
SERVER: SERVER,
|
SERVER: SERVER,
|
||||||
|
|
||||||
IS_OSX: navigator.platform ? navigator.platform.indexOf('Mac') !== -1 : /OS X/.test(navigator.userAgent),
|
IS_OSX: IS_OSX,
|
||||||
|
IS_WIN: IS_WIN,
|
||||||
|
META_NAME: IS_OSX ? "⌘" : (IS_WIN ? "Win" : "Meta"),
|
||||||
|
|
||||||
// Twitch Client ID for API Stuff
|
// Twitch Client ID for API Stuff
|
||||||
CLIENT_ID: "a3bc9znoz6vi8ozsoca0inlcr4fcvkl",
|
CLIENT_ID: "a3bc9znoz6vi8ozsoca0inlcr4fcvkl",
|
||||||
|
|
|
@ -111,7 +111,6 @@ FFZ.prototype.setup_channel = function() {
|
||||||
var game = data.stream.game || (data.stream.channel && data.stream.channel.game);
|
var game = data.stream.game || (data.stream.channel && data.stream.channel.game);
|
||||||
if ( game ) {
|
if ( game ) {
|
||||||
t.set('content.game', game);
|
t.set('content.game', game);
|
||||||
t.set('content.rollbackData.game', game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( data.stream.channel ) {
|
if ( data.stream.channel ) {
|
||||||
|
@ -228,9 +227,9 @@ FFZ.prototype._modify_cindex = function(view) {
|
||||||
f.rebuild_race_ui();
|
f.rebuild_race_ui();
|
||||||
|
|
||||||
if ( f.settings.auto_theater ) {
|
if ( f.settings.auto_theater ) {
|
||||||
var Layout = utils.ember_lookup('service:layout');
|
var player = f.players && f.players[id] && f.players[id].get('player');
|
||||||
if ( Layout )
|
if ( player )
|
||||||
Layout.set('isTheatreMode', true);
|
player.setTheatre(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$().on("click", ".ffz-creative-tag-link", function(e) {
|
this.$().on("click", ".ffz-creative-tag-link", function(e) {
|
||||||
|
@ -296,7 +295,7 @@ FFZ.prototype._modify_cindex = function(view) {
|
||||||
if ( ! btn ) {
|
if ( ! btn ) {
|
||||||
btn = document.createElement('span');
|
btn = document.createElement('span');
|
||||||
btn.id = 'ffz-ui-host-button';
|
btn.id = 'ffz-ui-host-button';
|
||||||
btn.className = 'button action';
|
btn.className = 'button button--text';
|
||||||
|
|
||||||
btn.addEventListener('click', this.ffzClickHost.bind(this, false));
|
btn.addEventListener('click', this.ffzClickHost.bind(this, false));
|
||||||
|
|
||||||
|
@ -336,7 +335,7 @@ FFZ.prototype._modify_cindex = function(view) {
|
||||||
if ( ! btn ) {
|
if ( ! btn ) {
|
||||||
btn = document.createElement('span');
|
btn = document.createElement('span');
|
||||||
btn.id = 'ffz-ui-host-button';
|
btn.id = 'ffz-ui-host-button';
|
||||||
btn.className = 'button action';
|
btn.className = 'button button--text';
|
||||||
|
|
||||||
btn.addEventListener('click', this.ffzClickHost.bind(this, true));
|
btn.addEventListener('click', this.ffzClickHost.bind(this, true));
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,35 @@ FFZ.settings_info.input_complete_emotes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.settings_info.input_complete_aliases = {
|
||||||
|
type: "select",
|
||||||
|
options: {
|
||||||
|
0: "Disabled",
|
||||||
|
1: "By Name or Alias",
|
||||||
|
2: "Aliases Only"
|
||||||
|
},
|
||||||
|
|
||||||
|
value: 1,
|
||||||
|
|
||||||
|
process_value: function(val) {
|
||||||
|
if ( typeof val === 'string' )
|
||||||
|
return parseInt(val) || 0;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
category: "Chat Input",
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
name: "Tab-Complete User Aliases",
|
||||||
|
help: "Use tab completion to complete aliases you've given to users rather than their username.",
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
if ( this._inputv )
|
||||||
|
Ember.propertyDidChange(this._inputv, 'ffz_name_suggestions');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.input_complete_name_at = {
|
FFZ.settings_info.input_complete_name_at = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: true,
|
value: true,
|
||||||
|
@ -479,8 +508,11 @@ FFZ.prototype._modify_chat_input = function(component) {
|
||||||
ind = this.get('ffz_partial_word_start'),
|
ind = this.get('ffz_partial_word_start'),
|
||||||
text = this.get('textareaValue'),
|
text = this.get('textareaValue'),
|
||||||
|
|
||||||
content = ((f.settings.input_complete_name_at && item.type === 'user' && this.get('ffz_partial_word').charAt(0) === '@') ? '@' : '') +
|
first_char = text.charAt(0),
|
||||||
((item.command_content && text.charAt(0) === '/' ?
|
is_cmd = first_char === '/' || first_char === '.',
|
||||||
|
|
||||||
|
content = ((f.settings.input_complete_name_at && ! is_cmd && item.type === 'user' && this.get('ffz_partial_word').charAt(0) === '@') ? '@' : '') +
|
||||||
|
((item.command_content && is_cmd ?
|
||||||
item.command_content : item.content) || item.label),
|
item.command_content : item.content) || item.label),
|
||||||
|
|
||||||
trail = text.substr(ind + this.get('ffz_partial_word').length),
|
trail = text.substr(ind + this.get('ffz_partial_word').length),
|
||||||
|
@ -664,26 +696,50 @@ FFZ.prototype._modify_chat_input = function(component) {
|
||||||
|
|
||||||
|
|
||||||
// Always include Users
|
// Always include Users
|
||||||
var user_output = {};
|
var user_output = {},
|
||||||
|
alias_setting = f.settings.input_complete_aliases;
|
||||||
|
|
||||||
for(var i=0; i < suggestions.length; i++) {
|
for(var i=0; i < suggestions.length; i++) {
|
||||||
var suggestion = suggestions[i],
|
var suggestion = suggestions[i],
|
||||||
name = suggestion.id;
|
name = suggestion.id,
|
||||||
|
alias = f.aliases[name];
|
||||||
|
|
||||||
if ( user_output[name] ) {
|
if ( user_output[name] && ! user_output[name].is_alias ) {
|
||||||
var token = user_output[name];
|
var token = user_output[name];
|
||||||
token.whispered |= suggestion.whispered;
|
token.whispered |= suggestion.whispered;
|
||||||
if ( suggestion.timestamp > token.timestamp )
|
if ( suggestion.timestamp > token.timestamp )
|
||||||
token.timestamp = suggestion.timestamp;
|
token.timestamp = suggestion.timestamp;
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
output.push(user_output[name] = {
|
if ( alias_setting !== 2 )
|
||||||
type: "user",
|
output.push(user_output[name] = {
|
||||||
command_content: name,
|
type: "user",
|
||||||
label: FFZ.get_capitalization(name),
|
command_content: name,
|
||||||
whispered: suggestion.whispered,
|
label: FFZ.get_capitalization(name),
|
||||||
timestamp: suggestion.timestamp || new Date(0),
|
whispered: suggestion.whispered,
|
||||||
info: 'User'
|
timestamp: suggestion.timestamp || new Date(0),
|
||||||
});
|
info: 'User',
|
||||||
|
is_alias: false
|
||||||
|
});
|
||||||
|
|
||||||
|
if ( alias && alias_setting ) {
|
||||||
|
if ( user_output[alias] && user_output[alias].is_alias ) {
|
||||||
|
var token = user_output[name];
|
||||||
|
token.whispered |= suggestion.whispered;
|
||||||
|
token.timestamp = Math.max(token.timestamp, suggestion.timestamp);
|
||||||
|
|
||||||
|
} else if ( ! user_output[alias] )
|
||||||
|
output.push(user_output[alias] = {
|
||||||
|
type: "user",
|
||||||
|
command_content: name,
|
||||||
|
label: alias,
|
||||||
|
whispered: suggestion.whispered,
|
||||||
|
timestamp: suggestion.timestamp || new Date(0),
|
||||||
|
info: 'User Alias',
|
||||||
|
is_alias: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -974,12 +974,12 @@ FFZ.prototype._modify_cview = function(view) {
|
||||||
if ( current_channel ) {
|
if ( current_channel ) {
|
||||||
icon.innerHTML = constants.CAMERA;
|
icon.innerHTML = constants.CAMERA;
|
||||||
row.title = "Current Channel";
|
row.title = "Current Channel";
|
||||||
row.classList.add('tooltip');
|
row.classList.add('html-tooltip');
|
||||||
|
|
||||||
} else if ( host_channel ) {
|
} else if ( host_channel ) {
|
||||||
icon.innerHTML = constants.EYE;
|
icon.innerHTML = constants.EYE;
|
||||||
row.title = "Hosted Channel";
|
row.title = "Hosted Channel";
|
||||||
row.classList.add('tooltip');
|
row.classList.add('html-tooltip');
|
||||||
}
|
}
|
||||||
|
|
||||||
name_el.className = 'ffz-room';
|
name_el.className = 'ffz-room';
|
||||||
|
@ -1008,7 +1008,7 @@ FFZ.prototype._modify_cview = function(view) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
btn = document.createElement('a');
|
btn = document.createElement('a');
|
||||||
btn.className = 'leave-chat tooltip';
|
btn.className = 'leave-chat html-tooltip';
|
||||||
btn.innerHTML = constants.CLOSE;
|
btn.innerHTML = constants.CLOSE;
|
||||||
btn.title = 'Leave Group';
|
btn.title = 'Leave Group';
|
||||||
|
|
||||||
|
@ -1090,9 +1090,9 @@ FFZ.prototype._modify_cview = function(view) {
|
||||||
|
|
||||||
|
|
||||||
// Chat Room Management Button
|
// Chat Room Management Button
|
||||||
link.className = 'button glyph-only';
|
link.className = 'button button--icon-only';
|
||||||
link.title = "Chat Room Management";
|
link.title = "Chat Room Management";
|
||||||
link.innerHTML = constants.ROOMS + '<span class="notifications"></span>';
|
link.innerHTML = '<figure class="icon">' + constants.ROOMS + '</figure><span class="notifications"></span>';
|
||||||
|
|
||||||
jQuery(link).tipsy({gravity: "n", offset: 5});
|
jQuery(link).tipsy({gravity: "n", offset: 5});
|
||||||
|
|
||||||
|
@ -1106,9 +1106,9 @@ FFZ.prototype._modify_cview = function(view) {
|
||||||
|
|
||||||
// Invite Button
|
// Invite Button
|
||||||
link = document.createElement('a'),
|
link = document.createElement('a'),
|
||||||
link.className = 'button glyph-only tooltip invite';
|
link.className = 'button button--icon-only html-tooltip invite';
|
||||||
link.title = "Invite a User";
|
link.title = "Invite a User";
|
||||||
link.innerHTML = constants.INVITE;
|
link.innerHTML = '<figure class="icon">' + constants.INVITE + '</figure>';
|
||||||
|
|
||||||
link.addEventListener('click', function() {
|
link.addEventListener('click', function() {
|
||||||
var controller = view.get('controller');
|
var controller = view.get('controller');
|
||||||
|
@ -1170,7 +1170,7 @@ FFZ.prototype._modify_cview = function(view) {
|
||||||
|
|
||||||
tab.setAttribute('data-room', room_id);
|
tab.setAttribute('data-room', room_id);
|
||||||
|
|
||||||
tab.className = 'ffz-chat-tab tooltip';
|
tab.className = 'ffz-chat-tab html-tooltip';
|
||||||
tab.classList.toggle('current-channel', current_channel);
|
tab.classList.toggle('current-channel', current_channel);
|
||||||
tab.classList.toggle('host-channel', host_channel);
|
tab.classList.toggle('host-channel', host_channel);
|
||||||
tab.classList.toggle('group-chat', group);
|
tab.classList.toggle('group-chat', group);
|
||||||
|
|
|
@ -224,7 +224,7 @@ FFZ.prototype._modify_conversation_line = function(component) {
|
||||||
colored = style ? ' has-color' : '';
|
colored = style ? ' has-color' : '';
|
||||||
|
|
||||||
if ( alias )
|
if ( alias )
|
||||||
e.push('<span class="from ffz-alias tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias) + '</span>');
|
e.push('<span class="from ffz-alias html-tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias) + '</span>');
|
||||||
else
|
else
|
||||||
e.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name) + '</span>');
|
e.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name) + '</span>');
|
||||||
|
|
||||||
|
|
|
@ -189,13 +189,13 @@ FFZ.prototype.setup_profile_following = function() {
|
||||||
this._hook_followers(followers);
|
this._hook_followers(followers);
|
||||||
|
|
||||||
var counted = false;
|
var counted = false;
|
||||||
if ( following.get('isLoaded') || following.get('isLoading') ) {
|
if ( following && (following.get('isLoaded') || following.get('isLoading')) ) {
|
||||||
refresher(following);
|
refresher(following);
|
||||||
count++;
|
count++;
|
||||||
counted = true;
|
counted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( followers.get('isLoaded') || followers.get('isLoading') ) {
|
if ( followers && (followers.get('isLoaded') || followers.get('isLoading')) ) {
|
||||||
refresher(followers);
|
refresher(followers);
|
||||||
if ( ! counted )
|
if ( ! counted )
|
||||||
count++;
|
count++;
|
||||||
|
@ -285,8 +285,8 @@ FFZ.prototype._modify_display_followed_item = function(component) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actions = createElement('div', 'actions'),
|
var actions = createElement('div', 'actions'),
|
||||||
follow = createElement('button', 'button follow'),
|
follow = createElement('button', 'button ffz-no-bg follow'),
|
||||||
notif = createElement('button', 'button notifications'),
|
notif = createElement('button', 'button ffz-no-bg notifications'),
|
||||||
|
|
||||||
update_follow = function() {
|
update_follow = function() {
|
||||||
data = user_cache[user_id];
|
data = user_cache[user_id];
|
||||||
|
@ -358,7 +358,7 @@ FFZ.prototype._modify_display_followed_item = function(component) {
|
||||||
|
|
||||||
FFZ.prototype._hook_following = function(Following) {
|
FFZ.prototype._hook_following = function(Following) {
|
||||||
var f = this;
|
var f = this;
|
||||||
if ( Following.ffz_hooked )
|
if ( ! Following || Following.ffz_hooked )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Following.reopen({
|
Following.reopen({
|
||||||
|
@ -398,7 +398,7 @@ FFZ.prototype._hook_following = function(Following) {
|
||||||
|
|
||||||
FFZ.prototype._hook_followers = function(Followers) {
|
FFZ.prototype._hook_followers = function(Followers) {
|
||||||
var f = this;
|
var f = this;
|
||||||
if ( Followers.ffz_hooked )
|
if ( ! Followers || Followers.ffz_hooked )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Followers.reopen({
|
Followers.reopen({
|
||||||
|
|
|
@ -299,7 +299,7 @@ FFZ.settings_info.chat_rows = {
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
this.toggle_style('chat-background', !this.has_bttv && val);
|
this.toggle_style('chat-background', !this.has_bttv && val);
|
||||||
this.toggle_style('chat-setup', !this.has_bttv && (val || this.settings.chat_separators));
|
this.toggle_style('chat-setup', !this.has_bttv && (val || this.settings.chat_separators || this.settings.highlight_messages_with_mod_card));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ FFZ.settings_info.chat_separators = {
|
||||||
help: "Display thin lines between chat messages for further visual separation.",
|
help: "Display thin lines between chat messages for further visual separation.",
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
this.toggle_style('chat-setup', !this.has_bttv && (val || this.settings.chat_rows));
|
this.toggle_style('chat-setup', !this.has_bttv && (val || this.settings.chat_rows || this.settings.highlight_messages_with_mod_card));
|
||||||
|
|
||||||
this.toggle_style('chat-separator', !this.has_bttv && val);
|
this.toggle_style('chat-separator', !this.has_bttv && val);
|
||||||
this.toggle_style('chat-separator-3d', !this.has_bttv && val === 2);
|
this.toggle_style('chat-separator-3d', !this.has_bttv && val === 2);
|
||||||
|
@ -342,6 +342,18 @@ FFZ.settings_info.chat_separators = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.settings_info.old_sub_notices = {
|
||||||
|
type: "boolean",
|
||||||
|
value: false,
|
||||||
|
|
||||||
|
category: "Chat Appearance",
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
name: "Old-Style Subscriber Notices",
|
||||||
|
help: "Display the old style subscriber notices, with the message on a separate line."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.chat_padding = {
|
FFZ.settings_info.chat_padding = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
@ -577,7 +589,7 @@ FFZ.prototype.setup_line = function() {
|
||||||
// Chat Enhancements
|
// Chat Enhancements
|
||||||
document.body.classList.toggle('ffz-alias-italics', this.settings.alias_italics);
|
document.body.classList.toggle('ffz-alias-italics', this.settings.alias_italics);
|
||||||
|
|
||||||
this.toggle_style('chat-setup', !this.has_bttv && (this.settings.chat_rows || this.settings.chat_separators));
|
this.toggle_style('chat-setup', !this.has_bttv && (this.settings.chat_rows || this.settings.chat_separators || this.settings.highlight_messages_with_mod_card));
|
||||||
this.toggle_style('chat-padding', !this.has_bttv && this.settings.chat_padding);
|
this.toggle_style('chat-padding', !this.has_bttv && this.settings.chat_padding);
|
||||||
|
|
||||||
this.toggle_style('chat-background', !this.has_bttv && this.settings.chat_rows);
|
this.toggle_style('chat-background', !this.has_bttv && this.settings.chat_rows);
|
||||||
|
@ -708,22 +720,22 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
|
|
||||||
if ( btn === false ) {
|
if ( btn === false ) {
|
||||||
if ( deleted )
|
if ( deleted )
|
||||||
output += '<a class="mod-icon float-left tooltip unban" title="Unban User" href="#">Unban</a>';
|
output += '<a class="mod-icon float-left html-tooltip unban" title="Unban User" href="#">Unban</a>';
|
||||||
else
|
else
|
||||||
output += '<a class="mod-icon float-left tooltip ban" title="Ban User" href="#">Ban</a>';
|
output += '<a class="mod-icon float-left html-tooltip ban" title="Ban User" href="#">Ban</a>';
|
||||||
|
|
||||||
} else if ( btn === 600 )
|
} else if ( btn === 600 )
|
||||||
output += '<a class="mod-icon float-left tooltip timeout" title="Timeout User (10m)" href="#">Timeout</a>';
|
output += '<a class="mod-icon float-left html-tooltip timeout" title="Timeout User (10m)" href="#">Timeout</a>';
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if ( typeof btn === "string" ) {
|
if ( typeof btn === "string" ) {
|
||||||
cmd = btn.replace(/{user}/g, user).replace(/ *<LINE> */, "\n");
|
cmd = btn.replace(/{user}/g, user).replace(/ *<LINE> */, "\n");
|
||||||
tip = "Custom Command" + (cmd.indexOf("\n") !== -1 ? 's' : '') + '\n' + cmd;
|
tip = "Custom Command" + (cmd.indexOf("\n") !== -1 ? 's' : '') + '<br>' + utils.quote_san(cmd).replace('\n','<br>');
|
||||||
} else {
|
} else {
|
||||||
cmd = "/timeout " + user + " " + btn;
|
cmd = "/timeout " + user + " " + btn;
|
||||||
tip = "Timeout User (" + utils.duration_string(btn) + ")";
|
tip = "Timeout User (" + utils.duration_string(btn) + ")";
|
||||||
}
|
}
|
||||||
output += '<a class="mod-icon float-left tooltip' + (cmd.substr(0,9) === '/timeout' ? ' is-timeout' : '') + ' custom" data-cmd="' + utils.quote_attr(cmd) + '" title="' + utils.quote_attr(tip) + '" href="#">' + prefix + '</a>';
|
output += '<a class="mod-icon float-left html-tooltip' + (cmd.substr(0,9) === '/timeout' ? ' is-timeout' : '') + ' custom" data-cmd="' + utils.quote_attr(cmd) + '" title="' + tip + '" href="#">' + prefix + '</a>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,10 +762,20 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
|
|
||||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (is_replay ? f.settings.dark_twitch : (Settings && Settings.get('settings.darkMode'))),
|
is_dark = (Layout && Layout.get('isTheatreMode')) || (is_replay ? f.settings.dark_twitch : (Settings && Settings.get('settings.darkMode'))),
|
||||||
|
|
||||||
|
system_msg = this.get('systemMsg'),
|
||||||
output = '';
|
output = '';
|
||||||
|
|
||||||
|
output = '<div class="indicator"></div>';
|
||||||
|
|
||||||
output = '<div class="indicator"></div><span class="timestamp float-left">' + this.get('timestamp') + '</span> ';
|
// System Message
|
||||||
|
if ( system_msg ) {
|
||||||
|
output += '<div class="system-msg">' + utils.sanitize(system_msg) + '</div>';
|
||||||
|
if ( this.get('shouldRenderMessageBody') === false )
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timestamp
|
||||||
|
output += '<span class="timestamp float-left">' + this.get('timestamp') + '</span> ';
|
||||||
|
|
||||||
// Moderator Actions
|
// Moderator Actions
|
||||||
output += this.buildModIconsHTML();
|
output += this.buildModIconsHTML();
|
||||||
|
@ -767,10 +789,10 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]) || '',
|
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]) || '',
|
||||||
colored = style ? ' has-color' + (is_replay ? ' replay-color' : '') : '';
|
colored = style ? ' has-color' + (is_replay ? ' replay-color' : '') : '';
|
||||||
|
|
||||||
output += '<span class="from' + (alias ? ' ffz-alias tooltip' : '') + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '');
|
output += '<span class="from' + (alias ? ' ffz-alias html-tooltip' : '') + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '');
|
||||||
|
|
||||||
if ( alias )
|
if ( alias )
|
||||||
output += '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias);
|
output += '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias);
|
||||||
else
|
else
|
||||||
output += '">' + utils.sanitize(name);
|
output += '">' + utils.sanitize(name);
|
||||||
|
|
||||||
|
@ -787,10 +809,10 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
to_colored = to_style ? ' has-color' : '';
|
to_colored = to_style ? ' has-color' : '';
|
||||||
|
|
||||||
output += "</span><svg class='svg-whisper-arrow' height='10px' version='1.1' width='16px'><polyline points='6 2, 10 6, 6 10, 6 2' /></svg>";
|
output += "</span><svg class='svg-whisper-arrow' height='10px' version='1.1' width='16px'><polyline points='6 2, 10 6, 6 10, 6 2' /></svg>";
|
||||||
output += '<span class="to' + (to_alias ? ' ffz-alias tooltip' : '') + to_colored + '" style="' + to_style + (to_colors ? '" data=color="' + to_color : '');
|
output += '<span class="to' + (to_alias ? ' ffz-alias html-tooltip' : '') + to_colored + '" style="' + to_style + (to_colors ? '" data=color="' + to_color : '');
|
||||||
|
|
||||||
if ( to_alias )
|
if ( to_alias )
|
||||||
output += '" title="' + utils.sanitize(to_name) + '">' + utils.sanitize(to_alias);
|
output += '" title="' + utils.quote_san(to_name) + '">' + utils.sanitize(to_alias);
|
||||||
else
|
else
|
||||||
output += '">' + utils.sanitize(to_name);
|
output += '">' + utils.sanitize(to_name);
|
||||||
}
|
}
|
||||||
|
@ -833,10 +855,12 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
var el = this.get('element'),
|
var el = this.get('element'),
|
||||||
output = this.buildSenderHTML();
|
output = this.buildSenderHTML();
|
||||||
|
|
||||||
if ( this.get('msgObject.deleted') )
|
// If this is a whisper, or if we should render the message body, render it.
|
||||||
output += this.buildDeletedMessageHTML()
|
if ( this.get('shouldRenderMessageBody') !== false )
|
||||||
else
|
if ( this.get('msgObject.deleted') )
|
||||||
output += this.buildMessageHTML();
|
output += this.buildDeletedMessageHTML()
|
||||||
|
else
|
||||||
|
output += this.buildMessageHTML();
|
||||||
|
|
||||||
el.innerHTML = output;
|
el.innerHTML = output;
|
||||||
},
|
},
|
||||||
|
@ -932,10 +956,18 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
else if ( e.target.classList.contains('from') ) {
|
else if ( e.target.classList.contains('from') ) {
|
||||||
var n = this.$();
|
var n = this.get('element'),
|
||||||
|
bounds = n && n.getBoundingClientRect() || document.body.getBoundingClientRect(),
|
||||||
|
x = 0, right;
|
||||||
|
|
||||||
|
if ( bounds.left > 400 )
|
||||||
|
right = bounds.left - 40;
|
||||||
|
|
||||||
this.sendAction("showModOverlay", {
|
this.sendAction("showModOverlay", {
|
||||||
left: n.offset().left,
|
left: bounds.left,
|
||||||
top: n.offset().top + n.height(),
|
right: right,
|
||||||
|
top: bounds.top + bounds.height,
|
||||||
|
real_top: bounds.top,
|
||||||
sender: from
|
sender: from
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -995,7 +1027,7 @@ FFZ.prototype._modify_vod_line = function(component) {
|
||||||
return '<span class="mod-icons float-left">' +
|
return '<span class="mod-icons float-left">' +
|
||||||
(this.get('msgObject.deleted') ?
|
(this.get('msgObject.deleted') ?
|
||||||
'<em class="mod-icon float-left unban"></em>' :
|
'<em class="mod-icon float-left unban"></em>' :
|
||||||
'<a class="mod-icon float-left tooltip delete" title="Delete Message" href="#">Delete</a>') + '</span>';
|
'<a class="mod-icon float-left html-tooltip delete" title="Delete Message" href="#">Delete</a>') + '</span>';
|
||||||
},
|
},
|
||||||
|
|
||||||
buildDeletedMesageHTML: function() {
|
buildDeletedMesageHTML: function() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
var FFZ = window.FrankerFaceZ,
|
var FFZ = window.FrankerFaceZ,
|
||||||
utils = require("../utils"),
|
utils = require("../utils"),
|
||||||
constants = require("../constants"),
|
constants = require("../constants"),
|
||||||
|
styles = require("../compiled_styles"),
|
||||||
helpers,
|
helpers,
|
||||||
|
|
||||||
TO_REG = /^\/t(?:imeout)? +([^ ]+)(?: +(\d+)(?: +(.+))?)?$/,
|
TO_REG = /^\/t(?:imeout)? +([^ ]+)(?: +(\d+)(?: +(.+))?)?$/,
|
||||||
|
@ -66,24 +67,112 @@ FFZ.basic_settings.chat_hover_pause = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.chat_hover_pause = {
|
FFZ.settings_info.highlight_messages_with_mod_card = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
|
||||||
|
no_bttv: true,
|
||||||
|
category: "Chat Moderation",
|
||||||
|
name: "Highlight Messages with Mod Card Open",
|
||||||
|
help: "Highlight a user's messages in chat when their moderation card is open.",
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
this.toggle_style('chat-setup', !this.has_bttv && (this.settings.chat_rows || this.settings.chat_separators || val));
|
||||||
|
|
||||||
|
if ( ! this._mod_card )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( val )
|
||||||
|
utils.update_css(this._chat_style, 'mod-card-highlight', styles['chat-user-bg'].replace(/{user_id}/g, this._mod_card.get('cardInfo.user.id')));
|
||||||
|
else
|
||||||
|
utils.update_css(this._chat_style, 'mod-card-highlight');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.settings_info.chat_mod_icon_visibility = {
|
||||||
|
type: "select",
|
||||||
|
options: {
|
||||||
|
0: "Disabled",
|
||||||
|
1: "Enabled",
|
||||||
|
2: "When Ctrl is Held",
|
||||||
|
3: "When " + constants.META_NAME + " is Held",
|
||||||
|
4: "When Alt is Held",
|
||||||
|
5: "When Shift is Held"
|
||||||
|
},
|
||||||
|
|
||||||
|
value: function() {
|
||||||
|
var settings = utils.ember_lookup('controller:settings');
|
||||||
|
return (settings && settings.get('settings.showModIcons')) ? 1 : 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
process_value: function(val) {
|
||||||
|
if ( typeof val === "string" )
|
||||||
|
return parseInt(val) || 0;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
no_bttv: true,
|
no_bttv: true,
|
||||||
|
|
||||||
category: "Chat Moderation",
|
category: "Chat Moderation",
|
||||||
name: "Pause Chat Scrolling on Mouse Hover",
|
name: "Display In-Line Mod Icons",
|
||||||
help: "Automatically prevent the chat from scrolling when moving the mouse over it to prevent moderation mistakes and link misclicks.",
|
help: "Choose when you should see in-line moderation icons in chat.",
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
var settings = utils.ember_lookup('controller:settings');
|
||||||
|
if ( settings )
|
||||||
|
settings.set('settings.showModIcons', val === 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.settings_info.chat_hover_pause = {
|
||||||
|
type: "select",
|
||||||
|
options: {
|
||||||
|
0: "Disabled",
|
||||||
|
1: "On Hover",
|
||||||
|
2: "When Ctrl is Held",
|
||||||
|
3: "When " + constants.META_NAME + " is Held",
|
||||||
|
4: "When Alt is Held",
|
||||||
|
5: "When Shift is Held",
|
||||||
|
|
||||||
|
6: "Ctrl or Hover",
|
||||||
|
7: constants.META_NAME + " or Hover",
|
||||||
|
8: "Alt or Hover",
|
||||||
|
9: "Shift or Hover"
|
||||||
|
},
|
||||||
|
value: 0,
|
||||||
|
|
||||||
|
process_value: function(val) {
|
||||||
|
if ( val === true )
|
||||||
|
return 1;
|
||||||
|
else if ( val === false )
|
||||||
|
return 0;
|
||||||
|
else if ( typeof val === "string" )
|
||||||
|
return parseInt(val) || 0;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
category: "Chat Moderation",
|
||||||
|
name: "Pause Chat Scrolling",
|
||||||
|
help: "Automatically prevent the chat from scrolling when moving the mouse over it or holding Ctrl to prevent moderation mistakes and link misclicks.",
|
||||||
|
|
||||||
on_update: function(val) {
|
on_update: function(val) {
|
||||||
if ( ! this._roomv )
|
if ( ! this._roomv )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this._roomv.ffzDisableFreeze();
|
||||||
|
|
||||||
|
// Remove the old warning to make sure the label updates.
|
||||||
|
var el = this._roomv.get('element'),
|
||||||
|
warning = el && el.querySelector('.chat-interface .more-messages-indicator.ffz-freeze-indicator');
|
||||||
|
if ( warning )
|
||||||
|
warning.parentElement.removeChild(warning);
|
||||||
|
|
||||||
if ( val )
|
if ( val )
|
||||||
this._roomv.ffzEnableFreeze();
|
this._roomv.ffzEnableFreeze();
|
||||||
else
|
|
||||||
this._roomv.ffzDisableFreeze();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -495,6 +584,17 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
} catch(err) { }
|
} catch(err) { }
|
||||||
|
|
||||||
|
|
||||||
|
this.log("Listening to the Settings controller to catch mod icon state changes.");
|
||||||
|
var f = this,
|
||||||
|
Settings = utils.ember_lookup('controller:settings');
|
||||||
|
|
||||||
|
if ( Settings )
|
||||||
|
Settings.addObserver('settings.showModIcons', function() {
|
||||||
|
if ( Settings.get('settings.showModIcons') )
|
||||||
|
f.settings.set('chat_mod_icon_visibility', 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
this.log("Modifying Mousetrap stopCallback so we can catch ESC.");
|
this.log("Modifying Mousetrap stopCallback so we can catch ESC.");
|
||||||
var orig_stop = Mousetrap.stopCallback;
|
var orig_stop = Mousetrap.stopCallback;
|
||||||
Mousetrap.stopCallback = function(e, element, combo) {
|
Mousetrap.stopCallback = function(e, element, combo) {
|
||||||
|
@ -511,8 +611,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
|
|
||||||
this.log("Hooking the Ember Moderation Card view.");
|
this.log("Hooking the Ember Moderation Card view.");
|
||||||
var Card = utils.ember_resolve('component:chat/moderation-card'),
|
var Card = utils.ember_resolve('component:chat/moderation-card');
|
||||||
f = this;
|
|
||||||
|
|
||||||
Card.reopen({
|
Card.reopen({
|
||||||
ffzForceRedraw: function() {
|
ffzForceRedraw: function() {
|
||||||
|
@ -520,6 +619,10 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
if ( f.settings.mod_card_history )
|
if ( f.settings.mod_card_history )
|
||||||
this.ffzRenderHistory();
|
this.ffzRenderHistory();
|
||||||
|
|
||||||
|
// Highlight this user's chat messages.
|
||||||
|
if ( f.settings.highlight_messages_with_mod_card )
|
||||||
|
utils.update_css(f._chat_style, 'mod-card-highlight', styles['chat-user-bg'].replace(/{user_id}/g, this.get('cardInfo.user.id')));
|
||||||
|
|
||||||
}.observes("cardInfo.isModeratorOrHigher", "cardInfo.user.id"),
|
}.observes("cardInfo.isModeratorOrHigher", "cardInfo.user.id"),
|
||||||
|
|
||||||
ffzRebuildInfo: function() {
|
ffzRebuildInfo: function() {
|
||||||
|
@ -528,12 +631,12 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
if ( ! info )
|
if ( ! info )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var out = '<span class="stat tooltip" title="Total Views">' + constants.EYE + ' ' + utils.number_commas(this.get('cardInfo.user.views') || 0) + '</span>',
|
var out = '<span class="stat html-tooltip" title="Total Views">' + constants.EYE + ' ' + utils.number_commas(this.get('cardInfo.user.views') || 0) + '</span>',
|
||||||
since = utils.parse_date(this.get('cardInfo.user.created_at') || ''),
|
since = utils.parse_date(this.get('cardInfo.user.created_at') || ''),
|
||||||
followers = this.get('cardInfo.user.ffz_followers');
|
followers = this.get('cardInfo.user.ffz_followers');
|
||||||
|
|
||||||
if ( typeof followers === "number" ) {
|
if ( typeof followers === "number" ) {
|
||||||
out += '<span class="stat tooltip" title="Followers">' + constants.HEART + ' ' + utils.number_commas(followers || 0) + '</span>';
|
out += '<span class="stat html-tooltip" title="Followers">' + constants.HEART + ' ' + utils.number_commas(followers || 0) + '</span>';
|
||||||
|
|
||||||
} else if ( followers === undefined ) {
|
} else if ( followers === undefined ) {
|
||||||
var t = this;
|
var t = this;
|
||||||
|
@ -550,7 +653,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
var now = Date.now() - (f._ws_server_offset || 0),
|
var now = Date.now() - (f._ws_server_offset || 0),
|
||||||
age = Math.floor((now - since.getTime()) / 1000);
|
age = Math.floor((now - since.getTime()) / 1000);
|
||||||
if ( age > 0 ) {
|
if ( age > 0 ) {
|
||||||
out += '<span class="stat tooltip" title="Member Since: ' + (age > 86400 ? since.toLocaleDateString() : since.toLocaleString()) + '">' + constants.CLOCK + ' ' + utils.human_time(age, 10) + '</span>';
|
out += '<span class="stat html-tooltip" title="Member Since: ' + utils.quote_san(age > 86400 ? since.toLocaleDateString() : since.toLocaleString()) + '">' + constants.CLOCK + ' ' + utils.human_time(age, 10) + '</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,6 +670,9 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
willDestroy: function() {
|
willDestroy: function() {
|
||||||
if ( f._mod_card === this )
|
if ( f._mod_card === this )
|
||||||
f._mod_card = undefined;
|
f._mod_card = undefined;
|
||||||
|
|
||||||
|
utils.update_css(f._chat_style, 'mod-card-highlight');
|
||||||
|
|
||||||
this._super();
|
this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -594,6 +700,8 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
user_id = controller.get('cardInfo.user.id'),
|
user_id = controller.get('cardInfo.user.id'),
|
||||||
alias = f.aliases[user_id],
|
alias = f.aliases[user_id],
|
||||||
|
|
||||||
|
handle_key,
|
||||||
|
|
||||||
ban_reason = function() {
|
ban_reason = function() {
|
||||||
return ban_reasons && ban_reasons.value ? ' ' + ban_reasons.value : "";
|
return ban_reasons && ban_reasons.value ? ' ' + ban_reasons.value : "";
|
||||||
};
|
};
|
||||||
|
@ -601,6 +709,9 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
this.ffz_room_id = room_id;
|
this.ffz_room_id = room_id;
|
||||||
|
|
||||||
|
// Highlight this user's chat messages.
|
||||||
|
if ( f.settings.highlight_messages_with_mod_card )
|
||||||
|
utils.update_css(f._chat_style, 'mod-card-highlight', styles['chat-user-bg'].replace(/{user_id}/g, user_id));
|
||||||
|
|
||||||
// Action Override
|
// Action Override
|
||||||
this.set('banAction', function(e) {
|
this.set('banAction', function(e) {
|
||||||
|
@ -677,7 +788,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
},
|
},
|
||||||
|
|
||||||
add_btn_make = function(cmd) {
|
add_btn_make = function(cmd) {
|
||||||
var btn = document.createElement('button'),
|
var btn = utils.createElement('button', 'button ffz-no-bg'),
|
||||||
segment = cmd.split(' ', 1)[0],
|
segment = cmd.split(' ', 1)[0],
|
||||||
title = cmds[segment] > 1 ? cmd.split(' ', cmds[segment]) : [segment];
|
title = cmds[segment] > 1 ? cmd.split(' ', cmds[segment]) : [segment];
|
||||||
|
|
||||||
|
@ -686,7 +797,6 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
title = _.map(title, function(s){ return s.capitalize() }).join(' ');
|
title = _.map(title, function(s){ return s.capitalize() }).join(' ');
|
||||||
|
|
||||||
btn.className = 'button';
|
|
||||||
btn.innerHTML = utils.sanitize(title);
|
btn.innerHTML = utils.sanitize(title);
|
||||||
btn.title = utils.sanitize(cmd.replace(/{user}/g, controller.get('cardInfo.user.id') || '{user}'));
|
btn.title = utils.sanitize(cmd.replace(/{user}/g, controller.get('cardInfo.user.id') || '{user}'));
|
||||||
|
|
||||||
|
@ -718,7 +828,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
if ( f.settings.mod_card_hotkeys ) {
|
if ( f.settings.mod_card_hotkeys ) {
|
||||||
el.classList.add('no-mousetrap');
|
el.classList.add('no-mousetrap');
|
||||||
|
|
||||||
el.addEventListener('keyup', function(e) {
|
handle_key = function(e) {
|
||||||
var key = e.keyCode || e.which,
|
var key = e.keyCode || e.which,
|
||||||
user_id = controller.get('cardInfo.user.id'),
|
user_id = controller.get('cardInfo.user.id'),
|
||||||
is_mod = controller.get('cardInfo.isModeratorOrHigher'),
|
is_mod = controller.get('cardInfo.isModeratorOrHigher'),
|
||||||
|
@ -753,7 +863,9 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
t.get('closeAction')();
|
t.get('closeAction')();
|
||||||
});
|
};
|
||||||
|
|
||||||
|
el.addEventListener('keyup', handle_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -773,13 +885,13 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
btn_make = function(timeout) {
|
btn_make = function(timeout) {
|
||||||
var btn = document.createElement('button')
|
var btn = document.createElement('button')
|
||||||
btn.className = 'button';
|
btn.className = 'button ffz-no-bg';
|
||||||
btn.innerHTML = utils.duration_string(timeout);
|
btn.innerHTML = utils.duration_string(timeout);
|
||||||
btn.title = "Timeout User for " + utils.number_commas(timeout) + " Second" + (timeout != 1 ? "s" : "");
|
btn.title = "Timeout User for " + utils.number_commas(timeout) + " Second" + (timeout != 1 ? "s" : "");
|
||||||
|
|
||||||
if ( f.settings.mod_card_hotkeys && timeout === 600 )
|
if ( f.settings.mod_card_hotkeys && timeout === 600 )
|
||||||
btn.title = "(T)" + btn.title.substr(1);
|
btn.title = "(T)" + btn.title.substr(1);
|
||||||
else if ( f.settings.mod_card_hotkeys && timeout === 1 )
|
else if ( f.settings.mod_card_hotkeys && timeout === 1 )
|
||||||
btn.title = "(P)urge - " + btn.title;
|
btn.title = "(P)urge - " + btn.title;
|
||||||
|
|
||||||
jQuery(btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
jQuery(btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
||||||
|
@ -812,7 +924,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
if ( f.settings.mod_card_reasons && f.settings.mod_card_reasons.length ) {
|
if ( f.settings.mod_card_reasons && f.settings.mod_card_reasons.length ) {
|
||||||
// Moderation Reasons
|
// Moderation Reasons
|
||||||
line = utils.createElement('div', 'extra-interface interface clearfix');
|
line = utils.createElement('div', 'extra-interface interface clearfix');
|
||||||
ban_reasons = utils.createElement('select', 'ffz-ban-reasons', '<option value="">Select a Ban (R)eason</option>');
|
ban_reasons = utils.createElement('select', 'ffz-ban-reasons', '<option value="">Select a Ban ' + (f.settings.mod_card_hotkeys ? '(R)' : 'R') + 'eason</option>');
|
||||||
line.appendChild(ban_reasons);
|
line.appendChild(ban_reasons);
|
||||||
|
|
||||||
for(var i=0; i < f.settings.mod_card_reasons.length; i++) {
|
for(var i=0; i < f.settings.mod_card_reasons.length; i++) {
|
||||||
|
@ -832,8 +944,8 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
// Unban Button
|
// Unban Button
|
||||||
var unban_btn = document.createElement('button');
|
var unban_btn = document.createElement('button');
|
||||||
unban_btn.className = 'unban button glyph-only light';
|
unban_btn.className = 'unban button button--icon-only light';
|
||||||
unban_btn.innerHTML = CHECK;
|
unban_btn.innerHTML = '<figure class="icon">' + CHECK + '</figure>';
|
||||||
unban_btn.title = (f.settings.mod_card_hotkeys ? "(U)" : "U") + "nban User";
|
unban_btn.title = (f.settings.mod_card_hotkeys ? "(U)" : "U") + "nban User";
|
||||||
|
|
||||||
jQuery(unban_btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
jQuery(unban_btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
||||||
|
@ -843,6 +955,10 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tooltips for ban and ignore.
|
||||||
|
jQuery("button.ignore, button.ban").tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
||||||
|
|
||||||
|
|
||||||
// More Fixing Other Buttons
|
// More Fixing Other Buttons
|
||||||
var op_btn = el.querySelector('button.mod');
|
var op_btn = el.querySelector('button.mod');
|
||||||
if ( op_btn ) {
|
if ( op_btn ) {
|
||||||
|
@ -863,7 +979,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
var msg_btn = el.querySelector(".interface > button.message-button");
|
var msg_btn = el.querySelector(".interface > button.message-button");
|
||||||
if ( msg_btn ) {
|
if ( msg_btn ) {
|
||||||
msg_btn.innerHTML = 'W';
|
msg_btn.innerHTML = 'W';
|
||||||
msg_btn.classList.add('glyph-only');
|
msg_btn.classList.add('button--icon-only');
|
||||||
msg_btn.classList.add('message');
|
msg_btn.classList.add('message');
|
||||||
|
|
||||||
msg_btn.title = "Whisper User";
|
msg_btn.title = "Whisper User";
|
||||||
|
@ -871,8 +987,8 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
|
|
||||||
var real_msg = document.createElement('button');
|
var real_msg = document.createElement('button');
|
||||||
real_msg.className = 'message-button button glyph-only message tooltip';
|
real_msg.className = 'message-button button button--icon-only message html-tooltip';
|
||||||
real_msg.innerHTML = MESSAGE;
|
real_msg.innerHTML = '<figure class="icon">' + MESSAGE + '</figure>';
|
||||||
real_msg.title = "Message User";
|
real_msg.title = "Message User";
|
||||||
|
|
||||||
real_msg.addEventListener('click', function() {
|
real_msg.addEventListener('click', function() {
|
||||||
|
@ -885,8 +1001,8 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
|
|
||||||
// Alias Button
|
// Alias Button
|
||||||
var alias_btn = document.createElement('button');
|
var alias_btn = document.createElement('button');
|
||||||
alias_btn.className = 'alias button glyph-only tooltip';
|
alias_btn.className = 'alias button button--icon-only html-tooltip';
|
||||||
alias_btn.innerHTML = constants.EDIT;
|
alias_btn.innerHTML = '<figure class="icon">' + constants.EDIT + '</figure>';
|
||||||
alias_btn.title = "Set Alias";
|
alias_btn.title = "Set Alias";
|
||||||
|
|
||||||
alias_btn.addEventListener('click', function() {
|
alias_btn.addEventListener('click', function() {
|
||||||
|
@ -932,26 +1048,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
this.ffzRenderHistory();
|
this.ffzRenderHistory();
|
||||||
|
|
||||||
// Reposition the menu if it's off-screen.
|
// Reposition the menu if it's off-screen.
|
||||||
var el_bound = el.getBoundingClientRect(),
|
this.ffzReposition();
|
||||||
body_bound = document.body.getBoundingClientRect(),
|
|
||||||
|
|
||||||
renderBottom = this.get('cardInfo.renderBottom'),
|
|
||||||
renderRight = this.get('cardInfo.renderRight');
|
|
||||||
|
|
||||||
if ( renderRight ) {
|
|
||||||
var offset = (el_bound.left + el_bound.width) - renderRight;
|
|
||||||
el.style.left = (el_bound.left - offset) + "px";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( renderBottom ) {
|
|
||||||
var offset = el_bound.bottom - renderBottom;
|
|
||||||
el.style.top = (el_bound.top - offset) + "px";
|
|
||||||
|
|
||||||
} else if ( el_bound.bottom > body_bound.bottom ) {
|
|
||||||
var offset = el_bound.bottom - body_bound.bottom;
|
|
||||||
if ( el_bound.top - offset > body_bound.top )
|
|
||||||
el.style.top = (el_bound.top - offset) + "px";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Focus the Element
|
// Focus the Element
|
||||||
this.$().draggable({
|
this.$().draggable({
|
||||||
|
@ -968,6 +1065,30 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ffzReposition: function() {
|
||||||
|
var el = this.get('element'),
|
||||||
|
el_bound = el.getBoundingClientRect(),
|
||||||
|
body_bound = document.body.getBoundingClientRect(),
|
||||||
|
|
||||||
|
renderBottom = this.get('cardInfo.renderBottom'),
|
||||||
|
renderRight = this.get('cardInfo.renderRight');
|
||||||
|
|
||||||
|
if ( renderRight ) {
|
||||||
|
var offset = (el_bound.left + el_bound.width) - renderRight;
|
||||||
|
el.style.left = (el_bound.left - offset) + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( renderBottom ) {
|
||||||
|
var offset = el_bound.bottom - renderBottom;
|
||||||
|
el.style.top = (el_bound.top - offset) + "px";
|
||||||
|
|
||||||
|
} else if ( el_bound.bottom > body_bound.bottom ) {
|
||||||
|
var offset = el_bound.bottom - body_bound.bottom;
|
||||||
|
if ( el_bound.top - offset > body_bound.top )
|
||||||
|
el.style.top = (el_bound.top - offset) + "px";
|
||||||
|
}
|
||||||
|
}.observes('cardInfo.renderTop', 'cardInfo.renderLeft', 'cardInfo.renderRight', 'cardInfo.renderBottom'),
|
||||||
|
|
||||||
ffzRenderHistory: function() {
|
ffzRenderHistory: function() {
|
||||||
var t = this,
|
var t = this,
|
||||||
Chat = utils.ember_lookup('controller:chat'),
|
Chat = utils.ember_lookup('controller:chat'),
|
||||||
|
@ -1093,7 +1214,7 @@ FFZ.prototype.setup_mod_card = function() {
|
||||||
logs = document.createElement('ul');
|
logs = document.createElement('ul');
|
||||||
back = document.createElement('button');
|
back = document.createElement('button');
|
||||||
|
|
||||||
back.className = 'button back-button';
|
back.className = 'button ffz-no-bg back-button';
|
||||||
back.innerHTML = '« Back';
|
back.innerHTML = '« Back';
|
||||||
|
|
||||||
back.addEventListener('click', function() {
|
back.addEventListener('click', function() {
|
||||||
|
@ -1184,7 +1305,7 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
||||||
|
|
||||||
|
|
||||||
if ( alias )
|
if ( alias )
|
||||||
out.push('<span class="from ffz-alias tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias) + '</span>');
|
out.push('<span class="from ffz-alias html-tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias) + '</span>');
|
||||||
else
|
else
|
||||||
out.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name ) + '</span>');
|
out.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name ) + '</span>');
|
||||||
|
|
||||||
|
@ -1287,6 +1408,11 @@ FFZ.prototype._update_alias = function(user) {
|
||||||
el_from.title = alias ? cap_name : '';
|
el_from.title = alias ? cap_name : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update tab completion.
|
||||||
|
if ( this._inputv )
|
||||||
|
Ember.propertyDidChange(this._inputv, 'ffz_name_suggestions');
|
||||||
|
|
||||||
// TODO: Update conversations~
|
// TODO: Update conversations~
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,10 +77,10 @@ FFZ.prototype.setup_room = function() {
|
||||||
this.set("showModerationCard", true);
|
this.set("showModerationCard", true);
|
||||||
|
|
||||||
// We pass in renderBottom and renderRight, which we use to reposition the window
|
// We pass in renderBottom and renderRight, which we use to reposition the window
|
||||||
// after we know how big it actually is.
|
// after we know how big it actually is. This doesn't work a lot of the time.
|
||||||
this.set("moderationCardInfo", {
|
this.set("moderationCardInfo", {
|
||||||
user: chan,
|
user: chan,
|
||||||
renderTop: e.top,
|
renderTop: e.real_top || e.top,
|
||||||
renderLeft: e.left,
|
renderLeft: e.left,
|
||||||
renderBottom: e.bottom,
|
renderBottom: e.bottom,
|
||||||
renderRight: e.right,
|
renderRight: e.right,
|
||||||
|
@ -171,6 +171,12 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
f._roomv = this;
|
f._roomv = this;
|
||||||
|
|
||||||
this.ffz_frozen = false;
|
this.ffz_frozen = false;
|
||||||
|
this.ffz_ctrl = false;
|
||||||
|
|
||||||
|
// Monitor the Ctrl key.
|
||||||
|
this._ffz_keyw = this.ffzOnKey.bind(this);
|
||||||
|
document.body.addEventListener('keydown', this._ffz_keyw);
|
||||||
|
document.body.addEventListener('keyup', this._ffz_keyw);
|
||||||
|
|
||||||
// Fix scrolling.
|
// Fix scrolling.
|
||||||
this._ffz_mouse_down = this.ffzMouseDown.bind(this);
|
this._ffz_mouse_down = this.ffzMouseDown.bind(this);
|
||||||
|
@ -215,9 +221,43 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
if ( this._ffz_chat_display )
|
if ( this._ffz_chat_display )
|
||||||
this._ffz_chat_display = undefined;
|
this._ffz_chat_display = undefined;
|
||||||
|
|
||||||
|
if ( this._ffz_keyw ) {
|
||||||
|
document.body.removeEventListener('keydown', this._ffz_keyw);
|
||||||
|
document.body.removeEventListener('keyup', this._ffz_keyw);
|
||||||
|
this._ffz_keyw = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
this.ffzDisableFreeze();
|
this.ffzDisableFreeze();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ffzOnKey: function(event) {
|
||||||
|
this.ffz_ctrl = event.ctrlKey;
|
||||||
|
this.ffz_alt = event.altKey;
|
||||||
|
this.ffz_shift = event.shiftKey;
|
||||||
|
this.ffz_meta = event.metaKey;
|
||||||
|
|
||||||
|
var cmi = f.settings.chat_mod_icon_visibility;
|
||||||
|
if ( ! this._ffz_outside && cmi > 1 )
|
||||||
|
this.get('element').classList.toggle('show-mod-icons',
|
||||||
|
cmi === 2 ? this.ffz_ctrl :
|
||||||
|
cmi === 3 ? this.ffz_meta :
|
||||||
|
cmi === 4 ? this.ffz_alt :
|
||||||
|
this.ffz_shift);
|
||||||
|
|
||||||
|
if ( this._ffz_outside || f.settings.chat_hover_pause < 2 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Okay, so at this point we should change the state of the freeze?
|
||||||
|
var should_freeze = this.ffzShouldBeFrozen(),
|
||||||
|
freeze_change = this.ffz_frozen !== should_freeze;
|
||||||
|
|
||||||
|
if ( freeze_change )
|
||||||
|
if ( should_freeze )
|
||||||
|
this.ffzFreeze();
|
||||||
|
else
|
||||||
|
this.ffzUnfreeze();
|
||||||
|
},
|
||||||
|
|
||||||
ffzUpdateStatus: function() {
|
ffzUpdateStatus: function() {
|
||||||
var room = this.get('controller.model'),
|
var room = this.get('controller.model'),
|
||||||
el = this.get('element'),
|
el = this.get('element'),
|
||||||
|
@ -273,8 +313,8 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
if ( ! messages )
|
if ( ! messages )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
|
|
||||||
this._ffz_messages = messages;
|
this._ffz_messages = messages;
|
||||||
|
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
|
||||||
|
|
||||||
this._ffz_mouse_move = this.ffzMouseMove.bind(this);
|
this._ffz_mouse_move = this.ffzMouseMove.bind(this);
|
||||||
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
|
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
|
||||||
|
@ -311,11 +351,8 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzPulse: function() {
|
ffzPulse: function() {
|
||||||
if ( this.ffz_frozen ) {
|
if ( this.ffz_frozen && ! this.ffzShouldBeFrozen() )
|
||||||
var elapsed = Date.now() - this._ffz_last_move;
|
this.ffzUnfreeze();
|
||||||
if ( elapsed > 750 )
|
|
||||||
this.ffzUnfreeze();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzUnfreeze: function(from_stuck) {
|
ffzUnfreeze: function(from_stuck) {
|
||||||
|
@ -327,11 +364,17 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
this._scrollToBottom();
|
this._scrollToBottom();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ffzFreeze: function() {
|
||||||
|
this.ffz_frozen = true;
|
||||||
|
if ( this.get('stuckToBottom') ) {
|
||||||
|
this.set('controller.model.messageBufferSize', f.settings.scrollback_length + 150);
|
||||||
|
this.ffzWarnPaused();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
ffzMouseDown: function(event) {
|
ffzMouseDown: function(event) {
|
||||||
var t = this._$chatMessagesScroller;
|
var t = this._$chatMessagesScroller;
|
||||||
if ( t && t[0] && ((!this.ffz_frozen && "mousedown" === event.type) || "mousewheel" === event.type || (is_android && "scroll" === event.type) ) ) {
|
if ( t && t[0] && ((!this.ffz_frozen && "mousedown" === event.type) || "mousewheel" === event.type || (is_android && "scroll" === event.type) ) ) {
|
||||||
if ( event.type === "mousedown" )
|
|
||||||
f.log("Freezing from mouse down!", event);
|
|
||||||
var r = t[0].scrollHeight - t[0].scrollTop - t[0].offsetHeight;
|
var r = t[0].scrollHeight - t[0].scrollTop - t[0].offsetHeight;
|
||||||
this._setStuckToBottom(10 >= r);
|
this._setStuckToBottom(10 >= r);
|
||||||
}
|
}
|
||||||
|
@ -341,29 +384,57 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
this._ffz_outside = true;
|
this._ffz_outside = true;
|
||||||
var e = this;
|
var e = this;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if ( e._ffz_outside )
|
if ( e._ffz_outside ) {
|
||||||
|
if ( f.settings.chat_mod_icon_visibility > 1 )
|
||||||
|
e.get('element').classList.toggle('show-mod-icons', false);
|
||||||
e.ffzUnfreeze();
|
e.ffzUnfreeze();
|
||||||
|
}
|
||||||
}, 25);
|
}, 25);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ffzShouldBeFrozen: function(since) {
|
||||||
|
if ( since === undefined )
|
||||||
|
since = Date.now() - this._ffz_last_move;
|
||||||
|
|
||||||
|
var hp = f.settings.chat_hover_pause;
|
||||||
|
return (this.ffz_ctrl && (hp === 2 || hp === 6)) || (this.ffz_meta && (hp === 3 || hp === 7)) || (this.ffz_alt && (hp === 4 || hp === 8)) || (this.ffz_shift && (hp === 5 || hp === 9)) || (since < 750 && (hp === 1 || hp > 5));
|
||||||
|
},
|
||||||
|
|
||||||
ffzMouseMove: function(event) {
|
ffzMouseMove: function(event) {
|
||||||
|
// Store the last move time.
|
||||||
this._ffz_last_move = Date.now();
|
this._ffz_last_move = Date.now();
|
||||||
this._ffz_outside = false;
|
this._ffz_outside = false;
|
||||||
|
|
||||||
if ( event.screenX === this._ffz_last_screenx && event.screenY === this._ffz_last_screeny )
|
// If nothing of interest has happened, stop.
|
||||||
|
if ( event.altKey === this.ffz_alt && event.shiftKey === this.ffz_shift && event.ctrlKey === this.ffz_ctrl && event.metaKey === this.ffz_meta && event.screenX === this._ffz_last_screenx && event.screenY === this._ffz_last_screeny )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Grab a bit of state.
|
||||||
|
this.ffz_ctrl = event.ctrlKey;
|
||||||
|
this.ffz_alt = event.altKey;
|
||||||
|
this.ffz_shift = event.shiftKey;
|
||||||
|
this.ffz_meta = event.metaKey;
|
||||||
|
|
||||||
this._ffz_last_screenx = event.screenX;
|
this._ffz_last_screenx = event.screenX;
|
||||||
this._ffz_last_screeny = event.screenY;
|
this._ffz_last_screeny = event.screenY;
|
||||||
|
|
||||||
if ( this.ffz_frozen )
|
var cmi = f.settings.chat_mod_icon_visibility;
|
||||||
return;
|
if ( ! this._ffz_outside && cmi > 1 )
|
||||||
|
this.get('element').classList.toggle('show-mod-icons',
|
||||||
|
cmi === 2 ? this.ffz_ctrl :
|
||||||
|
cmi === 3 ? this.ffz_meta :
|
||||||
|
cmi === 4 ? this.ffz_alt :
|
||||||
|
this.ffz_shift);
|
||||||
|
|
||||||
this.ffz_frozen = true;
|
// Should the state have changed?
|
||||||
if ( this.get('stuckToBottom') ) {
|
var should_freeze = this.ffzShouldBeFrozen(),
|
||||||
this.set('controller.model.messageBufferSize', f.settings.scrollback_length + 150);
|
freeze_change = this.ffz_frozen !== should_freeze;
|
||||||
this.ffzWarnPaused();
|
|
||||||
}
|
if ( freeze_change )
|
||||||
|
if ( should_freeze )
|
||||||
|
this.ffzFreeze();
|
||||||
|
else
|
||||||
|
this.ffzUnfreeze();
|
||||||
},
|
},
|
||||||
|
|
||||||
_scrollToBottom: _.throttle(function() {
|
_scrollToBottom: _.throttle(function() {
|
||||||
|
@ -400,7 +471,19 @@ FFZ.prototype._modify_rview = function(view) {
|
||||||
if ( ! warning ) {
|
if ( ! warning ) {
|
||||||
warning = document.createElement('div');
|
warning = document.createElement('div');
|
||||||
warning.className = 'more-messages-indicator ffz-freeze-indicator';
|
warning.className = 'more-messages-indicator ffz-freeze-indicator';
|
||||||
warning.innerHTML = '(Chat Paused Due to Mouse Movement)';
|
|
||||||
|
var hp = f.settings.chat_hover_pause,
|
||||||
|
label = hp === 2 ? 'Ctrl Key' :
|
||||||
|
hp === 3 ? (constants.META_NAME + ' Key') :
|
||||||
|
hp === 4 ? 'Alt Key' :
|
||||||
|
hp === 5 ? 'Shift Key' :
|
||||||
|
hp === 6 ? 'Ctrl or Mouse' :
|
||||||
|
hp === 7 ? (constants.META_NAME + ' or Mouse') :
|
||||||
|
hp === 8 ? 'Alt or Mouse' :
|
||||||
|
hp === 9 ? 'Shift or Mouse' :
|
||||||
|
'Mouse Movement';
|
||||||
|
|
||||||
|
warning.innerHTML = '(Chat Paused Due to ' + label + ')';
|
||||||
|
|
||||||
var cont = el.querySelector('.chat-interface');
|
var cont = el.querySelector('.chat-interface');
|
||||||
if ( ! cont )
|
if ( ! cont )
|
||||||
|
@ -923,8 +1006,10 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
user = f.get_user(),
|
user = f.get_user(),
|
||||||
room_id = this.get('id');
|
room_id = this.get('id');
|
||||||
|
|
||||||
if ( (Chat && Chat.get('currentChannelRoom') === this) || (user && user.login === room_id) || (f._chatv && f._chatv._ffz_host === room_id) || (f.settings.pinned_rooms && f.settings.pinned_rooms.indexOf(room_id) !== -1) )
|
/* ???
|
||||||
return this.ffzUnsubscribe(true);
|
if ( (Chat && Chat.get('currentChannelRoom') === this) || (user && user.login === room_id) || (f._chatv && f._chatv._ffz_host === room_id) || (f.settings.pinned_rooms && f.settings.pinned_rooms.indexOf(room_id) !== -1) )
|
||||||
|
f.ws_unsub()
|
||||||
|
return this.ffzUnsubscribe(true);*/
|
||||||
|
|
||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
@ -1284,6 +1369,31 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
|
|
||||||
addMessage: function(msg) {
|
addMessage: function(msg) {
|
||||||
if ( msg ) {
|
if ( msg ) {
|
||||||
|
var is_resub = msg.tags && msg.tags['msg-id'] === 'resub',
|
||||||
|
room_id = this.get('id');
|
||||||
|
|
||||||
|
// Ignore resubs in other rooms.
|
||||||
|
if ( is_resub && ! f.settings.hosted_sub_notices && (msg.tags['room-id'] != this.get('roomProperties._id') || HOSTED_SUB.test(msg.tags['system-msg'])) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Split this into two messages if requested.
|
||||||
|
if ( is_resub && f.settings.old_sub_notices ) {
|
||||||
|
this.addMessage({
|
||||||
|
style: "notification",
|
||||||
|
from: "twitchnotify",
|
||||||
|
date: msg.date || new Date,
|
||||||
|
room: room_id,
|
||||||
|
message: msg.tags['system-msg']
|
||||||
|
});
|
||||||
|
|
||||||
|
// If there's no message just quit now.
|
||||||
|
if ( ! msg.message )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// And delete the system message so it won't render weirdly.
|
||||||
|
msg.tags['system-msg'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
var is_whisper = msg.style === 'whisper';
|
var is_whisper = msg.style === 'whisper';
|
||||||
|
|
||||||
// Ignore whispers if conversations are enabled.
|
// Ignore whispers if conversations are enabled.
|
||||||
|
@ -1291,7 +1401,7 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( ! is_whisper )
|
if ( ! is_whisper )
|
||||||
msg.room = this.get('id');
|
msg.room = room_id;
|
||||||
|
|
||||||
// Look up color and labels.
|
// Look up color and labels.
|
||||||
if ( this.tmiRoom && msg.from ) {
|
if ( this.tmiRoom && msg.from ) {
|
||||||
|
@ -1434,6 +1544,13 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
try {
|
try {
|
||||||
this.ffz_last_input = Date.now();
|
this.ffz_last_input = Date.now();
|
||||||
|
|
||||||
|
var first_char = text.charAt(0),
|
||||||
|
is_cmd = first_char === '/' || first_char === '.';
|
||||||
|
|
||||||
|
// Strip trailing whitespace from commands.
|
||||||
|
if ( is_cmd )
|
||||||
|
text = text.replace(/\s+$/, '');
|
||||||
|
|
||||||
if ( text && ! ignore_history ) {
|
if ( text && ! ignore_history ) {
|
||||||
// Command History
|
// Command History
|
||||||
var mru = this.get('mru_list'),
|
var mru = this.get('mru_list'),
|
||||||
|
|
|
@ -37,7 +37,7 @@ FFZ.msg_commands = {};
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
var VER = FFZ.version_info = {
|
var VER = FFZ.version_info = {
|
||||||
major: 3, minor: 5, revision: 203,
|
major: 3, minor: 5, revision: 216,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ FFZ.prototype.initialize = function(increment, delay) {
|
||||||
if ( location.hostname === 'passport.twitch.tv' || /^\/user\/two_factor/.test(location.pathname) )
|
if ( location.hostname === 'passport.twitch.tv' || /^\/user\/two_factor/.test(location.pathname) )
|
||||||
return this.log("Found authentication sub-page. Not initializing.");
|
return this.log("Found authentication sub-page. Not initializing.");
|
||||||
|
|
||||||
if ( ['im.twitch.tv', 'api.twitch.tv'].indexOf(location.hostname) !== -1 )
|
if ( ['im.twitch.tv', 'api.twitch.tv'].indexOf(location.hostname) !== -1 || /^\/products\//.test(location.pathname) )
|
||||||
return this.log("Found banned sub-domain. Not initializing.");
|
return this.log("Found banned sub-domain. Not initializing.");
|
||||||
|
|
||||||
// Check for the player
|
// Check for the player
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ember-chat .chat-messages .chat-line.brick--marked { padding-left: 8px }
|
||||||
|
|
||||||
|
|
||||||
/* Remove Extra Conversation Padding */
|
/* Remove Extra Conversation Padding */
|
||||||
.conversation-window .conversation-chat-lines {
|
.conversation-window .conversation-chat-lines {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
|
|
@ -15,4 +15,12 @@
|
||||||
|
|
||||||
.chat-history .chat-line:before {
|
.chat-history .chat-line:before {
|
||||||
top: 0; bottom: 0;
|
top: 0; bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-line.brick--marked {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-line.brick--marked:before {
|
||||||
|
box-shadow: 3px 0 0 #6441a4 inset;
|
||||||
}
|
}
|
19
src/styles/chat-user-bg.css
Normal file
19
src/styles/chat-user-bg.css
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
.chat-lines .chat-line[data-sender="{user_id}"]:before {
|
||||||
|
background-color: rgba(0,127,255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-lines .chat-line[data-sender="{user_id}"]:nth-child(2n+0):before {
|
||||||
|
background-color: rgba(0,127,255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theatre .chat-lines .chat-line[data-sender="{user_id}"]:before,
|
||||||
|
.dark .chat-lines .chat-line[data-sender="{user_id}"]:before,
|
||||||
|
.force-dark .chat-lines .chat-line[data-sender="{user_id}"]:before {
|
||||||
|
background-color: rgba(0,63,127, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theatre .chat-lines .chat-line[data-sender="{user_id}"]:nth-child(2n+0):before,
|
||||||
|
.dark .chat-lines .chat-line[data-sender="{user_id}"]:nth-child(2n+0):before,
|
||||||
|
.force-dark .chat-lines .chat-line[data-sender="{user_id}"]:nth-child(2n+0):before {
|
||||||
|
background-color: rgba(0,63,127, 0.4);
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ var FFZ = window.FrankerFaceZ,
|
||||||
constants = require("./constants"),
|
constants = require("./constants"),
|
||||||
helpers,
|
helpers,
|
||||||
conv_helpers,
|
conv_helpers,
|
||||||
|
emote_helpers,
|
||||||
|
|
||||||
EXPLANATION_WARN = '<hr>This link has been sent to you via a whisper rather than standard chat, and has not been checked or approved of by any moderators or staff members. Please treat this link with caution and do not visit it if you do not trust the sender.',
|
EXPLANATION_WARN = '<hr>This link has been sent to you via a whisper rather than standard chat, and has not been checked or approved of by any moderators or staff members. Please treat this link with caution and do not visit it if you do not trust the sender.',
|
||||||
|
|
||||||
|
@ -160,6 +161,12 @@ FFZ.prototype.setup_tokenization = function() {
|
||||||
this.error("Unable to get conversation helper functions.", err);
|
this.error("Unable to get conversation helper functions.", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
emote_helpers = window.require && window.require("web-client/utilities/tmi-emotes").default;
|
||||||
|
} catch(err) {
|
||||||
|
this.error("Unable to get tmi-emotes helper function.", err);
|
||||||
|
}
|
||||||
|
|
||||||
this.log("Hooking Ember chat line helpers.");
|
this.log("Hooking Ember chat line helpers.");
|
||||||
|
|
||||||
var f = this;
|
var f = this;
|
||||||
|
@ -395,6 +402,9 @@ FFZ.prototype.tokenize_conversation_line = function(message, prevent_notificatio
|
||||||
if ( conv_helpers && conv_helpers.checkActionMessage )
|
if ( conv_helpers && conv_helpers.checkActionMessage )
|
||||||
tokens = conv_helpers.checkActionMessage(tokens);
|
tokens = conv_helpers.checkActionMessage(tokens);
|
||||||
|
|
||||||
|
if ( emote_helpers )
|
||||||
|
emotes = emote_helpers(emotes);
|
||||||
|
|
||||||
// Standard Tokenization
|
// Standard Tokenization
|
||||||
if ( helpers && helpers.linkifyMessage )
|
if ( helpers && helpers.linkifyMessage )
|
||||||
tokens = helpers.linkifyMessage(tokens);
|
tokens = helpers.linkifyMessage(tokens);
|
||||||
|
@ -775,8 +785,8 @@ FFZ.prototype.render_token = function(render_links, warn_links, token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( token.type === "deleted" )
|
else if ( token.type === "deleted" )
|
||||||
return '<span class="deleted-word tooltip" title="' + utils.quote_attr(token.text) + '" data-text="' + utils.sanitize(token.text) + '">×××</span>';
|
return '<span class="deleted-word html-tooltip" title="' + utils.quote_san(token.text) + '" data-text="' + utils.sanitize(token.text) + '">×××</span>';
|
||||||
//return `<span class="deleted-word tooltip" title="${utils.quote_attr(token.text)}" data-text="${utils.sanitize(token.text)}">×××</span>`;
|
//return `<span class="deleted-word html-tooltip" title="${utils.quote_attr(token.text)}" data-text="${utils.sanitize(token.text)}">×××</span>`;
|
||||||
|
|
||||||
else if ( token.type === "mention" )
|
else if ( token.type === "mention" )
|
||||||
return '<span class="' + (token.isOwnMessage ? 'mentioning' : 'mentioned') + '">' + utils.sanitize(token.user) + '</span>';
|
return '<span class="' + (token.isOwnMessage ? 'mentioning' : 'mentioned') + '">' + utils.sanitize(token.user) + '</span>';
|
||||||
|
|
|
@ -69,7 +69,7 @@ FFZ.prototype.setup_following_count = function(has_ember) {
|
||||||
setTimeout(this._install_following_tooltips.bind(this), 2000);
|
setTimeout(this._install_following_tooltips.bind(this), 2000);
|
||||||
|
|
||||||
// If we don't have Ember, no point in trying this stuff.
|
// If we don't have Ember, no point in trying this stuff.
|
||||||
if ( ! has_ember )
|
if ( this.is_dashboard || ! has_ember )
|
||||||
return this._following_get_me();
|
return this._following_get_me();
|
||||||
|
|
||||||
this.log("Connecting to Live Streams model.");
|
this.log("Connecting to Live Streams model.");
|
||||||
|
@ -163,10 +163,10 @@ FFZ.prototype._update_following_count = function() {
|
||||||
|
|
||||||
f = this;
|
f = this;
|
||||||
|
|
||||||
if ( HostLive && document.body.getAttribute('data-current-path').indexOf('directory.following') !== -1 )
|
if ( ! this.is_dashboard && HostLive && document.body.getAttribute('data-current-path').indexOf('directory.following') !== -1 )
|
||||||
HostLive.load();
|
HostLive.load();
|
||||||
|
|
||||||
if ( Live )
|
if ( ! this.is_dashboard && Live )
|
||||||
Live.load();
|
Live.load();
|
||||||
else {
|
else {
|
||||||
var u = this.get_user();
|
var u = this.get_user();
|
||||||
|
|
|
@ -612,9 +612,9 @@ FFZ.menu_pages.channel = {
|
||||||
unlock_text.innerHTML = "Subscribe to unlock Emoticons";
|
unlock_text.innerHTML = "Subscribe to unlock Emoticons";
|
||||||
nonsub_message.appendChild(unlock_text);
|
nonsub_message.appendChild(unlock_text);
|
||||||
|
|
||||||
sub_link.className = "action subscribe-button button primary";
|
sub_link.className = "action js-sub-button subscribe-button button button--purchase";
|
||||||
sub_link.href = product.get("product_url");
|
sub_link.href = product.get("product_url");
|
||||||
sub_link.innerHTML = '<span class="subscribe-text">Subscribe</span><span class="subscribe-price">' + product.get("price") + '</span>';
|
sub_link.innerHTML = '<span class="subscribe-text">Subscribe</span><span class="subscribe-price button__num-block">' + product.get("price") + '</span>';
|
||||||
nonsub_message.appendChild(sub_link);
|
nonsub_message.appendChild(sub_link);
|
||||||
|
|
||||||
inner.appendChild(sub_message);
|
inner.appendChild(sub_message);
|
||||||
|
|
|
@ -116,7 +116,7 @@ FFZ.prototype.rebuild_race_ui = function() {
|
||||||
race_container.setAttribute('data-channel', channel_id);
|
race_container.setAttribute('data-channel', channel_id);
|
||||||
|
|
||||||
var btn = document.createElement('span');
|
var btn = document.createElement('span');
|
||||||
btn.className = 'button drop action';
|
btn.className = 'button button--text button--dropmenu';
|
||||||
btn.title = "SpeedRunsLive Race";
|
btn.title = "SpeedRunsLive Race";
|
||||||
btn.innerHTML = '<span class="logo"></span>';
|
btn.innerHTML = '<span class="logo"></span>';
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ FFZ.prototype.rebuild_race_ui = function() {
|
||||||
race_container.setAttribute('data-channel', hosted_id);
|
race_container.setAttribute('data-channel', hosted_id);
|
||||||
|
|
||||||
var btn = document.createElement('span');
|
var btn = document.createElement('span');
|
||||||
btn.className = 'button drop action';
|
btn.className = 'button button--text button--dropmenu';
|
||||||
btn.title = "SpeedRunsLive Race";
|
btn.title = "SpeedRunsLive Race";
|
||||||
btn.innerHTML = '<span class="logo"></span>';
|
btn.innerHTML = '<span class="logo"></span>';
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ FFZ.prototype._update_race = function(container, not_timer) {
|
||||||
// Make sure we don't leave any tooltips lying around when we update.
|
// Make sure we don't leave any tooltips lying around when we update.
|
||||||
// Of course, we should just rewrite logic to not constantly mutilate
|
// Of course, we should just rewrite logic to not constantly mutilate
|
||||||
// rows.
|
// rows.
|
||||||
jQuery('.tooltip', tbody).trigger('mouseout');
|
jQuery('.html-tooltip', tbody).trigger('mouseout');
|
||||||
|
|
||||||
tbody.innerHTML = '';
|
tbody.innerHTML = '';
|
||||||
var entrants = [], done = true;
|
var entrants = [], done = true;
|
||||||
|
@ -312,23 +312,23 @@ FFZ.prototype._update_race = function(container, not_timer) {
|
||||||
hitbox_link = ent.hitbox ? '<a target="_new" class="hitbox" href="http://www.hitbox.tv/' + utils.sanitize(ent.hitbox) + '"></a>' : '',
|
hitbox_link = ent.hitbox ? '<a target="_new" class="hitbox" href="http://www.hitbox.tv/' + utils.sanitize(ent.hitbox) + '"></a>' : '',
|
||||||
time = elapsed ? utils.time_to_string(ent.time||elapsed) : "",
|
time = elapsed ? utils.time_to_string(ent.time||elapsed) : "",
|
||||||
place = utils.place_string(ent.place),
|
place = utils.place_string(ent.place),
|
||||||
comment = ent.comment ? utils.sanitize(ent.comment) : "";
|
comment = ent.comment ? utils.quote_san(ent.comment) : "";
|
||||||
|
|
||||||
tbody.innerHTML += '<tr' + (comment ? ' title="' + comment + '"' : '') + ' class="' + ent.state + (comment ? ' tooltip' : '') + '"><td>' + place + '</td><td>' + name + '</td><td>' + twitch_link + hitbox_link + '</td><td class="time">' + (ent.state == "forfeit" ? "Forfeit" : time) + '</td></tr>';
|
tbody.innerHTML += '<tr' + (comment ? ' title="' + comment + '"' : '') + ' class="' + ent.state + (comment ? ' html-tooltip' : '') + '"><td>' + place + '</td><td>' + name + '</td><td>' + twitch_link + hitbox_link + '</td><td class="time">' + (ent.state == "forfeit" ? "Forfeit" : time) + '</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this._race_game != race.game || this._race_goal != race.goal ) {
|
if ( this._race_game != race.game || this._race_goal != race.goal ) {
|
||||||
this._race_game = race.game;
|
this._race_game = race.game;
|
||||||
this._race_goal = race.goal;
|
this._race_goal = race.goal;
|
||||||
|
|
||||||
var game = utils.sanitize(race.game),
|
var game = utils.quote_san(race.game),
|
||||||
goal = utils.unquote_attr(race.goal),
|
goal = utils.unquote_attr(race.goal),
|
||||||
old_goal = popup.getAttribute('data-old-goal');
|
old_goal = popup.getAttribute('data-old-goal');
|
||||||
|
|
||||||
if ( goal !== old_goal ) {
|
if ( goal !== old_goal ) {
|
||||||
popup.setAttribute('data-old-goal', goal);
|
popup.setAttribute('data-old-goal', goal);
|
||||||
goal = goal ? this.render_tokens(this.tokenize_line("jtv", null, goal, true)) : '';
|
goal = goal ? this.render_tokens(this.tokenize_line("jtv", null, goal, true)) : '';
|
||||||
info.innerHTML = '<h2 class="tooltip" title="' + game + '">' + game + '</h2><span class="goal"><b>Goal: </b>' + goal + '</span>';
|
info.innerHTML = '<h2 class="html-tooltip" title="' + game + '">' + game + '</h2><span class="goal"><b>Goal: </b>' + goal + '</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,10 @@ var sanitize_el = document.createElement('span'),
|
||||||
return msg.replace(R_AMP, "&").replace(R_QUOTE, """).replace(R_SQUOTE, "'").replace(R_LT, "<").replace(R_GT, ">");
|
return msg.replace(R_AMP, "&").replace(R_QUOTE, """).replace(R_SQUOTE, "'").replace(R_LT, "<").replace(R_GT, ">");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
quote_san = function(msg) {
|
||||||
|
return sanitize(msg).replace(R_QUOTE, """).replace(R_SQUOTE, "'");
|
||||||
|
},
|
||||||
|
|
||||||
HUMAN_NUMBERS = [
|
HUMAN_NUMBERS = [
|
||||||
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
|
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
|
||||||
],
|
],
|
||||||
|
@ -333,6 +337,10 @@ module.exports = FFZ.utils = {
|
||||||
|
|
||||||
closer = show_modal(contents, cb, width);
|
closer = show_modal(contents, cb, width);
|
||||||
|
|
||||||
|
try {
|
||||||
|
input.focus();
|
||||||
|
} catch(err) { }
|
||||||
|
|
||||||
form.addEventListener('submit', function(e) { e.preventDefault(); cb(true); return false });
|
form.addEventListener('submit', function(e) { e.preventDefault(); cb(true); return false });
|
||||||
okay_btn.addEventListener('click', function(e) { e.preventDefault(); cb(true); return false });
|
okay_btn.addEventListener('click', function(e) { e.preventDefault(); cb(true); return false });
|
||||||
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
|
close_btn.addEventListener('click', function(e) { e.preventDefault(); cb(false); return false });
|
||||||
|
@ -423,6 +431,7 @@ module.exports = FFZ.utils = {
|
||||||
sanitize: sanitize,
|
sanitize: sanitize,
|
||||||
unquote_attr: unquote_attr,
|
unquote_attr: unquote_attr,
|
||||||
quote_attr: quote_attr,
|
quote_attr: quote_attr,
|
||||||
|
quote_san: quote_san,
|
||||||
|
|
||||||
date_string: function(date) {
|
date_string: function(date) {
|
||||||
return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
|
return date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
|
||||||
|
|
78
style.css
78
style.css
|
@ -325,7 +325,7 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
||||||
color: #a68ed2;
|
color: #a68ed2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-theater-stats .app-main.theatre .button.glyph-only svg path {
|
.ffz-theater-stats .app-main.theatre .button.button--icon-only svg path {
|
||||||
fill: #a68ed2;
|
fill: #a68ed2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,6 +336,8 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
||||||
|
|
||||||
/* SRL Race Support */
|
/* SRL Race Support */
|
||||||
|
|
||||||
|
#ffz-ui-host-button { vertical-align: middle }
|
||||||
|
|
||||||
#ffz-following-popup.right {
|
#ffz-following-popup.right {
|
||||||
right: 0;
|
right: 0;
|
||||||
left: auto;
|
left: auto;
|
||||||
|
@ -354,6 +356,7 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
||||||
|
|
||||||
#ffz-ui-race .button span.logo {
|
#ffz-ui-race .button span.logo {
|
||||||
padding-left: 44px;
|
padding-left: 44px;
|
||||||
|
margin-bottom: -10px;
|
||||||
background-image: url("//cdn.frankerfacez.com/script/srl_button.png");
|
background-image: url("//cdn.frankerfacez.com/script/srl_button.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1288,8 +1291,11 @@ img.channel_background[src="null"] { display: none; }
|
||||||
.ffz-moderation-card button {
|
.ffz-moderation-card button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
|
color: #6441a4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-moderation-card .mod-controls button figure { padding: 0 }
|
||||||
|
|
||||||
.ember-chat .ffz-moderation-card .mod-controls button {
|
.ember-chat .ffz-moderation-card .mod-controls button {
|
||||||
width: auto;
|
width: auto;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
@ -1306,10 +1312,13 @@ img.channel_background[src="null"] { display: none; }
|
||||||
padding-right: 0 !important;
|
padding-right: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-moderation-card .button.glyph-only { padding: 0 !important }
|
.ffz-moderation-card .button.button--icon-only {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-moderation-card button:not(.glyph-only):hover,
|
.ffz-moderation-card button:not(.button--icon-only):hover,
|
||||||
.ffz-moderation-card button:not(.glyph-only):focus {
|
.ffz-moderation-card button:not(.button--icon-only):focus {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: rgba(117,80,186, 1);
|
background-color: rgba(117,80,186, 1);
|
||||||
}
|
}
|
||||||
|
@ -1404,6 +1413,13 @@ img.channel_background[src="null"] { display: none; }
|
||||||
|
|
||||||
/* Chat Rows */
|
/* Chat Rows */
|
||||||
|
|
||||||
|
.theatre .conversation-window .conversation-chat-line,
|
||||||
|
.dark .chat-line,
|
||||||
|
.force-dark .chat-line,
|
||||||
|
.theatre .chat-line {
|
||||||
|
color: #acacbf;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-alias-italics .ffz-alias { font-style: italic; }
|
.ffz-alias-italics .ffz-alias { font-style: italic; }
|
||||||
|
|
||||||
.ember-chat .chat-messages .chat-line.ffz-has-deleted {
|
.ember-chat .chat-messages .chat-line.ffz-has-deleted {
|
||||||
|
@ -1720,7 +1736,7 @@ th.ffz-row-switch {
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ffz-group-tabs .button.glyph-only svg {
|
#ffz-group-tabs .button.button--icon-only svg {
|
||||||
margin: 6px 0;
|
margin: 6px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2216,6 +2232,14 @@ body:not([data-current-path^="user."]) .ffz-sidebar-swap .ember-chat .chat-inter
|
||||||
background-color: #191919;
|
background-color: #191919;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-no-blue .theatre .conversation-input-bar textarea,
|
||||||
|
.ffz-no-blue .theatre input.text,
|
||||||
|
.ffz-no-blue .theatre input.countries-input,
|
||||||
|
.ffz-no-blue .theatre .recurly input,
|
||||||
|
.ffz-no-blue .recurly .theatre input {
|
||||||
|
background-color: #202020;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-no-blue .warp__anchor,
|
.ffz-no-blue .warp__anchor,
|
||||||
.ffz-no-blue .warp__item--anchor,
|
.ffz-no-blue .warp__item--anchor,
|
||||||
.ffz-no-blue .warp__drawer,
|
.ffz-no-blue .warp__drawer,
|
||||||
|
@ -2966,6 +2990,14 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
||||||
background-size: 100%
|
background-size: 100%
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
/* Button Fix */
|
||||||
|
|
||||||
|
.ffz-no-bg {
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Odd Badges */
|
/* Odd Badges */
|
||||||
.badge.click_url { cursor: pointer }
|
.badge.click_url { cursor: pointer }
|
||||||
|
|
||||||
|
@ -2981,8 +3013,36 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
||||||
background-image: image-set(url("https://cdn.frankerfacez.com/badges/twitch/warcraft/horde/1.png") 1x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/horde/2.png") 2x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/horde/4.png") 4x);
|
background-image: image-set(url("https://cdn.frankerfacez.com/badges/twitch/warcraft/horde/1.png") 1x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/horde/2.png") 2x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/horde/4.png") 4x);
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge.warcraft.version-protoss {
|
|
||||||
background: url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/1.png") #5bc7ff;
|
/* New Resub Banner */
|
||||||
background-image: -webkit-image-set(url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/1.png") 1x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/2.png") 2x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/4.png") 4x);
|
|
||||||
background-image: image-set(url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/1.png") 1x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/2.png") 2x,url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/4.png") 4x);
|
.top-notification--resub {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-notification--resub > * {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-message {
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-room .show-mod-icons .chat-line:not(.admin) .mod-icons {
|
||||||
|
display: block !important;
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
bottom: 1px;
|
||||||
|
padding: 4px 5px 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 99;
|
||||||
|
background-color: rgba(255,255,255,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theatre .chat-room .show-mod-icons .chat-line:not(.admin) .mod-icons,
|
||||||
|
.dark .chat-room .show-mod-icons .chat-line:not(.admin) .mod-icons,
|
||||||
|
.force-dark .chat-room .show-mod-icons .chat-line:not(.admin) .mod-icons {
|
||||||
|
background-color: rgba(0,0,0,0.8);
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue