From 1ce2fc3c22a1a2b3427455fdc45fea957df2e41c Mon Sep 17 00:00:00 2001 From: rainbow napkin Date: Mon, 16 Dec 2024 23:25:51 -0500 Subject: [PATCH] Finished up with implementing media link embeds in chat. --- src/app/channel/commandPreprocessor.js | 90 +++++++++++++++----------- www/css/channel.css | 5 ++ www/js/channel/chatPostprocessor.js | 31 ++++++++- www/js/channel/commandPreprocessor.js | 2 + 4 files changed, 89 insertions(+), 39 deletions(-) diff --git a/src/app/channel/commandPreprocessor.js b/src/app/channel/commandPreprocessor.js index 18d477c..547904f 100644 --- a/src/app/channel/commandPreprocessor.js +++ b/src/app/channel/commandPreprocessor.js @@ -49,12 +49,8 @@ module.exports = class commandPreprocessor{ //If we're going to relay this command as a message, continue on to chat processing if(this.sendFlag){ - //Create message from commandArray - this.message = this.commandArray.join('').trimStart(); - - //Validate links and mark them by embed type - await this.markLinks(); - + //Prep the message + await this.prepMessage(); //Send the chat this.sendChat(); } @@ -101,44 +97,56 @@ module.exports = class commandPreprocessor{ //Set standard link type var linkType = 'link'; - //Pull content type - var response = await fetch(link,{ - method: "HEAD", - }); + //Don't try this at home, we're what you call "Experts" + //TODO: Handle this shit simultaneously and send the chat before its done, then send updated types for each link as they're pulled individually + try{ + //Pull content type + var response = await fetch(link,{ + method: "HEAD", + }); - //Get file type from header - const fileType = response.headers.get('content-type'); - const fileSize = response.headers.get('content-length'); + //Get file type from header + const fileType = response.headers.get('content-type'); + const fileSize = response.headers.get('content-length'); - - //If they're reporting file types - if(fileType != null){ - //If we have an image - if(fileType.match('image/')){ - //If the file size is unreported OR it's smaller than 4MB (not all servers report this and images that big are pretty rare) - if(fileSize == null || fileSize <= maxSize){ - //Mark link as an image - linkType = 'image'; - } - //If it's a video - }else if(fileType.match('video/mp4' || 'video/webm')){ - //If the server is reporting file-size and it's reporting under 4MB (Reject unreported sizes to be on the safe side is video is huge) - if(fileSize != null && fileSize <= maxSize){ - //mark link as a video - linkType = 'video'; + //If they're reporting file types + if(fileType != null){ + //If we have an image + if(fileType.match('image/')){ + //If the file size is unreported OR it's smaller than 4MB (not all servers report this and images that big are pretty rare) + if(fileSize == null || fileSize <= maxSize){ + //Mark link as an image + linkType = 'image'; + } + //If it's a video + }else if(fileType.match('video/mp4' || 'video/webm')){ + //If the server is reporting file-size and it's reporting under 4MB (Reject unreported sizes to be on the safe side is video is huge) + if(fileSize != null && fileSize <= maxSize){ + //mark link as a video + linkType = 'video'; + } } } - } + //Probably bad form but if something happens in here I'm blaming whoever hosted the link + //maybe don't host a fucked up server and I wouldn't handle with an empty catch + }catch{}; //Add a marked link object to our links array this.links.push({ link, - linkType + type: linkType }); } } + async prepMessage(){ + //Create message from commandArray + this.message = this.commandArray.join('').trimStart(); + //Validate links and mark them by embed type + await this.markLinks(); + } + sendChat(){ //FUCKIN' SEND IT! this.chatHandler.relayUserChat(this.socket, this.message, this.chatType, this.links); @@ -153,7 +161,7 @@ class commandProcessor{ //Command keywords get run through .toLowerCase(), so we should use lowercase method names for command methods whisper(preprocessor){ - //splice out our whisper + //splice out our command preprocessor.commandArray.splice(0,2); //Mark out the current message as a whisper @@ -169,10 +177,15 @@ class commandProcessor{ //Check if the user has permission, and publicly shame them if they don't (lmao) if(chanDB != null && await chanDB.permCheck(preprocessor.socket.user, 'announce')){ - //splice out our whisper + //splice out our command preprocessor.commandArray.splice(0,2); + + //Prep the message using pre-processor functions chat-handling + await preprocessor.prepMessage(); + //send it - this.chatHandler.relayChannelAnnouncement(preprocessor.socket.chan, preprocessor.commandArray.join('')); + this.chatHandler.relayChannelAnnouncement(preprocessor.socket.chan, preprocessor.message, preprocessor.links); + //throw send flag return false; } @@ -184,10 +197,15 @@ class commandProcessor{ async serverannounce(preprocessor){ //Check if the user has permission, and publicly shame them if they don't (lmao) if(await permissionModel.permCheck(preprocessor.socket.user, 'announce')){ - //splice out our whisper + //splice out our command preprocessor.commandArray.splice(0,2); + + //Prep the message using pre-processor functions for chat-handling + await preprocessor.prepMessage(); + //send it - this.chatHandler.relayServerAnnouncement(preprocessor.commandArray.join('')); + this.chatHandler.relayServerAnnouncement(preprocessor.message, preprocessor.links); + //throw send flag return false; } diff --git a/www/css/channel.css b/www/css/channel.css index 0ebc2c3..5b46bf5 100644 --- a/www/css/channel.css +++ b/www/css/channel.css @@ -270,4 +270,9 @@ span.user-entry{ .tokewhisper{ font-size: 9pt; +} + +.chat-img, .chat-video{ + max-width: 100%; + max-height: 10em; } \ No newline at end of file diff --git a/www/js/channel/chatPostprocessor.js b/www/js/channel/chatPostprocessor.js index 0619c17..01800be 100644 --- a/www/js/channel/chatPostprocessor.js +++ b/www/js/channel/chatPostprocessor.js @@ -29,8 +29,8 @@ class chatPostprocessor{ splitBody(){ //Create an empty array to hold the body this.bodyArray = []; - //Split string by words (except for file seperator to keep link placeholders in-tact) - const splitString = this.chatBody.innerHTML.split(/(? { @@ -62,6 +62,25 @@ class chatPostprocessor{ //Inject it into the original string, and add it to string array stringArray.push(wordObj.string.replace('␜',link.outerHTML)); + }else if(wordObj.type == 'image'){ + //Create an img node from our link + const img = document.createElement('img'); + img.classList.add('chat-img'); + img.src = wordObj.link; + + //Inject it into the original string, and add it to string array + stringArray.push(wordObj.string.replace('␜',img.outerHTML)); + }else if(wordObj.type == 'video'){ + //Create a video node from our link + const vid = document.createElement('video'); + vid.classList.add('chat-video'); + vid.src = wordObj.link; + vid.controls = false; + vid.autoplay = true; + vid.loop = true; + + //Inject it into the original string, and add it to string array + stringArray.push(wordObj.string.replace('␜',vid.outerHTML)); } }); @@ -92,6 +111,12 @@ class chatPostprocessor{ } processLinks(){ + //If we don't have links + if(this.rawData.links == null){ + //Don't bother + return; + } + this.rawData.links.forEach((link, linkIndex) => { this.bodyArray.forEach((wordObj, wordIndex) => { //Check current wordobj for link (placeholder may contain whitespace with it) @@ -102,7 +127,7 @@ class chatPostprocessor{ //but we also don't want to clobber any surrounding whitespace string: wordObj.string.replace(`␜${linkIndex}␜`, '␜'), link: link.link, - type: "link" + type: link.type } } }) diff --git a/www/js/channel/commandPreprocessor.js b/www/js/channel/commandPreprocessor.js index 186c34d..2f8b158 100644 --- a/www/js/channel/commandPreprocessor.js +++ b/www/js/channel/commandPreprocessor.js @@ -39,6 +39,8 @@ class commandPreprocessor{ } processLinks(){ + //Strip out file seperators in-case the user is being a smart-ass + this.message = this.message.replaceAll('␜',''); //Split message by links var splitMessage = this.message.split(/(https?:\/\/[^\s]+)/g); //Create an empty array to hold links