From 64f9d713daf0f7b5c87eb3ae61335bb023c62612 Mon Sep 17 00:00:00 2001 From: rainbow napkin Date: Mon, 6 Oct 2025 04:48:17 -0400 Subject: [PATCH] PMHandler now tracks unread messages and lights pm icon to notify user. --- www/css/theme/movie-night.css | 1 + www/js/channel/panels/pmPanel.js | 31 ++++++++----- www/js/channel/pmHandler.js | 75 ++++++++++++++++++++++++++++++-- 3 files changed, 92 insertions(+), 15 deletions(-) diff --git a/www/css/theme/movie-night.css b/www/css/theme/movie-night.css index 5ce7db6..439002d 100644 --- a/www/css/theme/movie-night.css +++ b/www/css/theme/movie-night.css @@ -168,6 +168,7 @@ textarea{ .positive-low{ color: var(--focus0); + text-shadow: var(--focus-glow0-alt0); } .inactive{ diff --git a/www/js/channel/panels/pmPanel.js b/www/js/channel/panels/pmPanel.js index 4af334f..b908858 100644 --- a/www/js/channel/panels/pmPanel.js +++ b/www/js/channel/panels/pmPanel.js @@ -32,10 +32,23 @@ class pmPanel extends panelObj{ */ this.activeSesh = ""; + /** + * Random UUID to identify the panel with the pmHandler + */ + this.uuid = crypto.randomUUID(); + + //Tell PMHandler to start tracking this panel + this.client.pmHandler.panelList.set(this.uuid, null); + this.defineListeners(); } closer(){ + //Tell PMHandler to start tracking this panel + this.client.pmHandler.panelList.delete(this.uuid); + + //Run derived closer + super.closer(); } docSwitch(){ @@ -146,6 +159,9 @@ class pmPanel extends panelObj{ //Set the first one as active this.activeSesh = seshList[0][1].id; + + //Tell PMHandler what sesh we have open for notification reasons + this.client.pmHandler.readSesh(this.uuid, this.activeSesh); } //For each session tracked by the pmHandler @@ -202,6 +218,9 @@ class pmPanel extends panelObj{ //Set new sesh as active sesh event.target.classList.add('positive'); + //Tell PMHandler what sesh we have open for notification reasons + this.client.pmHandler.readSesh(this.uuid, this.activeSesh); + //Re-render message buffer this.renderMessages(); } @@ -296,18 +315,6 @@ class startSeshPopup{ startSesh(event){ //If we clicked or hit enter if(event.key == null || event.key == "Enter"){ - /* - //Cook a new sesh from - const newSesh = new pmSesh({ - //Split usernames by space - sender: this.client.user.user, - recipients: this.usernamePrompt.value.split(" ") - }); - - //Pop new sesh into pmHandler - this.client.pmHandler.seshList.set(newSesh.id, newSesh); - */ - //Send message out to server this.client.pmSocket.emit("pm", { recipients: this.usernamePrompt.value.split(" "), diff --git a/www/js/channel/pmHandler.js b/www/js/channel/pmHandler.js index ac5417b..6553edb 100644 --- a/www/js/channel/pmHandler.js +++ b/www/js/channel/pmHandler.js @@ -38,6 +38,11 @@ class pmHandler{ */ this.seshList = new Map(); + /** + * List of open PM Panels + */ + this.panelList = new Map(); + this.defineListeners(); this.setupInput(); } @@ -66,10 +71,11 @@ class pmHandler{ //Store whether or not current message has been consumed by an existing sesh let consumed = false; - const nameObj = pmHandler.genSeshName(data); + //Store whether or not we have this sesh open in an existing PMPanel + let displayed = false; - //Create members array from scratch to avoid changing the input data for further processing - const members = nameObj.recipients; + //Pull session name from static generation method + const nameObj = pmHandler.genSeshName(data); //For each existing sesh for(const seshEntry of this.seshList){ @@ -81,6 +87,24 @@ class pmHandler{ //Dump collected message into the matching session sesh.messages.push(data); + //Set sesh to unread + sesh.unread = true; + + //For each open PM Panel + for(const panel of this.panelList){ + //If sesh ID matches an open sesh in an existing panel + if(sesh.id == panel[1]){ + //Set sesh to read + sesh.unread = false; + } + } + + //If the message was unread + if(sesh.unread){ + //Notify user of new message/sesh + this.handlePing(); + } + //Add sesh to sesh map this.seshList.set(sesh.id, sesh); @@ -94,11 +118,51 @@ class pmHandler{ //Generate a new sesh const sesh = new pmSesh(data, client); + //Notify user of new message/sesh + this.handlePing(); + //Add it to the sesh list this.seshList.set(sesh.id, sesh); } } + handlePing(){ + //Light up the icon + this.pmIcon.classList.add('positive-low'); + } + + //Handles UI updates after reading all messages + checkAllRead(){ + //For each sesh + for(const sesh of this.seshList){ + //If a sesh is unread + if(sesh.unread){ + //LOOK OUT BOYS, THIS ONE'S BEEN READ! CHEESE IT! + return; + } + } + + //Unlight the icon + this.pmIcon.classList.remove('positive-low'); + } + + readSesh(panelID, seshID){ + //Set current sesh for panel + this.panelList.set(panelID, seshID); + + //Get requested session + const sesh = this.seshList.get(seshID); + + //Set it to unread + sesh.unread = false; + + //Commit sesh back to sesh list + this.seshList.set(sesh.id, sesh); + + //Check if all messages are read and handle em' if they are + this.checkAllRead(); + } + static genSeshName(message){ const recipients = []; @@ -153,6 +217,11 @@ class pmSesh{ */ this.id = nameObj.name; + /** + * Whether or not we have unread messages within the session + */ + this.unread = true; + /** * Array containing all session messages */