import {q, ElemJS, ejs} from "./basic.js" import {store} from "./store/store.js" import {Timeline} from "./Timeline.js" import * as lsm from "./lsm.js" function resolveMxc(url, size, method) { const [server, id] = url.match(/^mxc:\/\/([^/]+)\/(.*)/).slice(1) if (size && method) { return `${lsm.get("domain")}/_matrix/media/r0/thumbnail/${server}/${id}?width=${size}&height=${size}&method=${method}` } else { return `${lsm.get("domain")}/_matrix/media/r0/download/${server}/${id}` } } class ActiveGroupMarker extends ElemJS { constructor() { super(q("#c-group-marker")) store.activeGroup.subscribe("changeSelf", this.render.bind(this)) } render() { if (store.activeGroup.exists()) { const group = store.activeGroup.value() this.style("opacity", 1) this.style("transform", `translateY(${group.element.offsetTop}px)`) } else { this.style("opacity", 0) } } } const activeGroupMarker = new ActiveGroupMarker() class Group extends ElemJS { constructor(key, data) { super("div") this.data = data this.class("c-group") this.child( (this.data.icon ? ejs("img").class("c-group__icon").attribute("src", this.data.icon) : ejs("div").class("c-group__icon") ), ejs("div").class("c-group__name").text(this.data.name) ) this.on("click", this.onClick.bind(this)) store.activeGroup.subscribe("changeSelf", this.render.bind(this)) } render() { const active = store.activeGroup.value() === this this.element.classList[active ? "add" : "remove"]("c-group--active") } onClick() { store.activeGroup.set(this) } } class Room extends ElemJS { constructor(id, data) { super("div") this.id = id this.data = data this.timeline = new Timeline() this.class("c-room") this.on("click", this.onClick.bind(this)) store.activeRoom.subscribe("changeSelf", this.render.bind(this)) this.render() } getName() { let name = this.data.state.events.find(e => e.type === "m.room.name") if (name) { name = name.content.name } else { const users = this.data.summary["m.heroes"] const usernames = users.map(u => (u.match(/^@([^:]+):/) || [])[1] || u) name = usernames.join(", ") } return name } getIcon() { const avatar = this.data.state.events.find(e => e.type === "m.room.avatar") if (avatar) { return resolveMxc(avatar.content.url || avatar.content.avatar_url, 32, "crop") } else { return null } } isDirect() { return store.directs.has(this.id) } getGroup() { return this.isDirect() ? store.groups.get("directs").value() : store.groups.get("channels").value() } onClick() { store.activeRoom.set(this) } render() { this.clearChildren() // data const icon = this.getIcon() if (icon) { this.child(ejs("img").class("c-room__icon").attribute("src", icon)) } else { this.child(ejs("div").class("c-room__icon", "c-room__icon--no-icon")) } this.child(ejs("div").class("c-room__name").text(this.getName())) // active const active = store.activeRoom.value() === this this.element.classList[active ? "add" : "remove"]("c-room--active") } } class Rooms extends ElemJS { constructor() { super(q("#c-rooms")) this.roomData = [] this.rooms = [] store.rooms.subscribe("askAdd", this.askAdd.bind(this)) store.rooms.subscribe("addItem", this.addItem.bind(this)) // store.rooms.subscribe("changeItem", this.render.bind(this)) store.activeGroup.subscribe("changeSelf", this.render.bind(this)) store.directs.subscribe("changeItem", this.render.bind(this)) this.render() } askAdd(event, {key, data}) { const room = new Room(key, data) store.rooms.addEnd(key, room) } addItem(event, key) { const room = store.rooms.get(key).value() if (room.getGroup() === store.activeGroup.value()) { this.child(room) } } render() { this.clearChildren() let first = null // set room list store.rooms.forEach((id, room) => { if (room.value().getGroup() === store.activeGroup.value()) { if (!first) first = room.value() this.child(room.value()) } }) // if needed, change the active room to be an item in the room list if (!store.activeRoom.exists() || store.activeRoom.value().getGroup() !== store.activeGroup.value()) { if (first) { store.activeRoom.set(first) } else { store.activeRoom.delete() } } } } const rooms = new Rooms() class Groups extends ElemJS { constructor() { super(q("#c-groups-list")) store.groups.subscribe("askAdd", this.askAdd.bind(this)) store.groups.subscribe("addItem", this.addItem.bind(this)) } askAdd(event, {key, data}) { const group = new Group(key, data) store.groups.addEnd(key, group) } addItem(event, key) { this.child(store.groups.get(key).value()) } } const groups = new Groups() ;[ { id: "directs", name: "Directs", icon: "/static/directs.svg" }, { id: "channels", name: "Channels", icon: "/static/channels.svg" }/*, { id: "123", name: "Fediverse Drama Museum" }, { id: "456", name: "Epicord" }, { id: "789", name: "Invidious" }*/ ].forEach(data => store.groups.askAdd(data.id, data)) /* ;[ {id: "001", name: "riley", group: store.groups.get("directs").value()}, {id: "002", name: "BadAtNames", group: store.groups.get("directs").value()}, {id: "003", name: "lynxano", group: store.groups.get("directs").value()}, {id: "004", name: "quarky", group: store.groups.get("directs").value()}, {id: "005", name: "lepton", group: store.groups.get("directs").value()}, {id: "006", name: "ash", group: store.groups.get("directs").value()}, {id: "007", name: "mewmew", group: store.groups.get("directs").value()}, {id: "008", name: "Toniob", group: store.groups.get("directs").value()}, {id: "009", name: "cockandball", group: store.groups.get("directs").value()}, {id: "010", name: "Carbon brainstorming", group: store.groups.get("channels").value()}, {id: "011", name: "Bibliogram", group: store.groups.get("channels").value()}, {id: "012", name: "Monsters Inc Debate Hall", group: store.groups.get("channels").value()}, {id: "013", name: "DRB clan", group: store.groups.get("channels").value()}, {id: "014", name: "mettaton simp zone", group: store.groups.get("channels").value()}, {id: "015", name: "witches", group: store.groups.get("123").value()}, {id: "016", name: "snouts", group: store.groups.get("123").value()}, {id: "017", name: "monads", group: store.groups.get("123").value()}, {id: "018", name: "radical", group: store.groups.get("123").value()}, {id: "019", name: "blobcat", group: store.groups.get("123").value()}, {id: "020", name: "main", group: store.groups.get("456").value()}, {id: "021", name: "gaming", group: store.groups.get("456").value()}, {id: "022", name: "inhalers", group: store.groups.get("456").value()}, {id: "023", name: "minecraft", group: store.groups.get("456").value()}, {id: "024", name: "osu", group: store.groups.get("456").value()}, {id: "025", name: "covid", group: store.groups.get("456").value()} ].forEach(data => store.rooms.askAdd(data.id, data)) */ store.activeGroup.set(store.groups.get("directs").value())