Skip to content

Instantly share code, notes, and snippets.

@fatihmert
Last active April 14, 2021 21:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fatihmert/c981f57feb9a4bfa0e0e8111d3ea2afc to your computer and use it in GitHub Desktop.
Save fatihmert/c981f57feb9a4bfa0e0e8111d3ea2afc to your computer and use it in GitHub Desktop.
bug fix :)
// @ts-check
import { APIWrapper, API_EVENT_TYPE } from "./api.js";
import { addMessage, animateGift, isPossiblyAnimatingGift, isAnimatingGiftUI } from "./dom_updates.js";
const api = new APIWrapper();
// const api = new APIWrapper(null, true, false);
// const api = new APIWrapper(null, true, true);
// show logs
window.dbg = true;
// exceptions
const BreakException = {};
// classes
class EventItem {
constructor(event, priority){
this.event = event;
this.priority = priority;
}
}
// priority queue data structure
class EventQueue {
constructor(){
this.events = [];
}
enqueue(event, priority){
const eventItem = new EventItem(event, priority);
let contain = false;
try{
this.events.forEach((event, i) => {
if(event.priority > eventItem.priority){
this.events.splice(i, 0, eventItem);
contain = !contain;
throw BreakException;
}
});
}catch(e){
if (e !== BreakException)
throw e;
}
!contain && this.events.push(eventItem);
}
dequeue(){
if (this.isEmpty())
throw "Underflow";
return this.events.shift();
}
front(){
if (this.isEmpty())
throw "No events in Queue";
return this.events[0];
}
isEmpty(){
return this.events.length == 0;
}
get count(){
return this.events.length;
}
}
// enum flags
const EVENT_PRIORITY = {
APIMessageEvent: 1,
APIGiftEvent: 2,
APIAnimatedGiftEvent: 3,
}
const PRIORITY_MAP = {};
PRIORITY_MAP[`${API_EVENT_TYPE.ANIMATED_GIFT}`] = EVENT_PRIORITY.APIAnimatedGiftEvent;
PRIORITY_MAP[`${API_EVENT_TYPE.GIFT}`] = EVENT_PRIORITY.APIGiftEvent;
PRIORITY_MAP[`${API_EVENT_TYPE.MESSAGE}`] = EVENT_PRIORITY.APIMessageEvent;
const LOG_TYPE = Object.keys(window.console).reduce((eax, current) => {
const item = {};
item[`${current}`] = current;
return {...eax, ...item};
}, {});
// constants
const EVENT_DELAY = 500;
const COUNT = {
animation: 0,
message: 0
};
const queue = new EventQueue();
// helper
const log = (type, ...values) => window.dbg && window.console[`${type}`](...values);
const isMessage = event => [API_EVENT_TYPE.MESSAGE, API_EVENT_TYPE.GIFT].includes(event.type);
const isAnimation = event => [API_EVENT_TYPE.ANIMATED_GIFT].includes(event.type);
// logic
const app = () => {
if(!queue.isEmpty()){
const first = queue.front();
if(isMessage(first.event)){
addMessage(first.event);
log(LOG_TYPE.log, '🚀 Fired->addMessage:\t', first);
queue.dequeue();
}else if(isAnimation(first.event) && !isPossiblyAnimatingGift() && !isAnimatingGiftUI()){
animateGift(first.event);
log(LOG_TYPE.log, '🚀 Fired->animateGift:\t', first);
queue.dequeue();
}
}
}
// event stream
api.setEventHandler((events) => {
if(events.length > 0){
// computed instant events data count from stream for logs
let fromCount = {
animation: 0,
message: 0,
}
events.map(event => {
// queuing
queue.enqueue(event, PRIORITY_MAP[event.type]);
let animationValue = +isAnimation(event);
let messageValue = +isMessage(event);
// for only log, +(bool) >> int
fromCount.animation += animationValue;
fromCount.message += messageValue;
// general sum
COUNT.animation += animationValue;
COUNT.message += messageValue;
});
// when coming new data from event stream
log(LOG_TYPE.table, {
"all_new": events.length,
"new_animations": fromCount.animation,
"new_messages": fromCount.message,
"queue_messages": COUNT.message,
"queue_animations": COUNT.animation,
});
}
})
window.addEventListener('DOMContentLoaded', e => {
app(); // when dom loaded, once invoke
setInterval(app, EVENT_DELAY); // queuing like behavior observing
});
// NOTE: UI helper methods from `dom_updates` are already imported above.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment