@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add Maniphest Hovercard event listener

Summary:
Refs T1048
badassery

Test Plan: Used in a future diff. Verified correct appearance of hovercard

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T1048

Differential Revision: https://secure.phabricator.com/D5544

authored by

Anh Nhan Nguyen and committed by
epriestley
b14883bc 81389e79

+122
+2
src/__phutil_library_map__.php
··· 618 618 'ManiphestDefaultTaskExtensions' => 'applications/maniphest/extensions/ManiphestDefaultTaskExtensions.php', 619 619 'ManiphestEdgeEventListener' => 'applications/maniphest/event/ManiphestEdgeEventListener.php', 620 620 'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php', 621 + 'ManiphestHovercardEventListener' => 'applications/maniphest/event/ManiphestHovercardEventListener.php', 621 622 'ManiphestPeopleMenuEventListener' => 'applications/maniphest/event/ManiphestPeopleMenuEventListener.php', 622 623 'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php', 623 624 'ManiphestReplyHandler' => 'applications/maniphest/ManiphestReplyHandler.php', ··· 2289 2290 'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions', 2290 2291 'ManiphestEdgeEventListener' => 'PhutilEventListener', 2291 2292 'ManiphestExportController' => 'ManiphestController', 2293 + 'ManiphestHovercardEventListener' => 'PhutilEventListener', 2292 2294 'ManiphestPeopleMenuEventListener' => 'PhutilEventListener', 2293 2295 'ManiphestRemarkupRule' => 'PhabricatorRemarkupRuleObject', 2294 2296 'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
+1
src/applications/maniphest/application/PhabricatorApplicationManiphest.php
··· 39 39 public function getEventListeners() { 40 40 return array( 41 41 new ManiphestPeopleMenuEventListener(), 42 + new ManiphestHovercardEventListener(), 42 43 ); 43 44 } 44 45
+117
src/applications/maniphest/event/ManiphestHovercardEventListener.php
··· 1 + <?php 2 + 3 + final class ManiphestHovercardEventListener extends PhutilEventListener { 4 + 5 + public function register() { 6 + $this->listen(PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD); 7 + } 8 + 9 + public function handleEvent(PhutilEvent $event) { 10 + switch ($event->getType()) { 11 + case PhabricatorEventType::TYPE_UI_DIDRENDERHOVERCARD: 12 + $this->handleHovercardEvent($event); 13 + break; 14 + } 15 + } 16 + 17 + private function handleHovercardEvent(PhutilEvent $event) { 18 + $viewer = $event->getUser(); 19 + $hovercard = $event->getValue('hovercard'); 20 + $handle = $event->getValue('handle'); 21 + $phid = $handle->getPHID(); 22 + $task = $event->getValue('object'); 23 + 24 + if (!($task instanceof ManiphestTask)) { 25 + return; 26 + } 27 + 28 + // Fun with "Unbeta Pholio", hua hua 29 + $e_dep_on = PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK; 30 + $e_dep_by = PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK; 31 + 32 + $edge_query = id(new PhabricatorEdgeQuery()) 33 + ->withSourcePHIDs(array($phid)) 34 + ->withEdgeTypes( 35 + array( 36 + $e_dep_on, 37 + $e_dep_by, 38 + )); 39 + $edges = idx($edge_query->execute(), $phid); 40 + $edge_phids = $edge_query->getDestinationPHIDs(); 41 + 42 + $owner_phid = $task->getOwnerPHID(); 43 + $project_phids = $task->getProjectPHIDs(); 44 + 45 + $phids = array_filter(array_merge( 46 + array($owner_phid), 47 + $edge_phids, 48 + $project_phids)); 49 + 50 + $viewer_handles = $this->loadHandles($phids, $viewer); 51 + 52 + $hovercard->setTitle(pht('T%d', $task->getID())) 53 + ->setDetail($task->getTitle()); 54 + 55 + $owner = phutil_tag('em', array(), pht('None')); 56 + if ($owner_phid) { 57 + $owner = $viewer_handles[$owner_phid]->renderLink(); 58 + } 59 + 60 + $hovercard->addField(pht('Assigned to'), $owner); 61 + if ($project_phids) { 62 + $hovercard->addField(pht('Projects'), 63 + $this->renderHandlesForPHIDs($project_phids, $viewer_handles)); 64 + } 65 + 66 + if ($edge_phids) { 67 + $edge_types = array( 68 + PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK 69 + => pht('Dependent Tasks'), 70 + PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK 71 + => pht('Depends On'), 72 + ); 73 + 74 + $max_count = 6; 75 + foreach ($edge_types as $edge_type => $edge_name) { 76 + if ($edges[$edge_type]) { 77 + // TODO: This can be made more sophisticated. We still load all 78 + // edges into memory. Only load the ones we need. 79 + $edge_overflow = array(); 80 + if (count($edges[$edge_type]) > $max_count) { 81 + $edges[$edge_type] = array_slice($edges[$edge_type], 0, 6, true); 82 + $edge_overflow = ', ...'; 83 + } 84 + 85 + $hovercard->addField( 86 + $edge_name, 87 + $this->renderHandlesForPHIDs( 88 + array_keys($edges[$edge_type]), 89 + $viewer_handles) 90 + ->appendHTML($edge_overflow)); 91 + } 92 + } 93 + } 94 + 95 + $hovercard->addTag(ManiphestView::renderTagForTask($task)); 96 + 97 + $event->setValue('hovercard', $hovercard); 98 + } 99 + 100 + protected function loadHandles(array $phids, $viewer) { 101 + return id(new PhabricatorObjectHandleData($phids)) 102 + ->setViewer($viewer) 103 + ->loadHandles(); 104 + } 105 + 106 + protected function renderHandlesForPHIDs(array $phids, 107 + array $handles, $glue = ', ') { 108 + 109 + $items = array(); 110 + foreach ($phids as $phid) { 111 + $items[] = $handles[$phid]->renderLink(); 112 + } 113 + 114 + return phutil_implode_html($glue, $items); 115 + } 116 + 117 + }
+2
src/infrastructure/events/constant/PhabricatorEventType.php
··· 31 31 const TYPE_UI_DIDRENDEROBJECTS = 'ui.didRenderObjects'; 32 32 const TYPE_UI_WILLRENDERPROPERTIES = 'ui.willRenderProperties'; 33 33 34 + const TYPE_UI_DIDRENDERHOVERCARD = 'ui.didRenderHovercard'; 35 + 34 36 const TYPE_PEOPLE_DIDRENDERMENU = 'people.didRenderMenu'; 35 37 }