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:
parent
12427d2750
commit
a89b71f0a2
14 changed files with 217 additions and 259 deletions
|
@ -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>
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
},
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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")
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 || "");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue