forked from cadence/Carbon
254 lines
6.9 KiB
JavaScript
254 lines
6.9 KiB
JavaScript
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())
|