1
mirror of https://gitlab.com/commento/commento.git synced 2025-06-29 22:56:37 -04:00

frontend: check in html, css, js

This commit is contained in:
Adhityaa
2018-06-03 21:36:17 +05:30
parent 5b7b97a4bf
commit a88dea879b
38 changed files with 3153 additions and 4 deletions

View File

@ -0,0 +1,11 @@
(function (global, document) {
// Prefills the email field from the URL parameter.
global.prefillEmail = function() {
if (paramGet("email") != undefined) {
$("#email").val(paramGet("email"));
$("#password").click();
}
};
} (window, document));

10
frontend/js/chartist.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,41 @@
(function (global, document) {
// Opens the danger zone.
global.dangerOpen = function() {
$(".view").hide();
$("#danger-view").show();
};
// Deletes a domain.
global.domainDeleteHandler = function() {
var data = global.dashboard.$data;
domainDelete(data.domains[data.cd].domain, function(success) {
if (success)
document.location = '/dashboard';
});
}
// Freezes a domain.
global.domainFreezeHandler = function() {
var data = global.dashboard.$data;
data.domains[data.cd].state = "frozen"
domainUpdate(data.domains[data.cd])
document.location.hash = "#modal-close";
}
// Unfreezes a domain.
global.domainUnfreezeHandler = function() {
var data = global.dashboard.$data;
data.domains[data.cd].state = "unfrozen"
domainUpdate(data.domains[data.cd])
document.location.hash = "#modal-close";
}
} (window, document));

View File

