Plugin Directory

Changeset 3453884


Ignore:
Timestamp:
02/04/2026 03:01:35 PM (8 weeks ago)
Author:
enkic
Message:

v2.4.7

Location:
ai-builder
Files:
2 added
7 edited
50 copied

Legend:

Unmodified
Added
Removed
  • ai-builder/tags/2.4.7/admin/pages/settings.php

    r3408247 r3453884  
    4646                    <th scope="row"><label for="siteDescription">Site description & context</label></th>
    4747                    <td>
    48                         <textarea name="siteDescription" id="siteDescription" class="large-text" rows="4"
     48                        <textarea name="siteDescription" id="siteDescription" class="large-text" rows="4" maxlength="500"
    4949                            placeholder="Describe your site and add any additional context that will help AI generate better content"></textarea>
     50                        <p id="siteDescription-counter" class="description" style="margin-top:4px;margin-bottom:4px;">0/500</p>
    5051                        <p class="description">Start with your site's description, then add any relevant information about your business, target audience, or specific requirements.</p>
    5152                    </td>
     
    111112            </tbody>
    112113        </table>
     114        <div id="aibui-settings-toast" style="display:none;"></div>
    113115
    114116        <p class="submit">
    115             <button type="submit" class="button button-primary">Save Settings</button>
     117            <button type="submit" class="button button-primary button-center">Save Settings</button>
    116118        </p>
    117119    </form>
    118120
    119     <div id="aibui-settings-toast" style="display:none;"></div>
    120121</div>
  • ai-builder/tags/2.4.7/aibui-builder.php

    r3443924 r3453884  
    44 * Plugin URI:        https://website-ai-builder.com/
    55 * Description: This plugin is used to build your website with AI.
    6  * Version: 2.4.6
     6 * Version: 2.4.7
    77 * Author: enkic
    88 * Author URI:        https://enkicorbin.fr/
     
    1818
    1919// Définir la version du plugin
    20 define('AIBUI_VERSION', '2.4.6');
     20define('AIBUI_VERSION', '2.4.7');
    2121
    2222/**
     
    540540    }
    541541
     542    $current_screen = get_current_screen();
    542543    // Charger les styles et scripts pour la page account du plugin AI Builder
    543     $current_screen = get_current_screen();
    544544    if ($current_screen && strpos($current_screen->id, 'aibui-assistant') !== false) {
    545545        wp_enqueue_style(
     
    755755            )
    756756        );
     757    }
     758
     759    // Bandeau de review : uniquement sur les pages admin du plugin
     760    if ($current_screen) {
     761        $screen_id = $current_screen->id;
     762        $is_plugin_screen =
     763            strpos($screen_id, 'aibui-assistant') !== false ||
     764            strpos($screen_id, 'aibui-credits') !== false ||
     765            strpos($screen_id, 'aibui-tuto') !== false ||
     766            strpos($screen_id, 'aibui-multi-page') !== false ||
     767            strpos($screen_id, 'aibui-agent-chat') !== false ||
     768            strpos($screen_id, 'aibui-translation-settings') !== false ||
     769            strpos($screen_id, 'aibui-settings') !== false;
     770
     771        if ($is_plugin_screen) {
     772            // S'assurer que config.js est chargé
     773            wp_enqueue_script(
     774                'ai-builder-config',
     775                plugin_dir_url(__FILE__) . 'config.js',
     776                [],
     777                AIBUI_VERSION,
     778                true
     779            );
     780            wp_enqueue_script(
     781                'ai-builder-review-banner',
     782                plugin_dir_url(__FILE__) . 'assets/js/review-banner.js',
     783                ['ai-builder-config'],
     784                AIBUI_VERSION,
     785                true
     786            );
     787            wp_localize_script(
     788                'ai-builder-review-banner',
     789                'aiBuilderReviewVars',
     790                array(
     791                    'ajaxurl'   => admin_url('admin-ajax.php'),
     792                    'nonce'     => wp_create_nonce('aibui_nonce'),
     793                    'reviewUrl' => 'https://wordpress.org/support/plugin/ai-builder/reviews/#new-post',
     794                )
     795            );
     796        }
    757797    }
    758798
  • ai-builder/tags/2.4.7/assets/css/settings.css

    r3397412 r3453884  
    1515}
    1616
    17 .ai-builder-settings > p {
     17.ai-builder-settings>p {
    1818  margin-top: 0;
    1919  margin-bottom: 28px;
     
    113113}
    114114
     115.ai-builder-settings .submit {
     116  margin-top: 32px;
     117  text-align: center;
     118}
     119
    115120.ai-builder-settings .submit .button-primary:hover {
    116121  transform: translateY(-1px);
     
    154159  }
    155160}
    156 
  • ai-builder/tags/2.4.7/assets/js/chat-widget.js

    r3443924 r3453884  
    5959    "beforeend",
    6060    `
    61       <div id="chat-toggle">🤖 AI Builder</div>
     61      <div id="chat-toggle">AI Builder</div>
    6262      <div id="chat-box">
    6363        <div id="chat-header">
     
    7777        <div id="chat-messages"></div>
    7878        <div id="chat-input">
    79           <textarea placeholder="Create a modern pricing page with 3 plans and call-to-action buttons..." rows="2"></textarea>
     79          <textarea placeholder="Create a modern pricing page with 3 plans and call-to-action buttons..." rows="2" maxlength="2000"></textarea>
     80          <div id="chat-char-counter">0/2000</div>
    8081          <button>Generate</button>
    8182          <button id="chat-undo" style="display: none;">Undo</button>
     
    131132  const input = document.querySelector("#chat-input textarea");
    132133  const sendBtn = document.querySelector("#chat-input button");
     134  const charCounter = document.getElementById("chat-char-counter");
    133135  const undoBtn = document.getElementById("chat-undo");
    134136  let chatHistory = [];
     137
     138  const MAX_CHAT_CHARS = 2000;
     139
     140  // Met à jour le compteur de caractères du chat
     141  function updateChatCharCounter() {
     142    if (!input || !charCounter) return;
     143    const currentLength = input.value.length;
     144    // Sécurité : tronquer si, pour une raison quelconque, on dépasse la limite
     145    if (currentLength > MAX_CHAT_CHARS) {
     146      input.value = input.value.slice(0, MAX_CHAT_CHARS);
     147    }
     148    charCounter.textContent = `${input.value.length}/${MAX_CHAT_CHARS}`;
     149  }
     150
     151  if (input) {
     152    input.addEventListener("input", updateChatCharCounter);
     153    // Initialiser l'affichage du compteur
     154    updateChatCharCounter();
     155  }
     156
     157  // Indicateur de saisie de l'IA (3 points animés)
     158  function createTypingIndicator() {
     159    if (!messages) return null;
     160    let indicator = document.getElementById("chat-typing-indicator");
     161    if (!indicator) {
     162      indicator = document.createElement("div");
     163      indicator.id = "chat-typing-indicator";
     164      indicator.innerHTML = `
     165        <span class="typing-dot"></span>
     166        <span class="typing-dot"></span>
     167        <span class="typing-dot"></span>
     168      `;
     169    }
     170    return indicator;
     171  }
     172
     173  function showTypingIndicator() {
     174    if (!messages) return;
     175    const indicator = createTypingIndicator();
     176    if (!indicator) return;
     177    if (!messages.contains(indicator)) {
     178      messages.appendChild(indicator);
     179    }
     180  }
     181
     182  function hideTypingIndicator() {
     183    const indicator = document.getElementById("chat-typing-indicator");
     184    if (indicator && indicator.parentNode) {
     185      indicator.parentNode.removeChild(indicator);
     186    }
     187  }
    135188
    136189  function getChatStorageKey() {
     
    292345    if (!messages) return;
    293346
     347    // Si un indicateur de saisie est présent, le garder toujours en bas
     348    const typingIndicator = document.getElementById("chat-typing-indicator");
     349    if (typingIndicator && typingIndicator.parentNode === messages) {
     350      messages.removeChild(typingIndicator);
     351    }
     352
    294353    const messageDiv = document.createElement("div");
    295354    messageDiv.className = type === "assistant" ? "ai-message" : "user-message";
    296355
    297356    if (type === "assistant") {
    298       messageDiv.innerHTML = `<strong>🤖</strong> ${message}`;
     357      messageDiv.innerHTML = `${message}`;
    299358    } else {
    300       messageDiv.innerHTML = `<strong>👤</strong> ${message}`;
     359      messageDiv.innerHTML = `${message}`;
    301360    }
    302361
    303362    messages.appendChild(messageDiv);
     363
     364    // Ré‑ajouter l'indicateur de saisie en bas si nécessaire
     365    if (typingIndicator) {
     366      messages.appendChild(typingIndicator);
     367    }
    304368    messages.scrollTop = messages.scrollHeight;
    305369
     
    11971261    // 🔒 Désactiver le bouton + animation loading
    11981262    sendBtn.disabled = true;
    1199     sendBtn.classList.add("loading");
     1263    // sendBtn.classList.add("loading");
    12001264    sendBtn.textContent = "Generating...";
    12011265
     
    12051269    }
    12061270
     1271    // 👀 Afficher l'indicateur de saisie de l'IA
     1272    if (typeof showTypingIndicator === "function") {
     1273      showTypingIndicator();
     1274    }
     1275
    12071276    // Ajouter le message utilisateur à l'historique
    12081277    addMessage(finalQuestion, "user");
    12091278    input.value = "";
     1279    // Réinitialiser le compteur après envoi
     1280    if (typeof updateChatCharCounter === "function") {
     1281      updateChatCharCounter();
     1282    }
    12101283    messages.scrollTop = messages.scrollHeight;
    12111284
     
    13521425        toggleBtn.classList.remove("generating");
    13531426      }
     1427
     1428      // 👀 Masquer l'indicateur de saisie de l'IA
     1429      if (typeof hideTypingIndicator === "function") {
     1430        hideTypingIndicator();
     1431      }
    13541432    }
    13551433  }
     
    13671445const cssStyles = document.createElement("style");
    13681446cssStyles.textContent = `
     1447  /* Zone de saisie du chat */
     1448  #chat-input {
     1449    display: flex;
     1450    flex-direction: column;
     1451    gap: 6px;
     1452  }
     1453
     1454  #chat-input textarea {
     1455    width: 100%;
     1456    resize: vertical;
     1457  }
     1458
     1459  #chat-char-counter {
     1460    align-self: flex-end;
     1461    font-size: 11px;
     1462    color: #888;
     1463  }
     1464
     1465  /* Indicateur de saisie de l'IA */
     1466  #chat-typing-indicator {
     1467    display: inline-flex;
     1468    align-items: center;
     1469    gap: 4px;
     1470    padding: 6px 10px;
     1471    border-radius: 12px;
     1472    background-color: #f1f3f5;
     1473    color: #555;
     1474    font-size: 12px;
     1475    max-width: 80%;
     1476    margin-top: 4px;
     1477  }
     1478
     1479  #chat-typing-indicator .typing-dot {
     1480    width: 6px;
     1481    height: 6px;
     1482    border-radius: 50%;
     1483    background-color: #888;
     1484    display: inline-block;
     1485    animation: ai-typing-bounce 1s infinite ease-in-out;
     1486  }
     1487
     1488  #chat-typing-indicator .typing-dot:nth-child(2) {
     1489    animation-delay: 0.15s;
     1490  }
     1491
     1492  #chat-typing-indicator .typing-dot:nth-child(3) {
     1493    animation-delay: 0.3s;
     1494  }
     1495
     1496  @keyframes ai-typing-bounce {
     1497    0%, 60%, 100% {
     1498      transform: translateY(0);
     1499      opacity: 0.4;
     1500    }
     1501    30% {
     1502      transform: translateY(-4px);
     1503      opacity: 1;
     1504    }
     1505  }
     1506
    13691507  /* Header du chat avec bouton CSS intégré */
    13701508  #chat-header {
  • ai-builder/tags/2.4.7/assets/js/settings.js

    r3408247 r3453884  
    4141      toast.style.display = "none";
    4242    }, 4000);
     43  }
     44
     45  // Limite et compteur pour "Site description & context"
     46  const SITE_DESCRIPTION_MAX = 500;
     47  const siteDescriptionTextarea = document.getElementById("siteDescription");
     48  const siteDescriptionCounter = document.getElementById("siteDescription-counter");
     49
     50  function updateSiteDescriptionCounter() {
     51    if (!siteDescriptionTextarea || !siteDescriptionCounter) return;
     52    let value = siteDescriptionTextarea.value || "";
     53    if (value.length > SITE_DESCRIPTION_MAX) {
     54      value = value.slice(0, SITE_DESCRIPTION_MAX);
     55      siteDescriptionTextarea.value = value;
     56    }
     57    siteDescriptionCounter.textContent = `${value.length}/${SITE_DESCRIPTION_MAX}`;
     58  }
     59
     60  if (siteDescriptionTextarea && siteDescriptionCounter) {
     61    siteDescriptionTextarea.addEventListener("input", updateSiteDescriptionCounter);
     62    // Initialiser l'affichage au chargement
     63    updateSiteDescriptionCounter();
    4364  }
    4465
     
    94115      document.getElementById("secondaryColor").value = secondaryColor;
    95116      document.getElementById("siteName").value = siteName;
    96       document.getElementById("siteDescription").value = siteDescription;
     117      const siteDescriptionEl = document.getElementById("siteDescription");
     118      if (siteDescriptionEl) {
     119        siteDescriptionEl.value = siteDescription;
     120        // Mettre à jour le compteur si déjà chargé
     121        if (typeof updateSiteDescriptionCounter === "function") {
     122          updateSiteDescriptionCounter();
     123        }
     124      }
    97125
    98126      if (designStyle) {
  • ai-builder/tags/2.4.7/readme.txt

    r3443924 r3453884  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.4.6
     7Stable tag: 2.4.7
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
  • ai-builder/trunk/admin/pages/settings.php

    r3408247 r3453884  
    4646                    <th scope="row"><label for="siteDescription">Site description & context</label></th>
    4747                    <td>
    48                         <textarea name="siteDescription" id="siteDescription" class="large-text" rows="4"
     48                        <textarea name="siteDescription" id="siteDescription" class="large-text" rows="4" maxlength="500"
    4949                            placeholder="Describe your site and add any additional context that will help AI generate better content"></textarea>
     50                        <p id="siteDescription-counter" class="description" style="margin-top:4px;margin-bottom:4px;">0/500</p>
    5051                        <p class="description">Start with your site's description, then add any relevant information about your business, target audience, or specific requirements.</p>
    5152                    </td>
     
    111112            </tbody>
    112113        </table>
     114        <div id="aibui-settings-toast" style="display:none;"></div>
    113115
    114116        <p class="submit">
    115             <button type="submit" class="button button-primary">Save Settings</button>
     117            <button type="submit" class="button button-primary button-center">Save Settings</button>
    116118        </p>
    117119    </form>
    118120
    119     <div id="aibui-settings-toast" style="display:none;"></div>
    120121</div>
  • ai-builder/trunk/aibui-builder.php

    r3443924 r3453884  
    44 * Plugin URI:        https://website-ai-builder.com/
    55 * Description: This plugin is used to build your website with AI.
    6  * Version: 2.4.6
     6 * Version: 2.4.7
    77 * Author: enkic
    88 * Author URI:        https://enkicorbin.fr/
     
    1818
    1919// Définir la version du plugin
    20 define('AIBUI_VERSION', '2.4.6');
     20define('AIBUI_VERSION', '2.4.7');
    2121
    2222/**
     
    540540    }
    541541
     542    $current_screen = get_current_screen();
    542543    // Charger les styles et scripts pour la page account du plugin AI Builder
    543     $current_screen = get_current_screen();
    544544    if ($current_screen && strpos($current_screen->id, 'aibui-assistant') !== false) {
    545545        wp_enqueue_style(
     
    755755            )
    756756        );
     757    }
     758
     759    // Bandeau de review : uniquement sur les pages admin du plugin
     760    if ($current_screen) {
     761        $screen_id = $current_screen->id;
     762        $is_plugin_screen =
     763            strpos($screen_id, 'aibui-assistant') !== false ||
     764            strpos($screen_id, 'aibui-credits') !== false ||
     765            strpos($screen_id, 'aibui-tuto') !== false ||
     766            strpos($screen_id, 'aibui-multi-page') !== false ||
     767            strpos($screen_id, 'aibui-agent-chat') !== false ||
     768            strpos($screen_id, 'aibui-translation-settings') !== false ||
     769            strpos($screen_id, 'aibui-settings') !== false;
     770
     771        if ($is_plugin_screen) {
     772            // S'assurer que config.js est chargé
     773            wp_enqueue_script(
     774                'ai-builder-config',
     775                plugin_dir_url(__FILE__) . 'config.js',
     776                [],
     777                AIBUI_VERSION,
     778                true
     779            );
     780            wp_enqueue_script(
     781                'ai-builder-review-banner',
     782                plugin_dir_url(__FILE__) . 'assets/js/review-banner.js',
     783                ['ai-builder-config'],
     784                AIBUI_VERSION,
     785                true
     786            );
     787            wp_localize_script(
     788                'ai-builder-review-banner',
     789                'aiBuilderReviewVars',
     790                array(
     791                    'ajaxurl'   => admin_url('admin-ajax.php'),
     792                    'nonce'     => wp_create_nonce('aibui_nonce'),
     793                    'reviewUrl' => 'https://wordpress.org/support/plugin/ai-builder/reviews/#new-post',
     794                )
     795            );
     796        }
    757797    }
    758798
  • ai-builder/trunk/assets/css/settings.css

    r3397412 r3453884  
    1515}
    1616
    17 .ai-builder-settings > p {
     17.ai-builder-settings>p {
    1818  margin-top: 0;
    1919  margin-bottom: 28px;
     
    113113}
    114114
     115.ai-builder-settings .submit {
     116  margin-top: 32px;
     117  text-align: center;
     118}
     119
    115120.ai-builder-settings .submit .button-primary:hover {
    116121  transform: translateY(-1px);
     
    154159  }
    155160}
    156 
  • ai-builder/trunk/assets/js/chat-widget.js

    r3443924 r3453884  
    5959    "beforeend",
    6060    `
    61       <div id="chat-toggle">🤖 AI Builder</div>
     61      <div id="chat-toggle">AI Builder</div>
    6262      <div id="chat-box">
    6363        <div id="chat-header">
     
    7777        <div id="chat-messages"></div>
    7878        <div id="chat-input">
    79           <textarea placeholder="Create a modern pricing page with 3 plans and call-to-action buttons..." rows="2"></textarea>
     79          <textarea placeholder="Create a modern pricing page with 3 plans and call-to-action buttons..." rows="2" maxlength="2000"></textarea>
     80          <div id="chat-char-counter">0/2000</div>
    8081          <button>Generate</button>
    8182          <button id="chat-undo" style="display: none;">Undo</button>
     
    131132  const input = document.querySelector("#chat-input textarea");
    132133  const sendBtn = document.querySelector("#chat-input button");
     134  const charCounter = document.getElementById("chat-char-counter");
    133135  const undoBtn = document.getElementById("chat-undo");
    134136  let chatHistory = [];
     137
     138  const MAX_CHAT_CHARS = 2000;
     139
     140  // Met à jour le compteur de caractères du chat
     141  function updateChatCharCounter() {
     142    if (!input || !charCounter) return;
     143    const currentLength = input.value.length;
     144    // Sécurité : tronquer si, pour une raison quelconque, on dépasse la limite
     145    if (currentLength > MAX_CHAT_CHARS) {
     146      input.value = input.value.slice(0, MAX_CHAT_CHARS);
     147    }
     148    charCounter.textContent = `${input.value.length}/${MAX_CHAT_CHARS}`;
     149  }
     150
     151  if (input) {
     152    input.addEventListener("input", updateChatCharCounter);
     153    // Initialiser l'affichage du compteur
     154    updateChatCharCounter();
     155  }
     156
     157  // Indicateur de saisie de l'IA (3 points animés)
     158  function createTypingIndicator() {
     159    if (!messages) return null;
     160    let indicator = document.getElementById("chat-typing-indicator");
     161    if (!indicator) {
     162      indicator = document.createElement("div");
     163      indicator.id = "chat-typing-indicator";
     164      indicator.innerHTML = `
     165        <span class="typing-dot"></span>
     166        <span class="typing-dot"></span>
     167        <span class="typing-dot"></span>
     168      `;
     169    }
     170    return indicator;
     171  }
     172
     173  function showTypingIndicator() {
     174    if (!messages) return;
     175    const indicator = createTypingIndicator();
     176    if (!indicator) return;
     177    if (!messages.contains(indicator)) {
     178      messages.appendChild(indicator);
     179    }
     180  }
     181
     182  function hideTypingIndicator() {
     183    const indicator = document.getElementById("chat-typing-indicator");
     184    if (indicator && indicator.parentNode) {
     185      indicator.parentNode.removeChild(indicator);
     186    }
     187  }
    135188
    136189  function getChatStorageKey() {
     
    292345    if (!messages) return;
    293346
     347    // Si un indicateur de saisie est présent, le garder toujours en bas
     348    const typingIndicator = document.getElementById("chat-typing-indicator");
     349    if (typingIndicator && typingIndicator.parentNode === messages) {
     350      messages.removeChild(typingIndicator);
     351    }
     352
    294353    const messageDiv = document.createElement("div");
    295354    messageDiv.className = type === "assistant" ? "ai-message" : "user-message";
    296355
    297356    if (type === "assistant") {
    298       messageDiv.innerHTML = `<strong>🤖</strong> ${message}`;
     357      messageDiv.innerHTML = `${message}`;
    299358    } else {
    300       messageDiv.innerHTML = `<strong>👤</strong> ${message}`;
     359      messageDiv.innerHTML = `${message}`;
    301360    }
    302361
    303362    messages.appendChild(messageDiv);
     363
     364    // Ré‑ajouter l'indicateur de saisie en bas si nécessaire
     365    if (typingIndicator) {
     366      messages.appendChild(typingIndicator);
     367    }
    304368    messages.scrollTop = messages.scrollHeight;
    305369
     
    11971261    // 🔒 Désactiver le bouton + animation loading
    11981262    sendBtn.disabled = true;
    1199     sendBtn.classList.add("loading");
     1263    // sendBtn.classList.add("loading");
    12001264    sendBtn.textContent = "Generating...";
    12011265
     
    12051269    }
    12061270
     1271    // 👀 Afficher l'indicateur de saisie de l'IA
     1272    if (typeof showTypingIndicator === "function") {
     1273      showTypingIndicator();
     1274    }
     1275
    12071276    // Ajouter le message utilisateur à l'historique
    12081277    addMessage(finalQuestion, "user");
    12091278    input.value = "";
     1279    // Réinitialiser le compteur après envoi
     1280    if (typeof updateChatCharCounter === "function") {
     1281      updateChatCharCounter();
     1282    }
    12101283    messages.scrollTop = messages.scrollHeight;
    12111284
     
    13521425        toggleBtn.classList.remove("generating");
    13531426      }
     1427
     1428      // 👀 Masquer l'indicateur de saisie de l'IA
     1429      if (typeof hideTypingIndicator === "function") {
     1430        hideTypingIndicator();
     1431      }
    13541432    }
    13551433  }
     
    13671445const cssStyles = document.createElement("style");
    13681446cssStyles.textContent = `
     1447  /* Zone de saisie du chat */
     1448  #chat-input {
     1449    display: flex;
     1450    flex-direction: column;
     1451    gap: 6px;
     1452  }
     1453
     1454  #chat-input textarea {
     1455    width: 100%;
     1456    resize: vertical;
     1457  }
     1458
     1459  #chat-char-counter {
     1460    align-self: flex-end;
     1461    font-size: 11px;
     1462    color: #888;
     1463  }
     1464
     1465  /* Indicateur de saisie de l'IA */
     1466  #chat-typing-indicator {
     1467    display: inline-flex;
     1468    align-items: center;
     1469    gap: 4px;
     1470    padding: 6px 10px;
     1471    border-radius: 12px;
     1472    background-color: #f1f3f5;
     1473    color: #555;
     1474    font-size: 12px;
     1475    max-width: 80%;
     1476    margin-top: 4px;
     1477  }
     1478
     1479  #chat-typing-indicator .typing-dot {
     1480    width: 6px;
     1481    height: 6px;
     1482    border-radius: 50%;
     1483    background-color: #888;
     1484    display: inline-block;
     1485    animation: ai-typing-bounce 1s infinite ease-in-out;
     1486  }
     1487
     1488  #chat-typing-indicator .typing-dot:nth-child(2) {
     1489    animation-delay: 0.15s;
     1490  }
     1491
     1492  #chat-typing-indicator .typing-dot:nth-child(3) {
     1493    animation-delay: 0.3s;
     1494  }
     1495
     1496  @keyframes ai-typing-bounce {
     1497    0%, 60%, 100% {
     1498      transform: translateY(0);
     1499      opacity: 0.4;
     1500    }
     1501    30% {
     1502      transform: translateY(-4px);
     1503      opacity: 1;
     1504    }
     1505  }
     1506
    13691507  /* Header du chat avec bouton CSS intégré */
    13701508  #chat-header {
  • ai-builder/trunk/assets/js/settings.js

    r3408247 r3453884  
    4141      toast.style.display = "none";
    4242    }, 4000);
     43  }
     44
     45  // Limite et compteur pour "Site description & context"
     46  const SITE_DESCRIPTION_MAX = 500;
     47  const siteDescriptionTextarea = document.getElementById("siteDescription");
     48  const siteDescriptionCounter = document.getElementById("siteDescription-counter");
     49
     50  function updateSiteDescriptionCounter() {
     51    if (!siteDescriptionTextarea || !siteDescriptionCounter) return;
     52    let value = siteDescriptionTextarea.value || "";
     53    if (value.length > SITE_DESCRIPTION_MAX) {
     54      value = value.slice(0, SITE_DESCRIPTION_MAX);
     55      siteDescriptionTextarea.value = value;
     56    }
     57    siteDescriptionCounter.textContent = `${value.length}/${SITE_DESCRIPTION_MAX}`;
     58  }
     59
     60  if (siteDescriptionTextarea && siteDescriptionCounter) {
     61    siteDescriptionTextarea.addEventListener("input", updateSiteDescriptionCounter);
     62    // Initialiser l'affichage au chargement
     63    updateSiteDescriptionCounter();
    4364  }
    4465
     
    94115      document.getElementById("secondaryColor").value = secondaryColor;
    95116      document.getElementById("siteName").value = siteName;
    96       document.getElementById("siteDescription").value = siteDescription;
     117      const siteDescriptionEl = document.getElementById("siteDescription");
     118      if (siteDescriptionEl) {
     119        siteDescriptionEl.value = siteDescription;
     120        // Mettre à jour le compteur si déjà chargé
     121        if (typeof updateSiteDescriptionCounter === "function") {
     122          updateSiteDescriptionCounter();
     123        }
     124      }
    97125
    98126      if (designStyle) {
  • ai-builder/trunk/readme.txt

    r3443924 r3453884  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.4.6
     7Stable tag: 2.4.7
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
Note: See TracChangeset for help on using the changeset viewer.