forked from thelounge/thelounge
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
801d7c9
commit 4471229
Showing
22 changed files
with
831 additions
and
665 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); |
Oops, something went wrong.