Page MenuHomePhabricator

D8525.diff
No OneTemporary

D8525.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -109,6 +109,7 @@
'rsrc/css/application/search/search-results.css' => 'f240504c',
'rsrc/css/application/settings/settings.css' => 'ea8f5915',
'rsrc/css/application/slowvote/slowvote.css' => '266df6a1',
+ 'rsrc/css/application/subscriptions/subscribers-list.css' => '5bb30c78',
'rsrc/css/application/tokens/tokens.css' => 'fb286311',
'rsrc/css/application/uiexample/example.css' => '4741b891',
'rsrc/css/core/core.css' => 'da26ddb2',
@@ -804,6 +805,7 @@
'sprite-projects-css' => '7578fa56',
'sprite-status-css' => '8bce1c97',
'sprite-tokens-css' => '1706b943',
+ 'subscribers-list-css' => '5bb30c78',
'syntax-highlighting-css' => '3c18c1cb',
'tokens-css' => 'fb286311',
),
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2092,6 +2092,7 @@
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
+ 'PhabricatorSubscriptionsListController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsListController.php',
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
'PhabricatorSymbolNameLinter' => 'infrastructure/lint/hook/PhabricatorSymbolNameLinter.php',
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
@@ -2521,6 +2522,8 @@
'SleepBuildStepImplementation' => 'applications/harbormaster/step/SleepBuildStepImplementation.php',
'SlowvoteEmbedView' => 'applications/slowvote/view/SlowvoteEmbedView.php',
'SlowvoteRemarkupRule' => 'applications/slowvote/remarkup/SlowvoteRemarkupRule.php',
+ 'SubscriptionListDialogBuilder' => 'applications/subscriptions/view/SubscriptionListDialogBuilder.php',
+ 'SubscriptionListStringBuilder' => 'applications/subscriptions/view/SubscriptionListStringBuilder.php',
'UploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/UploadArtifactBuildStepImplementation.php',
'VariableBuildStepImplementation' => 'applications/harbormaster/step/VariableBuildStepImplementation.php',
'WaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php',
@@ -4889,6 +4892,7 @@
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
+ 'PhabricatorSubscriptionsListController' => 'PhabricatorController',
'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php
--- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php
+++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php
@@ -516,11 +516,13 @@
pht('Priority'),
ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
- $view->addProperty(
- pht('Subscribers'),
- $task->getCCPHIDs()
- ? $this->renderHandlesForPHIDs($task->getCCPHIDs(), ',')
- : phutil_tag('em', array(), pht('None')));
+ $handles = $this->getLoadedHandles();
+ $cc_handles = array_select_keys($handles, $task->getCCPHIDs());
+ $subscriber_html = id(new SubscriptionListStringBuilder())
+ ->setObjectPHID($task->getPHID())
+ ->setHandles($cc_handles)
+ ->buildPropertyString();
+ $view->addProperty(pht('Subscribers'), $subscriber_html);
$view->addProperty(
pht('Author'),
diff --git a/src/applications/subscriptions/application/PhabricatorApplicationSubscriptions.php b/src/applications/subscriptions/application/PhabricatorApplicationSubscriptions.php
--- a/src/applications/subscriptions/application/PhabricatorApplicationSubscriptions.php
+++ b/src/applications/subscriptions/application/PhabricatorApplicationSubscriptions.php
@@ -21,6 +21,7 @@
'/subscriptions/' => array(
'(?P<action>add|delete)/'.
'(?P<phid>[^/]+)/' => 'PhabricatorSubscriptionsEditController',
+ 'list/(?P<phid>[^/]+)/' => 'PhabricatorSubscriptionsListController',
),
);
}
diff --git a/src/applications/subscriptions/controller/PhabricatorSubscriptionsListController.php b/src/applications/subscriptions/controller/PhabricatorSubscriptionsListController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/subscriptions/controller/PhabricatorSubscriptionsListController.php
@@ -0,0 +1,49 @@
+<?php
+
+final class PhabricatorSubscriptionsListController
+ extends PhabricatorController {
+
+ private $phid;
+
+ public function willProcessRequest(array $data) {
+ $this->phid = idx($data, 'phid');
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $viewer = $request->getUser();
+ $phid = $this->phid;
+
+ $object = id(new PhabricatorObjectQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($phid))
+ ->executeOne();
+
+ if ($object instanceof PhabricatorSubscribableInterface) {
+ $subscriber_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
+ $phid);
+ } else if ($object instanceof ManiphestTask) {
+ $subscriber_phids = $object->getCCPHIDs();
+ }
+
+ $handle_phids = $subscriber_phids;
+ $handle_phids[] = $phid;
+
+ $handles = id(new PhabricatorHandleQuery())
+ ->setViewer($viewer)
+ ->withPHIDs($handle_phids)
+ ->execute();
+ $object_handle = $handles[$phid];
+
+ $dialog = id(new SubscriptionListDialogBuilder())
+ ->setViewer($viewer)
+ ->setTitle(pht('Subscribers for %s', $object_handle->getFullName()))
+ ->setObjectPHID($phid)
+ ->setHandles($handles)
+ ->buildDialog();
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ }
+
+}
diff --git a/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php b/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php
--- a/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php
+++ b/src/applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php
@@ -113,14 +113,13 @@
->setViewer($user)
->withPHIDs($subscribers)
->execute();
- $sub_view = array();
- foreach ($subscribers as $subscriber) {
- $sub_view[] = $handles[$subscriber]->renderLink();
- }
- $sub_view = phutil_implode_html(', ', $sub_view);
} else {
- $sub_view = phutil_tag('em', array(), pht('None'));
+ $handles = array();
}
+ $sub_view = id(new SubscriptionListStringBuilder())
+ ->setObjectPHID($object->getPHID())
+ ->setHandles($handles)
+ ->buildPropertyString();
$view = $event->getValue('view');
$view->addProperty(pht('Subscribers'), $sub_view);
diff --git a/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php b/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php
new file mode 100644
--- /dev/null
+++ b/src/applications/subscriptions/view/SubscriptionListDialogBuilder.php
@@ -0,0 +1,78 @@
+<?php
+
+final class SubscriptionListDialogBuilder {
+
+ private $viewer;
+ private $handles;
+ private $objectPHID;
+ private $title;
+
+ public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ public function getViewer() {
+ return $this->viewer;
+ }
+
+ public function setHandles(array $handles) {
+ assert_instances_of($handles, 'PhabricatorObjectHandle');
+ $this->handles = $handles;
+ return $this;
+ }
+
+ public function getHandles() {
+ return $this->handles;
+ }
+
+ public function setObjectPHID($object_phid) {
+ $this->objectPHID = $object_phid;
+ return $this;
+ }
+
+ public function getObjectPHID() {
+ return $this->objectPHID;
+ }
+
+ public function setTitle($title) {
+ $this->title = $title;
+ return $this;
+ }
+
+ public function getTitle() {
+ return $this->title;
+ }
+
+ public function buildDialog() {
+ $phid = $this->getObjectPHID();
+ $handles = $this->getHandles();
+ $object_handle = $handles[$phid];
+ unset($handles[$phid]);
+
+ require_celerity_resource('subscribers-list-css');
+ return id(new AphrontDialogView())
+ ->setUser($this->getViewer())
+ ->setClass('subscriber-list-dialog')
+ ->setTitle($this->getTitle())
+ ->appendChild($this->buildBody($this->getViewer(), $handles))
+ ->addCancelButton($object_handle->getURI(), pht('Dismiss'));
+ }
+
+ private function buildBody(PhabricatorUser $viewer, array $handles) {
+
+ $list = id(new PHUIObjectItemListView())
+ ->setUser($viewer);
+ foreach ($handles as $handle) {
+ // TODO - include $handle image - T4400
+ $item = id(new PHUIObjectItemView())
+ ->setHeader($handle->getFullName())
+ ->setHref($handle->getURI())
+ ->setDisabled($handle->isDisabled());
+ $list->addItem($item);
+ }
+
+ return $list;
+ }
+
+}
diff --git a/src/applications/subscriptions/view/SubscriptionListStringBuilder.php b/src/applications/subscriptions/view/SubscriptionListStringBuilder.php
new file mode 100644
--- /dev/null
+++ b/src/applications/subscriptions/view/SubscriptionListStringBuilder.php
@@ -0,0 +1,64 @@
+<?php
+
+final class SubscriptionListStringBuilder {
+
+ private $handles;
+ private $objectPHID;
+
+ public function setHandles(array $handles) {
+ assert_instances_of($handles, 'PhabricatorObjectHandle');
+ $this->handles = $handles;
+ return $this;
+ }
+
+ public function getHandles() {
+ return $this->handles;
+ }
+
+ public function setObjectPHID($object_phid) {
+ $this->objectPHID = $object_phid;
+ return $this;
+ }
+
+ public function getObjectPHID() {
+ return $this->objectPHID;
+ }
+
+ public function buildPropertyString() {
+ $phid = $this->getObjectPHID();
+ $handles = $this->getHandles();
+
+ if (!$handles) {
+ return phutil_tag('em', array(), pht('None'));
+ }
+
+ $html = array();
+ $show_count = 3;
+ $subscribers_count = count($handles);
+ if ($subscribers_count <= $show_count) {
+ return phutil_implode_html(', ', mpull($handles, 'renderLink'));
+ }
+
+ $args = array('%s, %s, %s, and %s');
+ $shown = 0;
+ foreach ($handles as $handle) {
+ $shown++;
+ if ($shown > $show_count) {
+ break;
+ }
+ $args[] = $handle->renderLink();
+ }
+ $not_shown_count = $subscribers_count - $show_count;
+ $not_shown_txt = pht('%d other(s)', $not_shown_count);
+ $args[] = javelin_tag(
+ 'a',
+ array(
+ 'href' => '/subscriptions/list/'.$phid.'/',
+ 'sigil' => 'workflow'
+ ),
+ $not_shown_txt);
+
+ return call_user_func_array('pht', $args);
+ }
+
+}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
--- a/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
+++ b/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
@@ -541,6 +541,11 @@
),
),
+ '%d other(s)' => array(
+ '1 other',
+ '%d others',
+ ),
+
'%s edited subscriber(s), added %d: %s; removed %d: %s.' =>
'%s edited subscribers, added: %3$s; removed: %5$s',
diff --git a/webroot/rsrc/css/application/subscriptions/subscribers-list.css b/webroot/rsrc/css/application/subscriptions/subscribers-list.css
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/css/application/subscriptions/subscribers-list.css
@@ -0,0 +1,15 @@
+/**
+ * @provides subscribers-list-css
+ */
+
+.subscriber-list-dialog {
+ width: 400px;
+}
+
+.subscriber-list-dialog .aphront-dialog-body {
+ padding: 0;
+}
+
+.subscriber-list-dialog .phui-object-item-list-view {
+ margin: 0;
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 2, 3:19 AM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6721819
Default Alt Text
D8525.diff (12 KB)

Event Timeline