1/** 2 * JTS Chat status card â optional live refresh. 3 */ 4(function () { 5 'use strict'; 6 7 if (typeof jtsChatStatus === 'undefined') { 8 return; 9 } 10 11 function qs(el, sel) { 12 return el.querySelector(sel); 13 } 14 15 function pluralChatters(n) { 16 n = parseInt(n, 10) || 0; 17 return n === 1 ? '1 chatter' : n + ' chatters'; 18 } 19 20 function apply(card, data) { 21 if (!data) return; 22 var n = data.chatters || 0; 23 card.classList.toggle('has-chatters', n > 0); 24 25 var chattersEl = qs(card, '[data-role="chatters"]'); 26 if (chattersEl) { 27 chattersEl.innerHTML = 28 pluralChatters(n) + ' <span class="jts-chat-status-online">online</span>'; 29 } 30 31 var lastEl = qs(card, '[data-role="last"]'); 32 if (lastEl) { 33 lastEl.textContent = data.last_message_relative || 'No messages yet'; 34 if (data.last_message_at) { 35 lastEl.setAttribute('data-iso', data.last_message_at); 36 } 37 } 38 39 var preview = qs(card, '[data-role="preview"]'); 40 if (preview) { 41 if (data.last_message_preview) { 42 preview.hidden = false; 43 preview.classList.remove('is-empty'); 44 var nameEl = qs(preview, '[data-role="preview-name"]'); 45 var bodyEl = qs(preview, '[data-role="preview-body"]'); 46 if (!bodyEl) { 47 preview.innerHTML = 48 (data.last_message_name 49 ? '<strong data-role="preview-name"></strong> ' 50 : '') + '<span data-role="preview-body"></span>'; 51 nameEl = qs(preview, '[data-role="preview-name"]'); 52 bodyEl = qs(preview, '[data-role="preview-body"]'); 53 } 54 if (nameEl) { 55 nameEl.textContent = data.last_message_name 56 ? data.last_message_name + ':' 57 : ''; 58 } 59 if (bodyEl) { 60 bodyEl.textContent = data.last_message_preview; 61 } 62 } else { 63 preview.hidden = true; 64 preview.classList.add('is-empty'); 65 } 66 } 67 } 68 69 function fetchStatus(card) { 70 var room = card.getAttribute('data-room') || ''; 71 var url = 72 jtsChatStatus.restUrl + 73 '/status' + 74 (room ? '?room=' + encodeURIComponent(room) : ''); 75 return fetch(url, { 76 credentials: 'same-origin', 77 headers: { 'X-WP-Nonce': jtsChatStatus.nonce }, 78 }) 79 .then(function (r) { 80 return r.json(); 81 }) 82 .then(function (data) { 83 apply(card, data); 84 }) 85 .catch(function () { 86 /* quiet */ 87 }); 88 } 89 90 function boot() { 91 var cards = document.querySelectorAll('.jts-chat-status-card.is-live'); 92 if (!cards.length) { 93 // Still mark has-chatters on static cards from server HTML. 94 var all = document.querySelectorAll('.jts-chat-status-card'); 95 for (var j = 0; j < all.length; j++) { 96 var t = all[j].querySelector('[data-role="chatters"]'); 97 if (t && /[1-9]/.test(t.textContent || '')) { 98 all[j].classList.add('has-chatters'); 99 } 100 } 101 return; 102 } 103 104 var poll = jtsChatStatus.pollMs || 15000; 105 for (var i = 0; i < cards.length; i++) { 106 (function (card) { 107 // Initial green-dot state from SSR text. 108 var t = card.querySelector('[data-role="chatters"]'); 109 if (t && /[1-9]/.test(t.textContent || '')) { 110 card.classList.add('has-chatters'); 111 } 112 fetchStatus(card); 113 setInterval(function () { 114 fetchStatus(card); 115 }, poll); 116 })(cards[i]); 117 } 118 } 119 120 if (document.readyState === 'loading') { 121 document.addEventListener('DOMContentLoaded', boot); 122 } else { 123 boot(); 124 } 125})();
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.