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

From DQWiki
Jump to navigationJump to search
mNo edit summary
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 1: Line 1:
/* Lorekeeper Standalone Terminal v6 - Royal Brown Theme */
/* Lorekeeper Widget Loader - v1.1.3 (Hardened Responsive Iframe) */
(function() {
(function() {
     var checkCount = 0;
     var username = mw.config.get('wgUserName');
     var initTimer = setInterval(function() {
    var isMobileParent = window.innerWidth < 768; // Measure the true Wiki window size
         if (document.body) { clearInterval(initTimer); setupLore(); }
   
        if (checkCount++ > 100) clearInterval(initTimer);
    // Uses the correct Firebase Hosted App URL
     }, 100);
    var iframeUrl = 'https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app/widget';
   
     var params = [];
    if (username) {
         params.push('user=' + encodeURIComponent(username));
    } else {
        params.push('guest=Traveler');
    }
   
    // Tell the iframe if the user is ACTUALLY on mobile
    if (isMobileParent) {
        params.push('isMobile=true');
    }
   
    if (params.length > 0) {
        iframeUrl += '?' + params.join('&');
     }


     function setupLore() {
     // Create a container that doesn't block the Wiki
        if (document.getElementById('lore-terminal-btn')) return;
    var widgetContainer = document.createElement('div');
    widgetContainer.id = 'lorekeeper-widget-container';
    widgetContainer.style.cssText = 'position:fixed; bottom:0; right:0; z-index:99999; pointer-events:none; transition: width 0.3s ease, height 0.3s ease;';
    widgetContainer.style.width = isMobileParent ? '80px' : '300px';
    widgetContainer.style.height = isMobileParent ? '80px' : '120px';


        // 1. Earthy RPG Style CSS
    var iframe = document.createElement('iframe');
        var css =  
    iframe.src = iframeUrl;
            '#lore-chat::-webkit-scrollbar { width: 5px; }' +
    iframe.style.cssText = 'width:100%; height:100%; border:none; background:transparent; pointer-events:auto;';
            '#lore-chat::-webkit-scrollbar-thumb { background: #f97316; border-radius: 10px; }' +
    iframe.setAttribute('allow', 'clipboard-write'); // For links/sharing later
            '.lore-msg { margin-bottom: 12px; padding: 12px 16px; border-radius: 15px; font-size: 14px; line-height: 1.5; box-shadow: 0 4px 10px rgba(0,0,0,0.2); }' +
            '.lore-user { background: #f97316; color: #000; align-self: flex-end; margin-left: 35px; border-bottom-right-radius: 4px; font-weight: 500; }' +
            '.lore-ai { background: #24140e; color: #f7f3e8; align-self: flex-start; margin-right: 35px; border-left: 4px solid #f97316; border-bottom-left-radius: 4px; }' +
            '.lore-ai b { color: #f97316; }';
       
        var style = document.createElement('style');
        style.type = 'text/css';
        style.appendChild(document.createTextNode(css));
        document.head.appendChild(style);


        // 2. The Button (Dark Brown w/ Orange Border)
    widgetContainer.appendChild(iframe);
        var btn = document.createElement('div');
    document.body.appendChild(widgetContainer);
        btn.id = 'lore-terminal-btn';
        btn.innerHTML = '&#10024;';
        btn.setAttribute('style', 'position:fixed !important; bottom:25px !important; right:25px !important; width:65px !important; height:65px !important; background:#2d140e !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(0,0,0,0.6) !important; z-index:9999999 !important; border:3px solid #f97316 !important; transition: transform 0.2s ease;');


        // 3. The Chat Box (Matched to App Colors)
    // Listen for the widget telling the Wiki to "Grow" and "Shrink"
        var box = document.createElement('div');
    window.addEventListener('message', function(event) {
         box.id = 'lore-terminal-box';
         // Enforce secure origin check for the correct App Hosting domain
        box.setAttribute('style', 'position:fixed !important; bottom:105px !important; right:25px !important; width:420px !important; height:620px !important; background:#1a0d09 !important; border:1px solid #412a23 !important; border-radius:24px !important; display:none; flex-direction:column !important; box-shadow:0 30px 80px rgba(0,0,0,0.9) !important; z-index:9999999 !important; color:#f7f3e8 !important; font-family:serif !important; overflow:hidden;');
        if (event.origin !== 'https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app') return;
          
          
         box.innerHTML =  
         if (event.data.type === 'lorekeeper-resize') {
            '<div style="padding:18px 20px; border-bottom:1px solid #412a23; background:rgba(249,115,22,0.05); display:flex; justify-content:space-between; align-items:center;">' +
            var w = event.data.width;
                '<div><b style="color:#f97316; font-size:16px; letter-spacing:1px; text-transform:uppercase;">Archives</b><br><small style="opacity:0.6; font-size:10px;">Kingdom of the West</small></div>' +
            var h = event.data.height;
                '<span id="lore-close" style="cursor:pointer; font-size:24px; opacity:0.5; color:#f97316;">&times;</span>' +
             // Handle both pixel numbers (desktop) and string values like "100vw" (mobile)
             '</div>' +
             widgetContainer.style.width = (typeof w === 'number') ? w + 'px' : w;
             '<div id="lore-chat" style="flex:1; overflow-y:auto; padding:20px; display:flex; flex-direction:column; background:#1a0d09;">' +
             widgetContainer.style.height = (typeof h === 'number') ? h + 'px' : h;
                '<div class="lore-msg lore-ai">Greetings, Traveler. I am the Lorekeeper. What history shall we unearth today?</div>' +
        }
            '</div>' +
    });
             '<div style="padding:18px; background:rgba(0,0,0,0.3); border-top:1px solid #412a23; display:flex; gap:10px;">' +
                '<input id="lore-input" placeholder="Consult the scrolls..." style="flex:1; background:#000; border:1px solid #412a23; padding:12px; border-radius:12px; color:#f7f3e8; outline:none; font-size:14px;">' +
                '<button id="lore-send" style="background:#f97316; color:#000; border:none; padding:10px 20px; border-radius:10px; cursor:pointer; font-weight:bold;">ASK</button>' +
            '</div>';


        document.body.appendChild(btn);
    // Optional: Resync if they resize the window wildly (desktop to mobile mode live)
        document.body.appendChild(box);
    window.addEventListener('resize', function() {
 
         var newIsMobile = window.innerWidth < 768;
        var input = document.getElementById('lore-input');
         if (newIsMobile !== isMobileParent) {
        var chat = document.getElementById('lore-chat');
             isMobileParent = newIsMobile;
 
             // You could reload the iframe here, but keeping it simple is usually safest.
        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 = '';
 
            var uMsg = document.createElement('div');
             uMsg.className = 'lore-msg lore-user';
            uMsg.innerText = val;
            chat.appendChild(uMsg);
            chat.scrollTop = chat.scrollHeight;
 
             var aMsg = document.createElement('div');
            aMsg.className = 'lore-msg lore-ai';
            aMsg.innerText = "Consulting the royal records...";
            chat.appendChild(aMsg);
 
            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 || "The archives are silent on this matter.";
                        } catch(e) { aMsg.innerText = "Failed to parse the scribe scrolls."; }
                    } else { aMsg.innerText = "The connection to the archives has been severed (Status " + xhr.status + ")."; }
                    chat.scrollTop = chat.scrollHeight;
                }
            };
            xhr.send(JSON.stringify({ prompt: val }));
        };
        input.onkeydown = function(e) { if (e.keyCode === 13) document.getElementById('lore-send').click(); };
    }
})();
})();

