Merge branch 'main' into bbr

This commit is contained in:
Sanaei 2026-01-18 15:45:18 +01:00 committed by GitHub
commit 5f5d9ff611
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 116 additions and 30 deletions

View file

@ -18,6 +18,7 @@ on:
- 'go.mod'
- 'go.sum'
- 'x-ui.service.debian'
- 'x-ui.service.arch'
- 'x-ui.service.rhel'
jobs:
@ -80,6 +81,7 @@ jobs:
mkdir x-ui
cp xui-release x-ui/
cp x-ui.service.debian x-ui/
cp x-ui.service.arch x-ui/
cp x-ui.service.rhel x-ui/
cp x-ui.sh x-ui/
mv x-ui/xui-release x-ui/x-ui

View file

@ -818,6 +818,15 @@ install_x-ui() {
fi
fi
;;
arch | manjaro | parch)
if [ -f "x-ui.service.arch" ]; then
echo -e "${green}Found x-ui.service.arch in extracted files, installing...${plain}"
cp -f x-ui.service.arch ${xui_service}/x-ui.service >/dev/null 2>&1
if [[ $? -eq 0 ]]; then
service_installed=true
fi
fi
;;
*)
if [ -f "x-ui.service.rhel" ]; then
echo -e "${green}Found x-ui.service.rhel in extracted files, installing...${plain}"
@ -837,6 +846,9 @@ install_x-ui() {
ubuntu | debian | armbian)
curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.debian >/dev/null 2>&1
;;
arch | manjaro | parch)
curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.arch >/dev/null 2>&1
;;
*)
curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.rhel >/dev/null 2>&1
;;

View file

@ -737,6 +737,7 @@ update_x-ui() {
rm ${xui_folder} -f >/dev/null 2>&1
rm ${xui_folder}/x-ui.service -f >/dev/null 2>&1
rm ${xui_folder}/x-ui.service.debian -f >/dev/null 2>&1
rm ${xui_folder}/x-ui.service.arch -f >/dev/null 2>&1
rm ${xui_folder}/x-ui.service.rhel -f >/dev/null 2>&1
rm ${xui_folder}/x-ui -f >/dev/null 2>&1
rm ${xui_folder}/x-ui.sh -f >/dev/null 2>&1
@ -819,6 +820,15 @@ update_x-ui() {
fi
fi
;;
arch | manjaro | parch)
if [ -f "x-ui.service.arch" ]; then
echo -e "${green}Installing arch-like systemd unit...${plain}"
cp -f x-ui.service.arch ${xui_service}/x-ui.service >/dev/null 2>&1
if [[ $? -eq 0 ]]; then
service_installed=true
fi
fi
;;
*)
if [ -f "x-ui.service.rhel" ]; then
echo -e "${green}Installing rhel-like systemd unit...${plain}"
@ -837,6 +847,9 @@ update_x-ui() {
ubuntu | debian | armbian)
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.debian >/dev/null 2>&1
;;
arch | manjaro | parch)
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.arch >/dev/null 2>&1
;;
*)
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.rhel >/dev/null 2>&1
;;

View file

