From 532f55cb862202dc3ca393756212186a2b4b9714 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Mon, 28 Aug 2017 23:06:28 +0300 Subject: [PATCH] Redraw channels --- client/js/render.js | 47 ++++++++++++++++++++++--- client/js/socket-events/auth.js | 2 +- client/js/socket-events/init.js | 56 ++++++++++++++++++++---------- client/js/socket-events/more.js | 2 +- client/js/socket-events/network.js | 3 +- 5 files changed, 82 insertions(+), 28 deletions(-) diff --git a/client/js/render.js b/client/js/render.js index 9e18ffe7..bb8be296 100644 --- a/client/js/render.js +++ b/client/js/render.js @@ -8,6 +8,7 @@ const utils = require("./utils"); const sorting = require("./sorting"); const constants = require("./constants"); const condensed = require("./condensed"); +const helpers_parse = require("./libs/handlebars/parse"); const chat = $("#chat"); const sidebar = $("#sidebar"); @@ -27,11 +28,11 @@ module.exports = { renderNetworks, }; -function buildChannelMessages(chanId, chanType, messages) { +function buildChannelMessages(container, chanId, chanType, messages) { return messages.reduce((docFragment, message) => { appendMessage(docFragment, chanId, chanType, message); return docFragment; - }, $(document.createDocumentFragment())); + }, container); } function appendMessage(container, chanId, chanType, msg) { @@ -121,7 +122,7 @@ function renderChannel(data) { } function renderChannelMessages(data) { - const documentFragment = buildChannelMessages(data.id, data.type, data.messages); + const documentFragment = buildChannelMessages($(document.createDocumentFragment()), data.id, data.type, data.messages); const channel = chat.find("#chan-" + data.id + " .messages").append(documentFragment); const template = $(templates.unread_marker()); @@ -168,7 +169,7 @@ function renderChannelUsers(data) { } } -function renderNetworks(data) { +function renderNetworks(data, singleNetwork) { sidebar.find(".empty").hide(); sidebar.find(".networks").append( templates.network({ @@ -176,15 +177,51 @@ function renderNetworks(data) { }) ); + let newChannels; const channels = $.map(data.networks, function(n) { return n.channels; }); + + if (!singleNetwork && utils.lastMessageId > -1) { + newChannels = []; + + channels.forEach((channel) => { + const chan = $("#chan-" + channel.id); + + if (chan.length > 0) { + if (chan.data("type") === "channel") { + chan + .data("needsNamesRefresh", true) + .find(".header .topic") + .html(helpers_parse(channel.topic)) + .attr("title", channel.topic); + } + + if (channel.messages.length > 0) { + const container = chan.find(".messages"); + buildChannelMessages(container, channel.id, channel.type, channel.messages); + + if (container.find(".msg").length >= 100) { + container.find(".show-more").addClass("show"); + } + + container.trigger("keepToBottom"); + } + } else { + newChannels.push(channel); + } + }); + } else { + newChannels = channels; + } + chat.append( templates.chat({ channels: channels }) ); - channels.forEach((channel) => { + + newChannels.forEach((channel) => { renderChannel(channel); if (channel.type === "channel") { diff --git a/client/js/socket-events/auth.js b/client/js/socket-events/auth.js index cb0ef4ee..e544948f 100644 --- a/client/js/socket-events/auth.js +++ b/client/js/socket-events/auth.js @@ -6,7 +6,7 @@ const storage = require("../localStorage"); const utils = require("../utils"); socket.on("auth", function(data) { - // If we reconnected and serverHash differents, that means the server restarted + // If we reconnected and serverHash differs, that means the server restarted // And we will reload the page to grab the latest version if (utils.serverHash > -1 && data.serverHash > -1 && data.serverHash !== utils.serverHash) { socket.disconnect(); diff --git a/client/js/socket-events/init.js b/client/js/socket-events/init.js index f200a834..6debd9d9 100644 --- a/client/js/socket-events/init.js +++ b/client/js/socket-events/init.js @@ -1,6 +1,7 @@ "use strict"; const $ = require("jquery"); +const escape = require("css.escape"); const socket = require("../socket"); const render = require("../render"); const webpush = require("../webpush"); @@ -12,11 +13,11 @@ socket.on("init", function(data) { $("#loading-page-message, #connection-error").text("Rendering…"); const lastMessageId = utils.lastMessageId; + let previousActive = 0; - // TODO: this is hacky if (lastMessageId > -1) { + previousActive = sidebar.find(".active").data("id"); sidebar.find(".networks").empty(); - $("#chat").empty(); } if (data.networks.length === 0) { @@ -45,21 +46,38 @@ socket.on("init", function(data) { $("#sign-in").remove(); } - const id = data.active; - const target = sidebar.find("[data-id='" + id + "']").trigger("click", { - replaceHistory: true - }); - const dataTarget = document.querySelector("[data-target='" + window.location.hash + "']"); - if (window.location.hash && dataTarget) { - dataTarget.click(); - } else if (target.length === 0) { - const first = sidebar.find(".chan") - .eq(0) - .trigger("click"); - if (first.length === 0) { - $("#footer").find(".connect").trigger("click", { - pushState: false, - }); - } - } + openCorrectChannel(previousActive, data.active); }); + +function openCorrectChannel(clientActive, serverActive) { + let target; + + // Open last active channel + if (clientActive > 0) { + target = sidebar.find("[data-id='" + clientActive + "']"); + } + + // Open window provided in location.hash + if (!target && window.location.hash) { + target = $("#footer, #sidebar").find("[data-target='" + escape(window.location.hash) + "']"); + } + + // Open last active channel according to the server + if (!target) { + target = sidebar.find("[data-id='" + serverActive + "']"); + } + + // If target channel is found, open it + if (target) { + target.trigger("click", { + replaceHistory: true + }); + + return; + } + + // Open the connect window + $("#footer .connect").trigger("click", { + pushState: false + }); +} diff --git a/client/js/socket-events/more.js b/client/js/socket-events/more.js index d762b542..b5f0fab6 100644 --- a/client/js/socket-events/more.js +++ b/client/js/socket-events/more.js @@ -33,7 +33,7 @@ socket.on("more", function(data) { } // Add the older messages - const documentFragment = render.buildChannelMessages(data.chan, type, data.messages); + const documentFragment = render.buildChannelMessages($(document.createDocumentFragment()), data.chan, type, data.messages); chan.prepend(documentFragment); // Move unread marker to correct spot if needed diff --git a/client/js/socket-events/network.js b/client/js/socket-events/network.js index 846a6a34..a55b0433 100644 --- a/client/js/socket-events/network.js +++ b/client/js/socket-events/network.js @@ -6,7 +6,7 @@ const render = require("../render"); const sidebar = $("#sidebar"); socket.on("network", function(data) { - render.renderNetworks(data); + render.renderNetworks(data, true); sidebar.find(".chan") .last() @@ -20,4 +20,3 @@ socket.on("network", function(data) { socket.on("network_changed", function(data) { sidebar.find("#network-" + data.network).data("options", data.serverOptions); }); -