mirror of
https://github.com/commercialhaskell/stackage-server.git
synced 2026-01-11 19:58:28 +01:00
Add tag voting (#35)
This commit is contained in:
parent
3fb5375230
commit
f36df17c01
@ -43,15 +43,27 @@ getPackageR pn = do
|
||||
|
||||
return (packages, downloads, recentDownloads, nLikes, liked, metadata)
|
||||
|
||||
tags <- fmap (map (\(E.Value v) -> v))
|
||||
(runDB (E.selectDistinct
|
||||
myTags <-
|
||||
case muid of
|
||||
Nothing -> return []
|
||||
Just uid ->
|
||||
fmap (map (\(E.Value v) -> v))
|
||||
(runDB (E.select
|
||||
(E.from (\t ->
|
||||
do E.where_ (t ^. TagPackage E.==. E.val pn E.&&.
|
||||
t ^. TagVoter E.==. E.val uid)
|
||||
E.orderBy [E.asc (t ^. TagTag)]
|
||||
return (t ^. TagTag)))))
|
||||
tags <- fmap (map (\(E.Value v,E.Value count) -> (v,count::Int,any (==v) myTags)))
|
||||
(runDB (E.select
|
||||
(E.from (\(t `E.LeftOuterJoin` bt) -> do
|
||||
E.on $ t E.^. TagTag E.==. bt E.^. BannedTagTag
|
||||
E.where_
|
||||
$ (t ^. TagPackage E.==. E.val pn) E.&&.
|
||||
(E.isNothing $ E.just $ bt E.^. BannedTagTag)
|
||||
E.groupBy (t ^. TagTag)
|
||||
E.orderBy [E.asc (t ^. TagTag)]
|
||||
return (t ^. TagTag)))))
|
||||
return (t ^. TagTag,E.count (t ^. TagTag))))))
|
||||
|
||||
let likeTitle = if liked
|
||||
then "You liked this!"
|
||||
@ -191,3 +203,20 @@ postPackageTagR packageName =
|
||||
do slug <- mkSlugLen 1 20 tag
|
||||
void (runDB (P.insert (Tag packageName slug uid)))
|
||||
Nothing -> error "Need a slug"
|
||||
|
||||
postPackageUntagR :: PackageName -> Handler ()
|
||||
postPackageUntagR packageName =
|
||||
maybeAuthId >>=
|
||||
\muid ->
|
||||
case muid of
|
||||
Nothing -> return ()
|
||||
Just uid ->
|
||||
do mtag <- lookupPostParam "slug"
|
||||
case mtag of
|
||||
Just tag ->
|
||||
do slug <- mkSlugLen 1 20 tag
|
||||
void (runDB (P.deleteWhere
|
||||
[TagPackage ==. packageName
|
||||
,TagTag ==. slug
|
||||
,TagVoter ==. uid]))
|
||||
Nothing -> error "Need a slug"
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
/package/#PackageName/like PackageLikeR POST
|
||||
/package/#PackageName/unlike PackageUnlikeR POST
|
||||
/package/#PackageName/tag PackageTagR POST
|
||||
/package/#PackageName/untag PackageUntagR POST
|
||||
/tags TagListR GET
|
||||
/tag/#Slug TagR GET
|
||||
/banned-tags BannedTagsR GET PUT
|
||||
|
||||
@ -21,10 +21,12 @@ $newline never
|
||||
$if null tags
|
||||
<span .no-tags>
|
||||
No tags yet. #
|
||||
$forall tag <- tags
|
||||
$forall (tag,count,tagged) <- tags
|
||||
<span .tag>
|
||||
<a href=@{TagR tag}>
|
||||
#{tag}
|
||||
<a href=@{TagR tag} .tag-name>
|
||||
#{tag} #
|
||||
<a .tag-count .tag-toggle data-slug=#{tag} :tagged:.tagged title="Add/remove vote for: #{tag}">
|
||||
#{count}
|
||||
, #
|
||||
<i #add-tag class="fa fa-plus-square" title="Show/hide tag form">
|
||||
<form #add-tag-form .hidden>
|
||||
|
||||
@ -1,8 +1,35 @@
|
||||
$(function(){
|
||||
var loggedIn = $('.user-handle').length > 0;
|
||||
var tags = Object.create(null);
|
||||
|
||||
function toggleClick(){
|
||||
if (!loggedIn) {
|
||||
login();
|
||||
return false;
|
||||
}
|
||||
|
||||
var $this = $(this);
|
||||
var normalized = $this.data('slug');
|
||||
var upvote = !$this.hasClass('tagged');
|
||||
$this.text($this.text() * 1 + (upvote? 1 : -1));
|
||||
$this.toggleClass('tagged');
|
||||
if (upvote)
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '@{PackageTagR pn}',
|
||||
data: {slug:normalized}
|
||||
});
|
||||
else
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '@{PackageUntagR pn}',
|
||||
data: {slug:normalized}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$('.tags').find('.tag').each(function(){
|
||||
tags[$(this).find('a').text()] = true;
|
||||
tags[$(this).find('.tag-name').text()] = true;
|
||||
});
|
||||
$('.expanding').each(function(){
|
||||
var $this = $(this);
|
||||
@ -41,6 +68,7 @@ $(function(){
|
||||
login();
|
||||
}
|
||||
});
|
||||
$('.tag-toggle').click(toggleClick);
|
||||
$('#add-tag').click(function(){
|
||||
if (!loggedIn) login();
|
||||
$('#add-tag-form').toggleClass('hidden');
|
||||
@ -79,15 +107,23 @@ $(function(){
|
||||
|
||||
if (!tags[normalized]) {
|
||||
var tag = $('<span><a></a></span>');
|
||||
tag.find('a').text(normalized).attr('href','/tag/' + normalized);
|
||||
tag.find('a').text(normalized + ' ').attr('href','/tag/' + normalized);
|
||||
$('.tags').prepend(', ');
|
||||
var count = $('<a>1</a>')
|
||||
.addClass('tag-count')
|
||||
.addClass('tag-toggle')
|
||||
.addClass('tagged')
|
||||
.data('slug',normalized)
|
||||
.attr('title','Add/remove vote for: ' + normalized)
|
||||
.click(toggleClick);
|
||||
$('.tags').prepend(count);
|
||||
$('.tags').prepend(tag);
|
||||
}
|
||||
|
||||
tags[normalized] = true;
|
||||
},
|
||||
error: function(err){
|
||||
$('#tag-msg').text('invalid slug; too short or too long').show();
|
||||
$('#tag-msg').text("Couldn't add that tag").show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -192,3 +192,22 @@ h2.changes-title {
|
||||
.no-tags {
|
||||
color: #888;
|
||||
}
|
||||
.tag-count {
|
||||
border: 0.1em solid #d8d8d8;
|
||||
text-shadow: none;
|
||||
padding: 0 0.25em;
|
||||
border-radius: 0.25em;
|
||||
color: #999;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.tag-count:hover {
|
||||
border: 0.1em solid #333;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.tag-count.tagged {
|
||||
background: #06537d;
|
||||
border: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user