jQuery(document).ready(function($) {
//console.log('mxchatChat object:', mxchatChat);
// Initialize color settings
var userMessageBgColor = mxchatChat.user_message_bg_color;
var userMessageFontColor = mxchatChat.user_message_font_color;
var botMessageBgColor = mxchatChat.bot_message_bg_color;
var botMessageFontColor = mxchatChat.bot_message_font_color;
var linkTarget = mxchatChat.link_target === 'on' ? '_blank' : '_self';
function getChatSession() {
var sessionId = getCookie('mxchat_session_id');
//console.log("Session ID retrieved from cookie: ", sessionId);
if (!sessionId) {
sessionId = generateSessionId();
//console.log("Generated new session ID: ", sessionId);
setChatSession(sessionId);
}
//console.log("Final session ID: ", sessionId);
return sessionId;
}
function setChatSession(sessionId) {
// Set the cookie with a 24-hour expiration (86400 seconds)
document.cookie = "mxchat_session_id=" + sessionId + "; path=/; max-age=86400; SameSite=Lax";
}
// Get cookie value by name
function getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
// Generate a new session ID
function generateSessionId() {
return 'mxchat_chat_' + Math.random().toString(36).substr(2, 9);
}
// Function to handle sending a message
function sendMessage() {
var message = $('#chat-input').val();
if (message) {
appendMessage("user", message);
$('#chat-input').val('');
// Show typing indicator
appendThinkingMessage(); // Use this instead of appendMessage for the typing indicator
scrollToBottom(); // Add this line
callMxChat(message, function(response) {
// Replace typing indicator with actual response
replaceLastMessage("bot", response);
});
}
}
// Function to append a thinking message with animation
function appendThinkingMessage() {
// Remove any existing thinking dots first
$('.thinking-dots').remove();
// Retrieve the bot message font color and background color
var botMessageFontColor = mxchatChat.bot_message_font_color;
var botMessageBgColor = mxchatChat.bot_message_bg_color;
var thinkingHtml = '
' +
'
' +
'' +
'' +
'' +
'
' +
'
';
// Append the thinking dots to the chat container (or within the temporary message div)
$("#chat-box").append('
' + thinkingHtml + '
');
scrollToBottom();
}
// Trigger send button click when "Enter" key is pressed in the input field
$('#chat-input').keypress(function(e) {
if (e.which == 13) {
e.preventDefault();
$('#send-button').click();
}
});
// Handle send button click
$('#send-button').click(function() {
sendMessage();
});
// Use the linkTarget in your linkify function
function linkify(inputText) {
// Convert Markdown-style links to HTML links first
var markdownLinkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
var replacedText = inputText.replace(markdownLinkPattern, '$1');
// URLs starting with http://, https://, or ftp://, but not already inside an tag
var urlPattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[--A-Z0-9+&@#\/%=~_|])(?![^<]*<\/a>)/gim;
replacedText = replacedText.replace(urlPattern, '$1');
// URLs starting with "www." not already inside an tag
var wwwPattern = /(^|[^\/])(www\.[\S]+(\b|$))(?![^<]*<\/a>)/gim;
replacedText = replacedText.replace(wwwPattern, '$1$2');
return replacedText;
}
// Updated appendMessage function with debugging
function appendMessage(sender, message, isTemporary = false) {
var messageClass = sender === "user" ? "user-message" : "bot-message";
var bgColor = sender === "user" ? userMessageBgColor : botMessageBgColor;
var fontColor = sender === "user" ? userMessageFontColor : botMessageFontColor;
var messageDiv = $('
').addClass(messageClass).css({
'background': bgColor,
'color': fontColor
}).html(linkify(formatBoldText(convertNewlinesToBreaks(message))));
if (isTemporary) {
messageDiv.addClass('temporary-message');
}
messageDiv.hide().appendTo('#chat-box').fadeIn(300);
scrollToBottom();
}
// Function to replace the last message in the chat
// Function to replace the last message in the chat
function replaceLastMessage(sender, newMessage) {
var messageClass = sender === "user" ? "user-message" : "bot-message";
var lastMessageDiv = $('#chat-box').find('.' + messageClass + '.temporary-message').last();
// Apply linkify, formatBoldText, and convertNewlinesToBreaks to the new message
var formattedMessage = linkify(formatBoldText(convertNewlinesToBreaks(newMessage)));
// Check if the new message is the rate limit message before replacing
if (newMessage === mxchatChat.rate_limit_message) {
// Append rate limit message without replacing anything
appendMessage("bot", formattedMessage);
return; // Exit the function to prevent replacing the rate limit message
}
if (lastMessageDiv.length) {
lastMessageDiv.fadeOut(200, function() {
// Replace the content with the formatted message
$(this).html(formattedMessage).removeClass('temporary-message').fadeIn(200);
});
} else {
appendMessage(sender, formattedMessage);
}
scrollToBottom();
}
// Optimized scrollToBottom function for instant scrolling
function scrollToBottom(instant = false) {
var chatBox = $('#chat-box');
if (instant) {
// Instantly set the scroll position to the bottom
chatBox.scrollTop(chatBox.prop("scrollHeight"));
} else {
// Use requestAnimationFrame for smoother scrolling if needed
let start = null;
const scrollHeight = chatBox.prop("scrollHeight");
const initialScroll = chatBox.scrollTop();
const distance = scrollHeight - initialScroll;
const duration = 500; // Duration in ms
function smoothScroll(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
const currentScroll = initialScroll + (distance * (progress / duration));
chatBox.scrollTop(currentScroll);
if (progress < duration) {
requestAnimationFrame(smoothScroll);
} else {
chatBox.scrollTop(scrollHeight); // Ensure it's exactly at the bottom
}
}
requestAnimationFrame(smoothScroll);
}
}
// Function to format text with **bold** inside double asterisks
function formatBoldText(text) {
return text.replace(/\*\*(.*?)\*\*/g, '$1');
}
// Function to convert newline characters to HTML line breaks and handle paragraph spacing
function convertNewlinesToBreaks(text) {
var lines = text.split('\n');
var formattedText = '';
for (var i = 0; i < lines.length; i++) {
formattedText += lines[i] + ' ';
}
return formattedText;
}
// Copy to clipboard function
// Function to copy text to clipboard
function copyToClipboard(text) {
var tempInput = $('');
$('body').append(tempInput);
tempInput.val(text).select();
document.execCommand('copy');
tempInput.remove();
}
// Initialize session ID
var sessionId = getChatSession();
function callMxChat(message, callback) {
var sessionId = getChatSession();
$.ajax({
url: mxchatChat.ajax_url,
type: 'POST',
dataType: 'json',
data: {
action: 'mxchat_handle_chat_request',
message: message,
session_id: sessionId,
nonce: mxchatChat.nonce
},
success: function(response) {
//console.log("Chat response:", response);
// Check for redirect_url in the response and redirect
if (response.redirect_url) {
window.location.href = response.redirect_url;
} else if (response.message) {
callback(response.message);
}
},
error: function(xhr, status, error) {
//console.error("Error during chat message submission:", status, error);
appendMessage("bot", "Error communicating with the server.");
}
});
}
function loadChatHistory() {
var sessionId = getChatSession();
// Manually enable persistence for testing
var chatPersistenceEnabled = mxchatChat.chat_persistence_toggle === 'on'; // Reading from localized script
//console.log("Chat persistence enabled: ", chatPersistenceEnabled);
//console.log("Session ID for history loading: ", sessionId);
if (chatPersistenceEnabled && sessionId) {
//console.log("Loading chat history for session ID:", sessionId);
$.ajax({
url: mxchatChat.ajax_url,
type: 'POST',
dataType: 'json',
data: {
action: 'mxchat_fetch_conversation_history',
session_id: sessionId
},
success: function(response) {
//console.log("Chat history response:", response);
if (response.success && response.data && Array.isArray(response.data.conversation)) {
var $chatBox = $('#chat-box');
var $fragment = $(document.createDocumentFragment());
$.each(response.data.conversation, function(index, message) {
var messageElement = $('
').addClass(message.role === 'user' ? 'user-message' : 'bot-message')
.css({
'background': message.role === 'user' ? userMessageBgColor : botMessageBgColor,
'color': message.role === 'user' ? userMessageFontColor : botMessageFontColor
})
.html(linkify(formatBoldText(convertNewlinesToBreaks(message.content))));
$fragment.append(messageElement);
});
$chatBox.append($fragment);
scrollToBottom(true);
} else {
console.warn("No conversation history found.");
}
},
error: function(xhr, status, error) {
//console.error("Error loading chat history:", status, error);
appendMessage("bot", "Unable to load chat history.");
}
});
} else {
console.warn("Chat persistence is disabled or no session ID found. Not loading history.");
}
}
$(document).ready(function() {
loadChatHistory();
});
// Helper function to check if a string is an image HTML
function isImageHtml(str) {
return str.startsWith('');
}
// Function to remove thinking dots
function removeThinkingDots() {
$('.thinking-dots').closest('.temporary-message').remove();
}
function isMobile() {
// This can be a simple check, or more sophisticated detection of mobile devices
return window.innerWidth <= 768; // Example threshold for mobile devices
}
function disableScroll() {
if (isMobile()) {
$('body').css('overflow', 'hidden');
}
}
function enableScroll() {
if (isMobile()) {
$('body').css('overflow', '');
}
}
// Function to show the chatbot widget (moved outside the Complianz logic)
function showChatWidget() {
setTimeout(function() {
$('#floating-chatbot-button').css('display', 'flex').fadeTo(500, 1);
$('#pre-chat-message').fadeIn(500);
}, 250);
}
// Function to hide the chatbot widget
function hideChatWidget() {
$('#floating-chatbot-button').css('display', 'none');
$('#pre-chat-message').fadeOut(250);
}
var applyComplianzLogic = mxchatChat.complianz_toggle;
if (applyComplianzLogic) {
// Apply the Complianz logic for showing/hiding the chatbot based on consent
function checkConsentAndShowChat() {
var consentStatus = typeof cmplz_has_consent === "function" && cmplz_has_consent('marketing');
var consentType = typeof complianz !== 'undefined' ? complianz.consenttype : null;
//console.log('cmplz_has_consent("marketing"):', consentStatus);
//console.log('Complianz consent type:', consentType);
if (consentType === 'optin' && !consentStatus) {
hideChatWidget();
} else if (consentType === 'optout' && !consentStatus) {
hideChatWidget();
} else {
showChatWidget();
}
}
checkConsentAndShowChat();
$(document).on('cmplz_status_change', function(event, category) {
//console.log('Consent status changed for category:', category);
checkConsentAndShowChat();
});
} else {
// Show the chatbot by default if Complianz logic is not applied
showChatWidget();
}
// Toggle chatbot visibility on floating button click
$(document).on('click', '#floating-chatbot-button', function() {
var chatbot = $('#floating-chatbot');
if (chatbot.hasClass('hidden')) {
chatbot.removeClass('hidden').addClass('visible');
$(this).addClass('hidden');
$('#pre-chat-message').fadeOut(250); // Hide pre-chat message
disableScroll(); // Disable scroll when chatbot opens
} else {
chatbot.removeClass('visible').addClass('hidden');
$(this).removeClass('hidden');
$('#pre-chat-message').fadeIn(250); // Show pre-chat message
enableScroll(); // Enable scroll when chatbot closes
}
});
// Close button click handler for chat widget
$(document).on('click', '#exit-chat-button', function() {
$('#floating-chatbot').addClass('hidden').removeClass('visible');
$('#floating-chatbot-button').removeClass('hidden');
$('#pre-chat-message').fadeIn(250); // Show pre-chat message
enableScroll(); // Enable scroll when chatbot is minimized
});
// Close pre-chat message on click
$(document).on('click', '.close-pre-chat-message', function(e) {
e.stopPropagation(); // Prevent triggering the parent .pre-chat-message click
$('#pre-chat-message').fadeOut(200, function() {
$(this).remove();
});
});
// Open chatbot when pre-chat message is clicked
$(document).on('click', '#pre-chat-message', function() {
var chatbot = $('#floating-chatbot');
if (chatbot.hasClass('hidden')) {
chatbot.removeClass('hidden').addClass('visible');
$('#floating-chatbot-button').addClass('hidden');
$('#pre-chat-message').fadeOut(250); // Hide pre-chat message
disableScroll(); // Disable scroll when chatbot opens
}
});
// If the chatbot is initially hidden, ensure the button is visible
if ($('#floating-chatbot').hasClass('hidden')) {
$('#floating-chatbot-button').removeClass('hidden');
}
function setFullHeight() {
var vh = $(window).innerHeight() * 0.01;
$(':root').css('--vh', vh + 'px');
}
// Set the height when the page loads
$(document).ready(function() {
setFullHeight();
});
// Set the height on resize and orientation change events
$(window).on('resize orientationchange', function() {
setFullHeight();
});
var preChatMessage = document.getElementById('pre-chat-message');
var closeButton = document.querySelector('.close-pre-chat-message');
if (closeButton) {
closeButton.addEventListener('click', function() {
preChatMessage.style.display = 'none';
// Send an AJAX request to set the transient flag
var xhr = new XMLHttpRequest();
xhr.open('POST', mxchatChat.ajax_url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('action=mxchat_dismiss_pre_chat_message&_ajax_nonce=' + mxchatChat.nonce);
});
}
});