1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-05 02:28:31 +00:00

3.5.334. Remove logviewer's beta state. Fix bitrate calculation. Tweak pause chat scrolling UI. Update channel information automatically. Support channel-specific badges. Rewrite how layout styles are calculated. Fix sidebar tooltips.

This commit is contained in:
SirStendec 2016-10-16 15:05:11 -04:00
parent 12427d2750
commit a89b71f0a2
14 changed files with 217 additions and 259 deletions

View file

@ -1,3 +1,26 @@
<div class="list-header">3.5.334 <time datetime="2016-10-16">(2016-10-16)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Changed: Remove beta status from Logviewer Integration and enable it by default.</li>
<li>Fixed: Incorrect bitrate calculation for the Flash player.</li>
<li>Fixed: Pause Chat Scrolling UI would incorrectly remain when BTTV is present.</li>
<li>Fixed: Channel information should be updated periodically.</li>
<li>Fixed: CSS tweaks.</li>
</ul>
<div class="list-header">3.5.333 <time datetime="2016-10-15">(2016-10-15)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Added: Support for channel specific badge variations.</li>
<li>Changed: Rewrite how layout applies player styles to support Twitch hijinx.</li>
<li>Fixed: Twitch was applying sidebar tooltips too much and it could create significant lag for some users.</li>
<li>Fixed: Theater Mode channel metadata would go under chat with swapped sidebars enabled.</li>
</ul>
<div class="list-header">3.5.332 <time datetime="2016-10-15">(2016-10-15)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Clicking hashtags in channel titles broke and I never noticed.</li>
<li>Fixed: Metadata popups also broke.</li>
</ul>
<div class="list-header">3.5.331 <time datetime="2016-10-15">(2016-10-15)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>I was thinking to myself "Hey, self, the new hosting page is kind of... bare, right?" but then I thought "Hey wait, I have that thing that can do the stuff to Twitch, right?"</li>

View file

