|
216 | 216 | height: auto; |
217 | 217 | } |
218 | 218 | } |
| 219 | +.mode-btn { |
| 220 | + padding: 8px 14px; |
| 221 | + margin: 4px; |
| 222 | + border-radius: 6px; |
| 223 | + border: 1px solid #888; |
| 224 | + background: #eee; |
| 225 | + font-size: 1rem; |
| 226 | +} |
| 227 | + |
| 228 | +.mode-btn.active { |
| 229 | + background: #4caf50; |
| 230 | + color: white; |
| 231 | + border-color: #4caf50; |
| 232 | +} |
219 | 233 | </style> |
220 | 234 | </head> |
221 | 235 | <body> |
|
336 | 350 | </button> |
337 | 351 | </div> |
338 | 352 |
|
| 353 | + <div id="async-thread" style=" |
| 354 | + display: none; |
| 355 | + border: 1px solid #ccc; |
| 356 | + padding: 10px; |
| 357 | + margin: 10px; |
| 358 | + height: 200px; |
| 359 | + overflow-y: auto; |
| 360 | + background: #fafafa; |
| 361 | + border-radius: 6px; |
| 362 | +"></div> |
| 363 | + |
| 364 | +<div id="async-input-area" style="display: none; margin: 10px;"> |
| 365 | + <input id="async-input" type="text" style="width: 70%; padding: 8px;"> |
| 366 | + <button id="async-send">Send</button> |
| 367 | +</div> |
339 | 368 | <div id="conversation-memory" |
340 | 369 | aria-label="Conversation memory" |
341 | 370 | role="region"> |
@@ -403,8 +432,6 @@ <h2 id="users-heading">Users</h2> |
403 | 432 | </script> |
404 | 433 | <script src="bridge.js"></script> |
405 | 434 |
|
406 | | -<script src="bridge.js"></script> |
407 | | - |
408 | 435 | <script> |
409 | 436 | window.addEventListener("DOMContentLoaded", () => { |
410 | 437 |
|
@@ -656,19 +683,55 @@ <h2 id="users-heading">Users</h2> |
656 | 683 | window.addEventListener("load", startPolling); |
657 | 684 | window.addEventListener("beforeunload", stopPolling); |
658 | 685 |
|
| 686 | + let currentMode = "live"; |
| 687 | + |
| 688 | + const liveBtn = document.getElementById("mode-live"); |
| 689 | + const asyncBtn = document.getElementById("mode-async"); |
| 690 | + |
| 691 | + const asyncThread = document.getElementById("async-thread"); |
| 692 | + const asyncInputArea = document.getElementById("async-input-area"); |
| 693 | + |
| 694 | + function updateModeUI() { |
| 695 | + if (currentMode === "live") { |
| 696 | + liveBtn.classList.add("active"); |
| 697 | + asyncBtn.classList.remove("active"); |
| 698 | + asyncThread.style.display = "none"; |
| 699 | + asyncInputArea.style.display = "none"; |
| 700 | + } else { |
| 701 | + liveBtn.classList.remove("active"); |
| 702 | + asyncBtn.classList.add("active"); |
| 703 | + asyncThread.style.display = "block"; |
| 704 | + asyncInputArea.style.display = "block"; |
| 705 | + } |
| 706 | + } |
| 707 | + |
| 708 | + liveBtn.onclick = () => { currentMode = "live"; updateModeUI(); }; |
| 709 | + asyncBtn.onclick = () => { currentMode = "async"; updateModeUI(); }; |
659 | 710 |
|
660 | | - /* --------------------------------------------------------- |
661 | | - 9. LEGACY API WRAPPERS |
662 | | - --------------------------------------------------------- */ |
663 | | -window.connectWithNickname = () => { … } |
664 | | - window.disconnectEverything = () => bridge.disconnectEverything(); |
665 | | - window.sendChat = (text) => bridge.sendChat(text); |
666 | | - window.joinChannel = (id) => bridge.joinChannel(id); |
667 | | - window.getChannels = () => bridge.getChannels(); |
668 | | - window.getUsers = () => bridge.getUsers(); |
669 | | - window.getCurrentChannel = () => bridge.getCurrentChannel(); |
| 711 | + document.getElementById("async-send").onclick = () => { |
| 712 | + const text = document.getElementById("async-input").value.trim(); |
| 713 | + if (!text) return; |
| 714 | + bridge.sendMessage(text, "async"); |
| 715 | + document.getElementById("async-input").value = ""; |
| 716 | + }; |
670 | 717 |
|
| 718 | + bridge.on("async-message", (msg) => { |
| 719 | + const div = document.createElement("div"); |
| 720 | + div.textContent = `${new Date(msg.timestamp).toLocaleTimeString()} — ${msg.text}`; |
| 721 | + asyncThread.appendChild(div); |
| 722 | + asyncThread.scrollTop = asyncThread.scrollHeight; |
| 723 | + }); |
| 724 | + |
| 725 | +bridge.getAsyncMessages().then(messages => { |
| 726 | + messages.forEach(msg => { |
| 727 | + const div = document.createElement("div"); |
| 728 | + div.textContent = `${new Date(msg.timestamp).toLocaleTimeString()} — ${msg.text}`; |
| 729 | + asyncThread.appendChild(div); |
| 730 | + }); |
671 | 731 | }); |
| 732 | + |
| 733 | +/* ⭐ Close DOMContentLoaded ⭐ */ |
| 734 | +}); |
672 | 735 | </script> |
673 | 736 | </body> |
674 | 737 | </html> |
0 commit comments