From ed0577f09e354abb5053bc1c8f24c0ba10fa17f9 Mon Sep 17 00:00:00 2001 From: SirStendec Date: Tue, 30 Jun 2020 19:48:46 -0400 Subject: [PATCH] 4.20.1 * Added: Option to hide Twitch's native stream uptime. Enabled by default when using FFZ's own stream uptime. * Fixed: Implement stream metadata for the new Twitch layout. * Fixed: Display the subscription tier in badge tool-tips for Tier 2 and Tier 3 subscriber badges. This release involves significant changes under the hood. Due to Twitch's heavy use of functional React components and effects in recent updates to their site, we need to start listening for DOM nodes rather than components in many cases. To that end, I've implemented the Elemental module to grab elements using MutationObservers. I didn't want to, but this is where we're at. In a future release I'll be using Elemental to add support back to the directory for certain features. --- package.json | 2 +- src/experiments.json | 4 +- src/modules/chat/badges.jsx | 17 +- src/modules/chat/room.js | 10 + src/modules/metadata.jsx | 30 +- src/sites/twitch-twilight/index.js | 10 + src/sites/twitch-twilight/modules/channel.js | 579 ++++++------------ .../twitch-twilight/modules/channel_bar.jsx | 291 --------- .../twitch-twilight/modules/chat/index.js | 214 +++---- .../modules/css_tweaks/index.js | 16 + .../css_tweaks/styles/hide-native-uptime.scss | 9 + .../modules/directory/game.jsx | 4 +- src/sites/twitch-twilight/modules/player.jsx | 35 +- src/sites/twitch-twilight/styles/channel.scss | 15 + src/utilities/compat/elemental.js | 302 +++++++++ src/utilities/compat/fine.js | 5 + 16 files changed, 719 insertions(+), 824 deletions(-) delete mode 100644 src/sites/twitch-twilight/modules/channel_bar.jsx create mode 100644 src/sites/twitch-twilight/modules/css_tweaks/styles/hide-native-uptime.scss create mode 100644 src/utilities/compat/elemental.js diff --git a/package.json b/package.json index bf9810c4..543e9ade 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "frankerfacez", "author": "Dan Salvato LLC", - "version": "4.20.0", + "version": "4.20.1", "description": "FrankerFaceZ is a Twitch enhancement suite.", "license": "Apache-2.0", "scripts": { diff --git a/src/experiments.json b/src/experiments.json index c65bfa4d..257f9b09 100644 --- a/src/experiments.json +++ b/src/experiments.json @@ -3,8 +3,8 @@ "name": "New API Stress Testing", "description": "Send duplicate requests to the new API server for load testing.", "groups": [ - {"value": true, "weight": 50}, - {"value": false, "weight": 50} + {"value": true, "weight": 25}, + {"value": false, "weight": 75} ] } } \ No newline at end of file diff --git a/src/modules/chat/badges.jsx b/src/modules/chat/badges.jsx index f93418e0..4e3c2ec7 100644 --- a/src/modules/chat/badges.jsx +++ b/src/modules/chat/badges.jsx @@ -358,12 +358,21 @@ export default class Badges extends Module { continue; let title = bd.title || global_badge.title; + const tier = bd.tier || global_badge.tier; + if ( d.data ) { if ( d.badge === 'subscriber' ) { - title = this.i18n.t('badges.subscriber.months', '{title} ({count,number} Month{count,en_plural})', { - title, - count: d.data - }); + if ( tier > 0 ) + title = this.i18n.t('badges.subscriber.tier-months', '{title}\n(Tier {tier}, {months,number} Month{months,en_plural})', { + title, + tier, + months: d.data + }); + else + title = this.i18n.t('badges.subscriber.months', '{title}\n({count,number} Month{count,en_plural})', { + title, + count: d.data + }); } else if ( d.badge === 'founder' ) { title = this.i18n.t('badges.founder.months', '{title}\n(Subscribed for {count,number} Month{count,en_plural})', { title, diff --git a/src/modules/chat/room.js b/src/modules/chat/room.js index f227a993..698162e0 100644 --- a/src/modules/chat/room.js +++ b/src/modules/chat/room.js @@ -401,6 +401,16 @@ export default class Room { const sid = data.setID, bs = b[sid] = b[sid] || {}; + if ( sid === 'subscriber' ) { + const id = parseInt(data.version, 10); + if ( ! isNaN(id) && isFinite(id) ) { + data.tier = (id - (id % 1000)) / 1000; + if ( data.tier < 0 ) + data.tier = 0; + } else + data.tier = 0; + } + bs[data.version] = data; this.badge_count++; } diff --git a/src/modules/metadata.jsx b/src/modules/metadata.jsx index 5cfde0fc..d36552f6 100644 --- a/src/modules/metadata.jsx +++ b/src/modules/metadata.jsx @@ -81,14 +81,17 @@ export default class Metadata extends Module { refresh() { return this.settings.get('metadata.uptime') > 0 }, setup(data) { - const socket = this.resolve('socket'), - created_at = data?.meta?.createdAt; + const socket = this.resolve('socket'); + let created = data?.channel?.live_since; + if ( ! created ) { + const created_at = data?.meta?.createdAt; + if ( ! created_at ) + return {}; - if ( ! created_at ) - return {}; + created = new Date(created_at); + } - const created = new Date(created_at), - now = Date.now() - socket._time_drift; + const now = Date.now() - socket._time_drift; return { created, @@ -381,7 +384,12 @@ export default class Metadata extends Module { } updateMetadata(keys) { - const bar = this.resolve('site.channel_bar'); + const channel = this.resolve('site.channel'); + if ( channel ) + for(const el of channel.InfoBar.instances) + channel.updateMetadata(el, keys); + + /*const bar = this.resolve('site.channel_bar'); if ( bar ) { for(const inst of bar.ChannelBar.instances) bar.updateMetadata(inst, keys); @@ -391,7 +399,7 @@ export default class Metadata extends Module { if ( legacy_bar ) { for(const inst of legacy_bar.ChannelBar.instances) legacy_bar.updateMetadata(inst, keys); - } + }*/ } async renderLegacy(key, data, container, timers, refresh_fn) { @@ -465,7 +473,7 @@ export default class Metadata extends Module { if ( def.popup && def.click ) { el = (
@@ -490,7 +498,7 @@ export default class Metadata extends Module { } else btn = popup = el = (