~abyxcos/hummingbird

0734b67a14b664b4b4247b86aa8d7c6f0a712ae6 — abyxcos 2 years ago a547f24
Add some reply and edit detection.
2 files changed, 61 insertions(+), 38 deletions(-)

M hummingbird.js
M hummingbird_ajax.js
M hummingbird.js => hummingbird.js +17 -14
@@ 150,8 150,12 @@ function showRoom(room) {
	var messageList = el('div')
	var prevSender = ''
	for (m of sortedMessages) {
		// If there is no body the message was deleted, don't display it.
		if (!m.type) { continue }

		//var user = _(account).get(['rooms', room, 'users', m.user_id], {})
		let user = users[m.sender]
		let body, avatar, reply, edit
		let body, avatar

		// Group messages together if they're from the same sender.
		if (prevSender != m.sender) {


@@ 165,14 169,6 @@ function showRoom(room) {
			body = ''
		}

		// Check if we have related events. Replies, edits, etc.
		// We can be multiple types at once (edit to a reply).
		// XXX reply = _(m).get(['content', 'm.relates_to', 'm.in_reply_to', 'event_id'])
		// XXX edit = _(m).get(['content', 'm.relates_to', 'event_id'])
		// TODO: edits => m[content][m.new_content]
		// TODO:    body, formatted_body, msgtype
		// TODO:    need to move the user line to it's own div so we can just replace body

		// Check our message type and render it appropriately.
		switch (m.type) {
			case 'm.notice':


@@ 181,23 177,30 @@ function showRoom(room) {
			case 'm.emote':
				// TODO: /me messages. 
			case 'm.text':
				if (reply) {
				// We have a deleted message.
				if (!m.body) { continue }

				if (m.reply) {
					// TODO: We may not have fetched the event we're replying to yet.
					let mp = _(messages).get([room, reply])
					let mp = _(messages).get([room, m.reply])
					if (!mp) {
						body += 'In reply to unknown:<br>'
						body += 'In reply to an older message:<br>'
					} else {
						body += `In reply to ${mp.sender}:<br>`
					}

					let replyText = el('div')
					replyText.innerHTML = m.body
					// XXX: Sometimes we don't have a mx-reply block.
					replyText.querySelector('mx-reply')?.remove()
					body += replyText.innerHTML
				} else {
					body += m.body || '(deleted)'
					body += m.body
				}

				if (m.edit) {
					body += ' (edited)'
				}

				break
			case 'm.image':
				body += `

M hummingbird_ajax.js => hummingbird_ajax.js +44 -24
@@ 219,7 219,8 @@ function parseMessageEvents(events, room) {
	// Message events.
	for (e of events) {
		// TODO: Maybe we should make a stray messages struct and return it?
		if (e.room_id != room) {
		// If we're recursing, room_id may not be set.
		if (e.room_id && e.room_id != room) {
			console.error('Received message for another room while syncing ', room)
			console.error(e)
			continue


@@ 233,33 234,52 @@ function parseMessageEvents(events, room) {

		// TODO: We still want to sanitize the HTML and rewrite links.
		switch (e.content.msgtype) {
			case 'm.text':
				m.body = e.content.formatted_body || e.content.body
				// format: "org.matrix.custom.html"
				break
			case 'm.image':
				m.body = e.content.body
				m.data = {
					url:		e.content.url,
					fetched:	false,
					img:		null,
					size:		e.content.info?.size,
					h:			e.content.info?.h,
					w:			e.content.info?.w,
				}
			case 'm.room.redaction':
				m.body = null
				m.reason = e.content.reason
				m.relatedEvent = e.content.redacts
				break
		case 'm.text':
			m.body = e.content.formatted_body || e.content.body
			// format: "org.matrix.custom.html"

			// Check if we have any edits or replies.
			switch (e.content['m.relates_to']?.rel_type) {
			case undefined:
				// We were probably redacted.
				// Let's try recursing on redacted_because.
				//redact = parseMessageEvents(e.redacted_because, room)
				// No relation exists.
				break
			case 'm.replace':
				m.edit = e.content['m.relates_to'].event_id
				// Manually merge the new message as someone may have changed the type.
				m.type = e.content['m.new_content'].msgtype
				m.body = e.content['m.new_content'].formatted_body ||
					e.content['m.new_content'].formatted_body
				break
			case 'net.maunium.reply':
			default:
				console.error('Unhandled message event type: ', e)
				m.reply = e.content['m.relates_to']['m.in_reply_to'].event_id
				break
			}

			break
		case 'm.image':
			m.body = e.content.body
			m.data = {
				url:		e.content.url,
				fetched:	false,
				img:		null,
				size:		e.content.info?.size,
				h:			e.content.info?.h,
				w:			e.content.info?.w,
			}
		case 'm.room.redaction':
			m.body = null
			m.reason = e.content.reason
			m.relatedEvent = e.content.redacts
			break
		case undefined:
			// We were probably redacted.
			// Let's try recursing on redacted_because.
			//redact = parseMessageEvents(e.redacted_because, room)
			break
		default:
			console.error('Unhandled message event type: ', e)
			break
		}

		messages[e.event_id] = m