From c3226a4fe10e36ad2eba5c115165a20aa41148c4 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Fri, 10 Apr 2020 13:51:36 +0200 Subject: [PATCH] Automatically reoopen conversations on page reload --- assets/css/components/calls/window.css | 27 ++++++++ assets/js/common/customEvents.js | 45 +++++++++++++ assets/js/common/ws.js | 5 +- assets/js/components/calls/controller.js | 63 ++++++++++++++++++- assets/js/components/calls/window.js | 19 +++++- .../js/components/conversations/interface.js | 22 ++++++- system/config/dev.config.php | 3 +- 7 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 assets/css/components/calls/window.css create mode 100644 assets/js/common/customEvents.js diff --git a/assets/css/components/calls/window.css b/assets/css/components/calls/window.css new file mode 100644 index 00000000..c50f90d2 --- /dev/null +++ b/assets/css/components/calls/window.css @@ -0,0 +1,27 @@ +/** + * Call window + */ + +#callsTarget { + position: fixed; + width: 100%; + height: 100%; + top: 0px; + visibility: hidden; + z-index: 1000; +} + +.call-window { + width: 300px; + min-width: 300px; + min-height: 174px; + position: absolute; + top: 100px; + right: 10px; + z-index: 100; + border: 1px black solid; + display: flex; + flex-direction: column; + background-color: #000000b3; + visibility: visible; +} \ No newline at end of file diff --git a/assets/js/common/customEvents.js b/assets/js/common/customEvents.js new file mode 100644 index 00000000..1cc8c6fa --- /dev/null +++ b/assets/js/common/customEvents.js @@ -0,0 +1,45 @@ +/** + * Base class for events on custom class management + * + * @author Pierre Hubert + */ + +class CustomEvents { + + constructor() { + + /** + * @type {Map any>>} + */ + this.evts = new Map(); + } + + /** + * Register to an event + * + * @param {string} evt The name of the event to register to + * @param {(e) => any} cb Callback function + */ + on(evt, cb) { + if(!this.evts.has(evt)) + this.evts.set(evt, []); + + this.evts.get(evt).push(cb) + } + + + /** + * Propagate a new event + * + * @param {string} evt The name of the event + * @param {any} data Data associated with the event + */ + emitEvent(evt, data) { + if(!this.evts.has(evt)) + this.evts.set(evt, []); + + this.evts.get(evt).forEach((e) => { + e(data) + }) + } +} \ No newline at end of file diff --git a/assets/js/common/ws.js b/assets/js/common/ws.js index 5444f7bd..c4d497ff 100644 --- a/assets/js/common/ws.js +++ b/assets/js/common/ws.js @@ -42,7 +42,10 @@ class UserWebSocket { this.ws = new WebSocket(url); // Wait for connection - this.ws.addEventListener("open", () => console.log("Connected to websocket!")) + this.ws.addEventListener("open", () => { + console.info("Connected to websocket!"); + SendEvent("wsOpen") + }) this.ws.addEventListener("error", (e) => this.Error(e)) this.ws.addEventListener("close", (e) => this.Closed(e)); diff --git a/assets/js/components/calls/controller.js b/assets/js/components/calls/controller.js index 27defd4d..827de2ee 100644 --- a/assets/js/components/calls/controller.js +++ b/assets/js/components/calls/controller.js @@ -25,6 +25,67 @@ class CallsController { // Create a new window for the conversation const window = new CallWindow(conv); OpenConversations.set(conv.ID, window) + this.AddToLocalStorage(conv.ID); + + window.on("close", () => { + OpenConversations.delete(conv.ID) + this.RemoveFromLocalStorage(conv.ID) + }) } -} \ No newline at end of file + + /** + * Add the conversation to local storage + * + * @param {number} convID Target conversation ID + */ + static AddToLocalStorage(convID) { + const list = this.GetListLocalStorage(); + if(!list.includes(convID)) + list.push(convID) + this.SetListLocalStorage(list) + } + + /** + * @param {number} convID Target conversation ID + */ + static RemoveFromLocalStorage(convID) { + this.SetListLocalStorage( + this.GetListLocalStorage().filter(e => e != convID) + ) + } + + /** + * @return {number[]} The ID of the opened conversations + */ + static GetListLocalStorage() { + const content = localStorage.getItem("calls") + if(content == null) + return [] + else + return JSON.parse(content).filter(e => e != null); + } + + /** + * Update the list of open calls + * + * @param {number[]} list New list + */ + static SetListLocalStorage(list) { + localStorage.setItem("calls", JSON.stringify(list)) + } +} + +document.addEventListener("wsClosed", () => { + // Close all the current conversations + OpenConversations.forEach((v) => v.Close(false)) + + OpenConversations = new Map(); +}) + + +document.addEventListener("wsOpen", () => { + CallsController.GetListLocalStorage().forEach(async c => { + CallsController.Open(await getSingleConversation(c)) + }) +}) \ No newline at end of file diff --git a/assets/js/components/calls/window.js b/assets/js/components/calls/window.js index f2abf0d9..2cff2ca4 100644 --- a/assets/js/components/calls/window.js +++ b/assets/js/components/calls/window.js @@ -5,7 +5,7 @@ */ -class CallWindow { +class CallWindow extends CustomEvents { /** * Create a new call window @@ -13,6 +13,7 @@ class CallWindow { * @param {Conversation} conv Information about the target conversation */ constructor(conv) { + super() this.construct(conv); } @@ -48,8 +49,22 @@ class CallWindow { this.closeButton = createElem2({ appendTo: windowHead.querySelector(".pull-right"), type: "a", - innerHTML: "" + innerHTML: "", + onclick: () => this.Close() }) + } + /** + * Close this window & cancel the call + * + * @param {boolean} propagate Set to true to propagate + * the event + */ + Close(propagate = true) { + this.rootEl.remove(); + + if(propagate) + this.emitEvent("closed"); + } } \ No newline at end of file diff --git a/assets/js/components/conversations/interface.js b/assets/js/components/conversations/interface.js index 1abc5d64..896a5a09 100644 --- a/assets/js/components/conversations/interface.js +++ b/assets/js/components/conversations/interface.js @@ -4,7 +4,7 @@ * @author Pierre HUBERT */ -ComunicWeb.components.conversations.interface = { +const ConversationsInterface = { /** * @var {Object} __conversationsList Cached list of conversations @@ -486,6 +486,26 @@ ComunicWeb.components.conversations.interface = { }, } +ComunicWeb.components.conversations.interface = ConversationsInterface; + + +/** + * Get information about a single conversation + * + * @param {number} convID The ID of the target conversation + */ +async function getSingleConversation(convID) { + return new Promise((res, err) => { + ConversationsInterface.getInfosOne(convID, (info) => { + if(info.error) + err(info.error) + else + res(info) + }, false) + }) +} + + //Register conversations cache cleaning function ComunicWeb.common.cacheManager.registerCacheCleaner("ComunicWeb.components.conversations.interface.emptyCache"); diff --git a/system/config/dev.config.php b/system/config/dev.config.php index abea3dfd..04aaa303 100644 --- a/system/config/dev.config.php +++ b/system/config/dev.config.php @@ -223,7 +223,7 @@ class Dev { "css/components/incognito/ui.css", //Calls component - + "css/components/calls/window.css", //Sidebar component "css/components/sidebar.css", @@ -299,6 +299,7 @@ class Dev { //Utilities "js/common/utils.js", + "js/common/customEvents.js", //Functions schema "js/common/functionsSchema.js",