Skip to content

Commit

Permalink
Add modules for socket events
Browse files Browse the repository at this point in the history
  • Loading branch information
AlMcKinlay committed Jun 20, 2017
1 parent 801d7c9 commit 4471229
Show file tree
Hide file tree
Showing 22 changed files with 831 additions and 665 deletions.
677 changes: 12 additions & 665 deletions client/js/lounge.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions client/js/options.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use strict";

const $ = require("jquery");
const settings = $("#settings");
const userStyles = $("#user-specified-css");
Expand Down
193 changes: 193 additions & 0 deletions client/js/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
"use strict";

const $ = require("jquery");
const templates = require("../views");
const options = require("./options");
const utils = require("./utils");
const sorting = require("./sorting");

const chat = $("#chat");
const sidebar = $("#sidebar");

module.exports = {
buildChannelMessages,
buildChatMessage,
renderChannel,
renderChannelMessages,
renderChannelUsers,
renderNetworks
};

function buildChannelMessages(channel, messages) {
return messages.reduce(function(docFragment, message) {
docFragment.append(buildChatMessage({
chan: channel,
msg: message
}));
return docFragment;
}, $(document.createDocumentFragment()));
}

function buildChatMessage(data) {
const type = data.msg.type;
let target = "#chan-" + data.chan;
if (type === "error") {
target = "#chan-" + chat.find(".active").data("id");
}

const chan = chat.find(target);
let template = "msg";

if (!data.msg.highlight && !data.msg.self && (type === "message" || type === "notice") && options.highlights.some(function(h) {
return data.msg.text.toLocaleLowerCase().indexOf(h.toLocaleLowerCase()) > -1;
})) {
data.msg.highlight = true;
}

if ([
"invite",
"join",
"mode",
"kick",
"nick",
"part",
"quit",
"topic",
"topic_set_by",
"action",
"whois",
"ctcp",
"channel_list",
"ban_list",
].indexOf(type) !== -1) {
template = "msg_action";
} else if (type === "unhandled") {
template = "msg_unhandled";
}

const msg = $(templates[template](data.msg));
const text = msg.find(".text");

if (template === "msg_action") {
text.html(templates.actions[type](data.msg));
}

if ((type === "message" || type === "action") && chan.hasClass("channel")) {
const nicks = chan.find(".users").data("nicks");
if (nicks) {
const find = nicks.indexOf(data.msg.from);
if (find !== -1) {
nicks.splice(find, 1);
nicks.unshift(data.msg.from);
}
}
}

return msg;
}

function renderChannel(data) {
renderChannelMessages(data);

if (data.type === "channel") {
renderChannelUsers(data);
}
}

function renderChannelMessages(data) {
const documentFragment = buildChannelMessages(data.id, data.messages);
const channel = chat.find("#chan-" + data.id + " .messages").append(documentFragment);

if (data.firstUnread > 0) {
const first = channel.find("#msg-" + data.firstUnread);

// TODO: If the message is far off in the history, we still need to append the marker into DOM
if (!first.length) {
channel.prepend(templates.unread_marker());
} else {
first.before(templates.unread_marker());
}
} else {
channel.append(templates.unread_marker());
}

if (data.type !== "lobby") {
let lastDate;
$(chat.find("#chan-" + data.id + " .messages .msg[data-time]")).each(function() {
const msg = $(this);
const msgDate = new Date(msg.attr("data-time"));

// Top-most message in a channel
if (!lastDate) {
lastDate = msgDate;
msg.before(templates.date_marker({msgDate: msgDate}));
}

if (lastDate.toDateString() !== msgDate.toDateString()) {
msg.before(templates.date_marker({msgDate: msgDate}));
}

lastDate = msgDate;
});
}
}

function renderChannelUsers(data) {
const users = chat.find("#chan-" + data.id).find(".users");
let nicks = users.data("nicks") || [];
const oldSortOrder = {};

for (const i in nicks) {
oldSortOrder[nicks[i]] = i;
}

nicks = [];

for (const i in data.users) {
nicks.push(data.users[i].nick);
}

nicks = nicks.sort(function(a, b) {
return (oldSortOrder[a] || Number.MAX_VALUE) - (oldSortOrder[b] || Number.MAX_VALUE);
});

const search = users
.find(".search")
.attr("placeholder", nicks.length + " " + (nicks.length === 1 ? "user" : "users"));

users
.data("nicks", nicks)
.find(".names-original")
.html(templates.user(data));

// Refresh user search
if (search.val().length) {
search.trigger("input");
}
}

