@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.

Embed slowvotes have basic interaction

Summary: User can now vote through embed slowvote

Test Plan: Voted'n stuff

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin, chad, AnhNhan

Maniphest Tasks: T2883

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

authored by

Lauri-Henrik Jalonen and committed by
epriestley
1fa30775 67da5d6e

+236 -50
+14 -1
src/__celerity_resource_map__.php
··· 2269 2269 ), 2270 2270 'disk' => '/rsrc/js/application/repository/repository-crossreference.js', 2271 2271 ), 2272 + 'javelin-behavior-slowvote-embed' => 2273 + array( 2274 + 'uri' => '/res/1315b118/rsrc/js/application/slowvote/behavior-slowvote-embed.js', 2275 + 'type' => 'js', 2276 + 'requires' => 2277 + array( 2278 + 0 => 'javelin-behavior', 2279 + 1 => 'javelin-util', 2280 + 2 => 'javelin-stratcom', 2281 + 3 => 'javelin-dom', 2282 + ), 2283 + 'disk' => '/rsrc/js/application/slowvote/behavior-slowvote-embed.js', 2284 + ), 2272 2285 'javelin-behavior-stripe-payment-form' => 2273 2286 array( 2274 2287 'uri' => '/res/c1a12d77/rsrc/js/application/phortune/behavior-stripe-payment-form.js', ··· 3332 3345 ), 3333 3346 'phabricator-slowvote-css' => 3334 3347 array( 3335 - 'uri' => '/res/357ccc42/rsrc/css/application/slowvote/slowvote.css', 3348 + 'uri' => '/res/d1c2e05a/rsrc/css/application/slowvote/slowvote.css', 3336 3349 'type' => 'css', 3337 3350 'requires' => 3338 3351 array(
+2
src/__phutil_library_map__.php
··· 1388 1388 'PhabricatorSlowvoteOption' => 'applications/slowvote/storage/PhabricatorSlowvoteOption.php', 1389 1389 'PhabricatorSlowvotePoll' => 'applications/slowvote/storage/PhabricatorSlowvotePoll.php', 1390 1390 'PhabricatorSlowvotePollController' => 'applications/slowvote/controller/PhabricatorSlowvotePollController.php', 1391 + 'PhabricatorSlowvoteVoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteVoteController.php', 1391 1392 'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php', 1392 1393 'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php', 1393 1394 'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php', ··· 3088 3089 'PhabricatorSlowvoteOption' => 'PhabricatorSlowvoteDAO', 3089 3090 'PhabricatorSlowvotePoll' => 'PhabricatorSlowvoteDAO', 3090 3091 'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController', 3092 + 'PhabricatorSlowvoteVoteController' => 'PhabricatorSlowvoteController', 3091 3093 'PhabricatorSlugTestCase' => 'PhabricatorTestCase', 3092 3094 'PhabricatorSortTableExample' => 'PhabricatorUIExample', 3093 3095 'PhabricatorSourceCodeView' => 'AphrontView',
+1
src/applications/slowvote/application/PhabricatorApplicationSlowvote.php
··· 42 42 '/vote/' => array( 43 43 '(?:view/(?P<view>\w+)/)?' => 'PhabricatorSlowvoteListController', 44 44 'create/' => 'PhabricatorSlowvoteCreateController', 45 + '(?P<id>[1-9]\d*)/' => 'PhabricatorSlowvoteVoteController', 45 46 ), 46 47 ); 47 48 }
+10 -41
src/applications/slowvote/controller/PhabricatorSlowvotePollController.php
··· 44 44 $comment_text = $viewer_comment->getCommentText(); 45 45 } 46 46 47 - if ($request->isFormPost()) { 48 - $comment = idx($comments_by_user, $viewer_phid, null); 49 - if ($comment) { 50 - $comment->delete(); 51 - } 52 - 53 - $comment_text = $request->getStr('comments'); 54 - if (strlen($comment_text)) { 55 - id(new PhabricatorSlowvoteComment()) 56 - ->setAuthorPHID($viewer_phid) 57 - ->setPollID($poll->getID()) 58 - ->setCommentText($comment_text) 59 - ->save(); 60 - } 61 - 62 - $votes = $request->getArr('vote'); 63 - 64 - switch ($poll->getMethod()) { 65 - case PhabricatorSlowvotePoll::METHOD_PLURALITY: 66 - // Enforce only one vote. 67 - $votes = array_slice($votes, 0, 1); 68 - break; 69 - case PhabricatorSlowvotePoll::METHOD_APPROVAL: 70 - // No filtering. 71 - break; 72 - default: 73 - throw new Exception("Unknown poll method!"); 74 - } 47 + if ($request->isAjax()) { 48 + $embed = id(new SlowvoteEmbedView()) 49 + ->setPoll($poll) 50 + ->setOptions($options) 51 + ->setViewerChoices($viewer_choices); 75 52 76 - foreach ($viewer_choices as $viewer_choice) { 77 - $viewer_choice->delete(); 78 - } 79 - 80 - foreach ($votes as $vote) { 81 - id(new PhabricatorSlowvoteChoice()) 82 - ->setAuthorPHID($viewer_phid) 83 - ->setPollID($poll->getID()) 84 - ->setOptionID($vote) 85 - ->save(); 86 - } 87 - 88 - return id(new AphrontRedirectResponse())->setURI('/V'.$poll->getID()); 53 + return id(new AphrontAjaxResponse()) 54 + ->setContent(array( 55 + 'pollID' => $poll->getID(), 56 + 'contentHTML' => $embed->render())); 89 57 } 90 58 91 59 require_celerity_resource('phabricator-slowvote-css'); ··· 159 127 160 128 $form = id(new AphrontFormView()) 161 129 ->setUser($user) 130 + ->setAction(sprintf('/vote/%d/', $poll->getID())) 162 131 ->appendChild(hsprintf( 163 132 '<p class="aphront-form-instructions">%s</p>', 164 133 $instructions))
+135
src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php
··· 1 + <?php 2 + 3 + /** 4 + * @group slowvote 5 + */ 6 + final class PhabricatorSlowvoteVoteController 7 + extends PhabricatorSlowvoteController { 8 + 9 + private $id; 10 + 11 + public function willProcessRequest(array $data) { 12 + $this->id = $data['id']; 13 + } 14 + 15 + public function processRequest() { 16 + $request = $this->getRequest(); 17 + $user = $request->getUser(); 18 + 19 + $poll = id(new PhabricatorSlowvotePoll())->load($this->id); 20 + $options = id(new PhabricatorSlowvoteOption())->loadAllWhere( 21 + 'pollID = %d', 22 + $poll->getID()); 23 + $user_choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere( 24 + 'pollID = %d AND authorPHID = %s', 25 + $poll->getID(), 26 + $user->getPHID()); 27 + 28 + $comment_text = $request->getStr('comments'); 29 + $old_comment = id(new PhabricatorSlowvoteComment())->loadOneWhere( 30 + 'pollID = %d AND authorPHID = %s', 31 + $poll->getID(), 32 + $user->getPHID()); 33 + 34 + $update_comment = false; 35 + if ($old_comment && $comment_text && 36 + $old_comment->getCommentText() !== $comment_text) { 37 + 38 + $update_comment = true; 39 + } else if (!$old_comment && $comment_text) { 40 + $update_comment = true; 41 + } 42 + 43 + if ($update_comment) { 44 + if ($old_comment) { 45 + $old_comment->delete(); 46 + } 47 + 48 + id(new PhabricatorSlowvoteComment()) 49 + ->setAuthorPHID($user->getPHID()) 50 + ->setPollID($poll->getID()) 51 + ->setCommentText($comment_text) 52 + ->save(); 53 + } 54 + 55 + $old_votes = mpull($user_choices, null, 'getOptionID'); 56 + 57 + if ($request->isAjax()) { 58 + $vote = $request->getInt('vote'); 59 + $votes = array_keys($old_votes); 60 + $votes = array_fuse($votes, $votes); 61 + 62 + if ($poll->getMethod() == PhabricatorSlowvotePoll::METHOD_PLURALITY) { 63 + if (idx($votes, $vote, false)) { 64 + $votes = array(); 65 + } else { 66 + $votes = array($vote); 67 + } 68 + } else { 69 + if (idx($votes, $vote, false)) { 70 + unset($votes[$vote]); 71 + } else { 72 + $votes[$vote] = $vote; 73 + } 74 + } 75 + 76 + $this->updateVotes($user, $poll, $old_votes, $votes); 77 + 78 + $updated_choices = id(new PhabricatorSlowvoteChoice())->loadAllWhere( 79 + 'pollID = %d AND authorPHID = %s', 80 + $poll->getID(), 81 + $user->getPHID()); 82 + 83 + $embed = id(new SlowvoteEmbedView()) 84 + ->setPoll($poll) 85 + ->setOptions($options) 86 + ->setViewerChoices($updated_choices); 87 + 88 + return id(new AphrontAjaxResponse()) 89 + ->setContent(array( 90 + 'pollID' => $poll->getID(), 91 + 'contentHTML' => $embed->render())); 92 + } 93 + 94 + if (!$request->isFormPost()) { 95 + return id(new Aphront404Response()); 96 + } 97 + 98 + $votes = $request->getArr('vote'); 99 + $votes = array_fuse($votes, $votes); 100 + 101 + $this->updateVotes($user, $poll, $old_votes, $votes); 102 + 103 + return id(new AphrontRedirectResponse())->setURI('/V'.$poll->getID()); 104 + 105 + } 106 + 107 + private function updateVotes($user, $poll, $old_votes, $votes) { 108 + 109 + if (!empty($votes) && count($votes) > 1 && 110 + $poll->getMethod() == PhabricatorSlowvotePoll::METHOD_PLURALITY) { 111 + return id(new Aphront400Response()); 112 + } 113 + 114 + foreach ($old_votes as $old_vote) { 115 + if (!idx($votes, $old_vote->getOptionID(), false)) { 116 + $old_vote->delete(); 117 + } 118 + } 119 + 120 + foreach ($votes as $vote) { 121 + if (idx($old_votes, $vote, false)) { 122 + continue; 123 + } 124 + 125 + id(new PhabricatorSlowvoteChoice()) 126 + ->setAuthorPHID($user->getPHID()) 127 + ->setPollID($poll->getID()) 128 + ->setOptionID($vote) 129 + ->save(); 130 + } 131 + 132 + } 133 + 134 + 135 + }
+28 -5
src/applications/slowvote/view/SlowvoteEmbedView.php
··· 39 39 } 40 40 41 41 require_celerity_resource('phabricator-slowvote-css'); 42 + require_celerity_resource('javelin-behavior-slowvote-embed'); 43 + 44 + $config = array( 45 + 'pollID' => $this->poll->getID()); 46 + Javelin::initBehavior('slowvote-embed', $config); 42 47 43 48 $user_choices = array(); 44 49 if (!empty($this->viewerChoices)) { ··· 56 61 57 62 $selected = ''; 58 63 64 + 59 65 if (idx($user_choices, $option->getID(), false)) { 60 66 $classes .= ' phabricator-slowvote-embed-option-selected'; 61 67 $selected = '@'; 62 68 } 63 69 64 - $option_text = phutil_tag( 70 + $is_selected = javelin_tag( 71 + 'div', 72 + array( 73 + 'class' => 'phabricator-slowvote-embed-option-vote', 74 + 'sigil' => 'slowvote-embed-vote' 75 + ), 76 + $selected); 77 + 78 + $option_text = javelin_tag( 65 79 'div', 66 80 array( 67 - 'class' => $classes 81 + 'class' => $classes, 82 + 'sigil' => 'slowvote-option', 83 + 'meta' => array( 84 + 'optionID' => $option->getID() 85 + ) 68 86 ), 69 - $selected.$option->getName()); 87 + array($is_selected, $option->getName())); 70 88 71 89 $options[] = phutil_tag( 72 90 'div', ··· 95 113 array(), 96 114 $options); 97 115 98 - return phutil_tag( 116 + return javelin_tag( 99 117 'div', 100 118 array( 101 - 'class' => 'phabricator-slowvote-embed' 119 + 'class' => 'phabricator-slowvote-embed', 120 + 'sigil' => 'slowvote-embed', 121 + 'meta' => array( 122 + 'pollID' => $this->poll->getID() 123 + ) 102 124 ), 103 125 array($header, $body)); 104 126 } 127 + 105 128 }
+3 -3
webroot/rsrc/css/application/slowvote/slowvote.css
··· 80 80 background: #F0FFFF; 81 81 } 82 82 83 - .phabricator-slowvote-embed-option-selected { 84 - padding-left: 0px !important; 83 + .phabricator-slowvote-embed-option-vote { 84 + display: inline-block; 85 + width: 1em; 85 86 } 86 87 87 88 .phabricator-slowvote-embed-option-text { 88 89 border: 1px solid #dbdbdb; 89 90 border-left: 0px; 90 - padding-left: 1em; 91 91 }
+43
webroot/rsrc/js/application/slowvote/behavior-slowvote-embed.js
··· 1 + /** 2 + * @provides javelin-behavior-slowvote-embed 3 + * @requires javelin-behavior 4 + * javelin-util 5 + * javelin-stratcom 6 + * javelin-dom 7 + */ 8 + JX.behavior('slowvote-embed', function(config) { 9 + JX.Stratcom.listen( 10 + ['click'], 11 + 'slowvote-option', 12 + function(e) { 13 + if (!e.isNormalMouseEvent()) { 14 + return; 15 + } 16 + e.kill(); 17 + 18 + var pollID = e.getNodeData('slowvote-embed').pollID; 19 + var voteURI = '/vote/' + pollID + '/'; 20 + 21 + var request = new JX.Request(voteURI, function(r) { 22 + var updated_poll = JX.$H(r.contentHTML); 23 + var root = JX.$('base-page'); 24 + 25 + var polls = JX.DOM.scry(root, 'div', 'slowvote-embed'); 26 + 27 + for(var i = 0; i < polls.length; i++) { 28 + var data = JX.Stratcom.getData(polls[i]); 29 + 30 + if (data.pollID == pollID) { 31 + JX.DOM.replace(polls[i], updated_poll); 32 + } 33 + 34 + } 35 + 36 + }); 37 + 38 + request.addData({vote: e.getNodeData('slowvote-option').optionID}); 39 + request.send(); 40 + 41 + }); 42 + 43 + });