frontend,api: open source comment sticky
This commit is contained in:
parent
cf0b394b05
commit
610b61831d
@ -7,4 +7,5 @@ type page struct {
|
||||
Path string `json:"path"`
|
||||
IsLocked bool `json:"isLocked"`
|
||||
CommentCount int `json:"commentCount"`
|
||||
StickyCommentHex string `json:"stickyCommentHex"`
|
||||
}
|
||||
|
@ -11,20 +11,21 @@ func pageGet(domain string, path string) (page, error) {
|
||||
}
|
||||
|
||||
statement := `
|
||||
SELECT isLocked, commentCount
|
||||
SELECT isLocked, commentCount, stickyCommentHex
|
||||
FROM pages
|
||||
WHERE domain=$1 AND path=$2;
|
||||
`
|
||||
row := db.QueryRow(statement, domain, path)
|
||||
|
||||
p := page{Domain: domain, Path: path}
|
||||
if err := row.Scan(&p.IsLocked, &p.CommentCount); err != nil {
|
||||
if err := row.Scan(&p.IsLocked, &p.CommentCount, &p.StickyCommentHex); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
// If there haven't been any comments, there won't be a record for this
|
||||
// page. The sane thing to do is return defaults.
|
||||
// TODO: the defaults are hard-coded in two places: here and the schema
|
||||
p.IsLocked = false
|
||||
p.CommentCount = 0
|
||||
p.StickyCommentHex = "none"
|
||||
} else {
|
||||
logger.Errorf("error scanning page: %v", err)
|
||||
return page{}, errorInternal
|
||||
|
@ -13,12 +13,12 @@ func pageUpdate(p page) error {
|
||||
// commentCount
|
||||
statement := `
|
||||
INSERT INTO
|
||||
pages (domain, path, isLocked)
|
||||
VALUES ($1, $2, $3 )
|
||||
pages (domain, path, isLocked, stickyCommentHex)
|
||||
VALUES ($1, $2, $3, $4 )
|
||||
ON CONFLICT (domain, path) DO
|
||||
UPDATE SET isLocked = $3;
|
||||
UPDATE SET isLocked = $3, stickyCommentHex = $4;
|
||||
`
|
||||
_, err := db.Exec(statement, p.Domain, p.Path, p.IsLocked)
|
||||
_, err := db.Exec(statement, p.Domain, p.Path, p.IsLocked, p.StickyCommentHex)
|
||||
if err != nil {
|
||||
logger.Errorf("error setting page attributes: %v", err)
|
||||
return errorInternal
|
||||
|
2
db/20181218183803-sticky-comments.sql
Normal file
2
db/20181218183803-sticky-comments.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE pages
|
||||
ADD stickyCommentHex TEXT NOT NULL DEFAULT 'none';
|
@ -47,6 +47,7 @@
|
||||
var ID_DOWNVOTE = "commento-comment-downvote-";
|
||||
var ID_APPROVE = "commento-comment-approve-";
|
||||
var ID_REMOVE = "commento-comment-remove-";
|
||||
var ID_STICKY = "commento-comment-sticky-";
|
||||
var ID_CONTENTS = "commento-comment-contents-";
|
||||
var ID_SUBMIT_BUTTON = "commento-submit-button-";
|
||||
var ID_FOOTER = "commento-footer";
|
||||
@ -67,6 +68,7 @@
|
||||
var shownSubmitButton = {"root": false};
|
||||
var chosenAnonymous = false;
|
||||
var isLocked = false;
|
||||
var stickyCommentHex = "none";
|
||||
var shownReply = {};
|
||||
var configuredOauths = [];
|
||||
var loginBoxType = "signup";
|
||||
@ -341,6 +343,7 @@
|
||||
isFrozen = resp.isFrozen;
|
||||
|
||||
isLocked = resp.attributes.isLocked;
|
||||
stickyCommentHex = resp.attributes.stickyCommentHex;
|
||||
|
||||
comments = resp.comments;
|
||||
commenters = resp.commenters;
|
||||
@ -449,10 +452,14 @@
|
||||
|
||||
commentsArea.innerHTML = "";
|
||||
|
||||
if (!isLocked)
|
||||
append(mainArea, textareaCreate("root"));
|
||||
if (isLocked) {
|
||||
if (isAuthenticated)
|
||||
append(mainArea, messageCreate("This thread is locked. You cannot add new comments."));
|
||||
else
|
||||
append(mainArea, textareaCreate("root"));
|
||||
}
|
||||
else
|
||||
append(mainArea, messageCreate("This thread is locked. You cannot create new comments."));
|
||||
append(mainArea, textareaCreate("root"));
|
||||
|
||||
append(mainArea, commentsArea);
|
||||
append(root, mainArea);
|
||||
@ -588,6 +595,10 @@
|
||||
}
|
||||
|
||||
cur.sort(function(a, b) {
|
||||
if (a.commentHex == stickyCommentHex)
|
||||
return -Infinity;
|
||||
if (b.commentHex == stickyCommentHex)
|
||||
return Infinity;
|
||||
return b.score - a.score;
|
||||
});
|
||||
|
||||
@ -608,6 +619,7 @@
|
||||
var downvote = create("button");
|
||||
var approve = create("button");
|
||||
var remove = create("button");
|
||||
var sticky = create("button");
|
||||
var children = commentsRecurse(parentMap, comment.commentHex);
|
||||
var contents = create("div");
|
||||
var color = colorGet(commenter.name);
|
||||
@ -629,6 +641,7 @@
|
||||
downvote.id = ID_DOWNVOTE + comment.commentHex;
|
||||
approve.id = ID_APPROVE + comment.commentHex;
|
||||
remove.id = ID_REMOVE + comment.commentHex;
|
||||
sticky.id = ID_STICKY + comment.commentHex;
|
||||
contents.id = ID_CONTENTS + comment.commentHex;
|
||||
|
||||
collapse.title = "Collapse";
|
||||
@ -638,6 +651,14 @@
|
||||
reply.title = "Reply";
|
||||
approve.title = "Approve";
|
||||
remove.title = "Remove";
|
||||
if (stickyCommentHex == comment.commentHex) {
|
||||
if (isModerator)
|
||||
sticky.title = "Unsticky";
|
||||
else
|
||||
sticky.title = "This comment has been stickied";
|
||||
}
|
||||
else
|
||||
sticky.title = "Sticky";
|
||||
|
||||
card.style["borderLeft"] = "2px solid " + color;
|
||||
name.innerText = commenter.name;
|
||||
@ -684,6 +705,11 @@
|
||||
classAdd(approve, "option-approve");
|
||||
classAdd(remove, "option-button");
|
||||
classAdd(remove, "option-remove");
|
||||
classAdd(sticky, "option-button");
|
||||
if (stickyCommentHex == comment.commentHex)
|
||||
classAdd(sticky, "option-unsticky");
|
||||
else
|
||||
classAdd(sticky, "option-sticky");
|
||||
|
||||
if (isAuthenticated) {
|
||||
if (comment.direction > 0)
|
||||
@ -696,6 +722,7 @@
|
||||
attrSet(collapse, "onclick", "commentCollapse('" + comment.commentHex + "')");
|
||||
attrSet(approve, "onclick", "commentApprove('" + comment.commentHex + "')");
|
||||
attrSet(remove, "onclick", "commentDelete('" + comment.commentHex + "')");
|
||||
attrSet(sticky, "onclick", "commentSticky('" + comment.commentHex + "')");
|
||||
|
||||
if (isAuthenticated) {
|
||||
if (comment.direction > 0) {
|
||||
@ -730,14 +757,19 @@
|
||||
append(options, downvote);
|
||||
append(options, upvote);
|
||||
|
||||
if (!isLocked)
|
||||
append(options, reply);
|
||||
append(options, reply);
|
||||
|
||||
if (isModerator) {
|
||||
if (parentHex == "root")
|
||||
append(options, sticky);
|
||||
append(options, remove);
|
||||
if (comment.state == "unapproved")
|
||||
append(options, approve);
|
||||
}
|
||||
else {
|
||||
if (stickyCommentHex == comment.commentHex)
|
||||
append(options, sticky);
|
||||
}
|
||||
|
||||
attrSet(options, "style", "width: " + ((options.childNodes.length+1)*32) + "px;");
|
||||
for (var i = 0; i < options.childNodes.length; i++)
|
||||
@ -1278,6 +1310,7 @@
|
||||
function pageUpdate(callback) {
|
||||
var attributes = {
|
||||
"isLocked": isLocked,
|
||||
"stickyCommentHex": stickyCommentHex,
|
||||
};
|
||||
|
||||
var json = {
|
||||
@ -1314,6 +1347,32 @@
|
||||
}
|
||||
|
||||
|
||||
global.commentSticky = function(commentHex) {
|
||||
if (stickyCommentHex != "none") {
|
||||
var sticky = $(ID_STICKY + stickyCommentHex);
|
||||
classRemove(sticky, "option-unsticky");
|
||||
classAdd(sticky, "option-sticky");
|
||||
}
|
||||
|
||||
if (stickyCommentHex == commentHex)
|
||||
stickyCommentHex = "none";
|
||||
else
|
||||
stickyCommentHex = commentHex;
|
||||
|
||||
pageUpdate(function(success) {
|
||||
var sticky = $(ID_STICKY + commentHex);
|
||||
if (stickyCommentHex == commentHex) {
|
||||
classRemove(sticky, "option-sticky");
|
||||
classAdd(sticky, "option-unsticky");
|
||||
}
|
||||
else {
|
||||
classRemove(sticky, "option-unsticky");
|
||||
classAdd(sticky, "option-sticky");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function mainAreaCreate() {
|
||||
var mainArea = create("div");
|
||||
|
||||
|
@ -83,6 +83,20 @@
|
||||
background: $green-7;
|
||||
}
|
||||
|
||||
.commento-option-sticky,
|
||||
.commento-option-unsticky {
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
@include mask-image('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8"?><svg enable-background="new 0 0 487.222 487.222" version="1.1" viewBox="0 0 487.22 487.22" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m486.55 186.81c-1.6-4.9-5.8-8.4-10.9-9.2l-152-21.6-68.4-137.5c-2.3-4.6-7-7.5-12.1-7.5s-9.8 2.9-12.1 7.6l-67.5 137.9-152 22.6c-5.1 0.8-9.3 4.3-10.9 9.2s-0.2 10.3 3.5 13.8l110.3 106.9-25.5 151.4c-0.9 5.1 1.2 10.2 5.4 13.2 2.3 1.7 5.1 2.6 7.9 2.6 2.2 0 4.3-0.5 6.3-1.6l135.7-71.9 136.1 71.1c2 1 4.1 1.5 6.2 1.5 7.4 0 13.5-6.1 13.5-13.5 0-1.1-0.1-2.1-0.4-3.1l-26.3-150.5 109.6-107.5c3.9-3.6 5.2-9 3.6-13.9zm-137 107.1c-3.2 3.1-4.6 7.6-3.8 12l22.9 131.3-118.2-61.7c-3.9-2.1-8.6-2-12.6 0l-117.8 62.4 22.1-131.5c0.7-4.4-0.7-8.8-3.9-11.9l-95.6-92.8 131.9-19.6c4.4-0.7 8.2-3.4 10.1-7.4l58.6-119.7 59.4 119.4c2 4 5.8 6.7 10.2 7.4l132 18.8-95.3 93.3z" fill="%231e2127"/></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
background: $gray-5;
|
||||
}
|
||||
|
||||
.commento-option-unsticky {
|
||||
@include mask-image('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8"?><svg viewBox="0 0 487.22 487.22" xmlns="http://www.w3.org/2000/svg"><g><title>background</title><rect x="-1" y="-1" fill="none"/></g><g><title>Layer 1</title><path d="m486.55 186.81c-1.6-4.9-5.8-8.4-10.9-9.2l-152-21.6-68.4-137.5c-2.3-4.6-7-7.5-12.1-7.5s-9.8 2.9-12.1 7.6l-67.5 137.9-152 22.6c-5.1 0.8-9.3 4.3-10.9 9.2s-0.2 10.3 3.5 13.8l110.3 106.9-25.5 151.4c-0.9 5.1 1.2 10.2 5.4 13.2 2.3 1.7 5.1 2.6 7.9 2.6 2.2 0 4.3-0.5 6.3-1.6l135.7-71.9 136.1 71.1c2 1 4.1 1.5 6.2 1.5 7.4 0 13.5-6.1 13.5-13.5 0-1.1-0.1-2.1-0.4-3.1l-26.3-150.5 109.6-107.5c3.9-3.6 5.2-9 3.6-13.9z" fill="%231e2127"/></g></svg>');
|
||||
background: $yellow-7;
|
||||
}
|
||||
|
||||
.commento-option-button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user