From bff88e9f6a3e3da7b88edf414e5e64f7bf82737b Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Fri, 2 Dec 2022 09:09:30 +0100 Subject: [PATCH] Avatars use text or colored silhouette as defaults --- plugins/avatars/avatars.js | 36 ++++++++++++++++++++++- plugins/avatars/identicon.js | 2 ++ plugins/avatars/images/empty-contact.png | Bin 665 -> 0 bytes plugins/avatars/index.php | 19 ++++-------- 4 files changed, 43 insertions(+), 14 deletions(-) delete mode 100644 plugins/avatars/images/empty-contact.png diff --git a/plugins/avatars/avatars.js b/plugins/avatars/avatars.js index 501fdfae8..81a16b460 100644 --- a/plugins/avatars/avatars.js +++ b/plugins/avatars/avatars.js @@ -1,5 +1,39 @@ (rl => { + const size = 50; + + window.identiconSvg = (hash, txt) => { + // color defaults to last 7 chars as hue at 70% saturation, 50% brightness + // hsl2rgb adapted from: https://gist.github.com/aemkei/1325937 + let h = (parseInt(hash.substr(-7), 16) / 0xfffffff) * 6, s = 0.7, l = 0.5, + v = [ + l += s *= l < .5 ? l : 1 - l, + l - h % 1 * s * 2, + l -= s *= 2, + l, + l + h % 1 * s, + l + s + ], + m = txt ? 128 : 200, + color = 'rgb(' + [ + v[ ~~h % 6 ] * m, // red + v[ (h | 16) % 6 ] * m, // green + v[ (h | 8) % 6 ] * m // blue + ].map(Math.round).join(',') + ')'; + + if (txt) { + return ` + + ${txt} + `; + } + return ` + + `; + }; + const queue = [], avatars = new Map, @@ -26,7 +60,7 @@ (from.name?.split(/[^\p{L}]+/gu) || []).reduce((a, s) => a + (s[0] || ''), '') .slice(0,2) .toUpperCase(), - setIdenticon = (from, fn) => window.identiconSvg && hash(from.email).then(hash => + setIdenticon = (from, fn) => hash(from.email).then(hash => fn('data:image/svg+xml;base64,' + btoa(window.identiconSvg(hash, fromChars(from)))) ), addQueue = (msg, fn) => { diff --git a/plugins/avatars/identicon.js b/plugins/avatars/identicon.js index 59664ccbb..237c2e574 100644 --- a/plugins/avatars/identicon.js +++ b/plugins/avatars/identicon.js @@ -31,6 +31,8 @@ window.identiconSvg = (hash, txt) => { dy=".1em" dominant-baseline="middle" fill="#FFF">${txt} `; } else { + txt = ``; + const cell = Math.floor((size - ((Math.floor(size * margin)) * 2)) / 5), imargin = Math.floor((size - cell * 5) / 2), rectangles = [], diff --git a/plugins/avatars/images/empty-contact.png b/plugins/avatars/images/empty-contact.png deleted file mode 100644 index 4418810b82e90b24e9ffb514ec673e25c76b964e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 665 zcmV;K0%rY*P)n9y>$(Q_Z{U>NbN-usPo3X*Kh}4zwbx$%^{1<@Dyc}hSVYXidMw9mjKdJ# z;W_T2KO$a^DS(KWilf+q@qZcq0Vi=VB0gsah=^&pg+(n+y@Rz8@xIFbJr#}bK|hwY zF?}xP)a&*BMx)WT4Yi66*oajX=5NA^DhAXloPL4b2|{>h7JxF#EKZOERz<{=902nY zgdj}7%p3rd6Q=TsIRKJAf;j+&6527G1K@i?01QOL(0>Prh+$k#0B|YSLk1VBxW5d;{%imdF^DS_ zmN**`A9H#Dj<@+LzsISZwa_mwJixU!rk;t2=h*>D?Z>AU#=pX`6dU)XSftTtys6jg zuyT|y@3x4zm%E&9)_FV~#kl*poodsfLhRSD1RJm#^U>Qv_4x!hakYHRe*71Jh?s=U z*oK7(zRZU4u*^soTWxd|Ef_upTgx`cO#enN(1+8b1t~^h_;@2d&%OW9@Mb;35uA&N zuWbR8ZNqgqgaw(t*&kycuK%gvEBU(g&$WMu}tZz7oqY?3=D4Vo>DmGa&=md848u=x(L+5Eb?$*j%UUVQp zfxR`%(7Bpk)8Xm@addJs('avatars.js'); $this->addJsonHook('Avatar', 'DoAvatar'); $this->addPartHook('Avatar', 'ServiceAvatar'); - $identicon = $this->Config()->Get('plugin', 'identicon', 'identicon'); - if ('none' != $identicon) { - if ('jdenticon' === $this->Config()->Get('plugin', 'identicon', 'identicon')) { - $this->addJs('jdenticon.js'); - } else { - $this->addJs('identicon.js'); - } + $identicon = $this->Config()->Get('plugin', 'identicon', ''); + if ($identicon && \is_file(__DIR__ . "/{$identicon}.js")) { + $this->addJs("{$identicon}.js"); } // https://github.com/the-djmaze/snappymail/issues/714 $this->Config()->Get('plugin', 'delay', true) || $this->addHook('filter.json-response', 'FilterJsonResponse'); @@ -93,9 +89,9 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECT) // ->SetAllowedInJs(true) ->SetDefaultValue([ - ['id' => 'identicon', 'name' => 'Name characters or squares'], - ['id' => 'jdenticon', 'name' => 'Triangles shape'], - ['id' => 'none', 'name' => 'none'] + ['id' => '', 'name' => 'Name characters else silhouette'], + ['id' => 'identicon', 'name' => 'Name characters else squares'], + ['id' => 'jdenticon', 'name' => 'Triangles shape'] ]) ->SetDescription('https://wikipedia.org/wiki/Identicon'), \RainLoop\Plugins\Property::NewInstance('bimi')->SetLabel('Lookup BIMI') @@ -212,9 +208,6 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin 'services/' . \preg_replace('/^.+\\.([^.]+\\.[^.]+)$/D', '$1', $sDomain), 'services/' . \preg_replace('/^(.+\\.)?(paypal\\.[a-z][a-z])$/D', 'paypal.com', $sDomain) ]; - if (!$this->Config()->Get('plugin', 'identicon', false)) { - $aServices[] = 'empty-contact'; // DATA_IMAGE_USER_DOT_PIC - } foreach ($aServices as $service) { $file = __DIR__ . "/images/{$service}.png"; if (\file_exists($file)) {