3x-ui/web/html/common/page.html
lolka1333 4800f8fb70
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 <test123@gmail.com>
2026-01-05 05:50:40 +01:00

92 lines
No EOL
3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{ define "page/head_start" }}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" href="{{ .base_path }}assets/ant-design-vue/antd.min.css">
<link rel="stylesheet" href="{{ .base_path }}assets/css/custom.min.css?{{ .cur_ver }}">
<style>
[v-cloak] {
display: none;
}
/* vazirmatn-regular - arabic_latin_latin-ext */
@font-face {
font-display: swap;
font-family: 'Vazirmatn';
font-style: normal;
font-weight: 400;
src: url('{{ .base_path }}assets/Vazirmatn-UI-NL-Regular.woff2') format('woff2');
unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC, U+0030-0039;
}
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;
}
}
</style>
<title>{{ .host }} {{ i18n .title}}</title>
{{ end }}
{{ define "page/head_end" }}
</head>
{{ end }}
{{ define "page/body_start" }}
<body>
<div id="message"></div>
{{ end }}
{{ define "page/body_scripts" }}
<script src="{{ .base_path }}assets/vue/vue.min.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/moment/moment.min.js"></script>
<script src="{{ .base_path }}assets/ant-design-vue/antd.min.js"></script>
<script src="{{ .base_path }}assets/axios/axios.min.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/qs/qs.min.js"></script>
<script src="{{ .base_path }}assets/js/axios-init.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
<script>
const basePath = '{{ .base_path }}';
axios.defaults.baseURL = basePath;
</script>
<script src="{{ .base_path }}assets/js/websocket.js?{{ .cur_ver }}"></script>
{{ end }}
{{ define "page/body_end" }}
</body>
</html>
{{ end }}