User:Jono Bean/common.js: Difference between revisions

From DQWiki
Jump to navigationJump to search
mNo edit summary
mNo edit summary
Line 1: Line 1:
/* Lorekeeper Standalone Terminal v4 - Premium Streaming */
/* Lorekeeper Standalone Terminal v5 - Compatible & Premium */
(function() {
(function() {
     var checkCount = 0;
     var checkCount = 0;
Line 13: Line 13:
         if (document.getElementById('lore-terminal-btn')) return;
         if (document.getElementById('lore-terminal-btn')) return;


         // 1. Inject Styles
         // 1. Set up Styles manually
         var style = document.createElement('style');
         var css =  
        style.innerHTML =  
             '#lore-chat::-webkit-scrollbar { width: 4px; }' +
             '#lore-chat::-webkit-scrollbar { width: 4px; }' +
             '#lore-chat::-webkit-scrollbar-thumb { background: #8b5cf6; border-radius: 10px; }' +
             '#lore-chat::-webkit-scrollbar-thumb { background: #8b5cf6; border-radius: 10px; }' +
             '.lore-msg { margin-bottom: 15px; padding: 12px 16px; border-radius: 15px; font-size: 14px; position: relative; animation: fadeIn 0.3s ease; }' +
             '.lore-msg { margin-bottom: 15px; padding: 12px 16px; border-radius: 15px; font-size: 14px; position: relative; }' +
             '.lore-user { background: #8b5cf6; color: #fff; align-self: flex-end; margin-left: 40px; border-bottom-right-radius: 4px; }' +
             '.lore-user { background: #8b5cf6; color: #fff; align-self: flex-end; margin-left: 40px; border-bottom-right-radius: 4px; text-align: right; }' +
             '.lore-ai { background: #1a1a24; color: #e2e8f0; align-self: flex-start; margin-right: 40px; border-left: 4px solid #8b5cf6; border-bottom-left-radius: 4px; }' +
             '.lore-ai { background: #1a1a24; color: #e2e8f0; align-self: flex-start; margin-right: 40px; border-left: 4px solid #8b5cf6; border-bottom-left-radius: 4px; }';
            '@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }';
       
         document.head.appendChild(style);
        var style = document.createElement('style');
        style.type = 'text/css';
        if (style.styleSheet) style.styleSheet.cssText = css;  
        else style.appendChild(document.createTextNode(css));
         document.getElementsByTagName('head')[0].appendChild(style);


         // 2. Create Floating Button
         // 2. Create Floating Button
         var btn = document.createElement('div');
         var btn = document.createElement('div');
         btn.id = 'lore-terminal-btn';
         btn.id = 'lore-terminal-btn';
         btn.innerHTML = '?';
         btn.innerHTML = '✨'; // Sparkles
         btn.setAttribute('style', 'position:fixed !important; bottom:25px !important; right:25px !important; width:65px !important; height:65px !important; background:linear-gradient(135deg, #8b5cf6, #6d28d9) !important; border-radius:50% !important; display:flex !important; align-items:center !important; justify-content:center !important; font-size:32px !important; cursor:pointer !important; box-shadow:0 10px 30px rgba(139,92,246,0.5) !important; z-index:999999 !important; border:2px solid rgba(255,255,255,0.4) !important; transition:0.3s ease;');
         btn.setAttribute('style', 'position:fixed !important; bottom:25px !important; right:25px !important; width:65px !important; height:65px !important; background:linear-gradient(135deg, #8b5cf6, #6d28d9) !important; border-radius:50% !important; display:flex !important; align-items:center !important; justify-content:center !important; font-size:32px !important; cursor:pointer !important; box-shadow:0 10px 30px rgba(139,92,246,0.5) !important; z-index:999999 !important; border:2px solid rgba(255,255,255,0.4) !important;');


         // 3. Create Chat Box
         // 3. Create Chat Box
         var box = document.createElement('div');
         var box = document.createElement('div');
         box.id = 'lore-terminal-box';
         box.id = 'lore-terminal-box';
         box.setAttribute('style', 'position:fixed !important; bottom:105px !important; right:25px !important; width:420px !important; height:650px !important; background:rgba(10,10,15,0.98) !important; backdrop-filter:blur(15px); border:1px solid rgba(139,92,246,0.4) !important; border-radius:30px !important; display:none; flex-direction:column !important; box-shadow:0 30px 60px rgba(0,0,0,0.8) !important; z-index:999999 !important; color:#fff !important; font-family:system-ui, sans-serif !important; overflow:hidden;');
         box.setAttribute('style', 'position:fixed !important; bottom:105px !important; right:25px !important; width:400px !important; height:600px !important; background:#0a0a0f !important; border:1px solid #8b5cf6 !important; border-radius:30px !important; display:none; flex-direction:column !important; box-shadow:0 30px 60px rgba(0,0,0,0.8) !important; z-index:999999 !important; color:#fff !important; font-family:sans-serif !important; overflow:hidden;');
          
          
         box.innerHTML =  
         box.innerHTML =  
             '<div style="padding:20px; border-bottom:1px solid rgba(139,92,246,0.2); background:rgba(139,92,246,0.1); display:flex; justify-content:space-between; align-items:center;">' +
             '<div style="padding:20px; border-bottom:1px solid rgba(139,92,246,0.2); background:rgba(139,92,246,0.1); display:flex; justify-content:space-between; align-items:center;">' +
                 '<div><b style="color:#a78bfa; font-size:16px;">The Lorekeeper</b><br><small style="opacity:0.6; font-size:10px; text-transform:uppercase; letter-spacing:1px;">Royal Archives</small></div>' +
                 '<div><b style="color:#a78bfa; font-size:16px;">The Lorekeeper</b><br><small style="opacity:0.6; font-size:10px; text-transform:uppercase;">Royal Archives</small></div>' +
                 '<span id="lore-close" style="cursor:pointer; font-size:24px; opacity:0.5;">&times;</span>' +
                 '<span id="lore-close" style="cursor:pointer; font-size:24px; opacity:0.5;">&times;</span>' +
             '</div>' +
             '</div>' +
             '<div id="lore-chat" style="flex:1; overflow-y:auto; padding:20px; display:flex; flex-direction:column; gap:5px;">' +
             '<div id="lore-chat" style="flex:1; overflow-y:auto; padding:20px; display:flex; flex-direction:column; gap:5px; background:#0a0a0f;">' +
                 '<div class="lore-msg lore-ai">Greetings, Traveler. I am the Scribe of the Western Kingdom. What knowledge do you seek from the archives?</div>' +
                 '<div class="lore-msg lore-ai">Greetings, Traveler. I am the Scribe of the Western Kingdom. What knowledge do you seek from the archives?</div>' +
             '</div>' +
             '</div>' +
             '<div style="padding:20px; background:rgba(0,0,0,0.4); border-top:1px solid rgba(255,255,255,0.05); display:flex; gap:10px;">' +
             '<div style="padding:15px; background:rgba(0,0,0,0.4); border-top:1px solid #333; display:flex; gap:10px;">' +
                 '<input id="lore-input" placeholder="Inquire about the world..." style="flex:1; background:rgba(255,255,255,0.05); border:1px solid rgba(139,92,246,0.3); padding:12px 18px; border-radius:15px; color:#fff; outline:none; font-size:14px;">' +
                 '<input id="lore-input" placeholder="Inquire about the world..." style="flex:1; background:#111; border:1px solid #444; padding:12px; border-radius:15px; color:#fff; outline:none; font-size:14px;">' +
                 '<button id="lore-send" style="background:#8b5cf6; color:#fff; border:none; width:50px; height:45px; border-radius:12px; cursor:pointer; font-weight:bold; font-size:18px;">&rarr;</button>' +
                 '<button id="lore-send" style="background:#8b5cf6; color:#fff; border:none; padding:10px 15px; border-radius:12px; cursor:pointer; font-weight:bold;">Ask</button>' +
             '</div>';
             '</div>';


Line 53: Line 56:
         var input = document.getElementById('lore-input');
         var input = document.getElementById('lore-input');
         var chat = document.getElementById('lore-chat');
         var chat = document.getElementById('lore-chat');
        var convId = 'anon-' + Math.random().toString(36).substring(7);


         btn.onclick = function() { box.style.display = (box.style.display == 'none') ? 'flex' : 'none'; };
         btn.onclick = function() { box.style.display = (box.style.display == 'none') ? 'flex' : 'none'; };
         document.getElementById('lore-close').onclick = function() { box.style.display = 'none'; };
         document.getElementById('lore-close').onclick = function() { box.style.display = 'none'; };


         function addMessage(text, isAi) {
         document.getElementById('lore-send').onclick = function() {
            var m = document.createElement('div');
             var val = input.value.trim();
            m.className = 'lore-msg ' + (isAi ? 'lore-ai' : 'lore-user');
             if (!val) return;
            m.innerText = text;
            chat.appendChild(m);
            chat.scrollTop = chat.scrollHeight;
            return m;
        }
 
        async function handleAsk() {
             var q = input.value.trim();
             if (!q) return;
             input.value = '';
             input.value = '';
            addMessage(q, false);


             var aMsg = addMessage('', true);
            // User Message
             aMsg.innerHTML = '<i style="opacity:0.5">Consulting the Scribe Notes...</i>';
             var uMsg = document.createElement('div');
             uMsg.className = 'lore-msg lore-user';
            uMsg.innerText = val;
            chat.appendChild(uMsg);
            chat.scrollTop = chat.scrollHeight;


             try {
             // AI Message Container
                const response = await fetch('https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app/api/lore/stream', {
            var aMsg = document.createElement('div');
                    method: 'POST',
            aMsg.className = 'lore-msg lore-ai';
                    headers: { 'Content-Type': 'application/json' },
            aMsg.innerText = "Consulting the records...";
                    body: JSON.stringify({ question: q, conversationId: convId })
            chat.appendChild(aMsg);
                });


                const reader = response.body.getReader();
            // API Call (ES5 Compatible)
                const decoder = new TextDecoder();
            var xhr = new XMLHttpRequest();
                aMsg.innerText = '';
            xhr.open("POST", "https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app/api/askLore", true);
                var content = '';
            xhr.setRequestHeader("Content-Type", "application/json");
 
            xhr.onreadystatechange = function() {
                while (true) {
                if (xhr.readyState === 4) {
                    const { done, value } = await reader.read();
                     if (xhr.status === 200) {
                     if (done) break;
                        try {
                    content += decoder.decode(value);
                            var response = JSON.parse(xhr.responseText);
                    aMsg.innerText = content;
                            aMsg.innerText = response.text || response.data.text;
                    chat.scrollTop = chat.scrollHeight;
                            chat.scrollTop = chat.scrollHeight;
                        } catch(e) { aMsg.innerText = "Error parsing archives."; }
                    } else { aMsg.innerText = "Connection lost."; }
                 }
                 }
             } catch (e) { aMsg.innerText = "The archives are sealed for now. Please try again later."; }
             };
         }
            xhr.send(JSON.stringify({ prompt: val }));
 
         };
         document.getElementById('lore-send').onclick = handleAsk;
          
         input.onkeydown = function(e) { if (e.key === 'Enter') handleAsk(); };
         input.onkeydown = function(e) { if (e.keyCode === 13) document.getElementById('lore-send').click(); };
     }
     }
})();
})();

