mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-23 07:12:41 +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:
parent
e48fa0398b
commit
054ea7dc4a
5 changed files with 127 additions and 129 deletions
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 |
|
@ -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 = {
|
|
||||||
"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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_state() {
|
var upv = JX.DOM.find(root, 'a', 'upvote');
|
||||||
upnode.className = "ponder-upbutton " + voteclass[vote];
|
JX.DOM.alterClass(upv, 'ponder-vote-active', (data.vote > 0));
|
||||||
downnode.className = "ponder-downbutton " + voteclass[vote];
|
|
||||||
JX.DOM.setContent(countnode, JX.$H(count.toString()));
|
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() {
|
JX.Stratcom.listen(
|
||||||
return { phid : config.nodeid, vote : vote };
|
'click',
|
||||||
}
|
'downvote',
|
||||||
|
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) {
|
JX.Stratcom.listen(
|
||||||
count += votecycle[vote].up - vote;
|
'click',
|
||||||
vote = votecycle[vote].up;
|
'upvote',
|
||||||
trigger();
|
function(e) {
|
||||||
update_state();
|
handle_vote(e, 1);
|
||||||
}
|
});
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue