| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-11-15 17:47:09 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-11-15 17:48:29 UTC |
| parent | 3e0a0a8c00b408e9ad74fbd3f130a737aa4b70c2 |
| xmpp/ChatMessage.hx | +5 | -0 |
| xmpp/Identicon.hx | +31 | -0 |
diff --git a/xmpp/ChatMessage.hx b/xmpp/ChatMessage.hx index 3764c58..46d0b71 100644 --- a/xmpp/ChatMessage.hx +++ b/xmpp/ChatMessage.hx @@ -4,6 +4,7 @@ import haxe.Exception; using Lambda; import xmpp.JID; +import xmpp.Identicon; enum MessageDirection { MessageReceived; @@ -216,6 +217,10 @@ class ChatMessage { return direction == MessageReceived; } + public function threadIcon() { + return threadId == null ? null : Identicon.svg(threadId); + } + public function asStanza(?type: String):Stanza { var attrs: haxe.DynamicAccess<String> = { type: type ?? "chat" }; if (from != null) attrs.set("from", from.asString()); diff --git a/xmpp/Identicon.hx b/xmpp/Identicon.hx new file mode 100644 index 0000000..df596bf --- /dev/null +++ b/xmpp/Identicon.hx @@ -0,0 +1,31 @@ +package xmpp; + +import xmpp.Color; +import haxe.crypto.Sha1; +import haxe.io.Bytes; +import haxe.io.BytesInput; + +@:expose +class Identicon { + public static function svg(source: String) { + final sha = Sha1.make(Bytes.ofString(source)); + final input = new BytesInput(sha); + input.bigEndian = true; + final hash = input.readInt32(); + var uri = 'data:image/svg+xml,<svg%20xmlns="http://www.w3.org/2000/svg"%20version="1.1"%20width="5"%20height="5"%20viewBox="0%200%205%205">'; + uri += "<style>rect{fill:%23" + Color.forString(source).substr(1) + ";}</style>"; + var i = 0; + for (x in 0...3) { + for (y in 0...5) { + final value = hash >> (i++); + if (value % 2 == 0) { + uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + x + "\"%20y=\"" + y + "\"/>"; + if (x != 2) { + uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + (4 - x) + "\"%20y=\"" + y + "\"/>"; + } + } + } + } + return uri + "</svg>"; + } +}