@ -0,0 +1,144 @@
(function (global, document) {
// Selects a domain.
global.domainSelect = function(domain) {
var data = global.dashboard.$data;
var domains = data.domains;
for (var i = 0; i < domains.length; i++) {
if (domains[i].domain == domain) {
vs("frozen", domains[i].state == "frozen");
domains[i].selected = true;
data.cd = i;
data.importedComments = domains[i].importedComments;
}
else
domains[i].selected = false;
}
data.showSettings = true;
settingDeselectAll();
$(".view").hide();
};
// Deselects all domains.
global.domainDeselectAll = function() {
var data = global.dashboard.$data;
var domains = data.domains;
for (var i = 0; i < domains.length; i++)
domains[i].selected = false;
}
// Creates a new domain.
global.domainNewHandler = function() {
var json = {
session: global.cookieGet("session"),
name: $("#new-domain-name").val(),
domain: $("#new-domain-domain").val(),
}
global.buttonDisable("#add-site-button");
global.post(global.origin + "/api/domain/new", json, function(resp) {
global.buttonEnable("#add-site-button");
$("#new-domain-name").val("");
$("#new-domain-domain").val("");
document.location.hash = "#modal-close";
if (!resp.success) {
global.globalErrorShow(resp.message);
return;
}
global.domainRefresh(function() {
global.domainSelect(resp.domain);
global.domainDeselectAll();
global.settingSelect("installation");
});
});
}
// Refreshes the list of domains.
global.domainRefresh = function(callback) {
var json = {
session: global.cookieGet("session"),
};
global.post(global.origin + "/api/domain/list", json, function(resp) {
if (!resp.success) {
global.globalErrorShow(resp.message);
return;
}
resp.domains = resp.domains.sort(function(a, b) {
var x = a.creationDate; var y = b.creationDate;
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
for (var i = 0; i < resp.domains.length; i++) {
resp.domains[i].show = true;
resp.domains[i].selected = false;
resp.domains[i].origName = resp.domains[i].name;
resp.domains[i].origDomain = resp.domains[i].domain;
resp.domains[i].viewsLast30Days = global.numberify(0);
resp.domains[i].commentsLast30Days = global.numberify(0);
for (var j = 0; j < resp.domains[i].moderators.length; j++) {
resp.domains[i].moderators[j].timeAgo = global.timeSince(
Date.parse(resp.domains[i].moderators[j].addDate));
}
}
global.vs("domains", resp.domains);
if (callback !== undefined)
callback();
});
};
// Updates a domain with the backend.
global.domainUpdate = function(domain, callback) {
var json = {
session: global.cookieGet("session"),
domain: domain,
};
global.post(global.origin + "/api/domain/update", json, function(resp) {
if (callback !== undefined)
callback(resp.success);
if (!resp.success) {
global.globalErrorShow(resp.message);
return;
}
});
}
// Deletes a domain.
global.domainDelete = function(domain, callback) {
var json = {
session: global.cookieGet("session"),
domain: domain,
};
global.post(global.origin + "/api/domain/delete", json, function(resp) {
if (!resp.success) {
global.globalErrorShow(resp.message);
return;
}
if (callback !== undefined)
callback(resp.success);
});
}
} (window, document));

View File

@ -0,0 +1,19 @@
(function (global, document) {
// Opens the general settings window.
global.generalOpen = function() {
$(".view").hide();
$("#general-view").show();
};
global.generalSaveHandler = function() {
var data = global.dashboard.$data;
global.buttonDisable("#save-general-button");
global.domainUpdate(data.domains[data.cd], function() {
global.globalOKShow("Settings saved!");
global.buttonEnable("#save-general-button");
});
};
} (window, document));

View File

@ -0,0 +1,33 @@
(function (global, document) {
// Opens the import window.
global.importOpen = function() {
$(".view").hide();
$("#import-view").show();
}
global.importDisqus = function() {
var url = $("#disqus-url").val();
var data = global.dashboard.$data;
var json = {
session: global.cookieGet("session"),
domain: data.domains[data.cd].domain,
url: url,
}
global.buttonDisable("#disqus-import-button");
global.post(global.origin + "/api/import/disqus", json, function(resp) {
global.buttonEnable("#disqus-import-button");
if (!resp.success) {
global.globalErrorShow(resp.message);
return;
}
globalOKShow("Imported " + resp.numImported + " comments!");
});
}
} (window, document));

View File

@ -0,0 +1,22 @@
(function (global, document) {
// Opens the installation view.
global.installationOpen = function() {
var data = global.dashboard.$data;
var html = '' +
'<div id="commento"></div>\n' +
'<script src="' + window.cdn + '/js/commento.js"><\/script>\n' +
'';
$("#code-div").text(html);
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
$(".view").hide();
$("#installation-view").show();
};
} (window, document));

View File

@ -0,0 +1,82 @@
(function (global, document) {
// Opens the moderatiosn settings window.
global.moderationOpen = function() {
$(".view").hide();
$("#moderation-view").show();
};
// Adds a moderator.
global.moderatorNewHandler = function() {
var data = global.dashboard.$data;
var email = $("#new-mod").val();
var json = {
session: global.cookieGet("session"),
domain: data.domains[data.cd].domain,
email: email,
}
var idx = -1;
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
if (data.domains[data.cd].moderators[i].email == email) {
idx = i;
break;
}
}
if (idx == -1) {
data.domains[data.cd].moderators.push({"email": email, "timeAgo": "just now"});
global.buttonDisable("#new-mod-button");
global.post(global.origin + "/api/domain/moderator/new", json, function(resp) {
global.buttonEnable("#new-mod-button");
if (!resp.success) {
global.globalErrorShow(resp.message);
return
}
global.globalOKShow("Added a new moderator!");
$("#new-mod").val("");
$("#new-mod").focus();
});
}
else {
global.globalErrorShow("Already a moderator.");
}
}
// Deletes a moderator.
global.moderatorDeleteHandler = function(email) {
var data = global.dashboard.$data;
var json = {
session: global.cookieGet("session"),
domain: data.domains[data.cd].domain,
email: email,
}
var idx = -1;
for (var i = 0; i < data.domains[data.cd].moderators.length; i++) {
if (data.domains[data.cd].moderators[i].email == email) {
idx = i;
break;
}
}
if (idx != -1) {
data.domains[data.cd].moderators.splice(idx, 1);
global.post(global.origin + "/api/domain/moderator/delete", json, function(resp) {
if (!resp.success) {
global.globalErrorShow(resp.message);
return
}
globalOKShow("Removed!");
});
}
}
} (window, document));

View File

@ -0,0 +1,46 @@
(function (global, document) {
// Sets the vue.js toggle to select and deselect panes visually.
function settingSelectCSS(id) {
var data = global.dashboard.$data;
var settings = data.settings;
for (var i = 0; i < settings.length; i++) {
if (settings[i].id == id) {
settings[i].selected = true;
}
else {
settings[i].selected = false;
}
}
}
// Selects a setting.
global.settingSelect = function(id) {
var data = global.dashboard.$data;
var settings = data.settings;
settingSelectCSS(id);
$("ul.tabs li").removeClass("current");
$(".content").removeClass("current");
$(".original").addClass("current");
for (var i = 0; i < settings.length; i++) {
if (id == settings[i].id)
settings[i].open();
}
};
// Deselects all settings.
global.settingDeselectAll = function() {
var data = global.dashboard.$data;
var settings = data.settings;
for (var i = 0; i < settings.length; i++)
settings[i].selected = false;
}
} (window, document));

View File

@ -0,0 +1,100 @@
(function (global, document) {
global.numberify = function(x) {
if (x == 0)
return {"zeros": "000", "num": "", "units": ""}
if (x < 10)
return {"zeros": "00", "num": x, "units": ""}
if (x < 100)
return {"zeros": "0", "num": x, "units": ""}
if (x < 1000)
return {"zeros": "", "num": x, "units": ""}
var res;
if (x < 1000000) {
res = numberify((x/1000).toFixed(0))
res.units = "K"
}
else if (x < 1000000000) {
res = numberify((x/1000000).toFixed(0))
res.units = "M"
}
else if (x < 1000000000000) {
res = numberify((x/1000000000).toFixed(0))
res.units = "B"
}
if (res.num*10 % 10 == 0)
res.num = Math.ceil(res.num);
return res;
}
global.statisticsOpen = function() {
var data = global.dashboard.$data;
var json = {
session: global.cookieGet("session"),
domain: data.domains[data.cd].domain,
}
$(".view").hide();
post(global.origin + "/api/domain/statistics", json, function(resp) {
$("#statistics-view").show();
if (!resp.success) {
globalErrorShow(resp.message);
return;
}
var options = {
showPoint: false,
axisY: {
onlyInteger: true,
showGrid: false,
},
axisX: {
showGrid: false,
},
showArea: true,
};
var views;
var comments;
views = resp.viewsLast30Days;
// views = [0, 1, 4, 16, 14, 12, 10, 25, 13, 5, 20, 25, 12, 57, 46, 64, 4, 36, 7, 80, 43, 86, 121, 6, 74, 94, 83, 73, 140, 89, 25];
comments = resp.commentsLast30Days;
// comments = [0, 0, 1, 2, 3, 3, 4, 5, 7, 8, 5, 9, 9, 5, 6, 7, 8, 3, 1, 16, 3, 10, 8, 5, 12, 5, 4, 8, 4, 23, 19];
var labels = new Array();
for (var i = 0; i < views.length; i++) {
if ((views.length-i) % 7 == 0) {
var x = (views.length-i)/7;
labels.push(x + " week" + (x > 1 ? "s" : "") + " ago");
}
else
labels.push("");
}
new Chartist.Line("#views-graph", {
labels: labels,
series: [views],
}, options);
new Chartist.Line("#comments-graph", {
labels: labels,
series: [comments],
}, options);
data.domains[data.cd].viewsLast30Days = numberify(views.reduce(function(a, b) { return a + b; }, 0));
data.domains[data.cd].commentsLast30Days = numberify(comments.reduce(function(a, b) { return a + b; }, 0));
});
}
} (window, document));

89
frontend/js/dashboard.js Normal file
View File

@ -0,0 +1,89 @@
(function (global, document) {
// Sets a vue.js field. Short for "vue set".
function vs(field, value) {
Vue.set(global.dashboard, field, value);
}
global.vs = vs;
// Sets the owner's name in the navbar.
global.navbarFill = function() {
$("#owner-name").text(global.owner.name);
};
// Constructs the vue.js object
global.vueConstruct = function(callback) {
var settings = [
{
"id": "installation",
"text": "Installation",
"meaning": "Install Commento with HTML",
"selected": false,
"open": installationOpen,
},
{
"id": "general",
"text": "General Settings",
"meaning": "Names, domains and the rest",
"selected": false,
"open": generalOpen,
},
{
"id": "moderation",
"text": "Moderation Settings",
"meaning": "Approve and delete comments",
"selected": false,
"open": moderationOpen,
},
{
"id": "statistics",
"text": "Statistics",
"meaning": "Usage and comment statistics",
"selected": false,
"open": statisticsOpen,
},
{
"id": "import",
"text": "Import Comments",
"meaning": "Import from a different service",
"selected": false,
"open": importOpen,
},
{
"id": "danger",
"text": "Danger Zone",
"meaning": "Delete or freeze domain",
"selected": false,
"open": dangerOpen,
},
];
var reactiveData = {
// list of panes; mutable because selection information is stored within
settings: settings,
// list of domains dynamically loaded; obviously mutable
domains: [{show: false, viewsLast30Days: global.numberify(0), commentsLast30Days: global.numberify(0), moderators: []}],
// whether or not to show the settings column; mutable because we do not
// show the column until a domain has been selected
showSettings: false,
// currently selected domain index; obviously mutable
cd: 0, // stands for "current domain"
};
global.dashboard = new Vue({
el: "#dashboard",
data: reactiveData,
});
if (callback !== undefined)
callback();
};
} (window, document));

31
frontend/js/errors.js Normal file
View File

@ -0,0 +1,31 @@
(function (global, document) {
// Registers a given ID for a fade out after 5 seconds.
global.registerHide = function(id) {
var el = $(id);
setTimeout(function() {
$(id).fadeOut("fast");
}, 5000);
}
// Shows a global message on the given label ID and registers it for hiding.
global.showGlobalMessage = function(id, text) {
global.textSet(id, text);
global.registerHide(id);
}
// Shows a global error message.
global.globalErrorShow = function(text) {
global.showGlobalMessage("#global-error", text);
}
// Shows a global success message.
global.globalOKShow = function(text) {
global.showGlobalMessage("#global-ok", text);
}
} (window, document));

3
frontend/js/highlight.js Normal file

File diff suppressed because one or more lines are too long

31
frontend/js/http.js Normal file
View File

@ -0,0 +1,31 @@
(function (global, document) {
// Performs a JSON POST request to the given url with the given data and
// calls the callback function with the JSON response.
global.post = function(url, json, callback) {
$.ajax({
url: url,
type: "POST",
data: JSON.stringify(json),
success: function(data) {
var resp = JSON.parse(data);
callback(resp);
},
});
}
// Performs a GET request and calls the callback function with the JSON
// response.
global.get = function(url, callback) {
$.ajax({
url: url,
type: "GET",
success: function(data) {
var resp = JSON.parse(data);
callback(resp);
},
});
}
} (window, document));

4
frontend/js/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

73
frontend/js/login.js Normal file
View File

@ -0,0 +1,73 @@
(function (global, document) {
// Shows messages produced from email confirmation attempts.
function displayConfirmedEmail() {
var confirmed = global.paramGet("confirmed");
if (confirmed == "true") {
$("#msg").html("Successfully confirmed! Login to continue.")
}
else if (confirmed == "false") {
$("#err").html("That link has expired.")
}
}
// Shows messages produced from password reset attempts.
function displayChangedPassword() {
var changed = paramGet("changed");
if (changed == "true") {
$("#msg").html("Password changed successfully! Login to continue.")
}
}
// Shows messages produced from completed signups.
function displaySignedUp() {
var signedUp = paramGet("signedUp");
if (signedUp == "true") {
$("#msg").html("Registration successful! Login to continue.")
}
}
// Shows email confirmation and password reset messages, if any.
global.displayMessages = function() {
displayConfirmedEmail();
displayChangedPassword();
displaySignedUp();
};
// Logs the user in and redirects to the dashboard.
global.login = function() {
var all_ok = global.unfilledMark(["#email", "#password"], function(el) {
el.css("border-bottom", "1px solid red");
});
if (!all_ok) {
global.textSet("#err", "Please make sure all fields are filled");
return;
}
var json = {
"email": $("#email").val(),
"password": $("#password").val(),
};
global.buttonDisable("#login-button");
global.post(global.origin + "/api/owner/login", json, function(resp) {
global.buttonEnable("#login-button");
if (!resp.success) {
global.textSet("#err", resp.message);
return;
}
global.cookieSet("session", resp.session);
document.location = "/dashboard";
});
};
} (window, document));

20
frontend/js/self.js Normal file
View File

@ -0,0 +1,20 @@
(function (global, document) {
// Get self details.
global.selfGet = function(callback) {
var json = {
"session": global.cookieGet("session"),
};
global.post(global.origin + "/api/owner/self", json, function(resp) {
if (!resp.success || !resp.loggedIn) {
document.location = "/login";
return;
}
global.owner = resp.owner;
callback();
});
};
}(window, document));

43
frontend/js/signup.js Normal file
View File

@ -0,0 +1,43 @@
(function (global, document) {
// Signs up the user and redirects to either the login page or the email
// confirmation, depending on whether or not SMTP is configured in the
// backend.
global.signup = function() {
if ($("#password").val() != $("#password2").val()) {
global.textSet("#err", "The two passwords don't match");
return;
}
var all_ok = unfilledMark(["#email", "#name", "#password", "#password2"], function(el) {
el.css("border-bottom", "1px solid red");
});
if (!all_ok) {
global.textSet("#err", "Please make sure all fields are filled");
return;
}
var json = {
"email": $("#email").val(),
"name": $("#name").val(),
"password": $("#password").val(),
};
global.buttonDisable("#signup-button");
post(global.origin + "/api/owner/new", json, function(resp) {
global.buttonEnable("#signup-button")
if (!resp.success) {
global.textSet("#err", resp.message);
return;
}
if (resp.confirmEmail)
document.location = "/confirm-email";
else
document.location = "/login?signedUp=true";
});
};
} (window, document));

108
frontend/js/utils.js Normal file
View File

@ -0,0 +1,108 @@
(function (global, document) {
// Gets a GET parameter in the current URL.
global.paramGet = function(param) {
var pageURL = decodeURIComponent(window.location.search.substring(1));
var urlVariables = pageURL.split('&');
for (var i = 0; i < urlVariables.length; i++) {
var paramURL = urlVariables[i].split('=');
if (paramURL[0] === param)
return paramURL[1] === undefined ? true : paramURL[1];
}
return null;
}
// Sets the disabled attribute in a button.
global.buttonDisable = function(id) {
var el = $(id);
el.attr("disabled", true);
}
// Unsets the disabled attribute in a button.
global.buttonEnable = function(id) {
var el = $(id);
el.attr("disabled", false);
}
// Sets the text on the given label ID.
global.textSet = function(id, text) {
var el = $(id);
el.show();
el.text(text);
}
// Given an array of input IDs, this function calls a callback function with
// the first unfilled ID.
global.unfilledMark = function(fields, callback) {
var all_ok = true;
for (var i = 0; i < fields.length; i++) {
var el = $(fields[i]);
if (el.val() == "") {
callback(el);
}
}
return all_ok;
}
// Gets the value of a cookie.
global.cookieGet = function(name) {
var c = "; " + document.cookie;
var x = c.split("; " + name + "=");
if (x.length == 2)
return x.pop().split(";").shift();
};
// Sets the value of a cookie.
global.cookieSet = function(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=/";
}
// Converts a date in the past to a human-friendly duration relative to now.
global.timeSince = function(date) {
var seconds = Math.floor((new Date() - date) / 1000);
var interval = Math.floor(seconds / 31536000);
if (interval > 1)
return interval + " years ago";
interval = Math.floor(seconds / 2592000);
if (interval > 1)
return interval + " months ago";
interval = Math.floor(seconds / 86400);
if (interval > 1)
return interval + " days ago";
interval = Math.floor(seconds / 3600);
if (interval > 1)
return interval + " hours ago";
interval = Math.floor(seconds / 60);
if (interval > 1)
return interval + " minutes ago";
if (seconds > 5)
return Math.floor(seconds) + " seconds ago";
else
return "just now";
}
} (window, document));

6
frontend/js/vue.js Normal file

File diff suppressed because one or more lines are too long