showmy.chat
showmy.chat copied to clipboard
Remove deletion delay when themes don't animate/transition outgoing messages
This feels a bit weird for themes without an animation. I'd expect messages to disappear after the time I set in the urlbuilder on the homepage. For themes with an animation: the animation starts at the time I set. For themes without: do they stay onscreen for the time I set + 1.2s?
Originally posted by @NickyMeuleman in https://github.com/BenDMyers/showmy.chat/pull/91#discussion_r813480092
In #91, showmy.chat added an API to animate messages as they were being deleted (data-twitch-message-display-status="deleting"
). However, this meant that we couldn't remove messages immediately — we had to apply the style hook, wait a bit (1.2 seconds), and then delete.
This works great for themes that have outgoing message animations, but it introduces a delay when no animations are used — the overlay user says "remove messages after 5 seconds," and the overlay actually removes them after 6.2 seconds. This isn't noticeable after a long enough message lifespan (the difference between 20 seconds and 21.2 seconds isn't especially profound). However, it would be nice if we could tighten the gap between when the user says to remove messages and when we actually remove them in the case that the theme doesn't animate outgoing messages.
Themes could use either CSS transitions or CSS animations to animate an outgoing message. To detect animations, we've found the getAnimations
method, which landed in Chrome 84. With Twitch streamers forced to update their OBS instances soon to continue streaming to Twitch, using >75
Chrome APIs is on the table, but I'd like to give it a few months before we start using >75
APIs just to be safe.
do animations fire a transitionend
event?
@fimion Animations fire an animationend
event, but I don't believe they fire transitionend
.
We're using both transitionend
and animationend
as cues to go ahead and remove the element, and they work well from what we've seen.
From src/scripts/utilities.mjs
// Give animation a chance
messageToDelete.addEventListener(
'transitionend',
_callbackRemoveMessageFromDom
);
messageToDelete.addEventListener(
'animationend',
_callbackRemoveMessageFromDom
);
// If no animation, delete anyways
setTimeout(_callbackRemoveMessageFromDom, 1200);
In case of no animation/transition, or an animation/transition that takes too long, we have that setTimeout
call that'll delete the node anyways after 1.2 seconds.
The animationend
/transitionend
work well — if a theme supplies some sort of "deleting" animation that takes less than 1.2 seconds, it'll be respected, and the element will be deleted immediately after the animation/transition is done.
The trouble here is in cases where themes don't supply a "deleting" animation/transition, meaning that the overlay will wait a full 1.2 seconds to make time for an animation/transition that isn't happening.
use getComputedStyles
to check for an animation or transition?
Also, context on why 1.2 seconds: I figured the absolute longest a "deleting" message should take should be one second. Ideally, deletions would take even less time — since oftentimes, the goal is to clear up space or remove spam and bigotry, and so the goal should be to make sure the message GTFOs. With a 1 second max deletion time, I gave an extra 0.2 sec as a bit of a buffer — hence 1.2 seconds.
use
getComputedStyles
to check for an animation or transition?
@fimion I think this could work! Any chance you'd be interested in (and available for) spinning up a PR?
let me take a look at it, because this would also potentially mess with anything that has a transition/animation for insertion or whatever.
For sure. For what it's worth, now that we've established data-twitch-message-display-status="deleting"
as a precedent, I'd be comfortable setting data-twitch-message-display-status="incoming"
(or similar) for new messages, and porting existing themes' entrance animations to that hook.
we might also need to set up full FLIP style classes for things so that it is easier to handle transitions/animations
Not knowing anything about FLIP, would setting up a FLIP approach like that still afford the stylesheet full control over the entrance/exit animations? (i.e. themes don't have to modify the JavaScript to get custom animations?)
correct. the idea behind FLIP is First Last Invert Play. (this is how the vue transition component works.)
Basically, we give 3 classes/attributes for animation/transition.
-
enter-from/leaving-from
state - This is the initial state we need to be in to make the transition work (eg:opacity:0;
for ourenter-from
state, oropacity:1;
for ourleaving-from
state) -
enter-active/leaving-active
state - this is where you'd define the transition or animation you'd want to use (egtransition: opacity 1s ease;
). -
enter-to/leaving-to
state - this is where you'd apply the end state of your transition (egopacity:1;
for ourenter-to
state oropacity:0;
for ourleave-to
state)
the implementation works as follows:
apply both the from
state and the active
state. then remove the from
state and apply the to
state. listen for transition/animation end and then remove the active
and to
states.
Let me see if I can get more information about the best way to listen for this.
Iiiinteresting. I'd be open to exploring this!