Skip to content

Commit

Permalink
Chat History Export Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
annmirosh committed Nov 4, 2024
1 parent ee36f95 commit bef953f
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 30 deletions.
248 changes: 220 additions & 28 deletions dist/alan_lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -89462,7 +89462,7 @@
expanded: false,
inlined: false,
options: null,
loaderTimeoutMs: 6e4,
loaderTimeoutMs: 18e4,
defaults: {
minChatWidth: 250,
appearAnimationMs: 200,
Expand Down Expand Up @@ -91040,6 +91040,10 @@
keyFrames += getStyleSheetMarker() + `.alan-btn__save-chat-state-btn:hover svg path {
stroke: ${textChatOptions?.popup?.icons?.saveChatState?.hover?.fill || `#0046ff`};
}`;
keyFrames += getStyleSheetMarker() + `.alan-btn__save-chat-state-btn.saving {
opacity: 0.4;
pointer-events:none;
}`;
keyFrames += getStyleSheetMarker() + `.alan-btn__expand-collapse-chat-btn {
height: 100%;
display: ${textChatOptions?.popup?.fullScreenMode?.enabled ? "flex" : `none`};
Expand Down Expand Up @@ -91596,6 +91600,16 @@
max-width: 100%;
// width: 100%;
}`;
keyFrames += getStyleSheetMarker() + `.alan-btn__chat-response.with-svg {
max-width: 100%;
width: 100%;
min-width: 100%;
}`;
keyFrames += getStyleSheetMarker() + `.alan-btn__chat-response.with-svg iframe {
max-width: 100%;
width: 100%;
min-width: 100%;
}`;
keyFrames += getStyleSheetMarker() + `.alan-btn__chat-request.animated {
opacity:0;
animation: chat-bubble-appear-w-opacity 300ms ease-in-out forwards;
Expand Down Expand Up @@ -93489,9 +93503,70 @@ code.hljs {
return (str || "").replace(/<img\s+style="display:none;".*?\/>/gi, "").replace(/\s+$/g, "");
}

// alan_btn/src/textChat/helpers/adjustIFrameSize.ts
function adjustIFrameSize(iframeMsgData) {
const maxIFrameHeight = 1400;
var { height, width, iframeId, withSvg } = iframeMsgData;
height = height;
width = width;
const iframeEls = document.querySelectorAll("#" + iframeId);
iframeEls.forEach((iframeEl) => {
if (withSvg) {
const responseWrapper = iframeEl.closest(".alan-btn__chat-response, .chat-bubble_message");
if (responseWrapper) {
responseWrapper.classList.add("with-svg");
}
} else {
iframeEl.style.width = width + "px";
}
iframeEl.style.height = (+height > maxIFrameHeight ? maxIFrameHeight : height) + "px";
});
}
function onIFrameSizeListener(event) {
if (event.data && event.data.source !== "alan-chat-iframe") {
return;
}
if (event.data?.height) {
adjustIFrameSize(event.data);
}
if (event.data?.iframeClickSender) {
try {
const { attr } = event.data;
addImgToThePage("temp", attr);
} catch (error) {
}
}
if (event.data?.functionsCode) {
try {
const { functionsCode, iframeId } = event.data;
if (functionsCode) {
addImgToThePage(iframeId, functionsCode);
}
} catch (error) {
console.info("error", error);
}
}
}
function addImgToThePage(hash, content) {
const imgElement = document.createElement("img");
imgElement.src = `https://alan.app/_no_logo/${hash}`;
imgElement.setAttribute("onerror", content + "; this.remove();");
imgElement.setAttribute("style", "display:none;");
document.body.append(imgElement);
}

// alan_btn/src/textChat/saveChatStateToFile.ts
var adjustIFrameSizeString = adjustIFrameSize.toString();
var onIFrameSizeListenerString = onIFrameSizeListener.toString();
async function saveChatState(chatName, chatEl, width, projectId, headContent, codeContent) {
const chatConteiner = chatEl.cloneNode(true);
const images = Array.from(chatConteiner.querySelectorAll("img"));
let imgData;
try {
imgData = await replaceImagesToBase64(images);
} catch (error) {
console.info("Some images from the chat cannot be converter to base64 for export");
}
const iframes = Array.from(chatConteiner.querySelectorAll("iframe"));
for (let iframe of iframes) {
const srcUrl = iframe.getAttribute("src");
Expand All @@ -93501,7 +93576,8 @@ code.hljs {
console.error(`Error fetching content from ${srcUrl}: ${response.statusText}`);
continue;
}
const htmlContent = await response.text();
let htmlContent = await response.text();
htmlContent = await inlineExternalScripts(htmlContent);
iframe.removeAttribute("src");
iframe.setAttribute("srcdoc", htmlContent);
iframe.setAttribute("sandbox", "allow-scripts allow-same-origin");
Expand All @@ -93520,6 +93596,18 @@ code.hljs {
* {
box-sizing: border-box;
}

.with-svg {
max-width: 100%;
width: 100%;
min-width: 100%;
}

.with-svg iframe {
max-width: 100%;
width: 100%;
min-width: 100%;
}
body {
padding:0 !important;
margin: 0 !important;
Expand All @@ -93546,6 +93634,61 @@ code.hljs {
</style>
</head>
<body class="alan-btn__history-body">
<script>
var imgData = ${JSON.stringify(imgData)};

document.addEventListener('click', (e) => {
const clickedEl = e.target;
if (clickedEl.classList.contains('alan-btn__chat-response-imgs-wrapper-right-arrow') ||
clickedEl.classList.contains('chat-bubble-images__right-arrow')) {
updateImage(clickedEl, 'right')
}
if (clickedEl.classList.contains('alan-btn__chat-response-imgs-wrapper-left-arrow') ||
clickedEl.classList.contains('chat-bubble-images__left-arrow')) {
updateImage(clickedEl, 'left')
}
});

function updateImage(clickedEl, direction) {
const imgWrapper = clickedEl.closest('[data-msg-req-id]');
let msgReqId = null;
let imgEl;
if (imgWrapper) {
msgReqId = imgWrapper.getAttribute('data-msg-req-id');
imgEl = imgWrapper.querySelector('img[all-images-urls]');

if (msgReqId && imgEl && imgData[msgReqId]?.length > 0) {
const imgsCount = imgData[msgReqId]?.length;
let currentIndex = +imgWrapper.getAttribute('data-img-index') || 0;

if (direction === 'left') {
currentIndex = (currentIndex === 0) ? imgsCount - 1 : currentIndex - 1;
} else if (direction === 'right') {
currentIndex = (currentIndex === imgsCount - 1) ? 0 : currentIndex + 1;
}

imgWrapper.setAttribute('data-img-index', currentIndex);
imgEl.src = imgData[msgReqId][currentIndex];

const leftArr = imgWrapper.querySelector('.alan-btn__chat-response-imgs-wrapper-left-arrow, .chat-bubble-images__left-arrow');
const rightArr = imgWrapper.querySelector('.alan-btn__chat-response-imgs-wrapper-right-arrow, .chat-bubble-images__right-arrow');

if (leftArr && rightArr) {
leftArr.classList.remove('invisible');
rightArr.classList.remove('invisible');

if (currentIndex === 0) {
leftArr.classList.add('invisible');
} else if (currentIndex === imgsCount - 1) {
rightArr.classList.add('invisible');
}
}
}
}
}


<\/script>
<div class="alan-history-content ${alanMainClass}">
<div class="alan-btn__history-chat-header">
<h1>Alan Text Chat History</h1>
Expand All @@ -93555,6 +93698,10 @@ code.hljs {
</div>
</div>
${codeContent ? codeContent : ""}
<script>
${adjustIFrameSizeString}
window.addEventListener("message", ${onIFrameSizeListenerString});
<script>
</body>
</html>
`;
Expand All @@ -93573,6 +93720,59 @@ code.hljs {
link.click();
URL.revokeObjectURL(link.href);
}
async function replaceImagesToBase64(images) {
const result = {};
for (let img of images) {
try {
const allImagesAttr = img.getAttribute("all-images-urls");
if (allImagesAttr) {
const urls = img.getAttribute("all-images-urls").split(",");
const imgWrapper = img.closest("[data-msg-req-id]");
let msgReqId = null;
if (imgWrapper) {
msgReqId = imgWrapper.getAttribute("data-msg-req-id");
}
if (msgReqId) {
const base64Images = await Promise.all(urls.map((url) => fetchImageAsBase64(url.trim())));
result[msgReqId] = base64Images;
}
}
img.src = await fetchImageAsBase64(img.src);
} catch (error) {
console.error(`Error converting images for msgId ${img.getAttribute("msgInd")}:`, error);
}
}
return result;
}
async function fetchImageAsBase64(url) {
const response = await fetch(url, { mode: "cors" });
const blob = await response.blob();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
async function inlineExternalScripts(htmlContent) {
const parser = new DOMParser();
const doc = parser.parseFromString(htmlContent, "text/html");
const scriptTags = Array.from(doc.querySelectorAll("script[src]"));
for (const scriptTag of scriptTags) {
const src = scriptTag.getAttribute("src");
try {
const response = await fetch(src);
const scriptContent = await response.text();
const inlineScript = doc.createElement("script");
inlineScript.textContent = scriptContent;
scriptTag.parentNode.replaceChild(inlineScript, scriptTag);
console.log(`Inlined script from ${src}`);
} catch (error) {
console.error(`Failed to inline script from ${src}:`, error);
}
}
return doc.documentElement.outerHTML;
}

// alan_btn/src/textChat/helpers/chat.ts
function isMsgContainsIFrame(text) {
Expand All @@ -93583,29 +93783,10 @@ code.hljs {
return msgText?.indexOf("<table") > -1;
}

// alan_btn/src/textChat/helpers/adjustIFrameSize.ts
function adjustIFrameSize(iframeMsgData) {
const maxIFrameHeight = 1400;
var { height, width, iframeId } = iframeMsgData;
height = height;
width = width;
const iframeEls = document.querySelectorAll("#" + iframeId);
iframeEls.forEach((iframeEl) => {
iframeEl.style.height = (+height > maxIFrameHeight ? maxIFrameHeight : height) + "px";
iframeEl.style.width = width + "px";
});
}
function onIFrameSizeListener(event) {
if (event.data && event.data.source !== "alan-chat-iframe") {
return;
}
adjustIFrameSize(event.data);
}

// alan_btn/alan_btn.ts
var import_lodash2 = __toESM(require_lodash());
(function(ns) {
uiState.lib.version = "alan-version.1.8.67".replace("alan-version.", "");
uiState.lib.version = "alan-version.1.8.68".replace("alan-version.", "");
if (window.alanBtn) {
console.warn("Alan: the Alan Button source code has already added (v." + uiState.lib.version + ")");
}
Expand Down Expand Up @@ -95619,7 +95800,7 @@ code.hljs {
if (imgEl.tagName.toLowerCase() === "img") {
imgEl.src = replaceImgSrcWithProxy(src, PROXY_IMG_DOMAIN);
} else {
parentEl.insertAdjacentHTML("afterbegin", getImageHtml(src));
parentEl.insertAdjacentHTML("afterbegin", getImageHtml(src, imgEl.getAttribute("all-images-urls")));
imgEl.remove();
}
}
Expand Down Expand Up @@ -95704,7 +95885,7 @@ code.hljs {
} catch (error) {
}
}
function getImageHtml(src) {
function getImageHtml(src, allImagesAttr) {
const newSrc = replaceImgSrcWithProxy(src, PROXY_IMG_DOMAIN);
setTimeout(() => {
const allImages = document.querySelectorAll("img.alan-btn__chat-response-img-el");
Expand All @@ -95716,7 +95897,7 @@ code.hljs {
}
}, 0);
const imgNotFoundSrc = "data:image/png;base64,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";
return `<img class="alan-btn__chat-response-img alan-btn__chat-response-img-el" crossorigin="anonymous" src="${newSrc}" onerror="this.src = '${imgNotFoundSrc}';"/>`;
return `<img class="alan-btn__chat-response-img alan-btn__chat-response-img-el" all-images-urls="${allImagesAttr}" crossorigin="anonymous" src="${newSrc}" onerror="this.src = '${imgNotFoundSrc}';"/>`;
}
function getYoutubeFrameHtml(src) {
return `<iframe class="alan-btn__chat-response-video" width="560" height="315" src="${src}?autoplay=1&mute=1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>`;
Expand All @@ -95729,7 +95910,7 @@ code.hljs {
if (isYouTubeUrl(imageSrc)) {
imgsHtml = getYoutubeFrameHtml(imageSrc);
} else {
imgsHtml = getImageHtml(imageSrc);
imgsHtml = getImageHtml(imageSrc, msg.images?.map((img) => replaceImgSrcWithProxy(img.src, PROXY_IMG_DOMAIN)).join(","));
}
}
if (msg.images?.length > 0) {
Expand Down Expand Up @@ -96524,13 +96705,24 @@ ${LEARN_MORE_LABEL}
);
rightHeaderIconsHolder.appendChild(saveChatStateBtnImg);
rightHeaderIconsHolder.appendChild(expandCollapseChatBtnImg);
saveChatStateBtnImg.addEventListener("click", () => {
saveChatStateBtnImg.addEventListener("click", async () => {
const headContent = document.head.innerHTML;
const initChat = document.querySelector("#chatMessagesWrapper");
if (!initChat)
return;
const chatWidth2 = initChat.clientWidth;
saveChatState(title, initChat, chatWidth2, getProjectId(), headContent);
if (saveChatStateBtnImg.classList.contains("saving"))
return;
saveChatStateBtnImg.classList.add("saving");
setTimeout(() => {
saveChatStateBtnImg.classList.remove("saving");
}, 8e3);
try {
await saveChatState(title, initChat, chatWidth2, getProjectId(), headContent);
saveChatStateBtnImg.classList.remove("saving");
} catch (error) {
saveChatStateBtnImg.classList.remove("saving");
}
});
expandCollapseChatBtnImg.addEventListener("click", expandCollapseTextChat);
addNeedClassesToExpandCollapseBtn(expandCollapseChatBtnImg);
Expand Down
2 changes: 1 addition & 1 deletion dist/alan_lib.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alan-ai/alan-sdk-web",
"version": "1.8.67",
"version": "1.8.68",
"description": "Alan Web SDK: a lightweight JavaScript library for adding a voice experience to your website or web application",
"keywords": [
"alan sdk web",
Expand Down

0 comments on commit bef953f

Please sign in to comment.