From f21ed9229695ed1cbcc86d65b52d98cfc9116f5a Mon Sep 17 00:00:00 2001 From: "Farhad H. P. Shirvan" <9374298+farhadh@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:46:55 +0200 Subject: feat: add panel update functionality via web GUI (#4117) * feat: add panel update functionality via web GUI * feat: enhance panel update notifications in web GUI * feat: implement panel update modal and enhance translation strings * fix design --- web/html/index.html | 113 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 10 deletions(-) (limited to 'web/html') diff --git a/web/html/index.html b/web/html/index.html index 0a36b9cb..62e9453b 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -139,7 +139,7 @@ {{ i18n "pages.index.restartXray" }} - + [[ status.xray.version != 'Unknown' ? `v${status.xray.version}` : '{{ i18n @@ -169,6 +169,14 @@ + v{{ .cur_ver }} @@ -317,9 +325,36 @@ - + + + + {{ i18n "pages.index.currentPanelVersion" }} + v[[ panelUpdateModal.info.currentVersion || '{{ .cur_ver }}' ]] + + + {{ i18n "pages.index.latestPanelVersion" }} + + [[ panelUpdateModal.info.latestVersion || '-' ]] + + + + {{ i18n "pages.index.panelUpToDate" }} + {{ i18n "pages.index.upToDate" }} + + +
+ + {{ i18n "pages.index.updatePanel" }} + +
+
+ - + @@ -799,9 +834,11 @@ const versionModal = { visible: false, + activeKey: '1', versions: [], - show(versions) { + show(versions, activeKey = '1') { this.visible = true; + this.activeKey = activeKey; this.versions = versions; }, hide() { @@ -809,6 +846,24 @@ }, }; + const panelUpdateModal = { + visible: false, + info: { + currentVersion: '{{ .cur_ver }}', + latestVersion: '', + updateAvailable: false, + }, + show(info) { + this.visible = true; + if (info) { + this.info = info; + } + }, + hide() { + this.visible = false; + }, + }; + const logModal = { visible: false, logs: [], @@ -958,11 +1013,12 @@ spinning: false }, status: new Status(), - cpuHistory: [], // small live widget history - cpuHistoryLong: [], // aggregated points from backend - cpuHistoryLabels: [], - cpuHistoryModal: { visible: false, bucket: 2 }, + cpuHistory: [], // small live widget history + cpuHistoryLong: [], // aggregated points from backend + cpuHistoryLabels: [], + cpuHistoryModal: { visible: false, bucket: 2 }, versionModal, + panelUpdateModal, logModal, xraylogModal, backupModal, @@ -1049,16 +1105,25 @@ console.error('Failed to fetch bucketed cpu history', e) } }, - async openSelectV2rayVersion() { + async openSelectV2rayVersion(activeKey = '1') { this.loading(true); const msg = await HttpUtil.get('/panel/api/server/getXrayVersion'); this.loading(false); if (!msg.success) { return; } - versionModal.show(msg.obj); + versionModal.show(msg.obj, activeKey); this.loadCustomGeo(); }, + async openPanelUpdate() { + this.loading(true); + const msg = await HttpUtil.get('/panel/api/server/getPanelUpdateInfo'); + this.loading(false); + if (!msg.success) { + return; + } + panelUpdateModal.show(msg.obj); + }, customGeoFormatTime(ts) { if (!ts) return ''; return typeof moment !== 'undefined' ? moment(ts * 1000).format('YYYY-MM-DD HH:mm') : String(ts); @@ -1195,6 +1260,27 @@ }, }); }, + updatePanel() { + this.$confirm({ + title: '{{ i18n "pages.index.panelUpdateDialog" }}', + content: '{{ i18n "pages.index.panelUpdateDialogDesc" }}' + .replace('#version#', panelUpdateModal.info.latestVersion || ''), + okText: '{{ i18n "confirm"}}', + class: themeSwitcher.currentTheme, + cancelText: '{{ i18n "cancel"}}', + onOk: async () => { + panelUpdateModal.hide(); + this.loading(true, '{{ i18n "pages.index.dontRefresh"}}'); + const msg = await HttpUtil.post('/panel/api/server/updatePanel'); + if (!msg.success) { + this.loading(false); + return; + } + await PromiseUtil.sleep(15000); + window.location.reload(); + }, + }); + }, updateGeofile(fileName) { const isSingleFile = !!fileName; this.$confirm({ @@ -1346,6 +1432,13 @@ // Initial status fetch await this.getStatus(); + // Silently check for panel updates so the indicator shows on load + HttpUtil.get('/panel/api/server/getPanelUpdateInfo').then(msg => { + if (msg && msg.success && msg.obj) { + panelUpdateModal.info = msg.obj; + } + }); + // Setup WebSocket for real-time updates if (window.wsClient) { window.wsClient.connect(); -- cgit v1.2.3