diff --git a/modules/static/charybdis.css b/modules/static/charybdis.css index d4c1db734..70d0bc942 100644 --- a/modules/static/charybdis.css +++ b/modules/static/charybdis.css @@ -2614,6 +2614,8 @@ div.main > form.search label .ircd .room div.members .menu .item { + padding-left: 0px; + padding-right: 0px; } .ircd .room div.members .menu .item .name diff --git a/modules/static/charybdis.js b/modules/static/charybdis.js index 866e0bcdf..59a3c96e3 100644 --- a/modules/static/charybdis.js +++ b/modules/static/charybdis.js @@ -71,7 +71,8 @@ mc.ready = async function(event) catch(error) { console.error("IRCd Charybdis Client: Main exited (error): " + error + " " + error.stack); - mc.unhandled(error); + //mc.unhandled(error); + mc.abort(error); } finally { diff --git a/modules/static/charybdis/io.request.js b/modules/static/charybdis/io.request.js index 96228d4d6..56ed155f6 100644 --- a/modules/static/charybdis/io.request.js +++ b/modules/static/charybdis/io.request.js @@ -161,6 +161,8 @@ mc.io.request.constructor = function(ctx = {}) // Insert request into active table. The request can be aborted hereafter. mc.io.requests.insert(this); + this.started = mc.now(); + // This should be done here for now this.xhr.open(this.ctx.method, this.ctx.url); @@ -390,6 +392,7 @@ mc.io.request.on.readystatechange = function(event) { let state = this.xhr.readyState; let handler = mc.io.request.on.readystatechange[state]; + this.event = event; // The promise is resolved for the user before the lib's handlers are called. // This is because the DONE handler has to fulfill all outstanding promises for @@ -499,40 +502,56 @@ mc.io.request.success = function(event) mc.io.request.error = function(event) { - let xhr = this.xhr; - let response = xhr.response; - let error = + let error = new mc.error( { - name: - xhr.statusText == "error"? "Network Request Error": - empty(xhr.statusText)? "abort": - xhr.statusText, - - status: - xhr.status != 0? xhr.status : "client side", - - m: - xhr.responseType == "json"? xhr.response : undefined, - message: !empty(this.reason)? this.reason: - response && xhr.responseType == "text"? - response: - "There may be a network connectivity problem.", + this.response && this.xhr.responseType == "text"? + this.xhr.responseText: + this.started + this.ctx.timeout <= mc.now()? + "timeout": + maybe(() => this.event.detail)? + this.event.detail: + undefined, + + name: + this.xhr.statusText == "error"? + "Network Request Error": + this.xhr.statusText == "abort"? + "Network Request Canceled": + !empty(this.xhr.statusText)? + this.xhr.statusText: + this.started + this.ctx.timeout <= mc.now()? + "timeout": + !empty(this.reason)? + this.reason: + !window.navigator.onLine? + "disconnected": + this.started + 10 > mc.now()? + "killed": + "timeout", + + status: + this.xhr.status != 0? this.xhr.status : "Client", + + m: + this.xhr.responseType == "json"? this.xhr.response : undefined, request_stack: this.stack, + event: + this.event, + element: this.ctx.element, - }; + }); - if(!empty(error.m)) - delete error.message; + //if(!empty(error.m)) + // delete error.message; let data = undefined; - error = new mc.error(error); mc.io.request.continuation.call(this, error, data); }; diff --git a/modules/static/charybdis/main.js b/modules/static/charybdis/main.js index 4483313fc..78c5b0733 100644 --- a/modules/static/charybdis/main.js +++ b/modules/static/charybdis/main.js @@ -101,6 +101,15 @@ mc.main.init = async function() */ mc.main.fini = async function() { + console.log("Synchronizing WebStorage..."); try + { + mc.storage.sync(); + } + catch(error) + { + console.error("Error synchronizing WebStorage: " + error); + } + console.log("Stopping remaining tasks..."); try { await mc.main.interrupt(); @@ -132,7 +141,7 @@ mc.main.fini = async function() mc.main.on_logout(); } - console.log("Synchronizing WebStorage..."); try + console.log("Resynchronizing WebStorage..."); try { mc.storage.sync(); } @@ -140,6 +149,15 @@ mc.main.fini = async function() { console.error("Error synchronizing WebStorage: " + error); } + + console.log("Final angular repaint..."); try + { + mc.ng.apply(); + } + catch(error) + { + console.error("Error repainting: " + error); + } }; /** @@ -172,13 +190,39 @@ mc.main.fault = async function(error) switch(error.status) { - case "Client Side": - if(error.name == "abort") + case "Client": + if(error.name == "disconnected") + { + console.warn("client disconnected"); + mc.unhandled(error); return false; + } + + if(error.name == "killed") + { + console.error("client fatal"); + mc.unhandled(error); + return false; + } + + if(error.name == "timeout") + { + console.warn("client timeout"); + mc.ng.root().error = undefined; + mc.ng.mc().error = undefined; + return true; + } + + console.warn("client unhandled " + error); + mc.unhandled(error); + return false; default: + console.error("fault unhandled"); throw error; } + + return false; }; /** diff --git a/modules/static/charybdis/sync.js b/modules/static/charybdis/sync.js index 6b3801aa4..3ce9c814a 100644 --- a/modules/static/charybdis/sync.js +++ b/modules/static/charybdis/sync.js @@ -46,18 +46,22 @@ mc.sync = async function(opts = {}) }); let request = mc.m.sync.get(opts); - let data = await request.response; - opts.query.since = maybe(() => data.next_batch); - - if(mc.opts.sync_debug) - debug.object(data, mc.opts.sync_debug); - - for(let key in data) { - let handler = mc.sync[key]; - if(handler !== undefined) - handler(data[key]); + let data = await request.response; + opts.query.since = maybe(() => data.next_batch); + + if(mc.opts.sync_debug) + debug.object(data, mc.opts.sync_debug); + + for(let key in data) + { + let handler = mc.sync[key]; + if(handler !== undefined) + handler(data[key]); + } } + + return true; }; mc.sync["rooms"] = function(rooms) diff --git a/modules/static/index.html b/modules/static/index.html index b8a7d7e59..c571ea726 100644 --- a/modules/static/index.html +++ b/modules/static/index.html @@ -2248,6 +2248,42 @@ type="text/ng-template" + +