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

4.0.0-rc12.10

* Fixed: Chat Width not applying correctly on pages like Videos on the old channel layout.
* Changed: Implement an IntersectionObserver into the emote menu in an attempt to get the menu rendering faster when there are an incredible number of emote sets.

* Changed: Roll out the new API experiment to 25%. (This is still pulling data from the old server, and merely serves to test the performance of the new server stack.)
This commit is contained in:
SirStendec 2018-08-16 23:33:27 -04:00
parent 6518c8e7a4
commit 1c19fe2282
6 changed files with 136 additions and 8 deletions

View file

@ -3,8 +3,8 @@
"name": "New API Stress Testing", "name": "New API Stress Testing",
"description": "Send duplicate requests to the new API server for load testing.", "description": "Send duplicate requests to the new API server for load testing.",
"groups": [ "groups": [
{"value": true, "weight": 0}, {"value": true, "weight": 25},
{"value": false, "weight": 100} {"value": false, "weight": 75}
] ]
} }
} }

View file

@ -100,7 +100,7 @@ class FrankerFaceZ extends Module {
FrankerFaceZ.Logger = Logger; FrankerFaceZ.Logger = Logger;
const VER = FrankerFaceZ.version_info = { const VER = FrankerFaceZ.version_info = {
major: 4, minor: 0, revision: 0, extra: '-rc12.9', major: 4, minor: 0, revision: 0, extra: '-rc12.10',
commit: __git_commit__, commit: __git_commit__,
build: __webpack_hash__, build: __webpack_hash__,
toString: () => toString: () =>

View file

@ -189,7 +189,7 @@ export default class Room {
if ( this.manager.experiments.getAssignment('api_load') ) if ( this.manager.experiments.getAssignment('api_load') )
try { try {
fetch(`${NEW_API}/v1/rooms/${this.id ? `id/${this.id}` : this.login}`).catch(() => {}); fetch(`${NEW_API}/v1/room/${this.id ? `id/${this.id}` : this.login}`).catch(() => {});
} catch(err) { /* do nothing */ } } catch(err) { /* do nothing */ }
let response, data; let response, data;

View file

@ -440,8 +440,21 @@ export default class EmoteMenu extends Module {
constructor(props) { constructor(props) {
super(props); super(props);
this.ref = null;
this.saveRef = ref => {
if ( this.ref )
this.props.stopObserving(this.ref);
this.ref = ref;
if ( ref )
this.props.startObserving(this.ref, this);
}
const collapsed = storage.get('emote-menu.collapsed') || []; const collapsed = storage.get('emote-menu.collapsed') || [];
this.state = {collapsed: props.data && collapsed.includes(props.data.key)} this.state = {
collapsed: props.data && collapsed.includes(props.data.key),
intersecting: window.IntersectionObserver ? false : true
}
this.clickHeading = this.clickHeading.bind(this); this.clickHeading = this.clickHeading.bind(this);
this.clickEmote = this.clickEmote.bind(this); this.clickEmote = this.clickEmote.bind(this);
@ -450,6 +463,16 @@ export default class EmoteMenu extends Module {
this.onMouseLeave = this.onMouseLeave.bind(this); this.onMouseLeave = this.onMouseLeave.bind(this);
} }
componentDidMount() {
if ( this.ref )
this.props.startObserving(this.ref, this);
}
componentWillUnmount() {
if ( this.ref )
this.props.stopObserving(this.ref);
}
clickEmote(event) { clickEmote(event) {
if ( t.emotes.handleClick(event) ) if ( t.emotes.handleClick(event) )
return; return;
@ -534,7 +557,7 @@ export default class EmoteMenu extends Module {
} }
} }
return (<section data-key={data.key} class={filtered ? 'filtered' : ''}> return (<section ref={this.saveRef} data-key={data.key} class={filtered ? 'filtered' : ''}>
{show_heading ? (<heading class="tw-pd-1 tw-border-b tw-flex tw-flex-nowrap" onClick={this.clickHeading}> {show_heading ? (<heading class="tw-pd-1 tw-border-b tw-flex tw-flex-nowrap" onClick={this.clickHeading}>
{image} {image}
<div class="tw-pd-l-05"> <div class="tw-pd-l-05">
@ -584,6 +607,9 @@ export default class EmoteMenu extends Module {
} }
renderEmote(emote, locked, source, sellout) { renderEmote(emote, locked, source, sellout) {
if ( ! this.state.intersecting )
return <span key={emote.id} class="emote-picker__placeholder" style={{width: `${emote.width||28}px`, height: `${emote.height||28}px`}} />;
return (<button return (<button
key={emote.id} key={emote.id}
class={`ffz-tooltip emote-picker__emote-link${locked ? ' locked' : ''}`} class={`ffz-tooltip emote-picker__emote-link${locked ? ' locked' : ''}`}
@ -685,11 +711,23 @@ export default class EmoteMenu extends Module {
} }
} }
let timer;
const doClear = () => this.emit('tooltips:cleanup'),
clearTooltips = () => {
clearTimeout(timer);
setTimeout(doClear, 100);
};
this.MenuComponent = class FFZEmoteMenuComponent extends React.Component { this.MenuComponent = class FFZEmoteMenuComponent extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.ref = null;
this.saveScrollRef = ref => {
this.ref = ref;
this.createObserver();
}
this.state = { this.state = {
tab: null, tab: null,
tone: t.settings.provider.get('emoji-tone', null) tone: t.settings.provider.get('emoji-tone', null)
@ -697,6 +735,11 @@ export default class EmoteMenu extends Module {
this.componentWillReceiveProps(props); this.componentWillReceiveProps(props);
this.observing = new Map;
this.startObserving = this.startObserving.bind(this);
this.stopObserving = this.stopObserving.bind(this);
this.handleObserve = this.handleObserve.bind(this);
this.pickTone = this.pickTone.bind(this); this.pickTone = this.pickTone.bind(this);
this.clickTab = this.clickTab.bind(this); this.clickTab = this.clickTab.bind(this);
this.clickRefresh = this.clickRefresh.bind(this); this.clickRefresh = this.clickRefresh.bind(this);
@ -704,11 +747,87 @@ export default class EmoteMenu extends Module {
this.handleKeyDown = this.handleKeyDown.bind(this); this.handleKeyDown = this.handleKeyDown.bind(this);
} }
createObserver() {
if ( this.observer ) {
if ( this._observed === this.ref )
return;
this.observer.disconnect();
this.observer = this._observed = null;
}
if ( ! this.ref || ! window.IntersectionObserver )
return;
this._observed = this.ref;
this.observer = new IntersectionObserver(this.handleObserve, {
root: this.ref,
rootMargin: '50px 0px',
threshold: 0.01
});
for(const element of this.observing.keys())
this.observer.observe(element);
}
destroyObserver() {
if ( ! this.observer )
return;
this.observer.disconnect();
this.observer = this._observed = null;
}
handleObserve(event) {
let changed = false;
for(const entry of event) {
const inst = this.observing.get(entry.target);
if ( ! inst || inst.state.intersecting === entry.isIntersecting )
continue;
changed = true;
inst.setState({
intersecting: entry.isIntersecting
});
}
if ( changed )
requestAnimationFrame(clearTooltips);
}
startObserving(element, inst) {
const old_inst = this.observing.get(element);
if ( inst === old_inst )
return;
if ( old_inst )
this.stopObserving(element);
this.observing.set(element, inst);
if ( this.observer )
this.observer.observe(element);
}
stopObserving(element) {
if ( ! this.observing.has(element) )
return;
this.observing.delete(element);
if ( this.observer )
this.observer.unobserve(element);
}
componentDidMount() { componentDidMount() {
if ( this.ref )
this.createObserver();
window.ffz_menu = this; window.ffz_menu = this;
} }
componentWillUnmount() { componentWillUnmount() {
this.destroyObserver();
if ( window.ffz_menu === this ) if ( window.ffz_menu === this )
window.ffz_menu = null; window.ffz_menu = null;
} }
@ -1439,7 +1558,7 @@ export default class EmoteMenu extends Module {
data-test-selector="scrollable-area-wrapper" data-test-selector="scrollable-area-wrapper"
data-simplebar data-simplebar
> >
<div class="simplebar-scroll-content"> <div ref={this.saveScrollRef} class="simplebar-scroll-content">
<div class="simplebar-content"> <div class="simplebar-content">
{loading && this.renderLoading()} {loading && this.renderLoading()}
{!loading && sets && sets.map(data => createElement( {!loading && sets && sets.map(data => createElement(
@ -1448,7 +1567,9 @@ export default class EmoteMenu extends Module {
key: data.key, key: data.key,
data, data,
filtered: this.state.filtered, filtered: this.state.filtered,
onClickEmote: this.props.onClickEmote onClickEmote: this.props.onClickEmote,
startObserving: this.startObserving,
stopObserving: this.stopObserving
} }
))} ))}
{! loading && (! sets || ! sets.length) && this.renderEmpty()} {! loading && (! sets || ! sets.length) && this.renderEmpty()}

View file

@ -10,6 +10,7 @@ body .channel-page__video-player--theatre-mode {
body .video-watch-page__right-column, body .video-watch-page__right-column,
body .channel-page__right-column, body .channel-page__right-column,
body .right-column:not(.right-column--collapsed), body .right-column:not(.right-column--collapsed),
body .channel-videos__right-column,
body .channel-root__right-column { body .channel-root__right-column {
width: var(--ffz-chat-width); width: var(--ffz-chat-width);
} }

View file

@ -133,6 +133,12 @@
opacity: 0.5; opacity: 0.5;
} }
.emote-picker__placeholder {
display: inline-block;
margin: .5rem .5rem 0;
min-width: 2.8rem;
}
.emote-picker__tab { .emote-picker__tab {
border-top: 1px solid transparent; border-top: 1px solid transparent;