import {ElemJS} from "./basic.js" import {Subscribable} from "./store/Subscribable.js" class Event extends ElemJS { constructor(data) { super("div") this.class("c-message") this.data = null this.update(data) } update(data) { this.data = data this.render() } render() { this.child(this.data.content.body) } } class Timeline extends Subscribable { constructor() { super() Object.assign(this.events, { addItem: [], removeItem: [] }) Object.assign(this.eventDeps, { addItem: [], removeItem: [] }) this.list = [] this.map = new Map() this.elementsMap = new Map() this.elementsList = [] } _binarySearch(event, min = 0, max = -1) { if (this.list.length === 0) return {success: false, i: 0} if (max === -1) max = this.list.length - 1 let mid = Math.floor((max + min) / 2) // success condition if (this.list[mid] && this.list[mid].event_id === event.event_id) return {success: true, i: mid} // failed condition if (min >= max) { while (mid !== -1 && (!this.list[mid] || this.list[mid].origin_server_ts > event.origin_server_ts)) mid-- return { success: false, i: mid + 1 } } // recurse (below) if (this.list[mid].origin_server_ts > event.origin_server_ts) return this._binarySearch(event, min, mid-1) // recurse (above) else return this._binarySearch(event, mid+1, max) } updateEvents(events) { for (const event of events) { if (this.map.has(event.event_id)) { this.map.set(event.event_id, event) this.elementsMap.get(event.event_id).update(this.map.get(event.event_id)) } else { const index = this._binarySearch(event).i this.list.splice(index, 0, event) this.map.set(event.event_id, event) const e = new Event(event) this.elementsList.splice(index, 0, e) this.elementsMap.set(event.event_id, e) this.broadcast("addItem", {index, element: e}) } } } getGroupedEvents() { let currentSender = Symbol("N/A") let groups = [] let currentGroup = [] for (const event of this.list) { if (event.sender === currentSender) { currentGroup.push(event) } else { if (currentGroup.length) groups.push(currentGroup) currentGroup = [event] currentSender = event.sender } } if (currentGroup.length) groups.push(currentGroup) return groups } } export {Timeline}