forked from cadence/Carbon
Refactor state events and support showing joins
This commit is contained in:
parent
c0cb857c07
commit
6b88ede18e
3 changed files with 63 additions and 17 deletions
|
@ -43,6 +43,14 @@ class Event extends ElemJS {
|
|||
this.update(data)
|
||||
}
|
||||
|
||||
// predicates
|
||||
|
||||
canGroup() {
|
||||
return this.data.type === "m.room.message"
|
||||
}
|
||||
|
||||
// operations
|
||||
|
||||
setGroup(group) {
|
||||
this.group = group
|
||||
}
|
||||
|
@ -59,7 +67,17 @@ class Event extends ElemJS {
|
|||
|
||||
render() {
|
||||
this.element.classList[this.data.pending ? "add" : "remove"]("c-message--pending")
|
||||
this.text(this.data.content.body)
|
||||
if (this.data.type === "m.room.message") {
|
||||
this.text(this.data.content.body)
|
||||
} else if (this.data.type === "m.room.member") {
|
||||
if (this.data.content.membership === "join") {
|
||||
this.child(ejs("i").text("joined the room"))
|
||||
} else {
|
||||
this.child(ejs("i").text("left the room"))
|
||||
}
|
||||
} else {
|
||||
this.child(ejs("i").text(`Unsupported event type ${this.data.type}`))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,13 +87,19 @@ class Sender {
|
|||
this.sender.subscribe("changeSelf", this.update.bind(this))
|
||||
this.name = new ElemJS("div").class("c-message-group__name")
|
||||
this.avatar = new ElemJS("div").class("c-message-group__avatar")
|
||||
this.displayingGoodData = false
|
||||
this.update()
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.sender.exists()) {
|
||||
// name
|
||||
this.name.text(this.sender.value().content.displayname)
|
||||
if (this.sender.value().content.displayname) {
|
||||
this.name.text(this.sender.value().content.displayname)
|
||||
this.displayingGoodData = true
|
||||
} else if (!this.displayingGoodData) {
|
||||
this.name.text(this.sender.value().state_key)
|
||||
}
|
||||
|
||||
// avatar
|
||||
this.avatar.clearChildren()
|
||||
|
@ -181,7 +205,7 @@ class ReactiveTimeline extends ElemJS {
|
|||
}
|
||||
|
||||
class Timeline extends Subscribable {
|
||||
constructor(id) {
|
||||
constructor(room) {
|
||||
super()
|
||||
Object.assign(this.events, {
|
||||
beforeChange: [],
|
||||
|
@ -191,25 +215,49 @@ class Timeline extends Subscribable {
|
|||
beforeChange: [],
|
||||
afterChange: []
|
||||
})
|
||||
this.id = id
|
||||
this.room = room
|
||||
this.id = this.room.id
|
||||
this.list = []
|
||||
this.map = new Map()
|
||||
this.reactiveTimeline = new ReactiveTimeline(id, [])
|
||||
this.reactiveTimeline = new ReactiveTimeline(this.id, [])
|
||||
this.latest = 0
|
||||
this.pending = new Set()
|
||||
}
|
||||
|
||||
updateStateEvents(events) {
|
||||
for (const eventData of events) {
|
||||
let id = eventData.event_id
|
||||
if (eventData.type === "m.room.member") {
|
||||
// update members
|
||||
if (eventData.membership !== "leave") {
|
||||
this.room.members.get(eventData.state_key).set(eventData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateEvents(events) {
|
||||
this.broadcast("beforeChange")
|
||||
// handle state events
|
||||
this.updateStateEvents(events)
|
||||
for (const eventData of events) {
|
||||
// set variables
|
||||
this.latest = Math.max(this.latest, eventData.origin_server_ts)
|
||||
let id = eventData.event_id
|
||||
// handle local echoes
|
||||
if (eventData.sender === lsm.get("mx_user_id") && eventData.content && this.pending.has(eventData.content["chat.carbon.message.pending_id"])) {
|
||||
id = eventData.content["chat.carbon.message.pending_id"]
|
||||
}
|
||||
// handle timeline events
|
||||
if (this.map.has(id)) {
|
||||
// update existing event
|
||||
this.map.get(id).update(eventData)
|
||||
} else {
|
||||
// skip displaying events that we don't know how to
|
||||
if (eventData.type === "m.reaction") {
|
||||
continue
|
||||
}
|
||||
// add new event
|
||||
const event = new Event(eventData)
|
||||
this.map.set(id, event)
|
||||
this.reactiveTimeline.addEvent(event)
|
||||
|
@ -238,6 +286,7 @@ class Timeline extends Subscribable {
|
|||
"chat.carbon.message.pending_id": id
|
||||
}
|
||||
const fakeEvent = {
|
||||
type: "m.room.message",
|
||||
origin_server_ts: Date.now(),
|
||||
event_id: id,
|
||||
sender: lsm.get("mx_user_id"),
|
||||
|
|
|
@ -62,7 +62,7 @@ class Room extends ElemJS {
|
|||
|
||||
this.id = id
|
||||
this.data = data
|
||||
this.timeline = new Timeline(this.id)
|
||||
this.timeline = new Timeline(this)
|
||||
this.group = null
|
||||
this.members = new SubscribeMapList(SubscribeValue)
|
||||
|
||||
|
|
|
@ -47,19 +47,15 @@ function manageSync(root) {
|
|||
}
|
||||
|
||||
// set up rooms
|
||||
Object.entries(root.rooms.join).forEach(([id, room]) => {
|
||||
Object.entries(root.rooms.join).forEach(([id, data]) => {
|
||||
if (!store.rooms.has(id)) {
|
||||
store.rooms.askAdd(id, room)
|
||||
store.rooms.askAdd(id, data)
|
||||
}
|
||||
const storeRoom = store.rooms.get(id).value()
|
||||
room.state.events.forEach(event => {
|
||||
if (event.type === "m.room.member") {
|
||||
storeRoom.members.get(event.state_key).set(event)
|
||||
}
|
||||
})
|
||||
const timeline = storeRoom.timeline
|
||||
if (room.timeline.events.length) newEvents = true
|
||||
timeline.updateEvents(room.timeline.events)
|
||||
const room = store.rooms.get(id).value()
|
||||
const timeline = room.timeline
|
||||
if (data.timeline.events.length) newEvents = true
|
||||
timeline.updateStateEvents(data.state.events)
|
||||
timeline.updateEvents(data.timeline.events)
|
||||
})
|
||||
|
||||
// set up groups
|
||||
|
@ -90,6 +86,7 @@ function manageSync(root) {
|
|||
store.rooms.get(groupRoom.room_id).value().setGroup(id)
|
||||
}
|
||||
})
|
||||
store.newEvents.broadcast("changeSelf") // trigger a room list update
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue