Greasy Fork

Greasy Fork is available in English.

TriX UI Library

UI library for the TriX Executor. Not intended for direct installation.

当前为 2025-07-02 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/541462/1618113/TriX%20UI%20Library.js

// ==UserScript==
// @name        TriX UI Library
// @namespace   https://github.com/YourUsername/TriX-Executor
// @version     1.6.0
// @description UI library for the TriX Executor. Not intended for direct installation.
// @author      You
// @license     MIT
// ==/UserScript==

const TriX_UI = (function() {
    'use strict';

    const UI = {
        isMinimized:false, currentScriptName:"",
        init() {
            this.injectCSS();
            this.injectHTML();
            this.attachEventListeners();
            TriX_Core.ScriptManager.populateScriptList();
            this.updateTabCountUI(1);
            this.log("TriX UI Library v1.6.0 initialized.");
        },
        updateTabCountUI(count) {
            const openBtnBadge = document.getElementById('trix-open-btn-badge');
            const headerBadge = document.getElementById('trix-header-tab-counter');
            if (openBtnBadge) openBtnBadge.textContent = count;
            if (headerBadge) headerBadge.textContent = count;
        },
        updateConnectionStatus(isOnline, ping) {
            const statusIndicator = document.getElementById('trix-conn-status-indicator');
            const statusText = document.getElementById('trix-conn-status-text');
            if (!statusIndicator || !statusText) return;

            if (isOnline) {
                statusIndicator.style.backgroundColor = '#4CAF50'; // Green
                statusText.textContent = `${ping}ms`;
                statusText.title = 'Online';
            } else {
                statusIndicator.style.backgroundColor = '#F44336'; // Red
                statusText.textContent = 'Offline';
                statusText.title = 'Offline';
            }
        },
        injectCSS() { GM_addStyle(`
            /* --- Font Imports --- */
            @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
            @import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap');
            
            :root {
                --trix-bg-primary: #1a1b26;
                --trix-bg-secondary: #24283b;
                --trix-bg-tertiary: #414868;
                --trix-accent-color: #7aa2f7;
                --trix-accent-cyan: #7dcfff;
                --trix-accent-green: #9ece6a;
                --trix-accent-red: #f7768e;
                --trix-text-primary: #c0caf5;
                --trix-text-secondary: #a9b1d6;
                --trix-border-color: #16161e;
            }
            #trix-container, #trix-open-btn { font-family: 'Roboto', sans-serif !important; }
            #trix-container{position:fixed!important;top:50px!important;left:50px!important;width:650px;height:420px;background-color:var(--trix-bg-primary);border:1px solid var(--trix-border-color);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.3);z-index:1000000!important;display:flex!important;flex-direction:column;resize:both;overflow:hidden;min-width:500px;min-height:350px}
            #trix-container.hidden{display:none!important}#trix-container.minimized{height:auto!important;min-height:0!important;resize:none!important}#trix-container.minimized #trix-body,#trix-container.minimized #trix-footer{display:none!important}
            #trix-open-btn{position:fixed!important;top:20px!important;right:20px!important;z-index:999999!important;display:flex!important;align-items:center;background-color:var(--trix-accent-color)!important;color:#fff!important;border:none!important;border-radius:5px;padding:10px 15px!important;cursor:pointer!important;box-shadow:0 0 15px rgba(122,162,247,.5);font-weight:700!important;font-size:14px!important;transition:transform .2s ease}
            #trix-open-btn:hover { transform: translateY(-2px); }
            .trix-tab-badge{display:inline-block;background-color:rgba(0,0,0,0.2);color:var(--trix-text-primary);padding:2px 8px;margin-left:8px;border-radius:10px;font-size:12px;font-weight:700;line-height:1.2;vertical-align:middle;min-width:10px;text-align:center}
            #trix-header{background-color:var(--trix-bg-secondary);padding:8px 12px;cursor:move;user-select:none;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--trix-border-color)}#trix-header-title{display:flex;align-items:center;font-weight:700;color:var(--trix-text-primary)}#trix-logo{width:24px;height:24px;margin-right:10px}
            #trix-window-controls button{background:0 0;border:none;color:var(--trix-text-secondary);font-size:18px;cursor:pointer;margin-left:10px;padding:0 4px;line-height:1;transition:color .2s}#trix-window-controls button:hover{color:var(--trix-accent-cyan)}#trix-close-btn:hover{color:var(--trix-accent-red)}
            #trix-body{flex-grow:1;display:flex;overflow:hidden}
            #trix-left-panel{width:160px;background-color:var(--trix-bg-secondary);padding:10px 0;display:flex;flex-direction:column;border-right:1px solid var(--trix-border-color)}#trix-script-list-title{padding:0 10px 15px;font-weight:700;color:var(--trix-text-primary);border-bottom:1px solid var(--trix-border-color)}#trix-script-list{flex-grow:1;overflow-y:auto;margin-top:10px}
            .trix-script-item{padding:8px 15px;cursor:pointer;color:var(--trix-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-left:3px solid transparent;transition:all .2s}.trix-script-item:hover{background-color:var(--trix-bg-tertiary);color:var(--trix-text-primary)}.trix-script-item.active{border-left:3px solid var(--trix-accent-color);background:linear-gradient(90deg, rgba(122,162,247,0.1), transparent);color:var(--trix-text-primary)!important;font-weight:700}
            #trix-right-panel{flex-grow:1;display:flex;flex-direction:column;background-color: var(--trix-bg-primary);}
            #trix-editor, #trix-console { font-family: 'Fira Code', 'Consolas', monospace; }
            #trix-editor{flex-grow:1;background-color:transparent;color:var(--trix-text-primary);border:none;padding:10px;box-sizing:border-box;resize:none;font-size:14px}
            #trix-console{height:140px;background-color:var(--trix-bg-secondary);border-top:1px solid var(--trix-border-color);padding:5px;overflow-y:auto;font-size:12px}#trix-console div{padding:2px 8px;border-bottom:1px solid #1e202c;word-break:break-all}#trix-console .log-error{color:var(--trix-accent-red)}#trix-console .log-warn{color:#e0af68}#trix-console .log-info{color:var(--trix-accent-cyan)}#trix-console .log-broadcast{color:var(--trix-accent-green);font-style:italic}
            #trix-footer{display:flex;gap:10px;padding:10px;background-color:var(--trix-bg-secondary);border-top:1px solid var(--trix-border-color);align-items:center}
            .trix-button{background-color:var(--trix-bg-tertiary);border:1px solid var(--trix-border-color);color:var(--trix-text-primary);padding:8px 15px;cursor:pointer;border-radius:5px;transition:all .2s;display:flex;align-items:center;gap:6px}.trix-button:hover{background-color:#4a5276;border-color:#565f89}.trix-button.primary{background-color:var(--trix-accent-color);color:#1a1b26;font-weight:700}.trix-button.primary:hover{background-color:#9aadef;border-color:var(--trix-accent-color)}.trix-button.danger{background-color:var(--trix-accent-red);color:#1a1b26}.trix-button.danger:hover{background-color:#f88e9a;border-color:var(--trix-accent-red)}
            #trix-footer-status{margin-left:auto;display:flex;align-items:center;gap:6px;font-size:12px;color:var(--trix-text-secondary)}
            #trix-conn-status-indicator{width:10px;height:10px;border-radius:50%;background-color:#f7768e;transition:background-color .5s;}
        `);},
        injectHTML(){const e=`<div id="trix-container" class="hidden"><div id="trix-header"><div id="trix-header-title"><img id="trix-logo" src="https://i.postimg.cc/0NkRZxDm/image.png" alt="TriX Logo"> <span id="trix-header-title-text">TriX Executor</span><span id="trix-header-tab-counter" class="trix-tab-badge">1</span></div><div id="trix-window-controls"><button id="trix-minimize-btn" title="Minimize">-</button> <button id="trix-close-btn" title="Close">✕</button></div></div><div id="trix-body"><div id="trix-left-panel"><div id="trix-script-list-title">Script List</div><div id="trix-script-list"></div></div><div id="trix-right-panel"><textarea id="trix-editor" placeholder="-- Paste or load a script here..."></textarea><div id="trix-console"></div></div></div><div id="trix-footer"><button id="trix-execute-btn" class="trix-button primary">▶ Execute</button> <button id="trix-clear-btn" class="trix-button">🗑️ Clear</button> <input type="text" id="trix-save-name" placeholder="Script Name..." class="trix-button" style="flex-grow:1; cursor:text;"> <button id="trix-save-btn" class="trix-button">💾 Save</button> <button id="trix-delete-btn" class="trix-button danger">❌ Delete</button><div id="trix-footer-status"><span id="trix-conn-status-indicator"></span><span id="trix-conn-status-text">Connecting...</span></div></div></div><button id="trix-open-btn"><span>Open TriX</span><span id="trix-open-btn-badge" class="trix-tab-badge">1</span></button>`;document.body.insertAdjacentHTML("beforeend",e)},
        attachEventListeners(){const e=document.getElementById("trix-container"),t=document.getElementById("trix-header");t.addEventListener("mousedown",t=>{if(t.target.closest("#trix-window-controls"))return;let s=!0;const o=t.clientX-e.offsetLeft,n=t.clientY-e.offsetTop,i=i=>{s&&(i.preventDefault(),e.style.left=`${i.clientX-o}px`,e.style.top=`${i.clientY-n}px`)},d=()=>{s=!1,document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",d)};document.addEventListener("mousemove",i),document.addEventListener("mouseup",d)}),document.getElementById("trix-open-btn").addEventListener("click",()=>this.togglePanel(!0)),document.getElementById("trix-close-btn").addEventListener("click",()=>this.togglePanel(!1)),document.getElementById("trix-minimize-btn").addEventListener("click",()=>{this.isMinimized=!this.isMinimized,e.classList.toggle("minimized",this.isMinimized)}),document.getElementById("trix-script-list").addEventListener("click",e=>{if(e.target.matches(".trix-script-item")){const t=e.target.dataset.scriptKey;TriX_Core.ScriptManager.loadScriptToEditor(t)}}),document.getElementById("trix-execute-btn").addEventListener("click",()=>TriX_Core.Executor.execute(document.getElementById("trix-editor").value)),document.getElementById("trix-clear-btn").addEventListener("click",()=>{document.getElementById("trix-editor").value="",document.getElementById("trix-save-name").value="",this.setActiveScriptItem(null),this.currentScriptName=""}),document.getElementById("trix-save-btn").addEventListener("click",TriX_Core.ScriptManager.saveScriptFromEditor),document.getElementById("trix-delete-btn").addEventListener("click",TriX_Core.ScriptManager.deleteCurrentScript)},
        togglePanel(e){const t=document.getElementById("trix-container"),s=document.getElementById("trix-open-btn"),o=t.classList.contains("hidden");!0===e||o?(t.classList.remove("hidden"),s.style.display="none"):(t.classList.add("hidden"),s.style.display="flex")},
        log(e,t="log"){const s=document.getElementById("trix-console");if(!s)return;const o=document.createElement("div");o.className=`log-${t}`,o.textContent=`> ${String(e)}`,s.prepend(o)},
        setActiveScriptItem(e){document.querySelectorAll(".trix-script-item").forEach(t=>{t.classList.toggle("active",t.dataset.scriptKey===e)})}
    };
    return UI;
})();