mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-10-03 10:24:20 +08:00
Added advanced PluginPropertyType::SELECT for improved Avatars plugin
This commit is contained in:
parent
2f4e17da51
commit
c56cc7be73
7 changed files with 57 additions and 59 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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 |
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -671,7 +671,7 @@ window.identiconSvg = hash => {
|
|||
|
||||
renderer.finish();
|
||||
|
||||
return 'data:image/svg+xml;base64,' + btoa(writer);
|
||||
return writer;
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
@ -12,5 +12,6 @@ class PluginPropertyType
|
|||
PASSWORD = 3,
|
||||
SELECTION = 4,
|
||||
BOOL = 5,
|
||||
URL = 6;
|
||||
URL = 6,
|
||||
SELECT = 8;
|
||||
}
|
||||
|
|
|
@ -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 -->
|
||||
|
|
Loading…
Add table
Reference in a new issue