Added advanced PluginPropertyType::SELECT for improved Avatars plugin

This commit is contained in:
the-djmaze 2022-12-01 19:09:05 +01:00
parent 2f4e17da51
commit c56cc7be73
7 changed files with 57 additions and 59 deletions

View file

@ -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);
}
}
});

View file

@ -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 = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}px" height="${size}px" viewBox="0 0 ${size} ${size}" version="1.1">
<circle fill="${color}" width="${size}" height="${size}" cx="${size/2}" cy="${size/2}" r="${size/2}"/>
<text x="${size}%" y="${size}%" style="color:#FFF" alignment-baseline="middle" text-anchor="middle"
@ -30,18 +31,12 @@ window.identiconSvg = (hash, txt) => {
dy=".1em" dominant-baseline="middle" fill="#FFF">${txt}</text>
</svg>`;
} 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("<rect x='" + (x * cell + imargin)
+ "' y='" + (y * cell + imargin)
+ "' width='" + cell + "' height='" + cell + "'/>");
// 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('')
+ "</g>";
}
return 'data:image/svg+xml;base64,' + btoa(
"<svg xmlns='http://www.w3.org/2000/svg' width='" + size + "' height='" + size + "'>" + txt + "</svg>"
);
return "<svg xmlns='http://www.w3.org/2000/svg' width='" + size + "' height='" + size + "'>" + txt + "</svg>";
};
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -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;
}

View file

@ -671,7 +671,7 @@ window.identiconSvg = hash => {
renderer.finish();
return 'data:image/svg+xml;base64,' + btoa(writer);
return writer;
};
})();

View file

@ -12,5 +12,6 @@ class PluginPropertyType
PASSWORD = 3,
SELECTION = 4,
BOOL = 5,
URL = 6;
URL = 6,
SELECT = 8;
}

View file

@ -28,6 +28,9 @@
<input type="url"
data-bind="value: value, attr: {placeholder: placeholder}">
<!-- /ko -->
<!-- ko if: 8 === Type -->
<select data-bind="options: Default, optionsText: 'name', optionsValue: 'id', value: value"></select>
<!-- /ko -->
<!-- ko if: '' !== Desc -->
<span tabindex="0" class="help-block"><span data-bind="text: Desc"></span></span>
<!-- /ko -->