1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

Simplify upvote/downvote implementation

Summary:
Use sigils to simplify the vote implementation and move most rendering to the server.

Use unicode glyphs in place of graphics.

Test Plan: {F19539}

Reviewers: pieter, starruler

Reviewed By: pieter

CC: aran

Maniphest Tasks: T1644

Differential Revision: https://secure.phabricator.com/D3518
This commit is contained in:
epriestley 2012-09-30 20:12:35 -07:00
parent e48fa0398b
commit 054ea7dc4a
5 changed files with 127 additions and 129 deletions

View file

@ -47,23 +47,60 @@ final class PonderVotableView extends AphrontView {
require_celerity_resource('ponder-vote-css'); require_celerity_resource('ponder-vote-css');
require_celerity_resource('javelin-behavior-ponder-votebox'); require_celerity_resource('javelin-behavior-ponder-votebox');
Javelin::initBehavior( Javelin::initBehavior('ponder-votebox', array());
'ponder-votebox',
$uri = id(new PhutilURI($this->uri))->alter('phid', $this->phid);
$up = javelin_render_tag(
'a',
array( array(
'nodeid' => $this->phid, 'href' => (string)$uri,
'vote' => $this->vote, 'sigil' => 'upvote',
'count' => $this->count, 'mustcapture' => true,
'uri' => $this->uri 'class' => ($this->vote > 0) ? 'ponder-vote-active' : null,
)); ),
"\xE2\x96\xB2");
$content = $down = javelin_render_tag(
'<div class="ponder-votable">'. 'a',
'<div id="'.phutil_escape_html($this->phid).'" class="ponder-votebox"> array(
</div>'. 'href' => (string)$uri,
$this->renderChildren(). 'sigil' => 'downvote',
'</div>'; 'mustcapture' => true,
'class' => ($this->vote < 0) ? 'ponder-vote-active' : null,
),
"\xE2\x96\xBC");
return $content; $count = javelin_render_tag(
'div',
array(
'class' => 'ponder-vote-count',
'sigil' => 'ponder-vote-count',
),
phutil_escape_html($this->count));
return javelin_render_tag(
'div',
array(
'class' => 'ponder-votable',
'sigil' => 'ponder-votable',
'meta' => array(
'count' => (int)$this->count,
'vote' => (int)$this->vote,
),
),
javelin_render_tag(
'div',
array(
'class' => 'ponder-votebox',
),
$up.$count.$down).
phutil_render_tag(
'div',
array(
'class' => 'ponder-votebox-content',
),
$this->renderChildren()));
} }
} }

View file

