~singpolyma/jabber-client-demo

8cdad4ac633f8c39fdb51d41de4e07be87421483 — Stephen Paul Weber 1 year, 10 months ago c59e23e
Message correction
1 files changed, 61 insertions(+), 12 deletions(-)

M client.rb
M client.rb => client.rb +61 -12
@@ 39,7 39,11 @@ include Glimmer
set_caps(
	"https://git.singpolyma.net/jabber-client-demo",
	[],
	["urn:xmpp:avatar:metadata+notify", "urn:xmpp:receipts"]
	[
		"urn:xmpp:avatar:metadata+notify",
		"urn:xmpp:receipts",
		"urn:xmpp:message-correct:0"
	]
)

$avatars = {}


@@ 134,6 138,28 @@ class Conversation
							@message_entry.text = ""
						end
					}

					button("Correct") {
						stretchy false

						on_clicked do
							replace_row = @messages.rindex { |message|
								message[1] == format_sender(BLATHER.jid.stripped)
							}
							m = message
							m << xml_child(m, :replace, "urn:xmpp:message-correct:0").tap { |replace|
								replace["id"] = @messages[replace_row].last
							}
							EM.defer do
								BLATHER << m
								DB.execute(<<~SQL, [m.to_s, @jid, @messages[replace_row].last])
									UPDATE messages SET stanza=? WHERE conversation=? AND stanza_id=?
								SQL
							end
							@messages[replace_row] = message_row(m, @messages[replace_row][-2])
							@message_entry.text = ""
						end
					}
				}
			}



@@ 177,6 203,13 @@ class Conversation
		@messages << message_row(m, true)
	end

	def new_correction(replace_id, m)
		row = @messages.find_index { |r| r.last == replace_id }
		return unless row

		@messages[row] = message_row(m, true)
	end

	def delivered_message(id)
		row = @messages.find_index { |r| r.last == id }
		return unless row


@@ 283,14 316,31 @@ def handle_rsm_reply_when_idle(fin)
	sync_mam(last)
end

def insert_message(
	m,
	mam_id:,
	counterpart: m.from.stripped.to_s,
	delay: m.delay&.stamp&.to_i
)
	if (replace = m.at("./ns:replace", ns: "urn:xmpp:message-correct:0"))
		DB.execute(<<~SQL, [m.to_s, counterpart, replace["id"].to_s])
			UPDATE messages SET stanza=? WHERE conversation=? AND stanza_id=?
		SQL
	else
		delay ||= Time.now.to_i
		DB.execute(<<~SQL, [mam_id, m.id, counterpart, delay, m.to_s])
			INSERT OR IGNORE INTO messages
			(mam_id, stanza_id, conversation, created_at, stanza, delivered)
			VALUES (?,?,?,?,?,1)
		SQL
	end
end

def handle_live_message(m, counterpart: m.from.stripped.to_s)
	mam_id = m.xpath("./ns:stanza-id", ns: "urn:xmpp:sid:0").find { |el|
		el["by"] == jid.stripped.to_s
	}&.[]("id")
	delay = m.delay&.stamp&.to_i || Time.now.to_i
	DB.execute(<<~SQL, [mam_id, m.id, counterpart, delay, m.to_s])
		INSERT INTO messages (mam_id, stanza_id, conversation, created_at, stanza, delivered) VALUES (?,?,?,?,?,1)
	SQL
	insert_message(m, mam_id: mam_id, counterpart: counterpart)

	if mam_id
		DB.execute(<<~SQL, [mam_id])


@@ 301,7 351,11 @@ def handle_live_message(m, counterpart: m.from.stripped.to_s)
	LibUI.queue_main do
		conversation = $conversations[counterpart]
		if conversation
			conversation.new_message(m)
			if (replace = m.at("./ns:replace", ns: "urn:xmpp:message-correct:0"))
				conversation.new_correction(replace["id"].to_s, m)
			else
				conversation.new_message(m)
			end
		else
			Conversation.open(counterpart)
		end


@@ 368,12 422,7 @@ message "./ns:result", ns: "urn:xmpp:mam:2" do |_, result|
		delay =
			fwd.find_first("./ns:delay", ns: "urn:xmpp:delay")
			&.[]("stamp")&.then(Time.method(:parse))
		delay = delay&.to_i || m.delay&.stamp&.to_i || Time.now.to_i
		DB.execute(<<~SQL, [mam_id, m.id, counterpart, delay, m.to_s])
			INSERT OR IGNORE INTO messages
			(mam_id, stanza_id, conversation, created_at, stanza)
			VALUES (?,?,?,?,?)
		SQL
		insert_message(m, mam_id: mam_id, counterpart: counterpart, delay: delay)
	else
		DB.execute(<<~SQL, [mam_id, m.id])
			UPDATE messages SET mam_id=? WHERE stanza_id=?