mirror of
https://github.com/thelounge/thelounge
synced 2024-11-26 22:10:22 +00:00
Merge pull request #1920 from thelounge/xpaw/more-eslint
Enforce padding-line-between-statements
This commit is contained in:
commit
1ce2792fc4
49 changed files with 161 additions and 0 deletions
|
@ -48,6 +48,18 @@ rules:
|
||||||
no-var: error
|
no-var: error
|
||||||
object-curly-spacing: [error, never]
|
object-curly-spacing: [error, never]
|
||||||
padded-blocks: [error, never]
|
padded-blocks: [error, never]
|
||||||
|
padding-line-between-statements:
|
||||||
|
- error
|
||||||
|
- blankLine: always
|
||||||
|
prev:
|
||||||
|
- block
|
||||||
|
- block-like
|
||||||
|
next: "*"
|
||||||
|
- blankLine: always
|
||||||
|
prev: "*"
|
||||||
|
next:
|
||||||
|
- block
|
||||||
|
- block-like
|
||||||
prefer-const: error
|
prefer-const: error
|
||||||
prefer-rest-params: error
|
prefer-rest-params: error
|
||||||
prefer-spread: error
|
prefer-spread: error
|
||||||
|
|
|
@ -50,6 +50,7 @@ const nicksStrategy = {
|
||||||
match: /\B(@([a-zA-Z_[\]\\^{}|`@][a-zA-Z0-9_[\]\\^{}|`-]*)?)$/,
|
match: /\B(@([a-zA-Z_[\]\\^{}|`@][a-zA-Z0-9_[\]\\^{}|`-]*)?)$/,
|
||||||
search(term, callback) {
|
search(term, callback) {
|
||||||
term = term.slice(1);
|
term = term.slice(1);
|
||||||
|
|
||||||
if (term[0] === "@") {
|
if (term[0] === "@") {
|
||||||
callback(completeNicks(term.slice(1), true)
|
callback(completeNicks(term.slice(1), true)
|
||||||
.map((val) => ["@" + val[0], "@" + val[1]]));
|
.map((val) => ["@" + val[0], "@" + val[1]]));
|
||||||
|
@ -122,6 +123,7 @@ const foregroundColorStrategy = {
|
||||||
post: "</b>",
|
post: "</b>",
|
||||||
}).rendered];
|
}).rendered];
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -150,6 +152,7 @@ const backgroundColorStrategy = {
|
||||||
post: "</b>",
|
post: "</b>",
|
||||||
}).rendered];
|
}).rendered];
|
||||||
}
|
}
|
||||||
|
|
||||||
return pair;
|
return pair;
|
||||||
})
|
})
|
||||||
.map((pair) => pair.concat(match[1])); // Needed to pass fg color to `template`...
|
.map((pair) => pair.concat(match[1])); // Needed to pass fg color to `template`...
|
||||||
|
@ -268,9 +271,11 @@ function completeNicks(word, isFuzzy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const words = users.data("nicks");
|
const words = users.data("nicks");
|
||||||
|
|
||||||
if (isFuzzy) {
|
if (isFuzzy) {
|
||||||
return fuzzyGrep(word, words);
|
return fuzzyGrep(word, words);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $.grep(
|
return $.grep(
|
||||||
words,
|
words,
|
||||||
(w) => !w.toLowerCase().indexOf(word)
|
(w) => !w.toLowerCase().indexOf(word)
|
||||||
|
@ -291,6 +296,7 @@ function completeChans(word) {
|
||||||
.find(".chan")
|
.find(".chan")
|
||||||
.each(function() {
|
.each(function() {
|
||||||
const self = $(this);
|
const self = $(this);
|
||||||
|
|
||||||
if (!self.hasClass("lobby")) {
|
if (!self.hasClass("lobby")) {
|
||||||
words.push(self.attr("aria-label"));
|
words.push(self.attr("aria-label"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ function updateText(condensed, addedTypes) {
|
||||||
});
|
});
|
||||||
|
|
||||||
let text = strings.pop();
|
let text = strings.pop();
|
||||||
|
|
||||||
if (strings.length) {
|
if (strings.length) {
|
||||||
text = strings.join(", ") + ", and " + text;
|
text = strings.join(", ") + ", and " + text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ sidebar.on("submit", ".join-form", function() {
|
||||||
const key = form.find("input[name='key']");
|
const key = form.find("input[name='key']");
|
||||||
const keyString = key.val();
|
const keyString = key.val();
|
||||||
const chan = utils.findCurrentNetworkChan(channelString);
|
const chan = utils.findCurrentNetworkChan(channelString);
|
||||||
|
|
||||||
if (chan.length) {
|
if (chan.length) {
|
||||||
chan.trigger("click");
|
chan.trigger("click");
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,6 +77,7 @@ sidebar.on("submit", ".join-form", function() {
|
||||||
target: form.prev().data("id"),
|
target: form.prev().data("id"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
closeForm(form.closest(".network"));
|
closeForm(form.closest(".network"));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Generates a string from "color-1" to "color-32" based on an input string
|
// Generates a string from "color-1" to "color-32" based on an input string
|
||||||
module.exports = function(str) {
|
module.exports = function(str) {
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
for (let i = 0; i < str.length; i++) {
|
||||||
hash += str.charCodeAt(i);
|
hash += str.charCodeAt(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ function fill(existingEntries, text) {
|
||||||
end: textSegment.start,
|
end: textSegment.start,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
position = textSegment.end;
|
position = textSegment.end;
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
@ -11,6 +11,7 @@ function findNames(text, users) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let match;
|
let match;
|
||||||
|
|
||||||
while ((match = nickRegExp.exec(text))) {
|
while ((match = nickRegExp.exec(text))) {
|
||||||
if (users.indexOf(match[1]) > -1) {
|
if (users.indexOf(match[1]) > -1) {
|
||||||
result.push({
|
result.push({
|
||||||
|
|
|
@ -46,6 +46,7 @@ function parseStyle(text) {
|
||||||
strikethrough = false;
|
strikethrough = false;
|
||||||
monospace = false;
|
monospace = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
resetStyle();
|
resetStyle();
|
||||||
|
|
||||||
// When called, this "closes" the current fragment by adding an entry to the
|
// When called, this "closes" the current fragment by adding an entry to the
|
||||||
|
@ -111,9 +112,11 @@ function parseStyle(text) {
|
||||||
|
|
||||||
if (colorCodes) {
|
if (colorCodes) {
|
||||||
textColor = Number(colorCodes[1]);
|
textColor = Number(colorCodes[1]);
|
||||||
|
|
||||||
if (colorCodes[2]) {
|
if (colorCodes[2]) {
|
||||||
bgColor = Number(colorCodes[2]);
|
bgColor = Number(colorCodes[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color code length is > 1, so bump the current position cursor by as
|
// Color code length is > 1, so bump the current position cursor by as
|
||||||
// much (and reset the start cursor for the current text block as well)
|
// much (and reset the start cursor for the current text block as well)
|
||||||
position += colorCodes[0].length;
|
position += colorCodes[0].length;
|
||||||
|
@ -123,6 +126,7 @@ function parseStyle(text) {
|
||||||
textColor = undefined;
|
textColor = undefined;
|
||||||
bgColor = undefined;
|
bgColor = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HEX_COLOR:
|
case HEX_COLOR:
|
||||||
|
@ -132,9 +136,11 @@ function parseStyle(text) {
|
||||||
|
|
||||||
if (colorCodes) {
|
if (colorCodes) {
|
||||||
hexColor = colorCodes[1].toUpperCase();
|
hexColor = colorCodes[1].toUpperCase();
|
||||||
|
|
||||||
if (colorCodes[2]) {
|
if (colorCodes[2]) {
|
||||||
hexBgColor = colorCodes[2].toUpperCase();
|
hexBgColor = colorCodes[2].toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color code length is > 1, so bump the current position cursor by as
|
// Color code length is > 1, so bump the current position cursor by as
|
||||||
// much (and reset the start cursor for the current text block as well)
|
// much (and reset the start cursor for the current text block as well)
|
||||||
position += colorCodes[0].length;
|
position += colorCodes[0].length;
|
||||||
|
@ -154,6 +160,7 @@ function parseStyle(text) {
|
||||||
textColor = tmp;
|
textColor = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ITALIC:
|
case ITALIC:
|
||||||
emitFragment();
|
emitFragment();
|
||||||
italic = !italic;
|
italic = !italic;
|
||||||
|
@ -194,12 +201,14 @@ function prepare(text) {
|
||||||
.reduce((prev, curr) => {
|
.reduce((prev, curr) => {
|
||||||
if (prev.length) {
|
if (prev.length) {
|
||||||
const lastEntry = prev[prev.length - 1];
|
const lastEntry = prev[prev.length - 1];
|
||||||
|
|
||||||
if (properties.every((key) => curr[key] === lastEntry[key])) {
|
if (properties.every((key) => curr[key] === lastEntry[key])) {
|
||||||
lastEntry.text += curr.text;
|
lastEntry.text += curr.text;
|
||||||
lastEntry.end += curr.text.length;
|
lastEntry.end += curr.text.length;
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev.concat([curr]);
|
return prev.concat([curr]);
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,24 +13,31 @@ const colorClass = require("./colorClass");
|
||||||
// Create an HTML `span` with styling information for a given fragment
|
// Create an HTML `span` with styling information for a given fragment
|
||||||
function createFragment(fragment) {
|
function createFragment(fragment) {
|
||||||
const classes = [];
|
const classes = [];
|
||||||
|
|
||||||
if (fragment.bold) {
|
if (fragment.bold) {
|
||||||
classes.push("irc-bold");
|
classes.push("irc-bold");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment.textColor !== undefined) {
|
if (fragment.textColor !== undefined) {
|
||||||
classes.push("irc-fg" + fragment.textColor);
|
classes.push("irc-fg" + fragment.textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment.bgColor !== undefined) {
|
if (fragment.bgColor !== undefined) {
|
||||||
classes.push("irc-bg" + fragment.bgColor);
|
classes.push("irc-bg" + fragment.bgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment.italic) {
|
if (fragment.italic) {
|
||||||
classes.push("irc-italic");
|
classes.push("irc-italic");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment.underline) {
|
if (fragment.underline) {
|
||||||
classes.push("irc-underline");
|
classes.push("irc-underline");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment.strikethrough) {
|
if (fragment.strikethrough) {
|
||||||
classes.push("irc-strikethrough");
|
classes.push("irc-strikethrough");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragment.monospace) {
|
if (fragment.monospace) {
|
||||||
classes.push("irc-monospace");
|
classes.push("irc-monospace");
|
||||||
}
|
}
|
||||||
|
@ -89,6 +96,7 @@ module.exports = function parse(text, users) {
|
||||||
if (intersection) {
|
if (intersection) {
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev.concat([curr]);
|
return prev.concat([curr]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
(function() {
|
(function() {
|
||||||
var displayReload = function displayReload() {
|
var displayReload = function displayReload() {
|
||||||
var loadingReload = document.getElementById("loading-reload");
|
var loadingReload = document.getElementById("loading-reload");
|
||||||
|
|
||||||
if (loadingReload) {
|
if (loadingReload) {
|
||||||
loadingReload.style.display = "block";
|
loadingReload.style.display = "block";
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ $(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const channel = target.closest(".chan");
|
const channel = target.closest(".chan");
|
||||||
|
|
||||||
if (utils.isOpInChannel(channel) && channel.data("type") === "channel") {
|
if (utils.isOpInChannel(channel) && channel.data("type") === "channel") {
|
||||||
output += templates.contextmenu_divider();
|
output += templates.contextmenu_divider();
|
||||||
output += templates.contextmenu_item({
|
output += templates.contextmenu_item({
|
||||||
|
@ -127,6 +128,7 @@ $(function() {
|
||||||
data: target.data("target"),
|
data: target.data("target"),
|
||||||
});
|
});
|
||||||
output += templates.contextmenu_divider();
|
output += templates.contextmenu_divider();
|
||||||
|
|
||||||
if (target.hasClass("lobby")) {
|
if (target.hasClass("lobby")) {
|
||||||
output += templates.contextmenu_item({
|
output += templates.contextmenu_item({
|
||||||
class: "list",
|
class: "list",
|
||||||
|
@ -141,6 +143,7 @@ $(function() {
|
||||||
data: target.data("id"),
|
data: target.data("id"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.hasClass("channel")) {
|
if (target.hasClass("channel")) {
|
||||||
output += templates.contextmenu_item({
|
output += templates.contextmenu_item({
|
||||||
class: "list",
|
class: "list",
|
||||||
|
@ -149,6 +152,7 @@ $(function() {
|
||||||
data: target.data("id"),
|
data: target.data("id"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
output += templates.contextmenu_item({
|
output += templates.contextmenu_item({
|
||||||
class: "close",
|
class: "close",
|
||||||
action: "close",
|
action: "close",
|
||||||
|
@ -213,6 +217,7 @@ $(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let focus = $.noop;
|
let focus = $.noop;
|
||||||
|
|
||||||
if (!("ontouchstart" in window || navigator.maxTouchPoints > 0)) {
|
if (!("ontouchstart" in window || navigator.maxTouchPoints > 0)) {
|
||||||
focus = function() {
|
focus = function() {
|
||||||
if (chat.find(".active").hasClass("chan")) {
|
if (chat.find(".active").hasClass("chan")) {
|
||||||
|
@ -250,6 +255,7 @@ $(function() {
|
||||||
if (text.charAt(0) === "/") {
|
if (text.charAt(0) === "/") {
|
||||||
const args = text.substr(1).split(" ");
|
const args = text.substr(1).split(" ");
|
||||||
const cmd = args.shift().toLowerCase();
|
const cmd = args.shift().toLowerCase();
|
||||||
|
|
||||||
if (typeof utils.inputCommands[cmd] === "function" && utils.inputCommands[cmd](args)) {
|
if (typeof utils.inputCommands[cmd] === "function" && utils.inputCommands[cmd](args)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -336,6 +342,7 @@ $(function() {
|
||||||
const openWindow = function openWindow(e, data) {
|
const openWindow = function openWindow(e, data) {
|
||||||
const self = $(this);
|
const self = $(this);
|
||||||
const target = self.data("target");
|
const target = self.data("target");
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -397,13 +404,16 @@ $(function() {
|
||||||
|
|
||||||
let title = $(document.body).data("app-name");
|
let title = $(document.body).data("app-name");
|
||||||
const chanTitle = chan.attr("aria-label");
|
const chanTitle = chan.attr("aria-label");
|
||||||
|
|
||||||
if (chanTitle.length > 0) {
|
if (chanTitle.length > 0) {
|
||||||
title = `${chanTitle} — ${title}`;
|
title = `${chanTitle} — ${title}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = title;
|
document.title = title;
|
||||||
|
|
||||||
const type = chan.data("type");
|
const type = chan.data("type");
|
||||||
let placeholder = "";
|
let placeholder = "";
|
||||||
|
|
||||||
if (type === "channel" || type === "query") {
|
if (type === "channel" || type === "query") {
|
||||||
placeholder = `Write to ${chanTitle}`;
|
placeholder = `Write to ${chanTitle}`;
|
||||||
}
|
}
|
||||||
|
@ -418,6 +428,7 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const chanChat = chan.find(".chat");
|
const chanChat = chan.find(".chat");
|
||||||
|
|
||||||
if (chanChat.length > 0 && type !== "special") {
|
if (chanChat.length > 0 && type !== "special") {
|
||||||
chanChat.sticky();
|
chanChat.sticky();
|
||||||
}
|
}
|
||||||
|
@ -446,6 +457,7 @@ $(function() {
|
||||||
if (data && data.pushState === false) {
|
if (data && data.pushState === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = {};
|
const state = {};
|
||||||
|
|
||||||
if (self.prop("id")) {
|
if (self.prop("id")) {
|
||||||
|
@ -486,10 +498,12 @@ $(function() {
|
||||||
if (chan.hasClass("lobby")) {
|
if (chan.hasClass("lobby")) {
|
||||||
cmd = "/quit";
|
cmd = "/quit";
|
||||||
const server = chan.find(".name").html();
|
const server = chan.find(".name").html();
|
||||||
|
|
||||||
if (!confirm("Disconnect from " + server + "?")) { // eslint-disable-line no-alert
|
if (!confirm("Disconnect from " + server + "?")) { // eslint-disable-line no-alert
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.emit("input", {
|
socket.emit("input", {
|
||||||
target: chan.data("id"),
|
target: chan.data("id"),
|
||||||
text: cmd,
|
text: cmd,
|
||||||
|
@ -602,6 +616,7 @@ $(function() {
|
||||||
if ($("body").hasClass("public") && (window.location.hash === "#connect" || window.location.hash === "")) {
|
if ($("body").hasClass("public") && (window.location.hash === "#connect" || window.location.hash === "")) {
|
||||||
$("#connect").one("show", function() {
|
$("#connect").one("show", function() {
|
||||||
const params = URI(document.location.search).search(true);
|
const params = URI(document.location.search).search(true);
|
||||||
|
|
||||||
// Possible parameters: name, host, port, password, tls, nick, username, realname, join
|
// Possible parameters: name, host, port, password, tls, nick, username, realname, join
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Iterating_over_own_properties_only
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Iterating_over_own_properties_only
|
||||||
for (let key in params) {
|
for (let key in params) {
|
||||||
|
@ -611,6 +626,7 @@ $(function() {
|
||||||
key = key.replace(/\W/g, "");
|
key = key.replace(/\W/g, "");
|
||||||
|
|
||||||
const element = $("#connect input[name='" + key + "']");
|
const element = $("#connect input[name='" + key + "']");
|
||||||
|
|
||||||
// if the element exists, it isn't disabled, and it isn't hidden
|
// if the element exists, it isn't disabled, and it isn't hidden
|
||||||
if (element.length > 0 && !element.is(":disabled") && !element.is(":hidden")) {
|
if (element.length > 0 && !element.is(":disabled") && !element.is(":hidden")) {
|
||||||
if (element.is(":checkbox")) {
|
if (element.is(":checkbox")) {
|
||||||
|
@ -647,10 +663,12 @@ $(function() {
|
||||||
// This should always be 24h later but re-computing exact value just in case
|
// This should always be 24h later but re-computing exact value just in case
|
||||||
setTimeout(updateDateMarkers, msUntilNextDay());
|
setTimeout(updateDateMarkers, msUntilNextDay());
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(updateDateMarkers, msUntilNextDay());
|
setTimeout(updateDateMarkers, msUntilNextDay());
|
||||||
|
|
||||||
window.addEventListener("popstate", (e) => {
|
window.addEventListener("popstate", (e) => {
|
||||||
const {state} = e;
|
const {state} = e;
|
||||||
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ module.exports.initialize = () => {
|
||||||
if (Notification.permission === "default" && desktopNotificationsCheckbox.prop("checked")) {
|
if (Notification.permission === "default" && desktopNotificationsCheckbox.prop("checked")) {
|
||||||
desktopNotificationsCheckbox.prop("checked", false);
|
desktopNotificationsCheckbox.prop("checked", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
desktopNotificationsCheckbox.prop("disabled", false);
|
desktopNotificationsCheckbox.prop("disabled", false);
|
||||||
warningBlocked.hide();
|
warningBlocked.hide();
|
||||||
}
|
}
|
||||||
|
@ -148,6 +149,7 @@ module.exports.initialize = () => {
|
||||||
const highlightsTokens = options.highlights.map(function(h) {
|
const highlightsTokens = options.highlights.map(function(h) {
|
||||||
return escapeRegExp(h);
|
return escapeRegExp(h);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (highlightsTokens && highlightsTokens.length) {
|
if (highlightsTokens && highlightsTokens.length) {
|
||||||
module.exports.highlightsRE = new RegExp("\\b(?:" + highlightsTokens.join("|") + ")\\b", "i");
|
module.exports.highlightsRE = new RegExp("\\b(?:" + highlightsTokens.join("|") + ")\\b", "i");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -141,19 +141,23 @@ function openImageViewer(link, {pushState = true} = {}) {
|
||||||
// Previous image
|
// Previous image
|
||||||
let previousImage = link.closest(".preview").prev(".preview")
|
let previousImage = link.closest(".preview").prev(".preview")
|
||||||
.find(".toggle-content.show .toggle-thumbnail").last();
|
.find(".toggle-content.show .toggle-thumbnail").last();
|
||||||
|
|
||||||
if (!previousImage.length) {
|
if (!previousImage.length) {
|
||||||
previousImage = link.closest(".msg").prevAll()
|
previousImage = link.closest(".msg").prevAll()
|
||||||
.find(".toggle-content.show .toggle-thumbnail").last();
|
.find(".toggle-content.show .toggle-thumbnail").last();
|
||||||
}
|
}
|
||||||
|
|
||||||
previousImage.addClass("previous-image");
|
previousImage.addClass("previous-image");
|
||||||
|
|
||||||
// Next image
|
// Next image
|
||||||
let nextImage = link.closest(".preview").next(".preview")
|
let nextImage = link.closest(".preview").next(".preview")
|
||||||
.find(".toggle-content.show .toggle-thumbnail").first();
|
.find(".toggle-content.show .toggle-thumbnail").first();
|
||||||
|
|
||||||
if (!nextImage.length) {
|
if (!nextImage.length) {
|
||||||
nextImage = link.closest(".msg").nextAll()
|
nextImage = link.closest(".msg").nextAll()
|
||||||
.find(".toggle-content.show .toggle-thumbnail").first();
|
.find(".toggle-content.show .toggle-thumbnail").first();
|
||||||
}
|
}
|
||||||
|
|
||||||
nextImage.addClass("next-image");
|
nextImage.addClass("next-image");
|
||||||
|
|
||||||
imageViewer.html(templates.image_viewer({
|
imageViewer.html(templates.image_viewer({
|
||||||
|
@ -173,12 +177,14 @@ function openImageViewer(link, {pushState = true} = {}) {
|
||||||
// History management
|
// History management
|
||||||
if (pushState) {
|
if (pushState) {
|
||||||
let clickTarget = "";
|
let clickTarget = "";
|
||||||
|
|
||||||
// Images can be in a message (channel URL previews) or not (window URL
|
// Images can be in a message (channel URL previews) or not (window URL
|
||||||
// preview, e.g. changelog). This is sub-optimal and needs improvement to
|
// preview, e.g. changelog). This is sub-optimal and needs improvement to
|
||||||
// make image preview more generic and not specific for channel previews.
|
// make image preview more generic and not specific for channel previews.
|
||||||
if (link.closest(".msg").length > 0) {
|
if (link.closest(".msg").length > 0) {
|
||||||
clickTarget = `#${link.closest(".msg").prop("id")} `;
|
clickTarget = `#${link.closest(".msg").prop("id")} `;
|
||||||
}
|
}
|
||||||
|
|
||||||
clickTarget += `a.toggle-thumbnail[href="${link.prop("href")}"] img`;
|
clickTarget += `a.toggle-thumbnail[href="${link.prop("href")}"] img`;
|
||||||
history.pushState({clickTarget}, null, null);
|
history.pushState({clickTarget}, null, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ const socket = require("../socket");
|
||||||
|
|
||||||
socket.on("change-password", function(data) {
|
socket.on("change-password", function(data) {
|
||||||
const passwordForm = $("#change-password");
|
const passwordForm = $("#change-password");
|
||||||
|
|
||||||
if (data.error || data.success) {
|
if (data.error || data.success) {
|
||||||
const message = data.success ? data.success : data.error;
|
const message = data.success ? data.success : data.error;
|
||||||
const feedback = passwordForm.find(".feedback");
|
const feedback = passwordForm.find(".feedback");
|
||||||
|
|
|
@ -24,6 +24,7 @@ socket.on("more", function(data) {
|
||||||
// Remove the date-change marker we put at the top, because it may
|
// Remove the date-change marker we put at the top, because it may
|
||||||
// not actually be a date change now
|
// not actually be a date change now
|
||||||
const children = $(chan).children();
|
const children = $(chan).children();
|
||||||
|
|
||||||
if (children.eq(0).hasClass("date-marker-container")) { // Check top most child
|
if (children.eq(0).hasClass("date-marker-container")) { // Check top most child
|
||||||
children.eq(0).remove();
|
children.eq(0).remove();
|
||||||
} else if (children.eq(1).hasClass("date-marker-container")) {
|
} else if (children.eq(1).hasClass("date-marker-container")) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ const chat = $("#chat");
|
||||||
const sidebar = $("#sidebar");
|
const sidebar = $("#sidebar");
|
||||||
|
|
||||||
let pop;
|
let pop;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pop = new Audio();
|
pop = new Audio();
|
||||||
pop.src = "audio/pop.ogg";
|
pop.src = "audio/pop.ogg";
|
||||||
|
@ -69,6 +70,7 @@ function processReceivedMessage(data) {
|
||||||
notifyMessage(targetId, channel, data);
|
notifyMessage(targetId, channel, data);
|
||||||
|
|
||||||
const lastVisible = container.find("div:visible").last();
|
const lastVisible = container.find("div:visible").last();
|
||||||
|
|
||||||
if (data.msg.self
|
if (data.msg.self
|
||||||
|| lastVisible.hasClass("unread-marker")
|
|| lastVisible.hasClass("unread-marker")
|
||||||
|| (lastVisible.hasClass("date-marker")
|
|| (lastVisible.hasClass("date-marker")
|
||||||
|
@ -100,8 +102,10 @@ function processReceivedMessage(data) {
|
||||||
|
|
||||||
if ((data.msg.type === "message" || data.msg.type === "action") && channel.hasClass("channel")) {
|
if ((data.msg.type === "message" || data.msg.type === "action") && channel.hasClass("channel")) {
|
||||||
const nicks = channel.find(".users").data("nicks");
|
const nicks = channel.find(".users").data("nicks");
|
||||||
|
|
||||||
if (nicks) {
|
if (nicks) {
|
||||||
const find = nicks.indexOf(data.msg.from.nick);
|
const find = nicks.indexOf(data.msg.from.nick);
|
||||||
|
|
||||||
if (find !== -1) {
|
if (find !== -1) {
|
||||||
nicks.splice(find, 1);
|
nicks.splice(find, 1);
|
||||||
nicks.unshift(data.msg.from.nick);
|
nicks.unshift(data.msg.from.nick);
|
||||||
|
@ -119,6 +123,7 @@ function notifyMessage(targetId, channel, msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = sidebar.find(".chan[data-id='" + targetId + "']");
|
const button = sidebar.find(".chan[data-id='" + targetId + "']");
|
||||||
|
|
||||||
if (msg.highlight || (options.notifyAllMessages && msg.type === "message")) {
|
if (msg.highlight || (options.notifyAllMessages && msg.type === "message")) {
|
||||||
if (!document.hasFocus() || !channel.hasClass("active")) {
|
if (!document.hasFocus() || !channel.hasClass("active")) {
|
||||||
if (options.notification) {
|
if (options.notification) {
|
||||||
|
@ -140,12 +145,15 @@ function notifyMessage(targetId, channel, msg) {
|
||||||
body = msg.from.nick + " invited you to " + msg.channel;
|
body = msg.from.nick + " invited you to " + msg.channel;
|
||||||
} else {
|
} else {
|
||||||
title = msg.from.nick;
|
title = msg.from.nick;
|
||||||
|
|
||||||
if (!button.hasClass("query")) {
|
if (!button.hasClass("query")) {
|
||||||
title += " (" + button.attr("aria-label").trim() + ")";
|
title += " (" + button.attr("aria-label").trim() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type === "message") {
|
if (msg.type === "message") {
|
||||||
title += " says:";
|
title += " says:";
|
||||||
}
|
}
|
||||||
|
|
||||||
body = cleanIrcMessage(msg.text);
|
body = cleanIrcMessage(msg.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ socket.on("nick", function(data) {
|
||||||
const id = data.network;
|
const id = data.network;
|
||||||
const nick = data.nick;
|
const nick = data.nick;
|
||||||
const network = sidebar.find("#network-" + id).data("nick", nick);
|
const network = sidebar.find("#network-" + id).data("nick", nick);
|
||||||
|
|
||||||
if (network.find(".active").length) {
|
if (network.find(".active").length) {
|
||||||
utils.setNick(nick);
|
utils.setNick(nick);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,10 @@ function expand() {
|
||||||
|
|
||||||
function join(args) {
|
function join(args) {
|
||||||
const channel = args[0];
|
const channel = args[0];
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
const chan = findCurrentNetworkChan(channel);
|
const chan = findCurrentNetworkChan(channel);
|
||||||
|
|
||||||
if (chan.length) {
|
if (chan.length) {
|
||||||
chan.trigger("click");
|
chan.trigger("click");
|
||||||
}
|
}
|
||||||
|
@ -113,10 +115,12 @@ function confirmExit() {
|
||||||
function move(array, old_index, new_index) {
|
function move(array, old_index, new_index) {
|
||||||
if (new_index >= array.length) {
|
if (new_index >= array.length) {
|
||||||
let k = new_index - array.length;
|
let k = new_index - array.length;
|
||||||
|
|
||||||
while ((k--) + 1) {
|
while ((k--) + 1) {
|
||||||
this.push(undefined);
|
this.push(undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
array.splice(new_index, 0, array.splice(old_index, 1)[0]);
|
array.splice(new_index, 0, array.splice(old_index, 1)[0]);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ module.exports = requireViews.keys().reduce((acc, path) => {
|
||||||
} else {
|
} else {
|
||||||
tmp[key] = tmp[key] || {};
|
tmp[key] = tmp[key] || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = tmp[key];
|
tmp = tmp[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
1
index.js
1
index.js
|
@ -9,6 +9,7 @@ process.chdir(__dirname);
|
||||||
// other issues
|
// other issues
|
||||||
// Try to display messages nicely, but gracefully degrade if anything goes wrong
|
// Try to display messages nicely, but gracefully degrade if anything goes wrong
|
||||||
const pkg = require("./package.json");
|
const pkg = require("./package.json");
|
||||||
|
|
||||||
if (!require("semver").satisfies(process.version, pkg.engines.node)) {
|
if (!require("semver").satisfies(process.version, pkg.engines.node)) {
|
||||||
let colors;
|
let colors;
|
||||||
let log;
|
let log;
|
||||||
|
|
|
@ -397,6 +397,7 @@ function pullRequestNumbersInCommits(commits) {
|
||||||
if (pullRequestId) {
|
if (pullRequestId) {
|
||||||
array.push(pullRequestId);
|
array.push(pullRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
@ -439,6 +440,7 @@ function printLine(entry) {
|
||||||
if (entry.title) {
|
if (entry.title) {
|
||||||
return printPullRequest(entry);
|
return printPullRequest(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return printCommit(entry);
|
return printCommit(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,6 +571,7 @@ function parse(entries) {
|
||||||
if (!result[dependencyType][packageName]) {
|
if (!result[dependencyType][packageName]) {
|
||||||
result[dependencyType][packageName] = [];
|
result[dependencyType][packageName] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
result[dependencyType][packageName].push(entry);
|
result[dependencyType][packageName].push(entry);
|
||||||
} else {
|
} else {
|
||||||
log.info(`${colors.bold(packageName)} was updated in ${colors.green("#" + entry.number)} then removed since last release. Skipping.`);
|
log.info(`${colors.bold(packageName)} was updated in ${colors.green("#" + entry.number)} then removed since last release. Skipping.`);
|
||||||
|
@ -591,6 +594,7 @@ function parse(entries) {
|
||||||
result.uncategorized.other.push(entry);
|
result.uncategorized.other.push(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}, {
|
}, {
|
||||||
skipped: [],
|
skipped: [],
|
||||||
|
@ -616,6 +620,7 @@ function extractContributors(entries) {
|
||||||
if (pullRequest.author.login !== "greenkeeper") {
|
if (pullRequest.author.login !== "greenkeeper") {
|
||||||
memo.add("@" + pullRequest.author.login);
|
memo.add("@" + pullRequest.author.login);
|
||||||
}
|
}
|
||||||
|
|
||||||
return memo;
|
return memo;
|
||||||
}, new Set());
|
}, new Set());
|
||||||
|
|
||||||
|
@ -699,6 +704,7 @@ async function addToChangelog(newEntry) {
|
||||||
} else {
|
} else {
|
||||||
log.error(error);
|
log.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,6 +730,7 @@ async function addToChangelog(newEntry) {
|
||||||
|
|
||||||
// Step 4: Print out some information about what just happened to the console
|
// Step 4: Print out some information about what just happened to the console
|
||||||
const commitCommand = `git commit -m 'Add changelog entry for v${version}' CHANGELOG.md`;
|
const commitCommand = `git commit -m 'Add changelog entry for v${version}' CHANGELOG.md`;
|
||||||
|
|
||||||
if (isPrerelease(version)) {
|
if (isPrerelease(version)) {
|
||||||
log.info(`You can now run: ${colors.bold(commitCommand)}`);
|
log.info(`You can now run: ${colors.bold(commitCommand)}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -115,14 +115,17 @@ Client.prototype.emit = function(event, data) {
|
||||||
Client.prototype.find = function(channelId) {
|
Client.prototype.find = function(channelId) {
|
||||||
let network = null;
|
let network = null;
|
||||||
let chan = null;
|
let chan = null;
|
||||||
|
|
||||||
for (const i in this.networks) {
|
for (const i in this.networks) {
|
||||||
const n = this.networks[i];
|
const n = this.networks[i];
|
||||||
chan = _.find(n.channels, {id: channelId});
|
chan = _.find(n.channels, {id: channelId});
|
||||||
|
|
||||||
if (chan) {
|
if (chan) {
|
||||||
network = n;
|
network = n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network && chan) {
|
if (network && chan) {
|
||||||
return {
|
return {
|
||||||
network: network,
|
network: network,
|
||||||
|
@ -340,6 +343,7 @@ Client.prototype.input = function(data) {
|
||||||
Client.prototype.inputLine = function(data) {
|
Client.prototype.inputLine = function(data) {
|
||||||
const client = this;
|
const client = this;
|
||||||
const target = client.find(data.target);
|
const target = client.find(data.target);
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +377,7 @@ Client.prototype.inputLine = function(data) {
|
||||||
|
|
||||||
if (cmd in inputs) {
|
if (cmd in inputs) {
|
||||||
const plugin = inputs[cmd];
|
const plugin = inputs[cmd];
|
||||||
|
|
||||||
if (connected || plugin.allowDisconnected) {
|
if (connected || plugin.allowDisconnected) {
|
||||||
connected = true;
|
connected = true;
|
||||||
plugin.input.apply(client, [target.network, target.chan, cmd, args]);
|
plugin.input.apply(client, [target.network, target.chan, cmd, args]);
|
||||||
|
@ -427,6 +432,7 @@ Client.prototype.open = function(socketId, target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
target = this.find(target);
|
target = this.find(target);
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -459,6 +465,7 @@ Client.prototype.sort = function(data) {
|
||||||
|
|
||||||
case "channels": {
|
case "channels": {
|
||||||
const network = _.find(this.networks, {id: data.target});
|
const network = _.find(this.networks, {id: data.target});
|
||||||
|
|
||||||
if (!network) {
|
if (!network) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -478,6 +485,7 @@ Client.prototype.sort = function(data) {
|
||||||
Client.prototype.names = function(data) {
|
Client.prototype.names = function(data) {
|
||||||
const client = this;
|
const client = this;
|
||||||
const target = client.find(data.target);
|
const target = client.find(data.target);
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ ClientManager.prototype.autoloadUsers = function() {
|
||||||
// Existing users removed since last time users were loaded
|
// Existing users removed since last time users were loaded
|
||||||
_.difference(loaded, updatedUsers).forEach((name) => {
|
_.difference(loaded, updatedUsers).forEach((name) => {
|
||||||
const client = _.find(this.clients, {name: name});
|
const client = _.find(this.clients, {name: name});
|
||||||
|
|
||||||
if (client) {
|
if (client) {
|
||||||
client.quit(true);
|
client.quit(true);
|
||||||
this.clients = _.without(this.clients, client);
|
this.clients = _.without(this.clients, client);
|
||||||
|
@ -86,6 +87,7 @@ ClientManager.prototype.loadUser = function(name) {
|
||||||
client = new Client(this, name, userConfig);
|
client = new Client(this, name, userConfig);
|
||||||
this.clients.push(client);
|
this.clients.push(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,9 +133,11 @@ ClientManager.prototype.updateUser = function(name, opts, callback) {
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
log.error(`Tried to update invalid user ${colors.green(name)}. This is most likely a bug.`);
|
log.error(`Tried to update invalid user ${colors.green(name)}. This is most likely a bug.`);
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(true);
|
callback(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,9 +155,11 @@ ClientManager.prototype.updateUser = function(name, opts, callback) {
|
||||||
return callback ? callback() : true;
|
return callback ? callback() : true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(`Failed to update user ${colors.green(name)} (${e})`);
|
log.error(`Failed to update user ${colors.green(name)} (${e})`);
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(e);
|
callback(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,9 +40,11 @@ _.merge(Helper.config, program.config);
|
||||||
|
|
||||||
require("./start");
|
require("./start");
|
||||||
require("./config");
|
require("./config");
|
||||||
|
|
||||||
if (!Helper.config.public && !Helper.config.ldap.enable) {
|
if (!Helper.config.public && !Helper.config.ldap.enable) {
|
||||||
require("./users");
|
require("./users");
|
||||||
}
|
}
|
||||||
|
|
||||||
require("./install");
|
require("./install");
|
||||||
require("./uninstall");
|
require("./uninstall");
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ program
|
||||||
}
|
}
|
||||||
|
|
||||||
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
||||||
|
|
||||||
const errorHandler = (error) => {
|
const errorHandler = (error) => {
|
||||||
log.error(
|
log.error(
|
||||||
`Failed to uninstall ${colors.green(packageName)}. ` +
|
`Failed to uninstall ${colors.green(packageName)}. ` +
|
||||||
|
|
|
@ -37,6 +37,7 @@ program
|
||||||
log.error("Password cannot be empty.");
|
log.error("Password cannot be empty.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
log.prompt({
|
log.prompt({
|
||||||
text: "Save logs to disk?",
|
text: "Save logs to disk?",
|
||||||
|
|
|
@ -28,6 +28,7 @@ program
|
||||||
log.error(`User ${colors.bold(name)} does not exist.`);
|
log.error(`User ${colors.bold(name)} does not exist.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const child_spawn = child.spawn(
|
const child_spawn = child.spawn(
|
||||||
process.env.EDITOR || "vi",
|
process.env.EDITOR || "vi",
|
||||||
[Helper.getUserConfigPath(name)],
|
[Helper.getUserConfigPath(name)],
|
||||||
|
|
|
@ -27,6 +27,7 @@ program
|
||||||
log.error(`User ${colors.bold(name)} does not exist.`);
|
log.error(`User ${colors.bold(name)} does not exist.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const file = Helper.getUserConfigPath(name);
|
const file = Helper.getUserConfigPath(name);
|
||||||
const user = require(file);
|
const user = require(file);
|
||||||
log.prompt({
|
log.prompt({
|
||||||
|
@ -36,6 +37,7 @@ program
|
||||||
if (err) {
|
if (err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.password = Helper.password.hash(password);
|
user.password = Helper.password.hash(password);
|
||||||
user.sessions = {};
|
user.sessions = {};
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
|
|
|
@ -56,12 +56,15 @@ class Utils {
|
||||||
} else if (/^\[.*\]$/.test(value)) { // Arrays
|
} else if (/^\[.*\]$/.test(value)) { // Arrays
|
||||||
// Supporting arrays `[a,b]` and `[a, b]`
|
// Supporting arrays `[a,b]` and `[a, b]`
|
||||||
const array = value.slice(1, -1).split(/,\s*/);
|
const array = value.slice(1, -1).split(/,\s*/);
|
||||||
|
|
||||||
// If [] is given, it will be parsed as `[ "" ]`, so treat this as empty
|
// If [] is given, it will be parsed as `[ "" ]`, so treat this as empty
|
||||||
if (array.length === 1 && array[0] === "") {
|
if (array.length === 1 && array[0] === "") {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return array.map(parseValue); // Re-parses all values of the array
|
return array.map(parseValue); // Re-parses all values of the array
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,12 @@ function getVersion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let _gitCommit;
|
let _gitCommit;
|
||||||
|
|
||||||
function getGitCommit() {
|
function getGitCommit() {
|
||||||
if (_gitCommit !== undefined) {
|
if (_gitCommit !== undefined) {
|
||||||
return _gitCommit;
|
return _gitCommit;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_gitCommit = require("child_process")
|
_gitCommit = require("child_process")
|
||||||
.execSync("git rev-parse --short HEAD 2> /dev/null") // Returns hash of current commit
|
.execSync("git rev-parse --short HEAD 2> /dev/null") // Returns hash of current commit
|
||||||
|
|
|
@ -141,11 +141,13 @@ Network.prototype.export = function() {
|
||||||
})
|
})
|
||||||
.map(function(chan) {
|
.map(function(chan) {
|
||||||
const keys = ["name"];
|
const keys = ["name"];
|
||||||
|
|
||||||
if (chan.type === Chan.Type.CHANNEL) {
|
if (chan.type === Chan.Type.CHANNEL) {
|
||||||
keys.push("key");
|
keys.push("key");
|
||||||
} else if (chan.type === Chan.Type.QUERY) {
|
} else if (chan.type === Chan.Type.QUERY) {
|
||||||
keys.push("type");
|
keys.push("type");
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.pick(chan, keys);
|
return _.pick(chan, keys);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ function advancedLdapAuth(user, password, callback) {
|
||||||
});
|
});
|
||||||
res.on("end", function() {
|
res.on("end", function() {
|
||||||
ldapclient.unbind();
|
ldapclient.unbind();
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
callback(false);
|
callback(false);
|
||||||
}
|
}
|
||||||
|
@ -115,15 +116,18 @@ function ldapAuth(manager, client, user, password, callback) {
|
||||||
if (valid && !client) {
|
if (valid && !client) {
|
||||||
manager.addUser(user, null);
|
manager.addUser(user, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(valid);
|
callback(valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
let auth;
|
let auth;
|
||||||
|
|
||||||
if ("baseDN" in Helper.config.ldap) {
|
if ("baseDN" in Helper.config.ldap) {
|
||||||
auth = simpleLdapAuth;
|
auth = simpleLdapAuth;
|
||||||
} else {
|
} else {
|
||||||
auth = advancedLdapAuth;
|
auth = advancedLdapAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
return auth(user, password, callbackWrapper);
|
return auth(user, password, callbackWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ function fetch(callback) {
|
||||||
// Find the current release among releases on GitHub
|
// Find the current release among releases on GitHub
|
||||||
for (i = 0; i < body.length; i++) {
|
for (i = 0; i < body.length; i++) {
|
||||||
release = body[i];
|
release = body[i];
|
||||||
|
|
||||||
if (release.tag_name === versions.current.version) {
|
if (release.tag_name === versions.current.version) {
|
||||||
versions.current.changelog = release.body_html;
|
versions.current.changelog = release.body_html;
|
||||||
prerelease = release.prerelease;
|
prerelease = release.prerelease;
|
||||||
|
|
|
@ -19,6 +19,7 @@ exports.input = function(network, chan, cmd, args) {
|
||||||
|
|
||||||
if (!network.irc.network.cap.isEnabled("echo-message")) {
|
if (!network.irc.network.cap.isEnabled("echo-message")) {
|
||||||
const channel = network.getChannel(target);
|
const channel = network.getChannel(target);
|
||||||
|
|
||||||
if (typeof channel !== "undefined") {
|
if (typeof channel !== "undefined") {
|
||||||
network.irc.emit("privmsg", {
|
network.irc.emit("privmsg", {
|
||||||
nick: network.irc.user.nick,
|
nick: network.irc.user.nick,
|
||||||
|
|
|
@ -8,6 +8,7 @@ exports.commands = ["query"];
|
||||||
|
|
||||||
exports.input = function(network, chan, cmd, args) {
|
exports.input = function(network, chan, cmd, args) {
|
||||||
const target = args[0];
|
const target = args[0];
|
||||||
|
|
||||||
if (args.length === 0 || target.length === 0) {
|
if (args.length === 0 || target.length === 0) {
|
||||||
chan.pushMessage(this, new Msg({
|
chan.pushMessage(this, new Msg({
|
||||||
type: Msg.Type.ERROR,
|
type: Msg.Type.ERROR,
|
||||||
|
@ -17,11 +18,13 @@ exports.input = function(network, chan, cmd, args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = _.find(network.channels, {name: target});
|
const query = _.find(network.channels, {name: target});
|
||||||
|
|
||||||
if (typeof query !== "undefined") {
|
if (typeof query !== "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char = target[0];
|
const char = target[0];
|
||||||
|
|
||||||
if (network.irc.network.options.CHANTYPES && network.irc.network.options.CHANTYPES.includes(char)) {
|
if (network.irc.network.options.CHANTYPES && network.irc.network.options.CHANTYPES.includes(char)) {
|
||||||
chan.pushMessage(this, new Msg({
|
chan.pushMessage(this, new Msg({
|
||||||
type: Msg.Type.ERROR,
|
type: Msg.Type.ERROR,
|
||||||
|
|
|
@ -14,6 +14,7 @@ exports.input = function({irc}, chan, cmd, args) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
irc.setTopic(chan.name, args.join(" "));
|
irc.setTopic(chan.name, args.join(" "));
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@ module.exports = function(irc, network) {
|
||||||
irc.on("banlist", function(banlist) {
|
irc.on("banlist", function(banlist) {
|
||||||
const channel = banlist.channel;
|
const channel = banlist.channel;
|
||||||
const bans = banlist.bans;
|
const bans = banlist.bans;
|
||||||
|
|
||||||
if (!bans || bans.length === 0) {
|
if (!bans || bans.length === 0) {
|
||||||
const msg = new Msg({
|
const msg = new Msg({
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
|
@ -21,6 +22,7 @@ module.exports = function(irc, network) {
|
||||||
|
|
||||||
const chanName = `Banlist for ${channel}`;
|
const chanName = `Banlist for ${channel}`;
|
||||||
let chan = network.getChannel(chanName);
|
let chan = network.getChannel(chanName);
|
||||||
|
|
||||||
if (typeof chan === "undefined") {
|
if (typeof chan === "undefined") {
|
||||||
chan = new Chan({
|
chan = new Chan({
|
||||||
type: Chan.Type.SPECIAL,
|
type: Chan.Type.SPECIAL,
|
||||||
|
|
|
@ -122,6 +122,7 @@ function parse(msg, preview, res, client) {
|
||||||
if (!preview.link.startsWith("https://")) {
|
if (!preview.link.startsWith("https://")) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
preview.type = "audio";
|
preview.type = "audio";
|
||||||
preview.res = res.type;
|
preview.res = res.type;
|
||||||
|
|
||||||
|
@ -133,6 +134,7 @@ function parse(msg, preview, res, client) {
|
||||||
if (!preview.link.startsWith("https://")) {
|
if (!preview.link.startsWith("https://")) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
preview.res = res.type;
|
preview.res = res.type;
|
||||||
preview.type = "video";
|
preview.type = "video";
|
||||||
|
|
||||||
|
@ -191,6 +193,7 @@ function emitPreview(client, msg, preview) {
|
||||||
|
|
||||||
function fetch(uri, cb) {
|
function fetch(uri, cb) {
|
||||||
let req;
|
let req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
req = request.get({
|
req = request.get({
|
||||||
url: uri,
|
url: uri,
|
||||||
|
@ -214,6 +217,7 @@ function fetch(uri, cb) {
|
||||||
// response is an image
|
// response is an image
|
||||||
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch
|
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch
|
||||||
const contentLength = parseInt(res.headers["content-length"], 10) || 0;
|
const contentLength = parseInt(res.headers["content-length"], 10) || 0;
|
||||||
|
|
||||||
if (contentLength > limit) {
|
if (contentLength > limit) {
|
||||||
req.abort();
|
req.abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,7 @@ module.exports = function(irc, network) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let match;
|
let match;
|
||||||
|
|
||||||
while ((match = nickRegExp.exec(data.message))) {
|
while ((match = nickRegExp.exec(data.message))) {
|
||||||
if (chan.findUser(match[1])) {
|
if (chan.findUser(match[1])) {
|
||||||
msg.users.push(match[1]);
|
msg.users.push(match[1]);
|
||||||
|
|
|
@ -16,6 +16,7 @@ module.exports = function(irc, network) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetChan = network.getChannel(data.channel);
|
const targetChan = network.getChannel(data.channel);
|
||||||
|
|
||||||
if (typeof targetChan === "undefined") {
|
if (typeof targetChan === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +40,7 @@ module.exports = function(irc, network) {
|
||||||
targetChan = network.channels[0];
|
targetChan = network.channels[0];
|
||||||
} else {
|
} else {
|
||||||
targetChan = network.getChannel(data.target);
|
targetChan = network.getChannel(data.target);
|
||||||
|
|
||||||
if (typeof targetChan === "undefined") {
|
if (typeof targetChan === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +82,7 @@ module.exports = function(irc, network) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = targetChan.findUser(mode.param);
|
const user = targetChan.findUser(mode.param);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ module.exports = function(irc, network) {
|
||||||
|
|
||||||
irc.on("userlist", function(data) {
|
irc.on("userlist", function(data) {
|
||||||
const chan = network.getChannel(data.channel);
|
const chan = network.getChannel(data.channel);
|
||||||
|
|
||||||
if (typeof chan === "undefined") {
|
if (typeof chan === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ module.exports = function(irc, network) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg;
|
let msg;
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
msg = new Msg({
|
msg = new Msg({
|
||||||
type: Msg.Type.ERROR,
|
type: Msg.Type.ERROR,
|
||||||
|
|
|
@ -18,6 +18,7 @@ function loadLocalThemes() {
|
||||||
if (err) {
|
if (err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
builtInThemes
|
builtInThemes
|
||||||
.filter((theme) => theme.endsWith(".css"))
|
.filter((theme) => theme.endsWith(".css"))
|
||||||
.map(makeLocalThemeObject)
|
.map(makeLocalThemeObject)
|
||||||
|
@ -27,6 +28,7 @@ function loadLocalThemes() {
|
||||||
|
|
||||||
function addTheme(packageName, packageObject) {
|
function addTheme(packageName, packageObject) {
|
||||||
const theme = makePackageThemeObject(packageName, packageObject);
|
const theme = makePackageThemeObject(packageName, packageObject);
|
||||||
|
|
||||||
if (theme) {
|
if (theme) {
|
||||||
themes.set(theme.name, theme);
|
themes.set(theme.name, theme);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +56,7 @@ function makePackageThemeObject(moduleName, module) {
|
||||||
if (!module || module.type !== "theme") {
|
if (!module || module.type !== "theme") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const modulePath = Helper.getPackageModulePath(moduleName);
|
const modulePath = Helper.getPackageModulePath(moduleName);
|
||||||
const displayName = module.name || moduleName;
|
const displayName = module.name || moduleName;
|
||||||
const filename = path.join(modulePath, module.css);
|
const filename = path.join(modulePath, module.css);
|
||||||
|
|
|
@ -55,9 +55,11 @@ module.exports = function() {
|
||||||
app.get("/themes/:theme.css", (req, res) => {
|
app.get("/themes/:theme.css", (req, res) => {
|
||||||
const themeName = req.params.theme;
|
const themeName = req.params.theme;
|
||||||
const theme = themes.getFilename(themeName);
|
const theme = themes.getFilename(themeName);
|
||||||
|
|
||||||
if (theme === undefined) {
|
if (theme === undefined) {
|
||||||
return res.status(404).send("Not found");
|
return res.status(404).send("Not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.sendFile(theme);
|
return res.sendFile(theme);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,9 +67,11 @@ module.exports = function() {
|
||||||
const packageName = req.params.package;
|
const packageName = req.params.package;
|
||||||
const fileName = req.params.filename;
|
const fileName = req.params.filename;
|
||||||
const packageFile = packages.getPackage(packageName);
|
const packageFile = packages.getPackage(packageName);
|
||||||
|
|
||||||
if (!packageFile || !packages.getStylesheets().includes(`${packageName}/${fileName}`)) {
|
if (!packageFile || !packages.getStylesheets().includes(`${packageName}/${fileName}`)) {
|
||||||
return res.status(404).send("Not found");
|
return res.status(404).send("Not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const packagePath = Helper.getPackageModulePath(packageName);
|
const packagePath = Helper.getPackageModulePath(packageName);
|
||||||
return res.sendFile(path.join(packagePath, fileName));
|
return res.sendFile(path.join(packagePath, fileName));
|
||||||
});
|
});
|
||||||
|
@ -161,6 +165,7 @@ module.exports = function() {
|
||||||
|
|
||||||
// Handle ctrl+c and kill gracefully
|
// Handle ctrl+c and kill gracefully
|
||||||
let suicideTimeout = null;
|
let suicideTimeout = null;
|
||||||
|
|
||||||
const exitGracefully = function() {
|
const exitGracefully = function() {
|
||||||
if (suicideTimeout !== null) {
|
if (suicideTimeout !== null) {
|
||||||
return;
|
return;
|
||||||
|
@ -304,12 +309,14 @@ function initializeClient(socket, client, token, lastMessage) {
|
||||||
const old = data.old_password;
|
const old = data.old_password;
|
||||||
const p1 = data.new_password;
|
const p1 = data.new_password;
|
||||||
const p2 = data.verify_password;
|
const p2 = data.verify_password;
|
||||||
|
|
||||||
if (typeof p1 === "undefined" || p1 === "") {
|
if (typeof p1 === "undefined" || p1 === "") {
|
||||||
socket.emit("change-password", {
|
socket.emit("change-password", {
|
||||||
error: "Please enter a new password",
|
error: "Please enter a new password",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1 !== p2) {
|
if (p1 !== p2) {
|
||||||
socket.emit("change-password", {
|
socket.emit("change-password", {
|
||||||
error: "Both new password fields must match",
|
error: "Both new password fields must match",
|
||||||
|
@ -326,6 +333,7 @@ function initializeClient(socket, client, token, lastMessage) {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hash = Helper.password.hash(p1);
|
const hash = Helper.password.hash(p1);
|
||||||
|
|
||||||
client.setPassword(hash, (success) => {
|
client.setPassword(hash, (success) => {
|
||||||
|
@ -375,6 +383,7 @@ function initializeClient(socket, client, token, lastMessage) {
|
||||||
|
|
||||||
socket.on("msg:preview:toggle", function(data) {
|
socket.on("msg:preview:toggle", function(data) {
|
||||||
const networkAndChan = client.find(data.target);
|
const networkAndChan = client.find(data.target);
|
||||||
|
|
||||||
if (!networkAndChan) {
|
if (!networkAndChan) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -602,12 +611,14 @@ function performAuthentication(data) {
|
||||||
let auth = () => {
|
let auth = () => {
|
||||||
log.error("None of the auth plugins is enabled");
|
log.error("None of the auth plugins is enabled");
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i = 0; i < authPlugins.length; ++i) {
|
for (let i = 0; i < authPlugins.length; ++i) {
|
||||||
if (authPlugins[i].isEnabled()) {
|
if (authPlugins[i].isEnabled()) {
|
||||||
auth = authPlugins[i].auth;
|
auth = authPlugins[i].auth;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auth(manager, client, data.user, data.password, authCallback);
|
auth(manager, client, data.user, data.password, authCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ module.exports.write = function(user, network, chan, msg) {
|
||||||
let line = `[${time}] `;
|
let line = `[${time}] `;
|
||||||
|
|
||||||
const type = msg.type.trim();
|
const type = msg.type.trim();
|
||||||
|
|
||||||
if (type === "message" || type === "highlight") {
|
if (type === "message" || type === "highlight") {
|
||||||
// Format:
|
// Format:
|
||||||
// [2014-01-01 00:00:00] <Arnold> Put that cookie down.. Now!!
|
// [2014-01-01 00:00:00] <Arnold> Put that cookie down.. Now!!
|
||||||
|
|
|
@ -116,6 +116,7 @@ describe("LDAP authentication plugin", function() {
|
||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
originalLogInfo = log.info;
|
originalLogInfo = log.info;
|
||||||
|
|
||||||
log.info = () => {};
|
log.info = () => {};
|
||||||
|
|
||||||
server = startLdapServer(done);
|
server = startLdapServer(done);
|
||||||
|
|
|
@ -10,6 +10,7 @@ describe("packages", function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
originalLogInfo = log.info;
|
originalLogInfo = log.info;
|
||||||
|
|
||||||
log.info = () => {};
|
log.info = () => {};
|
||||||
|
|
||||||
delete require.cache[require.resolve("../../../src/plugins/packages")];
|
delete require.cache[require.resolve("../../../src/plugins/packages")];
|
||||||
|
|
|
@ -12,6 +12,7 @@ describe("Server", function() {
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
originalLogInfo = log.info;
|
originalLogInfo = log.info;
|
||||||
|
|
||||||
log.info = () => {};
|
log.info = () => {};
|
||||||
|
|
||||||
server = require("../src/server")();
|
server = require("../src/server")();
|
||||||
|
|
|
@ -10,6 +10,7 @@ const Chan = require("../src/models/chan");
|
||||||
function MockClient() {
|
function MockClient() {
|
||||||
this.user = {nick: "test-user"};
|
this.user = {nick: "test-user"};
|
||||||
}
|
}
|
||||||
|
|
||||||
util.inherits(MockClient, EventEmitter);
|
util.inherits(MockClient, EventEmitter);
|
||||||
|
|
||||||
MockClient.prototype.createMessage = function(opts) {
|
MockClient.prototype.createMessage = function(opts) {
|
||||||
|
|
Loading…
Reference in a new issue