@ -2,17 +2,45 @@
* @provides ponder-vote-css * @provides ponder-vote-css
*/ */
.ponder-votebox {
text-align: center;
.ponder-votable .phabricator-transaction-view {
margin : 0;
padding : 0;
} }
.ponder-votable .phabricator-transaction-detail { .ponder-votebox a {
min-height : 90px; font-size: 20px;
line-height: 20px;
display: block;
text-decoration: none;
color: #999999;
font-weight: normal;
/* Our default fonts have weirdly different up/down arrow sizes. */
font-family: Arial;
} }
.ponder-votebox a:hover {
color: #606060;
}
.ponder-votebox a.ponder-vote-active {
color: #3b5998;
}
.ponder-votebox a.ponder-vote-active:hover {
color: #a1bbe5;
}
.ponder-vote-count {
color: #888888;
font-size: 14px;
line-height: 14px;
font-weight: bold;
}
.ponder-votebox { .ponder-votebox {
float : left; float : left;
width : 32px; width : 32px;
@ -21,57 +49,11 @@
margin-left : 10px; margin-left : 10px;
} }
.ponder-upbutton { .ponder-votable .phabricator-transaction-view {
border : none;
padding : 0;
margin : 0; margin : 0;
width : 32px;
height : 13px;
}
.ponder-downbutton {
border : none;
padding : 0; padding : 0;
margin : 0;
width : 32px;
height : 13px;
} }
.ponder-votecount { .ponder-votable .phabricator-transaction-detail {
width : 32px; min-height : 90px;
height : 22pt;
padding : 0;
margin : 0;
overflow : visible;
text-align : center;
font-size : 15pt;
}
.ponder-upbutton:hover {
cursor : pointer;
}
.ponder-downbutton:hover {
cursor : pointer;
}
.ponder-votable-bottom {
clear : both;
}
.ponder-upbutton {
background : url(/rsrc/image/application/ponder/upvote.png) 0 -13px no-repeat;
}
.ponder-upbutton.ponder-vote-up {
background : url(/rsrc/image/application/ponder/upvote.png) 0 0 no-repeat;
}
.ponder-downbutton {
background : url(/rsrc/image/application/ponder/downvote.png)
0 -13px no-repeat;
}
.ponder-downbutton.ponder-vote-down {
background : url(/rsrc/image/application/ponder/downvote.png) 0 0 no-repeat;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

View file

@ -3,74 +3,53 @@
* @requires javelin-behavior * @requires javelin-behavior
* javelin-dom * javelin-dom
* javelin-util * javelin-util
* phabricator-shaped-request * javelin-stratcom
* javelin-request
*/ */
JX.behavior('ponder-votebox', function(config) { JX.behavior('ponder-votebox', function(config) {
var node = JX.$(config.nodeid); function handle_vote(e, vote) {
var vote = config.vote; e.kill();
var count = config.count | 0;
var targetURI = config.targetURI;
var upnode, countnode, downnode; var root = e.getNode('ponder-votable');
var data = e.getNodeData('ponder-votable');
// this defines the behavior of the up/downvote if (data.vote != vote) {
// buttons, e.g. clicking 'up' transitions from data.vote = vote;
// an 'up' vote to a 'none' vote data.count += vote;
var votecycle = { } else {
"1" : { up : "0", down : "-1" }, // User is undoing their vote.
"0" : { up : "1", down : "-1" }, data.vote = 0;
"-1" : { up : "1", down : "0" } data.count -= vote;
}; }
var voteclass = { var upv = JX.DOM.find(root, 'a', 'upvote');
"0" : "ponder-vote-none", JX.DOM.alterClass(upv, 'ponder-vote-active', (data.vote > 0));
"-1" : "ponder-vote-down",
"1" : "ponder-vote-up"
};
function decorate() { var downv = JX.DOM.find(root, 'a', 'downvote');
upnode = JX.$N('div'); JX.DOM.alterClass(downv, 'ponder-vote-active', (data.vote < 0))
countnode = JX.$N('div');
downnode = JX.$N('div'); JX.DOM.setContent(
node.appendChild(upnode); JX.DOM.find(root, 'div', 'ponder-vote-count'),
node.appendChild(countnode); data.count);
node.appendChild(downnode);
JX.DOM.alterClass(upnode, "ponder-upbutton " + voteclass[vote], true); new JX.Request(e.getTarget().href, JX.bag)
JX.DOM.alterClass(downnode, "ponder-downbutton " + voteclass[vote], true); .setData({vote: data.vote})
JX.DOM.alterClass(countnode, "ponder-votecount", true); .send()
} }
function update_state() { JX.Stratcom.listen(
upnode.className = "ponder-upbutton " + voteclass[vote]; 'click',
downnode.className = "ponder-downbutton " + voteclass[vote]; 'downvote',
JX.DOM.setContent(countnode, JX.$H(count.toString())); function(e) {
} handle_vote(e, -1);
});
function getdata() { JX.Stratcom.listen(
return { phid : config.nodeid, vote : vote }; 'click',
} 'upvote',
function(e) {
var request = new JX.PhabricatorShapedRequest(config.uri, JX.id, getdata); handle_vote(e, 1);
var trigger = JX.bind(request, request.trigger); });
function handle_upvote(e) {
count += votecycle[vote].up - vote;
vote = votecycle[vote].up;
trigger();
update_state();
}
function handle_downvote(e) {
count += votecycle[vote].down - vote;
vote = votecycle[vote].down;
trigger();
update_state();
}
decorate();
update_state();
JX.DOM.listen(upnode, 'click', null, handle_upvote);
JX.DOM.listen(downnode, 'click', null, handle_downvote);
}); });