mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-02 16:08:31 +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;
|
||||
}
|
||||
|
||||
.ffz-dark .moderation-card .button:not(.glyph-only):hover {
|
||||
.ffz-dark .moderation-card .button:not(.button--icon-only):hover {
|
||||
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 .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--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__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__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;
|
||||
}
|
||||
|
||||
.ffz-dark .button:not(.button--status):not(.primary) {
|
||||
.ffz-dark .message-button,
|
||||
.ffz-dark .button--text,
|
||||
.ffz-dark .button.ffz-no-bg {
|
||||
color: #a68ed2;
|
||||
}
|
||||
|
||||
.ffz-dark .button.glyph-only svg path {
|
||||
.ffz-dark .button.button--icon-only svg path {
|
||||
fill: #a68ed2;
|
||||
}
|
||||
|
||||
.ffz-dark .button.glyph-only:hover svg path {
|
||||
.ffz-dark .button.button--icon-only:hover svg path {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
|
@ -565,10 +573,6 @@ body.ffz-dark:not([data-page="teams#show"]),
|
|||
.ffz-dark .toggle-darkmode { display: none; }
|
||||
|
||||
/* 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-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.selected a,
|
||||
.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 {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
@ -1128,8 +1133,8 @@ body.ffz-dark:not([data-page="teams#show"]),
|
|||
fill: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
.ffz-dark .conversation-input-bar .emoticon-selector-box .emote-set {
|
||||
border-color: #323232;
|
||||
.ffz-dark .emoticon-selector-box .emote-set {
|
||||
border-color: #323232 !important;
|
||||
}
|
||||
|
||||
.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-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;
|
||||
background-color: #242424;
|
||||
}
|
||||
|
||||
.ffz-dark .activity-react__item svg.endorse-icon #head__base { fill: #fff }
|
||||
|
||||
.ffz-dark .activity-create__actions {
|
||||
background-color: #191919;
|
||||
box-shadow: 0 -1px 0 #474747;
|
||||
}
|
||||
|
||||
.ffz-dark .activity-create,
|
||||
.ffz-dark .activity-react__item {
|
||||
.ffz-dark .activity-button {
|
||||
border-color: #474747;
|
||||
color: #fff !important;
|
||||
background-color: #191919;
|
||||
}
|
||||
|
||||
.ffz-dark .activity-meta:before,
|
||||
.ffz-dark .activity-meta-divider:before,
|
||||
.ffz-dark .activity-card {
|
||||
border-color: #474747;
|
||||
}
|
||||
|
@ -1233,11 +1236,12 @@ body.ffz-dark:not([data-page="teams#show"]),
|
|||
background-color: #191919;
|
||||
}
|
||||
|
||||
.ffz-dark .activity-meta {
|
||||
.ffz-dark .activity-meta-divider {
|
||||
box-shadow: inset 0 -1px 0 #474747;
|
||||
}
|
||||
|
||||
.ffz-dark a.balloon__link:hover { color: #fff !important }
|
||||
.ffz-dark .activity-meta__name { color: #ccc }
|
||||
|
||||
|
||||
/* Search Panel */
|
||||
|
|
|
@ -128,8 +128,8 @@ FFZ.settings_info.sub_notice_badges = {
|
|||
value: false,
|
||||
|
||||
category: "Chat Appearance",
|
||||
name: "Subscriber Notice Badges",
|
||||
help: "Display a subscriber badge on chat messages about new subscribers.",
|
||||
name: "Old-Style Subscriber Notice Badges",
|
||||
help: "Display a subscriber badge on old-style chat messages about new subscribers.",
|
||||
|
||||
on_update: function(val) {
|
||||
this.toggle_style('badges-sub-notice', ! val);
|
||||
|
@ -348,8 +348,16 @@ FFZ.prototype.get_line_badges = function(msg) {
|
|||
globals = badgeCollection && badgeCollection.global || {},
|
||||
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.
|
||||
if ( typeof badge_tag === 'string' ) {
|
||||
else if ( typeof badge_tag === 'string' ) {
|
||||
var val = badge_tag.split(',');
|
||||
badge_tag = {};
|
||||
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],
|
||||
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 )
|
||||
continue;
|
||||
|
||||
|
@ -456,7 +450,7 @@ FFZ.prototype.render_badges = function(badges) {
|
|||
if ( badge.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("");
|
||||
|
|
|
@ -46,12 +46,12 @@ FFZ.settings_info.fix_color = {
|
|||
},
|
||||
|
||||
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' )
|
||||
this._rebuild_colors();
|
||||
}
|
||||
};
|
||||
if ( ! this.has_bttv && val !== '-1' )
|
||||
this._rebuild_colors();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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'),
|
||||
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]",
|
||||
SPLITTER = new RegExp(SEPARATORS + "*," + SEPARATORS + "*"),
|
||||
|
||||
|
@ -15,7 +19,9 @@ module.exports = FrankerFaceZ.constants = {
|
|||
DEBUG: DEBUG,
|
||||
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
|
||||
CLIENT_ID: "a3bc9znoz6vi8ozsoca0inlcr4fcvkl",
|
||||
|
|
|
@ -111,7 +111,6 @@ FFZ.prototype.setup_channel = function() {
|
|||
var game = data.stream.game || (data.stream.channel && data.stream.channel.game);
|
||||
if ( game ) {
|
||||
t.set('content.game', game);
|
||||
t.set('content.rollbackData.game', game);
|
||||
}
|
||||
|
||||
if ( data.stream.channel ) {
|
||||
|
@ -228,9 +227,9 @@ FFZ.prototype._modify_cindex = function(view) {
|
|||
f.rebuild_race_ui();
|
||||
|
||||
if ( f.settings.auto_theater ) {
|
||||
var Layout = utils.ember_lookup('service:layout');
|
||||
if ( Layout )
|
||||
Layout.set('isTheatreMode', true);
|
||||
var player = f.players && f.players[id] && f.players[id].get('player');
|
||||
if ( player )
|
||||
player.setTheatre(true);
|
||||
}
|
||||
|
||||
this.$().on("click", ".ffz-creative-tag-link", function(e) {
|
||||
|
@ -296,7 +295,7 @@ FFZ.prototype._modify_cindex = function(view) {
|
|||
if ( ! btn ) {
|
||||
btn = document.createElement('span');
|
||||
btn.id = 'ffz-ui-host-button';
|
||||
btn.className = 'button action';
|
||||
btn.className = 'button button--text';
|
||||
|
||||
btn.addEventListener('click', this.ffzClickHost.bind(this, false));
|
||||
|
||||
|
@ -336,7 +335,7 @@ FFZ.prototype._modify_cindex = function(view) {
|
|||
if ( ! btn ) {
|
||||
btn = document.createElement('span');
|
||||
btn.id = 'ffz-ui-host-button';
|
||||
btn.className = 'button action';
|
||||
btn.className = 'button button--text';
|
||||
|
||||
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 = {
|
||||
type: "boolean",
|
||||
value: true,
|
||||
|
@ -479,8 +508,11 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
ind = this.get('ffz_partial_word_start'),
|
||||
text = this.get('textareaValue'),
|
||||
|
||||
content = ((f.settings.input_complete_name_at && item.type === 'user' && this.get('ffz_partial_word').charAt(0) === '@') ? '@' : '') +
|
||||
((item.command_content && text.charAt(0) === '/' ?
|
||||
first_char = 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),
|
||||
|
||||
trail = text.substr(ind + this.get('ffz_partial_word').length),
|
||||
|
@ -664,26 +696,50 @@ FFZ.prototype._modify_chat_input = function(component) {
|
|||
|
||||
|
||||
// Always include Users
|
||||
var user_output = {};
|
||||
var user_output = {},
|
||||
alias_setting = f.settings.input_complete_aliases;
|
||||
|
||||
for(var i=0; i < suggestions.length; 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];
|
||||
token.whispered |= suggestion.whispered;
|
||||
if ( suggestion.timestamp > token.timestamp )
|
||||
token.timestamp = suggestion.timestamp;
|
||||
|
||||
} else
|
||||
output.push(user_output[name] = {
|
||||
type: "user",
|
||||
command_content: name,
|
||||
label: FFZ.get_capitalization(name),
|
||||
whispered: suggestion.whispered,
|
||||
timestamp: suggestion.timestamp || new Date(0),
|
||||
info: 'User'
|
||||
});
|
||||
} else {
|
||||
if ( alias_setting !== 2 )
|
||||
output.push(user_output[name] = {
|
||||
type: "user",
|
||||
command_content: name,
|
||||
label: FFZ.get_capitalization(name),
|
||||
whispered: suggestion.whispered,
|
||||
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;
|
||||
|
|
|
@ -974,12 +974,12 @@ FFZ.prototype._modify_cview = function(view) {
|
|||
if ( current_channel ) {
|
||||
icon.innerHTML = constants.CAMERA;
|
||||
row.title = "Current Channel";
|
||||
row.classList.add('tooltip');
|
||||
row.classList.add('html-tooltip');
|
||||
|
||||
} else if ( host_channel ) {
|
||||
icon.innerHTML = constants.EYE;
|
||||
row.title = "Hosted Channel";
|
||||
row.classList.add('tooltip');
|
||||
row.classList.add('html-tooltip');
|
||||
}
|
||||
|
||||
name_el.className = 'ffz-room';
|
||||
|
@ -1008,7 +1008,7 @@ FFZ.prototype._modify_cview = function(view) {
|
|||
});
|
||||
} else {
|
||||
btn = document.createElement('a');
|
||||
btn.className = 'leave-chat tooltip';
|
||||
btn.className = 'leave-chat html-tooltip';
|
||||
btn.innerHTML = constants.CLOSE;
|
||||
btn.title = 'Leave Group';
|
||||
|
||||
|
@ -1090,9 +1090,9 @@ FFZ.prototype._modify_cview = function(view) {
|
|||
|
||||
|
||||
// Chat Room Management Button
|
||||
link.className = 'button glyph-only';
|
||||
link.className = 'button button--icon-only';
|
||||
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});
|
||||
|
||||
|
@ -1106,9 +1106,9 @@ FFZ.prototype._modify_cview = function(view) {
|
|||
|
||||
// Invite Button
|
||||
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.innerHTML = constants.INVITE;
|
||||
link.innerHTML = '<figure class="icon">' + constants.INVITE + '</figure>';
|
||||
|
||||
link.addEventListener('click', function() {
|
||||
var controller = view.get('controller');
|
||||
|
@ -1170,7 +1170,7 @@ FFZ.prototype._modify_cview = function(view) {
|
|||
|
||||
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('host-channel', host_channel);
|
||||
tab.classList.toggle('group-chat', group);
|
||||
|
|
|
@ -224,7 +224,7 @@ FFZ.prototype._modify_conversation_line = function(component) {
|
|||
colored = style ? ' has-color' : '';
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
var counted = false;
|
||||
if ( following.get('isLoaded') || following.get('isLoading') ) {
|
||||
if ( following && (following.get('isLoaded') || following.get('isLoading')) ) {
|
||||
refresher(following);
|
||||
count++;
|
||||
counted = true;
|
||||
}
|
||||
|
||||
if ( followers.get('isLoaded') || followers.get('isLoading') ) {
|
||||
if ( followers && (followers.get('isLoaded') || followers.get('isLoading')) ) {
|
||||
refresher(followers);
|
||||
if ( ! counted )
|
||||
count++;
|
||||
|
@ -285,8 +285,8 @@ FFZ.prototype._modify_display_followed_item = function(component) {
|
|||
return;
|
||||
|
||||
var actions = createElement('div', 'actions'),
|
||||
follow = createElement('button', 'button follow'),
|
||||
notif = createElement('button', 'button notifications'),
|
||||
follow = createElement('button', 'button ffz-no-bg follow'),
|
||||
notif = createElement('button', 'button ffz-no-bg notifications'),
|
||||
|
||||
update_follow = function() {
|
||||
data = user_cache[user_id];
|
||||
|
@ -358,7 +358,7 @@ FFZ.prototype._modify_display_followed_item = function(component) {
|
|||
|
||||
FFZ.prototype._hook_following = function(Following) {
|
||||
var f = this;
|
||||
if ( Following.ffz_hooked )
|
||||
if ( ! Following || Following.ffz_hooked )
|
||||
return;
|
||||
|
||||
Following.reopen({
|
||||
|
@ -398,7 +398,7 @@ FFZ.prototype._hook_following = function(Following) {
|
|||
|
||||
FFZ.prototype._hook_followers = function(Followers) {
|
||||
var f = this;
|
||||
if ( Followers.ffz_hooked )
|
||||
if ( ! Followers || Followers.ffz_hooked )
|
||||
return;
|
||||
|
||||
Followers.reopen({
|
||||
|
|
|
@ -299,7 +299,7 @@ FFZ.settings_info.chat_rows = {
|
|||
|
||||
on_update: function(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.",
|
||||
|
||||
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-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 = {
|
||||
type: "boolean",
|
||||
value: false,
|
||||
|
@ -577,7 +589,7 @@ FFZ.prototype.setup_line = function() {
|
|||
// Chat Enhancements
|
||||
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-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 ( 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
|
||||
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 )
|
||||
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 {
|
||||
if ( typeof btn === "string" ) {
|
||||
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 {
|
||||
cmd = "/timeout " + user + " " + 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'))),
|
||||
|
||||
system_msg = this.get('systemMsg'),
|
||||
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
|
||||
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]) || '',
|
||||
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 )
|
||||
output += '" title="' + utils.sanitize(name) + '">' + utils.sanitize(alias);
|
||||
output += '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias);
|
||||
else
|
||||
output += '">' + utils.sanitize(name);
|
||||
|
||||
|
@ -787,10 +809,10 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
|||
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 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 )
|
||||
output += '" title="' + utils.sanitize(to_name) + '">' + utils.sanitize(to_alias);
|
||||
output += '" title="' + utils.quote_san(to_name) + '">' + utils.sanitize(to_alias);
|
||||
else
|
||||
output += '">' + utils.sanitize(to_name);
|
||||
}
|
||||
|
@ -833,10 +855,12 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
|||
var el = this.get('element'),
|
||||
output = this.buildSenderHTML();
|
||||
|
||||
if ( this.get('msgObject.deleted') )
|
||||
output += this.buildDeletedMessageHTML()
|
||||
else
|
||||
output += this.buildMessageHTML();
|
||||
// If this is a whisper, or if we should render the message body, render it.
|
||||
if ( this.get('shouldRenderMessageBody') !== false )
|
||||
if ( this.get('msgObject.deleted') )
|
||||
output += this.buildDeletedMessageHTML()
|
||||
else
|
||||
output += this.buildMessageHTML();
|
||||
|
||||
el.innerHTML = output;
|
||||
},
|
||||
|
@ -932,10 +956,18 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
|||
return;
|
||||
|
||||
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", {
|
||||
left: n.offset().left,
|
||||
top: n.offset().top + n.height(),
|
||||
left: bounds.left,
|
||||
right: right,
|
||||
top: bounds.top + bounds.height,
|
||||
real_top: bounds.top,
|
||||
sender: from
|
||||
});
|
||||
|
||||
|
@ -995,7 +1027,7 @@ FFZ.prototype._modify_vod_line = function(component) {
|
|||
return '<span class="mod-icons float-left">' +
|
||||
(this.get('msgObject.deleted') ?
|
||||
'<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() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
var FFZ = window.FrankerFaceZ,
|
||||
utils = require("../utils"),
|
||||
constants = require("../constants"),
|
||||
styles = require("../compiled_styles"),
|
||||
helpers,
|
||||
|
||||
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",
|
||||
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,
|
||||
|
||||
category: "Chat Moderation",
|
||||
name: "Pause Chat Scrolling on Mouse Hover",
|
||||
help: "Automatically prevent the chat from scrolling when moving the mouse over it to prevent moderation mistakes and link misclicks.",
|
||||
name: "Display In-Line Mod Icons",
|
||||
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) {
|
||||
if ( ! this._roomv )
|
||||
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 )
|
||||
this._roomv.ffzEnableFreeze();
|
||||
else
|
||||
this._roomv.ffzDisableFreeze();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -495,6 +584,17 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
} 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.");
|
||||
var orig_stop = Mousetrap.stopCallback;
|
||||
Mousetrap.stopCallback = function(e, element, combo) {
|
||||
|
@ -511,8 +611,7 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
|
||||
|
||||
this.log("Hooking the Ember Moderation Card view.");
|
||||
var Card = utils.ember_resolve('component:chat/moderation-card'),
|
||||
f = this;
|
||||
var Card = utils.ember_resolve('component:chat/moderation-card');
|
||||
|
||||
Card.reopen({
|
||||
ffzForceRedraw: function() {
|
||||
|
@ -520,6 +619,10 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
if ( f.settings.mod_card_history )
|
||||
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"),
|
||||
|
||||
ffzRebuildInfo: function() {
|
||||
|
@ -528,12 +631,12 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
if ( ! info )
|
||||
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') || ''),
|
||||
followers = this.get('cardInfo.user.ffz_followers');
|
||||
|
||||
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 ) {
|
||||
var t = this;
|
||||
|
@ -550,7 +653,7 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
var now = Date.now() - (f._ws_server_offset || 0),
|
||||
age = Math.floor((now - since.getTime()) / 1000);
|
||||
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() {
|
||||
if ( f._mod_card === this )
|
||||
f._mod_card = undefined;
|
||||
|
||||
utils.update_css(f._chat_style, 'mod-card-highlight');
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
|
@ -594,6 +700,8 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
user_id = controller.get('cardInfo.user.id'),
|
||||
alias = f.aliases[user_id],
|
||||
|
||||
handle_key,
|
||||
|
||||
ban_reason = function() {
|
||||
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;
|
||||
|
||||
// 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
|
||||
this.set('banAction', function(e) {
|
||||
|
@ -677,7 +788,7 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
},
|
||||
|
||||
add_btn_make = function(cmd) {
|
||||
var btn = document.createElement('button'),
|
||||
var btn = utils.createElement('button', 'button ffz-no-bg'),
|
||||
segment = cmd.split(' ', 1)[0],
|
||||
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(' ');
|
||||
|
||||
btn.className = 'button';
|
||||
btn.innerHTML = utils.sanitize(title);
|
||||
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 ) {
|
||||
el.classList.add('no-mousetrap');
|
||||
|
||||
el.addEventListener('keyup', function(e) {
|
||||
handle_key = function(e) {
|
||||
var key = e.keyCode || e.which,
|
||||
user_id = controller.get('cardInfo.user.id'),
|
||||
is_mod = controller.get('cardInfo.isModeratorOrHigher'),
|
||||
|
@ -753,7 +863,9 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
return;
|
||||
|
||||
t.get('closeAction')();
|
||||
});
|
||||
};
|
||||
|
||||
el.addEventListener('keyup', handle_key);
|
||||
}
|
||||
|
||||
|
||||
|
@ -773,13 +885,13 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
|
||||
btn_make = function(timeout) {
|
||||
var btn = document.createElement('button')
|
||||
btn.className = 'button';
|
||||
btn.className = 'button ffz-no-bg';
|
||||
btn.innerHTML = utils.duration_string(timeout);
|
||||
btn.title = "Timeout User for " + utils.number_commas(timeout) + " Second" + (timeout != 1 ? "s" : "");
|
||||
|
||||
if ( f.settings.mod_card_hotkeys && timeout === 600 )
|
||||
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;
|
||||
|
||||
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 ) {
|
||||
// Moderation Reasons
|
||||
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);
|
||||
|
||||
for(var i=0; i < f.settings.mod_card_reasons.length; i++) {
|
||||
|
@ -832,8 +944,8 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
|
||||
// Unban Button
|
||||
var unban_btn = document.createElement('button');
|
||||
unban_btn.className = 'unban button glyph-only light';
|
||||
unban_btn.innerHTML = CHECK;
|
||||
unban_btn.className = 'unban button button--icon-only light';
|
||||
unban_btn.innerHTML = '<figure class="icon">' + CHECK + '</figure>';
|
||||
unban_btn.title = (f.settings.mod_card_hotkeys ? "(U)" : "U") + "nban User";
|
||||
|
||||
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
|
||||
var op_btn = el.querySelector('button.mod');
|
||||
if ( op_btn ) {
|
||||
|
@ -863,7 +979,7 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
var msg_btn = el.querySelector(".interface > button.message-button");
|
||||
if ( msg_btn ) {
|
||||
msg_btn.innerHTML = 'W';
|
||||
msg_btn.classList.add('glyph-only');
|
||||
msg_btn.classList.add('button--icon-only');
|
||||
msg_btn.classList.add('message');
|
||||
|
||||
msg_btn.title = "Whisper User";
|
||||
|
@ -871,8 +987,8 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
|
||||
|
||||
var real_msg = document.createElement('button');
|
||||
real_msg.className = 'message-button button glyph-only message tooltip';
|
||||
real_msg.innerHTML = MESSAGE;
|
||||
real_msg.className = 'message-button button button--icon-only message html-tooltip';
|
||||
real_msg.innerHTML = '<figure class="icon">' + MESSAGE + '</figure>';
|
||||
real_msg.title = "Message User";
|
||||
|
||||
real_msg.addEventListener('click', function() {
|
||||
|
@ -885,8 +1001,8 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
|
||||
// Alias Button
|
||||
var alias_btn = document.createElement('button');
|
||||
alias_btn.className = 'alias button glyph-only tooltip';
|
||||
alias_btn.innerHTML = constants.EDIT;
|
||||
alias_btn.className = 'alias button button--icon-only html-tooltip';
|
||||
alias_btn.innerHTML = '<figure class="icon">' + constants.EDIT + '</figure>';
|
||||
alias_btn.title = "Set Alias";
|
||||
|
||||
alias_btn.addEventListener('click', function() {
|
||||
|
@ -932,26 +1048,7 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
this.ffzRenderHistory();
|
||||
|
||||
// Reposition the menu if it's off-screen.
|
||||
var 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";
|
||||
}
|
||||
this.ffzReposition();
|
||||
|
||||
// Focus the Element
|
||||
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() {
|
||||
var t = this,
|
||||
Chat = utils.ember_lookup('controller:chat'),
|
||||
|
@ -1093,7 +1214,7 @@ FFZ.prototype.setup_mod_card = function() {
|
|||
logs = document.createElement('ul');
|
||||
back = document.createElement('button');
|
||||
|
||||
back.className = 'button back-button';
|
||||
back.className = 'button ffz-no-bg back-button';
|
||||
back.innerHTML = '« Back';
|
||||
|
||||
back.addEventListener('click', function() {
|
||||
|
@ -1184,7 +1305,7 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
|||
|
||||
|
||||
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
|
||||
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 : '';
|
||||
}
|
||||
|
||||
|
||||
// Update tab completion.
|
||||
if ( this._inputv )
|
||||
Ember.propertyDidChange(this._inputv, 'ffz_name_suggestions');
|
||||
|
||||
// TODO: Update conversations~
|
||||
}
|
||||
|
||||
|
|
|
@ -77,10 +77,10 @@ FFZ.prototype.setup_room = function() {
|
|||
this.set("showModerationCard", true);
|
||||
|
||||
// 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", {
|
||||
user: chan,
|
||||
renderTop: e.top,
|
||||
renderTop: e.real_top || e.top,
|
||||
renderLeft: e.left,
|
||||
renderBottom: e.bottom,
|
||||
renderRight: e.right,
|
||||
|
@ -171,6 +171,12 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
f._roomv = this;
|
||||
|
||||
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.
|
||||
this._ffz_mouse_down = this.ffzMouseDown.bind(this);
|
||||
|
@ -215,9 +221,43 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
if ( this._ffz_chat_display )
|
||||
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();
|
||||
},
|
||||
|
||||
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() {
|
||||
var room = this.get('controller.model'),
|
||||
el = this.get('element'),
|
||||
|
@ -273,8 +313,8 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
if ( ! messages )
|
||||
return;
|
||||
|
||||
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
|
||||
this._ffz_messages = messages;
|
||||
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
|
||||
|
||||
this._ffz_mouse_move = this.ffzMouseMove.bind(this);
|
||||
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
|
||||
|
@ -311,11 +351,8 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
},
|
||||
|
||||
ffzPulse: function() {
|
||||
if ( this.ffz_frozen ) {
|
||||
var elapsed = Date.now() - this._ffz_last_move;
|
||||
if ( elapsed > 750 )
|
||||
this.ffzUnfreeze();
|
||||
}
|
||||
if ( this.ffz_frozen && ! this.ffzShouldBeFrozen() )
|
||||
this.ffzUnfreeze();
|
||||
},
|
||||
|
||||
ffzUnfreeze: function(from_stuck) {
|
||||
|
@ -327,11 +364,17 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
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) {
|
||||
var t = this._$chatMessagesScroller;
|
||||
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;
|
||||
this._setStuckToBottom(10 >= r);
|
||||
}
|
||||
|
@ -341,29 +384,57 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
this._ffz_outside = true;
|
||||
var e = this;
|
||||
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();
|
||||
}
|
||||
}, 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) {
|
||||
// Store the last move time.
|
||||
this._ffz_last_move = Date.now();
|
||||
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;
|
||||
|
||||
// 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_screeny = event.screenY;
|
||||
|
||||
if ( this.ffz_frozen )
|
||||
return;
|
||||
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);
|
||||
|
||||
this.ffz_frozen = true;
|
||||
if ( this.get('stuckToBottom') ) {
|
||||
this.set('controller.model.messageBufferSize', f.settings.scrollback_length + 150);
|
||||
this.ffzWarnPaused();
|
||||
}
|
||||
// Should the state have changed?
|
||||
var should_freeze = this.ffzShouldBeFrozen(),
|
||||
freeze_change = this.ffz_frozen !== should_freeze;
|
||||
|
||||
if ( freeze_change )
|
||||
if ( should_freeze )
|
||||
this.ffzFreeze();
|
||||
else
|
||||
this.ffzUnfreeze();
|
||||
},
|
||||
|
||||
_scrollToBottom: _.throttle(function() {
|
||||
|
@ -400,7 +471,19 @@ FFZ.prototype._modify_rview = function(view) {
|
|||
if ( ! warning ) {
|
||||
warning = document.createElement('div');
|
||||
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');
|
||||
if ( ! cont )
|
||||
|
@ -923,8 +1006,10 @@ FFZ.prototype._modify_room = function(room) {
|
|||
user = f.get_user(),
|
||||
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();
|
||||
},
|
||||
|
@ -1284,6 +1369,31 @@ FFZ.prototype._modify_room = function(room) {
|
|||
|
||||
addMessage: function(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';
|
||||
|
||||
// Ignore whispers if conversations are enabled.
|
||||
|
@ -1291,7 +1401,7 @@ FFZ.prototype._modify_room = function(room) {
|
|||
return;
|
||||
|
||||
if ( ! is_whisper )
|
||||
msg.room = this.get('id');
|
||||
msg.room = room_id;
|
||||
|
||||
// Look up color and labels.
|
||||
if ( this.tmiRoom && msg.from ) {
|
||||
|
@ -1434,6 +1544,13 @@ FFZ.prototype._modify_room = function(room) {
|
|||
try {
|
||||
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 ) {
|
||||
// Command History
|
||||
var mru = this.get('mru_list'),
|
||||
|
|
|
@ -37,7 +37,7 @@ FFZ.msg_commands = {};
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 203,
|
||||
major: 3, minor: 5, revision: 216,
|
||||
toString: function() {
|
||||
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) )
|
||||
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.");
|
||||
|
||||
// Check for the player
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
}
|
||||
|
||||
|
||||
.ember-chat .chat-messages .chat-line.brick--marked { padding-left: 8px }
|
||||
|
||||
|
||||
/* Remove Extra Conversation Padding */
|
||||
.conversation-window .conversation-chat-lines {
|
||||
padding-top: 0;
|
||||
|
|
|
@ -16,3 +16,11 @@
|
|||
.chat-history .chat-line:before {
|
||||
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"),
|
||||
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.',
|
||||
|
||||
|
@ -160,6 +161,12 @@ FFZ.prototype.setup_tokenization = function() {
|
|||
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.");
|
||||
|
||||
var f = this;
|
||||
|
@ -395,6 +402,9 @@ FFZ.prototype.tokenize_conversation_line = function(message, prevent_notificatio
|
|||
if ( conv_helpers && conv_helpers.checkActionMessage )
|
||||
tokens = conv_helpers.checkActionMessage(tokens);
|
||||
|
||||
if ( emote_helpers )
|
||||
emotes = emote_helpers(emotes);
|
||||
|
||||
// Standard Tokenization
|
||||
if ( helpers && helpers.linkifyMessage )
|
||||
tokens = helpers.linkifyMessage(tokens);
|
||||
|
@ -775,8 +785,8 @@ FFZ.prototype.render_token = function(render_links, warn_links, token) {
|
|||
}
|
||||
|
||||
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 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 html-tooltip" title="${utils.quote_attr(token.text)}" data-text="${utils.sanitize(token.text)}">×××</span>`;
|
||||
|
||||
else if ( token.type === "mention" )
|
||||
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);
|
||||
|
||||
// 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();
|
||||
|
||||
this.log("Connecting to Live Streams model.");
|
||||
|
@ -163,10 +163,10 @@ FFZ.prototype._update_following_count = function() {
|
|||
|
||||
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();
|
||||
|
||||
if ( Live )
|
||||
if ( ! this.is_dashboard && Live )
|
||||
Live.load();
|
||||
else {
|
||||
var u = this.get_user();
|
||||
|
|
|
@ -612,9 +612,9 @@ FFZ.menu_pages.channel = {
|
|||
unlock_text.innerHTML = "Subscribe to unlock Emoticons";
|
||||
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.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);
|
||||
|
||||
inner.appendChild(sub_message);
|
||||
|
|
|
@ -116,7 +116,7 @@ FFZ.prototype.rebuild_race_ui = function() {
|
|||
race_container.setAttribute('data-channel', channel_id);
|
||||
|
||||
var btn = document.createElement('span');
|
||||
btn.className = 'button drop action';
|
||||
btn.className = 'button button--text button--dropmenu';
|
||||
btn.title = "SpeedRunsLive Race";
|
||||
btn.innerHTML = '<span class="logo"></span>';
|
||||
|
||||
|
@ -148,7 +148,7 @@ FFZ.prototype.rebuild_race_ui = function() {
|
|||
race_container.setAttribute('data-channel', hosted_id);
|
||||
|
||||
var btn = document.createElement('span');
|
||||
btn.className = 'button drop action';
|
||||
btn.className = 'button button--text button--dropmenu';
|
||||
btn.title = "SpeedRunsLive Race";
|
||||
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.
|
||||
// Of course, we should just rewrite logic to not constantly mutilate
|
||||
// rows.
|
||||
jQuery('.tooltip', tbody).trigger('mouseout');
|
||||
jQuery('.html-tooltip', tbody).trigger('mouseout');
|
||||
|
||||
tbody.innerHTML = '';
|
||||
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>' : '',
|
||||
time = elapsed ? utils.time_to_string(ent.time||elapsed) : "",
|
||||
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 ) {
|
||||
this._race_game = race.game;
|
||||
this._race_goal = race.goal;
|
||||
|
||||
var game = utils.sanitize(race.game),
|
||||
var game = utils.quote_san(race.game),
|
||||
goal = utils.unquote_attr(race.goal),
|
||||
old_goal = popup.getAttribute('data-old-goal');
|
||||
|
||||
if ( goal !== old_goal ) {
|
||||
popup.setAttribute('data-old-goal', goal);
|
||||
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, ">");
|
||||
},
|
||||
|
||||
quote_san = function(msg) {
|
||||
return sanitize(msg).replace(R_QUOTE, """).replace(R_SQUOTE, "'");
|
||||
},
|
||||
|
||||
HUMAN_NUMBERS = [
|
||||
"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);
|
||||
|
||||
try {
|
||||
input.focus();
|
||||
} catch(err) { }
|
||||
|
||||
form.addEventListener('submit', 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 });
|
||||
|
@ -423,6 +431,7 @@ module.exports = FFZ.utils = {
|
|||
sanitize: sanitize,
|
||||
unquote_attr: unquote_attr,
|
||||
quote_attr: quote_attr,
|
||||
quote_san: quote_san,
|
||||
|
||||
date_string: function(date) {
|
||||
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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
|
@ -336,6 +336,8 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
|||
|
||||
/* SRL Race Support */
|
||||
|
||||
#ffz-ui-host-button { vertical-align: middle }
|
||||
|
||||
#ffz-following-popup.right {
|
||||
right: 0;
|
||||
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 {
|
||||
padding-left: 44px;
|
||||
margin-bottom: -10px;
|
||||
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 {
|
||||
margin: 0;
|
||||
padding: 0 5px;
|
||||
color: #6441a4;
|
||||
}
|
||||
|
||||
.ffz-moderation-card .mod-controls button figure { padding: 0 }
|
||||
|
||||
.ember-chat .ffz-moderation-card .mod-controls button {
|
||||
width: auto;
|
||||
margin-right: 10px;
|
||||
|
@ -1306,10 +1312,13 @@ img.channel_background[src="null"] { display: none; }
|
|||
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(.glyph-only):focus {
|
||||
.ffz-moderation-card button:not(.button--icon-only):hover,
|
||||
.ffz-moderation-card button:not(.button--icon-only):focus {
|
||||
color: #fff;
|
||||
background-color: rgba(117,80,186, 1);
|
||||
}
|
||||
|
@ -1404,6 +1413,13 @@ img.channel_background[src="null"] { display: none; }
|
|||
|
||||
/* 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; }
|
||||
|
||||
.ember-chat .chat-messages .chat-line.ffz-has-deleted {
|
||||
|
@ -1720,7 +1736,7 @@ th.ffz-row-switch {
|
|||
margin-right: 4px;
|
||||
}
|
||||
|
||||
#ffz-group-tabs .button.glyph-only svg {
|
||||
#ffz-group-tabs .button.button--icon-only svg {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
|
@ -2216,6 +2232,14 @@ body:not([data-current-path^="user."]) .ffz-sidebar-swap .ember-chat .chat-inter
|
|||
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__item--anchor,
|
||||
.ffz-no-blue .warp__drawer,
|
||||
|
@ -2966,6 +2990,14 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
background-size: 100%
|
||||
}*/
|
||||
|
||||
/* Button Fix */
|
||||
|
||||
.ffz-no-bg {
|
||||
background: transparent;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Odd Badges */
|
||||
.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);
|
||||
}
|
||||
|
||||
.badge.warcraft.version-protoss {
|
||||
background: url("https://cdn.frankerfacez.com/badges/twitch/warcraft/protoss/1.png") #5bc7ff;
|
||||
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);
|
||||
|
||||
/* New Resub Banner */
|
||||
|
||||
.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