PageSourceSearch

https://flexhub.nl/wp-content/themes/Smyler-theme/chatbot/chatbot.js?ver=1758103771

js flexhub.nl collected 2026-10-06 17:54:19 UTC 7,599 bytes, 203 lines download raw bytes

1// Dynamisch marked.js inladen
2(function() {
3  const script = document.createElement('script');
4  script.src = "https://cdn.jsdelivr.net/npm/marked/marked.min.js";
5  script.onload = function() {
6    console.log('✅ marked.js geladen');
7  };
8  document.head.appendChild(script);
9})();
10
11jQuery(function($) {
12  // Helper: laad/sla messages (JSON) op in localStorage
13  function loadMessages() {
14    try { return JSON.parse(localStorage.getItem('chatMsgs') || '[]'); }
15    catch(e){ return []; }
16  }
17  function saveMessages(arr) {
18    localStorage.setItem('chatMsgs', JSON.stringify(arr));
19  }
20
21  // Conversation ID aanmaken (1x) en bewaren
22  let conversationId = localStorage.getItem('conversationId');
23  if (!conversationId) {
24    conversationId = (crypto && crypto.randomUUID) ? crypto.randomUUID() :
25      'conv_' + Math.random().toString(36).slice(2) + Date.now();
26    localStorage.setItem('conversationId', conversationId);
27  }
28
29  // Herstel chat HTML (optioneel, puur voor weergave)
30  if (localStorage.getItem('chatHistory')) {
31    $('#chat-messages').html(localStorage.getItem('chatHistory'));
32  }
33
34  // ENTER verzendt bericht, SHIFT+ENTER nieuwe regel
35  $('#chat-input').on('keydown', function(e) {
36    if (e.key === 'Enter' && !e.shiftKey) {
37      e.preventDefault();
38      $('#chat-form').submit();
39    }
40  });
41
42  $('#chat-form').on('submit', function(e) {
43    e.preventDefault();
44
45    const msg = $('#chat-input').val().trim();
46    if (!msg) return;
47
48    // 1) Toon het gebruikersbericht in de UI
49    $('#chat-messages').append(`<div class="chat-user">${msg}</div>`);
50    $('#chat-input').val('');
51
52    // 2) Update de messages-array (voor Chatbase)
53    const messages = loadMessages();
54    messages.push({ role: 'user', content: msg });
55    saveMessages(messages);
56
57    // 3) Loader
58    $('#chat-messages').append(`
59      <div class="chat-bot-wrapper loading-bubble">
60        <div class="chat-bot loader">
61          <span class="dot"></span><span class="dot"></span><span class="dot"></span>
62        </div>
63      </div>
64    `);
65    $('#chat-messages').scrollTop($('#chat-messages')[0].scrollHeight);
66
67    // 4) Verstuur ALLES naar de server
68    $.post(flexhub_chatbot_ajax.ajax_url, {
69      action: 'flexhub_chatbot_message',
70      nonce: flexhub_chatbot_ajax.chatbot_nonce,
71      conversationId: conversationId,
72      messages: JSON.stringify(messages) // stuur de hele history mee
73    }, function(response) {
74      // Verwijder loader
75      $('.loading-bubble').remove();
76
77      if (response && response.success) {
78        // Chatbase kan { text: "...", sources: [...] } teruggeven
79        const botText = (typeof response.data === 'object' && response.data !== null)
80          ? (response.data.text || '')
81          : (response.data || '');
82
83        // 5) Toon antwoord
84        $('#chat-messages').append(`
85          <div class="chat-bot">
86            <div class="editor">
87              <img src="https://flexhub.nl/wp-content/uploads/2025/07/Beeldmerk_roze_RGB.svg" width="25" style="margin-right:5px;">Flexhub
88            </div>
89            ${marked.parse(botText)}
90          </div>
91        `);
92
93        // 6) Voeg assistent-bericht toe aan messages-array en sla op
94        const updated = loadMessages();
95        updated.push({ role: 'assistant', content: botText });
96        saveMessages(updated);
97      } else {
98        $('#chat-messages').append(`<div class="chat-bot error">Er ging iets mis...</div>`);
99      }
100
101      // Scroll + HTML-history bewaren (alleen voor UI)
102      $('#chat-messages').scrollTop($('#chat-messages')[0].scrollHeight);
103      localStorage.setItem('chatHistory', $('#chat-messages').html());
104    }).fail(function() {
105      $('.loading-bubble').remove();
106      $('#chat-messages').append(`<div class="chat-bot error">Er ging iets mis met de verbinding...</div>`);
107    });
108  });
109
110  // =========================
111  // Toggle + icoon wisselen + promo-balk verbergen t/m einde van vandaag
112  // =========================
113  const $btn   = $('#chatbot-toggle');
114  const $box   = $('#chatbot-box');
115  const $promo = $('.chatbox-toggle-header'); // paarse tekstbalk
116
117  // === Cookie helpers ===
118  function setCookieSeconds(name, value, seconds, domain) {
119    const attrs = [`path=/`, `max-age=${Math.max(0, seconds|0)}`];
120    if (domain) attrs.push(`domain=${domain}`);
121    document.cookie = `${name}=${encodeURIComponent(value)}; ${attrs.join('; ')}`;
122  }
123  function getCookie(name) {
124    const nameEQ = name + "=";
125    const ca = document.cookie.split(';');
126    for (let c of ca) {
127      while (c.charAt(0) === ' ') c = c.substring(1);
128      if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length));
129    }
130    return null;
131  }
132
133  // Config
134  const PROMO_KEY    = 'chatPromoHidden';
135  const PROMO_DOMAIN = '.flexhub.nl'; // leeg laten als je het tot 1 host wilt beperken
136
137  function secondsUntilEndOfToday() {
138    const now = new Date();
139    const end = new Date(now);
140    end.setHours(23, 59, 59, 999);
141    return Math.max(1, Math.floor((end - now) / 1000));
142  }
143
144  // Bij laden: als cookie bestaat (waarde '1'), direct verbergen
145  if (getCookie(PROMO_KEY) === '1') {
146    $promo.addClass('hidden').hide();
147  }
148
149  // Zorg dat er een <img> in de knop zit (zoals in je markup)
150  let $img = $btn.find('img').first();
151  if ($img.length === 0) {
152    $img = $('<img>', { width: 30, alt: 'Open chat' }).appendTo($btn);
153  }
154
155  // Iconen
156  const BOT_ICON   = 'https://flexhub.nl/wp-content/uploads/2025/08/bot.png';
157  const CLOSE_ICON = "data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18 6L6 18M6 6l12 12' stroke='white' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E";
158
159  // Promo-balk verbergen tot einde van vandaag
160  function hidePromoUntilEOD() {
161    if (!$promo.length) return;
162    const ttl = secondsUntilEndOfToday();
163    setCookieSeconds(PROMO_KEY, '1', ttl, PROMO_DOMAIN); // verloopt om 23:59:59
164    try { localStorage.setItem(PROMO_KEY, '1'); } catch(e) {} // optioneel voor anti-flash
165    $promo.stop(true, true).fadeOut(50, function() {
166      $promo.addClass('hidden');
167    });
168  }
169
170  function setState(open) {
171    if (open) {
172      $box.removeClass('hidden');
173      $btn.attr({ 'aria-expanded': 'true', 'aria-controls': 'chatbot-box', 'title': 'Sluit chat' });
174      $img.attr({ src: CLOSE_ICON, alt: 'Sluit chat' })
175          .css({ width: 20, height: 20, marginTop: 0 });
176      // Bij openen: verberg promo tot einde van vandaag
177      hidePromoUntilEOD();
178    } else {
179      $box.addClass('hidden');
180      $btn.attr({ 'aria-expanded': 'false', 'aria-controls': 'chatbot-box', 'title': 'Open chat' });
181      $img.attr({ src: BOT_ICON, alt: 'Open chat' })
182          .css({ width: 30, height: 25, marginTop: -8 });
183      // Cookie laten verlopen op middernacht; dan verschijnt promo vanzelf weer
184    }
185  }
186
187  // Initiale sync (markup zet .hidden standaard op de box)
188  setState(!$box.hasClass('hidden'));
189
190  // Toggle-handler
191  $(document).off('click', '#chatbot-toggle').on('click', '#chatbot-toggle', function (e) {
192    e.preventDefault();
193    const open = $btn.attr('aria-expanded') === 'true';
194    setState(!open);
195  });
196
197  // Klik op de promo-balk -> verberg tot einde van vandaag (zonder chat te openen)
198  $(document).on('click', '.chatbox-toggle-header', function () {
199    hidePromoUntilEOD();
200    // Eventueel ook direct chat openen:
201    // setState(true);
202  });
203});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.