# mxchat-basic/1.1.7/js/chat-script.js

MxChat – AI Chatbot &amp; Content Generation for WordPress, version 1.1.7. 473 lines.

- Page: https://pluginprobe.com/plugins/mxchat-basic/1.1.7/code/js/chat-script.js
- Raw: https://pluginprobe.com/plugins/mxchat-basic/1.1.7/raw/js/chat-script.js
- Modified: 2024-10-20T11:38:30+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/mxchat-basic/1.1.7/code/js/chat-script.js#L10-L20`.

```javascript
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 = '<div class="thinking-dots-container">' +
                           '<div class="thinking-dots">' +
                           '<span class="dot" style="background-color: ' + botMessageFontColor + ';"></span>' +
                           '<span class="dot" style="background-color: ' + botMessageFontColor + ';"></span>' +
                           '<span class="dot" style="background-color: ' + botMessageFontColor + ';"></span>' +
                           '</div>' +
                           '</div>';

        // Append the thinking dots to the chat container (or within the temporary message div)
        $("#chat-box").append('<div class="bot-message temporary-message" style="background-color: ' + botMessageBgColor + ';">' + thinkingHtml + '</div>');
        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, '<a href="$2" target="' + linkTarget + '">$1</a>');

        // URLs starting with http://, https://, or ftp://, but not already inside an <a> tag
        var urlPattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[--A-Z0-9+&@#\/%=~_|])(?![^<]*<\/a>)/gim;
        replacedText = replacedText.replace(urlPattern, '<a href="$1" target="' + linkTarget + '">$1</a>');

        // URLs starting with "www." not already inside an <a> tag
        var wwwPattern = /(^|[^\/])(www\.[\S]+(\b|$))(?![^<]*<\/a>)/gim;
        replacedText = replacedText.replace(wwwPattern, '$1<a href="http://$2" target="' + linkTarget + '">$2</a>');

        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 = $('<div>').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, '<strong>$1</strong>');
    }

    // 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] + '<br>';
        }

        return formattedText;
    }

    // Copy to clipboard function
    // Function to copy text to clipboard
    function copyToClipboard(text) {
        var tempInput = $('<input>');
        $('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 = $('<div>').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('<img') && str.endsWith('>');
    }

    // 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);
        });
    }
    
    
});

```
