frontend: add commento embed js and scss
This commit is contained in:
parent
8f2d7e58a5
commit
a6c6598c4a
@ -1,7 +1,7 @@
|
||||
SHELL = bash
|
||||
|
||||
# list of JS files to be built
|
||||
JS_BUILD = jquery.js vue.js highlight.js chartist.js login.js signup.js dashboard.js logout.js
|
||||
JS_BUILD = jquery.js vue.js highlight.js chartist.js login.js signup.js dashboard.js logout.js commento.js
|
||||
|
||||
jquery.js = jquery.js
|
||||
vue.js = vue.js
|
||||
@ -11,6 +11,7 @@ login.js = utils.js http.js auth-common.js login.js
|
||||
signup.js = utils.js http.js auth-common.js signup.js
|
||||
dashboard.js = utils.js http.js errors.js self.js dashboard.js dashboard-setting.js dashboard-domain.js dashboard-installation.js dashboard-general.js dashboard-moderation.js dashboard-statistics.js dashboard-import.js dashboard-danger.js
|
||||
logout.js = utils.js logout.js
|
||||
commento.js = commento.js
|
||||
|
||||
# for each file in $(JS_BUILD), list its composition
|
||||
|
||||
|
975
frontend/js/commento.js
Normal file
975
frontend/js/commento.js
Normal file
@ -0,0 +1,975 @@
|
||||
(function(global, document) {
|
||||
'use strict';
|
||||
|
||||
// Do not use other files like utils.js and http.js in the Makefile to build
|
||||
// commento.js for the following reasons:
|
||||
// - We don't use jQuery in the actual JavaScript payload because we need
|
||||
// to be lightweight.
|
||||
// - They pollute the global/window namespace (with global.post, etc.).
|
||||
// That's NOT fine when we expect them source our JavaScript. For example,
|
||||
// the user may have their own window.post defined. We don't want to
|
||||
// override that.
|
||||
|
||||
|
||||
var origin = global.commento_origin;
|
||||
var cdn = global.commento_cdn;
|
||||
var root = null;
|
||||
var isAuthenticated = false;
|
||||
var comments = [];
|
||||
var commenters = [];
|
||||
var requireIdentification = true;
|
||||
var requireModeration = true;
|
||||
var isModerator = false;
|
||||
var isFrozen = false;
|
||||
var chosenAnonymous = false;
|
||||
var shownSubmitButton = {"root": false};
|
||||
var shownReply = {};
|
||||
|
||||
|
||||
function $(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
|
||||
function dataGet(el, key) {
|
||||
return el.dataset[key];
|
||||
}
|
||||
|
||||
|
||||
function dataSet(el, key, data) {
|
||||
el.dataset[key] = data;
|
||||
}
|
||||
|
||||
|
||||
function append(root, el) {
|
||||
root.appendChild(el);
|
||||
}
|
||||
|
||||
|
||||
function prepend(root, el) {
|
||||
root.prepend(el);
|
||||
}
|
||||
|
||||
|
||||
function classAdd(el, cls) {
|
||||
el.classList.add("commento-" + cls);
|
||||
}
|
||||
|
||||
|
||||
function classRemove(el, cls) {
|
||||
el.classList.remove("commento-" + cls);
|
||||
}
|
||||
|
||||
|
||||
function create(el) {
|
||||
return document.createElement(el);
|
||||
}
|
||||
|
||||
|
||||
function remove(el) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
|
||||
|
||||
function attr(node, a, value) {
|
||||
node.setAttribute(a, value);
|
||||
}
|
||||
|
||||
|
||||
function post(url, data, callback) {
|
||||
var xmlDoc = new XMLHttpRequest();
|
||||
|
||||
xmlDoc.open("POST", url, true);
|
||||
xmlDoc.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xmlDoc.onload = function() {
|
||||
callback(JSON.parse(xmlDoc.response));
|
||||
};
|
||||
|
||||
xmlDoc.send(JSON.stringify(data));
|
||||
}
|
||||
|
||||
|
||||
function get(url, callback) {
|
||||
var xmlDoc = new XMLHttpRequest();
|
||||
|
||||
xmlDoc.open('GET', url, true);
|
||||
xmlDoc.onload = function() {
|
||||
callback(JSON.parse(xmlDoc.response));
|
||||
};
|
||||
|
||||
xmlDoc.send(null);
|
||||
}
|
||||
|
||||
|
||||
function call(callback) {
|
||||
if (typeof(callback) == "function")
|
||||
callback();
|
||||
}
|
||||
|
||||
|
||||
function rootSpinnerShow() {
|
||||
var spinner = create("div");
|
||||
|
||||
classAdd(spinner, "loading");
|
||||
|
||||
append(root, spinner);
|
||||
}
|
||||
|
||||
|
||||
function cookieGet(name) {
|
||||
var c = "; " + document.cookie;
|
||||
var x = c.split("; " + name + "=");
|
||||
if (x.length == 2)
|
||||
return x.pop().split(";").shift();
|
||||
}
|
||||
|
||||
|
||||
function cookieSet(name, value) {
|
||||
var expires = "";
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (365*24*60*60*1000));
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
|
||||
document.cookie = name + "=" + value + expires + "; path=/";
|
||||
}
|
||||
|
||||
function sessionGet() {
|
||||
var session = cookieGet("session");
|
||||
if (session === undefined)
|
||||
return "anonymous";
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
global.logout = function() {
|
||||
cookieSet("session", "anonymous");
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
function selfGet(callback) {
|
||||
var session = sessionGet();
|
||||
if (session == "anonymous") {
|
||||
isAuthenticated = false;
|
||||
call(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
var json = {
|
||||
session: sessionGet(),
|
||||
};
|
||||
|
||||
post(origin + "/api/commenter/self", json, function(resp) {
|
||||
console.log(resp);
|
||||
if (!resp.success) {
|
||||
cookieSet("session", "anonymous");
|
||||
call(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
var loggedContainer = create("div");
|
||||
var loggedInAs = create("div");
|
||||
var name = create("a");
|
||||
var photo = create("img");
|
||||
var logout = create("div");
|
||||
|
||||
classAdd(loggedContainer, "logged-container");
|
||||
classAdd(loggedInAs, "logged-in-as");
|
||||
classAdd(name, "name");
|
||||
classAdd(photo, "photo");
|
||||
classAdd(logout, "logout");
|
||||
|
||||
name.innerText = resp.commenter.name;
|
||||
logout.innerText = "Logout";
|
||||
|
||||
attr(name, "href", resp.commenter.link);
|
||||
if (resp.commenter.provider == "google") {
|
||||
attr(photo, "src", resp.commenter.photo + "?sz=50");
|
||||
} else {
|
||||
attr(photo, "src", resp.commenter.photo);
|
||||
}
|
||||
attr(logout, "onclick", "logout()");
|
||||
|
||||
append(loggedInAs, photo);
|
||||
append(loggedInAs, name);
|
||||
append(loggedContainer, loggedInAs);
|
||||
append(loggedContainer, logout);
|
||||
append(root, loggedContainer);
|
||||
|
||||
isAuthenticated = true;
|
||||
|
||||
call(callback);
|
||||
});
|
||||
}
|
||||
|
||||
function cssLoad(file) {
|
||||
var link = create("link");
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
|
||||
link.type = "text/css";
|
||||
attr(link, "href", file);
|
||||
attr(link, "rel", "stylesheet");
|
||||
|
||||
append(head, link);
|
||||
}
|
||||
|
||||
function jsLoad(file, ready) {
|
||||
var script = document.createElement("script");
|
||||
var loaded = false;
|
||||
|
||||
script.type = "application/javascript";
|
||||
script.src = file;
|
||||
script.async = true;
|
||||
script.onreadysessionchange = script.onload = function() {
|
||||
if (!loaded &&
|
||||
(!this.readySession ||
|
||||
this.readySession === "loaded" ||
|
||||
this.readySession === "complete"))
|
||||
{
|
||||
ready();
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
script.onload = script.onreadysessionchange = null;
|
||||
};
|
||||
|
||||
append(document.body, script);
|
||||
}
|
||||
|
||||
function footerLoad() {
|
||||
var footer = create("div");
|
||||
var aContainer = create("div");
|
||||
var a = create("a");
|
||||
var img = create("img");
|
||||
var text = create("span");
|
||||
|
||||
classAdd(footer, "footer");
|
||||
classAdd(aContainer, "logo-container");
|
||||
classAdd(a, "logo");
|
||||
classAdd(img, "logo-svg");
|
||||
classAdd(text, "logo-text");
|
||||
|
||||
attr(a, "href", "https://commento.io");
|
||||
attr(a, "target", "_blank");
|
||||
attr(img, "src", cdn + "/images/logo.svg");
|
||||
|
||||
text.innerText = "Powered by Commento";
|
||||
|
||||
append(a, img);
|
||||
append(a, text);
|
||||
append(aContainer, a);
|
||||
append(footer, aContainer);
|
||||
append(root, footer);
|
||||
}
|
||||
|
||||
function commentsGet(callback) {
|
||||
var json = {
|
||||
session: sessionGet(),
|
||||
domain: location.host,
|
||||
path: location.pathname,
|
||||
};
|
||||
|
||||
post(origin + "/api/comment/list", json, function(resp) {
|
||||
if (!resp.success) {
|
||||
errorShow(resp.message);
|
||||
return;
|
||||
}
|
||||
|
||||
requireModeration = resp.requireModeration;
|
||||
requireIdentification = resp.requireIdentification;
|
||||
isModerator = resp.isModerator;
|
||||
isFrozen = resp.isFrozen;
|
||||
comments = resp.comments;
|
||||
commenters = resp.commenters;
|
||||
|
||||
cssLoad(cdn + "/css/commento.css");
|
||||
|
||||
call(callback);
|
||||
});
|
||||
}
|
||||
|
||||
function errorShow(text) {
|
||||
var el = $(ID_ERROR);
|
||||
|
||||
el.innerText = text;
|
||||
|
||||
attr(el, "style", "display: block;");
|
||||
}
|
||||
|
||||
function createErrorElement() {
|
||||
var el = create("div");
|
||||
|
||||
el.id = ID_ERROR;
|
||||
|
||||
classAdd(el, "error-box");
|
||||
attr(el, "style", "display: none;");
|
||||
|
||||
append(root, el);
|
||||
}
|
||||
|
||||
function autoExpander(el) {
|
||||
return function() {
|
||||
el.style.height = "";
|
||||
el.style.height = Math.min(Math.max(el.scrollHeight, 75), 400) + "px";
|
||||
}
|
||||
};
|
||||
|
||||
function isMobile() {
|
||||
var mobile = false;
|
||||
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
|
||||
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4)))
|
||||
mobile = true;
|
||||
|
||||
return mobile;
|
||||
}
|
||||
|
||||
function textareaCreate(id) {
|
||||
var textareaSuperContainer = create("div");
|
||||
var textareaContainer = create("div");
|
||||
var textarea = create("textarea");
|
||||
|
||||
textareaSuperContainer.id = ID_SUPER_CONTAINER + id;
|
||||
textareaContainer.id = ID_TEXTAREA_CONTAINER + id;
|
||||
textarea.id = ID_TEXTAREA + id;
|
||||
|
||||
classAdd(textareaContainer, "textarea-container");
|
||||
|
||||
if (!isAuthenticated && !chosenAnonymous) {
|
||||
var buttonsContainer = create("div");
|
||||
|
||||
if (!isMobile()) {
|
||||
classAdd(buttonsContainer, "buttons-container");
|
||||
classAdd(textarea, "blurred-textarea");
|
||||
} else {
|
||||
classAdd(textarea, "hidden");
|
||||
classAdd(buttonsContainer, "mobile-buttons-container");
|
||||
classAdd(buttonsContainer, "opaque");
|
||||
}
|
||||
|
||||
var oauths = ["google"];
|
||||
if (!requireIdentification)
|
||||
oauths.push("anonymous");
|
||||
|
||||
for (var i = 0; i < oauths.length; i++) {
|
||||
var oauthButton = create("button");
|
||||
|
||||
classAdd(oauthButton, "button");
|
||||
classAdd(oauthButton, oauths[i] + "-button");
|
||||
|
||||
if (isMobile())
|
||||
classAdd(oauthButton, "opaque");
|
||||
|
||||
attr(oauthButton, "onclick", "commentoAuth('" + oauths[i] + "', '" + id + "')");
|
||||
|
||||
oauthButton.innerText = oauths[i][0].toUpperCase() + oauths[i].slice(1);
|
||||
|
||||
append(buttonsContainer, oauthButton);
|
||||
}
|
||||
|
||||
attr(textarea, "disabled", true);
|
||||
|
||||
append(textareaContainer, buttonsContainer);
|
||||
}
|
||||
|
||||
attr(textarea, "placeholder", "Join the discussion!");
|
||||
attr(textarea, "onclick", "showSubmitButton('" + id + "')");
|
||||
|
||||
textarea.oninput = autoExpander(textarea);
|
||||
|
||||
append(textareaContainer, textarea);
|
||||
append(textareaSuperContainer, textareaContainer);
|
||||
|
||||
return textareaSuperContainer;
|
||||
}
|
||||
|
||||
function rootCreate(callback) {
|
||||
var commentsArea = create("div");
|
||||
|
||||
commentsArea.id = ID_COMMENTS_AREA;
|
||||
|
||||
classAdd(commentsArea, "comments");
|
||||
|
||||
commentsArea.innerHTML = "";
|
||||
|
||||
append(root, textareaCreate("root"));
|
||||
append(root, commentsArea);
|
||||
|
||||
call(callback);
|
||||
}
|
||||
|
||||
function messageCreate(text) {
|
||||
var msg = create("div");
|
||||
|
||||
classAdd(msg, "moderation-notice");
|
||||
|
||||
msg.innerText = text;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
global.postComment = function(id) {
|
||||
var textarea = $(ID_TEXTAREA + id);
|
||||
|
||||
var comment = textarea.value;
|
||||
|
||||
if (comment == "") {
|
||||
classAdd(textarea, "red-border");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
classRemove(textarea, "red-border");
|
||||
}
|
||||
|
||||
var json = {
|
||||
"session": sessionGet(),
|
||||
"domain": location.host,
|
||||
"path": location.pathname,
|
||||
"parentHex": id,
|
||||
"markdown": comment,
|
||||
};
|
||||
|
||||
post(origin + "/api/comment/new", json, function(resp) {
|
||||
if (!resp.success) {
|
||||
errorShow(resp.message);
|
||||
return;
|
||||
}
|
||||
|
||||
$(ID_TEXTAREA + id).value = "";
|
||||
|
||||
commentsGet(function() {
|
||||
$(ID_COMMENTS_AREA).innerHTML = "";
|
||||
commentsRender();
|
||||
|
||||
if (requireModeration && !isModerator) {
|
||||
if (id == "root") {
|
||||
var body = $(ID_SUPER_CONTAINER + id);
|
||||
prepend(body, messageCreate("Your comment is under moderation."));
|
||||
} else {
|
||||
var body = $(ID_BODY + id);
|
||||
append(body, messageCreate("Your comment is under moderation."));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function colorGet(name) {
|
||||
var colors = [
|
||||
// some visually distincy
|
||||
"#35b2de", // some kind of teal/cyan
|
||||
"#62cd0a", // fresh lemon green
|
||||
"#383838", // shade of gray
|
||||
"#e4a90f", // comfy yellow
|
||||
"#f80707", // sharp red
|
||||
"#f0479c", // bright pink
|
||||
];
|
||||
|
||||
var total = 0;
|
||||
for (var i = 0; i < name.length; i++)
|
||||
total += name.charCodeAt(i);
|
||||
var color = colors[total % colors.length];
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
function timeDifference(current, previous) { // thanks stackoverflow
|
||||
var msJustNow = 5000;
|
||||
var msPerMinute = 60000;
|
||||
var msPerHour = 3600000;
|
||||
var msPerDay = 86400000;
|
||||
var msPerMonth = 2592000000;
|
||||
var msPerYear = 946080000000;
|
||||
|
||||
var elapsed = current - previous;
|
||||
|
||||
if (elapsed < msJustNow) {
|
||||
return 'just now';
|
||||
}
|
||||
else if (elapsed < msPerMinute) {
|
||||
return Math.round(elapsed/1000) + ' seconds ago';
|
||||
}
|
||||
else if (elapsed < msPerHour) {
|
||||
return Math.round(elapsed/msPerMinute) + ' minutes ago';
|
||||
}
|
||||
else if (elapsed < msPerDay ) {
|
||||
return Math.round(elapsed/msPerHour ) + ' hours ago';
|
||||
}
|
||||
else if (elapsed < msPerMonth) {
|
||||
return Math.round(elapsed/msPerDay) + ' days ago';
|
||||
}
|
||||
else if (elapsed < msPerYear) {
|
||||
return Math.round(elapsed/msPerMonth) + ' months ago';
|
||||
}
|
||||
else {
|
||||
return Math.round(elapsed/msPerYear ) + ' years ago';
|
||||
}
|
||||
}
|
||||
|
||||
function scorify(score) {
|
||||
if (score != 1)
|
||||
return score + " points";
|
||||
else
|
||||
return score + " point";
|
||||
}
|
||||
|
||||
var ID_ERROR = "commento-error";
|
||||
var ID_COMMENTS_AREA = "commento-comments-area";
|
||||
var ID_SUPER_CONTAINER = "commento-textarea-super-container-";
|
||||
var ID_TEXTAREA_CONTAINER = "commento-textarea-container-";
|
||||
var ID_TEXTAREA = "commento-textarea-";
|
||||
var ID_CARD = "commento-comment-card-";
|
||||
var ID_BODY = "commento-comment-body-";
|
||||
var ID_SUBTITLE = "commento-comment-subtitle-";
|
||||
var ID_SCORE = "commento-comment-score-";
|
||||
var ID_OPTIONS = "commento-comment-options-";
|
||||
var ID_EDIT = "commento-comment-edit-";
|
||||
var ID_REPLY = "commento-comment-reply-";
|
||||
var ID_COLLAPSE = "commento-comment-collapse-";
|
||||
var ID_UPVOTE = "commento-comment-upvote-";
|
||||
var ID_DOWNVOTE = "commento-comment-downvote-";
|
||||
var ID_APPROVE = "commento-comment-approve-";
|
||||
var ID_REMOVE = "commento-comment-remove-";
|
||||
var ID_CONTENTS = "commento-comment-contents-";
|
||||
var ID_SUBMIT_BUTTON = "commento-submit-button-";
|
||||
|
||||
function commentsRecurse(parentMap, parentHex) {
|
||||
var cur = parentMap[parentHex];
|
||||
if (!cur || !cur.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var cards = create("div");
|
||||
cur.forEach(function(comment) {
|
||||
var commenter = commenters[comment.commenterHex];
|
||||
var avatar;
|
||||
var card = create("div");
|
||||
var header = create("div");
|
||||
var subtitle = create("div");
|
||||
var score = create("div");
|
||||
var body = create("div");
|
||||
var options = create("div");
|
||||
var edit = create("button");
|
||||
var reply = create("button");
|
||||
var collapse = create("button");
|
||||
var upvote = create("div");
|
||||
var downvote = create("div");
|
||||
var approve = create("button");
|
||||
var remove = create("button");
|
||||
var children = commentsRecurse(parentMap, comment.commentHex);
|
||||
var contents = create("div");
|
||||
var color = colorGet(commenter.name);
|
||||
var name;
|
||||
if (commenter.link != "undefined")
|
||||
name = create("a");
|
||||
else
|
||||
name = create("div");
|
||||
|
||||
card.id = ID_CARD + comment.commentHex;
|
||||
body.id = ID_BODY + comment.commentHex;
|
||||
subtitle.id = ID_SUBTITLE + comment.commentHex;
|
||||
score.id = ID_SCORE + comment.commentHex;
|
||||
options.id = ID_OPTIONS + comment.commentHex;
|
||||
edit.id = ID_EDIT + comment.commentHex;
|
||||
reply.id = ID_REPLY + comment.commentHex;
|
||||
collapse.id = ID_COLLAPSE + comment.commentHex;
|
||||
upvote.id = ID_UPVOTE + comment.commentHex;
|
||||
downvote.id = ID_DOWNVOTE + comment.commentHex;
|
||||
approve.id = ID_APPROVE + comment.commentHex;
|
||||
remove.id = ID_REMOVE + comment.commentHex;
|
||||
contents.id = ID_CONTENTS + comment.commentHex;
|
||||
|
||||
collapse.title = "Collapse";
|
||||
upvote.title = "Upvote";
|
||||
downvote.title = "Downvote";
|
||||
edit.title = "Edit";
|
||||
reply.title = "Reply";
|
||||
approve.title = "Approve";
|
||||
remove.title = "Remove";
|
||||
|
||||
card.style["borderLeft"] = "2px solid " + color;
|
||||
name.innerText = commenter.name;
|
||||
body.innerHTML = comment.html;
|
||||
subtitle.innerHTML = timeDifference((new Date()).getTime(), Date.parse(comment.creationDate));
|
||||
score.innerText = scorify(comment.score);
|
||||
|
||||
if (commenter.photo == "undefined") {
|
||||
avatar = create("div");
|
||||
avatar.style["background"] = color;
|
||||
avatar.style["boxShadow"] = "0px 0px 0px 2px " + color;
|
||||
avatar.innerHTML = commenter.name[0].toUpperCase();
|
||||
classAdd(avatar, "avatar");
|
||||
} else {
|
||||
avatar = create("img");
|
||||
if (commenter.provider == "google") {
|
||||
attr(avatar, "src", commenter.photo + "?sz=50");
|
||||
} else {
|
||||
attr(avatar, "src", commenter.photo);
|
||||
}
|
||||
classAdd(avatar, "avatar-img");
|
||||
}
|
||||
|
||||
classAdd(card, "card");
|
||||
if (isModerator && comment.state == "unapproved")
|
||||
classAdd(card, "dark-card");
|
||||
classAdd(header, "header");
|
||||
classAdd(name, "name");
|
||||
classAdd(subtitle, "subtitle");
|
||||
classAdd(score, "score");
|
||||
classAdd(body, "body");
|
||||
classAdd(options, "options");
|
||||
classAdd(edit, "option-button");
|
||||
classAdd(edit, "option-edit");
|
||||
classAdd(reply, "option-button");
|
||||
classAdd(reply, "option-reply");
|
||||
classAdd(collapse, "option-button");
|
||||
classAdd(collapse, "option-collapse");
|
||||
classAdd(upvote, "option-button");
|
||||
classAdd(upvote, "option-upvote");
|
||||
classAdd(downvote, "option-button");
|
||||
classAdd(downvote, "option-downvote");
|
||||
classAdd(approve, "option-button");
|
||||
classAdd(approve, "option-approve");
|
||||
classAdd(remove, "option-button");
|
||||
classAdd(remove, "option-remove");
|
||||
|
||||
if (isAuthenticated) {
|
||||
if (comment.direction > 0)
|
||||
classAdd(upvote, "upvoted");
|
||||
else if (comment.direction < 0)
|
||||
classAdd(downvote, "downvoted");
|
||||
}
|
||||
|
||||
attr(edit, "onclick", "startEdit('" + comment.commentHex + "')");
|
||||
attr(reply, "onclick", "replyShow('" + comment.commentHex + "')");
|
||||
attr(collapse, "onclick", "commentCollapse('" + comment.commentHex + "')");
|
||||
attr(approve, "onclick", "commentApprove('" + comment.commentHex + "')");
|
||||
attr(remove, "onclick", "commentDelete('" + comment.commentHex + "')");
|
||||
|
||||
if (isAuthenticated) {
|
||||
if (comment.direction > 0) {
|
||||
attr(upvote, "onclick", "vote('" + comment.commentHex + "', 1, 0)");
|
||||
attr(downvote, "onclick", "vote('" + comment.commentHex + "', 1, -1)");
|
||||
}
|
||||
else if (comment.direction < 0) {
|
||||
attr(upvote, "onclick", "vote('" + comment.commentHex + "', -1, 1)");
|
||||
attr(downvote, "onclick", "vote('" + comment.commentHex + "', -1, 0)");
|
||||
}
|
||||
else {
|
||||
attr(upvote, "onclick", "vote('" + comment.commentHex + "', 0, 1)");
|
||||
attr(downvote, "onclick", "vote('" + comment.commentHex + "', 0, -1)");
|
||||
}
|
||||
} else if (!chosenAnonymous) {
|
||||
attr(upvote, "onclick", "replyShow('" + comment.commentHex + "')");
|
||||
}
|
||||
|
||||
if (isAuthenticated) {
|
||||
if (isModerator) {
|
||||
if (comment.state == "unapproved")
|
||||
attr(options, "style", "width: 192px;");
|
||||
else
|
||||
attr(options, "style", "width: 160px;");
|
||||
}
|
||||
else
|
||||
attr(options, "style", "width: 128px;");
|
||||
}
|
||||
else
|
||||
attr(options, "style", "width: 32px;");
|
||||
|
||||
if (commenter.link != "undefined")
|
||||
attr(name, "href", commenter.link);
|
||||
|
||||
if (false) // replace when edit is implemented
|
||||
append(options, edit);
|
||||
|
||||
if (isAuthenticated) {
|
||||
append(options, upvote);
|
||||
append(options, downvote);
|
||||
append(options, reply);
|
||||
}
|
||||
|
||||
if (isModerator) {
|
||||
if (comment.state == "unapproved")
|
||||
append(options, approve);
|
||||
append(options, remove);
|
||||
}
|
||||
|
||||
append(options, collapse);
|
||||
append(subtitle, score);
|
||||
append(header, options);
|
||||
append(header, avatar);
|
||||
append(header, name);
|
||||
append(header, subtitle);
|
||||
append(contents, body);
|
||||
|
||||
if (children) {
|
||||
classAdd(children, "body");
|
||||
append(contents, children);
|
||||
}
|
||||
|
||||
append(card, header);
|
||||
append(card, contents);
|
||||
append(cards, card);
|
||||
|
||||
shownSubmitButton[comment.commentHex] = false;
|
||||
});
|
||||
|
||||
return cards;
|
||||
}
|
||||
|
||||
|
||||
global.commentApprove = function(commentHex) {
|
||||
var json = {
|
||||
"session": sessionGet(),
|
||||
"commentHex": commentHex,
|
||||
}
|
||||
|
||||
post(origin + "/api/comment/approve", json, function(resp) {
|
||||
if (!resp.success) {
|
||||
errorShow(resp.message);
|
||||
return
|
||||
}
|
||||
|
||||
var card = $(ID_CARD + commentHex);
|
||||
var options = $(ID_OPTIONS + commentHex);
|
||||
var tick = $(ID_APPROVE + commentHex);
|
||||
|
||||
classRemove(card, "dark-card");
|
||||
attr(options, "style", "width: 160px;");
|
||||
remove(tick);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
global.commentDelete = function(commentHex) {
|
||||
var json = {
|
||||
"session": sessionGet(),
|
||||
"commentHex": commentHex,
|
||||
}
|
||||
|
||||
post(origin + "/api/comment/delete", json, function(resp) {
|
||||
if (!resp.success) {
|
||||
errorShow(resp.message);
|
||||
return
|
||||
}
|
||||
|
||||
var card = $(ID_CARD + commentHex);
|
||||
remove(card);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function nameWidthFix() {
|
||||
var els = document.getElementsByClassName("commento-name");
|
||||
|
||||
for (var i = 0; i < els.length; i++)
|
||||
attr(els[i], "style", "max-width: " + (els[i].getBoundingClientRect()["width"] + 20) + "px;")
|
||||
}
|
||||
|
||||
|
||||
global.vote = function(commentHex, oldVote, direction) {
|
||||
var upvote = $(ID_UPVOTE + commentHex);
|
||||
var downvote = $(ID_DOWNVOTE + commentHex);
|
||||
var score = $(ID_SCORE + commentHex);
|
||||
|
||||
var json = {
|
||||
"session": sessionGet(),
|
||||
"commentHex": commentHex,
|
||||
"direction": direction,
|
||||
};
|
||||
|
||||
if (direction > 0) {
|
||||
attr(upvote, "onclick", "vote('" + commentHex + "', 1, 0)");
|
||||
attr(downvote, "onclick", "vote('" + commentHex + "', 1, -1)");
|
||||
}
|
||||
else if (direction < 0) {
|
||||
attr(upvote, "onclick", "vote('" + commentHex + "', -1, 1)");
|
||||
attr(downvote, "onclick", "vote('" + commentHex + "', -1, 0)");
|
||||
}
|
||||
else {
|
||||
attr(upvote, "onclick", "vote('" + commentHex + "', 0, 1)");
|
||||
attr(downvote, "onclick", "vote('" + commentHex + "', 0, -1)");
|
||||
}
|
||||
|
||||
classRemove(upvote, "upvoted");
|
||||
classRemove(downvote, "downvoted");
|
||||
if (direction > 0)
|
||||
classAdd(upvote, "upvoted");
|
||||
else if (direction < 0)
|
||||
classAdd(downvote, "downvoted");
|
||||
|
||||
score.innerText = scorify(parseInt(score.innerText.replace(/[^\d-.]/g, "")) + direction - oldVote);
|
||||
|
||||
post(origin + "/api/comment/vote", json, function(resp) {});
|
||||
}
|
||||
|
||||
global.replyShow = function(id) {
|
||||
if (id in shownReply && shownReply[id])
|
||||
return;
|
||||
|
||||
var body = $(ID_BODY + id);
|
||||
append(body, textareaCreate(id));
|
||||
shownReply[id] = true;
|
||||
|
||||
var replyButton = $(ID_REPLY + id);
|
||||
|
||||
classRemove(replyButton, "option-reply");
|
||||
classAdd(replyButton, "option-cancel");
|
||||
|
||||
replyButton.title = "Cancel reply";
|
||||
|
||||
attr(replyButton, "onclick", "replyCollapse('" + id + "')")
|
||||
};
|
||||
|
||||
global.replyCollapse = function(id) {
|
||||
var replyButton = $(ID_REPLY + id);
|
||||
var el = $(ID_SUPER_CONTAINER + id);
|
||||
|
||||
el.remove();
|
||||
shownReply[id] = false;
|
||||
shownSubmitButton[id] = false;
|
||||
|
||||
classAdd(replyButton, "option-reply");
|
||||
classRemove(replyButton, "option-cancel");
|
||||
|
||||
replyButton.title = "Reply to this comment";
|
||||
|
||||
attr(replyButton, "onclick", "replyShow('" + id + "')")
|
||||
}
|
||||
|
||||
global.commentCollapse = function(id) {
|
||||
var contents = $(ID_CONTENTS + id);
|
||||
var button = $(ID_COLLAPSE + id);
|
||||
|
||||
classAdd(contents, "hidden");
|
||||
|
||||
classRemove(button, "option-collapse");
|
||||
classAdd(button, "option-uncollapse");
|
||||
|
||||
button.title = "Expand";
|
||||
|
||||
attr(button, "onclick", "commentUncollapse('" + id + "')");
|
||||
}
|
||||
|
||||
global.commentUncollapse = function(id) {
|
||||
var contents = $(ID_CONTENTS + id);
|
||||
var button = $(ID_COLLAPSE + id);
|
||||
|
||||
classRemove(contents, "hidden");
|
||||
|
||||
classRemove(button, "option-uncollapse");
|
||||
classAdd(button, "option-collapse");
|
||||
|
||||
button.title = "Collapse";
|
||||
|
||||
attr(button, "onclick", "commentCollapse('" + id + "')");
|
||||
}
|
||||
|
||||
function commentsRender() {
|
||||
var parentMap = {};
|
||||
var parentHex;
|
||||
|
||||
var commentsArea = $(ID_COMMENTS_AREA);
|
||||
|
||||
comments.forEach(function(comment) {
|
||||
parentHex = comment.parentHex;
|
||||
if (!(parentHex in parentMap)) {
|
||||
parentMap[parentHex] = [];
|
||||
}
|
||||
parentMap[parentHex].push(comment);
|
||||
});
|
||||
|
||||
var cards = commentsRecurse(parentMap, "root");
|
||||
if (cards) {
|
||||
append(commentsArea, cards);
|
||||
}
|
||||
}
|
||||
|
||||
global.showSubmitButton = function(id) {
|
||||
if (id in shownSubmitButton && shownSubmitButton[id])
|
||||
return;
|
||||
|
||||
shownSubmitButton[id] = true;
|
||||
|
||||
var el = $(ID_SUPER_CONTAINER + id);
|
||||
|
||||
var submit = create("button");
|
||||
|
||||
submit.id = ID_SUBMIT_BUTTON + id;
|
||||
|
||||
submit.innerText = "Add Comment";
|
||||
|
||||
classAdd(submit, "button");
|
||||
classAdd(submit, "submit-button");
|
||||
classAdd(el, "button-margin");
|
||||
|
||||
attr(submit, "onclick", "postComment('" + id + "')");
|
||||
|
||||
append(el, submit);
|
||||
}
|
||||
|
||||
global.commentoAuth = function(provider, id) {
|
||||
if (provider == "anonymous") {
|
||||
cookieSet("session", "anonymous");
|
||||
chosenAnonymous = true;
|
||||
refreshAll(function() {
|
||||
if (id != "root")
|
||||
global.replyShow(id);
|
||||
$(ID_TEXTAREA + id).click();
|
||||
$(ID_TEXTAREA + id).focus();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var popup = window.open("", "_blank");
|
||||
|
||||
get(origin + "/api/commenter/session/new", function(resp) {
|
||||
if (!resp.success) {
|
||||
errorShow(resp.message);
|
||||
return;
|
||||
}
|
||||
|
||||
cookieSet("session", resp.session);
|
||||
|
||||
popup.location = origin + "/api/oauth/" + provider + "/redirect?session=" + resp.session;
|
||||
|
||||
var interval = setInterval(function() {
|
||||
if (popup.closed) {
|
||||
refreshAll(function() {
|
||||
if (id != "root")
|
||||
global.replyShow(id);
|
||||
$(ID_TEXTAREA + id).click();
|
||||
$(ID_TEXTAREA + id).focus();
|
||||
});
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
}
|
||||
|
||||
function refreshAll(callback) {
|
||||
$("commento").innerHTML = "";
|
||||
shownSubmitButton = {"root": false};
|
||||
shownReply = {};
|
||||
main(callback);
|
||||
}
|
||||
|
||||
function main(callback) {
|
||||
root = $("commento");
|
||||
|
||||
createErrorElement();
|
||||
|
||||
selfGet(function() {
|
||||
commentsGet(function() {
|
||||
rootCreate(function() {
|
||||
commentsRender();
|
||||
nameWidthFix();
|
||||
footerLoad();
|
||||
attr(root, "style", "");
|
||||
call(callback);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", main);
|
||||
|
||||
}(window, document));
|
99
frontend/sass/commento-buttons.scss
Normal file
99
frontend/sass/commento-buttons.scss
Normal file
@ -0,0 +1,99 @@
|
||||
@import "colors-main.scss";
|
||||
|
||||
@mixin mask-image($image) {
|
||||
-webkit-mask-image: url($image);
|
||||
mask-image: url($image);
|
||||
}
|
||||
|
||||
.commento-option-button {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
padding: 0px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 3;
|
||||
background: $gray-4;
|
||||
}
|
||||
|
||||
.commento-option-reply {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
@include mask-image('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8"?><svg version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><g transform="matrix(1.7358 0 0 1.7335 4.2642 15.217)"><path d="m10 2.5 1e-6 -4.4421-9 7.4421 9 6.5759-1e-6 -4.6759c6.4194-1.4839 11.739 2.1762 11.739 2.1762s-2.0774-6.5475-11.739-7.0762z" fill="#abbac4"/></g></svg>');
|
||||
margin: 9px 3px 9px 3px;
|
||||
right: 32px;
|
||||
}
|
||||
|
||||
.commento-option-cancel {
|
||||
height: 13px;
|
||||
width: 13px;
|
||||
@include mask-image('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8"?><svg enable-background="new 0 0 129 129" version="1.1" viewBox="0 0 129 129" xmlns="http://www.w3.org/2000/svg"><path d="m7.6 121.4c0.8 0.8 1.8 1.2 2.9 1.2s2.1-0.4 2.9-1.2l51.1-51.1 51.1 51.1c0.8 0.8 1.8 1.2 2.9 1.2 1 0 2.1-0.4 2.9-1.2 1.6-1.6 1.6-4.2 0-5.8l-51.1-51.1 51.1-51.1c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8 0l-51.1 51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8 0s-1.6 4.2 0 5.8l51.1 51.1-51.1 51.1c-1.6 1.6-1.6 4.2 0 5.8z" fill="#abbac4"/></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
right: 32px;
|
||||
background: $gray-5;
|
||||
}
|
||||
|
||||
.commento-option-collapse {
|
||||
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 42 42" version="1.1" viewBox="0 0 42 42" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><polygon points="42 20 0 20 0 22 20 22 22 22 42 22" fill="#1e2127"/></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
right: 0px;
|
||||
background: $gray-7;
|
||||
}
|
||||
|
||||
.commento-option-uncollapse {
|
||||
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 42 42" version="1.1" viewBox="0 0 42 42" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><polygon points="42 20 22 20 22 0 20 0 20 20 0 20 0 22 20 22 20 42 22 42 22 22 42 22" fill="#1e2127"/></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
right: 0px;
|
||||
background: $gray-7;
|
||||
}
|
||||
|
||||
.commento-option-upvote,
|
||||
.commento-option-downvote {
|
||||
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 284.929 284.929" version="1.1" viewBox="0 0 284.93 284.93" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"> <path d="m282.08 195.28-133.05-133.04c-1.901-1.903-4.088-2.856-6.562-2.856s-4.665 0.953-6.567 2.856l-133.04 133.04c-1.906 1.906-2.856 4.093-2.856 6.568 0 2.474 0.953 4.664 2.856 6.566l14.272 14.271c1.903 1.903 4.093 2.854 6.567 2.854s4.664-0.951 6.567-2.854l112.2-112.2 112.21 112.21c1.902 1.903 4.093 2.848 6.563 2.848 2.478 0 4.668-0.951 6.57-2.848l14.274-14.277c1.902-1.902 2.847-4.093 2.847-6.566 1e-3 -2.476-0.944-4.666-2.846-6.569z" fill="#abbac4"/></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
}
|
||||
|
||||
.commento-option-upvote {
|
||||
right: 96px;
|
||||
}
|
||||
|
||||
.commento-option-downvote {
|
||||
transform: rotate(180deg);
|
||||
right: 64px;
|
||||
}
|
||||
|
||||
.commento-upvoted {
|
||||
background: $orange-7;
|
||||
}
|
||||
|
||||
.commento-downvoted {
|
||||
background: $indigo-6;
|
||||
}
|
||||
|
||||
.commento-option-remove {
|
||||
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 59 59" version="1.1" viewBox="0 0 59 59" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g fill="#1e2127"> <path d="m29.5 51c0.552 0 1-0.447 1-1v-33c0-0.553-0.448-1-1-1s-1 0.447-1 1v33c0 0.553 0.448 1 1 1z"/> <path d="m19.5 51c0.552 0 1-0.447 1-1v-33c0-0.553-0.448-1-1-1s-1 0.447-1 1v33c0 0.553 0.448 1 1 1z"/> <path d="m39.5 51c0.552 0 1-0.447 1-1v-33c0-0.553-0.448-1-1-1s-1 0.447-1 1v33c0 0.553 0.448 1 1 1z"/> <path d="M52.5,6H38.456c-0.11-1.25-0.495-3.358-1.813-4.711C35.809,0.434,34.751,0,33.499,0H23.5c-1.252,0-2.31,0.434-3.144,1.289 C19.038,2.642,18.653,4.75,18.543,6H6.5c-0.552,0-1,0.447-1,1s0.448,1,1,1h2.041l1.915,46.021C10.493,55.743,11.565,59,15.364,59 h28.272c3.799,0,4.871-3.257,4.907-4.958L50.459,8H52.5c0.552,0,1-0.447,1-1S53.052,6,52.5,6z M21.792,2.681 C22.24,2.223,22.799,2,23.5,2h9.999c0.701,0,1.26,0.223,1.708,0.681c0.805,0.823,1.128,2.271,1.24,3.319H20.553 C20.665,4.952,20.988,3.504,21.792,2.681z M46.544,53.979C46.538,54.288,46.4,57,43.636,57H15.364 c-2.734,0-2.898-2.717-2.909-3.042L10.542,8h37.915L46.544,53.979z"/></g></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
right: 128px;
|
||||
background: $red-8;
|
||||
}
|
||||
|
||||
.commento-option-approve {
|
||||
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 26 26" version="1.1" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg"><path d="m0.3 14c-0.2-0.2-0.3-0.5-0.3-0.7s0.1-0.5 0.3-0.7l1.4-1.4c0.4-0.4 1-0.4 1.4 0l0.1 0.1 5.5 5.9c0.2 0.2 0.5 0.2 0.7 0l13.4-13.9h0.1v-8.8818e-16c0.4-0.4 1-0.4 1.4 0l1.4 1.4c0.4 0.4 0.4 1 0 1.4l-16 16.6c-0.2 0.2-0.4 0.3-0.7 0.3s-0.5-0.1-0.7-0.3l-7.8-8.4-0.2-0.3z" fill="#1e2127"/></svg>');
|
||||
margin: 12px 6px 12px 6px;
|
||||
right: 160px;
|
||||
background: $green-7;
|
||||
}
|
||||
|
||||
.commento-option-button:focus {
|
||||
outline: none;
|
||||
}
|
187
frontend/sass/commento-input.scss
Normal file
187
frontend/sass/commento-input.scss
Normal file
@ -0,0 +1,187 @@
|
||||
@import "colors-main.scss";
|
||||
|
||||
textarea,
|
||||
input[type=text] {
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(50, 50, 93, .1);
|
||||
border-radius: 3px;
|
||||
color: #525f7f;
|
||||
}
|
||||
|
||||
input[type=text]::placeholder {
|
||||
color: #cacaca;
|
||||
}
|
||||
|
||||
textarea::placeholder {
|
||||
color: #aaa;
|
||||
font-size: 22px;
|
||||
padding-top: 13px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
display: inline-block;
|
||||
font-family: "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
||||
padding: 8px;
|
||||
outline: none;
|
||||
overflow: auto;
|
||||
min-height: 75px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.commento-red-border {
|
||||
border: 1px solid $red-7;
|
||||
}
|
||||
|
||||
.commento-textarea-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
.commento-button, .commento-buttons-container::before {
|
||||
opacity: 1;
|
||||
transform: translate(0px,-3px);
|
||||
}
|
||||
|
||||
.commento-submit-button {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.commento-blurred-textarea {
|
||||
opacity: .7;
|
||||
transform: scale(.95);
|
||||
filter: blur(4px);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 550px) {
|
||||
.commento-buttons-container::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commento-buttons-container {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.commento-mobile-buttons-container::before,
|
||||
.commento-buttons-container::before {
|
||||
content: "Authenticate with";
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
padding: 6px;
|
||||
color: $gray-8;
|
||||
transition: all 0.3s;
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.commento-mobile-buttons-container::before {
|
||||
content: "To join the discussion, authenticate with";;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 550px) {
|
||||
.commento-buttons-container::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.commento-button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
padding: 6px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
box-shadow: 0 4px 6px rgba(50,50,93,.11),0 1px 3px rgba(0,0,0,.08);
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
width: 100px;
|
||||
margin-left: 5px;
|
||||
margin-left: 5px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.commento-opaque {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.commento-opaque::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.commento-google-button {
|
||||
transition: all 0.3s;
|
||||
background: #dd4b39;
|
||||
}
|
||||
|
||||
.commento-github-button {
|
||||
transition: all 0.3s;
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.commento-anonymous-button {
|
||||
transition: all 0.3s;
|
||||
background: #096fa6;
|
||||
}
|
||||
|
||||
.commento-blurred-textarea {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
transition: 0.3s all;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.commento-approve-button,
|
||||
.commento-delete-button,
|
||||
.commento-submit-button {
|
||||
margin-top: 10px;
|
||||
opacity: 1;
|
||||
font-size: 14px;
|
||||
width: -moz-fit-content;
|
||||
width: -webkit-fit-content;
|
||||
width: -ms-fit-content;
|
||||
width: -o-fit-content;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.commento-submit-button {
|
||||
float: right;
|
||||
background: $indigo-7;
|
||||
}
|
||||
|
||||
.commento-approve-button {
|
||||
background: $green-7;
|
||||
}
|
||||
|
||||
.commento-delete-button {
|
||||
background: $red-7;
|
||||
}
|
||||
|
||||
.commento-button-margin {
|
||||
padding-bottom: 60px;
|
||||
}
|
37
frontend/sass/commento-logged.scss
Normal file
37
frontend/sass/commento-logged.scss
Normal file
@ -0,0 +1,37 @@
|
||||
@import "colors-main.scss";
|
||||
|
||||
.commento-logged-container {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
|
||||
.commento-logout {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 16px;
|
||||
color: $gray-5;
|
||||
}
|
||||
|
||||
.commento-logged-in-as {
|
||||
position: relative;
|
||||
|
||||
.commento-name {
|
||||
color: $gray-8;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 64px;
|
||||
}
|
||||
|
||||
.commento-photo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
38
frontend/sass/commento-logo.scss
Normal file
38
frontend/sass/commento-logo.scss
Normal file
@ -0,0 +1,38 @@
|
||||
@import "colors-main.scss";
|
||||
|
||||
.commento-footer {
|
||||
margin: 36px 0px 12px 0px;
|
||||
border-top: 1px solid $gray-1;
|
||||
padding-right: 12px;
|
||||
|
||||
.commento-logo-container {
|
||||
float: right;
|
||||
|
||||
.commento-logo {
|
||||
border: none;
|
||||
width: auto;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
|
||||
.commento-logo-svg {
|
||||
display: inline;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.commento-logo-text {
|
||||
font-size: 13px;
|
||||
color: $gray-6;
|
||||
display: inline;
|
||||
line-height: 24px;
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
20
frontend/sass/commento-tags.scss
Normal file
20
frontend/sass/commento-tags.scss
Normal file
@ -0,0 +1,20 @@
|
||||
@import "colors-main.scss";
|
||||
|
||||
code {
|
||||
background: $red-3;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
color: $red-6;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1f89ff;
|
||||
border-bottom: 1px solid #1f89ff;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:focus {
|
||||
box-shadow: 0 0 0 1px rgba(87, 85, 217, .2);
|
||||
}
|
134
frontend/sass/commento.scss
Normal file
134
frontend/sass/commento.scss
Normal file
@ -0,0 +1,134 @@
|
||||
#commento {
|
||||
font-family: "Source Sans Pro", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #50596c;
|
||||
overflow-x: hidden;
|
||||
text-rendering: optimizeLegibility;
|
||||
padding: 8px;
|
||||
|
||||
@import "colors-main.scss";
|
||||
@import "common-main.scss";
|
||||
|
||||
@import "commento-tags.scss";
|
||||
@import "commento-logo.scss";
|
||||
@import "commento-input.scss";
|
||||
@import "commento-logged.scss";
|
||||
@import "commento-buttons.scss";
|
||||
|
||||
.commento-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.commento-error-box {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
color: $red-7;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.commento-moderation-notice {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
color: $orange-7;
|
||||
font-weight: bold;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.commento-dark-card {
|
||||
background: $blue-1;
|
||||
}
|
||||
|
||||
.commento-card {
|
||||
padding: 12px 0px 0px 12px;
|
||||
margin-top: 16px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
|
||||
.commento-header {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.commento-avatar {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
font-size: 22px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
border: 1px solid #fff;
|
||||
box-shadow: 0px 0px 0px 2px #f00;
|
||||
}
|
||||
|
||||
.commento-avatar-img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.commento-avatar::after {
|
||||
content:"";
|
||||
display:block;
|
||||
}
|
||||
|
||||
.commento-name {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
border: none;
|
||||
display: block;
|
||||
z-index: 1;
|
||||
margin-left: 48px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.commento-subtitle {
|
||||
display: block;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-left: 48px;
|
||||
}
|
||||
|
||||
.commento-score {
|
||||
display: inline;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.commento-score::before {
|
||||
content: "\00a0 \00a0 \00b7 \00a0 \00a0";
|
||||
}
|
||||
|
||||
.commento-body {
|
||||
p {
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.commento-options {
|
||||
float: right;
|
||||
position: relative;
|
||||
height: 38px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.commento-moderation {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user