Hey
I’ve been using LiveView on and off for a while - I find that it’s really amazing for dashboards where I need live updated data. For example, I have a phoenix application with Broadway which reads from a rabbitmq queue, processes the json messages flowing through it and updates some stats counters I store in ETS.
With a table full of numbers changing on the screen it can be hard for a user to see the important stuff - ie. what parts are changing.
I’d like to present the solution I came up with, and start a discussion about better ways to do this.
in my live views I add a class “show_updates” where I want to see updates.
<span class="show_updates"> <%= @throughput %> events per second </span>
In my css I have an animation eg.
.live_view_updated {
animation-name: flash;
animation-duration: 1.0s;
}
@keyframes flash {
0% {background-color: inherit;}
5% {background-color:rgb(241, 241, 241);}
100% {background-color: inherit;}
}
And in my app.js I have the following;
let liveViewDirty = false; // tracks if we have any live_view_updated classes to clear
let liveSocket = new LiveSocket("/live", Socket, {
params: {
_csrf_token: csrfToken
},
dom: {
onBeforeElUpdated(from, target){
if(target.classList.contains("show_updates")) {
if (from.textContent != target.textContent) {
target.classList.add("live_view_updated");
liveViewDirty = true;
}
}
}
}
});
window.setInterval(() => {
if(liveViewDirty) {
let updated = document.querySelectorAll('.live_view_updated');
updated.forEach((node) => {
node.classList.remove("live_view_updated")
});
liveViewDirty = false;
}
}, 450);
when an element is updated by morphDom, I check if the element has the class “show_updates” in which case I add the class “live_view_updated” and mark liveViewDirty = true;
This triggers the animation.
every 450ms I poll and check if liveViewDirty is true, and if so, I remove the live_view_updated class.
What shows on the screen is a nice background flash of the elements that are updated.
The downside is because I’m polling, sometimes an animation isn’t complete and gets cancelled when the live_view_updated class is removed - so some elements don’t flash. It doesn’t happen too often though, so it mostly works. If I don’t clear the class often enough it might miss animating the subsequent update.
I just wondered if anyone else has any alternative ways to do this or any suggestions?
I guess I could add another class with a uuid and then trigger a setInterval to clean it up after the animation ends but this would couple my js timing with my css timing and having so many intervals could get expensive.
I’m a bit of a javascript / css rookie so any suggestions would be appreciated.