### Docker Installation Source: https://github.com/vaxilu/x-ui/blob/main/README.md Installs x-ui using Docker. This method requires Docker to be installed on the system. It maps local directories for data and certificates and restarts the container automatically. ```shell curl -fsSL https://get.docker.com | sh mkdir x-ui && cd x-ui docker run -itd --network=host \ -v $PWD/db/:/etc/x-ui/ \ -v $PWD/cert/:/root/cert/ \ --name x-ui --restart=unless-stopped \ enwaiax/x-ui:latest ``` -------------------------------- ### Manual Installation/Upgrade Source: https://github.com/vaxilu/x-ui/blob/main/README.md Provides steps for manually installing or upgrading x-ui by downloading the latest release, extracting it, and setting up systemd services. It includes instructions for handling different CPU architectures. ```shell cd /root/ rm x-ui/ /usr/local/x-ui/ /usr/bin/x-ui -rf tar zxvf x-ui-linux-amd64.tar.gz chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh cp x-ui/x-ui.sh /usr/bin/x-ui cp -f x-ui/x-ui.service /etc/systemd/system/ systemctl daemon-reload systemctl enable x-ui systemctl restart x-ui ``` -------------------------------- ### Vue.js Application Setup and Methods Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/setting.html This snippet details the initialization of the Vue.js application, including data properties for managing settings, user information, and UI states. It outlines methods for fetching all settings, updating settings, updating user information, and restarting the panel. It also includes logic for monitoring changes to settings and disabling the save button accordingly. ```javascript const app = new Vue({ delimiters: [ '[[', ']]' ], el: '#app', data: { siderDrawer, spinning: false, oldAllSetting: new AllSetting(), allSetting: new AllSetting(), saveBtnDisable: true, user: {}, }, methods: { loading(spinning = true) { this.spinning = spinning; }, async getAllSetting() { this.loading(true); const msg = await HttpUtil.post("/xui/setting/all"); this.loading(false); if (msg.success) { this.oldAllSetting = new AllSetting(msg.obj); this.allSetting = new AllSetting(msg.obj); this.saveBtnDisable = true; } }, async updateAllSetting() { this.loading(true); const msg = await HttpUtil.post("/xui/setting/update", this.allSetting); this.loading(false); if (msg.success) { await this.getAllSetting(); } }, async updateUser() { this.loading(true); const msg = await HttpUtil.post("/xui/setting/updateUser", this.user); this.loading(false); if (msg.success) { this.user = {}; } }, async restartPanel() { await new Promise(resolve => { this.$confirm({ title: '重启面板', content: '确定要重启面板吗?点击确定将于 3 秒后重启,若重启后无法访问面板,请前往服务器查看面板日志信息', okText: '确定', cancelText: '取消', onOk: () => resolve(), }); }); this.loading(true); const msg = await HttpUtil.post("/xui/setting/restartPanel"); this.loading(false); if (msg.success) { this.loading(true); await PromiseUtil.sleep(5000); location.reload(); } } }, async mounted() { await this.getAllSetting(); while (true) { await PromiseUtil.sleep(1000); this.saveBtnDisable = this.oldAllSetting.equals(this.allSetting); } } }); ``` -------------------------------- ### Install/Upgrade x-ui Source: https://github.com/vaxilu/x-ui/blob/main/README.md Installs or upgrades the x-ui panel using a provided script. This is the recommended method for most users. ```bash bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh) ``` -------------------------------- ### Text Modal Component Setup (JavaScript) Source: https://github.com/vaxilu/x-ui/blob/main/web/html/common/text_modal.html Defines a Vue.js component for a modal that displays text content, a file name, and a QR code. It integrates with ClipboardJS for copying content and QRious for generating QR codes. The `show` method handles the initialization and update of the QR code and clipboard functionality. ```javascript const txtModal = { title: '', content: '', fileName: '', qrcode: null, clipboard: null, visible: false, show: function (title='', content='', fileName='') { this.title = title; this.content = content; this.fileName = fileName; this.visible = true; textModalApp.$nextTick(() => { if (this.clipboard === null) { this.clipboard = new ClipboardJS('#txt-modal-ok-btn', { text: () => this.content, }); this.clipboard.on('success', () => app.$message.success('{{ i18n "copied" }}')); } if (this.qrcode === null) { this.qrcode = new QRious({ element: document.querySelector('#qrCode'), size: 260, value: content, }); } else { this.qrcode.value = content; } }); }, close: function () { this.visible = false; }, }; const textModalApp = new Vue({ el: '#text-modal', data: { txtModal: txtModal, }, }); ``` -------------------------------- ### Migrate from v2-ui Source: https://github.com/vaxilu/x-ui/blob/main/README.md Migrates all inbound account data from a v2-ui installation to x-ui. Note that panel settings and user credentials are not migrated. After migration, v2-ui should be stopped to avoid port conflicts. ```shell x-ui v2-ui ``` -------------------------------- ### Build Custom Docker Image Source: https://github.com/vaxilu/x-ui/blob/main/README.md Builds a custom Docker image for x-ui from the current directory. ```dockerfile docker build -t x-ui . ``` -------------------------------- ### Vue.js Application Initialization and Methods Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbounds.html Initializes the Vue.js application, defining data properties, methods for managing inbound connections (fetching, adding, updating, deleting, resetting traffic), and computed properties. It also includes watchers for search functionality and lifecycle hooks. ```javascript const app = new Vue({ delimiters: ['[[', ']]'], el: '#app', data: { siderDrawer, spinning: false, inbounds: [], dbInbounds: [], searchKey: '', }, methods: { loading(spinning=true) { this.spinning = spinning; }, async getDBInbounds() { this.loading(); const msg = await HttpUtil.post('/xui/inbound/list'); this.loading(false); if (!msg.success) { return; } this.setInbounds(msg.obj); }, setInbounds(dbInbounds) { this.inbounds.splice(0); this.dbInbounds.splice(0); for (const inbound of dbInbounds) { const dbInbound = new DBInbound(inbound); this.inbounds.push(dbInbound.toInbound()); this.dbInbounds.push(dbInbound); } }, searchInbounds(key) { if (ObjectUtil.isEmpty(key)) { this.searchedInbounds = this.dbInbounds.slice(); } else { this.searchedInbounds.splice(0, this.searchedInbounds.length); this.dbInbounds.forEach(inbound => { if (ObjectUtil.deepSearch(inbound, key)) { this.searchedInbounds.push(inbound); } }); } }, clickAction(action, dbInbound) { switch (action.key) { case "qrcode": this.showQrcode(dbInbound); break; case "edit": this.openEditInbound(dbInbound); break; case "resetTraffic": this.resetTraffic(dbInbound); break; case "delete": this.delInbound(dbInbound); break; } }, openAddInbound() { inModal.show({ title: '添加入站', okText: '添加', confirm: async (inbound, dbInbound) => { inModal.loading(); await this.addInbound(inbound, dbInbound); inModal.close(); } }); }, openEditInbound(dbInbound) { const inbound = dbInbound.toInbound(); inModal.show({ title: '修改入站', okText: '修改', inbound: inbound, dbInbound: dbInbound, confirm: async (inbound, dbInbound) => { inModal.loading(); await this.updateInbound(inbound, dbInbound); inModal.close(); } }); }, async addInbound(inbound, dbInbound) { const data = { up: dbInbound.up, down: dbInbound.down, total: dbInbound.total, remark: dbInbound.remark, enable: dbInbound.enable, expiryTime: dbInbound.expiryTime, listen: inbound.listen, port: inbound.port, protocol: inbound.protocol, settings: inbound.settings.toString(), streamSettings: inbound.stream.toString(), sniffing: inbound.canSniffing() ? inbound.sniffing.toString() : '{}', }; await this.submit('/xui/inbound/add', data, inModal); }, async updateInbound(inbound, dbInbound) { const data = { up: dbInbound.up, down: dbInbound.down, total: dbInbound.total, remark: dbInbound.remark, enable: dbInbound.enable, expiryTime: dbInbound.expiryTime, listen: inbound.listen, port: inbound.port, protocol: inbound.protocol, settings: inbound.settings.toString(), streamSettings: inbound.stream.toString(), sniffing: inbound.canSniffing() ? inbound.sniffing.toString() : '{}', }; await this.submit(`/xui/inbound/update/${dbInbound.id}`, data, inModal); }, resetTraffic(dbInbound) { this.$confirm({ title: '重置流量', content: '确定要重置流量吗?', okText: '重置', cancelText: '取消', onOk: () => { const inbound = dbInbound.toInbound(); dbInbound.up = 0; dbInbound.down = 0; this.updateInbound(inbound, dbInbound); }, }); }, delInbound(dbInbound) { this.$confirm({ title: '删除入站', content: '确定要删除入站吗?', okText: '删除', cancelText: '取消', onOk: () => this.submit('/xui/inbound/del/' + dbInbound.id), }); }, showQrcode(dbInbound) { const link = dbInbound.genLink(); qrModal.show('二维码', link); }, showInfo(dbInbound) { infoModal.show(dbInbound); }, switchEnable(dbInbound) { this.submit(`/xui/inbound/update/${dbInbound.id}`, dbInbound); }, async submit(url, data, modal) { const msg = await HttpUtil.postWithModal(url, data, modal); if (msg.success) { await this.getDBInbounds(); } }, }, watch: { searchKey(value) { this.searchInbounds(value); } }, mounted() { this.getDBInbounds(); }, computed: { total() { let down = 0, up = 0; for (let i = 0; i < this.dbInb } } }); ``` -------------------------------- ### X-UI API Endpoints Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/setting.html This section documents the API endpoints for managing X-UI settings and panel operations. It covers endpoints for retrieving all settings, updating settings, updating user information, and restarting the panel. ```APIDOC API Endpoints: GET /xui/setting/all Description: Retrieves all current settings for the X-UI panel. Returns: JSON object containing all settings. POST /xui/setting/update Description: Updates the X-UI panel settings. Request Body: JSON object with updated settings. Returns: Success or failure status. POST /xui/setting/updateUser Description: Updates user-specific settings. Request Body: JSON object with updated user settings. Returns: Success or failure status. POST /xui/setting/restartPanel Description: Restarts the X-UI panel. Returns: Success or failure status. May trigger a client-side reload after a delay. ``` -------------------------------- ### Shadowsocks Form Configuration Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/form/protocol/shadowsocks.html Defines the configuration form for Shadowsocks, specifying supported network protocols like TCP and UDP. ```go {{define "form/shadowsocks"}} \[ \[ method \] \] tcp+udp tcp udp {{end}} ``` -------------------------------- ### X-UI CSS Styling Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/setting.html This snippet contains CSS rules for styling the X-UI interface. It includes media queries for responsive design, margin adjustments for layout elements, and styling for tabs and lists. ```css @media (min-width: 769px) { .ant-layout-content { margin: 24px 16px; } } .ant-col-sm-24 { margin-top: 10px; } .ant-tabs-bar { margin: 0; } .ant-list-item { display: block; } .ant-tabs-top-bar { background: white; } ``` -------------------------------- ### Frontend Styling for x-ui Source: https://github.com/vaxilu/x-ui/blob/main/web/html/login.html This snippet contains CSS rules for styling the user interface of the x-ui project. It defines styles for the main application container, headings, buttons, and input fields, ensuring a consistent and visually appealing design. ```html {{template "head" .}} #app { padding-top: 100px; } h1 { text-align: center; color: #fff; margin: 20px 0 50px 0; } .ant-btn, .ant-input { height: 50px; border-radius: 30px; } .ant-input-affix-wrapper .ant-input-prefix { left: 23px; } .ant-input-affix-wrapper .ant-input:not(:first-child) { padding-left: 50px; }{{ .title }} ``` -------------------------------- ### JavaScript for Dynamic Background and Login Source: https://github.com/vaxilu/x-ui/blob/main/web/html/login.html This JavaScript code generates a dynamic gradient background for the application and implements the login functionality using Vue.js. It includes utility functions for random color and degree generation, and an asynchronous login method that handles user authentication via an HTTP POST request. ```javascript {{ i18n "login" }} {{template "js" .}} const leftColor = RandomUtil.randomIntRange(0x222222, 0xFFFFFF / 2).toString(16); const rightColor = RandomUtil.randomIntRange(0xFFFFFF / 2, 0xDDDDDD).toString(16); const deg = RandomUtil.randomIntRange(0, 360); const background = `linear-gradient(${deg}deg, #${leftColor} 10%, #${rightColor} 100%)`; document.querySelector('#app').style.background = background; const app = new Vue({ delimiters: ['[[', ']]'], el: '#app', data: { loading: false, user: new User(), }, methods: { async login() { this.loading = true; const msg = await HttpUtil.post('/login', this.user); this.loading = false; if (msg.success) { location.href = basePath + 'xui/'; } } } }); ``` -------------------------------- ### HTML Modal Templates Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbounds.html Contains various HTML templates for different modal dialogs used in the x-ui interface. These include templates for inbound data, prompts, QR codes, text display, and inbound information. ```html {{template "inboundModal"}} {{template "promptModal"}} {{template "qrcodeModal"}} {{template "textModal"}} {{template "inboundInfoModal"}} ``` -------------------------------- ### HTML Structure for x-ui Panel Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbounds.html This snippet represents the HTML structure of the x-ui panel, including template inclusions for head and common sider elements, CSS media queries for layout adjustments, and placeholders for dynamic data like total upload/download and inbound counts. ```html {{template "head" .}} @media (min-width: 769px) { .ant-layout-content { margin: 24px 16px; } } .ant-col-sm-24 { margin-top: 10px; } {{ template "commonSider" . }} Please go to the panel settings as soon as possible to modify the username and password, otherwise there may be a risk of leaking account information 总上传 / 下载: [[ sizeFormat(total.up) ]] / [[ sizeFormat(total.down) ]] 总用量: [[ sizeFormat(total.up + total.down) ]] 入站数量: [[ dbInbounds.length ]] {{template "js" .}} ``` -------------------------------- ### Inbound Protocol, Address, and Port Information (GoHTML) Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/component/inbound_info.html This GoHTML template snippet defines the structure for displaying inbound connection details such as protocol, address, and port. It's designed to be included within a larger component. ```gohtml {{define "component/inboundInfoComponent"}} 协议: [[ dbInbound.protocol ]] 地址: [[ dbInbound.address ]] 端口: [[ dbInbound.port ]] {{end}} ``` -------------------------------- ### JavaScript Base Path Configuration Source: https://github.com/vaxilu/x-ui/blob/main/web/html/common/js.html This snippet configures the base path and default base URL for Axios requests within the application. It relies on a Go template variable `{{ .base_path }}` to dynamically set the base URL. ```javascript const basePath = '{{ .base_path }}'; axios.defaults.baseURL = basePath; ``` -------------------------------- ### TLS Settings Form Definition Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/form/tls_settings.html Defines the structure for the TLS settings form, including fields for the certificate file path and its content. This is a Go template definition. ```go {{define "form/tlsSettings"}} certificate file path certificate file content {{end}} ``` -------------------------------- ### Inbound Network and TLS Information (GoHTML) Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/component/inbound_info.html This GoHTML template snippet defines how to display network protocol, TLS domain, and xtls domain for an inbound connection. It uses conditional logic to display '无' (none) if the serverName is not provided. ```gohtml {{define "inboundInfoStream"}} 传输: [[ inbound.network ]] tls域名: [[ inbound.serverName ? inbound.serverName : "无" ]] xtls域名: [[ inbound.serverName ? inbound.serverName : "无" ]] {{end}} ``` -------------------------------- ### Vue.js Integration for Inbound Modal Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbound_modal.html This code sets up a Vue.js instance to manage the inbound modal's UI and data binding. It defines the `inModal` and `protocols` objects as data properties, provides computed properties for `inbound` and `dbInbound`, and includes a method `streamNetworkChange` to handle changes in stream network settings, specifically resetting the TLS option when the network changes from 'kcp'. ```javascript new Vue({ delimiters: ['[[', ']]'], el: '#inbound-modal', data: { inModal: inModal, Protocols: protocols, SSMethods: SSMethods, get inbound() { return inModal.inbound; }, get dbInbound() { return inModal.dbInbound; } }, methods: { streamNetworkChange(oldValue) { if (oldValue === 'kcp') { this.inModal.inbound.tls = false; } } } }); ``` -------------------------------- ### Inbound Table Columns Configuration Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbounds.html Defines the configuration for columns displayed in the inbound connections table. Each column specifies its title, alignment, width, and rendering logic (e.g., scoped slots for custom rendering). ```javascript const columns = [ { title: "操作", align: 'center', width: 30, scopedSlots: { customRender: 'action' }, }, { title: "启用", align: 'center', width: 40, scopedSlots: { customRender: 'enable' }, }, { title: "id", align: 'center', dataIndex: "id", width: 30, }, { title: "备注", align: 'center', width: 100, dataIndex: "remark", }, { title: "协议", align: 'center', width: 60, scopedSlots: { customRender: 'protocol' }, }, { title: "端口", align: 'center', dataIndex: "port", width: 60, }, { title: "流量↑|↓", align: 'center', width: 150, scopedSlots: { customRender: 'traffic' }, }, { title: "详细信息", align: 'center', width: 40, scopedSlots: { customRender: 'settings' }, }, { title: "传输配置", align: 'center', width: 60, scopedSlots: { customRender: 'stream' }, }, { title: "到期时间", align: 'center', width: 80, scopedSlots: { customRender: 'expiryTime' }, } ]; ``` -------------------------------- ### Stream QUIC Configuration Options Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/form/stream/stream_quic.html Defines the available options for configuring stream QUIC, including encryption algorithms and camouflage protocols. These settings allow users to customize traffic behavior for security and privacy. ```go package main // Define the available options for stream QUIC configuration // This includes encryption methods and camouflage protocols. // Example usage within a configuration struct: // type QUICConfig struct { // Encryption string // Camouflage string // } // Available Encryption Methods: // aes-128-gcm // chacha20-poly1305 // none // Available Camouflage Protocols: // srtp (camouflage video call) // utp (camouflage BT download) // wechat-video (camouflage WeChat video) // dtls (camouflage DTLS 1.2 packages) // wireguard (camouflage wireguard packages) // none (not camouflage) func main() { // This is a placeholder for demonstration. Actual configuration would be part of the application logic. println("Stream QUIC configuration options defined.") } ``` -------------------------------- ### Stream Settings Protocols Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/form/stream/stream_settings.html Defines the supported protocols for stream settings in x-ui. This includes TCP, KCP, WebSocket, HTTP, QUIC, and gRPC. ```go {{define "form/streamSettings"}} tcp kcp ws http quic grpc {{end}} ``` -------------------------------- ### Inbound Modal JavaScript Logic Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbound_modal.html This JavaScript code defines the `inModal` object, which manages the state and behavior of the inbound configuration modal. It includes properties for visibility, loading states, confirmation callbacks, and methods to show, close, and update the modal's content with inbound and database inbound data. It also defines available network protocols. ```javascript const inModal = { title: '', visible: false, confirmLoading: false, okText: '确定', confirm: null, inbound: new Inbound(), dbInbound: new DBInbound(), ok() { ObjectUtil.execute(inModal.confirm, inModal.inbound, inModal.dbInbound); }, show({ title='', okText='确定', inbound=null, dbInbound=null, confirm=(inbound, dbInbound)=>{} }) { this.title = title; this.okText = okText; if (inbound) { this.inbound = Inbound.fromJson(inbound.toJson()); } else { this.inbound = new Inbound(); } if (dbInbound) { this.dbInbound = new DBInbound(dbInbound); } else { this.dbInbound = new DBInbound(); } this.confirm = confirm; this.visible = true; }, close() { inModal.visible = false; inModal.loading(false); }, loading(loading) { inModal.confirmLoading = loading; } }; const protocols = { VMESS: Protocols.VMESS, VLESS: Protocols.VLESS, TROJAN: Protocols.TROJAN, SHADOWSOCKS: Protocols.SHADOWSOCKS, DOKODEMO: Protocols.DOKODEMO, SOCKS: Protocols.SOCKS, HTTP: Protocols.HTTP }; ``` -------------------------------- ### Vue.js Status Monitoring and Xray Version Management Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/index.html This JavaScript code defines Vue.js components and logic for monitoring server status and managing Xray versions. It includes classes for representing resource usage (CPU, memory, disk, swap) and system status, along with methods for fetching data, updating the UI, and handling Xray version switching. The `Status` class parses server data to calculate resource percentages and display status indicators. ```javascript const State = { Running: "running", Stop: "stop", Error: "error", }; Object.freeze(State); class CurTotal { constructor(current, total) { this.current = current; this.total = total; } get percent() { if (this.total === 0) { return 0; } return toFixed(this.current / this.total * 100, 2); } get color() { const percent = this.percent; if (percent < 80) { return '#67C23A'; } else if (percent < 90) { return '#E6A23C'; } else { return '#F56C6C'; } } } class Status { constructor(data) { this.cpu = new CurTotal(0, 0); this.disk = new CurTotal(0, 0); this.loads = [0, 0, 0]; this.mem = new CurTotal(0, 0); this.netIO = {up: 0, down: 0}; this.netTraffic = {sent: 0, recv: 0}; this.swap = new CurTotal(0, 0); this.tcpCount = 0; this.udpCount = 0; this.uptime = 0; this.xray = {state: State.Stop, errorMsg: "", version: "", color: ""}; if (data == null) { return; } this.cpu = new CurTotal(data.cpu, 100); this.disk = new CurTotal(data.disk.current, data.disk.total); this.loads = data.loads.map(load => toFixed(load, 2)); this.mem = new CurTotal(data.mem.current, data.mem.total); this.netIO = data.netIO; this.netTraffic = data.netTraffic; this.swap = new CurTotal(data.swap.current, data.swap.total); this.tcpCount = data.tcpCount; this.udpCount = data.udpCount; this.uptime = data.uptime; this.xray = data.xray; switch (this.xray.state) { case State.Running: this.xray.color = "green"; break; case State.Stop: this.xray.color = "orange"; break; case State.Error: this.xray.color = "red"; break; default: this.xray.color = "gray"; } } } const versionModal = { visible: false, versions: [], show(versions) { this.visible = true; this.versions = versions; }, hide() { this.visible = false; }, }; const app = new Vue({ delimiters: ['[[', ']]'], el: '#app', data: { siderDrawer, status: new Status(), versionModal, spinning: false, loadingTip: '加载中', }, methods: { loading(spinning, tip = '加载中') { this.spinning = spinning; this.loadingTip = tip; }, async getStatus() { const msg = await HttpUtil.post('/server/status'); if (msg.success) { this.setStatus(msg.obj); } }, setStatus(data) { this.status = new Status(data); }, async openSelectV2rayVersion() { this.loading(true); const msg = await HttpUtil.post('server/getXrayVersion'); this.loading(false); if (!msg.success) { return; } versionModal.show(msg.obj); }, switchV2rayVersion(version) { this.$confirm({ title: '切换 xray 版本', content: '是否切换 xray 版本至' + ` ${version}?`, okText: '确定', cancelText: '取消', onOk: async () => { versionModal.hide(); this.loading(true, '安装中,请不要刷新此页面'); await HttpUtil.post(`/server/installXray/${version}`); this.loading(false); }, }); }, }, async mounted() { while (true) { try { await this.getStatus(); } catch (e) { console.error(e); } await PromiseUtil.sleep(2000); } }, }); ``` -------------------------------- ### Vue Template for Inbound Info Modal Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbound_info_modal.html This is a Go template snippet that defines the structure of the inbound information modal, likely rendering a component named 'component/inboundInfo'. It serves as the HTML structure for the modal managed by the JavaScript logic. ```html {{define "inboundInfoModal"}} {{template "component/inboundInfo"}} {{end}} ``` -------------------------------- ### HTML Head Template Source: https://github.com/vaxilu/x-ui/blob/main/web/html/common/head.html Defines the head section of the HTML template, including a v-cloak directive for Vue.js and dynamic title insertion. ```gohtml {{define "head"}} \[v-cloak\] { display: none; } {{.title}} {{end}} ``` -------------------------------- ### JavaScript QR Code Modal Component Source: https://github.com/vaxilu/x-ui/blob/main/web/html/common/qrcode_modal.html This snippet defines a JavaScript object `qrModal` for managing a QR code modal. It includes methods to show, close, and handle QR code generation and clipboard copying. It depends on Vue.js, ClipboardJS, and QRious libraries. ```javascript const qrModal = { title: '', content: '', okText: '', copyText: '', qrcode: null, clipboard: null, visible: false, show: function (title='', content='', okText='{{ i18n "copy" }}', copyText='') { this.title = title; this.content = content; this.okText = okText; if (ObjectUtil.isEmpty(copyText)) { this.copyText = content; } else { this.copyText = copyText; } this.visible = true; qrModalApp.$nextTick(() => { if (this.clipboard === null) { this.clipboard = new ClipboardJS('#qr-modal-ok-btn', { text: () => this.copyText, }); this.clipboard.on('success', () => app.$message.success('{{ i18n "copied" }}')); } if (this.qrcode === null) { this.qrcode = new QRious({ element: document.querySelector('#qrCode'), size: 260, value: content, }); } else { this.qrcode.value = content; } }); }, close: function () { this.visible = false; }, }; const qrModalApp = new Vue({ el: '#qrcode-modal', data: { qrModal: qrModal, }, }); ``` -------------------------------- ### JavaScript Prompt Modal Component Source: https://github.com/vaxilu/x-ui/blob/main/web/html/common/prompt_modal.html Defines a JavaScript object 'promptModal' for managing a modal dialog used for user input. It handles input types, key events (Enter, Ctrl+S), confirmation, and visibility. The component is integrated with a Vue.js application. ```javascript const promptModal = { title: '', type: '', value: '', okText: '确定', visible: false, keyEnter(e) { if (this.type !== 'textarea') { e.preventDefault(); this.ok(); } }, ctrlS(e) { if (this.type === 'textarea') { e.preventDefault(); promptModal.confirm(promptModal.value); } }, ok() { promptModal.close(); promptModal.confirm(promptModal.value); }, confirm() {}, open({ title = '', type = 'text', value = '', okText = '确定', confirm = () => {}, }) { this.title = title; this.type = type; this.value = value; this.okText = okText; this.confirm = confirm; this.visible = true; promptModalApp.$nextTick(() => { document.querySelector('#prompt-modal-input').focus(); }); }, close() { this.visible = false; } }; const promptModalApp = new Vue({ el: '#prompt-modal', data: { promptModal: promptModal, }, }); ``` -------------------------------- ### Inbound Info Modal JavaScript Logic Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbound_info_modal.html This JavaScript code defines the 'infoModal' object, which manages the state and behavior of the inbound information modal. It handles visibility, data updates, and ClipboardJS integration for copying inbound links. The modal is integrated with a Vue.js application. ```javascript const infoModal = { visible: false, inbound: new Inbound(), dbInbound: new DBInbound(), clipboard: null, okBtnPros: { attrs: { id: "inbound-info-modal-ok-btn", style: "", }, }, show(dbInbound) { this.inbound = dbInbound.toInbound(); this.dbInbound = new DBInbound(dbInbound); this.visible = true; if (dbInbound.hasLink()) { this.okBtnPros.attrs.style = ""; } else { this.okBtnPros.attrs.style = "display: none"; } if (this.clipboard == null) { infoModalApp.$nextTick(() => { this.clipboard = new ClipboardJS(`#${this.okBtnPros.attrs.id}`, { text: () => this.dbInbound.genLink(), }); this.clipboard.on('success', () => app.$message.success('复制成功')); }); } }, close() { infoModal.visible = false; }, }; const infoModalApp = new Vue({ delimiters: ['[[', ']]'], el: '#inbound-info-modal', data: { infoModal, get dbInbound() { return this.infoModal.dbInbound; }, get inbound() { return this.infoModal.inbound; } }, }); ``` -------------------------------- ### Vue.js Inbound Info Component Definition (JavaScript) Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/component/inbound_info.html This JavaScript code defines a Vue.js component named 'inbound-info'. It uses custom delimiters '[[' and ']]' for data binding and includes the 'component/inboundInfoComponent' template for its structure. It accepts 'dbInbound' and 'inbound' as props. ```javascript Vue.component('inbound-info', { delimiters: ['[[', ']]'], props: ["dbInbound", "inbound"], template: '{{template "component/inboundInfoComponent"}}', }); ``` -------------------------------- ### JavaScript Inbound Data Calculation Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/inbounds.html Calculates the total 'down' and 'up' values from an array of inbound data objects. It iterates through the `dbInbounds` array, summing the 'down' and 'up' properties of each object. The function returns an object containing the total 'down' and 'up' values. ```javascript async getInbounds() { let down = 0; let up = 0; for (let i = 0; i < this.dbInbounds.length; ++i) { down += this.dbInbounds[i].down; up += this.dbInbounds[i].up; } return { down: down, up: up }; } ``` -------------------------------- ### JavaScript Sider Drawer Functionality Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/common_sider.html Defines a JavaScript object `siderDrawer` to manage the visibility state of a sider drawer component. It includes methods to show, close, and toggle the drawer's visibility. ```javascript const siderDrawer = { visible: false, show() { this.visible = true; }, close() { this.visible = false; }, change() { this.visible = !this.visible; } }; ``` -------------------------------- ### Vue Setting List Item Component Source: https://github.com/vaxilu/x-ui/blob/main/web/html/xui/component/setting.html Defines the 'setting-list-item' Vue component. It accepts 'type', 'title', 'desc', and 'value' as props and uses the 'component/settingListItem' template. ```Vue Vue.component('setting-list-item', { props: ["type", "title", "desc", "value"], template: `{{template "component/settingListItem"}}`, }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.