1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-14 10:00:53 +00:00

3.5.389. Add setting to move Latest Uploads to the bottom of the directory or to hide it. Make pop-out chat the same width as the right sidebar. Comment out code to auto-pause hosted channels until such time as it's possible to make it work. Fix player tracking for finding and showing stats from it. Closes #59

This commit is contained in:
SirStendec 2016-12-03 22:44:26 -05:00
parent 60c3d51c7e
commit 5d09aca868
12 changed files with 138 additions and 71 deletions

View file

@ -1,3 +1,16 @@
<div class="list-header">3.5.389 <time datetime="2016-12-03">(2016-12-03)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Added: Setting to move the Latest Uploads to the bottom of the Following page or to hide it outright.</li>
<li>Changed: When you pop out chat, it will take the custom width you've given the right sidebar.</li>
<li>Removed: Auto-Pause Hosted Channels. Twitch has made it impossible to determine from the player if it is a host or not.</li>
<li>Fixed: Stream latency display.</li>
</ul>
<div class="list-header">3.5.388 <time datetime="2016-12-02">(2016-12-02)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Moderation cards.</li>
</ul>
<div class="list-header">3.5.387 <time datetime="2016-11-30">(2016-11-30)</time></div> <div class="list-header">3.5.387 <time datetime="2016-11-30">(2016-11-30)</time></div>
<ul class="chat-menu-content menu-side-padding"> <ul class="chat-menu-content menu-side-padding">
<li>Removed: Mini Player. Twitch has its own feature for that now.</li> <li>Removed: Mini Player. Twitch has its own feature for that now.</li>
@ -47,18 +60,5 @@
<li>API Changed: Badge classes now use <code>name_key</code> rather than <code>id</code> for badges added through the API to give them predictable classes.</li> <li>API Changed: Badge classes now use <code>name_key</code> rather than <code>id</code> for badges added through the API to give them predictable classes.</li>
</ul> </ul>
<div class="list-header">3.5.378 <time datetime="2016-11-23">(2016-11-23)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Chat breaking when trying to access data for a badge that ended up not loading.</li>
<li>Fixed: Host mode would no longer trigger with FFZ enabled due to the removal of an experiment flag.</li>
<li>API Changed: Add <code>name_key</code> parameter to API constructor.</li>
</ul>
<div class="list-header">3.5.377 <time datetime="2016-11-21">(2016-11-21)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Group bits emoticons in chat based on their prefix rather than as one single lump.</li>
<li>Fixed: Properly generate CSS for bits emoticons with every possible prefix.</li>
</ul>
<div class="list-header" id="ffz-old-news-button"><a href="#">View Older</a></div> <div class="list-header" id="ffz-old-news-button"><a href="#">View Older</a></div>
<div id="ffz-old-news"></div> <div id="ffz-old-news"></div>

View file

@ -1,3 +1,16 @@
<div class="list-header">3.5.378 <time datetime="2016-11-23">(2016-11-23)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Chat breaking when trying to access data for a badge that ended up not loading.</li>
<li>Fixed: Host mode would no longer trigger with FFZ enabled due to the removal of an experiment flag.</li>
<li>API Changed: Add <code>name_key</code> parameter to API constructor.</li>
</ul>
<div class="list-header">3.5.377 <time datetime="2016-11-21">(2016-11-21)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Group bits emoticons in chat based on their prefix rather than as one single lump.</li>
<li>Fixed: Properly generate CSS for bits emoticons with every possible prefix.</li>
</ul>
<div class="list-header">3.5.376 <time datetime="2016-11-21">(2016-11-21)</time></div> <div class="list-header">3.5.376 <time datetime="2016-11-21">(2016-11-21)</time></div>
<ul class="chat-menu-content menu-side-padding"> <ul class="chat-menu-content menu-side-padding">
<li>Fixed: Cheers aren't working yet, but they also don't break chat completely.</li> <li>Fixed: Cheers aren't working yet, but they also don't break chat completely.</li>

View file

