diff --git a/plugins/avatars/avatars.js b/plugins/avatars/avatars.js index ceb7daac6..a433234bb 100644 --- a/plugins/avatars/avatars.js +++ b/plugins/avatars/avatars.js @@ -22,10 +22,18 @@ return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string }, fromChars = from => - ((from.name || from.email).split(/[^\p{L}]+/gu) || []) - .reduce((a, s) => a + (s[0] || ''), '') +// (from.name?.split(/[^\p{Lu}]+/gu) || []).reduce((a, s) => a + (s || '')), '') + (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 => + fn('data:image/svg+xml;base64,' + btoa(window.identiconSvg(hash, fromChars(from)))) + ), + addQueue = (msg, fn) => { + setIdenticon(msg.from[0], fn); + queue.push([msg, fn]); + runQueue(); + }, runQueue = (() => { let item = queue.shift(); while (item) { @@ -40,13 +48,6 @@ url = `data:${data.Result.type};base64,${data.Result.data}`; avatars.set(getAvatarUid(item[0]), url); item[1](url); - } else if (window.identiconSvg) { - // rl.pluginSettingsGet('avatars', 'identicon'); - hash(from.email).then(hash => { - let url = window.identiconSvg(hash, fromChars(from)); - avatars.set(getAvatarUid(item[0]), url); - item[1](url); - }); } runQueue(); }, 'Avatar', { @@ -115,22 +116,15 @@ init: (element, self, dummy, msg) => { if (msg) { let url = getAvatar(msg), + from = msg.from[0], fn = url=>{element.src = url}; if (url) { fn(url); } else if (msg.avatar) { - let from = msg.from[0], - bimi = 'pass' == from.dkimStatus ? 1 : 0; - if (window.identiconSvg) { - // rl.pluginSettingsGet('avatars', 'identicon'); - element.onerror = () => hash(from.email).then(hash => - fn(window.identiconSvg(hash, fromChars(from))) - ); - } - fn(`?Avatar/${bimi}/${msg.avatar}`); + element.onerror = () => setIdenticon(from, fn); + fn(`?Avatar/${'pass' == from.dkimStatus ? 1 : 0}/${msg.avatar}`); } else { - queue.push([msg, fn]); - runQueue(); + addQueue(msg, fn); } } } @@ -164,14 +158,12 @@ if (url) { fn(url); } else if (msg.avatar) { - let bimi = 'pass' == msg.from[0].dkimStatus ? 1 : 0; - fn(`?Avatar/${bimi}/${msg.avatar}`); + fn(`?Avatar/${'pass' == msg.from[0].dkimStatus ? 1 : 0}/${msg.avatar}`); } else { -// let from = msg.from[0], bimi = 'pass' == from.dkimStatus ? 1 : 0; -// view.viewUserPic(`?Avatar/${bimi}/${encodeURIComponent(from.email)}`); +// let from = msg.from[0]; +// view.viewUserPic(`?Avatar/${'pass' == from.dkimStatus ? 1 : 0}/${encodeURIComponent(from.email)}`); // view.viewUserPicVisible(true); - queue.push([msg, fn]); - runQueue(); + addQueue(msg, fn); } } }); diff --git a/plugins/avatars/identicon.js b/plugins/avatars/identicon.js index 8a124d7ff..59664ccbb 100644 --- a/plugins/avatars/identicon.js +++ b/plugins/avatars/identicon.js @@ -15,14 +15,15 @@ window.identiconSvg = (hash, txt) => { l, l + h % 1 * s, l + s - ]; + ], + m = txt ? 128 : 255, + 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) { - const color = 'rgb(' + [ - v[ ~~h % 6 ] * 255 / 2, // red - v[ (h | 16) % 6 ] * 255 / 2, // green - v[ (h | 8) % 6 ] * 255 / 2 // blue - ].map(Math.round).join(',') + ')'; txt = ` { dy=".1em" dominant-baseline="middle" fill="#FFF">${txt} `; } else { - const color = 'rgb(' + [ - v[ ~~h % 6 ] * 255, // red - v[ (h | 16) % 6 ] * 255, // green - v[ (h | 8) % 6 ] * 255 // blue - ].map(Math.round).join(',') + ')', - cell = Math.floor((size - ((Math.floor(size * margin)) * 2)) / 5), + const cell = Math.floor((size - ((Math.floor(size * margin)) * 2)) / 5), imargin = Math.floor((size - cell * 5) / 2), rectangles = [], add = (x, y) => rectangles.push(""); - // the first 15 characters of the hash control the pixels (even/odd) // they are drawn down the middle first, then mirrored outwards for (let i = 0; i < 15; ++i) { @@ -51,7 +46,7 @@ window.identiconSvg = (hash, txt) => { } else if (i < 10) { add(1, (i - 5)); add(3, (i - 5)); - } else if (i < 15) { + } else { add(0, (i - 10)); add(4, (i - 10)); } @@ -61,9 +56,7 @@ window.identiconSvg = (hash, txt) => { + rectangles.join('') + ""; } - return 'data:image/svg+xml;base64,' + btoa( - "" + txt + "" - ); + return "" + txt + ""; }; })(); diff --git a/plugins/avatars/images/services/paypal.com.png b/plugins/avatars/images/services/paypal.com.png index 7ddea03c9..e3935011f 100644 Binary files a/plugins/avatars/images/services/paypal.com.png and b/plugins/avatars/images/services/paypal.com.png differ diff --git a/plugins/avatars/index.php b/plugins/avatars/index.php index ec8f0376b..7e7eda1d6 100644 --- a/plugins/avatars/index.php +++ b/plugins/avatars/index.php @@ -8,10 +8,10 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin URL = 'https://snappymail.eu/', VERSION = '1.2', RELEASE = '2022-11-29', - REQUIRED = '2.22.4', + REQUIRED = '2.22.5', CATEGORY = 'Contacts', LICENSE = 'MIT', - DESCRIPTION = 'Show photo of sender in message and messages list (supports BIMI and Gravatar, Contacts is still TODO)'; + DESCRIPTION = 'Show photo of sender in message and messages list (supports BIMI, Gravatar and identicon, Contacts is still TODO)'; public function Init() : void { @@ -19,9 +19,14 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin $this->addJs('avatars.js'); $this->addJsonHook('Avatar', 'DoAvatar'); $this->addPartHook('Avatar', 'ServiceAvatar'); -// $this->Config()->Get('plugin', 'identicon', false) && $this->addJs('jdenticon.js'); - // GitHub-style - $this->Config()->Get('plugin', 'identicon', false) && $this->addJs('identicon.js'); + $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'); + } + } // https://github.com/the-djmaze/snappymail/issues/714 $this->Config()->Get('plugin', 'delay', true) || $this->addHook('filter.json-response', 'FilterJsonResponse'); } @@ -84,9 +89,15 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin protected function configMapping() : array { $aResult = array( - \RainLoop\Plugins\Property::NewInstance('delay')->SetLabel('Delay loading') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) - ->SetDefaultValue(true), + \RainLoop\Plugins\Property::NewInstance('identicon')->SetLabel('Identicon') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECT) +// ->SetAllowedInJs(true) + ->SetDefaultValue([ + ['id' => 'identicon', 'name' => 'Name characters or squares'], + ['id' => 'jdenticon', 'name' => 'Triangles shape'], + ['id' => 'none', 'name' => 'none'] + ]) + ->SetDescription('https://wikipedia.org/wiki/Identicon'), \RainLoop\Plugins\Property::NewInstance('bimi')->SetLabel('Lookup BIMI') ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) ->SetDefaultValue(false) @@ -94,7 +105,10 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin \RainLoop\Plugins\Property::NewInstance('gravatar')->SetLabel('Lookup Gravatar') ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) ->SetDefaultValue(false) - ->SetDescription('https://wikipedia.org/wiki/Gravatar') + ->SetDescription('https://wikipedia.org/wiki/Gravatar'), + \RainLoop\Plugins\Property::NewInstance('delay')->SetLabel('Delay lookup loading') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) + ->SetDefaultValue(true), ); /* if (\class_exists('OC') && isset(\OC::$server)) { @@ -104,11 +118,6 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin ->SetDefaultValue(false); } */ - $aResult[] = \RainLoop\Plugins\Property::NewInstance('identicon')->SetLabel('Else create Identicon') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) -// ->SetAllowedInJs(true) - ->SetDefaultValue(false) - ->SetDescription('https://wikipedia.org/wiki/Identicon'); return $aResult; } diff --git a/plugins/avatars/jdenticon.js b/plugins/avatars/jdenticon.js index efaf9f69d..6652881a5 100644 --- a/plugins/avatars/jdenticon.js +++ b/plugins/avatars/jdenticon.js @@ -671,7 +671,7 @@ window.identiconSvg = hash => { renderer.finish(); - return 'data:image/svg+xml;base64,' + btoa(writer); + return writer; }; })(); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Enumerations/PluginPropertyType.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Enumerations/PluginPropertyType.php index 6b18a05f9..2cbf7a9d0 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Enumerations/PluginPropertyType.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Enumerations/PluginPropertyType.php @@ -12,5 +12,6 @@ class PluginPropertyType PASSWORD = 3, SELECTION = 4, BOOL = 5, - URL = 6; + URL = 6, + SELECT = 8; } diff --git a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsPluginProperty.html b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsPluginProperty.html index 0e952f2af..21a2a68d1 100644 --- a/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsPluginProperty.html +++ b/snappymail/v/0.0.0/app/templates/Views/Admin/AdminSettingsPluginProperty.html @@ -28,6 +28,9 @@ + + +