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)
|
this.update(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// predicates
|
||||||
|
|
||||||
|
canGroup() {
|
||||||
|
return this.data.type === "m.room.message"
|
||||||
|
}
|
||||||
|
|
||||||
|
// operations
|
||||||
|
|
||||||
setGroup(group) {
|
setGroup(group) {
|
||||||
this.group = group
|
this.group = group
|
||||||
}
|
}
|
||||||
|
@ -59,7 +67,17 @@ class Event extends ElemJS {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
this.element.classList[this.data.pending ? "add" : "remove"]("c-message--pending")
|
this.element.classList[this.data.pending ? "add" : "remove"]("c-message--pending")
|
||||||
|
if (this.data.type === "m.room.message") {
|
||||||
this.text(this.data.content.body)
|
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.sender.subscribe("changeSelf", this.update.bind(this))
|
||||||
this.name = new ElemJS("div").class("c-message-group__name")
|
this.name = new ElemJS("div").class("c-message-group__name")
|
||||||
this.avatar = new ElemJS("div").class("c-message-group__avatar")
|
this.avatar = new ElemJS("div").class("c-message-group__avatar")
|
||||||
|
this.displayingGoodData = false
|
||||||
this.update()
|
this.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
if (this.sender.exists()) {
|
if (this.sender.exists()) {
|
||||||
// name
|
// name
|
||||||
|
if (this.sender.value().content.displayname) {
|
||||||
this.name.text(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
|
// avatar
|
||||||
this.avatar.clearChildren()
|
this.avatar.clearChildren()
|
||||||
|
@ -181,7 +205,7 @@ class ReactiveTimeline extends ElemJS {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Timeline extends Subscribable {
|
class Timeline extends Subscribable {
|
||||||
constructor(id) {
|
constructor(room) {
|
||||||
super()
|
super()
|
||||||
Object.assign(this.events, {
|
Object.assign(this.events, {
|
||||||
beforeChange: [],
|
beforeChange: [],
|
||||||
|
@ -191,25 +215,49 @@ class Timeline extends Subscribable {
|
||||||
beforeChange: [],
|
beforeChange: [],
|
||||||
afterChange: []
|
afterChange: []
|
||||||
})
|
})
|
||||||
this.id = id
|
this.room = room
|
||||||
|
this.id = this.room.id
|
||||||
this.list = []
|
this.list = []
|
||||||
this.map = new Map()
|
this.map = new Map()
|
||||||
this.reactiveTimeline = new ReactiveTimeline(id, [])
|
this.reactiveTimeline = new ReactiveTimeline(this.id, [])
|
||||||
this.latest = 0
|
this.latest = 0
|
||||||
this.pending = new Set()
|
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) {
|
updateEvents(events) {
|
||||||
this.broadcast("beforeChange")
|
this.broadcast("beforeChange")
|
||||||
|
// handle state events
|
||||||
|
this.updateStateEvents(events)
|
||||||
for (const eventData of events) {
|
for (const eventData of events) {
|
||||||
|
// set variables
|
||||||
this.latest = Math.max(this.latest, eventData.origin_server_ts)
|
this.latest = Math.max(this.latest, eventData.origin_server_ts)
|
||||||
let id = eventData.event_id
|
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"])) {
|
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"]
|
id = eventData.content["chat.carbon.message.pending_id"]
|
||||||
}
|
}
|
||||||
|
// handle timeline events
|
||||||
if (this.map.has(id)) {
|
if (this.map.has(id)) {
|
||||||
|
// update existing event
|
||||||
this.map.get(id).update(eventData)
|
this.map.get(id).update(eventData)
|
||||||
} else {
|
} 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)
|
const event = new Event(eventData)
|
||||||
this.map.set(id, event)
|
this.map.set(id, event)
|
||||||
this.reactiveTimeline.addEvent(event)
|
this.reactiveTimeline.addEvent(event)
|
||||||
|
@ -238,6 +286,7 @@ class Timeline extends Subscribable {
|
||||||
"chat.carbon.message.pending_id": id
|
"chat.carbon.message.pending_id": id
|
||||||
}
|
}
|
||||||
const fakeEvent = {
|
const fakeEvent = {
|
||||||
|
type: "m.room.message",
|
||||||
origin_server_ts: Date.now(),
|
origin_server_ts: Date.now(),
|
||||||
event_id: id,
|
event_id: id,
|
||||||
sender: lsm.get("mx_user_id"),
|
sender: lsm.get("mx_user_id"),
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Room extends ElemJS {
|
||||||
|
|
||||||
this.id = id
|
this.id = id
|
||||||
this.data = data
|
this.data = data
|
||||||
this.timeline = new Timeline(this.id)
|
this.timeline = new Timeline(this)
|
||||||
this.group = null
|
this.group = null
|
||||||
this.members = new SubscribeMapList(SubscribeValue)
|
this.members = new SubscribeMapList(SubscribeValue)
|
||||||
|
|
||||||
|
|
|
@ -47,19 +47,15 @@ function manageSync(root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up rooms
|
// set up rooms
|
||||||
Object.entries(root.rooms.join).forEach(([id, room]) => {
|
Object.entries(root.rooms.join).forEach(([id, data]) => {
|
||||||
if (!store.rooms.has(id)) {
|
if (!store.rooms.has(id)) {
|
||||||
store.rooms.askAdd(id, room)
|
store.rooms.askAdd(id, data)
|
||||||
}
|
}
|
||||||
const storeRoom = store.rooms.get(id).value()
|
const room = store.rooms.get(id).value()
|
||||||
room.state.events.forEach(event => {
|
const timeline = room.timeline
|
||||||
if (event.type === "m.room.member") {
|
if (data.timeline.events.length) newEvents = true
|
||||||
storeRoom.members.get(event.state_key).set(event)
|
timeline.updateStateEvents(data.state.events)
|
||||||
}
|
timeline.updateEvents(data.timeline.events)
|
||||||
})
|
|
||||||
const timeline = storeRoom.timeline
|
|
||||||
if (room.timeline.events.length) newEvents = true
|
|
||||||
timeline.updateEvents(room.timeline.events)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// set up groups
|
// set up groups
|
||||||
|
@ -90,6 +86,7 @@ function manageSync(root) {
|
||||||
store.rooms.get(groupRoom.room_id).value().setGroup(id)
|
store.rooms.get(groupRoom.room_id).value().setGroup(id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
store.newEvents.broadcast("changeSelf") // trigger a room list update
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue