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

MxChat – AI Chatbot &amp; Content Generation for WordPress, version 1.0.10. 362 lines.

- Page: https://pluginprobe.com/plugins/mxchat-basic/1.0.10/code/js/chat-script.js
- Raw: https://pluginprobe.com/plugins/mxchat-basic/1.0.10/raw/js/chat-script.js
- Modified: 2024-09-19T00:52:48+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.0.10/code/js/chat-script.js#L10-L20`.

````javascript
jQuery(document).ready(function($) {
    // Check if floating chatbot button exists
    var floatingButton = $('#floating-chatbot-button');

    // Retrieve color settings from PHP
    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;
    // Retrieve link target setting (passed from PHP through wp_localize_script)
    var linkTarget = mxchatChat.link_target === 'on' ? '_blank' : '_self'; // Explicitly check for 'on' or 'off'

    // 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
    function appendMessage(sender, message, isTemporary = false) {
        var messageClass = sender === "user" ? "user-message" : "bot-message";
        var bgColor = sender === "user" ? mxchatChat.user_message_bg_color : mxchatChat.bot_message_bg_color;
        var fontColor = sender === "user" ? mxchatChat.user_message_font_color : mxchatChat.bot_message_font_color;

        var messageDiv = $('<div>').addClass(messageClass).css({
            'background': bgColor,
            'color': fontColor
        });

        if (sender === "assistant") {
            var codeRegex = /```([^]+)```/; // Regex to detect code blocks
            var match = codeRegex.exec(message);
            message = linkify(message);

            if (match) {
                var beforeCode = message.substring(0, match.index);
                var codePart = match[1]; // Extracted code content
                var afterCode = message.substring(match.index + match[0].length);

                if (beforeCode.trim()) {
                    messageDiv.append($('<span>').html(convertNewlinesToBreaks(beforeCode)));
                }

                var codeBlock = $('<pre>').append($('<code>').text(codePart));
                var copyButton = $('<button>').text('Copy').addClass('copy-btn');
                messageDiv.append(codeBlock).append(copyButton);

                copyButton.on('click', function() {
                    copyToClipboard(codePart);
                    alert('Code copied to clipboard!');
                });

                if (afterCode.trim()) {
                    messageDiv.append($('<span>').html(convertNewlinesToBreaks(afterCode)));
                }
            } else {
                messageDiv.html(formatBoldText(convertNewlinesToBreaks(message)));
            }
        } else {
            messageDiv.html(formatBoldText(convertNewlinesToBreaks(message)));
        }

        if (isTemporary) {
            messageDiv.addClass('temporary-message'); // Add a class for temporary messages
        }

        messageDiv.hide().appendTo('#chat-box').fadeIn(300); // Fade in the new message
    }

    // 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();

        // 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", newMessage);
            return; // Exit the function to prevent replacing the rate limit message
        }
        if (lastMessageDiv.length) {
            lastMessageDiv.fadeOut(200, function() {
                // Replace the content and fade in
                $(this).html(newMessage).removeClass('temporary-message').fadeIn(200);
            });
        } else {
            appendMessage(sender, newMessage);
        }
        scrollToBottom();
    }

    function scrollToBottom() {
        var chatBox = $('#chat-box');
        var newMessage = chatBox.children().last();

        // Calculate the position to scroll to
        // which is the top of the last message
        var positionToScroll = newMessage.position().top + chatBox.scrollTop();

        // Animate the scrolling to the calculated position
        chatBox.animate({
            scrollTop: positionToScroll
        }, 500);
    }

    // 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();
    }

    // Retrieve the custom rate limit message
    var rateLimitMessage = mxchatChat.rate_limit_message || "Rate limit exceeded. Please try again later.";

    // Call MxChat API
   function callMxChat(message, callback) {
        $.ajax({
            url: mxchatChat.ajax_url,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'mxchat_handle_chat_request',
                message: message,
                nonce: mxchatChat.nonce
            },
            success: function(response) {
                //console.log("API Response:", response);
                removeThinkingDots();
    
                if (response.message && typeof response.message === 'string') {
                    // Handle the valid response
                    var botMessage = linkify(response.message);
                    botMessage = convertNewlinesToBreaks(botMessage);
                    callback(botMessage);
                } else if (response.error) {
                    // Handle errors returned by the server
                    appendMessage("bot", response.error.message || "An unexpected error occurred.");
                } else {
                    // Handle unexpected formats
                    //console.log("Unexpected API response format:", response);
                    appendMessage("bot", "An unexpected response was received. Please try again.");
                }
            },
            error: function(jqXHR, textStatus, errorThrown) {
                //console.error("AJAX Error:", textStatus, errorThrown);
                removeThinkingDots(); 
                appendMessage("bot", "Error communicating with the server.");
            }
        });
    }


    // 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', '');
        }
    }

    // Show and fade in the chat widget after a delay
    function showAndFadeInChatWidget() {
        // Wait for 5 seconds before showing and starting the fade-in
        setTimeout(function() {
            $('#floating-chatbot-button').css('display', 'flex').fadeTo(500, 1);
            $('#pre-chat-message').fadeIn(500); // Fade in the pre-chat message
        }, 250);
    }

    // Call the function when the document is ready
    showAndFadeInChatWidget();

    // 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);
        });
    }
    
    
});

````