Latest revision as of 08:07, 1 March 2026

/* Lorekeeper Widget Loader - v1.1.3 (Hardened Responsive Iframe) */
(function() {
    var username = mw.config.get('wgUserName');
    var isMobileParent = window.innerWidth < 768; // Measure the true Wiki window size
    
    // Uses the correct Firebase Hosted App URL
    var iframeUrl = 'https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app/widget';
    
    var params = [];
    if (username) {
        params.push('user=' + encodeURIComponent(username));
    } else {
        params.push('guest=Traveler');
    }
    
    // Tell the iframe if the user is ACTUALLY on mobile
    if (isMobileParent) {
        params.push('isMobile=true');
    }
    
    if (params.length > 0) {
        iframeUrl += '?' + params.join('&');
    }

    // Create a container that doesn't block the Wiki
    var widgetContainer = document.createElement('div');
    widgetContainer.id = 'lorekeeper-widget-container';
    widgetContainer.style.cssText = 'position:fixed; bottom:0; right:0; z-index:99999; pointer-events:none; transition: width 0.3s ease, height 0.3s ease;';
    widgetContainer.style.width = isMobileParent ? '80px' : '300px'; 
    widgetContainer.style.height = isMobileParent ? '80px' : '120px';

    var iframe = document.createElement('iframe');
    iframe.src = iframeUrl;
    iframe.style.cssText = 'width:100%; height:100%; border:none; background:transparent; pointer-events:auto;';
    iframe.setAttribute('allow', 'clipboard-write'); // For links/sharing later

    widgetContainer.appendChild(iframe);
    document.body.appendChild(widgetContainer);

    // Listen for the widget telling the Wiki to "Grow" and "Shrink"
    window.addEventListener('message', function(event) {
        // Enforce secure origin check for the correct App Hosting domain
        if (event.origin !== 'https://npc-forge--npc-forge-qh4gc.asia-southeast1.hosted.app') return;
        
        if (event.data.type === 'lorekeeper-resize') {
            var w = event.data.width;
            var h = event.data.height;
            // Handle both pixel numbers (desktop) and string values like "100vw" (mobile)
            widgetContainer.style.width = (typeof w === 'number') ? w + 'px' : w;
            widgetContainer.style.height = (typeof h === 'number') ? h + 'px' : h;
        }
    });

    // Optional: Resync if they resize the window wildly (desktop to mobile mode live)
    window.addEventListener('resize', function() {
        var newIsMobile = window.innerWidth < 768;
        if (newIsMobile !== isMobileParent) {
            isMobileParent = newIsMobile;
            // You could reload the iframe here, but keeping it simple is usually safest.
        }
    });
})();