From 233a05a68abe1ba51dbcb7b53a7d2b859069efee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Thu, 24 Jan 2019 23:51:41 +0100 Subject: [PATCH] Allow setting Avatars on Communities by combining XEP-0084 (metadata + url) and XEP-0060 --- CHANGELOG.md | 1 + app/Info.php | 9 ++++- .../CommunitiesServer/_communitiesserver.tpl | 5 ++- .../CommunityAffiliations.php | 1 - .../_communityaffiliations.tpl | 7 +++- .../CommunityConfig/CommunityConfig.php | 40 +++++++++++++++++++ .../_communityconfig_avatar.tpl | 30 ++++++++++++++ app/widgets/CommunityData/CommunityData.php | 16 +++++++- app/widgets/CommunityData/_communitydata.tpl | 5 ++- app/widgets/CommunityData/communitydata.css | 6 +++ app/widgets/CommunityData/communitydata.js | 6 +++ .../_communitysubscriptions.tpl | 16 ++++++-- ...0124220622_add_avatar_hash_infos_table.php | 21 ++++++++++ lib/moxl/src/Moxl/Stanza/Avatar.php | 21 ++++++---- lib/moxl/src/Moxl/Xec/Action/Avatar/Get.php | 3 +- lib/moxl/src/Moxl/Xec/Action/Avatar/Set.php | 21 ++++++++-- .../src/Moxl/Xec/Action/Pubsub/GetItem.php | 27 ++++++++++++- .../src/Moxl/Xec/Action/Pubsub/GetItems.php | 18 +++++++++ .../src/Moxl/Xec/Action/Pubsub/GetItemsId.php | 7 +++- src/Movim/Picture.php | 23 ++++++++--- 20 files changed, 252 insertions(+), 31 deletions(-) create mode 100644 app/widgets/CommunityConfig/_communityconfig_avatar.tpl create mode 100644 app/widgets/CommunityData/communitydata.css create mode 100644 app/widgets/CommunityData/communitydata.js create mode 100644 database/migrations/20190124220622_add_avatar_hash_infos_table.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c2b0130..f5861d40d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ v0.14.1 (trunk) * Chat bubbles a bit more compact * Display single emojis as small stickers * Display chat states in MUC, handle the chat states with a new ChatStates class + * Allow setting Avatars on Communities by combining XEP-0084 (metadata + url) and XEP-0060 v0.14 --------------------------- diff --git a/app/Info.php b/app/Info.php index 66b8a89dd..91c0f9bdf 100644 --- a/app/Info.php +++ b/app/Info.php @@ -8,7 +8,7 @@ class Info extends Model { protected $primaryKey = ['server', 'node']; public $incrementing = false; - protected $fillable = ['server', 'node']; + protected $fillable = ['server', 'node', 'avatarhash']; public function setAdminaddressesAttribute(array $arr) { @@ -121,6 +121,13 @@ class Info extends Model ->first(); } + public function getPhoto($size = 'm') + { + return isset($this->attributes['avatarhash']) + ? getPhoto($this->attributes['avatarhash'], $size) + : null; + } + public function set($query) { $from = (string)$query->attributes()->from; diff --git a/app/widgets/CommunitiesServer/_communitiesserver.tpl b/app/widgets/CommunitiesServer/_communitiesserver.tpl index 4fe84c372..870fa258a 100644 --- a/app/widgets/CommunitiesServer/_communitiesserver.tpl +++ b/app/widgets/CommunitiesServer/_communitiesserver.tpl @@ -45,9 +45,10 @@ {/if} - {if="$value->logo"} + {$url = $value->getPhoto('m')} + {if="$url"} - + {else} diff --git a/app/widgets/CommunityAffiliations/CommunityAffiliations.php b/app/widgets/CommunityAffiliations/CommunityAffiliations.php index 49b73d8c1..e5b23089d 100644 --- a/app/widgets/CommunityAffiliations/CommunityAffiliations.php +++ b/app/widgets/CommunityAffiliations/CommunityAffiliations.php @@ -18,7 +18,6 @@ class CommunityAffiliations extends Base $this->registerEvent('pubsub_setaffiliations_handle', 'onAffiliationsSet'); $this->registerEvent('pubsub_delete_handle', 'onDelete'); $this->registerEvent('pubsub_delete_error', 'onDeleteError'); - $this->registerEvent('pubsub_getsubscriptions_handle', 'onSubscriptions'); $this->addjs('communityaffiliations.js'); diff --git a/app/widgets/CommunityAffiliations/_communityaffiliations.tpl b/app/widgets/CommunityAffiliations/_communityaffiliations.tpl index 064c3e326..6fa660441 100644 --- a/app/widgets/CommunityAffiliations/_communityaffiliations.tpl +++ b/app/widgets/CommunityAffiliations/_communityaffiliations.tpl @@ -1,5 +1,11 @@ {if="$role == 'owner'"} {/if} - diff --git a/app/widgets/CommunityConfig/CommunityConfig.php b/app/widgets/CommunityConfig/CommunityConfig.php index 9b382eceb..8c2221187 100644 --- a/app/widgets/CommunityConfig/CommunityConfig.php +++ b/app/widgets/CommunityConfig/CommunityConfig.php @@ -4,15 +4,20 @@ use Movim\Widget\Base; use Moxl\Xec\Action\Pubsub\GetConfig; use Moxl\Xec\Action\Pubsub\SetConfig; +use Moxl\Xec\Action\Avatar\Get as AvatarGet; +use Moxl\Xec\Action\Avatar\Set as AvatarSet; use Respect\Validation\Validator; +use Movim\Picture; + class CommunityConfig extends Base { public function load() { $this->registerEvent('pubsub_getconfig_handle', 'onConfig'); $this->registerEvent('pubsub_setconfig_handle', 'onConfigSaved'); + $this->registerEvent('avatar_set_pubsub', 'onAvatarSet'); } public function onConfig($packet) @@ -33,11 +38,46 @@ class CommunityConfig extends Base Dialog::fill($view->draw('_communityconfig'), true); } + public function onAvatarSet($packet) + { + $this->rpc('Dialog_ajaxClear'); + Notification::append(null, $this->__('avatar.updated')); + } + public function onConfigSaved() { Notification::append(false, $this->__('communityaffiliation.config_saved')); } + public function ajaxGetAvatar($origin, $node) + { + if (!$this->validateServerNode($origin, $node)) return; + + $view = $this->tpl(); + $view->assign('info', \App\Info::where('server', $origin) + ->where('node', $node) + ->first()); + + Dialog::fill($view->draw('_communityconfig_avatar')); + } + + public function ajaxSetAvatar($origin, $node, $form) + { + if (!$this->validateServerNode($origin, $node)) return; + + $key = $origin.$node.'avatar'; + + $p = new Picture; + $p->fromBase($form->photobin->value); + $p->set($key, 'jpeg', 60); + + $r = new AvatarSet; + $r->setTo($origin) + ->setNode($node) + ->setUrl($p->getOriginal($key)) + ->setData($p->toBase())->request(); + } + public function ajaxGetConfig($origin, $node, $advanced = false) { if (!$this->validateServerNode($origin, $node)) return; diff --git a/app/widgets/CommunityConfig/_communityconfig_avatar.tpl b/app/widgets/CommunityConfig/_communityconfig_avatar.tpl new file mode 100644 index 000000000..39f1c32f4 --- /dev/null +++ b/app/widgets/CommunityConfig/_communityconfig_avatar.tpl @@ -0,0 +1,30 @@ +
+
+ + +
+
    +
  • + + attach_file + +

    {$c->__('avatar.file')}

    +

    +
  • +
+
+
+ + +
diff --git a/app/widgets/CommunityData/CommunityData.php b/app/widgets/CommunityData/CommunityData.php index ca3e8ea42..d37769fc6 100644 --- a/app/widgets/CommunityData/CommunityData.php +++ b/app/widgets/CommunityData/CommunityData.php @@ -1,5 +1,7 @@ addcss('communitydata.css'); + $this->addjs('communitydata.js'); $this->registerEvent('disco_request_handle', 'onDiscoRequest', 'community'); + $this->registerEvent('pubsub_getitem_avatar', 'onDiscoRequest', 'community'); } public function onDiscoRequest($packet) { - list($origin, $node) = $packet->content; + list($origin, $node) = array_values($packet->content); if ((substr($node, 0, 30) != 'urn:xmpp:microblog:0:comments/')) { $this->rpc('MovimTpl.fill', '#community_data', $this->prepareData($origin, $node)); } } + public function ajaxGetAvatar($origin, $node) + { + $g = new GetItem; + $g->setTo($origin) + ->setNode($node) + ->setId('urn:xmpp:avatar:metadata') + ->request(); + } + public function prepareData($origin, $node) { $view = $this->tpl(); diff --git a/app/widgets/CommunityData/_communitydata.tpl b/app/widgets/CommunityData/_communitydata.tpl index 43ddac3e1..267e96c1b 100644 --- a/app/widgets/CommunityData/_communitydata.tpl +++ b/app/widgets/CommunityData/_communitydata.tpl @@ -1,10 +1,11 @@
{if="$info"}