function renderNetworks(data) {
sidebar.find(".empty").hide();
sidebar.find(".networks").append(
templates.network({
networks: data.networks
})
);

const channels = $.map(data.networks, function(n) {
return n.channels;
});
chat.append(
templates.chat({
channels: channels
})
);
channels.forEach(renderChannel);

utils.confirmExit();
sorting();

if (sidebar.find(".highlight").length) {
utils.toggleNotificationMarkers(true);
}
}
44 changes: 44 additions & 0 deletions client/js/socket-events/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use strict";

const $ = require("jquery");
const socket = require("../socket");
const storage = require("../localStorage");

socket.on("auth", function(data) {
const login = $("#sign-in");
let token;

login.find(".btn").prop("disabled", false);

if (!data.success) {
storage.remove("token");

const error = login.find(".error");
error.show().closest("form").one("submit", function() {
error.hide();
});
} else {
token = storage.get("token");
if (token) {
$("#loading-page-message").text("Authorizing…");
socket.emit("auth", {token: token});
}
}

const input = login.find("input[name='user']");
if (input.val() === "") {
input.val(storage.get("user") || "");
}
if (token) {
return;
}
$("#sidebar, #footer").find(".sign-in")
.trigger("click", {
pushState: false,
})
.end()
.find(".networks")
.html("")
.next()
.show();
});
35 changes: 35 additions & 0 deletions client/js/socket-events/change_password.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use strict";

const $ = require("jquery");
const socket = require("../socket");
const storage = require("../localStorage");

socket.on("change-password", function(data) {
const passwordForm = $("#change-password");
if (data.error || data.success) {
const message = data.success ? data.success : data.error;
const feedback = passwordForm.find(".feedback");

if (data.success) {
feedback.addClass("success").removeClass("error");
} else {
feedback.addClass("error").removeClass("success");
}

feedback.text(message).show();
feedback.closest("form").one("submit", function() {
feedback.hide();
});
}

if (data.token && storage.get("token") !== null) {
storage.set("token", data.token);
}

passwordForm
.find("input")
.val("")
.end()
.find(".btn")
.prop("disabled", false);
});
18 changes: 18 additions & 0 deletions client/js/socket-events/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use strict";

require("./auth");
require("./change_password");
require("./init");
require("./join");
require("./more");
require("./msg");
require("./names");
require("./network");
require("./nick");
require("./open");
require("./part");
require("./quit");
require("./sync_sort");
require("./toggle");
require("./topic");
require("./users");
44 changes: 44 additions & 0 deletions client/js/socket-events/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use strict";

const $ = require("jquery");
const socket = require("../socket");
const render = require("../render");
const sidebar = $("#sidebar");
const storage = require("../localStorage");

socket.on("init", function(data) {
$("#loading-page-message").text("Rendering…");

if (data.networks.length === 0) {
$("#footer").find(".connect").trigger("click", {
pushState: false,
});
} else {
render.renderNetworks(data);
}

if (data.token && $("#sign-in-remember").is(":checked")) {
storage.set("token", data.token);
} else {
storage.remove("token");
}

$("body").removeClass("signed-out");
$("#loading").remove();
$("#sign-in").remove();

const id = data.active;
const target = sidebar.find("[data-id='" + id + "']").trigger("click", {
replaceHistory: true
});
if (target.length === 0) {
const first = sidebar.find(".chan")
.eq(0)
.trigger("click");
if (first.length === 0) {
$("#footer").find(".connect").trigger("click", {
pushState: false,
});
}
}
});
36 changes: 36 additions & 0 deletions client/js/socket-events/join.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use strict";

const $ = require("jquery");
const socket = require("../socket");
const render = require("../render");
const chat = $("#chat");
const templates = require("../../views");
const sidebar = $("#sidebar");

socket.on("join", function(data) {
const id = data.network;
const network = sidebar.find("#network-" + id);
network.append(
templates.chan({
channels: [data.chan]
})
);
chat.append(
templates.chat({
channels: [data.chan]
})
);
render.renderChannel(data.chan);

// Queries do not automatically focus, unless the user did a whois
if (data.chan.type === "query" && !data.shouldOpen) {
return;
}

sidebar.find(".chan")
.sort(function(a, b) {
return $(a).data("id") - $(b).data("id");
})
.last()
.click();
});
Loading

0 comments on commit 4471229

Please sign in to comment.