diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 7688d87ae0..f8164a79bc 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -3297,7 +3297,7 @@ celerity_register_resource_map(array( ), 'phabricator-slowvote-css' => array( - 'uri' => '/res/94d20443/rsrc/css/application/slowvote/slowvote.css', + 'uri' => '/res/dd7e273e/rsrc/css/application/slowvote/slowvote.css', 'type' => 'css', 'requires' => array( diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c0280ab399..9095ebf08f 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1728,6 +1728,8 @@ phutil_register_library_map(array( 'ReleephStatusFieldSpecification' => 'applications/releeph/field/specification/ReleephStatusFieldSpecification.php', 'ReleephSummaryFieldSpecification' => 'applications/releeph/field/specification/ReleephSummaryFieldSpecification.php', 'ReleephUserView' => 'applications/releeph/view/user/ReleephUserView.php', + 'SlowvoteEmbedView' => 'applications/slowvote/view/SlowvoteEmbedView.php', + 'SlowvoteRemarkupRule' => 'applications/slowvote/remarkup/SlowvoteRemarkupRule.php', ), 'function' => array( @@ -3455,5 +3457,7 @@ phutil_register_library_map(array( 'ReleephStatusFieldSpecification' => 'ReleephFieldSpecification', 'ReleephSummaryFieldSpecification' => 'ReleephFieldSpecification', 'ReleephUserView' => 'AphrontView', + 'SlowvoteEmbedView' => 'AphrontView', + 'SlowvoteRemarkupRule' => 'PhabricatorRemarkupRuleObject', ), )); diff --git a/src/applications/phid/handle/PhabricatorObjectHandleData.php b/src/applications/phid/handle/PhabricatorObjectHandleData.php index e33a06b3de..2a9743a1d1 100644 --- a/src/applications/phid/handle/PhabricatorObjectHandleData.php +++ b/src/applications/phid/handle/PhabricatorObjectHandleData.php @@ -138,6 +138,11 @@ final class PhabricatorObjectHandleData { ->execute(); return mpull($mocks, null, 'getPHID'); + case PhabricatorPHIDConstants::PHID_TYPE_POLL: + $polls = id(new PhabricatorSlowvotePoll()) + ->loadAllWhere('phid IN (%Ls)', $phids); + return mpull($polls, null, 'getPHID'); + case PhabricatorPHIDConstants::PHID_TYPE_XACT: $subtypes = array(); foreach ($phids as $phid) { @@ -620,6 +625,25 @@ final class PhabricatorObjectHandleData { } break; + case PhabricatorPHIDConstants::PHID_TYPE_POLL: + foreach ($phids as $phid) { + $handle = new PhabricatorObjectHandle(); + $handle->setPHID($phid); + $handle->setType($type); + if (empty($objects[$phid])) { + $handle->setName('Unknown Slowvote'); + } else { + $poll = $objects[$phid]; + $handle->setName('V'.$poll->getID()); + $handle->setFullName( + 'V'.$poll->getID().': '.$poll->getQuestion()); + $handle->setURI('/V'.$poll->getID()); + $handle->setComplete(true); + } + $handles[$phid] = $handle; + } + break; + case PhabricatorPHIDConstants::PHID_TYPE_MCRO: foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); diff --git a/src/applications/slowvote/application/PhabricatorApplicationSlowvote.php b/src/applications/slowvote/application/PhabricatorApplicationSlowvote.php index 2a79292a03..8970fe15b5 100644 --- a/src/applications/slowvote/application/PhabricatorApplicationSlowvote.php +++ b/src/applications/slowvote/application/PhabricatorApplicationSlowvote.php @@ -30,6 +30,12 @@ final class PhabricatorApplicationSlowvote extends PhabricatorApplication { return self::GROUP_UTILITIES; } + public function getRemarkupRules() { + return array( + new SlowvoteRemarkupRule(), + ); + } + public function getRoutes() { return array( '/V(?P[1-9]\d*)' => 'PhabricatorSlowvotePollController', diff --git a/src/applications/slowvote/remarkup/SlowvoteRemarkupRule.php b/src/applications/slowvote/remarkup/SlowvoteRemarkupRule.php new file mode 100644 index 0000000000..e78e01084f --- /dev/null +++ b/src/applications/slowvote/remarkup/SlowvoteRemarkupRule.php @@ -0,0 +1,41 @@ +load(head($ids))); + + return id(new PhabricatorSlowvotePoll()) + ->loadAllWhere('id IN (%Ld)', $ids); + } + + protected function renderObjectEmbed($object, $handle, $options) { + $viewer = $this->getEngine()->getConfig('viewer'); + + $options = id(new PhabricatorSlowvoteOption())->loadAllWhere( + 'pollID = %d', + $object->getID()); + $choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere( + 'pollID = %d', + $object->getID()); + $choices_by_user = mgroup($choices, 'getAuthorPHID'); + + $viewer_choices = idx($choices_by_user, $viewer->getPHID(), array()); + + $embed = id(new SlowvoteEmbedView()) + ->setPoll($object) + ->setOptions($options) + ->setViewerChoices($viewer_choices); + + return $embed->render(); + } + +} diff --git a/src/applications/slowvote/view/SlowvoteEmbedView.php b/src/applications/slowvote/view/SlowvoteEmbedView.php new file mode 100644 index 0000000000..543ad24248 --- /dev/null +++ b/src/applications/slowvote/view/SlowvoteEmbedView.php @@ -0,0 +1,105 @@ +poll = $poll; + return $this; + } + + public function setOptions(array $options) { + $this->options = $options; + return $this; + } + + public function setViewerChoices(array $viewer_choices) { + $this->viewerChoices = $viewer_choices; + return $this; + } + + public function render() { + + if (!$this->poll) { + throw new Exception("Call setPoll() before render()!"); + } + + if (!$this->options) { + throw new Exception("Call setOptions() before render()!"); + } + + if ($this->poll->getShuffle()) { + shuffle($this->options); + } + + require_celerity_resource('phabricator-slowvote-css'); + + $user_choices = array(); + if (!empty($this->viewerChoices)) { + $user_choices = mpull($this->viewerChoices, null, 'getOptionID'); + } + + $options = array(); + $ribbon_colors = array('#DF0101', '#DF7401', '#D7DF01', '#74DF00', + '#01DF01', '#01DF74', '#01DFD7', '#0174DF', '#0101DF', '#5F04B4', + '#B404AE'); + shuffle($ribbon_colors); + + foreach ($this->options as $option) { + $classes = 'phabricator-slowvote-embed-option-text'; + + $selected = ''; + + if (idx($user_choices, $option->getID(), false)) { + $classes .= ' phabricator-slowvote-embed-option-selected'; + $selected = '@'; + } + + $option_text = phutil_tag( + 'div', + array( + 'class' => $classes + ), + $selected.$option->getName()); + + $options[] = phutil_tag( + 'div', + array( + 'class' => 'phabricator-slowvote-embed-option', + 'style' => + sprintf('border-left: 7px solid %s;', array_shift($ribbon_colors)) + ), + array($option_text)); + } + + $link_to_slowvote = phutil_tag( + 'a', + array( + 'href' => '/V'.$this->poll->getID() + ), + $this->poll->getQuestion()); + + $header = phutil_tag( + 'div', + array(), + array('V'.$this->poll->getID().': ', $link_to_slowvote)); + + $body = phutil_tag( + 'div', + array(), + $options); + + return phutil_tag( + 'div', + array( + 'class' => 'phabricator-slowvote-embed' + ), + array($header, $body)); + } +} diff --git a/webroot/rsrc/css/application/slowvote/slowvote.css b/webroot/rsrc/css/application/slowvote/slowvote.css index 6118920993..45433c1ac7 100644 --- a/webroot/rsrc/css/application/slowvote/slowvote.css +++ b/webroot/rsrc/css/application/slowvote/slowvote.css @@ -67,3 +67,25 @@ float: left; margin: 0px 4px 6px 0px; } + +.phabricator-slowvote-embed { + width: 400px; + background: #f7f7f7; + border: 1px solid #dbdbdb; + padding: 5px; +} + +.phabricator-slowvote-embed-option { + margin: 1px; + background: #F0FFFF; +} + +.phabricator-slowvote-embed-option-selected { + padding-left: 0px !important; +} + +.phabricator-slowvote-embed-option-text { + border: 1px solid #dbdbdb; + border-left: 0px; + padding-left: 1em; +}