From 96ee0393205e59bfaff8bf53c22e2b2a3796823a Mon Sep 17 00:00:00 2001 From: tuseto Date: Tue, 7 Nov 2023 13:48:55 +0200 Subject: [PATCH] Process image and video on stream (#56) * asd * something * Video and image from stream implemented * 1.0.45 * fix initial video does not show * init media after the message --- __tests__/unit/chat-ui.spec.js | 26 ++++++-- __tests__/unit/socket-services.spec.js | 4 ++ package-lock.json | 4 +- package.json | 2 +- src/lib/chat-ui.js | 85 +++++++++++++------------- src/lib/chat-widgets.js | 3 + src/lib/socket-services.js | 3 +- src/lib/styles.js | 1 + 8 files changed, 78 insertions(+), 50 deletions(-) diff --git a/__tests__/unit/chat-ui.spec.js b/__tests__/unit/chat-ui.spec.js index 58a2fa3..3737b20 100644 --- a/__tests__/unit/chat-ui.spec.js +++ b/__tests__/unit/chat-ui.spec.js @@ -211,7 +211,7 @@ describe('ChatUi', () => { test('that initial buttons are not appended from assistant if actions number is 10', () => { const element = document.createElement('span'); element.appendChild = jest.fn(); - sut.getLastMessageElement = jest.fn().mockReturnValue(element); + sut.getLastMessageElementConsistingMessage = jest.fn().mockReturnValue(element); actionService.handleAction = jest.fn().mockReturnValue(document.createElement('div')); sut.word = jest.fn(); @@ -224,7 +224,7 @@ describe('ChatUi', () => { test('that initial buttons are appended from assistant if actions number is 10', () => { const element = document.createElement('span'); element.appendChild = jest.fn(); - sut.getLastMessageElement = jest.fn().mockReturnValue(element); + sut.getLastMessageElementConsistingMessage = jest.fn().mockReturnValue(element); actionService.handleAction = jest.fn().mockReturnValue(document.createElement('div')); sut.word = jest.fn(); @@ -476,7 +476,7 @@ describe('ChatUi', () => { sut.historyTraverse([{ content: 'element1' }, { content: 'element2' }]); - expect(sut.initMedia).toBeCalledTimes(1); + expect(sut.initMedia).toBeCalledTimes(2); expect(sut.appendHtml).toBeCalledTimes(2); expect(sut.appendHtml).toBeCalledWith({ content: 'element1' }, false); expect(sut.appendHtml).toBeCalledWith({ content: 'element2' }, true); @@ -493,7 +493,7 @@ describe('ChatUi', () => { expect(sut.appendHtml).toBeCalledTimes(1); expect(sut.appendHtml).toBeCalledWith({ content: 'element2' }, true); expect(sut.initNewLine).toBeCalledTimes(1); - expect(sut.initMedia).toBeCalledTimes(1); + expect(sut.initMedia).toBeCalledTimes(2); }); }); @@ -725,5 +725,23 @@ describe('appendMedia calls the proper media markup', () => { expect(imageMarkupSpy).toBeCalledTimes(1); expect(videoMarkupSpy).not.toBeCalled(); }); + + test('set image fullscreen', () => { + document.body.innerHTML = '
'; + + var fullScreenImageContainer = document.querySelector('.fullscreen-background-filter'); + var fullScreenImage = fullScreenImageContainer.querySelector('img'); + + expect(fullScreenImageContainer.classList.contains("show-image")).toBeFalsy(); + expect(fullScreenImage.src).toBe("http://localhost/initial-src") + + document.querySelector('.media-image').click(); + + var fullScreenImageContainer = document.querySelector('.fullscreen-background-filter'); + var fullScreenImage = fullScreenImageContainer.querySelector('img'); + + expect(fullScreenImageContainer.classList.contains("show-image")).toBeTruthy(); + expect(fullScreenImage.src).toBe("http://localhost/image-to-show") + }); }); diff --git a/__tests__/unit/socket-services.spec.js b/__tests__/unit/socket-services.spec.js index 8d3da92..21b7a3b 100644 --- a/__tests__/unit/socket-services.spec.js +++ b/__tests__/unit/socket-services.spec.js @@ -33,6 +33,7 @@ describe('socket-services', () => { getLastMessageElement: jest.fn().mockImplementationOnce(() => document.querySelector('div')), processTextInCaseOfSquareBrackets: jest.fn(), processTextInCaseOfCurlyBrackets: jest.fn(), + processStringInCaseOfAngleBrackets: jest.fn(), elements: { messageIncrementor: { appendChild: jest.fn() }, }, @@ -72,6 +73,7 @@ describe('socket-services', () => { const state = { setCtaButton: jest.fn(), getLastMessageElement: ChatUi.getLastMessageElement, + getLastMessageElementConsistingMessage: ChatUi.getLastMessageElementConsistingMessage, elements: { messageIncrementor: document.querySelector('#message-incrementor') }, }; jest.spyOn(input, 'show'); @@ -114,6 +116,7 @@ describe('socket-services', () => { const state = { setCtaButton: jest.fn(), getLastMessageElement: ChatUi.getLastMessageElement, + getLastMessageElementConsistingMessage: ChatUi.getLastMessageElementConsistingMessage, elements: { messageIncrementor: document.querySelector('#message-incrementor'), promptContainer: document.querySelector('#prompt-container'), @@ -163,6 +166,7 @@ describe('socket-services', () => { const state = { setCtaButton: jest.fn(), getLastMessageElement: ChatUi.getLastMessageElement, + getLastMessageElementConsistingMessage: ChatUi.getLastMessageElementConsistingMessage, elements: { messageIncrementor: document.querySelector('#message-incrementor'), promptContainer: document.querySelector('#prompt-container'), diff --git a/package-lock.json b/package-lock.json index dea6013..37532ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "1ff-chat-ui", - "version": "1.0.44", + "version": "1.0.45", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "1ff-chat-ui", - "version": "1.0.44", + "version": "1.0.45", "license": "ISC", "dependencies": { "socket.io-client": "^4.6.1" diff --git a/package.json b/package.json index ddd9df3..aa1023a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "1ff-chat-ui", - "version": "1.0.44", + "version": "1.0.45", "description": "chatbot to communicate with taught ai", "main": "src/lib/chat-ui.js", "scripts": { diff --git a/src/lib/chat-ui.js b/src/lib/chat-ui.js index c2efd92..a15c05a 100644 --- a/src/lib/chat-ui.js +++ b/src/lib/chat-ui.js @@ -130,6 +130,17 @@ const ChatUi = { this.setDomContent(); this.setSocket(); this.setIntentionEvents(); + this.setImageFullScreen(); + }, + setImageFullScreen() { + document.querySelector('body').addEventListener('click', (e) => { + console.log('document', document); + if (e.target.classList.contains('media-image')) { + const fullScreen = document.querySelector('.fullscreen-background-filter'); + fullScreen.querySelector('img').src = e.target.src; + fullScreen.classList.toggle('show-image'); + } + }); }, setIntentionEvents() { intentions.on(intentionType.emailError, (response) => { @@ -222,7 +233,6 @@ const ChatUi = { historyTraverse(history) { let counter = 1; let isLastMessage = false; - history.forEach((data) => { let appended = false; @@ -235,20 +245,19 @@ const ChatUi = { isLastMessage = true; } if (counter === 1) { - this.initMedia(data.content); if (data.content.includes('^')) { appended = true; + this.initMedia(data.content); this.initNewLine(data, isLastMessage); } } if (!appended) { this.appendHtml(data, isLastMessage); + this.initMedia(data.content); } counter++; }); - - this.addImageAction(); }, initNewLine(data, isLastMessage) { const splittedContent = splitText(data.content, '^'); @@ -262,18 +271,8 @@ const ChatUi = { this.appendHtml(newData, isLastMessage); } }, - addImageAction() { - const images = document.querySelectorAll('.media-image'); - images.forEach((img) => { - img.addEventListener('click', () => { - const fullScreen = document.querySelector('.fullscreen-background-filter'); - fullScreen.classList.toggle('show-image'); - }); - }); - }, initMedia(content) { const link = getStringInAngleBrackets(content); - const extractedLink = link[0]; if (extractedLink) { this.appendMedia(extractedLink); @@ -387,6 +386,19 @@ const ChatUi = { this.boldedText = ''; } }, + processStringInCaseOfAngleBrackets() { + if (this.chunk.includes('<')) { + this.answersFromStream = this.chunk; + } + + if (this.answersFromStream.includes('>')) { + this.answersFromStream = this.answersFromStream.replace('<', '').replace('>', ''); + console.log('this.answersFromStream', this.answersFromStream); + this.appendMedia(this.answersFromStream); + this.answersFromStream = ''; + this.chunk = ''; + } + }, refreshLocalStorageHistory(history) { localStorage.setItem(STORAGE_KEY, JSON.stringify(history)); }, @@ -412,7 +424,7 @@ const ChatUi = { } }, addOptions() { - const element = this.getLastMessageElement('.assistant'); + const element = this.getLastMessageElementConsistingMessage('.assistant'); const answerConfig = getAnswerConfig(this.answersFromStream); const answersContainer = document.createElement('div'); const moveBtnNumber = '10'; @@ -438,6 +450,21 @@ const ChatUi = { this.elements.messageIncrementor.querySelectorAll(role).length - 1 ]; }, + getLastMessageElementConsistingMessage(role) { + const parentElements = this.elements.messageIncrementor.querySelectorAll(role); + var lastElement = null; + + for (let i = parentElements.length - 1; i >= 0; i--) { + const parent = parentElements[i]; + const child1 = parent.querySelector('.js-assistant-message'); + if (child1) { + lastElement = parent; + break; // Exit the loop as soon as a match is found + } + } + + return lastElement; + }, isFirstUserMessage() { let history = JSON.parse(localStorage.getItem(STORAGE_KEY)) || []; @@ -602,7 +629,7 @@ const ChatUi = { this.appendHtml(data); } - this.addImageAction(); + // this.addImageAction(); if (extractedString) { this.hideInput(extractedString); } @@ -626,31 +653,6 @@ const ChatUi = { } }, - /** - * Shows the image on full screen on click - */ - fullScreenImage() { - const link = getStringInAngleBrackets(this.assistant.initialMessage.content); - const extractedLink = link[0]; - const img = document.createElement('img'); - const background = document.createElement('div'); - const imgWrapper = document.createElement('div'); - const closeMark = document.createElement('span'); - - closeMark.innerHTML = `×`; - img.classList.add('media-image'); - imgWrapper.classList.add('fullscreen-image-wrapper'); - background.classList.add('fullscreen-background-filter'); - closeMark.classList.add('close-mark'); - - img.src = `${extractedLink}`; - imgWrapper.appendChild(img); - imgWrapper.appendChild(closeMark); - background.appendChild(imgWrapper); - this.elements.chatbotContainer.appendChild(background); - closeMark.addEventListener('click', () => background.classList.remove('show-image')); - }, - /** * * @param {*} extractedLink @@ -663,7 +665,6 @@ const ChatUi = { mediaBody.appendChild(videoMarkup(extractedLink)); } else { mediaBody.appendChild(imageMarkup(extractedLink)); - this.fullScreenImage(); } this.elements.messageIncrementor.appendChild(mediaBody); }, diff --git a/src/lib/chat-widgets.js b/src/lib/chat-widgets.js index 1886eb9..f903ecd 100644 --- a/src/lib/chat-widgets.js +++ b/src/lib/chat-widgets.js @@ -49,6 +49,7 @@ export const chatMarkup = (config) => `
+ ${imageFullscreen} `; export const initiatorProfile = (config) => { @@ -147,6 +148,8 @@ export const paymentButton = (translations) => ``; +export const imageFullscreen = `
×
` + export const closePaymentFormButton = `