Revision as of 08:01, 25 February 2026

/* Lorekeeper Standalone Terminal v5 - Compatible & Premium */
(function() {
    var checkCount = 0;
    var initTimer = setInterval(function() {
        if (document.body) {
            clearInterval(initTimer);
            setupLore();
        }
        if (checkCount++ > 100) clearInterval(initTimer);
    }, 100);

    function setupLore() {
        if (document.getElementById('lore-terminal-btn')) return;

        // 1. Set up Styles manually
        var css = 
            '#lore-chat::-webkit-scrollbar { width: 4px; }' +
            '#lore-chat::-webkit-scrollbar-thumb { background: #8b5cf6; border-radius: 10px; }' +
            '.lore-msg { margin-bottom: 15px; padding: 12px 16px; border-radius: 15px; font-size: 14px; position: relative; }' +
            '.lore-user { background: #8b5cf6; color: #fff; align-self: flex-end; margin-left: 40px; border-bottom-right-radius: 4px; text-align: right; }' +
            '.lore-ai { background: #1a1a24; color: #e2e8f0; align-self: flex-start; margin-right: 40px; border-left: 4px solid #8b5cf6; border-bottom-left-radius: 4px; }';
        
        var style = document.createElement('style');
        style.type = 'text/css';
        if (style.styleSheet) style.styleSheet.cssText = css; 
        else style.appendChild(document.createTextNode(css));
        document.getElementsByTagName('head')[0].appendChild(style);

        // 2. Create Floating Button
        var btn = document.createElement('div');
        btn.id = 'lore-terminal-btn';
        btn.innerHTML = '&#10024;'; // Sparkles
        btn.setAttribute('style', 'position:fixed !important; bottom:25px !important; right:25px !important; width:65px !important; height:65px !important; background:linear-gradient(135deg, #8b5cf6, #6d28d9) !important; border-radius:50% !important; display:flex !important; align-items:center !important; justify-content:center !important; font-size:32px !important; cursor:pointer !important; box-shadow:0 10px 30px rgba(139,92,246,0.5) !important; z-index:999999 !important; border:2px solid rgba(255,255,255,0.4) !important;');

        // 3. Create Chat Box
        var box = document.createElement('div');
        box.id = 'lore-terminal-box';
        box.setAttribute('style', 'position:fixed !important; bottom:105px !important; right:25px !important; width:400px !important; height:600px !important; background:#0a0a0f !important; border:1px solid #8b5cf6 !important; border-radius:30px !important; display:none; flex-direction:column !important; box-shadow:0 30px 60px rgba(0,0,0,0.8) !important; z-index:999999 !important; color:#fff !important; font-family:sans-serif !important; overflow:hidden;');
        
        box.innerHTML = 
            '<div style="padding:20px; border-bottom:1px solid rgba(139,92,246,0.2); background:rgba(139,92,246,0.1); display:flex; justify-content:space-between; align-items:center;">' +
                '<div><b style="color:#a78bfa; font-size:16px;">The Lorekeeper</b><br><small style="opacity:0.6; font-size:10px; text-transform:uppercase;">Royal Archives</small></div>' +
                '<span id="lore-close" style="cursor:pointer; font-size:24px; opacity:0.5;">&times;</span>' +
            '</div>' +
            '<div id="lore-chat" style="flex:1; overflow-y:auto; padding:20px; display:flex; flex-direction:column; gap:5px; background:#0a0a0f;">' +
                '<div class="lore-msg lore-ai">Greetings, Traveler. I am the Scribe of the Western Kingdom. What knowledge do you seek from the archives?</div>' +
            '</div>' +
            '<div style="padding:15px; background:rgba(0,0,0,0.4); border-top:1px solid #333; display:flex; gap:10px;">' +
                '<input id="lore-input" placeholder="Inquire about the world..." style="flex:1; background:#111; border:1px solid #444; padding:12px; border-radius:15px; color:#fff; outline:none; font-size:14px;">' +
                '<button id="lore-send" style="background:#8b5cf6; color:#fff; border:none; padding:10px 15px; border-radius:12px; cursor:pointer; font-weight:bold;">Ask</button>' +
            '</div>';

        document.body.appendChild(btn);
        document.body.appendChild(box);

        var input = document.getElementById('lore-input');
        var chat = document.getElementById('lore-chat');

        btn.onclick = function() { box.style.display = (box.style.display == 'none') ? 'flex' : 'none'; };
        document.getElementById('lore-close').onclick = function() { box.style.display = 'none'; };

        document.getElementById('lore-send').onclick = function() {
            var val = input.value.trim();
            if (!val) return;
            input.value = '';

            // User Message
            var uMsg = document.createElement('div');
            uMsg.className = 'lore-msg lore-user';
            uMsg.innerText = val;
            chat.appendChild(uMsg);
            chat.scrollTop = chat.scrollHeight;

            // AI Message Container
            var aMsg = document.createElement('div');
            aMsg.className = 'lore-msg lore-ai';
            aMsg.innerText = "Consulting the records...";
            chat.appendChild(aMsg);

            // API Call (ES5 Compatible)
            var xhr = new XMLHttpRequest();
            xhr.open("POST", "https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app/api/askLore", true);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        try {
                            var response = JSON.parse(xhr.responseText);
                            aMsg.innerText = response.text || response.data.text;
                            chat.scrollTop = chat.scrollHeight;
                        } catch(e) { aMsg.innerText = "Error parsing archives."; }
                    } else { aMsg.innerText = "Connection lost."; }
                }
            };
            xhr.send(JSON.stringify({ prompt: val }));
        };
        
        input.onkeydown = function(e) { if (e.keyCode === 13) document.getElementById('lore-send').click(); };
    }
})();