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('javelin-behavior-ponder-votebox');
Javelin::initBehavior(
'ponder-votebox',
Javelin::initBehavior('ponder-votebox', array());
$uri = id(new PhutilURI($this->uri))->alter('phid', $this->phid);
$up = javelin_render_tag(
'a',
array(
'nodeid' => $this->phid,
'vote' => $this->vote,
'count' => $this->count,
'uri' => $this->uri
));
'href' => (string)$uri,
'sigil' => 'upvote',
'mustcapture' => true,
'class' => ($this->vote > 0) ? 'ponder-vote-active' : null,
),
"\xE2\x96\xB2");
$content =
'<div class="ponder-votable">'.
'<div id="'.phutil_escape_html($this->phid).'" class="ponder-votebox">
</div>'.
$this->renderChildren().
'</div>';
$down = javelin_render_tag(
'a',
array(
'href' => (string)$uri,
'sigil' => 'downvote',
'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
*/
.ponder-votable .phabricator-transaction-view {
margin : 0;
padding : 0;
.ponder-votebox {
text-align: center;
}
.ponder-votable .phabricator-transaction-detail {
min-height : 90px;
.ponder-votebox a {
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 {
float : left;
width : 32px;
@ -21,57 +49,11 @@
margin-left : 10px;
}
.ponder-upbutton {
border : none;
padding : 0;
.ponder-votable .phabricator-transaction-view {
margin : 0;
width : 32px;
height : 13px;
}
.ponder-downbutton {
border : none;
padding : 0;
margin : 0;
width : 32px;
height : 13px;
}
.ponder-votecount {
width : 32px;
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;
.ponder-votable .phabricator-transaction-detail {
min-height : 90px;
}

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