From 85bf88e400fa7f4cb55d99517dace72068bcd6c8 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 24 Aug 2012 13:19:47 -0700 Subject: [PATCH] Allow pastes to be flagged Summary: This does a few things: - Allows you to flag pastes. This is straightforward. - Allows Applications to register event listeners. - Makes object action lists emit a 'didrenderactions' event, so other applications can add more actions. The Flags application injects its action in this way. This should generally make it much easier to add actions to objects when we add new applications, with less code duplication and better modularity. We have a really hacky version of this in Differential that I want to get rid of in lieu of this more general approach. I'm going to make object lists do the same thing, so any application can jump in and add stuff. Test Plan: Flagged and unflagged pastes. Viewed home page, differential, flags list. Reviewers: vrana, btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D3377 --- scripts/celerity/generate_sprites.php | 15 +++- src/__celerity_resource_map__.php | 10 +-- src/__phutil_library_map__.php | 2 + .../base/PhabricatorApplication.php | 4 ++ .../flag/ConduitAPI_flag_query_Method.php | 1 + .../PhabricatorDirectoryMainController.php | 1 + .../PhabricatorApplicationFlags.php | 6 ++ .../PhabricatorFlagEditController.php | 2 +- .../PhabricatorFlagListController.php | 1 + .../PhabricatorFlagsUIEventListener.php | 64 ++++++++++++++++++ .../flag/query/PhabricatorFlagQuery.php | 9 +++ .../PhabricatorPasteViewController.php | 2 + .../handle/PhabricatorObjectHandleData.php | 10 ++- .../events/PhabricatorEventEngine.php | 8 +++ .../events/constant/PhabricatorEventType.php | 6 ++ src/view/layout/PhabricatorActionListView.php | 35 +++++++++- .../layout/PhabricatorPropertyListView.php | 7 +- webroot/rsrc/css/autosprite.css | 36 ++++++++++ .../layout/phabricator-action-list-view.css | 4 +- .../layout/phabricator-property-list-view.css | 4 +- webroot/rsrc/image/autosprite.png | Bin 84760 -> 89649 bytes 21 files changed, 209 insertions(+), 18 deletions(-) create mode 100644 src/applications/flag/events/PhabricatorFlagsUIEventListener.php diff --git a/scripts/celerity/generate_sprites.php b/scripts/celerity/generate_sprites.php index df40173c85..5bf389f9a7 100755 --- a/scripts/celerity/generate_sprites.php +++ b/scripts/celerity/generate_sprites.php @@ -159,9 +159,18 @@ $action_template = id(new PhutilSprite()) ->setSourceSize(16, 16); $action_map = array( - 'file' => 'icon/page_white_text.png', - 'fork' => 'icon/arrow_branch.png', - 'edit' => 'icon/page_white_edit.png', + 'file' => 'icon/page_white_text.png', + 'fork' => 'icon/arrow_branch.png', + 'edit' => 'icon/page_white_edit.png', + 'flag-0' => 'icon/flag-0.png', + 'flag-1' => 'icon/flag-1.png', + 'flag-2' => 'icon/flag-2.png', + 'flag-3' => 'icon/flag-3.png', + 'flag-4' => 'icon/flag-4.png', + 'flag-5' => 'icon/flag-5.png', + 'flag-6' => 'icon/flag-6.png', + 'flag-7' => 'icon/flag-7.png', + 'flag-ghost' => 'icon/flag-ghost.png', ); foreach ($action_map as $icon => $source) { diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index d135a3c882..90056a29f2 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -65,8 +65,8 @@ celerity_register_resource_map(array( ), '/rsrc/image/autosprite.png' => array( - 'hash' => '4a85e6c178f7dbdf1dc4f59f47a5e56b', - 'uri' => '/res/4a85e6c1/rsrc/image/autosprite.png', + 'hash' => 'bd70ca6308d6f80a87a10068a04867f8', + 'uri' => '/res/bd70ca63/rsrc/image/autosprite.png', 'disk' => '/rsrc/image/autosprite.png', 'type' => 'png', ), @@ -671,7 +671,7 @@ celerity_register_resource_map(array( ), 'autosprite-css' => array( - 'uri' => '/res/9ed6c0e6/rsrc/css/autosprite.css', + 'uri' => '/res/114f6e40/rsrc/css/autosprite.css', 'type' => 'css', 'requires' => array( @@ -2265,7 +2265,7 @@ celerity_register_resource_map(array( ), 'phabricator-action-list-view-css' => array( - 'uri' => '/res/f70fbcd4/rsrc/css/layout/phabricator-action-list-view.css', + 'uri' => '/res/1b4eef71/rsrc/css/layout/phabricator-action-list-view.css', 'type' => 'css', 'requires' => array( @@ -2603,7 +2603,7 @@ celerity_register_resource_map(array( ), 'phabricator-property-list-view-css' => array( - 'uri' => '/res/598fccad/rsrc/css/layout/phabricator-property-list-view.css', + 'uri' => '/res/ff5d093d/rsrc/css/layout/phabricator-property-list-view.css', 'type' => 'css', 'requires' => array( diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 411db2cfd3..a3d94388bf 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -743,6 +743,7 @@ phutil_register_library_map(array( 'PhabricatorFlagListController' => 'applications/flag/controller/PhabricatorFlagListController.php', 'PhabricatorFlagListView' => 'applications/flag/view/PhabricatorFlagListView.php', 'PhabricatorFlagQuery' => 'applications/flag/query/PhabricatorFlagQuery.php', + 'PhabricatorFlagsUIEventListener' => 'applications/flag/events/PhabricatorFlagsUIEventListener.php', 'PhabricatorFormExample' => 'applications/uiexample/examples/PhabricatorFormExample.php', 'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/PhabricatorGarbageCollectorDaemon.php', 'PhabricatorGitGraphStream' => 'applications/repository/daemon/PhabricatorGitGraphStream.php', @@ -1864,6 +1865,7 @@ phutil_register_library_map(array( 'PhabricatorFlagEditController' => 'PhabricatorFlagController', 'PhabricatorFlagListController' => 'PhabricatorFlagController', 'PhabricatorFlagListView' => 'AphrontView', + 'PhabricatorFlagsUIEventListener' => 'PhutilEventListener', 'PhabricatorFormExample' => 'PhabricatorUIExample', 'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon', 'PhabricatorGlobalLock' => 'PhutilLock', diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 0420e20128..2bea83af0e 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -89,6 +89,10 @@ abstract class PhabricatorApplication { return null; } + public function getEventListeners() { + return array(); + } + /* -( URI Routing )-------------------------------------------------------- */ diff --git a/src/applications/conduit/method/flag/ConduitAPI_flag_query_Method.php b/src/applications/conduit/method/flag/ConduitAPI_flag_query_Method.php index 9368977f1e..04d4f4e5b4 100644 --- a/src/applications/conduit/method/flag/ConduitAPI_flag_query_Method.php +++ b/src/applications/conduit/method/flag/ConduitAPI_flag_query_Method.php @@ -48,6 +48,7 @@ final class ConduitAPI_flag_query_Method extends ConduitAPI_flag_Method { protected function execute(ConduitAPIRequest $request) { $query = new PhabricatorFlagQuery(); + $query->setViewer($request->getUser()); $owner_phids = $request->getValue('ownerPHIDs', array()); if ($owner_phids) { diff --git a/src/applications/directory/controller/PhabricatorDirectoryMainController.php b/src/applications/directory/controller/PhabricatorDirectoryMainController.php index e0784a211a..e9526f648e 100644 --- a/src/applications/directory/controller/PhabricatorDirectoryMainController.php +++ b/src/applications/directory/controller/PhabricatorDirectoryMainController.php @@ -206,6 +206,7 @@ final class PhabricatorDirectoryMainController $user = $this->getRequest()->getUser(); $flag_query = id(new PhabricatorFlagQuery()) + ->setViewer($user) ->withOwnerPHIDs(array($user->getPHID())) ->needHandles(true) ->setLimit(10); diff --git a/src/applications/flag/application/PhabricatorApplicationFlags.php b/src/applications/flag/application/PhabricatorApplicationFlags.php index 016e992954..e6721ec522 100644 --- a/src/applications/flag/application/PhabricatorApplicationFlags.php +++ b/src/applications/flag/application/PhabricatorApplicationFlags.php @@ -30,6 +30,12 @@ final class PhabricatorApplicationFlags extends PhabricatorApplication { return 'flags'; } + public function getEventListeners() { + return array( + new PhabricatorFlagsUIEventListener(), + ); + } + public function loadStatus(PhabricatorUser $user) { $status = array(); diff --git a/src/applications/flag/controller/PhabricatorFlagEditController.php b/src/applications/flag/controller/PhabricatorFlagEditController.php index ed1f292dcb..16926e0268 100644 --- a/src/applications/flag/controller/PhabricatorFlagEditController.php +++ b/src/applications/flag/controller/PhabricatorFlagEditController.php @@ -29,7 +29,7 @@ final class PhabricatorFlagEditController extends PhabricatorFlagController { $user = $request->getUser(); $phid = $this->phid; - $handle = PhabricatorObjectHandleData::loadOneHandle($phid); + $handle = PhabricatorObjectHandleData::loadOneHandle($phid, $user); if (!$handle->isComplete()) { return new Aphront404Response(); diff --git a/src/applications/flag/controller/PhabricatorFlagListController.php b/src/applications/flag/controller/PhabricatorFlagListController.php index a310e5f73c..da784cb920 100644 --- a/src/applications/flag/controller/PhabricatorFlagListController.php +++ b/src/applications/flag/controller/PhabricatorFlagListController.php @@ -29,6 +29,7 @@ final class PhabricatorFlagListController extends PhabricatorFlagController { $query = new PhabricatorFlagQuery(); $query->withOwnerPHIDs(array($user->getPHID())); + $query->setViewer($user); $query->needHandles(true); $flags = $query->execute(); diff --git a/src/applications/flag/events/PhabricatorFlagsUIEventListener.php b/src/applications/flag/events/PhabricatorFlagsUIEventListener.php new file mode 100644 index 0000000000..9ed31c4b06 --- /dev/null +++ b/src/applications/flag/events/PhabricatorFlagsUIEventListener.php @@ -0,0 +1,64 @@ +listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS); + } + + public function handleEvent(PhutilEvent $event) { + switch ($event->getType()) { + case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS: + $this->handleActionEvent($event); + break; + } + } + + private function handleActionEvent($event) { + $user = $event->getUser(); + $object = $event->getValue('object'); + + $flag = PhabricatorFlagQuery::loadUserFlag($user, $object->getPHID()); + + if ($flag) { + $color = PhabricatorFlagColor::getColorName($flag->getColor()); + $flag_action = id(new PhabricatorActionView()) + ->setWorkflow(true) + ->setHref('/flag/delete/'.$flag->getID().'/') + ->setName(phutil_escape_html('Remove '.$color.' Flag')) + ->setIcon('flag-'.$flag->getColor()); + } else { + $flag_action = id(new PhabricatorActionView()) + ->setWorkflow(true) + ->setHref('/flag/edit/'.$object->getPHID().'/') + ->setName('Flag For Later') + ->setIcon('flag-ghost'); + + if (!$user->isLoggedIn()) { + $flag_action->setDisabled(true); + } + } + + $actions = $event->getValue('actions'); + $actions[] = $flag_action; + $event->setValue('actions', $actions); + } + +} + diff --git a/src/applications/flag/query/PhabricatorFlagQuery.php b/src/applications/flag/query/PhabricatorFlagQuery.php index 78c6aa6b0c..63135af808 100644 --- a/src/applications/flag/query/PhabricatorFlagQuery.php +++ b/src/applications/flag/query/PhabricatorFlagQuery.php @@ -27,6 +27,12 @@ final class PhabricatorFlagQuery { private $needHandles; private $needObjects; + private $viewer; + + public function setViewer($viewer) { + $this->viewer = $viewer; + return $this; + } public function withOwnerPHIDs(array $owner_phids) { $this->ownerPHIDs = $owner_phids; @@ -94,6 +100,9 @@ final class PhabricatorFlagQuery { if ($this->needHandles || $this->needObjects) { $phids = ipull($data, 'objectPHID'); $query = new PhabricatorObjectHandleData($phids); + if ($this->viewer) { + $query->setViewer($this->viewer); + } if ($this->needHandles) { $handles = $query->loadHandles(); diff --git a/src/applications/paste/controller/PhabricatorPasteViewController.php b/src/applications/paste/controller/PhabricatorPasteViewController.php index 971840f05c..ddd559ce74 100644 --- a/src/applications/paste/controller/PhabricatorPasteViewController.php +++ b/src/applications/paste/controller/PhabricatorPasteViewController.php @@ -99,6 +99,8 @@ final class PhabricatorPasteViewController extends PhabricatorPasteController { PhabricatorPolicyCapability::CAN_EDIT); return id(new PhabricatorActionListView()) + ->setUser($user) + ->setObject($paste) ->addAction( id(new PhabricatorActionView()) ->setName(pht('Fork This Paste')) diff --git a/src/applications/phid/handle/PhabricatorObjectHandleData.php b/src/applications/phid/handle/PhabricatorObjectHandleData.php index 52e03a8cbc..3a535d53a7 100644 --- a/src/applications/phid/handle/PhabricatorObjectHandleData.php +++ b/src/applications/phid/handle/PhabricatorObjectHandleData.php @@ -30,8 +30,14 @@ final class PhabricatorObjectHandleData { return $this; } - public static function loadOneHandle($phid) { - $handles = id(new PhabricatorObjectHandleData(array($phid)))->loadHandles(); + public static function loadOneHandle($phid, $viewer = null) { + $query = new PhabricatorObjectHandleData(array($phid)); + + if ($viewer) { + $query->setViewer($viewer); + } + + $handles = $query->loadHandles(); return $handles[$phid]; } diff --git a/src/infrastructure/events/PhabricatorEventEngine.php b/src/infrastructure/events/PhabricatorEventEngine.php index c4d7729ed7..904b61757c 100644 --- a/src/infrastructure/events/PhabricatorEventEngine.php +++ b/src/infrastructure/events/PhabricatorEventEngine.php @@ -31,6 +31,14 @@ final class PhabricatorEventEngine { id(new DarkConsoleEventPluginAPI())->register(); id(new ManiphestEdgeEventListener())->register(); + $applications = PhabricatorApplication::getAllInstalledApplications(); + foreach ($applications as $application) { + $listeners = $application->getEventListeners(); + foreach ($listeners as $listener) { + $listener->register(); + } + } + } } diff --git a/src/infrastructure/events/constant/PhabricatorEventType.php b/src/infrastructure/events/constant/PhabricatorEventType.php index 8eeb1b7f76..5820ada8f6 100644 --- a/src/infrastructure/events/constant/PhabricatorEventType.php +++ b/src/infrastructure/events/constant/PhabricatorEventType.php @@ -38,4 +38,10 @@ final class PhabricatorEventType extends PhutilEventType { const TYPE_TEST_DIDRUNTEST = 'test.didRunTest'; + const TYPE_UI_DIDRENDERACTIONS = 'ui.didRenderActions'; + + const TYPE_UI_WILLRENDEROBJECTS = 'ui.willRenderObjects'; + const TYPE_UI_DDIDRENDEROBJECT = 'ui.didRenderObject'; + const TYPE_UI_DIDRENDEROBJECTS = 'ui.didRenderObjects'; + } diff --git a/src/view/layout/PhabricatorActionListView.php b/src/view/layout/PhabricatorActionListView.php index 5c7a1a9c67..cfc7671715 100644 --- a/src/view/layout/PhabricatorActionListView.php +++ b/src/view/layout/PhabricatorActionListView.php @@ -19,22 +19,51 @@ final class PhabricatorActionListView extends AphrontView { private $actions = array(); + private $object; + private $user; + + public function setObject(PhabricatorLiskDAO $object) { + $this->object = $object; + return $this; + } + + public function setUser(PhabricatorUser $user) { + $this->user = $user; + return $this; + } public function addAction(PhabricatorActionView $view) { $this->actions[] = $view; return $this; } - public function render() { - require_celerity_resource('phabricator-action-list-view-css'); + if (!$this->user) { + throw new Exception("Call setUser() before render()!"); + } + if (!$this->object) { + throw new Exception("Call setObject() before render()!"); + } + + $event = new PhabricatorEvent( + PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS, + array( + 'object' => $this->object, + 'actions' => $this->actions, + )); + $event->setUser($this->user); + PhutilEventEngine::dispatchEvent($event); + + $actions = $event->getValue('actions'); + + require_celerity_resource('phabricator-action-list-view-css'); return phutil_render_tag( 'ul', array( 'class' => 'phabricator-action-list-view', ), - $this->renderSingleView($this->actions)); + $this->renderSingleView($actions)); } diff --git a/src/view/layout/PhabricatorPropertyListView.php b/src/view/layout/PhabricatorPropertyListView.php index e3abbcfe69..b13d8b4700 100644 --- a/src/view/layout/PhabricatorPropertyListView.php +++ b/src/view/layout/PhabricatorPropertyListView.php @@ -55,7 +55,12 @@ final class PhabricatorPropertyListView extends AphrontView { array( 'class' => 'phabricator-property-list-view', ), - $list); + $list. + // NOTE: We need this (which is basically a "clear: both;" div) to make + // sure the property list is taller than the action list for objects with + // few properties but many actions. Otherwise, the action list may + // obscure the document content. + '
'); } diff --git a/webroot/rsrc/css/autosprite.css b/webroot/rsrc/css/autosprite.css index 4d62d03452..ed5d10a23a 100644 --- a/webroot/rsrc/css/autosprite.css +++ b/webroot/rsrc/css/autosprite.css @@ -262,3 +262,39 @@ .action-edit { background-position: 0px -2555px; } + +.action-flag-0 { + background-position: 0px -2572px; +} + +.action-flag-1 { + background-position: 0px -2589px; +} + +.action-flag-2 { + background-position: 0px -2606px; +} + +.action-flag-3 { + background-position: 0px -2623px; +} + +.action-flag-4 { + background-position: 0px -2640px; +} + +.action-flag-5 { + background-position: 0px -2657px; +} + +.action-flag-6 { + background-position: 0px -2674px; +} + +.action-flag-7 { + background-position: 0px -2691px; +} + +.action-flag-ghost { + background-position: 0px -2708px; +} diff --git a/webroot/rsrc/css/layout/phabricator-action-list-view.css b/webroot/rsrc/css/layout/phabricator-action-list-view.css index 65fb124fd9..1320d4c2c0 100644 --- a/webroot/rsrc/css/layout/phabricator-action-list-view.css +++ b/webroot/rsrc/css/layout/phabricator-action-list-view.css @@ -10,9 +10,9 @@ border: 1px solid #dcdcdc; padding: .5em 0; - position: absolute; + float: right; margin-top: -30px; - right: 1%; + margin-right: 1%; width: 20%; border-radius: 2px; font-size: 12px; diff --git a/webroot/rsrc/css/layout/phabricator-property-list-view.css b/webroot/rsrc/css/layout/phabricator-property-list-view.css index 0abc7f4c2c..5072568b9a 100644 --- a/webroot/rsrc/css/layout/phabricator-property-list-view.css +++ b/webroot/rsrc/css/layout/phabricator-property-list-view.css @@ -7,8 +7,10 @@ border-style: solid; border-width: 1px 0; background-color: #f9f9f9; +} - overflow: hidden; +.phabriator-property-list-view-end { + clear: both; } .device-desktop .phabricator-property-list-view { diff --git a/webroot/rsrc/image/autosprite.png b/webroot/rsrc/image/autosprite.png index ec0e480ec15b8ba2c3b71d9f5d50a34788457f63..4366ac3c2e74927c237df678aef802c4b19705ac 100644 GIT binary patch delta 10964 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

}# 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 O0000