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…
	
	Add table
		Add a link
		
	
		Reference in a new issue