@ -14,10 +14,12 @@ class WebSocketClient {
}
connect() {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
return;
}
this.shouldReconnect = true;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
// Ensure basePath ends with '/' for proper URL construction
let basePath = this.basePath || '';
@ -97,7 +99,10 @@ class WebSocketClient {
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event).push(callback);
const callbacks = this.listeners.get(event);
if (!callbacks.includes(callback)) {
callbacks.push(callback);
}
}
off(event, callback) {

View file

@ -1602,7 +1602,6 @@
if (payload && Array.isArray(payload)) {
// Use setInbounds to properly convert to DBInbound objects with methods
this.setInbounds(payload);
this.searchInbounds(this.searchKey);
}
});
@ -1614,14 +1613,31 @@
// Update online clients list in real-time
if (payload && Array.isArray(payload.onlineClients)) {
this.onlineClients = payload.onlineClients;
// Recalculate client counts to update online status
this.dbInbounds.forEach(dbInbound => {
const inbound = this.inbounds.find(ib => ib.id === dbInbound.id);
if (inbound && this.clientCount[dbInbound.id]) {
this.clientCount[dbInbound.id] = this.getClientCounts(dbInbound, inbound);
const nextOnlineClients = payload.onlineClients;
let onlineChanged = this.onlineClients.length !== nextOnlineClients.length;
if (!onlineChanged) {
const prevSet = new Set(this.onlineClients);
for (const email of nextOnlineClients) {
if (!prevSet.has(email)) {
onlineChanged = true;
break;
}
}
});
}
this.onlineClients = nextOnlineClients;
if (onlineChanged) {
// Recalculate client counts to update online status
this.dbInbounds.forEach(dbInbound => {
const inbound = this.inbounds.find(ib => ib.id === dbInbound.id);
if (inbound && this.clientCount[dbInbound.id]) {
this.clientCount[dbInbound.id] = this.getClientCounts(dbInbound, inbound);
}
});
if (this.enableFilter) {
this.filterInbounds();
}
}
}
// Update last online map in real-time

View file

@ -5,6 +5,43 @@
<script src="{{ .base_path }}assets/ant-design-vue/antd.min.js"></script>
<script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
<script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
<style>
.subscription-page .subscription-link-box {
cursor: pointer;
border-radius: 12px;
padding: 25px 20px 15px 20px;
margin-top: -12px;
word-break: break-all;
font-size: 13px;
line-height: 1.5;
text-align: left;
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
transition: all 0.3s;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.dark.subscription-page .subscription-link-box {
background: rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.1);
color: #fff;
}
.dark.subscription-page .subscription-link-box:hover {
background: rgba(0, 0, 0, 0.3);
border-color: rgba(255, 255, 255, 0.2);
}
.light.subscription-page .subscription-link-box {
background: rgba(0, 0, 0, 0.03);
border: 1px solid rgba(0, 0, 0, 0.08);
color: rgba(0, 0, 0, 0.85);
}
.light.subscription-page .subscription-link-box:hover {
background: rgba(0, 0, 0, 0.05);
border-color: rgba(0, 0, 0, 0.14);
}
</style>
{{ template "page/head_end" .}}
{{ template "page/body_start" .}}
@ -138,27 +175,12 @@
style="margin-bottom: -10px; position: relative; z-index: 2; box-shadow: 0 2px 4px rgba(0,0,0,0.2);">
<span>[[ linkName(link, idx) ]]</span>
</a-tag>
<div @click="copy(link)" style="
cursor: pointer;
background: rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
padding: 25px 20px 15px 20px;
margin-top: -12px;
word-break: break-all;
color: #fff;
font-size: 13px;
line-height: 1.5;
text-align: left;
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
transition: all 0.3s;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
" onmouseover="this.style.background='rgba(0, 0, 0, 0.3)'; this.style.borderColor='rgba(255, 255, 255, 0.2)'"
onmouseout="this.style.background='rgba(0, 0, 0, 0.2)'; this.style.borderColor='rgba(255, 255, 255, 0.1)'">
<div @click="copy(link)" class="subscription-link-box">
[[ link ]]
</div>
</div>
</div>
</div>
<br />

16
x-ui.service.arch Normal file
View file

@ -0,0 +1,16 @@
[Unit]
Description=x-ui Service
After=network.target
Wants=network.target
[Service]
EnvironmentFile=-/etc/conf.d/x-ui
Environment="XRAY_VMESS_AEAD_FORCED=false"
Type=simple
WorkingDirectory=/usr/lib/x-ui/
ExecStart=/usr/lib/x-ui/x-ui
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target

View file

@ -229,9 +229,9 @@ reset_user() {
read -rp "Do you want to disable currently configured two-factor authentication? (y/n): " twoFactorConfirm
if [[ $twoFactorConfirm != "y" && $twoFactorConfirm != "Y" ]]; then
${xui_folder}/x-ui setting -username ${config_account} -password ${config_password} -resetTwoFactor false >/dev/null 2>&1
${xui_folder}/x-ui setting -username "${config_account}" -password "${config_password}" -resetTwoFactor false >/dev/null 2>&1
else
${xui_folder}/x-ui setting -username ${config_account} -password ${config_password} -resetTwoFactor true >/dev/null 2>&1
${xui_folder}/x-ui setting -username "${config_account}" -password "${config_password}" -resetTwoFactor true >/dev/null 2>&1
echo -e "Two factor authentication has been disabled."
fi