const {ElemJS, ejs} = require("./basic.js") const {store} = require("./store/store.js") const {resolveMxc} = require("./functions.js") function nameToColor(str) { // code from element's react sdk const colors = ["#55a7f0", "#da55ff", "#1bc47c", "#ea657e", "#fd8637", "#22cec6", "#8c8de3", "#71bf22"] let hash = 0 let i let chr if (str.length === 0) { return hash } for (i = 0; i < str.length; i++) { chr = str.charCodeAt(i) hash = ((hash << 5) - hash) + chr hash |= 0 } hash = Math.abs(hash) % 8 return colors[hash] } class Avatar extends ElemJS { constructor() { super("div") this.class("c-message-group__avatar") this.mxc = undefined this.image = null this.update(null) } update(mxc) { if (mxc === this.mxc) return this.mxc = mxc this.hasImage = !!mxc if (this.hasImage) { const size = 96 const url = resolveMxc(mxc, size, "crop") this.image = ejs("img").class("c-message-group__icon").attribute("src", url).attribute("width", size).attribute("height", size) this.image.on("error", this.onError.bind(this)) } this.render() } onError() { this.hasImage = false this.render() } render() { this.clearChildren() if (this.hasImage) { this.child(this.image) } else { this.child( ejs("div").class("c-message-group__icon", "c-message-group__icon--no-icon") ) } } } /** Must update at least once to render. */ class Name extends ElemJS { constructor() { super("div") this.class("c-message-group__name") /** * Keeps track of whether we have the proper display name or not. * If we do, then we shoudn't override it with the mxid if the name becomes unavailable. */ this.hasName = false this.name = "" this.mxid = "" } update(event) { this.mxid = event.state_key if (event.content.displayname) { this.hasName = true this.name = event.content.displayname } else if (!this.hasName) { this.name = this.mxid } this.render() } render() { // set text this.text(this.name) // set color this.style("color", nameToColor(this.mxid)) } } class Sender { constructor(roomID, mxid) { this.sender = store.rooms.get(roomID).value().members.get(mxid) this.name = new Name() this.avatar = new Avatar() this.sender.subscribe("changeSelf", this.update.bind(this)) this.update() } update() { if (this.sender.exists()) { // name this.name.update(this.sender.value()) // avatar this.avatar.update(this.sender.value().content.avatar_url) } } } module.exports = { Sender }