diff --git a/client/css/style.css b/client/css/style.css index 08f6006a..d776988a 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -1483,6 +1483,15 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */ } #connection-error { + font-size: 12px; + line-height: 36px; + font-weight: bold; + letter-spacing: 1px; + word-spacing: 3px; + text-transform: uppercase; + background: #e74c3c; + color: #fff; + text-align: center; display: none; } diff --git a/client/index.html b/client/index.html index cdce541f..61abcde2 100644 --- a/client/index.html +++ b/client/index.html @@ -63,7 +63,7 @@
- +
diff --git a/client/js/render.js b/client/js/render.js index cb0adc36..9e18ffe7 100644 --- a/client/js/render.js +++ b/client/js/render.js @@ -35,6 +35,10 @@ function buildChannelMessages(chanId, chanType, messages) { } function appendMessage(container, chanId, chanType, msg) { + if (utils.lastMessageId < msg.id) { + utils.lastMessageId = msg.id; + } + let lastChild = container.children(".msg, .date-marker-container").last(); const renderedMessage = buildChatMessage(msg); diff --git a/client/js/socket-events/auth.js b/client/js/socket-events/auth.js index 6cdf923f..cb0ef4ee 100644 --- a/client/js/socket-events/auth.js +++ b/client/js/socket-events/auth.js @@ -10,6 +10,7 @@ socket.on("auth", function(data) { // And we will reload the page to grab the latest version if (utils.serverHash > -1 && data.serverHash > -1 && data.serverHash !== utils.serverHash) { socket.disconnect(); + $("#connection-error").text("Server restarted, reloading…"); location.reload(true); return; } @@ -40,7 +41,7 @@ socket.on("auth", function(data) { token = storage.get("token"); if (token) { - $("#loading-page-message").text("Authorizing…"); + $("#loading-page-message, #connection-error").text("Authorizing…"); socket.emit("auth", { user: user, diff --git a/client/js/socket-events/init.js b/client/js/socket-events/init.js index cd66f391..f200a834 100644 --- a/client/js/socket-events/init.js +++ b/client/js/socket-events/init.js @@ -6,11 +6,22 @@ const render = require("../render"); const webpush = require("../webpush"); const sidebar = $("#sidebar"); const storage = require("../localStorage"); +const utils = require("../utils"); socket.on("init", function(data) { - $("#loading-page-message").text("Rendering…"); + $("#loading-page-message, #connection-error").text("Rendering…"); + + const lastMessageId = utils.lastMessageId; + + // TODO: this is hacky + if (lastMessageId > -1) { + sidebar.find(".networks").empty(); + $("#chat").empty(); + } if (data.networks.length === 0) { + sidebar.find(".empty").show(); + $("#footer").find(".connect").trigger("click", { pushState: false, }); @@ -18,16 +29,22 @@ socket.on("init", function(data) { render.renderNetworks(data); } - if (data.token) { - storage.set("token", data.token); + if (lastMessageId > -1) { + $("#connection-error").removeClass("shown"); + $(".show-more-button, #input").prop("disabled", false); + $("#submit").show(); + } else { + if (data.token) { + storage.set("token", data.token); + } + + webpush.configurePushNotifications(data.pushSubscription, data.applicationServerKey); + + $("body").removeClass("signed-out"); + $("#loading").remove(); + $("#sign-in").remove(); } - webpush.configurePushNotifications(data.pushSubscription, data.applicationServerKey); - - $("body").removeClass("signed-out"); - $("#loading").remove(); - $("#sign-in").remove(); - const id = data.active; const target = sidebar.find("[data-id='" + id + "']").trigger("click", { replaceHistory: true diff --git a/client/js/socket.js b/client/js/socket.js index a646ad47..c5593f90 100644 --- a/client/js/socket.js +++ b/client/js/socket.js @@ -3,6 +3,7 @@ const $ = require("jquery"); const io = require("socket.io-client"); const path = window.location.pathname + "socket.io/"; +const status = $("#loading-page-message, #connection-error"); const socket = io({ transports: $(document.body).data("transports"), @@ -11,37 +12,16 @@ const socket = io({ reconnection: !$(document.body).hasClass("public") }); -window.lounge_socket = socket; // TODO: Remove later, this is for debugging +socket.on("disconnect", handleDisconnect); +socket.on("connect_error", handleDisconnect); +socket.on("error", handleDisconnect); -[ - "connect_error", - "connect_failed", - "disconnect", - "error", -].forEach(function(e) { - socket.on(e, function(data) { - $("#loading-page-message").text("Connection failed: " + data); - $("#connection-error").addClass("shown").one("click", function() { - window.onbeforeunload = null; - window.location.reload(); - }); - - // Disables sending a message by pressing Enter. `off` is necessary to - // cancel `inputhistory`, which overrides hitting Enter. `on` is then - // necessary to avoid creating new lines when hitting Enter without Shift. - // This is fairly hacky but this solution is not permanent. - $("#input").off("keydown").on("keydown", function(event) { - if (event.which === 13 && !event.shiftKey) { - event.preventDefault(); - } - }); - // Hides the "Send Message" button - $("#submit").hide(); - }); +socket.on("reconnecting", function(attempt) { + status.text(`Reconnecting… (attempt ${attempt})`); }); socket.on("connecting", function() { - $("#loading-page-message").text("Connecting…"); + status.text("Connecting…"); }); socket.on("connect", function() { @@ -54,7 +34,15 @@ socket.on("connect", function() { }); socket.on("authorized", function() { - $("#loading-page-message").text("Loading messages…"); + status.text("Loading messages…"); }); +function handleDisconnect(data) { + const message = data.message || data; + + status.text(`Waiting to reconnect… (${message})`).addClass("shown"); + $(".show-more-button, #input").prop("disabled", true); + $("#submit").hide(); +} + module.exports = socket; diff --git a/client/themes/crypto.css b/client/themes/crypto.css index 9b7bf72b..2f9f5424 100644 --- a/client/themes/crypto.css +++ b/client/themes/crypto.css @@ -65,12 +65,8 @@ a:hover, background: #00ff0e; } -.btn-reconnect { +#connection-error { background: #f00; - color: #fff; - border: 0; - border-radius: 0; - margin: 0; } #settings .opt { diff --git a/client/themes/example.css b/client/themes/example.css index a8efcbf9..d9764ac1 100644 --- a/client/themes/example.css +++ b/client/themes/example.css @@ -46,14 +46,6 @@ body { border-radius: 2px; } -.btn-reconnect { - background: #e74c3c; - color: #fff; - border: 0; - border-radius: 0; - margin: 0; -} - @media (max-width: 768px) { #sidebar { left: -220px; diff --git a/client/themes/morning.css b/client/themes/morning.css index 856c530c..0b576e8d 100644 --- a/client/themes/morning.css +++ b/client/themes/morning.css @@ -205,14 +205,6 @@ body { color: #99a2b4; } -.btn-reconnect { - background: #e74c3c; - color: #fff; - border: 0; - border-radius: 0; - margin: 0; -} - /* Form elements */ #chat-container ::-moz-placeholder { diff --git a/client/themes/zenburn.css b/client/themes/zenburn.css index 21aabd23..e4823cdf 100644 --- a/client/themes/zenburn.css +++ b/client/themes/zenburn.css @@ -232,14 +232,6 @@ body { color: #d2d39b; } -.btn-reconnect { - background: #e74c3c; - color: #fff; - border: 0; - border-radius: 0; - margin: 0; -} - /* Form elements */ #chat-container ::-moz-placeholder {