~singpolyma/jabber-client-demo

b0a0d990df2facf7bfdce496779464d869eae100 — Stephen Paul Weber 2 years ago f42589e
Avatars

Consistent color generation squares when no avatar
2 files changed, 51 insertions(+), 2 deletions(-)

M Gemfile
M client.rb
M Gemfile => Gemfile +1 -0
@@ 4,5 4,6 @@ source "https://rubygems.org"

gem "blather", git: "https://github.com/adhearsion/blather", branch: "develop"
gem "glimmer-dsl-libui", "~> 0.5.24"
gem "hsluv"
gem "sqlite3"
gem "xdg"

M client.rb => client.rb +50 -2
@@ 1,7 1,9 @@
# frozen_string_literal: true

require "base64"
require "glimmer-dsl-libui"
require "blather/client"
require "hsluv"
require "securerandom"
require "sqlite3"
require "xdg"


@@ 27,6 29,13 @@ end
BLATHER = self
include Glimmer

set_caps(
	"https://git.singpolyma.net/jabber-client-demo",
	[],
	["urn:xmpp:avatar:metadata+notify"]
)

$avatars = {}
$conversations = {}
$roster = [["", ""]]



@@ 47,7 56,7 @@ class Conversation

	def initialize(jid)
		@jid = jid
		@messages = [["", ""]]
		@messages = [[default_avatar(""), "", ""]]
		EM.defer do
			mam_messages = []
			DB.execute(<<~SQL, [@jid]) do |row|


@@ 87,6 96,7 @@ class Conversation

			vertical_box {
				table {
					image_column("Avatar")
					text_column("Sender")
					text_column("Message")
					editable false


@@ 136,9 146,18 @@ class Conversation
		BLATHER.my_roster[jid]&.name || jid
	end

	def default_avatar(string)
		hue = (Digest::SHA1.digest(string).unpack1("v").to_f / 65536) * 360
		rgb = Hsluv.rgb_prepare(Hsluv.hsluv_to_rgb(hue, 100, 50))
		rgba = rgb.pack("CCC") + "\xff".b
		image { image_part(rgba * 32 * 32, 32, 32, 4) }
	end

	def message_row(m)
		from = m.from&.stripped || BLATHER.jid.stripped
		[
			format_sender(m.from&.stripped || BLATHER.jid.stripped),
			$avatars[from.to_s] || default_avatar(from.to_s),
			format_sender(from),
			m.body
		]
	end


@@ 286,6 305,8 @@ when_ready do
		xml_child(iq, :enable, "urn:xmpp:carbons:2")
	}

	send_caps

	last_mam_id = DB.execute(<<~SQL)[0]&.first
		SELECT value FROM data WHERE key='last_mam_id' LIMIT 1
	SQL


@@ 346,6 367,33 @@ message :body do |m|
	handle_live_message(m)
end

pubsub_event(
	"//ns:items[@node='urn:xmpp:avatar:metadata']",
	ns: "http://jabber.org/protocol/pubsub#event"
) do |m|
	id = m.items.first&.payload_node&.children&.first&.[]("id")
	next $avatars.delete(m.from.stripped.to_s) unless id

	path = DATA_DIR + id.to_s
	key = m.from.stripped.to_s
	if path.exist?
		LibUI.queue_main { $avatars[key] = image(path.to_s, 32, 32) rescue nil }
	else
		write_with_handler(
			Blather::Stanza::PubSub::Items.new(:get).tap { |iq|
				iq.node = "urn:xmpp:avatar:data"
				iq.to = m.from
			}
		) do |reply|
			next if reply.error?

			data = Base64.decode64(reply.items.first&.payload_node&.text.to_s)
			path.write(data)
			LibUI.queue_main { $avatars[key] = image(path.to_s, 32, 32) rescue nil }
		end
	end
end

after(:roster) do
	LibUI.queue_main do
		$roster.clear