2017-05-18 20:08:54 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const $ = require("jquery");
|
2017-11-01 09:16:19 +00:00
|
|
|
const escape = require("css.escape");
|
2017-05-18 20:08:54 +00:00
|
|
|
const input = $("#input");
|
2018-03-08 13:46:05 +00:00
|
|
|
const viewport = $("#viewport");
|
2017-05-18 20:08:54 +00:00
|
|
|
|
2018-01-11 11:33:36 +00:00
|
|
|
var serverHash = -1; // eslint-disable-line no-var
|
|
|
|
var lastMessageId = -1; // eslint-disable-line no-var
|
2017-08-28 09:18:31 +00:00
|
|
|
|
2017-05-18 20:08:54 +00:00
|
|
|
module.exports = {
|
2017-10-03 20:59:19 +00:00
|
|
|
inputCommands: {collapse, expand, join},
|
2017-09-02 16:28:36 +00:00
|
|
|
findCurrentNetworkChan,
|
2017-08-28 09:18:31 +00:00
|
|
|
serverHash,
|
|
|
|
lastMessageId,
|
2017-05-18 20:08:54 +00:00
|
|
|
confirmExit,
|
|
|
|
forceFocus,
|
2018-03-08 16:27:20 +00:00
|
|
|
scrollIntoViewNicely,
|
2017-12-20 09:45:12 +00:00
|
|
|
hasRoleInChannel,
|
2017-05-18 20:08:54 +00:00
|
|
|
move,
|
|
|
|
resetHeight,
|
|
|
|
setNick,
|
|
|
|
toggleNickEditor,
|
2017-09-06 19:03:56 +00:00
|
|
|
toggleNotificationMarkers,
|
|
|
|
requestIdleCallback,
|
2017-05-18 20:08:54 +00:00
|
|
|
};
|
|
|
|
|
2017-09-02 16:28:36 +00:00
|
|
|
function findCurrentNetworkChan(name) {
|
|
|
|
name = name.toLowerCase();
|
|
|
|
|
|
|
|
return $(".network .chan.active")
|
|
|
|
.parent(".network")
|
|
|
|
.find(".chan")
|
|
|
|
.filter(function() {
|
2017-12-28 12:15:28 +00:00
|
|
|
return $(this).attr("aria-label").toLowerCase() === name;
|
2017-09-02 16:28:36 +00:00
|
|
|
})
|
|
|
|
.first();
|
|
|
|
}
|
|
|
|
|
2017-05-18 20:08:54 +00:00
|
|
|
function resetHeight(element) {
|
|
|
|
element.style.height = element.style.minHeight;
|
|
|
|
}
|
|
|
|
|
2017-12-20 09:45:12 +00:00
|
|
|
// Given a channel element will determine if the lounge user is one of the supplied roles.
|
|
|
|
function hasRoleInChannel(channel, roles) {
|
|
|
|
if (!channel || !roles) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-01 09:16:19 +00:00
|
|
|
const channelID = channel.data("id");
|
|
|
|
const network = $("#sidebar .network").has(`.chan[data-id="${channelID}"]`);
|
|
|
|
const ownNick = network.data("nick");
|
2018-03-04 20:03:11 +00:00
|
|
|
const user = channel.find(`.names-original .user[data-name="${escape(ownNick)}"]`).first();
|
2017-12-20 09:45:12 +00:00
|
|
|
return user.parent().is("." + roles.join(", ."));
|
2017-11-01 09:16:19 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 20:08:54 +00:00
|
|
|
// Triggering click event opens the virtual keyboard on mobile
|
|
|
|
// This can only be called from another interactive event (e.g. button click)
|
|
|
|
function forceFocus() {
|
2018-01-30 09:38:33 +00:00
|
|
|
input.trigger("click").trigger("focus");
|
2017-05-18 20:08:54 +00:00
|
|
|
}
|
|
|
|
|
2018-03-08 16:27:20 +00:00
|
|
|
// Reusable scrollIntoView parameters for channel list / user list
|
|
|
|
function scrollIntoViewNicely(el) {
|
|
|
|
// Ideally this would use behavior: "smooth", but that does not consistently work in e.g. Chrome
|
|
|
|
// https://github.com/iamdustan/smoothscroll/issues/28#issuecomment-364061459
|
|
|
|
el.scrollIntoView({block: "nearest", inline: "nearest"});
|
|
|
|
}
|
|
|
|
|
2017-09-22 20:25:14 +00:00
|
|
|
function collapse() {
|
2018-01-26 08:52:51 +00:00
|
|
|
$(".chan.active .toggle-button.toggle-preview.opened").click();
|
2017-09-22 20:25:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function expand() {
|
2018-01-26 08:52:51 +00:00
|
|
|
$(".chan.active .toggle-button.toggle-preview:not(.opened)").click();
|
2017-09-22 20:25:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-10-03 20:59:19 +00:00
|
|
|
function join(args) {
|
|
|
|
const channel = args[0];
|
2018-02-20 07:28:04 +00:00
|
|
|
|
2017-10-03 20:59:19 +00:00
|
|
|
if (channel) {
|
|
|
|
const chan = findCurrentNetworkChan(channel);
|
2018-02-20 07:28:04 +00:00
|
|
|
|
2017-10-03 20:59:19 +00:00
|
|
|
if (chan.length) {
|
2018-01-30 09:38:33 +00:00
|
|
|
chan.trigger("click");
|
2017-10-03 20:59:19 +00:00
|
|
|
}
|
2017-09-22 20:25:14 +00:00
|
|
|
}
|
2017-05-18 20:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function toggleNickEditor(toggle) {
|
|
|
|
$("#nick").toggleClass("editable", toggle);
|
2018-01-30 09:38:33 +00:00
|
|
|
$("#nick-value").prop("contenteditable", toggle);
|
2017-05-18 20:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function setNick(nick) {
|
|
|
|
// Closes the nick editor when canceling, changing channel, or when a nick
|
|
|
|
// is set in a different tab / browser / device.
|
|
|
|
toggleNickEditor(false);
|
|
|
|
|
|
|
|
$("#nick-value").text(nick);
|
|
|
|
}
|
|
|
|
|
|
|
|
const favicon = $("#favicon");
|
|
|
|
|
|
|
|
function toggleNotificationMarkers(newState) {
|
|
|
|
// Toggles the favicon to red when there are unread notifications
|
|
|
|
if (favicon.data("toggled") !== newState) {
|
2018-01-11 11:33:36 +00:00
|
|
|
const old = favicon.prop("href");
|
2018-01-30 09:38:33 +00:00
|
|
|
favicon.prop("href", favicon.data("other"));
|
2017-05-18 20:08:54 +00:00
|
|
|
favicon.data("other", old);
|
|
|
|
favicon.data("toggled", newState);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Toggles a dot on the menu icon when there are unread notifications
|
2018-03-08 13:46:05 +00:00
|
|
|
viewport.toggleClass("notified", newState);
|
2017-05-18 20:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function confirmExit() {
|
2018-02-23 19:22:05 +00:00
|
|
|
if ($(document.body).hasClass("public")) {
|
2017-05-18 20:08:54 +00:00
|
|
|
window.onbeforeunload = function() {
|
|
|
|
return "Are you sure you want to navigate away from this page?";
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function move(array, old_index, new_index) {
|
|
|
|
if (new_index >= array.length) {
|
|
|
|
let k = new_index - array.length;
|
2018-02-20 07:28:04 +00:00
|
|
|
|
2017-05-18 20:08:54 +00:00
|
|
|
while ((k--) + 1) {
|
|
|
|
this.push(undefined);
|
|
|
|
}
|
|
|
|
}
|
2018-02-20 07:28:04 +00:00
|
|
|
|
2017-05-18 20:08:54 +00:00
|
|
|
array.splice(new_index, 0, array.splice(old_index, 1)[0]);
|
|
|
|
return array;
|
|
|
|
}
|
2017-09-06 19:03:56 +00:00
|
|
|
|
|
|
|
function requestIdleCallback(callback, timeout) {
|
|
|
|
if (window.requestIdleCallback) {
|
|
|
|
// During an idle period the user agent will run idle callbacks in FIFO order
|
|
|
|
// until either the idle period ends or there are no more idle callbacks eligible to be run.
|
2018-03-05 00:59:16 +00:00
|
|
|
window.requestIdleCallback(callback, {timeout});
|
2017-09-06 19:03:56 +00:00
|
|
|
} else {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}
|