Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regarding Co-Existence with FrankerFaceZ #3609

Closed
SirStendec opened this issue Oct 12, 2019 · 3 comments
Closed

Regarding Co-Existence with FrankerFaceZ #3609

SirStendec opened this issue Oct 12, 2019 · 3 comments

Comments

@SirStendec
Copy link

Hello,

As everyone involved is well aware of at this point, FrankerFaceZ and BetterTTV currently conflict in certain ways that can cause our users to have reduced experiences with our respective applications. I'd like to propose a set of modifications to both extensions to hopefully bring them into harmony.

The root cause of the incompatibility is a difference in how the two extensions modify existing page elements. BetterTTV, to the best of my knowledge, uses MutationObservers exclusively to react to elements being added to the DOM, and adds event listeners to those DOM elements.

FrankerFaceZ discovers React components by listening for DOM changes with a MutationObserver and then walking the React component tree. Once FFZ has found what it wants, it relies on a combination of directly modifying React components' render() methods as well as installing hooks to their life-cycle events. When FrankerFaceZ alters a React component by modifying its render() method, we then call forceUpdate() on the React element, which can at times result in an existing DOM subtree being removed and recreated, depending on what changes.

Unfortunately, when React updates in that way it often doesn't trigger BetterTTV's MutationObservers and the extension does not recreate its event listeners.

My proposal is the creation of an event handler that FrankerFaceZ could use to notify BetterTTV when important parts of the DOM have updated, such that BetterTTV can then make sure that its own event listeners are still functioning correctly. Alternatively, FrankerFaceZ already exposes itself in the page and acts as an EventEmitter, so I could add a set of events that BetterTTV could itself listen to. Something like:

BetterTTV.handleEvent("dom-update", "chat-input", element);
// or
FrankerFaceZ.get().on(":dom-update", (key, element) => {
    ...
});

Elements that FrankerFaceZ updates that I feel relevant to this include: the chat Input area, the chat settings menu, and individual chat lines. Events would be fired within a requestAnimationFrame() after FrankerFaceZ updates a component with forceUpdate(). Events would not be fired unless forceUpdate() is used.

There are other elements that FFZ can update, but I'm unaware of any issues with anything not directly involving chat.


Additionally, while this does not represent as significant an issue with user experience, I have had some users expressing confusion that BetterTTV emotes are not included within our emote menu. If that's something you'd be interested in, I wouldn't mind access to a method that retrieves information on a user's available BetterTTV emotes.

Thanks,

Hopefully we can work together and get all this sorted out.

@SirStendec
Copy link
Author

Just a quick update on this. I had to push an update tonight for an unrelated issue, so I implemented an example of the second event I suggested. The following event is live:

FrankerFaceZ.get().on("core:dom-update", (key /* String */, element /* Node */, react /* Component */) => {
    ...
});

element may be null if the component has no child DOM nodes.

It would be better, I think, if BetterTTV had an event handler I could pump this event into rather than putting the burden of detecting FFZ onto BTTV. That way there'd be no concern of a race issue making BTTV miss the initial updates when FFZ loads.

This is assuming, of course, that you're open to the idea of passing events like this. Please let me know what you think.

@night
Copy link
Owner

night commented Oct 14, 2019

You can now emit loads to BetterTTV (in 7.2.70), which will retrigger bindings to ui elements.

window.BetterTTV.watcher.emitLoad('chat');

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related issues or feature requests.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants