diff options
| author | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2022-05-07 21:53:34 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2022-05-08 19:10:19 -0400 |
| commit | f6bd35e8e10faf4db80d6c8ccb45a5beae44c2be (patch) | |
| tree | 574bff4e3bb8fc98d2c38f1d91e2d938bc4a5caa /haunt | |
| parent | 96ad1a33e34ddcdd06cf31855e680a9b1b45c36a (diff) | |
[scheme] Initial comments API
Diffstat (limited to 'haunt')
| -rw-r--r-- | haunt/jakob/builder/blog.scm | 31 | ||||
| -rw-r--r-- | haunt/static/js/local.js | 110 |
2 files changed, 141 insertions, 0 deletions
diff --git a/haunt/jakob/builder/blog.scm b/haunt/jakob/builder/blog.scm index 8f02a80..2e54998 100644 --- a/haunt/jakob/builder/blog.scm +++ b/haunt/jakob/builder/blog.scm @@ -80,6 +80,37 @@ ".")) (article ,(post-sxml post)) (section + (@ (id "comments")) + (h2 "Comments for this Page") + (ul (@ (id "comment-container"))) + (form + (@ (action "https://jakob.space/api/comment") + (method "post")) + (label (@ (for "name")) "Name:") + (br) + (input (@ (name "name") (id "name") (type "text"))) + (br) + (label (@ (for "email")) "Email (optional; only used for Gravatar):") + (br) + (input (@ (name "email") (id "email") (type "text"))) + (br) + (label (@ (for "url")) "Homepage (optional):") + (br) + (input (@ (name "url") (id "url") (type "text"))) + (br) + (label (@ (for "comment")) "Comment (Markdown supported):") + (br) + (textarea (@ (name "comment") (id "comment") (rows "4") (cols "50") (maxlength "1024"))) + (br) + (label (@ (for "captcha")) "Captcha: Please integrate the following definite integral.") + (br) + (img (@ (id "captcha") (alt "captcha-image"))) + (br) + (input (@ (name "captcha") (id "captcha") (type "text"))) + (br) + (input (@ (value "Submit") (type "submit")))) + ,(script "local.js")) + (section (@ (id "webmention")) (h2 ,(hyperlink "https://indieweb.org/Webmention" "Webmentions") " for this Page") diff --git a/haunt/static/js/local.js b/haunt/static/js/local.js new file mode 100644 index 0000000..51e0ea1 --- /dev/null +++ b/haunt/static/js/local.js @@ -0,0 +1,110 @@ +/* + * local.js -- Fetch and display local comments. + * Copyright © 2022 Jakob L. Kreuze <zerodaysfordays@sdf.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ + +function getData(url, callback) { + let xhr = new XMLHttpRequest(); + xhr.onload = function(data) { + callback(data); + } + xhr.onerror = function(error) { + throw new Error(`Request failed: ${error}`); + } +} + +function makeComment(comment) { + const strip = (uri) => { + const sep = "://"; + return uri.substring(uri.indexOf(sep) + sep.length); + }; + + const element = (type, attributes) => { + let res = document.createElement(type); + for (const attribute in attributes) { + res.setAttribute(attribute, attributes[attribute]); + } + return res; + }; + + // Create the h-card section. + let avatar = element("img", { + "class": "u-photo", + "src": `https://www.gravatar.com/avatar/${comment.iconHash}?s=200` + }); + + let authorName = element("a", { + "class": "p-name u-url", + "href": comment.authorUrl + }); + authorName.textContent = comment.authorName; + + let authorURI = element("a", { + "class": "author_url", + "href": comment.author.url + }); + authorURI.textContent = strip(comment.author.url); + + let hCardContainer = element("div", { + "class": "p-author h-card author" + }); + hCardContainer.appendChild(avatar); + hCardContainer.appendChild(authorName); + hCardContainer.appendChild(authorURI); + + // Create the content section. + let contentContainer = element("div", { + "class": "e-content p-name comment-content", + }); + + contentContainer.textContent = comment.content; + + // Create the metaline section. + let pubTime = comment.published; + let time = element("time", { + "class": "dt-published", + "datetime": pubTime, + }); + time.textContent = (new Date(pubTime)).toString(); + + let linkBack = element("a", { + "class": "u-url", + "href": comment.url + }); + linkBack.appendChild(time); + + let metalineContainer = element("div", { + "class": "metaline" + }); + metalineContainer.appendChild(linkBack); + + // Put it all together. + let wrapper = element("li", { + "class": "p-comment h-cite comment", + }); + wrapper.appendChild(hCardContainer); + wrapper.appendChild(contentContainer); + wrapper.appendChild(metalineContainer); + + return wrapper; +} + +getData("http://localhost:8081/api/challenge", (b64data) => { + console.log("Here2"); + document.getElementById("captcha").src = 'data:image/png;base64,' + b64data; +}); +console.log("Here1"); |