Skip to content
This repository has been archived by the owner on Apr 5, 2022. It is now read-only.

Commit

Permalink
Staticman nested comments support from Huginn (#69)
Browse files Browse the repository at this point in the history
* Staticman nested comments support from Huginn

which is in turn a port from halogenical/beautifulhugo#222.  Introduced true
nested comments with reply functionality.

1. Reply target anchors to easily jump between replies.
2. Interactive reply target display with Gravatar and name.
3. Improved input type for "website" field.
4. Implemented FR #63 to construct POST URL in JS.
5. Clearer instructions for Google reCAPTCHA v2.
6. Introduced some SCSS variables for layout control
7. Fixed missing "id" attribute in each comment.
8. Fixed missing translation UI text for Staticman forms.
9. Changed default API endpoint to the one serving @staticmanlab due to
eduardoboucas/staticman#307.

* Added image alt text in response to the review bot

Gravatar alt text wasn't there in the original code, but I agree with the bot.

* Fixed clearForm() to clear fields after submit

* Set opacity to 0.5 when submitted

* Regenerated resources

* Fixed clearForm() again to empt textarea

* Corrected Eng submission msg
  • Loading branch information
VincentTam committed Aug 22, 2019
1 parent 7db7cad commit 118943a
Show file tree
Hide file tree
Showing 18 changed files with 671 additions and 82 deletions.
105 changes: 105 additions & 0 deletions assets/js/staticman.js
@@ -0,0 +1,105 @@
// Static comments
// from: https://github.com/eduardoboucas/popcorn/blob/gh-pages/js/main.js
$(document).ready(function() {
$('.post-new-comment').submit(function () {
var form = this;

$(form).addClass('loading');
$('input[type="submit"]:enabled').addClass('hidden'); // hide "submit"
$('input[type="submit"]:disabled').removeClass('hidden'); // show "submitted"

// Construct form action URL form JS to avoid spam
var api = '{{ .api | default "staticman3.herokuapp.com" }}';
var gitProvider = '{{ .gitprovider }}';
var username = '{{ .username }}';
var repo = '{{ .repo }}';
var branch = '{{ .branch }}';

$.ajax({
type: $(this).attr('method'),
url: ['https:/', api, 'v3/entry', gitProvider, username, repo, branch, 'comments'].join('/'),
data: $(this).serialize(),
contentType: 'application/x-www-form-urlencoded',
success: function (data) {
showAlert('success');
setTimeout(function(){ clearForm() }, 3000); // display success message for 3s
$(form).removeClass('loading');
},
error: function (err) {
console.log(err);
showAlert('failed');
$(form).removeClass('loading');
}
});

return false;
});

function showAlert(msg) {
if (msg == 'success') {
$('.post-new-comment .submit-success').removeClass('hidden'); // show submit success message
$('.post-new-comment .submit-failed').addClass('hidden'); // hide submit failed message
} else {
$('.post-new-comment .submit-success').addClass('hidden'); // hide submit success message
$('.post-new-comment .submit-failed').removeClass('hidden'); // show submit failed message
}
$('input[type="submit"]:enabled').removeClass('hidden'); // show "submit"
$('input[type="submit"]:disabled').addClass('hidden'); // hide "submitted"
}

function clearForm() {
resetReplyTarget();
$('.post-new-comment input')
.filter(function() {
return this.name.match(/^fields\[.*\]$/);
})
.val(''); // empty all text & hidden fields but not options
$('.post-new-comment textarea').val(''); // empty text area
$('.post-new-comment .submit-success').addClass('hidden'); // hide submission status
$('.post-new-comment .submit-failed').addClass('hidden'); // hide submission status
}

function resetReplyTarget() {
$('.post-new-comment .post-reply-notice .post-reply-name').text('');
$('.post-new-comment .post-reply-notice .post-comment-avatar').remove();
$('.post-new-comment .post-reply-notice .post-reply-close-btn').remove();
$('.post-new-comment .post-reply-notice').addClass('hidden'); // hide reply target display
$('.post-new-comment input[type="hidden"]')
.filter(function() {
return this.name.match(/^fields\[reply[a-zA-Z]*\]$/);
})
.val(''); // empty all hidden fields whose name starts from "reply"
}

// record reply target when "reply to this comment" is pressed
$('.post-comment').on('click', '.post-comment-reply-btn', function (evt){
resetReplyTarget();
var cmt = $(evt.delegateTarget);
var replyThread = cmt.find('.post-comment-threadID').text();
$('.post-new-comment input[name="fields[replyThread]"]').val(replyThread);
$('.post-new-comment input[name="fields[replyID]"]').val(cmt.attr("id"));
authorTag = cmt.find('.post-comment-author');
replyName = authorTag.text();
$('.post-new-comment input[name="fields[replyName]"]').val(replyName);

// display reply target avatar and name
$('.post-new-comment .post-reply-notice').removeClass('hidden');
$('.post-new-comment .post-reply-name').text(replyName);
avatarTag = cmt.find('.post-comment-avatar');
// use clone to avoid removal of avatar in comments by resetReplyTarget()
$('.post-new-comment .post-reply-arrow').after(avatarTag.clone());
// add button for removing reply target (static method would give error msg)
closeBtn = $("<a class='post-reply-close-btn button'></a>");
$('.post-new-comment .post-reply-notice').append(closeBtn);
});

// handle removal of reply target when '×' is pressed
$('.post-new-comment .post-reply-notice').on('click', '.post-reply-close-btn', function(){
resetReplyTarget();
});

// clear form when reset button is clicked
$('.post-new-comment input[type="reset"]').click(function (){
clearForm();
});
});
170 changes: 143 additions & 27 deletions assets/scss/main.scss
Expand Up @@ -514,45 +514,161 @@ textarea {
}

/* Staticman Comments */
$avatar-size: 3.25em;
$avatar-rsep: 1em;
$comment-vsep: 2.5em;
$comment-content-vsep: 1.5em;

.post-comment {
position: relative;
margin-bottom: 3em;
padding-left: 4.5em;
margin: $comment-vsep 0;
font-size: .8em;
}

.post-comment-avatar {
float: left;
width: 3.25em;
height: 3.25em;
margin-right: .5em;
}
/* Comment replies' additional left margin */
&.post-comment-reply {
margin-left: 2em;
/* Display Font Awesome '↷' to signify reply target */
.post-comment-author::after {
font-family: 'Font Awesome 5 Free';
content: '\f064';
margin: 0 0.3em;
display: inline-block;
vertical-align: middle;
font-weight: 900;
}
}

.post-comment-author {
display: inline-block;
margin: 0 0 .25em;
font-size: 1.25em;
line-height: 1;
a {
color: inherit;
text-decoration: none;
.post-comment-avatar {
float: left;
width: $avatar-size;
height: $avatar-size;
margin: 0 $avatar-rsep 0 0;
}

.post-comment-author-container {
/* -ve margin botton so that timestamp and author aren't too far */
margin-bottom: -0.5em;
.post-comment-author {
display: inline-block;
margin: 0 0 0;
font-size: 1.25em;
line-height: 0;
a {
color: inherit;
text-decoration: none;
}
}
}

.post-comment-timestamp {
font-size: .8em;
a {
color: inherit;
text-decoration: none;
}
}

.post-comment-content {
margin: $comment-content-vsep 0 0 $avatar-size + $avatar-rsep;
> figure, > ol, > p,
> table, > ul {
margin-bottom: 1.5em;
}
}

.post-comment-reply-btn-container {
margin: $comment-content-vsep 0 $comment-content-vsep $avatar-size + $avatar-rsep;
/* Display Font Awesome '↶' to signify reply target */
.post-comment-reply-btn {
font-size: .6rem;
&::before {
font-family: 'Font Awesome 5 Free';
content: '\f3e5';
margin: 0 0.6em 0 0;
display: inline-block;
vertical-align: middle;
font-weight: 900;
}
}
}
}

.post-comment-timestamp {
font-size: .8em;
a {
color: inherit;
text-decoration: none;
/* Comment form */
.post-new-comment {
/* Disable the form when it has just been submitted */
&.loading {
opacity: 0.5;
}

/* Post reply notice with vertical align middle for consistent output */
.post-reply-notice {
.post-comment-avatar {
width: 2em;
height: 2em;
margin: 0 .6em;
}

/* Display close button 'x' to clear reset reply target */
.post-reply-close-btn {
margin: 0 .5em;
padding: unset;
border: none;
vertical-align: middle;
&:hover {
border: none;
}
&:after {
content: '\2716';
}
}

.post-reply-arrow::after {
font-family: 'Font Awesome 5 Free';
content: '\f064';
display: inline-block;
vertical-align: middle;
font-weight: 900;
}

.post-reply-name {
vertical-align: middle;
}
}

/* Format reCaptcha */
.g-recaptcha {
margin: 0 0 0.25em;
}

/* Buttons */
.button {
margin: 0.25em 0;
}
}

.post-comment-content {
margin: 1.5em 0 0 3.75em;
> figure, > ol, > p,
> table, > ul {
margin-bottom: 1.5em;
/* Copied from other blocks for reply and 'x' buttons */
.button {
margin: .25em 0;
background-color: transparent;
border: solid 1px rgba(160, 160, 160, 0.3);
color: #3c3b3b;
cursor: pointer;
display: inline-block;
font-family: "Raleway", Helvetica, sans-serif;
font-weight: 800;
-moz-transition: background-color 0.2s ease, border 0.2s ease, color 0.2s ease;
-webkit-transition: background-color 0.2s ease, border 0.2s ease, color 0.2s ease;
-ms-transition: background-color 0.2s ease, border 0.2s ease, color 0.2s ease;
transition: background-color 0.2s ease, border 0.2s ease, color 0.2s ease;
text-align: center;
text-transform: uppercase;
width: fit-content;
&:hover {
border: solid 1px $accent-color;
color: $accent-color !important;
}
&:active {
background-color: rgba(46, 186, 174, 0.05);
}
}

Expand Down
2 changes: 1 addition & 1 deletion exampleSite/config.toml
Expand Up @@ -93,7 +93,7 @@ disableLanguages = [""]
# If using GitHub, go to https://github.com/apps/staticman-net
# If using GitLab, just add the GitLab bot, NO need to hit `/connect/v3/...`
enabled = false
api = "" # without trailing slash, defaults to "api.staticman.net"
api = "" # without trailing slash, defaults to "staticman3.herokuapp.com"
gitProvider = "github" # either "github" or "gitlab"
username = ""
repo = ""
Expand Down

0 comments on commit 118943a

Please sign in to comment.