230 lines
6.7 KiB
JavaScript
230 lines
6.7 KiB
JavaScript
/*Canopy - The next generation of stoner streaming software
|
|
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
|
|
|
/**
|
|
* Class for handling incoming Private Messages for the entire client
|
|
*/
|
|
class pmHandler{
|
|
/**
|
|
* Instantiates a new Private Message Handler object
|
|
* @param {channel} client - Parent client Management Object
|
|
*/
|
|
constructor(client){
|
|
/**
|
|
* Parent client management object
|
|
*/
|
|
this.client = client;
|
|
|
|
/**
|
|
* PM Icon in the main chat bar
|
|
*/
|
|
this.pmIcon = document.querySelector('#chat-panel-pm-icon');
|
|
|
|
/**
|
|
* List of PM Sessions
|
|
*/
|
|
this.seshList = new Map();
|
|
|
|
/**
|
|
* List of open PM Panels
|
|
*/
|
|
this.panelList = new Map();
|
|
|
|
this.defineListeners();
|
|
this.setupInput();
|
|
}
|
|
|
|
/**
|
|
* Defines network related event listeners for PM Handler
|
|
*/
|
|
defineListeners(){
|
|
this.client.pmSocket.on("message", this.handlePM.bind(this));
|
|
this.client.pmSocket.on("sent", this.handlePM.bind(this));
|
|
}
|
|
|
|
/**
|
|
* Defines inpet related event listeners for PM handler
|
|
*/
|
|
setupInput(){
|
|
this.pmIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new pmPanel(client))});
|
|
}
|
|
|
|
/**
|
|
* Handles received Private Messages from the PM service on the server, organizing it into the proper session from the sesh list
|
|
* Or creating a new sesh where a matching one does not a exist
|
|
* @param {object} data - Private Message data from the server
|
|
*/
|
|
handlePM(data){
|
|
//Store whether or not current message has been consumed by an existing sesh
|
|
let consumed = false;
|
|
|
|
//Store whether or not we have this sesh open in an existing PMPanel
|
|
let displayed = false;
|
|
|
|
//Pull session name from static generation method
|
|
const nameObj = pmHandler.genSeshName(data);
|
|
|
|
//For each existing sesh
|
|
for(const seshEntry of this.seshList){
|
|
//Pull sesh object from map entry
|
|
const sesh = seshEntry[1];
|
|
|
|
//If currently checked sesh ID matches calculated message sesh id
|
|
if(sesh.id == nameObj.name){
|
|
//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);
|
|
|
|
//Let the rest of the method know that we've consumed this message
|
|
consumed = true;
|
|
}
|
|
}
|
|
|
|
//If we made it through the loop without consuming the message
|
|
if(!consumed){
|
|
//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 = [];
|
|
|
|
//Manually iterate through recipients
|
|
for(const member of message.recipients){
|
|
//check to make sure we're not adding ourselves
|
|
if(member != client.user.user){
|
|
//Copy relevant array members by value instead of reference
|
|
recipients.push(member);
|
|
}
|
|
}
|
|
|
|
//If this wasn't our message
|
|
if(message.user != client.user.user){
|
|
//Push sender onto members list
|
|
recipients.push(message.user);
|
|
}
|
|
|
|
//Sort recipients
|
|
recipients.sort();
|
|
|
|
return {
|
|
name: recipients.join(', '),
|
|
recipients
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Class which represents an existing Private Messaging session between two or more users
|
|
*/
|
|
class pmSesh{
|
|
/**
|
|
* Instatiates a new pmSession object
|
|
* @param {Object} message - Initial Private Message object from server that initiated the session
|
|
*/
|
|
constructor(message, client){
|
|
/**
|
|
* Parent client management object
|
|
*/
|
|
this.client = client;
|
|
|
|
const nameObj = pmHandler.genSeshName(message);
|
|
|
|
/**
|
|
* Members of session excluding the currently logged in user
|
|
*/
|
|
this.recipients = nameObj.recipients
|
|
|
|
/**
|
|
* Name of the chat sesh, named after out-going recipients
|
|
*/
|
|
this.id = nameObj.name;
|
|
|
|
/**
|
|
* Whether or not we have unread messages within the session
|
|
*/
|
|
this.unread = true;
|
|
|
|
/**
|
|
* Array containing all session messages
|
|
*/
|
|
this.messages = (message.msg == "" || message.msg == null) ? [] : [message];
|
|
}
|
|
} |