You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
isso/isso/js/app/isso.js

329 lines
11 KiB

/* Isso Ich schrei sonst!
*/
define(["app/dom", "app/utils", "app/config", "app/api", "app/jade", "app/i18n", "app/lib", "app/globals"],
function($, utils, config, api, jade, i18n, lib, globals) {
"use strict";
var Postbox = function(parent) {
if (config['auth'] === true) {
var authCookie = utils.cookie('auth');
if (! authCookie) {
jade.set("cookie", {'valid': false});
} else {
var authData = lib.itsdangerous(authCookie)
if (! authData) {
jade.set("cookie", {'valid': false});
} else {
jade.set("cookie", {'valid': true, 'data': authData});
}
}
}
var el = $.htmlify(jade.render("postbox"));
// callback on success (e.g. to toggle the reply button)
el.onsuccess = function() {};
el.validate = function() {
if (utils.text($(".textarea", this).innerHTML).length < 3 ||
$(".textarea", this).classList.contains("placeholder"))
{
$(".textarea", this).focus();
return false;
}
return true;
};
// submit form, initialize optional fields with `null` and reset form.
// If replied to a comment, remove form completely.
var submit = $("[type=submit]", el)
if (submit === null) {
return el;
}
submit.on("click", function() {
if (! el.validate()) {
return;
}
api.create($("#isso-thread").getAttribute("data-isso-id"), {
author: $("[name=author]", el).value || null,
email: $("[name=email]", el).value || null,
10 years ago
website: $("[name=website]", el).value || null,
text: utils.text($(".textarea", el).innerHTML),
parent: parent || null
}).then(function(comment) {
$("[name=author]", el).value = "";
$("[name=email]", el).value = "";
10 years ago
$("[name=website]", el).value = "";
$(".textarea", el).innerHTML = "";
$(".textarea", el).blur();
insert(comment, true);
if (parent !== null) {
el.onsuccess();
}
});
});
lib.editorify($(".textarea", el));
return el;
};
var insert_loader = function(comment, lastcreated) {
var entrypoint;
if (comment.id === null) {
entrypoint = $("#isso-root");
comment.name = 'null';
} else {
entrypoint = $("#isso-" + comment.id + " > .text-wrapper > .isso-follow-up");
comment.name = comment.id;
}
var el = $.htmlify(jade.render("comment-loader", {"comment": comment}));
entrypoint.append(el);
$("a.load_hidden", el).on("click", function() {
el.remove();
api.fetch($("#isso-thread").getAttribute("data-isso-id"),
config["reveal-on-click"], config["max-comments-nested"],
comment.id,
lastcreated).then(
function(rv) {
if (rv.total_replies === 0) {
return;
}
var lastcreated = 0;
rv.replies.forEach(function(commentObject) {
insert(commentObject, false);
if(commentObject.created > lastcreated) {
lastcreated = commentObject.created;
}
});
if(rv.hidden_replies > 0) {
insert_loader(rv, lastcreated);
}
},
function(err) {
console.log(err);
});
});
};
var insert = function(comment, scrollIntoView) {
var el = $.htmlify(jade.render("comment", {"comment": comment}));
// update datetime every 60 seconds
var refresh = function() {
$(".permalink > date", el).textContent = utils.ago(
globals.offset.localTime(), new Date(parseInt(comment.created, 10) * 1000));
setTimeout(refresh, 60*1000);
};
// run once to activate
refresh();
if (config["avatar"]) {
$("div.avatar > svg", el).replace(lib.identicons.generate(comment.hash, 4, 48));
}
var entrypoint;
if (comment.parent === null) {
entrypoint = $("#isso-root");
} else {
entrypoint = $("#isso-" + comment.parent + " > .text-wrapper > .isso-follow-up");
}
entrypoint.append(el);
11 years ago
if (scrollIntoView) {
el.scrollIntoView();
11 years ago
}
var footer = $("#isso-" + comment.id + " > .text-wrapper > .isso-comment-footer"),
header = $("#isso-" + comment.id + " > .text-wrapper > .isso-comment-header"),
text = $("#isso-" + comment.id + " > .text-wrapper > .text");
var form = null; // XXX: probably a good place for a closure
$("a.reply", footer).toggle("click",
function(toggler) {
form = footer.insertAfter(new Postbox(comment.parent === null ? comment.id : comment.parent));
form.onsuccess = function() { toggler.next(); };
$(".textarea", form).focus();
$("a.reply", footer).textContent = i18n.translate("comment-close");
},
function() {
form.remove();
$("a.reply", footer).textContent = i18n.translate("comment-reply");
}
);
// update vote counter, but hide if votes sum to 0
var votes = function(value) {
var span = $("span.votes", footer);
if (span === null && value !== 0) {
footer.prepend($.new("span.votes", value));
} else {
if (value === 0) {
span.remove();
} else {
span.textContent = value;
}
}
};
$("a.upvote", footer).on("click", function() {
api.like(comment.id).then(function(rv) {
votes(rv.likes - rv.dislikes);
});
});
$("a.downvote", footer).on("click", function() {
api.dislike(comment.id).then(function(rv) {
votes(rv.likes - rv.dislikes);
});
});
$("a.edit", footer).toggle("click",
function(toggler) {
var edit = $("a.edit", footer);
var avatar = $(".avatar", el, false)[0];
edit.textContent = i18n.translate("comment-save");
edit.insertAfter($.new("a.cancel", i18n.translate("comment-cancel"))).on("click", function() {
toggler.canceled = true;
toggler.next();
});
toggler.canceled = false;
api.view(comment.id, 1).then(function(rv) {
var textarea = lib.editorify($.new("div.textarea"));
textarea.innerHTML = utils.detext(rv.text);
textarea.focus();
text.classList.remove("text");
text.classList.add("textarea-wrapper");
text.textContent = "";
text.append(textarea);
});
if (avatar !== null) {
avatar.hide();
}
},
function(toggler) {
var textarea = $(".textarea", text);
var avatar = $(".avatar", el, false)[0];
if (! toggler.canceled && textarea !== null) {
if (utils.text(textarea.innerHTML).length < 3) {
textarea.focus();
toggler.wait();
return;
} else {
api.modify(comment.id, {"text": utils.text(textarea.innerHTML)}).then(function(rv) {
text.innerHTML = rv.text;
comment.text = rv.text;
});
}
} else {
text.innerHTML = comment.text;
}
text.classList.remove("textarea-wrapper");
text.classList.add("text");
if (avatar !== null) {
avatar.show();
}
$("a.cancel", footer).remove();
$("a.edit", footer).textContent = i18n.translate("comment-edit");
}
);
$("a.delete", footer).toggle("click",
function(toggler) {
var del = $("a.delete", footer);
var state = ! toggler.state;
del.textContent = i18n.translate("comment-confirm");
del.on("mouseout", function() {
del.textContent = i18n.translate("comment-delete");
toggler.state = state;
del.onmouseout = null;
});
},
function() {
var del = $("a.delete", footer);
api.remove(comment.id).then(function(rv) {
if (rv) {
el.remove();
} else {
$("span.note", header).textContent = i18n.translate("comment-deleted");
11 years ago
text.innerHTML = "<p>&nbsp;</p>";
$("a.edit", footer).remove();
$("a.delete", footer).remove();
}
del.textContent = i18n.translate("comment-delete");
});
}
);
// remove edit and delete buttons when cookie is gone
var clear = function(button) {
if (! utils.cookie("isso-" + comment.id)) {
if ($(button, footer) !== null) {
$(button, footer).remove();
}
} else {
setTimeout(function() { clear(button); }, 15*1000);
}
};
clear("a.edit");
clear("a.delete");
// show direct reply to own comment when cookie is max aged
var show = function(el) {
if (utils.cookie("isso-" + comment.id)) {
setTimeout(function() { show(el); }, 15*1000);
} else {
footer.append(el);
}
};
if (! config["reply-to-self"] && utils.cookie("isso-" + comment.id)) {
show($("a.reply", footer).detach());
}
if(comment.hasOwnProperty('replies')) {
var lastcreated = 0;
comment.replies.forEach(function(replyObject) {
insert(replyObject, false);
if(replyObject.created > lastcreated) {
lastcreated = replyObject.created;
}
});
if(comment.hidden_replies > 0) {
insert_loader(comment, lastcreated);
}
}
};
return {
insert: insert,
insert_loader: insert_loader,
Postbox: Postbox
};
});