@ -165,10 +165,10 @@ FFZ.prototype.modify_channel_live = function(view) {
if ( f.settings.auto_theater ) { if ( f.settings.auto_theater ) {
var layout = this.get('layout'), var layout = this.get('layout'),
player = f.players && f.players[channel_id] && f.players[channel_id].get('player'), func = function(tries) {
func = function() { var player = f._player && f._player.get('player');
if ( typeof player.isLoading === 'function' && player.isLoading() ) if ( ! player || typeof player.isLoading === 'function' && player.isLoading() )
return setTimeout(func, 500); return (tries||0) < 20 ? setTimeout(func.bind(this, (tries||0) + 1), 500) : null;
// In case this happens before the event bindings are in, we just set // In case this happens before the event bindings are in, we just set
// the layout into theater mode manually. // the layout into theater mode manually.
@ -176,8 +176,7 @@ FFZ.prototype.modify_channel_live = function(view) {
layout.setTheatreMode(true); layout.setTheatreMode(true);
} }
if ( player ) func();
func();
} }
this.$().on("click", ".ffz-creative-tag-link", utils.transition_link(function(e) { this.$().on("click", ".ffz-creative-tag-link", utils.transition_link(function(e) {

View file

@ -350,6 +350,13 @@ FFZ.prototype.setup_chatview = function() {
if ( Chat ) { if ( Chat ) {
Chat.set('ffz_last_channel_room', Chat.get('currentChannelRoom.id')); Chat.set('ffz_last_channel_room', Chat.get('currentChannelRoom.id'));
Chat.reopen({ Chat.reopen({
openPopout: function() {
var room_id = this.get('currentRoom.id'),
width = f.settings.right_column_width;
return window.open("/" + room_id + "/chat?popout=", "_blank", "right=50,top=50,width=" + width + ",height=600,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no");
},
ffzUpdateChannels: function() { ffzUpdateChannels: function() {
if ( ! f._chatv || f.has_bttv ) if ( ! f._chatv || f.has_bttv )
return; return;

View file

@ -164,17 +164,40 @@ FFZ.settings_info.directory_host_menus = {
help: "Display a menu to select which channel to visit when clicking a hosted channel in the directory.", help: "Display a menu to select which channel to visit when clicking a hosted channel in the directory.",
on_update: function() { on_update: function() {
var f = this, var f = this,
HostModel = utils.ember_resolve('model:host'), HostModel = utils.ember_resolve('model:host'),
Following = HostModel && HostModel.collections[HostModel.collectionId("following")]; Following = HostModel && HostModel.collections[HostModel.collectionId("following")];
if ( ! Following ) if ( ! Following )
return; return;
Following.clear(); Following.clear();
Following.load(); Following.load();
} }
}; };
FFZ.settings_info.directory_uploads_position = {
type: "select",
options: {
0: "Default",
1: "At Bottom",
2: "Hidden"
},
value: 0,
process_value: utils.process_int(0),
category: "Directory",
no_mobile: true,
name: "Display Latest Uploads",
help: "Choose where to display the Latest Uploads section.",
on_update: function(val) {
utils.toggle_cls('ffz-hide-directory-uploads')(val === 2);
}
};
// -------------------- // --------------------
@ -184,8 +207,9 @@ FFZ.settings_info.directory_host_menus = {
FFZ._image_cache = {}; FFZ._image_cache = {};
FFZ.prototype.setup_directory = function() { FFZ.prototype.setup_directory = function() {
document.body.classList.toggle('ffz-creative-tags', this.settings.directory_creative_all_tags); utils.toggle_cls('ffz-creative-tags')(this.settings.directory_creative_all_tags);
document.body.classList.toggle('ffz-creative-showcase', this.settings.directory_creative_showcase); utils.toggle_cls('ffz-creative-showcase')(this.settings.directory_creative_showcase);
utils.toggle_cls('ffz-hide-directory-uploads')(this.settings.directory_uploads_position === 2);
var f = this, var f = this,
VodCoviews = utils.ember_lookup('service:vod-coviews'); VodCoviews = utils.ember_lookup('service:vod-coviews');
@ -222,6 +246,7 @@ FFZ.prototype.setup_directory = function() {
this.update_views('component:twitch-carousel/stream-item', function(x) { this.modify_directory_live(x, false, true) }, true); this.update_views('component:twitch-carousel/stream-item', function(x) { this.modify_directory_live(x, false, true) }, true);
this.update_views('component:host-preview', this.modify_directory_host, true, true); this.update_views('component:host-preview', this.modify_directory_host, true, true);
this.update_views('component:video-preview', this.modify_video_preview, true); this.update_views('component:video-preview', this.modify_video_preview, true);
this.update_views("component:video/following-uploads", this.modify_following_uploads);
this.update_views('component:game-follow-button', this.modify_game_follow_button); this.update_views('component:game-follow-button', this.modify_game_follow_button);
@ -230,6 +255,23 @@ FFZ.prototype.setup_directory = function() {
} }
FFZ.prototype.modify_following_uploads = function(component) {
var f = this;
utils.ember_reopen_view(component, {
ffz_init: function() {
var el = this.get('element');
el.classList.add('ffz-following-uploads');
if ( f.settings.directory_uploads_position === 1 ) {
var p = el.parentElement;
p.removeChild(el);
p.appendChild(el);
}
}
});
}
FFZ.prototype._modify_following = function() { FFZ.prototype._modify_following = function() {
var HostModel = utils.ember_resolve('model:host'), var HostModel = utils.ember_resolve('model:host'),
f = this; f = this;

View file

@ -253,11 +253,11 @@ FFZ.prototype.setup_layout = function() {
i = Math.round(9 * r / 16) + c, i = Math.round(9 * r / 16) + c,
d = h - extra_height, d = h - extra_height,
c = h - extra_theater_height, e = h - extra_theater_height,
l = Math.floor(r), l = Math.floor(r),
o = Math.floor(Math.min(i, d)), o = Math.floor(Math.min(i, d)),
s = Math.floor(Math.min(i, c)); s = Math.floor(Math.min(i, e));
return { return {
width: l, width: l,

View file

@ -915,11 +915,10 @@ FFZ.prototype.modify_moderation_card = function(component) {
} }
var el = this.get('element'), var el = this.get('element'),
controller = this.get('controller'),
t = this, t = this,
line, line,
is_mod = controller.get('cardInfo.isModeratorOrHigher'), is_mod = t.get('cardInfo.isModeratorOrHigher'),
ban_reasons, ban_reasons,
chat = utils.ember_lookup('controller:chat'), chat = utils.ember_lookup('controller:chat'),
@ -929,7 +928,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
ffz_room = f.rooms && f.rooms[room_id] || {}, ffz_room = f.rooms && f.rooms[room_id] || {},
is_broadcaster = user && room_id === user.login, is_broadcaster = user && room_id === user.login,
user_id = controller.get('cardInfo.user.id'), user_id = this.get('cardInfo.user.id'),
alias = f.aliases[user_id], alias = f.aliases[user_id],
handle_key, handle_key,
@ -997,7 +996,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
var name = el.querySelector('.moderation-card__name a'); var name = el.querySelector('.moderation-card__name a');
if ( name ) { if ( name ) {
name.classList.add('ffz-alias'); name.classList.add('ffz-alias');
var results = f.format_display_name(controller.get('cardInfo.user.display_name'), user_id); var results = f.format_display_name(this.get('cardInfo.user.display_name'), user_id);
name.innerHTML = results[0]; name.innerHTML = results[0];
name.title = results[1] || ''; name.title = results[1] || '';
@ -1053,7 +1052,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
}, },
add_btn_click = function(cmd) { add_btn_click = function(cmd) {
var user = controller.get('cardInfo.user'), var user = t.get('cardInfo.user'),
chat_controller = utils.ember_lookup('controller:chat'), chat_controller = utils.ember_lookup('controller:chat'),
room = chat_controller && chat_controller.get('currentRoom'); room = chat_controller && chat_controller.get('currentRoom');
@ -1072,7 +1071,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
html: true, html: true,
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n'), gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n'),
title: function() { title: function() {
var user = controller.get('cardInfo.user'), var user = t.get('cardInfo.user'),
chat_controller = utils.ember_lookup('controller:chat'), chat_controller = utils.ember_lookup('controller:chat'),
room = chat_controller && chat_controller.get('currentRoom'); room = chat_controller && chat_controller.get('currentRoom');
@ -1122,8 +1121,8 @@ FFZ.prototype.modify_moderation_card = function(component) {
var key = e.keyCode || e.which, var key = e.keyCode || e.which,
is_meta = e.ctrlKey || e.altKey || e.metaKey, is_meta = e.ctrlKey || e.altKey || e.metaKey,
tag = e.target && e.target.tagName, tag = e.target && e.target.tagName,
user_id = controller.get('cardInfo.user.id'), user_id = t.get('cardInfo.user.id'),
is_mod = controller.get('cardInfo.isModeratorOrHigher'), is_mod = t.get('cardInfo.isModeratorOrHigher'),
room = utils.ember_lookup('controller:chat').get('currentRoom'); room = utils.ember_lookup('controller:chat').get('currentRoom');
// We don't want modifier keys. Also don't override input to input elements. // We don't want modifier keys. Also don't override input to input elements.
@ -1182,7 +1181,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
el.classList.add('ffz-is-mod'); el.classList.add('ffz-is-mod');
var btn_click = function(timeout) { var btn_click = function(timeout) {
var user_id = controller.get('cardInfo.user.id'), var user_id = t.get('cardInfo.user.id'),
room = utils.ember_lookup('controller:chat').get('currentRoom'); room = utils.ember_lookup('controller:chat').get('currentRoom');
if ( timeout === -1 ) if ( timeout === -1 )
@ -1295,7 +1294,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
real_msg.title = "Message User"; real_msg.title = "Message User";
real_msg.addEventListener('click', function() { real_msg.addEventListener('click', function() {
window.open('//www.twitch.tv/message/compose?to=' + controller.get('cardInfo.user.id')); window.open('//www.twitch.tv/message/compose?to=' + t.get('cardInfo.user.id'));
}) })
msg_btn.parentElement.insertBefore(real_msg, msg_btn.nextSibling); msg_btn.parentElement.insertBefore(real_msg, msg_btn.nextSibling);
@ -1308,9 +1307,9 @@ FFZ.prototype.modify_moderation_card = function(component) {
alias_btn.title = "Set Alias"; alias_btn.title = "Set Alias";
alias_btn.addEventListener('click', function() { alias_btn.addEventListener('click', function() {
var user = controller.get('cardInfo.user.id'), var user = t.get('cardInfo.user.id'),
alias = f.aliases[user], alias = f.aliases[user],
results = f.format_display_name(controller.get('cardInfo.user.display_name'), user, true); results = f.format_display_name(t.get('cardInfo.user.display_name'), user, true);
utils.prompt( utils.prompt(
"Alias for <b" + (results[1] ? ' class="html-tooltip" title="' + utils.quote_attr(results[1]) + '">' : '>') + results[0] + "</b>", "Alias for <b" + (results[1] ? ' class="html-tooltip" title="' + utils.quote_attr(results[1]) + '">' : '>') + results[0] + "</b>",
@ -1333,7 +1332,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
var name = el.querySelector('h4.name'); var name = el.querySelector('h4.name');
if ( name ) { if ( name ) {
name.classList.toggle('ffz-alias', new_val); name.classList.toggle('ffz-alias', new_val);
var results = f.format_display_name(controller.get('cardInfo.user.display_name'), user_id); var results = f.format_display_name(t.get('cardInfo.user.display_name'), user_id);
name.innerHTML = results[0]; name.innerHTML = results[0];
name.title = results[1] || ''; name.title = results[1] || '';

View file

@ -59,7 +59,7 @@ FFZ.settings_info.player_volume_bar = {
}; };
FFZ.settings_info.player_pause_hosts = { /*FFZ.settings_info.player_pause_hosts = {
type: "select", type: "select",
options: { options: {
0: "Disabled", 0: "Disabled",
@ -73,7 +73,7 @@ FFZ.settings_info.player_pause_hosts = {
category: "Player", category: "Player",
name: "Auto-Pause Hosted Channels", name: "Auto-Pause Hosted Channels",
help: "Automatically pause hosted channels if you paused the channel doing the hosting, or just pause all hosts." help: "Automatically pause hosted channels if you paused the channel doing the hosting, or just pause all hosts."
} }*/
// --------------- // ---------------
@ -88,8 +88,6 @@ FFZ.prototype.setup_player = function() {
if ( Layout ) if ( Layout )
Layout.set('PLAYER_CONTROLS_HEIGHT', this.settings.classic_player ? 32 : 0); Layout.set('PLAYER_CONTROLS_HEIGHT', this.settings.classic_player ? 32 : 0);
this.players = {};
this.update_views('component:twitch-player2', this.modify_twitch_player); this.update_views('component:twitch-player2', this.modify_twitch_player);
} }
@ -102,8 +100,11 @@ FFZ.prototype.modify_twitch_player = function(player) {
var f = this; var f = this;
utils.ember_reopen_view(player, { utils.ember_reopen_view(player, {
ffz_init: function() { ffz_init: function() {
var channel_id = this.get('hostChannel.name'); // We can have multiple players in page now, thanks to persistent players.
f.players[channel_id] = this; // Usually the second one will be something we don't want though. Like
// the creative showcase.
if ( ! f._player || f._player.isDestroying || f._player.isDestroyed )
f._player = this;
var player = this.get('player'); var player = this.get('player');
if ( player && !this.get('ffz_post_player') ) if ( player && !this.get('ffz_post_player') )
@ -111,12 +112,11 @@ FFZ.prototype.modify_twitch_player = function(player) {
}, },
ffz_destroy: function() { ffz_destroy: function() {
var channel_id = this.get('hostChannel.name'); if ( f._player === this )
if ( f.players[channel_id] === this ) f._player = undefined;
f.players[channel_id] = undefined;
}, },
insertPlayer: function(ffz_reset) { /*insertPlayer: function(ffz_reset) {
// We want to see if this is a hosted video on a play // We want to see if this is a hosted video on a play
var should_start_paused = this.get('shouldStartPaused'), var should_start_paused = this.get('shouldStartPaused'),
channel_id = this.get('hostChannel.name'), channel_id = this.get('hostChannel.name'),
@ -136,7 +136,7 @@ FFZ.prototype.modify_twitch_player = function(player) {
// Restore the previous value so it doesn't mess anything up. // Restore the previous value so it doesn't mess anything up.
this.set('shouldStartPaused', should_start_paused); this.set('shouldStartPaused', should_start_paused);
}.on('didInsertElement'), }.on('didInsertElement'),*/
postPlayerSetup: function() { postPlayerSetup: function() {
this._super(); this._super();
@ -157,16 +157,16 @@ FFZ.prototype.modify_twitch_player = function(player) {
player.destroy(); player.destroy();
// Break down everything left over from that player. // Break down everything left over from that player.
this.$('#video-1').html(''); this.$('#player').html('');
Mousetrap.unbind(['alt+x', 'alt+t', 'esc']); Mousetrap.unbind(['alt+x', 'alt+t', 'esc']);
this.set('player', null); this.set('player', null);
this.set('ffz_post_player', false); this.set('ffz_post_player', false);
// Now, let Twitch create a new player as usual. // Now, let Twitch create a new player as usual.
Ember.run.next(this.insertPlayer.bind(this, true)); Ember.run.next(this.didInsertElement.bind(this));
}, },
ffzUpdatePlayerPaused: function() { /*ffzUpdatePlayerPaused: function() {
var channel_id = this.get('hostChannel.name'), var channel_id = this.get('hostChannel.name'),
hosted_id = this.get('channel.name'), hosted_id = this.get('channel.name'),
is_hosting = channel_id !== hosted_id, is_hosting = channel_id !== hosted_id,
@ -193,13 +193,13 @@ FFZ.prototype.modify_twitch_player = function(player) {
ffzHostChange: function() { ffzHostChange: function() {
this.set('ffz_host_paused', false); this.set('ffz_host_paused', false);
}.observes('channel'), }.observes('channel'),*/
ffzPostPlayer: function() { ffzPostPlayer: function() {
var f = this, var f = this,
channel_id = this.get('hostChannel.name'), /*channel_id = this.get('hostChannel.name'),
hosted_id = this.get('channel.name'), hosted_id = this.get('channel.name'),
is_hosting = channel_id !== hosted_id, is_hosting = channel_id !== hosted_id,*/
player = this.get('player'); player = this.get('player');
if ( ! player ) if ( ! player )
@ -207,11 +207,11 @@ FFZ.prototype.modify_twitch_player = function(player) {
this.set('ffz_post_player', true); this.set('ffz_post_player', true);
if ( ! is_hosting ) //if ( ! is_hosting )
this.set('ffz_original_paused', player.paused); // this.set('ffz_original_paused', player.paused);
player.addEventListener('pause', this.ffzUpdatePlayerPaused.bind(this)); //player.addEventListener('pause', this.ffzUpdatePlayerPaused.bind(this));
player.addEventListener('play', this.ffzUpdatePlayerPaused.bind(this)); //player.addEventListener('play', this.ffzUpdatePlayerPaused.bind(this));
// Make the stats window draggable and fix the button. // Make the stats window draggable and fix the button.
var stats = this.$('.player .js-playback-stats'); var stats = this.$('.player .js-playback-stats');

View file

@ -61,7 +61,7 @@ FFZ.channel_metadata = {};
// Version // Version
var VER = FFZ.version_info = { var VER = FFZ.version_info = {
major: 3, minor: 5, revision: 387, major: 3, minor: 5, revision: 389,
toString: function() { toString: function() {
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || ""); return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
} }

View file

@ -262,9 +262,8 @@ FFZ.debugging_blocks = {
type: "list", type: "list",
get_player: function() { get_player: function() {
for(var key in this.players) if ( this._player && ! this._player.isDestroyed )
if ( this.players[key] && ! this.players[key].isDestroyed && this.players[key].player ) return this._player.player;
return this.players[key].player;
}, },
visible: function() { return FFZ.debugging_blocks.player.get_player.call(this) }, visible: function() { return FFZ.debugging_blocks.player.get_player.call(this) },
@ -283,6 +282,8 @@ FFZ.debugging_blocks = {
try { try {
data.backend = player.getBackend(); data.backend = player.getBackend();
data.version = player.getVersion(); data.version = player.getVersion();
data.quality = player.getVariant();
data.qualities = _.map(player.getQualities(), function(x) { return x.group });
} catch(err) {} } catch(err) {}
var sorted_keys = Object.keys(data).sort(), var sorted_keys = Object.keys(data).sort(),

View file

@ -82,7 +82,7 @@ metadata.player_stats = {
setup: function(view, maybe_channel, is_hosting, channel) { setup: function(view, maybe_channel, is_hosting, channel) {
var channel_id = channel.get('id'), var channel_id = channel.get('id'),
player_cont = this.players && this.players[channel_id], player_cont = this._player,
player = player_cont && player_cont.player, player = player_cont && player_cont.player,
stats; stats;

View file

@ -18,6 +18,7 @@ body > div.tipsy .tipsy-arrow { opacity: 0.8; }
cursor: pointer; cursor: pointer;
} }
.ffz-hide-directory-uploads .ffz-following-uploads,
.pinned-cheers__dismiss, .pinned-cheers__dismiss,
.ffz-hide-pinned-cheers .pinned-cheers, .ffz-hide-pinned-cheers .pinned-cheers,
.cn-hosting--bottom .ffz-channel-options .balloon:after, .cn-hosting--bottom .ffz-channel-options .balloon:after,
@ -1306,6 +1307,7 @@ body:not(.ffz-bttv) .dropmenu.share { margin-bottom: 0; }
margin-top: -10px; margin-top: -10px;
} }
.ember-chat .chat-messages .chat-line--force-timestamp .timestamp,
.ffz-moderation-card.ffz-has-info .moderation-card__name .intl-login { display: inline } .ffz-moderation-card.ffz-has-info .moderation-card__name .intl-login { display: inline }
.ffz-moderation-card.ffz-has-info .flex { position: relative } .ffz-moderation-card.ffz-has-info .flex { position: relative }
@ -1400,6 +1402,10 @@ body:not(.ffz-hide-friends) .ffz-moderation-card .follow-button {
text-shadow: black 0 0 5px; text-shadow: black 0 0 5px;
} }
.ffz-moderation-card .moderation-card__name {
max-width: 235px;
}
.ffz-moderation-card .ffz-ban-reasons { .ffz-moderation-card .ffz-ban-reasons {
margin-top: 10px; margin-top: 10px;
width: 100%; width: 100%;