carbon/build/static/chat.js

65 lines
1.9 KiB
JavaScript

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}