From 4800f8fb706a092a38255ee70904227238b2a6f6 Mon Sep 17 00:00:00 2001 From: lolka1333 Date: Mon, 5 Jan 2026 05:50:40 +0100 Subject: [PATCH] feat: Real-time Outbound Traffic, UI Improvements & Fix (#3629) * Refactor HTML and JavaScript for improved UI and functionality - Cleaned up JavaScript methods in subscription.js for better readability. - Updated inbounds.html to clarify traffic update handling and removed unnecessary comments. - Enhanced xray.html by correcting casing in routingDomainStrategies. - Added mobile touch scrolling styles in page.html for better tab navigation on small screens. - Streamlined vless.html by removing redundant line breaks and improving form layout. - Refined subscription subpage.html for better structure and user experience. - Adjusted outbounds.html to improve button visibility and functionality. - Updated xray_traffic_job.go to ensure accurate traffic updates and real-time UI refresh. * Refactor client traffic handling in InboundService - Updated addClientTraffic method to initialize onlineClients as an empty slice instead of nil. - Improved clarity and consistency in handling empty onlineUsers scenario. * Add WebSocket support for outbounds traffic updates - Implemented WebSocket connection in xray.html to handle real-time updates for outbounds traffic. - Enhanced xray_traffic_job.go to retrieve and broadcast outbounds traffic updates. - Introduced MessageTypeOutbounds in hub.go for managing outbounds messages. - Added BroadcastOutbounds function in notifier.go to facilitate broadcasting outbounds updates to connected clients. --------- Co-authored-by: lolka1333 --- web/assets/js/subscription.js | 10 +- web/html/common/page.html | 34 +++ web/html/form/protocol/vless.html | 211 ++++++++---------- web/html/inbounds.html | 23 +- .../settings/panel/subscription/subpage.html | 167 ++++++-------- web/html/settings/xray/outbounds.html | 4 +- web/html/xray.html | 13 +- web/job/xray_traffic_job.go | 24 +- web/service/inbound.go | 4 +- web/websocket/hub.go | 1 + web/websocket/notifier.go | 8 + 11 files changed, 260 insertions(+), 239 deletions(-) diff --git a/web/assets/js/subscription.js b/web/assets/js/subscription.js index c7627837..b79d361c 100644 --- a/web/assets/js/subscription.js +++ b/web/assets/js/subscription.js @@ -138,14 +138,14 @@ return `streisand://import/${encodeURIComponent(this.app.subUrl)}`; }, v2raytunUrl() { - return this.app.subUrl; + return this.app.subUrl; }, npvtunUrl() { - return this.app.subUrl; + return this.app.subUrl; }, - happUrl() { - return `happ://add/${encodeURIComponent(this.app.subUrl)}`; - } + happUrl() { + return `happ://add/${encodeURIComponent(this.app.subUrl)}`; + } }, methods: { renderLink, diff --git a/web/html/common/page.html b/web/html/common/page.html index 0af63afb..058682d5 100644 --- a/web/html/common/page.html +++ b/web/html/common/page.html @@ -24,6 +24,40 @@ body { font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Vazirmatn', 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } + + /* mobile touch scrolling for tabs */ + @media (max-width: 576px) { + .ant-tabs-nav-container { + overflow-x: auto !important; + -webkit-overflow-scrolling: touch; + scroll-behavior: smooth; + overscroll-behavior-x: contain; + white-space: nowrap; + max-width: 100%; + padding: 0 !important; /* Remove padding for arrows */ + } + .ant-tabs-nav-wrap { + overflow: visible !important; + padding: 0 !important; + } + .ant-tabs-nav-scroll { + overflow: visible !important; + box-shadow: none !important; + } + .ant-tabs-nav { + display: flex !important; + transform: none !important; /* Disable JS transform */ + width: auto !important; + margin: 0 !important; + } + .ant-tabs-tab-prev, + .ant-tabs-tab-next { + display: none !important; /* Hide arrows */ + } + .ant-tabs-nav-container::-webkit-scrollbar { + display: none; + } + } {{ .host }} – {{ i18n .title}} {{ end }} diff --git a/web/html/form/protocol/vless.html b/web/html/form/protocol/vless.html index bdf75be3..fc9c3852 100644 --- a/web/html/form/protocol/vless.html +++ b/web/html/form/protocol/vless.html @@ -1,6 +1,5 @@ {{define "form/vless"}} - + {{template "form/client"}} @@ -22,115 +21,103 @@ - + - + + + Fallback [[ index + 1 ]] + + + + + + + + + + + + + + + + + + + + {{end}} \ No newline at end of file diff --git a/web/html/inbounds.html b/web/html/inbounds.html index 4e1149ae..eeffd98d 100644 --- a/web/html/inbounds.html +++ b/web/html/inbounds.html @@ -1608,24 +1608,9 @@ // Listen for traffic updates window.wsClient.on('traffic', (payload) => { - if (payload && payload.clientTraffics && Array.isArray(payload.clientTraffics)) { - // Update client traffic statistics - payload.clientTraffics.forEach(clientTraffic => { - const dbInbound = this.dbInbounds.find(ib => { - if (!ib) return false; - const clients = this.getInboundClients(ib); - return clients && Array.isArray(clients) && clients.some(c => c && c.email === clientTraffic.email); - }); - if (dbInbound && dbInbound.clientStats && Array.isArray(dbInbound.clientStats)) { - const stats = dbInbound.clientStats.find(s => s && s.email === clientTraffic.email); - if (stats) { - stats.up = clientTraffic.up || stats.up; - stats.down = clientTraffic.down || stats.down; - stats.total = clientTraffic.total || stats.total; - } - } - }); - } + // Note: Do NOT update total consumed traffic (stats.up, stats.down) from this event + // because clientTraffics contains delta/incremental values, not total accumulated values. + // Total traffic is updated via the 'inbounds' event which contains accumulated values from database. // Update online clients list in real-time if (payload && Array.isArray(payload.onlineClients)) { @@ -1645,8 +1630,6 @@ } }); - // Notifications disabled - white notifications are not needed - // Fallback to polling if WebSocket fails window.wsClient.on('error', () => { console.warn('WebSocket connection failed, falling back to polling'); diff --git a/web/html/settings/panel/subscription/subpage.html b/web/html/settings/panel/subscription/subpage.html index 0043d0d2..222352ff 100644 --- a/web/html/settings/panel/subscription/subpage.html +++ b/web/html/settings/panel/subscription/subpage.html @@ -20,28 +20,20 @@