mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-02 16:08:31 +00:00
3.5.319. More logviewer integration. Notes work now. Clean up colored badges a bit more. Fix for incorrect player height. Modify chat lines the new, improved way. Load user <-> emote set mappings from the API. Fix legacy badges not showing correctly. Remove negative margins from chat lines. Add a line saying a sub is a Twitch Prime sub to the FFZ menu. Dark theme CSS tweaks.
This commit is contained in:
parent
d02f87528d
commit
9ddfabb1b1
16 changed files with 723 additions and 581 deletions
|
@ -1,3 +1,24 @@
|
|||
<div class="list-header">3.5.319 <time datetime="2016-10-03">(2016-10-07)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Added: Load emote set <-> user mappings from the API.</li>
|
||||
<li>Added: Logviewer integration now supports notes.</li>
|
||||
<li>Changed: Simplify CSS for chat lines just a bit. No more negative margins.</li>
|
||||
<li>Changed: Minor CSS tweaks.</li>
|
||||
<li>Fixed: Legacy badges got broken when I added colored badges.</li>
|
||||
</ul>
|
||||
|
||||
<div class="list-header">3.5.318 <time datetime="2016-10-03">(2016-10-06)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Fixed: Twitch's player is still the wrong height. <em>**sigh**</em> Temporary fix.</li>
|
||||
</ul>
|
||||
|
||||
<div class="list-header">3.5.317 <time datetime="2016-10-03">(2016-10-05)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Fixed: More tweaks to Transparent (Color) badge rendering to make sure all badges are rendered correctly.</li>
|
||||
<li> </li>
|
||||
<li>Let's be honest, a release just isn't a release without a pair of immediate bugfixes, am I right?</li>
|
||||
</ul>
|
||||
|
||||
<div class="list-header">3.5.316 <time datetime="2016-10-03">(2016-10-05)</time></div>
|
||||
<ul class="chat-menu-content menu-side-padding">
|
||||
<li>Fixed: Prime emotes aren't sub emotes, tab-completion. Stop being silly.</li>
|
||||
|
|
|
@ -492,19 +492,20 @@ FFZ.prototype.render_badges = function(badges) {
|
|||
for(var key in badges) {
|
||||
var badge = badges[key],
|
||||
klass = badge.klass,
|
||||
css = '';
|
||||
css = '',
|
||||
is_colored = !(badge.no_color !== undefined ? badge.no_color : badge.transparent);
|
||||
|
||||
if ( badge.image )
|
||||
if ( setting === 6 )
|
||||
if ( is_colored && setting === 6 )
|
||||
css += '-webkit-mask-image:url("' + utils.quote_attr(badge.image) + '");';
|
||||
else
|
||||
css += 'background-image:url("' + utils.quote_attr(badge.image) + '");';
|
||||
|
||||
if ( badge.srcSet && setting !== 6 )
|
||||
if ( badge.srcSet && (setting !== 6 || !is_colored) )
|
||||
css += 'background-image:-webkit-image-set(' + badge.srcSet + ');background-image:image-set(' + badge.srcSet + ');'
|
||||
|
||||
if ( badge.color )
|
||||
if ( setting === 6 )
|
||||
if ( is_colored && setting === 6 )
|
||||
css += 'background: linear-gradient(' + badge.color + ',' + badge.color + ');';
|
||||
else
|
||||
css += 'background-color:' + badge.color + ';'
|
||||
|
@ -521,7 +522,7 @@ FFZ.prototype.render_badges = function(badges) {
|
|||
if ( badge.invert_invert )
|
||||
klass += ' invert-invert';
|
||||
|
||||
if ( ! badge.no_color && setting === 6 )
|
||||
if ( is_colored && setting === 6 )
|
||||
klass += ' colored';
|
||||
|
||||
if ( badge.transparent )
|
||||
|
|
|
@ -222,7 +222,7 @@ FFZ.prototype.setup_layout = function() {
|
|||
height = size[1],
|
||||
host_height = size[2];
|
||||
|
||||
return "<style>.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .dynamic-target-player,.dynamic-target-player object, .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object, .dynamic-player .player video{width:100% !important; height:100% !important}</style>";
|
||||
return "<style>.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .cn-hosted .dynamic-target-player,.cn-hosted .dynamic-target-player object, .cn-hosted .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object, .dynamic-player .player video{width:100% !important; height:100% !important}</style>";
|
||||
}.property("playerSize"),
|
||||
|
||||
ffzPortraitWarning: function() {
|
||||
|
|
|
@ -661,7 +661,12 @@ FFZ.prototype.setup_line = function() {
|
|||
if ( Line )
|
||||
this._modify_chat_line(Line);*/
|
||||
|
||||
this.log("Hooking the Ember VOD Chat Line component.");
|
||||
|
||||
this.update_views('component:vod-chat-line', this._modify_vod_line);
|
||||
this.update_views('component:chat/message-line', this._modify_chat_subline);
|
||||
this.update_views('component:chat/whisper-line', this._modify_chat_subline);
|
||||
|
||||
/*this.log("Hooking the Ember VOD Chat Line component.");
|
||||
var VOD = utils.ember_resolve('component:vod-chat-line');
|
||||
if ( VOD )
|
||||
this._modify_vod_line(VOD);
|
||||
|
@ -681,7 +686,7 @@ FFZ.prototype.setup_line = function() {
|
|||
if ( WLine )
|
||||
this._modify_chat_subline(WLine);
|
||||
else
|
||||
this.error("Couldn't find the Whisper Line component.");
|
||||
this.error("Couldn't find the Whisper Line component.");*/
|
||||
|
||||
|
||||
// Store the capitalization of our own name.
|
||||
|
|
|
@ -660,6 +660,9 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
this._lv_sock_user = null;
|
||||
}
|
||||
|
||||
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')));
|
||||
|
@ -748,41 +751,79 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
|
||||
lvOnMessage: function(cmd, data) {
|
||||
//f.log("[LV] Socket Message: " + cmd, data)
|
||||
// Make sure:
|
||||
// 1) It's a log-add command.
|
||||
// 2) We have logs loaded already.
|
||||
// 3) The loaded logs are for this user.
|
||||
if ( cmd !== 'log-add' || ! this._lv_logs || ! this._lv_logs.data || data.nick !== this._lv_logs.data.user.nick )
|
||||
return;
|
||||
if ( cmd === "comment-add" ) {
|
||||
if ( data.topic !== this.get('cardInfo.user.id') )
|
||||
return;
|
||||
|
||||
// Parse the message. Store the data.
|
||||
var t,
|
||||
message = f.lv_parse_message(data);
|
||||
this._lv_logs.data.before.push(message);
|
||||
this._lv_logs.data.user[message.is_ban ? 'timeouts' : 'messages'] += 1;
|
||||
FFZ.mod_card_pages.notes.add_note.call(f, this, this.get('element'), data);
|
||||
|
||||
// If we're viewing the chat history, update it.
|
||||
var el = this.get('element'),
|
||||
container = el && el.querySelector('.ffz-tab-container'),
|
||||
history = container && container.querySelector('.chat-history.lv-history');
|
||||
} else if ( cmd === "comment-update" ) {
|
||||
var el = this.get('element'),
|
||||
line = el && el.querySelector('.user-notes .chat-line[data-lv-id="' + data.id + '"]');
|
||||
|
||||
if ( history ) {
|
||||
var was_at_bottom = history.scrollTop >= (history.scrollHeight - history.clientHeight),
|
||||
last_line = history.querySelector('.chat-line:last-of-type'),
|
||||
ll_date = last_line && last_line.getAttribute('data-date'),
|
||||
date = message.date.toLocaleDateString();
|
||||
if ( ! line )
|
||||
return;
|
||||
|
||||
if ( last_line && ll_date !== date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
var new_line = FFZ.mod_card_pages.notes.build_note.call(f, this, data);
|
||||
line.outerHTML = new_line.outerHTML;
|
||||
|
||||
} else if ( cmd === "comment-delete" ) {
|
||||
var el = this.get('element'),
|
||||
line = el && el.querySelector('.user-notes .chat-line[data-lv-id="' + data.id + '"]');
|
||||
|
||||
if ( ! line )
|
||||
return;
|
||||
|
||||
// If we're the only message on this date, remove the timestamp line.
|
||||
var before_line = line.previousElementSibling,
|
||||
after_line = line.nextElementSibling;
|
||||
|
||||
if ( before_line && before_line.classList.contains('timestamp-line') &&
|
||||
(! after_line || after_line.classList.contains('timestamp-line')) )
|
||||
before_line.parentElement.removeChild(before_line);
|
||||
|
||||
// Remove the line itself.
|
||||
line.parentElement.removeChild(line);
|
||||
|
||||
} else if ( cmd === "log-add" ) {
|
||||
if ( ! this._lv_logs || ! this._lv_logs.data || data.nick !== this._lv_logs.data.user.nick )
|
||||
return;
|
||||
|
||||
// Parse the message. Store the data.
|
||||
var t,
|
||||
message = f.lv_parse_message(data);
|
||||
this._lv_logs.data.before.push(message);
|
||||
this._lv_logs.data.user[message.is_ban ? 'timeouts' : 'messages'] += 1;
|
||||
|
||||
// If we're viewing the chat history, update it.
|
||||
var el = this.get('element'),
|
||||
container = el && el.querySelector('.ffz-tab-container'),
|
||||
history = container && container.querySelector('.chat-history.lv-history');
|
||||
|
||||
if ( history ) {
|
||||
var was_at_bottom = history.scrollTop >= (history.scrollHeight - history.clientHeight),
|
||||
last_line = history.querySelector('.chat-line:last-of-type'),
|
||||
ll_date = last_line && last_line.getAttribute('data-date'),
|
||||
date = message.date.toLocaleDateString();
|
||||
|
||||
if ( last_line.classList.contains('no-messages') ) {
|
||||
last_line.parentElement.removeChild(last_line);
|
||||
last_line = null;
|
||||
ll_date = null;
|
||||
}
|
||||
|
||||
if ( last_line && ll_date !== date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
}
|
||||
|
||||
history.appendChild(f._build_mod_card_history(message, this, false,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, t, container, message)));
|
||||
|
||||
if ( was_at_bottom )
|
||||
setTimeout(function() { history.scrollTop = history.scrollHeight; })
|
||||
}
|
||||
|
||||
history.appendChild(f._build_mod_card_history(message, this, false,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, t, container, message)));
|
||||
|
||||
if ( was_at_bottom )
|
||||
setTimeout(function() { history.scrollTop = history.scrollHeight; })
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -862,7 +903,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
|
||||
// Should we be requesting a token? How about access levels?
|
||||
if ( f.settings.logviewer_test && ffz_room.has_logs )
|
||||
if ( ! ffz_room.logviewer_levels )
|
||||
if ( ! ffz_room.logviewer_levels || (user && user.login && ! ffz_room.logviewer_levels.me.valid ) )
|
||||
f.lv_get_token().then(function(token) {
|
||||
if ( ! token )
|
||||
return;
|
||||
|
@ -1009,12 +1050,13 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
handle_key = function(e) {
|
||||
var key = e.keyCode || e.which,
|
||||
is_meta = e.ctrlKey || e.altKey || e.metaKey,
|
||||
tag = e.target && e.target.tagName,
|
||||
user_id = controller.get('cardInfo.user.id'),
|
||||
is_mod = controller.get('cardInfo.isModeratorOrHigher'),
|
||||
room = utils.ember_lookup('controller:chat').get('currentRoom');
|
||||
|
||||
// We don't want modifier keys.'
|
||||
if ( is_meta )
|
||||
// We don't want modifier keys. Also don't override input to input elements.
|
||||
if ( is_meta || tag === 'TEXTAREA' || tag === 'INPUT')
|
||||
return;
|
||||
|
||||
if ( key === keycodes.C )
|
||||
|
@ -1244,7 +1286,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
|
||||
for(var page_id in FFZ.mod_card_pages) {
|
||||
var page = FFZ.mod_card_pages[page_id];
|
||||
if ( page && page.title && (page_id !== 'history' || f.settings.mod_card_history) ) {
|
||||
if ( page && page.title ) {
|
||||
var tab = utils.createElement('li', 'item', page.title);
|
||||
if ( page_id === 'default' )
|
||||
tab.classList.add('active');
|
||||
|
@ -1264,16 +1306,8 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
el.classList.add('ffz-default-tab');
|
||||
|
||||
// Message History
|
||||
if ( f.settings.mod_card_history ) {
|
||||
var history = utils.createElement('ul', 'interface chat-history live-history');
|
||||
el.appendChild(history);
|
||||
|
||||
var chat_history = ffz_room.user_history && ffz_room.user_history[user_id] || [];
|
||||
for(var i=0; i < chat_history.length; i++)
|
||||
history.appendChild(f._build_mod_card_history(chat_history[i], t, false));
|
||||
|
||||
setTimeout(function(){history.scrollTop = history.scrollHeight;});
|
||||
}
|
||||
if ( f.settings.mod_card_history )
|
||||
this.ffzRenderHistory();
|
||||
|
||||
// Reposition the menu if it's off-screen.
|
||||
this.ffzReposition();
|
||||
|
@ -1336,187 +1370,33 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
|||
}
|
||||
}.observes('cardInfo.renderTop', 'cardInfo.renderLeft', 'cardInfo.renderRight', 'cardInfo.renderBottom'),
|
||||
|
||||
/*ffzRenderHistory: function() {
|
||||
ffzRenderHistory: function() {
|
||||
var t = this,
|
||||
Chat = utils.ember_lookup('controller:chat'),
|
||||
room = Chat && Chat.get('currentRoom'),
|
||||
delete_links = room && room.get('roomProperties.hide_chat_links'),
|
||||
tmiSession = room.tmiSession || (window.TMI && TMI._sessions && TMI._sessions[0]),
|
||||
room_id = room.get('id'),
|
||||
room_id = Chat && Chat.get('currentRoom.id'),
|
||||
user_id = this.get('cardInfo.user.id'),
|
||||
ffz_room = room && f.rooms && f.rooms[room_id],
|
||||
user_history = ffz_room && ffz_room.user_history && ffz_room.user_history[user_id] || [],
|
||||
ffz_room = f.rooms && f.rooms[room_id],
|
||||
chat_history = ffz_room && ffz_room.user_history && ffz_room.user_history[user_id] || [],
|
||||
|
||||
el = this.get('element'),
|
||||
|
||||
history = el && el.querySelector('.ffz-tab-container');
|
||||
|
||||
if ( history && ! history.classList.contains('chat-history') ) {
|
||||
history.parentElement.removeChild(history);
|
||||
history = null;
|
||||
}
|
||||
history = el.querySelector('.chat-history.live-history');
|
||||
|
||||
if ( ! history ) {
|
||||
history = utils.createElement('ul', 'interface clearfix ffz-tab-container chat-history');
|
||||
history = utils.createElement('ul', 'interface chat-history live-history');
|
||||
el.appendChild(history);
|
||||
} else {
|
||||
history.classList.remove('loading');
|
||||
} else
|
||||
history.innerHTML = '';
|
||||
}
|
||||
|
||||
/*if ( user_history.length < 50 ) {
|
||||
var before = (user_history.length > 0 && user_history[0].date ? user_history[0].date.getTime() : Date.now()) - (f._ws_server_offset || 0);
|
||||
f.ws_send("user_history", [room_id, user_id, 50 - user_history.length], function(success, data) {
|
||||
if ( ! success )
|
||||
return;
|
||||
for(var i=0; i < chat_history.length; i++)
|
||||
history.appendChild(f._build_mod_card_history(chat_history[i], t, false));
|
||||
|
||||
f.parse_history(data, null, null, room_id, delete_links, tmiSession);
|
||||
|
||||
var i = data.length,
|
||||
was_at_top = history && history.scrollTop >= (history.scrollHeight - history.clientHeight),
|
||||
first = true;
|
||||
|
||||
while(i--) {
|
||||
var msg = data[i];
|
||||
if ( ! msg )
|
||||
continue;
|
||||
|
||||
msg.from_server = true;
|
||||
|
||||
if ( ! msg.date || msg.date.getTime() >= before )
|
||||
continue;
|
||||
|
||||
if ( first ) {
|
||||
first = false;
|
||||
history.insertBefore(f._build_mod_card_history({
|
||||
date: msg.date,
|
||||
from: "jtv",
|
||||
style: "admin",
|
||||
cachedTokens: ["(Server History Above)"]
|
||||
}), history.firstElementChild);
|
||||
}
|
||||
|
||||
history.insertBefore(f._build_mod_card_history(msg, t), history.firstElementChild);
|
||||
}
|
||||
|
||||
if ( was_at_top )
|
||||
setTimeout(function() { history.scrollTop = history.scrollHeight; });
|
||||
});
|
||||
}*//*
|
||||
|
||||
for(var i=0; i < user_history.length; i++)
|
||||
history.appendChild(f._build_mod_card_history(user_history[i], t));
|
||||
|
||||
// Lazy scroll-to-bottom
|
||||
history.scrollTop = history.scrollHeight;
|
||||
},*/
|
||||
|
||||
/*ffzAdjacentHistory: function(line) {
|
||||
var Chat = utils.ember_lookup('controller:chat'),
|
||||
t = this,
|
||||
|
||||
user_id = this.get('cardInfo.user.id'),
|
||||
|
||||
room = Chat && Chat.get('currentRoom'),
|
||||
room_id = room.get('id'),
|
||||
delete_links = room && room.get('roomProperties.hide_chat_links'),
|
||||
|
||||
tmiSession = room.tmiSession || (window.TMI && TMI._sessions && TMI._sessions[0]),
|
||||
|
||||
el = this.get('element'),
|
||||
history = el && el.querySelector('.chat-history'),
|
||||
logs = el && el.querySelector('.chat-history.adjacent-history'),
|
||||
|
||||
when = line.date.getTime(),
|
||||
scroll_top = logs && logs.scrollTop || history && history.scrollTop || 0;
|
||||
|
||||
if ( ! history )
|
||||
return;
|
||||
|
||||
if ( logs ) {
|
||||
logs.classList.add('loading');
|
||||
logs.scrollTop = 0;
|
||||
} else {
|
||||
history.classList.add('loading');
|
||||
history.scrollTop = 0;
|
||||
}
|
||||
|
||||
if ( ! f.ws_send("adjacent_history", [room_id, when, 2], function(success, data) {
|
||||
var was_loading = history.classList.contains('loading');
|
||||
if ( logs ) {
|
||||
logs.classList.remove('loading');
|
||||
logs.scrollTop = scroll_top;
|
||||
} else {
|
||||
history.classList.remove('loading');
|
||||
history.scrollTop = scroll_top;
|
||||
}
|
||||
|
||||
if ( ! success || ! data || ! data.length || ! was_loading )
|
||||
return;
|
||||
|
||||
var had_logs = false,
|
||||
found_original = false,
|
||||
back;
|
||||
|
||||
if ( logs ) {
|
||||
had_logs = true;
|
||||
logs.innerHTML = '';
|
||||
|
||||
} else {
|
||||
logs = utils.createElement('ul', 'interface clearfix chat-history adjacent-history');
|
||||
back = utils.createElement('button', 'button ffz-no-bg back-button');
|
||||
|
||||
back.innerHTML = '« Back';
|
||||
|
||||
back.addEventListener('click', function() {
|
||||
logs.parentElement.removeChild(logs);
|
||||
back.parentElement.removeChild(back);
|
||||
history.classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
f.parse_history(data, null, null, room_id, delete_links, tmiSession, function(msg) {
|
||||
msg.from_server = true;
|
||||
|
||||
var line_time = line.date.getTime() - (line.from_server ? 0 : (f._ws_server_offset || 0)),
|
||||
is_original = ! found_original && Math.abs(line_time - msg.date.getTime()) < (line.from_server ? 50 : 1000) && line.from === msg.from && line.message === msg.message;
|
||||
|
||||
msg.original_sender = user_id === msg.from;
|
||||
msg.is_original = is_original;
|
||||
found_original = found_original || is_original;
|
||||
|
||||
logs.insertBefore(f._build_mod_card_history(msg, t, true), logs.firstElementChild);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
if ( ! had_logs ) {
|
||||
history.classList.add('hidden');
|
||||
history.parentElement.insertBefore(logs, history);
|
||||
history.parentElement.insertBefore(back, logs);
|
||||
}
|
||||
|
||||
if ( found_original )
|
||||
setTimeout(function(){
|
||||
el = logs.querySelector('.original-msg');
|
||||
if ( el )
|
||||
logs.scrollTop = (el.offsetTop - logs.offsetTop) - (logs.clientHeight - el.clientHeight) / 2;
|
||||
});
|
||||
|
||||
}) )
|
||||
if ( logs ) {
|
||||
logs.classList.remove('loading');
|
||||
logs.scrollTop = scroll_top;
|
||||
} else {
|
||||
history.classList.remove('loading');
|
||||
history.scrollTop = scroll_top;
|
||||
}
|
||||
}*/
|
||||
setTimeout(function(){history.scrollTop = history.scrollHeight});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from, ts_click) {
|
||||
FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from, ts_click, mod_icons) {
|
||||
var l_el = document.createElement('li'),
|
||||
out = [],
|
||||
f = this;
|
||||
|
@ -1529,6 +1409,13 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from, ts_cli
|
|||
var alias = this.aliases[msg.from],
|
||||
results = this.format_display_name(msg.tags && msg.tags['display-name'], msg.from);
|
||||
|
||||
if ( mod_icons ) {
|
||||
out.push('<span class="mod-icons">');
|
||||
if ( typeof mod_icons === "string" )
|
||||
out.push(mod_icons);
|
||||
out.push('</span>');
|
||||
}
|
||||
|
||||
if ( show_from ) {
|
||||
// Badges
|
||||
out.push('<span class="badges">');
|
||||
|
@ -1729,329 +1616,4 @@ FFZ.chat_commands.u = function(room, args) {
|
|||
}
|
||||
}
|
||||
|
||||
FFZ.chat_commands.u.enabled = function() { return this.settings.short_commands; }
|
||||
|
||||
// ----------------
|
||||
// Moderation Card Pages
|
||||
// ----------------
|
||||
|
||||
FFZ.mod_card_pages = {};
|
||||
|
||||
FFZ.mod_card_pages.default = {
|
||||
title: "<span>C</span>ontrols",
|
||||
render: function(mod_card, el) { }
|
||||
}
|
||||
|
||||
FFZ.mod_card_pages.history = {
|
||||
title: "Chat <span>H</span>istory",
|
||||
|
||||
render_more: function(mod_card, el, history, ref_id, is_user, is_after) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
|
||||
btn_more = utils.createElement('li', 'button ffz-load-more' + (is_after ? ' load-after' : ''), '<span class="ffz-chevron"></span> Load More <span class="ffz-chevron"></span>');
|
||||
|
||||
if ( is_after )
|
||||
history.appendChild(btn_more);
|
||||
else
|
||||
history.insertBefore(btn_more, history.firstElementChild);
|
||||
|
||||
btn_more.addEventListener('click', function() {
|
||||
history.scrollTop = 0;
|
||||
history.classList.add('loading');
|
||||
f.lv_get_logs(room_id, is_user ? user_id : null, ref_id, is_after ? 0 : 10, is_after ? 10 : 0).then(function(data) {
|
||||
history.removeChild(btn_more);
|
||||
history.classList.remove('loading');
|
||||
|
||||
var messages = is_after ? data.after : data.before,
|
||||
last_message = history.querySelector('.chat-line:' + (is_after ? 'last' : 'first') + '-of-type'),
|
||||
last_date = last_message ? last_message.getAttribute('data-date') : (new Date).toLocaleDateString();
|
||||
|
||||
if ( last_message.classList.contains('timestamp-line') )
|
||||
last_message.parentElement.removeChild(last_message);
|
||||
|
||||
if ( ! is_after )
|
||||
messages.reverse();
|
||||
|
||||
var original_message = history.querySelector('.original-msg'),
|
||||
original_sender = original_message && original_message.getAttribute('data-sender');
|
||||
|
||||
for(var i=0; i < messages.length; i++) {
|
||||
var new_message = messages[i],
|
||||
date = new_message.date.toLocaleDateString(),
|
||||
date_line = null;
|
||||
|
||||
new_message.original_sender = original_sender === new_message.from;
|
||||
|
||||
var new_line = f._build_mod_card_history(
|
||||
new_message, mod_card, !is_user,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, mod_card, el, new_message)
|
||||
);
|
||||
|
||||
if ( is_user )
|
||||
new_line.classList.remove('ffz-mentioned');
|
||||
|
||||
new_message.original_sender = null;
|
||||
|
||||
if ( last_date !== date ) {
|
||||
date_line = utils.createElement('li', 'chat-line timestamp-line', is_after ? date : last_date);
|
||||
date_line.setAttribute('data-date', is_after ? date : last_date);
|
||||
last_date = date;
|
||||
if ( is_after )
|
||||
history.appendChild(date_line);
|
||||
else
|
||||
history.insertBefore(date_line, history.firstElementChild);
|
||||
}
|
||||
|
||||
if ( is_after )
|
||||
history.appendChild(new_line);
|
||||
else
|
||||
history.insertBefore(new_line, history.firstElementChild);
|
||||
}
|
||||
|
||||
if ( ! is_after && last_date !== (new Date).toLocaleDateString() ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', last_date);
|
||||
date_line.setAttribute('data-date', last_date);
|
||||
history.insertBefore(date_line, history.firstElementChild);
|
||||
}
|
||||
|
||||
// Only add the button back if there are even more messages to load.
|
||||
if ( messages.length >= 10 )
|
||||
if ( is_after )
|
||||
history.appendChild(btn_more);
|
||||
else
|
||||
history.insertBefore(btn_more, history.firstElementChild);
|
||||
|
||||
var original = history.querySelector('.chat-line[data-lv-id="' + ref_id + '"]');
|
||||
if ( original )
|
||||
setTimeout(function() {
|
||||
history.scrollTop = (original.offsetTop - history.offsetTop) - (history.clientHeight - original.clientHeight) / 2;
|
||||
});
|
||||
|
||||
ref_id = messages[messages.length-1].lv_id;
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
render_adjacent: function(mod_card, el, message) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
ffz_room = this.rooms[room_id],
|
||||
|
||||
old_history = el.querySelector('.chat-history'),
|
||||
history = el.querySelector('.adjacent-history');
|
||||
|
||||
old_history.classList.add('hidden');
|
||||
|
||||
if ( history )
|
||||
history.innerHTML = '';
|
||||
else {
|
||||
var btn_hide = utils.createElement('li', 'button ffz-back-button', '<span class="ffz-chevron"></span> Back'),
|
||||
btn_container = utils.createElement('ul', 'interface chat-history chat-back-button', btn_hide);
|
||||
|
||||
btn_hide.addEventListener('click', function() {
|
||||
el.removeChild(history);
|
||||
el.removeChild(btn_container);
|
||||
old_history.classList.remove('hidden');
|
||||
})
|
||||
|
||||
history = utils.createElement('ul', 'interface chat-history adjacent-history');
|
||||
el.appendChild(btn_container);
|
||||
el.appendChild(history);
|
||||
}
|
||||
|
||||
history.classList.add('loading');
|
||||
|
||||
f.lv_get_logs(room_id, null, message.lv_id, 10, 10).then(function(data) {
|
||||
history.classList.remove('loading');
|
||||
|
||||
// Should we display more?
|
||||
if ( data.before.length >= 10 )
|
||||
FFZ.mod_card_pages.history.render_more.call(
|
||||
f, mod_card, el, history, data.before[0].lv_id, false, false);
|
||||
|
||||
var last_date = (new Date).toLocaleDateString(),
|
||||
messages = _.union(data.before, [message], data.after);
|
||||
|
||||
for(var i=0; i < messages.length; i++) {
|
||||
var new_message = messages[i],
|
||||
date = new_message.date.toLocaleDateString();
|
||||
|
||||
if ( date !== last_date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
last_date = date;
|
||||
}
|
||||
|
||||
new_message.is_original = new_message.lv_id === message.lv_id;
|
||||
new_message.original_sender = new_message.from === message.from;
|
||||
|
||||
var msg_line = f._build_mod_card_history(new_message, mod_card, true,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, mod_card, el, new_message));
|
||||
|
||||
if ( new_message.is_original )
|
||||
msg_line.classList.remove('ffz-mentioned');
|
||||
|
||||
history.appendChild(msg_line);
|
||||
|
||||
// These objects can be persistent, so clear these.
|
||||
new_message.is_original = null;
|
||||
new_message.original_sender = null;
|
||||
}
|
||||
|
||||
if ( data.after.length >= 10 )
|
||||
FFZ.mod_card_pages.history.render_more.call(
|
||||
f, mod_card, el, history, data.after[data.after.length-1].lv_id, false, true);
|
||||
|
||||
setTimeout(function() {
|
||||
var original = history.querySelector('.original-msg');
|
||||
if ( original )
|
||||
history.scrollTop = (original.offsetTop - history.offsetTop) - (history.clientHeight - original.clientHeight) / 2;
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
render: function(mod_card, el) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
ffz_room = this.rooms[room_id],
|
||||
|
||||
history = utils.createElement('ul', 'interface chat-history lv-history');
|
||||
|
||||
el.appendChild(history);
|
||||
|
||||
// Are we relying on LogViewer here?
|
||||
if ( ! ffz_room.has_logs || ! mod_card.lv_view ) {
|
||||
history.innerHTML = '<li class="chat-line admin"><span class="message">You do not have permission to view chat history in this channel.</span></li>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Start loading!
|
||||
history.classList.add('loading');
|
||||
|
||||
mod_card.lvGetLogs().then(function(data) {
|
||||
f.log("[LV] Logs: " + user_id + " in " + room_id, data);
|
||||
history.classList.remove('loading');
|
||||
|
||||
// Should we display more?
|
||||
if ( data.before.length >= 10 )
|
||||
FFZ.mod_card_pages.history.render_more.call(
|
||||
f, mod_card, el, history, data.before[0].lv_id, true, false);
|
||||
|
||||
var last_date = (new Date).toLocaleDateString();
|
||||
|
||||
for(var i=0; i < data.before.length; i++) {
|
||||
var message = data.before[i],
|
||||
date = message.date.toLocaleDateString();
|
||||
|
||||
if ( date !== last_date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
last_date = date;
|
||||
}
|
||||
|
||||
var msg_line = f._build_mod_card_history(message, mod_card, false,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, mod_card, el, message));
|
||||
|
||||
msg_line.classList.remove('ffz-mentioned');
|
||||
history.appendChild(msg_line);
|
||||
}
|
||||
|
||||
history.scrollTop = history.scrollHeight;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
FFZ.mod_card_pages.stats = {
|
||||
title: "<span>S</span>tatistics",
|
||||
render: function(mod_card, el) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
ffz_room = f.rooms && f.rooms[room_id];
|
||||
|
||||
var container = utils.createElement('ul', 'interface version-list');
|
||||
el.appendChild(container);
|
||||
|
||||
if ( ffz_room.has_logs && mod_card.lv_view ) {
|
||||
container.classList.add('loading');
|
||||
|
||||
mod_card.lvGetLogs().then(function(data) {
|
||||
container.classList.remove('loading');
|
||||
container.innerHTML = '<li>Messages <span>' + utils.number_commas(data.user.messages) + '</span></li><li>Timeouts <span> ' + utils.number_commas(data.user.timeouts) + '</span></li>';
|
||||
});
|
||||
|
||||
var notice = utils.createElement('div', 'interface');
|
||||
notice.innerHTML = 'Chat Log Source: <a target="_blank" href="https://cbenni.com/' + room_id + '?user=' + user_id + '">CBenni\'s logviewer</a>';
|
||||
el.appendChild(notice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FFZ.mod_card_pages.notes = {
|
||||
title: "<span>N</span>otes",
|
||||
render: function(mod_card, el) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
room = controller && controller.get('currentRoom'),
|
||||
tmiSession = room.tmiSession || (window.TMI && TMI._sessions && TMI._sessions[0]),
|
||||
|
||||
room_id = room && room.get('id'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
|
||||
ffz_room = this.rooms[room_id],
|
||||
history = utils.createElement('ul', 'interface chat-history user-notes');
|
||||
|
||||
|
||||
el.appendChild(history);
|
||||
|
||||
if ( ! ffz_room.has_logs || ! mod_card.lv_view_notes ) {
|
||||
history.innerHTML = '<li class="chat-line admin"><span class="message">You do not have permission to view notes in this channel.</span></li>';
|
||||
return;
|
||||
}
|
||||
|
||||
history.classList.add('loading');
|
||||
|
||||
this.lv_get_token().then(function(token) {
|
||||
utils.logviewer.get("comments/" + room_id + "?topic=" + user_id, token)
|
||||
.then(utils.json).then(function(data) {
|
||||
|
||||
f.log("[LV] Comments: " + user_id + " in " + room_id, data);
|
||||
history.classList.remove('loading');
|
||||
|
||||
if ( data.length )
|
||||
for(var i=0; i < data.length; i++) {
|
||||
var raw = data[i],
|
||||
msg = {
|
||||
date: new Date(raw.added * 1000),
|
||||
from: raw.author,
|
||||
room: raw.channel,
|
||||
lv_id: raw.id,
|
||||
message: raw.text,
|
||||
tags: {},
|
||||
color: tmiSession && raw.author ? tmiSession.getColor(raw.author) : "#755000"
|
||||
};
|
||||
|
||||
f.tokenize_chat_line(msg, true, false);
|
||||
history.appendChild(f._build_mod_card_history(msg, mod_card, true));
|
||||
}
|
||||
else
|
||||
history.appendChild(utils.createElement('li', 'chat-line message-line admin',
|
||||
'<span class="message">There are no notes on this user.</span>'));
|
||||
|
||||
history.appendChild(utils.createElement('li', 'chat-line message-line admin',
|
||||
'<span clss="message">Create notes for this user at <a target="_blank" href="https://cbenni.com/' + room_id + '?user=' + user_id + '">CBenni\'s logviewer.</a></span>'));
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
FFZ.chat_commands.u.enabled = function() { return this.settings.short_commands; }
|
|
@ -301,6 +301,9 @@ FFZ.prototype.load_global_sets = function(callback, tries) {
|
|||
gs.push(key);
|
||||
f._load_set_json(key, undefined, set);
|
||||
}
|
||||
|
||||
f._load_set_users(data.users);
|
||||
|
||||
}).fail(function(data) {
|
||||
if ( data.status == 404 )
|
||||
return typeof callback == "function" && callback(false);
|
||||
|
@ -315,11 +318,33 @@ FFZ.prototype.load_global_sets = function(callback, tries) {
|
|||
}
|
||||
|
||||
|
||||
FFZ.prototype._load_set_users = function(data) {
|
||||
if ( data )
|
||||
for(var set_id in data)
|
||||
if ( data.hasOwnProperty(set_id) ) {
|
||||
var emote_set = this.emote_sets[set_id],
|
||||
users = data[set_id];
|
||||
|
||||
for(var i=0; i < users.length; i++) {
|
||||
var user = users[i],
|
||||
ud = this.users[user] = this.users[user] || {},
|
||||
sets = ud.sets = ud.sets || [];
|
||||
|
||||
if ( sets.indexOf(set_id) === -1 )
|
||||
sets.push(set_id);
|
||||
}
|
||||
|
||||
this.log('Added "' + (emote_set ? emote_set.title : set_id) + '" emote set to ' + utils.number_commas(users.length) + ' users.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FFZ.prototype.load_set = function(set_id, callback, tries) {
|
||||
var f = this;
|
||||
jQuery.getJSON(constants.API_SERVER + "v1/set/" + set_id)
|
||||
.done(function(data) {
|
||||
f._load_set_json(set_id, callback, data && data.set);
|
||||
f._load_set_users(data.users);
|
||||
|
||||
}).fail(function(data) {
|
||||
if ( data.status == 404 )
|
||||
|
|
|
@ -34,7 +34,7 @@ FFZ.msg_commands = {};
|
|||
|
||||
// Version
|
||||
var VER = FFZ.version_info = {
|
||||
major: 3, minor: 5, revision: 316,
|
||||
major: 3, minor: 5, revision: 319,
|
||||
toString: function() {
|
||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
.badges .moderator:not(.colored) {
|
||||
.badges .badge.moderator.version-1:not(.colored) {
|
||||
background-color: #068c10;
|
||||
background-image: url('//cdn.frankerfacez.com/script/legacy-mod.png');
|
||||
}
|
||||
|
||||
.badges .moderator.colored {
|
||||
.badges .badge.moderator.version-1.colored {
|
||||
background: linear-gradient(#068c10,#068c10);
|
||||
-webkit-mask-image: url('//cdn.frankerfacez.com/script/legacy-mod.png');
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
.badges .turbo:not(.colored) {
|
||||
.badges .badge.turbo.version-1:not(.colored) {
|
||||
background-color: #6441a3;
|
||||
background-image: url('//cdn.frankerfacez.com/script/legacy-turbo.png');
|
||||
}
|
||||
|
||||
.badges .turbo.colored {
|
||||
.badges .badge.turbo.version-1.colored {
|
||||
background: linear-gradient(#6441a3,#6441a3);
|
||||
-webkit-mask-image: url('//cdn.frankerfacez.com/script/legacy-turbo.png');
|
||||
}
|
|
@ -1,29 +1,29 @@
|
|||
.badges .staff:not(.colored) {
|
||||
.badges .badge.staff.version-1:not(.colored) {
|
||||
background-color: #6441a5;
|
||||
background-image: url('//cdn.frankerfacez.com/script/legacy-staff.png');
|
||||
}
|
||||
|
||||
.badges .staff.colored {
|
||||
.badges .badge.staff.version-1.colored {
|
||||
background: linear-gradient(#6441a5,#6441a5);
|
||||
-webkit-mask-image: url('//cdn.frankerfacez.com/script/legacy-staff.png');
|
||||
}
|
||||
|
||||
.badges .broadcaster:not(.colored) {
|
||||
.badges .badge.broadcaster.version-1:not(.colored) {
|
||||
background-color: #000;
|
||||
background-image: url('//cdn.frankerfacez.com/script/legacy-broadcaster.png');
|
||||
}
|
||||
|
||||
.badges .broadcaster.colored {
|
||||
.badges .badge.broadcaster.version-1.colored {
|
||||
background: linear-gradient(#e71818,#e71818);
|
||||
-webkit-mask-image: url('//cdn.frankerfacez.com/script/legacy-broadcaster.png');
|
||||
}
|
||||
|
||||
.badges .admin:not(.colored) {
|
||||
.badges .badge.admin.version-1:not(.colored) {
|
||||
background-color: #ff0303;
|
||||
background-image: url('//cdn.frankerfacez.com/script/legacy-admin.png');
|
||||
}
|
||||
|
||||
.badges .admin.colored {
|
||||
.badges .badge.admin.version-1.colored {
|
||||
background: linear-gradient(#ff0303,#ff0303);
|
||||
-webkit-mask-image: url('//cdn.frankerfacez.com/script/legacy-admin.png');
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
.conversation-window .conversation-system-messages,
|
||||
.conversation-window .conversation-chat-line,
|
||||
.conversation-window .timestamp-line {
|
||||
padding: 5px;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
position: absolute;
|
||||
z-index: -1;
|
||||
left: 0; right: 0;
|
||||
top: 2px; bottom: 1px;
|
||||
}
|
||||
|
||||
.chat-history .chat-line:before {
|
||||
top: 0; bottom: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@ FFZ.prototype.lv_get_token = function() {
|
|||
now = Date.now() / 1000;
|
||||
|
||||
return new Promise(function(succeed, fail) {
|
||||
// If we're not logged in, we can't get a token.
|
||||
var user = f.get_user();
|
||||
if ( ! user || ! user.login )
|
||||
return fail(null);
|
||||
|
||||
// Make sure the token will be valid for at least 5 more minutes.
|
||||
if ( token.token && token.expires > (now + 300) )
|
||||
return succeed(token.token);
|
||||
|
@ -38,6 +43,9 @@ FFZ.prototype.lv_get_token = function() {
|
|||
requests[i][succeeded ? 0 : 1](token.token);
|
||||
}
|
||||
|
||||
if ( succeeded && f._lv_ws_open )
|
||||
f._lv_ws_sock.send('42' + JSON.stringify(["token", token]));
|
||||
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
@ -143,6 +151,9 @@ FFZ.prototype.lv_ws_create = function() {
|
|||
ws.send('2probe');
|
||||
ws.send('5');
|
||||
|
||||
if ( f._lv_token.token )
|
||||
ws.send('42' + JSON.stringify(["token", f._lv_token.token]));
|
||||
|
||||
// Ping every 10 seconds just to be safe.
|
||||
f._lv_ws_ping_timer = setInterval(function() {
|
||||
ws.send('2');
|
||||
|
@ -246,4 +257,491 @@ FFZ.prototype.lv_ws_maybe_close = function() {
|
|||
|
||||
if ( (! this._lv_ws_topics || ! this._lv_ws_topics.length) && this._lv_ws_open )
|
||||
this._lv_ws_sock.close();
|
||||
}
|
||||
|
||||
|
||||
// ----------------
|
||||
// Moderation Card Pages
|
||||
// ----------------
|
||||
|
||||
FFZ.mod_card_pages = {};
|
||||
|
||||
FFZ.mod_card_pages.default = {
|
||||
title: "<span>C</span>ontrols",
|
||||
render: function(mod_card, el) { }
|
||||
}
|
||||
|
||||
FFZ.mod_card_pages.history = {
|
||||
title: "Chat <span>H</span>istory",
|
||||
|
||||
render_more: function(mod_card, el, history, ref_id, is_user, is_after) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
|
||||
btn_more = utils.createElement('li', 'button ffz-load-more' + (is_after ? ' load-after' : ''), '<span class="ffz-chevron"></span> Load More <span class="ffz-chevron"></span>');
|
||||
|
||||
if ( is_after )
|
||||
history.appendChild(btn_more);
|
||||
else
|
||||
history.insertBefore(btn_more, history.firstElementChild);
|
||||
|
||||
btn_more.addEventListener('click', function() {
|
||||
history.scrollTop = 0;
|
||||
history.classList.add('loading');
|
||||
f.lv_get_logs(room_id, is_user ? user_id : null, ref_id, is_after ? 0 : 10, is_after ? 10 : 0).then(function(data) {
|
||||
history.removeChild(btn_more);
|
||||
history.classList.remove('loading');
|
||||
|
||||
var messages = is_after ? data.after : data.before,
|
||||
last_message = history.querySelector('.chat-line:' + (is_after ? 'last' : 'first') + '-of-type'),
|
||||
last_date = last_message ? last_message.getAttribute('data-date') : (new Date).toLocaleDateString();
|
||||
|
||||
if ( last_message.classList.contains('timestamp-line') )
|
||||
last_message.parentElement.removeChild(last_message);
|
||||
|
||||
if ( ! is_after )
|
||||
messages.reverse();
|
||||
|
||||
var original_message = history.querySelector('.original-msg'),
|
||||
original_sender = original_message && original_message.getAttribute('data-sender');
|
||||
|
||||
for(var i=0; i < messages.length; i++) {
|
||||
var new_message = messages[i],
|
||||
date = new_message.date.toLocaleDateString(),
|
||||
date_line = null;
|
||||
|
||||
new_message.original_sender = original_sender === new_message.from;
|
||||
|
||||
var new_line = f._build_mod_card_history(
|
||||
new_message, mod_card, !is_user,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, mod_card, el, new_message)
|
||||
);
|
||||
|
||||
if ( is_user )
|
||||
new_line.classList.remove('ffz-mentioned');
|
||||
|
||||
new_message.original_sender = null;
|
||||
|
||||
if ( last_date !== date ) {
|
||||
date_line = utils.createElement('li', 'chat-line timestamp-line', is_after ? date : last_date);
|
||||
date_line.setAttribute('data-date', is_after ? date : last_date);
|
||||
last_date = date;
|
||||
if ( is_after )
|
||||
history.appendChild(date_line);
|
||||
else
|
||||
history.insertBefore(date_line, history.firstElementChild);
|
||||
}
|
||||
|
||||
if ( is_after )
|
||||
history.appendChild(new_line);
|
||||
else
|
||||
history.insertBefore(new_line, history.firstElementChild);
|
||||
}
|
||||
|
||||
if ( ! is_after && last_date !== (new Date).toLocaleDateString() ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', last_date);
|
||||
date_line.setAttribute('data-date', last_date);
|
||||
history.insertBefore(date_line, history.firstElementChild);
|
||||
}
|
||||
|
||||
// Only add the button back if there are even more messages to load.
|
||||
if ( messages.length >= 10 )
|
||||
if ( is_after )
|
||||
history.appendChild(btn_more);
|
||||
else
|
||||
history.insertBefore(btn_more, history.firstElementChild);
|
||||
|
||||
var original = history.querySelector('.chat-line[data-lv-id="' + ref_id + '"]');
|
||||
if ( original )
|
||||
setTimeout(function() {
|
||||
history.scrollTop = (original.offsetTop - history.offsetTop) - (history.clientHeight - original.clientHeight) / 2;
|
||||
});
|
||||
|
||||
ref_id = messages[messages.length-1].lv_id;
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
render_adjacent: function(mod_card, el, message) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
ffz_room = this.rooms[room_id],
|
||||
|
||||
old_history = el.querySelector('.chat-history'),
|
||||
history = el.querySelector('.adjacent-history');
|
||||
|
||||
old_history.classList.add('hidden');
|
||||
|
||||
if ( history )
|
||||
history.innerHTML = '';
|
||||
else {
|
||||
var btn_hide = utils.createElement('li', 'button ffz-back-button', '<span class="ffz-chevron"></span> Back'),
|
||||
btn_container = utils.createElement('ul', 'interface chat-history chat-back-button', btn_hide);
|
||||
|
||||
btn_hide.addEventListener('click', function() {
|
||||
el.removeChild(history);
|
||||
el.removeChild(btn_container);
|
||||
old_history.classList.remove('hidden');
|
||||
})
|
||||
|
||||
history = utils.createElement('ul', 'interface chat-history adjacent-history');
|
||||
el.appendChild(btn_container);
|
||||
el.appendChild(history);
|
||||
}
|
||||
|
||||
history.classList.add('loading');
|
||||
|
||||
f.lv_get_logs(room_id, null, message.lv_id, 10, 10).then(function(data) {
|
||||
history.classList.remove('loading');
|
||||
|
||||
// Should we display more?
|
||||
if ( data.before.length >= 10 )
|
||||
FFZ.mod_card_pages.history.render_more.call(
|
||||
f, mod_card, el, history, data.before[0].lv_id, false, false);
|
||||
|
||||
var last_date = (new Date).toLocaleDateString(),
|
||||
messages = _.union(data.before, [message], data.after);
|
||||
|
||||
for(var i=0; i < messages.length; i++) {
|
||||
var new_message = messages[i],
|
||||
date = new_message.date.toLocaleDateString();
|
||||
|
||||
if ( date !== last_date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
last_date = date;
|
||||
}
|
||||
|
||||
new_message.is_original = new_message.lv_id === message.lv_id;
|
||||
new_message.original_sender = new_message.from === message.from;
|
||||
|
||||
var msg_line = f._build_mod_card_history(new_message, mod_card, true,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, mod_card, el, new_message));
|
||||
|
||||
if ( new_message.is_original )
|
||||
msg_line.classList.remove('ffz-mentioned');
|
||||
|
||||
history.appendChild(msg_line);
|
||||
|
||||
// These objects can be persistent, so clear these.
|
||||
new_message.is_original = null;
|
||||
new_message.original_sender = null;
|
||||
}
|
||||
|
||||
if ( data.after.length >= 10 )
|
||||
FFZ.mod_card_pages.history.render_more.call(
|
||||
f, mod_card, el, history, data.after[data.after.length-1].lv_id, false, true);
|
||||
|
||||
setTimeout(function() {
|
||||
var original = history.querySelector('.original-msg');
|
||||
if ( original )
|
||||
history.scrollTop = (original.offsetTop - history.offsetTop) - (history.clientHeight - original.clientHeight) / 2;
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
render: function(mod_card, el) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
ffz_room = this.rooms[room_id],
|
||||
|
||||
history = utils.createElement('ul', 'interface chat-history lv-history');
|
||||
|
||||
el.appendChild(history);
|
||||
|
||||
// Are we relying on LogViewer here?
|
||||
if ( ! ffz_room.has_logs || ! mod_card.lv_view ) {
|
||||
history.innerHTML = '<li class="chat-line admin"><span class="message">You do not have permission to view chat history in this channel.</span></li>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Start loading!
|
||||
history.classList.add('loading');
|
||||
|
||||
mod_card.lvGetLogs().then(function(data) {
|
||||
history.classList.remove('loading');
|
||||
|
||||
// Should we display more?
|
||||
if ( data.before.length >= 10 )
|
||||
FFZ.mod_card_pages.history.render_more.call(
|
||||
f, mod_card, el, history, data.before[0].lv_id, true, false);
|
||||
|
||||
var last_date = (new Date).toLocaleDateString();
|
||||
|
||||
if ( ! data.before.length )
|
||||
history.innerHTML = '<li class="message-line chat-line admin no-messages"><span class="message">(There are no logged messages to display.)</span></li>';
|
||||
|
||||
for(var i=0; i < data.before.length; i++) {
|
||||
var message = data.before[i],
|
||||
date = message.date.toLocaleDateString();
|
||||
|
||||
if ( date !== last_date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
last_date = date;
|
||||
}
|
||||
|
||||
var msg_line = f._build_mod_card_history(message, mod_card, false,
|
||||
FFZ.mod_card_pages.history.render_adjacent.bind(f, mod_card, el, message));
|
||||
|
||||
msg_line.classList.remove('ffz-mentioned');
|
||||
history.appendChild(msg_line);
|
||||
}
|
||||
|
||||
history.scrollTop = history.scrollHeight;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
FFZ.mod_card_pages.stats = {
|
||||
title: "<span>S</span>tatistics",
|
||||
render: function(mod_card, el) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
room_id = controller && controller.get('currentRoom.id'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
ffz_room = f.rooms && f.rooms[room_id];
|
||||
|
||||
var container = utils.createElement('ul', 'interface version-list');
|
||||
el.appendChild(container);
|
||||
|
||||
if ( ffz_room.has_logs && mod_card.lv_view ) {
|
||||
container.classList.add('loading');
|
||||
|
||||
mod_card.lvGetLogs().then(function(data) {
|
||||
container.classList.remove('loading');
|
||||
container.innerHTML = '<li>Messages <span>' + utils.number_commas(data.user.messages) + '</span></li><li>Timeouts <span> ' + utils.number_commas(data.user.timeouts) + '</span></li>';
|
||||
});
|
||||
|
||||
var notice = utils.createElement('div', 'interface');
|
||||
notice.innerHTML = 'Chat Log Source: <a target="_blank" href="https://cbenni.com/' + room_id + '?user=' + user_id + '">CBenni\'s logviewer</a>';
|
||||
el.appendChild(notice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FFZ.mod_card_pages.notes = {
|
||||
title: "<span>N</span>otes",
|
||||
|
||||
add_note: function(mod_card, el, note, history, last_line, do_scroll) {
|
||||
if ( ! history )
|
||||
history = el.querySelector('.chat-history.user-notes');
|
||||
|
||||
if ( ! history )
|
||||
return;
|
||||
|
||||
if ( ! last_line )
|
||||
last_line = history.querySelector('.chat-line:last-of-type');
|
||||
|
||||
var was_at_bottom = do_scroll ? history.scrollTop >= (history.scrollHeight - history.clientHeight) : false,
|
||||
last_date = last_line ? last_line.getAttribute('data-date') : (new Date).toLocaleDateString();
|
||||
|
||||
if ( last_line && last_line.classList.contains('no-messages') ) {
|
||||
last_line.parentElement.removeChild(last_line);
|
||||
last_line = null;
|
||||
}
|
||||
|
||||
var output = FFZ.mod_card_pages.notes.build_note.call(this, mod_card, note),
|
||||
date = output.getAttribute('data-date');
|
||||
|
||||
if ( last_date !== date ) {
|
||||
var date_line = utils.createElement('li', 'chat-line timestamp-line', date);
|
||||
date_line.setAttribute('data-date', date);
|
||||
history.appendChild(date_line);
|
||||
}
|
||||
|
||||
history.appendChild(output);
|
||||
|
||||
if ( was_at_bottom )
|
||||
setTimeout(function() { history.scrollTop = history.scrollHeight });
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
build_note: function(mod_card, note) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
room = controller && controller.get('currentRoom'),
|
||||
user = this.get_user(),
|
||||
tmiSession = room.tmiSession || (window.TMI && TMI._sessions && TMI._sessions[0]),
|
||||
|
||||
message = {
|
||||
date: new Date(note.added * 1000),
|
||||
from: note.author,
|
||||
room: note.channel,
|
||||
lv_id: note.id,
|
||||
message: note.text,
|
||||
tags: {
|
||||
'display-name': FFZ.get_capitalization(note.author)
|
||||
},
|
||||
color: tmiSession && note.author ? tmiSession.getColor(note.author) : "#755000"
|
||||
};
|
||||
|
||||
this.tokenize_chat_line(message, true, false);
|
||||
|
||||
var can_edit = false, // mod_card.lv_write_notes && user && user.login === message.from,
|
||||
can_delete = false, //mod_card.lv_delete_notes || (user && user.login === message.from),
|
||||
can_mod = can_edit || can_delete;
|
||||
|
||||
var output = this._build_mod_card_history(message, mod_card, true, false, can_mod);
|
||||
|
||||
/*if ( can_mod ) {
|
||||
var mod_icons = output.querySelector('.mod-icons');
|
||||
if ( can_delete ) {
|
||||
var btn_delete = utils.createElement('a', 'mod-icon html-tooltip delete-note', 'Delete');
|
||||
btn_delete.title = 'Delete Note';
|
||||
mod_icons.appendChild(btn_delete);
|
||||
|
||||
btn_delete.addEventListener('click', function(e) {
|
||||
if ( e.ctrlKey || e.metaKey || e.altKey || btn_delete.classList.contains('loading') )
|
||||
return;
|
||||
|
||||
btn_delete.classList.add('loading');
|
||||
|
||||
f.lv_get_token().then(function(token) {
|
||||
utils.logviewer.del("comments/" + note.channel + "?id=" + note.id, token)
|
||||
.then(function(resp) {
|
||||
btn_delete.classList.remove('loading');
|
||||
if ( resp.ok )
|
||||
mod_card.lvOnMessage("comment-delete", note);
|
||||
else
|
||||
alert("An error occured deleting this note.");
|
||||
}).catch(function() {
|
||||
btn_delete.classList.remove('loading');
|
||||
alert("An error occured deleting this note.");
|
||||
});
|
||||
|
||||
}).catch(function() {
|
||||
btn_delete.classList.remove('loading');
|
||||
alert("An error occured deleting this note.");
|
||||
})
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
/*if ( can_edit ) {
|
||||
var btn_edit = utils.createElement('a', 'mod-icon html-tooltip edit-note', 'Edit');
|
||||
btn_edit.title = 'Edit Note';
|
||||
mod_icons.appendChild(btn_edit);
|
||||
}*
|
||||
}*/
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
render: function(mod_card, el) {
|
||||
var f = this,
|
||||
controller = utils.ember_lookup('controller:chat'),
|
||||
room = controller && controller.get('currentRoom'),
|
||||
tmiSession = room.tmiSession || (window.TMI && TMI._sessions && TMI._sessions[0]),
|
||||
|
||||
room_id = room && room.get('id'),
|
||||
user_id = mod_card.get('cardInfo.user.id'),
|
||||
|
||||
ffz_room = this.rooms[room_id],
|
||||
history = utils.createElement('ul', 'interface chat-history user-notes');
|
||||
|
||||
el.appendChild(history);
|
||||
|
||||
if ( ! ffz_room.has_logs || ! mod_card.lv_view_notes ) {
|
||||
history.innerHTML = '<li class="chat-line admin"><span class="message">You do not have permission to view notes in this channel.</span></li>';
|
||||
return;
|
||||
}
|
||||
|
||||
history.classList.add('loading');
|
||||
|
||||
this.lv_get_token().then(function(token) {
|
||||
utils.logviewer.get("comments/" + room_id + "?topic=" + user_id, token)
|
||||
.then(utils.json).then(function(data) {
|
||||
|
||||
f.log("[LV] Comments: " + user_id + " in " + room_id, data);
|
||||
history.classList.remove('loading');
|
||||
|
||||
// We want to listen to get new notes for this user.
|
||||
mod_card._lv_sock_room = room_id;
|
||||
mod_card._lv_sock_user = user_id;
|
||||
f.lv_ws_sub(room_id + '-' + user_id);
|
||||
|
||||
if ( data.length ) {
|
||||
var last_line = null;
|
||||
for(var i=0; i < data.length; i++)
|
||||
last_line = FFZ.mod_card_pages.notes.add_note.call(f, mod_card, el, data[i], history, last_line, false);
|
||||
}
|
||||
|
||||
else
|
||||
history.appendChild(utils.createElement('li', 'chat-line message-line admin no-messages',
|
||||
'<span class="message">There are no notes on this user.</span>'));
|
||||
});
|
||||
});
|
||||
|
||||
if ( mod_card.lv_write_notes ) {
|
||||
var textarea = utils.createElement('textarea', 'chat_text_input mousetrap note-text-input'),
|
||||
note_container = utils.createElement('div', 'interface textarea-contain note-input', textarea),
|
||||
btn_submit = utils.createElement('button', 'button float-right', 'Add Note'),
|
||||
btn_container = utils.createElement('div', 'chat-buttons-container clearfix', btn_submit),
|
||||
|
||||
submit_note = function() {
|
||||
if ( note_container.classList.contains('loading') )
|
||||
return;
|
||||
|
||||
var comment = textarea.value.trim();
|
||||
if ( ! comment.length )
|
||||
return;
|
||||
|
||||
note_container.classList.add('loading');
|
||||
textarea.disabled = btn_submit.disabled = true;
|
||||
|
||||
f.lv_get_token().then(function(token) {
|
||||
utils.logviewer.post("comments/" + room_id, null, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
comment: {
|
||||
topic: user_id,
|
||||
text: comment
|
||||
},
|
||||
token: token
|
||||
})
|
||||
}).then(function(resp) {
|
||||
note_container.classList.remove('loading');
|
||||
textarea.disabled = btn_submit.disabled = false;
|
||||
textarea.value = '';
|
||||
|
||||
if ( resp.ok )
|
||||
textarea.placeholder = 'The note was posted successfully. Write another note...';
|
||||
else
|
||||
alert("An error occured posting this note.");
|
||||
|
||||
}).catch(function() {
|
||||
note_container.classList.remove('loading');
|
||||
textarea.disabled = btn_submit.disabled = false;
|
||||
alert("An error occured posting this note.");
|
||||
});
|
||||
|
||||
}).catch(function() {
|
||||
note_container.classList.remove('loading');
|
||||
textarea.disabled = btn_submit.disabled = false;
|
||||
alert("An error occured posting this note.");
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
textarea.placeholder = 'Write a note about ' + user_id + '...';
|
||||
|
||||
btn_submit.addEventListener('click', submit_note);
|
||||
note_container.appendChild(btn_container);
|
||||
el.appendChild(note_container);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -83,6 +83,8 @@ FFZ.prototype.modify_chat_settings_menu = function(component) {
|
|||
|
||||
cb.addEventListener("change", function(e) {
|
||||
f.settings.set("dark_twitch", this.checked);
|
||||
if ( this.checked )
|
||||
f.settings.set("dark_no_blue", true);
|
||||
});
|
||||
|
||||
|
||||
|
@ -580,7 +582,8 @@ FFZ.menu_pages.channel = {
|
|||
var last_content = tickets.get("content");
|
||||
last_content = last_content.length > 0 ? last_content[last_content.length-1] : undefined;
|
||||
if ( last_content && last_content.purchase_profile && !last_content.purchase_profile.will_renew ) {
|
||||
var ends_at = utils.parse_date(last_content.access_end || "");
|
||||
var ends_at = utils.parse_date(last_content.access_end || ""),
|
||||
provider = last_content.purchase_profile && last_content.purchase_profile.payment_provider,
|
||||
sub_message = document.createElement("div"),
|
||||
nonsub_message = document.createElement("div"),
|
||||
unlock_text = document.createElement("span"),
|
||||
|
@ -593,6 +596,10 @@ FFZ.menu_pages.channel = {
|
|||
|
||||
unlock_text.className = "unlock-text";
|
||||
unlock_text.innerHTML = "Subscription expires in " + utils.time_to_string(end_time, true, true);
|
||||
|
||||
if ( provider === "samus" )
|
||||
unlock_text.innerHTML += '<br>(Twitch Prime Free Sub)';
|
||||
|
||||
nonsub_message.appendChild(unlock_text);
|
||||
inner.appendChild(sub_message);
|
||||
}
|
||||
|
|
|
@ -521,7 +521,7 @@ module.exports = FFZ.utils = {
|
|||
},
|
||||
|
||||
logviewer: {
|
||||
del: function(u,t,i) { return logviewer_call('del', u,t,i) },
|
||||
del: function(u,t,i) { return logviewer_call('delete', u,t,i) },
|
||||
get: function(u,t,i) { return logviewer_call('get', u,t,i) },
|
||||
post: function(u,t,i) { return logviewer_call('post', u,t,i) },
|
||||
put: function(u,t,i) { return logviewer_call('put', u,t,i) },
|
||||
|
|
63
style.css
63
style.css
|
@ -1139,20 +1139,20 @@ body.ffz-bttv-dark .ffz-ui-popup .ffz-ui-menu-page { border-bottom: none }
|
|||
|
||||
.app-main.theatre .chatReplay .chat-messages .chat-line .mod-icons,
|
||||
.ffz-dark .chatReplay .chat-messages .chat-line .mod-icons {
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.chatReplay .chat-messages .chat-line .mod-icons {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
left: 0; top: 2px; bottom: 2px;
|
||||
padding: 4px 5px 4px 4px;
|
||||
background: rgba(255,255,255,0.8);
|
||||
transition: margin-left .08s linear;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
left: 0; top: 2px; bottom: 2px;
|
||||
padding: 4px 5px 4px 4px;
|
||||
background: rgba(255,255,255,0.8);
|
||||
transition: margin-left .08s linear;
|
||||
}
|
||||
|
||||
.chatReplay .chat-messages .chat-line:hover .mod-icons {
|
||||
margin-left: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.chatReplay .chat-messages .horizontal-line { margin: 4px 0 }
|
||||
|
@ -1388,6 +1388,7 @@ img.channel_background[src="null"] { display: none; }
|
|||
|
||||
.ffz-moderation-card ul.menu + .interface { border-top: none }
|
||||
|
||||
.ffz-moderation-card .interface:last-child,
|
||||
.ffz-moderation-card .interface:not(:last-of-type) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
@ -1418,6 +1419,11 @@ img.channel_background[src="null"] { display: none; }
|
|||
|
||||
.ffz-moderation-card ul.menu span { text-decoration: underline }
|
||||
|
||||
.ffz-dark .moderation-card .interface,
|
||||
.theatre .moderation-card .interface,
|
||||
.dark .moderation-card .interface,
|
||||
.force-dark .moderation-card .interface,
|
||||
|
||||
.ffz-dark .ffz-moderation-card ul.menu,
|
||||
.theatre .ffz-moderation-card ul.menu,
|
||||
.dark .ffz-moderation-card ul.menu,
|
||||
|
@ -1519,7 +1525,10 @@ img.channel_background[src="null"] { display: none; }
|
|||
|
||||
/* Chat Rows */
|
||||
|
||||
.chat-line { overflow: hidden }
|
||||
.ember-chat .chat-messages .chat-line {
|
||||
margin: 0;
|
||||
padding: 3px 20px;
|
||||
}
|
||||
|
||||
.theatre .conversation-window .conversation-chat-line,
|
||||
.dark .chat-line,
|
||||
|
@ -1568,7 +1577,7 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
|
|||
/* Emoticon Tooltips */
|
||||
|
||||
.ffz-wide-tip hr {
|
||||
margin: 5px 0;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.ffz-wide-tip .tipsy-inner {
|
||||
|
@ -3387,20 +3396,19 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.chat-room .show-mod-icons .chat-line:not(.admin) .mod-icons {
|
||||
.chat-room .show-mod-icons .chat-lines .chat-line:not(.admin) .mod-icons {
|
||||
display: block !important;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
bottom: 1px;
|
||||
padding: 4px 5px 0;
|
||||
top: 0; bottom: 0;
|
||||
padding: 3px 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 {
|
||||
.theatre .chat-room .show-mod-icons .chat-lines .chat-line:not(.admin) .mod-icons,
|
||||
.dark .chat-room .show-mod-icons .chat-lines .chat-line:not(.admin) .mod-icons,
|
||||
.force-dark .chat-room .show-mod-icons .chat-lines .chat-line:not(.admin) .mod-icons {
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
|
@ -3556,4 +3564,23 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
|||
min-height: 70px;
|
||||
}
|
||||
|
||||
.ffz-hide-channel-banner .cn-bar__avatar-wrap { width: 4rem; height: 4rem; }
|
||||
.ffz-hide-channel-banner .cn-bar__avatar-wrap { width: 4rem; height: 4rem; }
|
||||
|
||||
/* Mod Card Notes */
|
||||
|
||||
.ffz-moderation-card .note-input textarea {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
resize: none;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ffz-moderation-card .mod-icons .delete-note {
|
||||
background-image: url("//cdn.frankerfacez.com/script/button_ban.svg");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.ffz-moderation-card .mod-icons .edit-note {
|
||||
background-image: url("//cdn.frankerfacez.com/script/button_edit.svg");
|
||||
background-repeat: no-repeat;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue