import { ElemJS, q, ejs } from "./basic.js"; import { store } from "./store/store.js"; const chatMessages = q("#c-chat-messages"); class Chat extends ElemJS { constructor() { super(q("#c-chat")); this.removableSubscriptions = []; store.activeRoom.subscribe("changeSelf", this.changeRoom.bind(this)); this.render(); } unsubscribe() { this.removableSubscriptions.forEach(({ name, target, subscription }) => { target.unsubscribe(name, subscription); }); this.removableSubscriptions.length = 0; } changeRoom() { // disconnect from the previous room this.unsubscribe(); // connect to the new room's timeline updater if (store.activeRoom.exists()) { const timeline = store.activeRoom.value().timeline; const subscription = () => { // scroll anchor does not work if the timeline is scrolled to the top. // at the start, when there are not enough messages for a full screen, this is the case. // once there are enough messages that scrolling is necessary, we initiate a scroll down to activate the scroll anchor. let oldDifference = chatMessages.scrollHeight - chatMessages.clientHeight; setTimeout(() => { let newDifference = chatMessages.scrollHeight - chatMessages.clientHeight; // console.log("height difference", oldDifference, newDifference) if (oldDifference < 24) { // this is jank this.element.parentElement.scrollBy(0, 1000); } }, 0); }; const name = "beforeChange"; this.removableSubscriptions.push({ name, target: timeline, subscription, }); timeline.subscribe(name, subscription); } this.render(); } render() { this.clearChildren(); if (store.activeRoom.exists()) { const reactiveTimeline = store.activeRoom.value().timeline.getTimeline(); this.child(reactiveTimeline); setTimeout(() => { this.element.parentElement.scrollBy(0, 1); reactiveTimeline.anchor.scroll(); }, 0); } } } const chat = new Chat(); export { chat };