@ -3,6 +3,7 @@ var FFZ = window.FrankerFaceZ,
utils = require('./utils'),
SPECIAL_BADGES = ['staff', 'admin', 'global_mod'],
NOT_KNOWN = ['subscriber'],
OTHER_KNOWN = ['turbo', 'warcraft', 'bits', 'premium'],
CSS_BADGES = {
@ -261,7 +262,7 @@ FFZ.settings_info.transparent_badges = {
};
// This requires -webkit-mask-image which isn't working in non-WebKit browsers.
if ( navigator.userAgent.indexOf('AppleWebKit') !== -1 )
if ( constants.IS_WEBKIT )
FFZ.settings_info.transparent_badges.options[6] = "Transparent (Colored)";
@ -408,14 +409,14 @@ FFZ.prototype.get_line_badges = function(msg) {
badge_tag = tags.badges || {};
// Twitch Badges
var badges = this.get_twitch_badges(badge_tag);
var badges = this.get_twitch_badges(badge_tag, room);
// FFZ Badges
return this.get_badges(from, room, badges, msg);
}
FFZ.prototype.get_twitch_badges = function(badge_tag) {
FFZ.prototype.get_twitch_badges = function(badge_tag, room_id) {
var badges = {},
hidden_badges = this.settings.hidden_badges,
@ -428,6 +429,12 @@ FFZ.prototype.get_twitch_badges = function(badge_tag) {
globals = badgeCollection && badgeCollection.global || {},
channel = badgeCollection && badgeCollection.channel || {};
// Is this the right channel?
if ( room_id && room_id !== channel.broadcasterName ) {
var ffz_room = this.rooms && this.rooms[room_id];
channel = ffz_room && ffz_room.badges || {};
}
// Whisper Chat Lines have a non-associative array for some reason.
if ( Array.isArray(badge_tag) ) {
var val = badge_tag;
@ -459,7 +466,7 @@ FFZ.prototype.get_twitch_badges = function(badge_tag) {
had_last = true;
}
var is_known = BADGE_POSITIONS.hasOwnProperty(badge) || OTHER_KNOWN.indexOf(badge) !== -1;
var is_known = NOT_KNOWN.indexOf(badge) === -1 && (BADGE_POSITIONS.hasOwnProperty(badge) || OTHER_KNOWN.indexOf(badge) !== -1);
badges[last_id] = {
klass: (BADGE_KLASSES[badge] || badge) + (is_known ? '' : ' unknown-badge') + ' version-' + version,
@ -502,7 +509,7 @@ FFZ.prototype.render_badges = function(badges) {
css += 'background-image:url("' + utils.quote_attr(badge.image) + '");';
if ( badge.srcSet && (setting !== 6 || !is_colored) )
css += 'background-image:-webkit-image-set(' + badge.srcSet + ');background-image:image-set(' + badge.srcSet + ');'
css += constants.IS_WEBKIT ? 'background-image:-webkit-image-set(' + badge.srcSet + ');' : 'background-image:image-set(' + badge.srcSet + ');';
if ( badge.color )
if ( is_colored && setting === 6 )

View file

@ -5,6 +5,7 @@ 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
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),
IS_WEBKIT = navigator.userAgent.indexOf('AppleWebKit/') !== -1 && navigator.userAgent.indexOf('Edge/') === -1,
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 + "*"),
@ -22,6 +23,7 @@ module.exports = FrankerFaceZ.constants = {
IS_OSX: IS_OSX,
IS_WIN: IS_WIN,
IS_WEBKIT: IS_WEBKIT,
META_NAME: IS_OSX ? "⌘" : (IS_WIN ? "Win" : "Meta"),
// Twitch Client ID for API Stuff

View file

@ -49,56 +49,48 @@ FFZ.prototype.setup_channel = function() {
Channel.reopen({
ffzUpdateInfo: function() {
return;
if ( this._ffz_update_timer )
clearTimeout(this._ffz_update_timer);
if ( ! this.get('channelModel.id') )
return;
this._ffz_update_timer = setTimeout(this.ffzCheckUpdate.bind(this), 55000 + (Math.random() * 10000));
}.observes("channelModel"),
}.observes("channelModel", "channelModel.hostModeTarget"),
ffzCheckUpdate: function() {
return;
var t = this,
channel_id = t.get('channelModel.id');
this.ffzUpdateInfo();
this._ffzUpdateModel(this.get('channelModel'));
this._ffzUpdateModel(this.get('channelModel.hostModeTarget'), true);
},
channel_id && utils.api.get("streams/" + channel_id, {}, {version:3})
_ffzUpdateModel: function(model, is_host) {
var channel_id = model && model.get('id');
if ( ! channel_id || model.get('isLoading') )
return;
utils.api.get("streams/" + channel_id, {}, {version: 3})
.done(function(data) {
// If it's loading, we can't update it or Ember will whine.
if ( t.get('channelModel.isLoading') )
return;
// If there's no stream, we can't update much.
if ( ! data || ! data.stream ) {
// If the stream is offline, clear its created_at time and set it to zero viewers.
t.set('channelModel.stream.createdAt', null);
t.set('channelModel.stream.viewers', 0);
model.set('stream.createdAt', null);
model.set('stream.viewers', 0);
return;
}
t.set('channelModel.stream.createdAt', utils.parse_date(data.stream.created_at) || null);
t.set('channelModel.stream.viewers', data.stream.viewers || 0);
var game = data.stream.game || (data.stream.channel && data.stream.channel.game);
if ( game ) {
t.set('channelModel.game', game);
}
model.set('stream.createdAt', utils.parse_date(data.stream.created_at));
model.set('stream.viewers', data.stream.viewers || 0);
model.set('stream.game', data.stream.game);
if ( data.stream.channel ) {
if ( data.stream.channel.status )
t.set('channelModel.status', data.stream.channel.status);
if ( data.stream.channel.views )
t.set('channelModel.views', data.stream.channel.views);
if ( data.stream.channel.followers && t.get('channelModel.followers.isFulfilled') )
t.set('channelModel.followers.content.meta.total', data.stream.channel.followers);
var info = data.stream.channel;
model.set('game', info.game);
model.set('status', info.status);
model.set('views', info.views);
if ( model.get('followers.isFulfilled') )
model.set('followers.content.meta.total', info.followers);
}
})
.always(function(data) {
t.ffzUpdateInfo();
if ( is_host && f._cindex )
f._cindex.ffzFixHostTitle();
});
},
@ -189,7 +181,7 @@ FFZ.prototype.modify_channel_live = function(view) {
}
this.$().on("click", ".ffz-creative-tag-link", utils.transition_link(function(e) {
utils.transition('creative.hashtag.index', this.getAttribute('data-tag'));
utils.transition('directory.creative.hashtag.index', this.getAttribute('data-tag'));
}));
},
@ -474,10 +466,9 @@ FFZ.prototype.modify_channel_live = function(view) {
if ( popup && popup.id === 'ffz-metadata-popup' && popup.getAttribute('data-key') === key )
return;
var data = info.setup ? info.setup.apply(f, basic_info) : basic_info;
data = info.setup ? info.setup.apply(f, data) : data;
var data = info.setup ? info.setup.apply(f, basic_info) : basic_info,
balloon = utils.createElement('div', 'balloon balloon--up show');
var balloon = utils.createElement('div', 'balloon balloon--up show');
data.unshift(balloon);
balloon.id = 'ffz-metadata-popup';
@ -563,7 +554,7 @@ FFZ.prototype.modify_channel_redesign = function(view) {
handleScroll: function(top) {
this._super();
var height = this.get('channelCoverHeight') + Layout.get('playerSize.1');
var height = this.get('channelCoverHeight') + Layout.get('fullSizePlayerDimensions.height');
document.body.classList.toggle('ffz-small-player', f.settings.small_player && top >= (height * .8));
},

View file

@ -487,8 +487,9 @@ FFZ.prototype.modify_from_display_preview = function(view) {
},
ffz_badges: function() {
var badges = f.get_twitch_badges(this.get('chatUser.chatBadges'));
return f.get_badges(this.get('userData.login'), this.get('chatUser.id'), badges);
var room_id = this.get('chatUser.id'),
badges = f.get_twitch_badges(this.get('chatUser.chatBadges'), room_id);
return f.get_badges(this.get('userData.login'), room_id, badges);
}.property('chatUser.chatBadges', 'userData.login', 'chatUser.id'),
/*ffzUpdateChatColor: function() {

View file

@ -203,9 +203,9 @@ FFZ.prototype.setup_directory = function() {
}),
areVodsViewable: function() {
var filtered = this.get('filteredVods');
return f.settings.enable_recommended_vods && filtered && filtered.length > 0;
}.property('filteredVods')
var vods = this.get('recommendedVods');
return f.settings.enable_recommended_vods && vods && vods.length > 0;
}.property('recommendedVods')
});
Ember.propertyDidChange(VodCoviews, 'isFollowingAboveHost');

View file

@ -173,9 +173,9 @@ FFZ.prototype.setup_layout = function() {
isTooSmallForRightColumn: function() {
if ( ! f.has_bttv && this.get('portraitMode') ) {
var size = this.get('playerSize'),
var size = this.get('fullSizePlayerDimensions'),
extra = this.get('ffzExtraHeight'),
height = size[1] + extra;
height = size.height + extra;
// Make sure we have at least a bit of room for the chat.
return this.get("windowHeight") < height;
@ -183,7 +183,7 @@ FFZ.prototype.setup_layout = function() {
} else
return this.get("windowWidth") < (1090 - this.get('rightColumnWidth'))
}.property("ffzExtraHeight", "windowWidth", "rightColumnWidth", "playerSize", "windowHeight"),
}.property("ffzExtraHeight", "windowWidth", "rightColumnWidth", "fullSizePlayerDimensions", "windowHeight"),
contentWidth: function() {
var left_width = this.get("isLeftColumnClosed") ? 50 : 240,
@ -199,7 +199,7 @@ FFZ.prototype.setup_layout = function() {
(f.settings.channel_title_top ? 70 : 80);
}.property(""),
playerSize: function() {
fullSizePlayerDimensions: function() {
var h = this.get('windowHeight'),
c = this.get('PLAYER_CONTROLS_HEIGHT'),
r = this.get('contentWidth'),
@ -215,17 +215,32 @@ FFZ.prototype.setup_layout = function() {
o = Math.floor(Math.min(i, d)),
s = Math.floor(Math.min(i, c));
return [l, o, s];
return {
width: l,
height: o,
targetHeight: s
}
}.property("ffzExtraHeight", "contentWidth", "windowHeight", "portraitMode", "PLAYER_CONTROLS_HEIGHT"),
playerStyle: function() {
var size = this.get('playerSize'),
width = size[0],
height = size[1],
host_height = size[2];
fullSizePlayerStyle: function() {
var size = this.get('fullSizePlayerDimensions');
return "<style>.ffz-small-player:not(.ffz-bttv)[data-current-path^=\"user.channel.\"] .app-main:not(.theatre) #player,.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .dynamic-target-player,.dynamic-target-player object,.ffz-small-player:not(.ffz-bttv)[data-current-path^=\"user.channel.\"] .app-main:not(.theatre) .cn-hosted #player, .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"),
return '<style>' +
'.ffz-small-player:not(.ffz-bttv)[data-current-path^="user.channel."] .app-main:not(.theatre) #player,' +
'.dynamic-player, .dynamic-player object, .dynamic-player video {' +
'width:' + size.width + 'px !important;' +
'height:' + size.height + 'px !important}' +
'.ffz-small-player:not(.ffz-bttv)[data-current-path^="user.channel."] .app-main:not(.theatre) #player,' +
'.dynamic-target-player, .dynamic-target-player object, .dynamic-target-player video {' +
'width:' + size.width + 'px !important;' +
'height:' + size.targetHeight + 'px !important}' +
'.dynamic-player .player object,' +
'.dynamic-player .player video {' +
'width: 100% !important;' +
'height: 100% !important}';
}.property("fullSizePlayerDimensions"),
ffzPortraitWarning: function() {
var t = this;
@ -260,10 +275,10 @@ FFZ.prototype.setup_layout = function() {
else {
if ( this.get('portraitMode') ) {
var size = this.get('playerSize'),
var size = this.get('fullSizePlayerDimensions'),
video_below = this.get('portraitVideoBelow'),
video_height = size[1] + this.get('ffzExtraHeight'),
video_height = size.height + this.get('ffzExtraHeight'),
chat_height = window_height - video_height,
video_top = video_below ? chat_height : 0,
@ -339,6 +354,8 @@ FFZ.prototype.setup_layout = function() {
'left:' + width + 'px !important}' +
'body:not(.ffz-sidebar-swap) #main_col:not(.expandRight) .cn-bar-fixed {' +
'right: ' + width + 'px}' +
'body.ffz-sidebar-swap .theatre .cn-metabar__more {' +
'left: ' + (width + 10) + 'px !important}' +
'body.ffz-sidebar-swap #main_col:not(.expandRight) .cn-bar-fixed {' +
'left: ' + width + 'px !important}' +
'.ffz-theater-stats .app-main.theatre .cn-metabar__more {' +
@ -349,7 +366,7 @@ FFZ.prototype.setup_layout = function() {
f._layout_style.innerHTML = out;
}
}.observes("ffzExtraHeight", "isRightColumnClosed", "playerSize", "rightColumnWidth", "portraitMode", "windowHeight", "windowWidth"),
}.observes("ffzExtraHeight", "isRightColumnClosed", "fullSizePlayerDimensions", "rightColumnWidth", "portraitMode", "windowHeight", "windowWidth"),
ffzUpdatePlayerStyle: function() {
Ember.propertyDidChange(Layout, 'playerStyle');
@ -368,7 +385,7 @@ FFZ.prototype.setup_layout = function() {
cr && cr.css && cr.css('top', f._chatv._ffz_tabs.offsetHeight + "px");
},0);
}
}.observes("isRightColumnClosed", "rightColumnWidth", "portraitMode", "playerSize")
}.observes("isRightColumnClosed", "rightColumnWidth", "portraitMode", "fullSizePlayerDimensions")
});

View file

@ -95,13 +95,13 @@ FFZ.settings_info.highlight_messages_with_mod_card = {
FFZ.settings_info.logviewer_test = {
type: "boolean",
value: false,
value: true,
no_bttv: true,
category: "Chat Moderation",
name: "Logviewer Integration <small>Beta</small>",
help: "Display information from CBenni's logviewer directly on moderation cards."
name: "Logviewer Integration",
help: "Display information from CBenni's Logviewer directly on moderation cards."
}

View file

@ -154,6 +154,7 @@ FFZ.prototype.setup_room = function() {
var inst = instances[key];
this.add_room(inst.id, inst);
this._modify_room(inst);
inst.ffzUpdateBadges();
inst.ffzPatchTMI();
}
@ -334,11 +335,6 @@ FFZ.prototype.modify_room_view = function(view) {
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);
if ( is_android )
@ -418,12 +414,6 @@ FFZ.prototype.modify_room_view = 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();
},
@ -518,14 +508,27 @@ FFZ.prototype.modify_room_view = function(view) {
return;
this._ffz_messages = messages;
if ( ! this._ffz_interval )
this._ffz_interval = setInterval(this.ffzPulse.bind(this), 200);
if ( ! this._ffz_mouse_move ) {
this._ffz_mouse_move = this.ffzMouseMove.bind(this);
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
messages.addEventListener('mousemove', this._ffz_mouse_move);
messages.addEventListener('touchmove', this._ffz_mouse_move);
}
if ( ! this._ffz_mouse_out ) {
this._ffz_mouse_out = this.ffzMouseOut.bind(this);
messages.addEventListener('mouseout', this._ffz_mouse_out);
}
// Monitor the Ctrl key.
if ( ! this._ffz_keyw ) {
this._ffz_keyw = this.ffzOnKey.bind(this);
document.body.addEventListener('keydown', this._ffz_keyw);
document.body.addEventListener('keyup', this._ffz_keyw);
}
},
ffzDisableFreeze: function() {
@ -552,6 +555,12 @@ FFZ.prototype.modify_room_view = function(view) {
messages.removeEventListener('mouseout', this._ffz_mouse_out);
this._ffz_mouse_out = undefined;
}
if ( this._ffz_keyw ) {
document.body.removeEventListener('keydown', this._ffz_keyw);
document.body.removeEventListener('keyup', this._ffz_keyw);
this._ffz_keyw = undefined;
}
},
ffzPulse: function() {
@ -883,6 +892,11 @@ FFZ.prototype.add_room = function(id, room) {
}
}
// Store the badges for this room now if we have them.
var bs = utils.ember_lookup('service:badges');
if ( bs && bs.badgeCollection && bs.badgeCollection.channel && bs.badgeCollection.channel.broadcasterName === id )
data.badges = bs.badgeCollection.channel;
// Look up if the room has moderation logs.
var f = this;
this.ws_send("has_logs", id, function(success, response) {
@ -950,172 +964,6 @@ FFZ.prototype.remove_room = function(id) {
}
// --------------------
// Chat History
// --------------------
/*FFZ.prototype._load_history = function(room_id, success, data) {
var room = this.rooms[room_id];
if ( ! room || ! room.room )
return;
if ( success )
this.log("Received " + data.length + " old messages for: " + room_id);
else
return this.log("Error retrieving chat history for: " + room_id);
if ( ! data.length )
return;
return this._insert_history(room_id, data, true);
}*/
/*FFZ.prototype._show_deleted = function(room_id) {
var room = this.rooms[room_id];
if ( ! room || ! room.room )
return;
var old_messages = room.room.get('messages.0.ffz_old_messages');
if ( ! old_messages || ! old_messages.length )
return;
room.room.set('messages.0.ffz_old_messages', undefined);
this._insert_history(room_id, old_messages);
}
FFZ.prototype._insert_history = function(room_id, data, from_server) {
var room = this.rooms[room_id], f = this;
if ( ! room || ! room.room )
return;
var current_user = this.get_user(),
r = room.room,
messages = r.get('messages'),
buffer_size = r.get('messageBufferSize'),
tmiSession = r.tmiSession || (TMI._sessions && TMI._sessions[0]),
delete_links = r.get('roomProperties.hide_chat_links'),
removed = 0,
inserted = 0,
first_inserted,
first_existing,
before;
first_existing = messages.length ? messages[0] : null;
if ( first_existing && first_existing.from === 'jtv' && first_existing.message === 'Welcome to the chat room!' )
first_existing = messages.length > 1 ? messages[1] : null;
if ( first_existing )
before = first_existing.date && first_existing.date.getTime();
this.parse_history(data, null, null, room_id, delete_links, tmiSession, function(msg) {
if ( from_server )
msg.from_server = true;
// Skip messages that are from the future.
if ( ! msg.date || (before && (before - (msg.from_server && ! first_existing.from_server ? f._ws_server_offset || 0 : 0)) < msg.date.getTime()) )
return true;
if ( f.settings.remove_deleted && msg.deleted )
return true;
if ( msg.tags && msg.tags.target && msg.tags.target !== '@@' ) {
var is_mine = current_user && current_user.login === msg.tags.target;
if ( ! is_mine && ! r.ffzShouldDisplayNotice() )
return true;
// Display the Ban Reason if we're a moderator or that user.
if ( msg.tags['ban-reason'] && (is_mine || r.get('isModeratorOrHigher')) ) {
msg.message = msg.message.substr(0, msg.message.length - 1) + ' with reason: ' + msg.tags['ban-reason'];
msg.cachedTokens = [utils.sanitize(msg.message)];
}
}
if ( r.shouldShowMessage(msg) && r.ffzShouldShowMessage(msg) ) {
if ( messages.length < buffer_size ) {
if ( msg.ffz_old_messages ) {
var max_messages = buffer_size - (messages.length + 1);
if ( max_messages <= 0 )
msg.ffz_old_messages = null;
else if ( msg.ffz_old_messages.length > max_messages )
msg.ffz_old_messages = msg.ffz_old_messages.slice(msg.ffz_old_messages.length - max_messages);
}
if ( ! first_inserted )
first_inserted = msg;
// Store the message ID for this message, of course.
var msg_id = msg.tags && msg.tags.id,
notice_type = msg.tags && msg.tags['msg-id'],
ids = r.ffz_ids = r.ffz_ids || {},
notices = r.ffz_last_notices = r.ffz_last_notices || {};
if ( msg_id && ! ids[msg_id] )
ids[msg_id] = msg;
if ( notice_type && ! notices[notice_type] )
notices[notice_type] = msg;
messages.unshiftObject(msg);
inserted += 1;
} else
return false;
}
// If there's a CLEARCHAT, stop processing.
if ( msg.tags && msg.tags.target === '@@' )
return false;
return true;
});
if ( ! first_inserted )
return;
var now = Date.now() - (first_inserted.from_server ? this._ws_server_offset || 0 : 0),
age = now - first_inserted.date.getTime();
if ( age > 300000 ) {
var msg = {
color: "#755000",
date: first_inserted.date,
from: "frankerfacez_admin",
style: "admin",
message: "(Last message is " + utils.human_time(age/1000) + " old.)",
room: room_id,
from_server: from_server
};
this.tokenize_chat_line(msg, false, delete_links);
if ( r.shouldShowMessage(msg) ) {
messages.insertAt(inserted, msg);
while ( messages.length > buffer_size ) {
// Remove this message from the ID tracker.
var m = messages.get(0),
msg_id = m.tags && m.tags.id,
notice_type = m.tags && m.tags['msg-id'];
if ( msg_id && r.ffz_ids && r.ffz_ids[msg_id] )
delete r.ffz_ids[msg_id];
if ( notice_type && r.ffz_last_notices && r.ffz_last_notices[notice_type] === m )
delete r.ffz_last_notices[notice_type];
messages.removeAt(0);
removed++;
}
}
}
}*/
// --------------------
// Receiving Set Info
// --------------------
@ -1206,6 +1054,24 @@ FFZ.prototype._modify_room = function(room) {
mru_list: [],
ffzUpdateBadges: function() {
var room_name = this.get('id'),
room_id = this.get('roomProperties._id'),
ffz_room = f.rooms && f.rooms[room_name];
if ( ! ffz_room || ! room_id || ffz_room.badges )
return;
fetch("https://badges.twitch.tv/v1/badges/channels/" + room_id + "/display?language=" + (Twitch.receivedLanguage || "en"), {
headers: {
'Client-ID': constants.CLIENT_ID
}
}).then(utils.json).then(function(data) {
ffz_room.badges = data && data.badge_sets;
});
}.observes('roomProperties._id'),
updateWait: function(value, was_banned, update) {
var wait = this.get('slowWait') || 0;
this.set('slowWait', value);
@ -1913,12 +1779,16 @@ FFZ.prototype._modify_room = function(room) {
// Split this into two messages if requested.
if ( is_resub && f.settings.old_sub_notices ) {
var message = msg.tags['system-msg'],
months = /for (\d+) months/.exec(message);
this.addMessage({
style: "notification",
from: "twitchnotify",
date: msg.date || new Date,
room: room_id,
message: msg.tags['system-msg']
message: message,
ffz_sub_months: months && parseInt(months[1])
});
// If there's no message just quit now.
@ -1969,7 +1839,20 @@ FFZ.prototype._modify_room = function(room) {
msg.tags = {};
if ( ! msg.tags.badges )
msg.tags.badges = {};
msg.tags.badges.subscriber = '1';
var ffz_room = f.rooms && f.rooms[room_id],
badges = ffz_room && ffz_room.badges || {},
sub_version = badges && badges.subscriber && badges.subscriber.versions;
if ( ! isNaN(msg.ffz_sub_months) ) {
var months = msg.ffz_sub_months;
msg.tags.badges.subscriber = ( months >= 24 && sub_version[24] ) ? 24 :
(months >= 12 && sub_version[12] ) ? 12 :
(months >= 6 && sub_version[6] ) ? 6 :
(months >= 3 && sub_version[3] ) ? 3 : 1;
} else
msg.tags.badges.subscriber = 1;
msg.tags.subscriber = true;
if ( msg.labels && msg.labels.indexOf("subscriber") === -1 )
msg.labels.push("subscriber");

View file

@ -261,6 +261,9 @@ FFZ.prototype.modify_navigation = function(component) {
ffz_init: function() {
f._nav = this;
// Fix tooltips now that we've overrode the function.
this._initTooltips();
// Override behavior for the Following link.
var el = this.get('element'),
following_link = el && el.querySelector('a[data-href="following"]');
@ -280,6 +283,35 @@ FFZ.prototype.modify_navigation = function(component) {
return false;
});
}
// Find the Settings warp item.
/*var settings_svg = el && el.querySelector('.svg-nav_settings');
if ( settings_svg ) {
var warp = settings_svg.parentElement.parentElement.parentElement,
container = warp.parentElement;
var figure = utils.createElement('figure', 'warp__avatar', constants.ZREKNARF),
span = utils.createElement('span', 'is-drawer-closed--hide', 'FrankerFaceZ Settings'),
ffz_setting = utils.createElement('a', 'ffz-settings-link html-tooltip', figure),
ffz_warp = utils.createElement('li', 'warp__item', ffz_setting);
ffz_setting.title = 'FrankerFaceZ Settings';
ffz_setting.appendChild(span);
container.insertBefore(ffz_warp, warp.nextElementSibling);
}*/
},
_initTooltips: function() {
this._tipsySelector = this.$("#js-warp a, #small_search button, #small_more button");
this._tipsySelector.off("mouseenter").off("mouseleave").teardownTipsy();
this._tipsySelector.tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'w')});
this.$('a[data-href="following"]').tipsy({
html: true,
className: function() { return f.settings.following_count ? 'ffz-wide-tip' : '' },
title: function() { return f._build_following_tooltip(this) },
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE * 2, 'w')
});
},
ffz_destroy: function() {

View file

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

View file

@ -121,7 +121,7 @@ metadata.player_stats = {
var bitrate;
if ( stats.playback_bytes_per_second )
bitrate = Math.round(stats.playback_bytes_per_second * 8 / 10.24) / 1000;
bitrate = Math.round(stats.playback_bytes_per_second * 8 / 10.24) / 100;
else
bitrate = Math.round(stats.current_bitrate * 100) / 100;

View file

@ -549,7 +549,7 @@ FFZ.mod_card_pages.stats = {
});
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>';
notice.innerHTML = 'Chat Log Source: <a target="_blank" href="https://cbenni.com/' + room_id + '?user=' + user_id + '">CBenni\'s Logviewer</a>';
el.appendChild(notice);
}
}
@ -714,7 +714,7 @@ FFZ.mod_card_pages.notes = {
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_submit = utils.createElement('a', 'button float-right', 'Add Note'),
btn_container = utils.createElement('div', 'chat-buttons-container clearfix', btn_submit),
submit_note = function() {

View file

@ -3593,8 +3593,9 @@ body:not(.ffz-channel-bar-bottom).ffz-small-player.ffz-minimal-channel-bar #play
}
.cn-hosting--bottom { padding-right: 0 }
#ffz-metadata-popup .button { margin: 0 }
.cn-hosting--bottom .button,
.cn-hosting--bottom .button:not(.follow-button),
.ffz-channel-options .qa-channel-options,
.ffz-share-box .qa-share-box__button { margin: 0 !important }
@ -3608,7 +3609,8 @@ body:not(.ffz-channel-bar-bottom).ffz-small-player.ffz-minimal-channel-bar #play
.cn-metabar__more > .ffz-share-box { order: 101 }
.cn-metabar__more > .ffz-channel-options { order: 999; margin-right: 0 !important }
.cn-hosting--bottom > .follow-button { order: 1; margin-right: 0 !important }
.cn-hosting--bottom > .follow-button { order: 1 }
.cn-hosting--bottom > .follow-button.is-following { margin-right: 0 !important }
.cn-hosting--bottom > .notification-controls { order: 1 }
.cn-hosting--bottom > span.ember-view { order: 2 }