Carbon/src/js/sender.js

121 lines
2.5 KiB
JavaScript

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
}