Plugin Directory

Changeset 3384431


Ignore:
Timestamp:
10/25/2025 11:27:21 AM (4 months ago)
Author:
mxchat
Message:

Fixed PDF encoding issue when hyperlinking PDF URLs and improved model selection process with the new openrouter.

Location:
mxchat-basic
Files:
103 added
7 edited

Legend:

Unmodified
Added
Removed
  • mxchat-basic/trunk/css/admin-style.css

    r3379814 r3384431  
    36583658}
    36593659
    3660 .mxchat-model-selector-modal .mxchat-model-selector-card {
     3660.mxchat-model-selector-modal .mxchat-model-selector-card,
     3661.mxchat-model-selector-modal .mxchat-openrouter-card {
    36613662    display: flex;
    36623663    border: 1px solid #ddd;
     
    36683669}
    36693670
    3670 .mxchat-model-selector-modal .mxchat-model-selector-card:hover {
     3671.mxchat-model-selector-modal .mxchat-model-selector-card:hover,
     3672.mxchat-model-selector-modal .mxchat-openrouter-card:hover {
    36713673    border-color: #6750A4;
    36723674    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    36733675}
    36743676
    3675 .mxchat-model-selector-modal .mxchat-model-selector-card.mxchat-model-selected {
     3677.mxchat-model-selector-modal .mxchat-model-selector-card.mxchat-model-selected,
     3678.mxchat-model-selector-modal .mxchat-openrouter-card.mxchat-model-selected {
    36763679    border-color: #6750A4;
    36773680    background-color: rgba(103, 80, 164, 0.05);
  • mxchat-basic/trunk/includes/class-mxchat-addons.php

    r3381226 r3384431  
    191191     */
    192192    public function enqueue_styles() {
    193         $plugin_version = '2.4.9';
     193        $plugin_version = '2.5.0';
    194194
    195195        wp_enqueue_style(
  • mxchat-basic/trunk/includes/class-mxchat-admin.php

    r3381226 r3384431  
    66486648public function mxchat_enqueue_admin_assets() {
    66496649    // Get plugin version (define this in your main plugin file)
    6650     $version = defined('MXCHAT_VERSION') ? MXCHAT_VERSION : '2.4.9';
     6650    $version = defined('MXCHAT_VERSION') ? MXCHAT_VERSION : '2.5.0';
    66516651
    66526652    // Use file modification time for development (remove in production)
  • mxchat-basic/trunk/includes/class-mxchat-integrator.php

    r3381226 r3384431  
    67016701public function mxchat_enqueue_scripts_styles() {
    67026702    // Define version numbers for the styles and scripts
    6703     $chat_style_version = '2.4.9';
    6704     $chat_script_version = '2.4.9';
     6703    $chat_style_version = '2.5.0';
     6704    $chat_script_version = '2.5.0';
    67056705    // Enqueue the script
    67066706    wp_enqueue_script(
  • mxchat-basic/trunk/js/mxchat-admin.js

    r3379814 r3384431  
    10521052$(document).on('click', '.mxchat-model-selector-card', function() {
    10531053    const modelValue = $(this).data('value');
    1054     const $modelSelect = $('#model'); // Add this line to ensure we have the element
    1055    
     1054    const $modelSelect = $('#model');
     1055    const $clickedCard = $(this);
     1056
    10561057    // Check if OpenRouter was selected
    10571058    if (modelValue === 'openrouter') {
     
    10591060        loadOpenRouterModels();
    10601061    } else {
    1061         // Normal model selection
    1062         $modelSelect.val(modelValue).trigger('change');
    1063        
    1064         // Manually save the model via AJAX
    1065         jQuery.ajax({
    1066             url: mxchatAdmin.ajax_url,
    1067             type: 'POST',
    1068             data: {
    1069                 action: 'mxchat_save_setting',
    1070                 name: 'model',
    1071                 value: modelValue,
    1072                 _ajax_nonce: mxchatAdmin.setting_nonce
    1073             },
    1074             success: function(response) {
    1075                 if (response.success) {
    1076                     // Update button text after successful save
    1077                     const selectedModelText = $modelSelect.find('option:selected').text();
    1078                     $('#mxchat_model_selector_btn').text(selectedModelText);
     1062        // Remove selection from all other cards
     1063        $('.mxchat-model-selector-card').removeClass('mxchat-model-selected').find('.mxchat-model-selector-checkmark').remove();
     1064
     1065        // Add selection to clicked card immediately for instant feedback
     1066        $clickedCard.addClass('mxchat-model-selected');
     1067        if ($clickedCard.find('.mxchat-model-selector-checkmark').length === 0) {
     1068            $clickedCard.append('<div class="mxchat-model-selector-checkmark">✓</div>');
     1069        }
     1070
     1071        // Brief delay to show the selection, then start saving
     1072        setTimeout(function() {
     1073            // Normal model selection
     1074            $modelSelect.val(modelValue).trigger('change');
     1075
     1076            // Show loading state on the card
     1077            $clickedCard.css('pointer-events', 'none');
     1078            const originalContent = $clickedCard.find('.mxchat-model-selector-title').html();
     1079            $clickedCard.find('.mxchat-model-selector-title').html(
     1080                '<span class="spinner is-active" style="float: none; margin: 0 5px 0 0;"></span> Saving...'
     1081            );
     1082
     1083            // Manually save the model via AJAX
     1084            jQuery.ajax({
     1085                url: mxchatAdmin.ajax_url,
     1086                type: 'POST',
     1087                data: {
     1088                    action: 'mxchat_save_setting',
     1089                    name: 'model',
     1090                    value: modelValue,
     1091                    _ajax_nonce: mxchatAdmin.setting_nonce
     1092                },
     1093                success: function(response) {
     1094                    if (response.success) {
     1095                        // Show success state
     1096                        $clickedCard.find('.mxchat-model-selector-title').html(
     1097                            '<span class="dashicons dashicons-yes" style="color: #46b450; margin-top: 3px;"></span> Saved!'
     1098                        );
     1099
     1100                        // Update button text after successful save
     1101                        const selectedModelText = $modelSelect.find('option:selected').text();
     1102                        $('#mxchat_model_selector_btn').text(selectedModelText);
     1103
     1104                        // Close modal after a short delay to show the success message
     1105                        setTimeout(function() {
     1106                            $('#mxchat_model_selector_modal').hide();
     1107                            // Restore original content and remove selection for next time
     1108                            $clickedCard.find('.mxchat-model-selector-title').html(originalContent);
     1109                            $clickedCard.removeClass('mxchat-model-selected').find('.mxchat-model-selector-checkmark').remove();
     1110                            $clickedCard.css('pointer-events', 'auto');
     1111                        }, 600);
     1112                    } else {
     1113                        // Show error state
     1114                        $clickedCard.find('.mxchat-model-selector-title').html(
     1115                            '<span class="dashicons dashicons-no" style="color: #dc3232;"></span> Error!'
     1116                        );
     1117
     1118                        setTimeout(function() {
     1119                            $clickedCard.find('.mxchat-model-selector-title').html(originalContent);
     1120                            $clickedCard.removeClass('mxchat-model-selected').find('.mxchat-model-selector-checkmark').remove();
     1121                            $clickedCard.css('pointer-events', 'auto');
     1122                        }, 1500);
     1123                    }
     1124                },
     1125                error: function() {
     1126                    // Show error state
     1127                    $clickedCard.find('.mxchat-model-selector-title').html(
     1128                        '<span class="dashicons dashicons-no" style="color: #dc3232;"></span> Error!'
     1129                    );
     1130
     1131                    setTimeout(function() {
     1132                        $clickedCard.find('.mxchat-model-selector-title').html(originalContent);
     1133                        $clickedCard.removeClass('mxchat-model-selected').find('.mxchat-model-selector-checkmark').remove();
     1134                        $clickedCard.css('pointer-events', 'auto');
     1135                    }, 1500);
    10791136                }
    1080             }
    1081         });
    1082        
    1083         $('#mxchat_model_selector_modal').hide();
     1137            });
     1138        }, 300); // 300ms delay to show the selection before starting to save
    10841139    }
    10851140});
     
    12201275function rebindModalEventHandlers() {
    12211276    const $modal = $('#mxchat_model_selector_modal');
    1222    
     1277
    12231278    // Re-bind category button clicks
    12241279    $('.mxchat-model-category-btn').off('click').on('click', function() {
     
    12291284        window.populateModelsGrid(searchTerm, category);
    12301285    });
    1231    
     1286
    12321287    // Re-bind search input
    12331288    $('#mxchat_model_search_input').off('input').on('input', function() {
     
    12381293}
    12391294
     1295function restoreDefaultModalFooter() {
     1296    const $modalFooter = $('#mxchat_model_selector_modal').find('.mxchat-model-selector-modal-footer');
     1297
     1298    // Restore default footer buttons
     1299    $modalFooter.html(`
     1300        <button id="mxchat_cancel_model_selection" class="button mxchat-model-cancel-btn">Cancel</button>
     1301    `);
     1302
     1303    // Re-bind cancel button
     1304    $('#mxchat_cancel_model_selection').on('click', function() {
     1305        $('#mxchat_model_selector_modal').hide();
     1306    });
     1307}
     1308
    12401309function displayOpenRouterModels(models) {
    12411310    const $modal = $('#mxchat_model_selector_modal');
    12421311    const $modalBody = $modal.find('.mxchat-model-selector-modal-body');
     1312    const $modalFooter = $modal.find('.mxchat-model-selector-modal-footer');
    12431313    const currentSelected = $('#openrouter_selected_model').val();
    1244    
     1314
     1315    // Variable to store the currently selected model (in the UI, not yet saved)
     1316    let pendingSelection = {
     1317        modelId: currentSelected || null,
     1318        modelName: $('#openrouter_selected_model_name').val() || null
     1319    };
     1320
    12451321    // Build new modal content with search and models
    12461322    const newContent = `
     
    12481324            <input type="text" id="mxchat_openrouter_search" class="mxchat-model-search-input" placeholder="Search OpenRouter models...">
    12491325            <p style="margin: 10px 0; color: #666; font-size: 13px;">
    1250                 <strong>${models.length} models available</strong> · 
     1326                <strong>${models.length} models available</strong> ·
    12511327                <a href="#" id="mxchat_back_to_provider_select" style="color: #2271b1;">← Back to providers</a>
    12521328            </p>
     
    12541330        <div class="mxchat-model-selector-grid" id="mxchat_openrouter_models_grid"></div>
    12551331    `;
    1256    
     1332
     1333    // Update footer with Save button for OpenRouter
     1334    const footerContent = `
     1335        <button id="mxchat_back_to_models_footer" class="button mxchat-model-cancel-btn">Back to Providers</button>
     1336        <button id="mxchat_save_openrouter_model" class="button button-primary" disabled>
     1337            <span class="dashicons dashicons-saved" style="margin-top: 3px;"></span> Save Selected Model
     1338        </button>
     1339    `;
     1340
    12571341    $modalBody.html(newContent);
     1342    $modalFooter.html(footerContent);
    12581343   
    12591344    // Function to render models
     
    12611346        const $grid = $('#mxchat_openrouter_models_grid');
    12621347        $grid.empty();
    1263        
     1348
    12641349        let filteredModels = models;
    12651350        if (filterText) {
    12661351            const lowerFilter = filterText.toLowerCase();
    1267             filteredModels = models.filter(m => 
     1352            filteredModels = models.filter(m =>
    12681353                m.id.toLowerCase().includes(lowerFilter) ||
    12691354                m.name.toLowerCase().includes(lowerFilter) ||
     
    12711356            );
    12721357        }
    1273        
     1358
    12741359        filteredModels.forEach(model => {
    1275             const isSelected = currentSelected === model.id;
     1360            const isSelected = pendingSelection.modelId === model.id;
    12761361            const contextLength = model.context_length ? `${(model.context_length / 1000).toFixed(0)}K` : '';
    12771362            const promptPrice = model.pricing.prompt ? `$${(model.pricing.prompt * 1000000).toFixed(2)}/1M` : '';
    1278            
     1363
    12791364            const $card = jQuery(`
    1280                 <div class="mxchat-model-selector-card mxchat-openrouter-card ${isSelected ? 'mxchat-model-selected' : ''}" data-model-id="${model.id}">
     1365                <div class="mxchat-openrouter-card ${isSelected ? 'mxchat-model-selected' : ''}" data-model-id="${model.id}" data-model-name="${model.name}">
    12811366                    <div class="mxchat-model-selector-icon">
    12821367                        ${getOpenRouterIcon(model.id)}
     
    12921377                </div>
    12931378            `);
    1294            
     1379
    12951380            $grid.append($card);
    12961381        });
     
    13191404    $('#mxchat_back_to_provider_select').on('click', function(e) {
    13201405        e.preventDefault();
     1406        // Restore footer to default state
     1407        restoreDefaultModalFooter();
    13211408        // Instead of location.reload(), restore original content
    13221409        restoreOriginalModalContent();
    13231410    });
    1324    
    1325 // Model selection
    1326 $(document).on('click', '.mxchat-openrouter-card', function() {
    1327     const modelId = $(this).data('model-id');
    1328     const modelName = models.find(m => m.id === modelId)?.name || modelId;
    1329    
    1330     // First, save that we're using OpenRouter
    1331     jQuery.ajax({
    1332         url: mxchatAdmin.ajax_url,
    1333         type: 'POST',
    1334         data: {
    1335             action: 'mxchat_save_setting',
    1336             name: 'model',
    1337             value: 'openrouter',
    1338             _ajax_nonce: mxchatAdmin.setting_nonce
    1339         },
    1340         success: function() {
    1341             // After model is set, save the model ID
    1342             jQuery.ajax({
    1343                 url: mxchatAdmin.ajax_url,
    1344                 type: 'POST',
    1345                 data: {
    1346                     action: 'mxchat_save_setting',
    1347                     name: 'openrouter_selected_model',
    1348                     value: modelId,
    1349                     _ajax_nonce: mxchatAdmin.setting_nonce
    1350                 },
    1351                 success: function() {
    1352                     // Update DOM immediately
    1353                     $('#openrouter_selected_model').val(modelId);
    1354                    
    1355                     // After model ID is saved, save the display name
    1356                     jQuery.ajax({
    1357                         url: mxchatAdmin.ajax_url,
    1358                         type: 'POST',
    1359                         data: {
    1360                             action: 'mxchat_save_setting',
    1361                             name: 'openrouter_selected_model_name',
    1362                             value: modelName,
    1363                             _ajax_nonce: mxchatAdmin.setting_nonce
    1364                         },
    1365                         success: function() {
    1366                             // Update DOM immediately
    1367                             $('#openrouter_selected_model_name').val(modelName);
    1368                            
    1369                             // Update button text
    1370                             $('#mxchat_model_selector_btn').text('OpenRouter: ' + modelName);
    1371                         }
    1372                     });
    1373                 }
    1374             });
    1375         }
    1376     });
    1377    
    1378     // Close modal
    1379     $modal.hide();
    1380 });
     1411
     1412    // Back to providers footer button
     1413    $('#mxchat_back_to_models_footer').on('click', function(e) {
     1414        e.preventDefault();
     1415        // Restore footer to default state
     1416        restoreDefaultModalFooter();
     1417        // Restore original content
     1418        restoreOriginalModalContent();
     1419    });
     1420
     1421    // Model selection - just highlight, don't save yet
     1422    $(document).on('click', '.mxchat-openrouter-card', function(e) {
     1423        e.stopPropagation(); // Prevent triggering the regular model card handler
     1424
     1425        const modelId = $(this).data('model-id');
     1426        const modelName = $(this).data('model-name');
     1427
     1428        // Remove selection from all cards
     1429        $('.mxchat-openrouter-card').removeClass('mxchat-model-selected').find('.mxchat-model-selector-checkmark').remove();
     1430
     1431        // Add selection to clicked card
     1432        $(this).addClass('mxchat-model-selected');
     1433        if ($(this).find('.mxchat-model-selector-checkmark').length === 0) {
     1434            $(this).append('<div class="mxchat-model-selector-checkmark">✓</div>');
     1435        }
     1436
     1437        // Update pending selection
     1438        pendingSelection.modelId = modelId;
     1439        pendingSelection.modelName = modelName;
     1440
     1441        // Enable the save button
     1442        $('#mxchat_save_openrouter_model').prop('disabled', false);
     1443    });
     1444
     1445    // Save button handler
     1446    $('#mxchat_save_openrouter_model').on('click', function() {
     1447        const $saveButton = $(this);
     1448
     1449        if (!pendingSelection.modelId) {
     1450            return;
     1451        }
     1452
     1453        // Disable button and show loading state
     1454        $saveButton.prop('disabled', true).html('<span class="spinner is-active" style="float: none; margin: 0 5px 0 0;"></span> Saving...');
     1455
     1456        // First, save that we're using OpenRouter
     1457        jQuery.ajax({
     1458            url: mxchatAdmin.ajax_url,
     1459            type: 'POST',
     1460            data: {
     1461                action: 'mxchat_save_setting',
     1462                name: 'model',
     1463                value: 'openrouter',
     1464                _ajax_nonce: mxchatAdmin.setting_nonce
     1465            },
     1466            success: function() {
     1467                // After model is set, save the model ID
     1468                jQuery.ajax({
     1469                    url: mxchatAdmin.ajax_url,
     1470                    type: 'POST',
     1471                    data: {
     1472                        action: 'mxchat_save_setting',
     1473                        name: 'openrouter_selected_model',
     1474                        value: pendingSelection.modelId,
     1475                        _ajax_nonce: mxchatAdmin.setting_nonce
     1476                    },
     1477                    success: function() {
     1478                        // Update DOM immediately
     1479                        $('#openrouter_selected_model').val(pendingSelection.modelId);
     1480
     1481                        // After model ID is saved, save the display name
     1482                        jQuery.ajax({
     1483                            url: mxchatAdmin.ajax_url,
     1484                            type: 'POST',
     1485                            data: {
     1486                                action: 'mxchat_save_setting',
     1487                                name: 'openrouter_selected_model_name',
     1488                                value: pendingSelection.modelName,
     1489                                _ajax_nonce: mxchatAdmin.setting_nonce
     1490                            },
     1491                            success: function() {
     1492                                // Update DOM immediately
     1493                                $('#openrouter_selected_model_name').val(pendingSelection.modelName);
     1494
     1495                                // Update button text
     1496                                $('#mxchat_model_selector_btn').text('OpenRouter: ' + pendingSelection.modelName);
     1497
     1498                                // Update the "Currently using" message
     1499                                const $currentSelection = $('#openrouter-current-selection');
     1500                                if ($currentSelection.length) {
     1501                                    $currentSelection.html(
     1502                                        '<span class="dashicons dashicons-yes" style="font-size: 16px; vertical-align: middle;"></span> ' +
     1503                                        'Currently using: <strong>' + pendingSelection.modelName + '</strong>'
     1504                                    ).show();
     1505                                }
     1506
     1507                                // Show success state briefly
     1508                                $saveButton.html('<span class="dashicons dashicons-yes" style="color: #46b450; margin-top: 3px;"></span> Saved!');
     1509
     1510                                // Close modal after short delay
     1511                                setTimeout(function() {
     1512                                    // Restore footer to default state
     1513                                    restoreDefaultModalFooter();
     1514                                    $modal.hide();
     1515                                }, 800);
     1516                            },
     1517                            error: function() {
     1518                                $saveButton.prop('disabled', false).html('<span class="dashicons dashicons-saved" style="margin-top: 3px;"></span> Save Selected Model');
     1519                                alert('Failed to save model name. Please try again.');
     1520                            }
     1521                        });
     1522                    },
     1523                    error: function() {
     1524                        $saveButton.prop('disabled', false).html('<span class="dashicons dashicons-saved" style="margin-top: 3px;"></span> Save Selected Model');
     1525                        alert('Failed to save model ID. Please try again.');
     1526                    }
     1527                });
     1528            },
     1529            error: function() {
     1530                $saveButton.prop('disabled', false).html('<span class="dashicons dashicons-saved" style="margin-top: 3px;"></span> Save Selected Model');
     1531                alert('Failed to save OpenRouter selection. Please try again.');
     1532            }
     1533        });
     1534    });
    13811535
    13821536}
  • mxchat-basic/trunk/mxchat-basic.php

    r3381226 r3384431  
    44 * Plugin URI: https://mxchat.ai/
    55 * Description: AI chatbot for WordPress with OpenAI, Claude, xAI, DeepSeek, live agent, PDF uploads, WooCommerce, and training on website data.
    6  * Version: 2.4.9
     6 * Version: 2.5.0
    77 * Author: MxChat
    88 * Author URI: https://mxchat.ai
     
    1818
    1919// Define plugin version constant for asset versioning
    20 define('MXCHAT_VERSION', '2.4.9');
     20define('MXCHAT_VERSION', '2.5.0');
    2121
    2222function mxchat_load_textdomain() {
  • mxchat-basic/trunk/readme.txt

    r3381226 r3384431  
    66Tested up to: 6.8
    77Requires PHP: 7.2
    8 Stable tag: 2.4.9
     8Stable tag: 2.5.0
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    181181== Changelog ==
    182182
    183 = 2.4.9 - October 20, 2025 =
    184 - Fix: Resolved pagination links not displaying in Knowledge Base Manager
     183= 2.5.0 - October 25, 2025 =
     184- Fix: Resolved PDF URL encoding issue that caused broken links to PDF documents
     185- Fix: Improved UI feedback when selecting chat models
     186- Fix: Enhanced OpenRouter flow selection interface
    185187
    186188= 2.4.8 - October 16, 2025 =
     
    560562* Fixed error when users didn't have WooCommerce it would return "Error communicating with server".
    561563
    562 == Upgrade Notice ==
    563 
    564 = 2.4.9 =
    565 - Fix: Resolved pagination links not displaying in Knowledge Base Manager
     564== Changelog ==
     565
     566= 2.5.0 =
     567* Fix: Resolved PDF URL encoding issue that caused broken links to PDF documents
     568* Fix: Improved UI feedback when selecting chat models
    566569
    567570== License & Warranty ==
Note: See TracChangeset for help on using the changeset viewer.