mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-06 21:24:10 +00:00
fix: repair clash subscription toggle and separate clash path settings
This commit is contained in:
parent
67bf6c1a9a
commit
d6de00cd00
6 changed files with 107 additions and 17 deletions
|
|
@ -0,0 +1,65 @@
|
|||
Task Record
|
||||
|
||||
Date: 2026-04-26
|
||||
Related Module: web settings / subscription assets / setting service
|
||||
Change Type: Fix
|
||||
|
||||
Background
|
||||
|
||||
The Clash subscription toggle in `/panel/settings` did not behave correctly in practice.
|
||||
The page was loading an outdated fingerprinted frontend model from `web/public` that did not include Clash subscription fields, which caused inconsistent binding and update behavior for `subClashEnable` and related properties.
|
||||
In addition, Clash subscription keys were not mapped in the settings grouping metadata, making their nested config representation inconsistent.
|
||||
|
||||
Changes
|
||||
|
||||
Regenerated fingerprinted frontend assets via `go run ./cmd/genassets` so the settings page now loads an updated `AllSetting` model containing:
|
||||
- `subClashEnable`
|
||||
- `subClashPath`
|
||||
- `subClashURI`
|
||||
|
||||
Updated settings group mappings in `web/service/setting.go`:
|
||||
- Added Clash keys to `subscriptionNetwork`:
|
||||
- `clashEnable -> subClashEnable`
|
||||
- `clashPath -> subClashPath`
|
||||
- `clashURI -> subClashURI`
|
||||
- Added corresponding Clash keys to legacy `sub` mapping for compatibility.
|
||||
|
||||
Impact
|
||||
|
||||
Affected modules or files.
|
||||
- `web/service/setting.go`
|
||||
- `web/public/assets-manifest.json`
|
||||
- `web/public/assets/js/model/setting.*.js` (fingerprinted replacement)
|
||||
- `web/public/assets/js/subscription.*.js` (fingerprinted replacement)
|
||||
- `web/public/assets/codemirror/yaml.*.js` (fingerprinted generated asset)
|
||||
|
||||
Whether APIs, database, config, build, or compatibility are affected.
|
||||
- API schema unchanged.
|
||||
- Database unchanged.
|
||||
- Settings file structure compatibility improved for Clash keys in nested/legacy mappings.
|
||||
- Frontend static asset fingerprints updated.
|
||||
|
||||
Whether upstream or downstream callers are affected.
|
||||
- Panel settings frontend now correctly tracks and submits Clash subscription toggle/path fields.
|
||||
- Subscription page uses refreshed asset bundle.
|
||||
|
||||
Verification
|
||||
|
||||
List validation commands or checks performed.
|
||||
- `go run ./cmd/genassets`
|
||||
- `go test -race ./web/service/...`
|
||||
|
||||
State the result.
|
||||
- Asset generation succeeded.
|
||||
- Related service tests passed.
|
||||
|
||||
If not verified, explain why.
|
||||
- No live runtime verification against a deployed panel/subscription server was performed in this local environment.
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
Remaining risks.
|
||||
- Existing browser caches may keep old fingerprint mappings until refresh; after deploy/restart, hard refresh may still be needed in some clients.
|
||||
|
||||
Recommended follow-up work.
|
||||
- Verify in a deployed environment that toggling `Clash Subscription` and editing `subClashPath` immediately reflects expected behavior after restart/reload cycle.
|
||||
|
|
@ -19,14 +19,15 @@
|
|||
"codemirror/lint/lint.css": "codemirror/lint/lint.5902b061.css",
|
||||
"codemirror/lint/lint.js": "codemirror/lint/lint.8d16a6b4.js",
|
||||
"codemirror/xq.min.css": "codemirror/xq.min.18b37ea8.css",
|
||||
"codemirror/yaml.js": "codemirror/yaml.7f87153b.js",
|
||||
"css/custom.min.css": "css/custom.min.7a7540cc.css",
|
||||
"js/axios-init.js": "js/axios-init.5d82a152.js",
|
||||
"js/model/dbinbound.js": "js/model/dbinbound.2232a7d6.js",
|
||||
"js/model/inbound.js": "js/model/inbound.afa36664.js",
|
||||
"js/model/outbound.js": "js/model/outbound.5b13ad17.js",
|
||||
"js/model/reality_targets.js": "js/model/reality_targets.6ca38c21.js",
|
||||
"js/model/setting.js": "js/model/setting.3c69ea22.js",
|
||||
"js/subscription.js": "js/subscription.d3d8665a.js",
|
||||
"js/model/setting.js": "js/model/setting.a37c1aec.js",
|
||||
"js/subscription.js": "js/subscription.84ade419.js",
|
||||
"js/util/index.js": "js/util/index.7ced4edf.js",
|
||||
"js/websocket.js": "js/websocket.938f634e.js",
|
||||
"moment/moment-jalali.min.js": "moment/moment-jalali.min.9d3db244.js",
|
||||
|
|
|
|||
1
web/public/assets/codemirror/yaml.7f87153b.js
Normal file
1
web/public/assets/codemirror/yaml.7f87153b.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var n=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(e,i){var t=e.peek(),r=i.escaped;if(i.escaped=!1,"#"==t&&(0==e.pos||/\s/.test(e.string.charAt(e.pos-1))))return e.skipToEnd(),"comment";if(e.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(i.literal&&e.indentation()>i.keyCol)return e.skipToEnd(),"string";if(i.literal&&(i.literal=!1),e.sol()){if(i.keyCol=0,i.pair=!1,i.pairStart=!1,e.match("---"))return"def";if(e.match("..."))return"def";if(e.match(/\s*-\s+/))return"meta"}if(e.match(/^(\{|\}|\[|\])/))return"{"==t?i.inlinePairs++:"}"==t?i.inlinePairs--:"["==t?i.inlineList++:i.inlineList--,"meta";if(0<i.inlineList&&!r&&","==t)return e.next(),"meta";if(0<i.inlinePairs&&!r&&","==t)return i.keyCol=0,i.pair=!1,i.pairStart=!1,e.next(),"meta";if(i.pairStart){if(e.match(/^\s*(\||\>)\s*/))return i.literal=!0,"meta";if(e.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==i.inlinePairs&&e.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(0<i.inlinePairs&&e.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(e.match(n))return"keyword"}return!i.pair&&e.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(i.pair=!0,i.keyCol=e.indentation(),"atom"):i.pair&&e.match(/^:\s*/)?(i.pairStart=!0,"meta"):(i.pairStart=!1,i.escaped="\\"==t,e.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")});
|
||||
|
|
@ -52,6 +52,10 @@ class AllSetting {
|
|||
this.subJsonNoises = "";
|
||||
this.subJsonMux = "";
|
||||
this.subJsonRules = "";
|
||||
this.subClashEnable = false;
|
||||
this.subClashPath = "/clash/";
|
||||
this.subClashURI = "";
|
||||
this.subClashTemplate = "";
|
||||
|
||||
this.timeLocation = "Local";
|
||||
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
sId: el.getAttribute('data-sid') || '',
|
||||
subUrl: el.getAttribute('data-sub-url') || '',
|
||||
subJsonUrl: el.getAttribute('data-subjson-url') || '',
|
||||
subClashUrl: el.getAttribute('data-subclash-url') || '',
|
||||
download: el.getAttribute('data-download') || '',
|
||||
upload: el.getAttribute('data-upload') || '',
|
||||
used: el.getAttribute('data-used') || '',
|
||||
|
|
@ -99,6 +100,8 @@
|
|||
const tpl = document.getElementById('subscription-data');
|
||||
const sj = tpl ? tpl.getAttribute('data-subjson-url') : '';
|
||||
if (sj) this.app.subJsonUrl = sj;
|
||||
const sc = tpl ? tpl.getAttribute('data-subclash-url') : '';
|
||||
if (sc) this.app.subClashUrl = sc;
|
||||
drawQR(this.app.subUrl);
|
||||
try {
|
||||
const elJson = document.getElementById('qrcode-subjson');
|
||||
|
|
@ -106,6 +109,12 @@
|
|||
new QRious({ element: elJson, value: this.app.subJsonUrl, size: 220 });
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
try {
|
||||
const elClash = document.getElementById('qrcode-subclash');
|
||||
if (elClash && this.app.subClashUrl) {
|
||||
new QRious({ element: elClash, value: this.app.subClashUrl, size: 220 });
|
||||
}
|
||||
} catch (e) { /* ignore */ }
|
||||
this._onResize = () => { this.viewportWidth = window.innerWidth; };
|
||||
window.addEventListener('resize', this._onResize);
|
||||
},
|
||||
|
|
@ -145,6 +154,10 @@
|
|||
},
|
||||
happUrl() {
|
||||
return `happ://add/${this.app.subUrl}`;
|
||||
},
|
||||
clashvergeUrl() {
|
||||
const url = this.app.subClashUrl || this.app.subUrl;
|
||||
return `clash-verge://install-config?url=${encodeURIComponent(url)}&name=${encodeURIComponent(this.app.sId)}`;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -171,20 +171,23 @@ var settingGroups = map[string]map[string]string{
|
|||
"lang": "tgLang",
|
||||
},
|
||||
"subscriptionNetwork": {
|
||||
"enable": "subEnable",
|
||||
"jsonEnable": "subJsonEnable",
|
||||
"listen": "subListen",
|
||||
"port": "subPort",
|
||||
"path": "subPath",
|
||||
"domain": "subDomain",
|
||||
"certFile": "subCertFile",
|
||||
"keyFile": "subKeyFile",
|
||||
"updates": "subUpdates",
|
||||
"encrypt": "subEncrypt",
|
||||
"showInfo": "subShowInfo",
|
||||
"uri": "subURI",
|
||||
"jsonPath": "subJsonPath",
|
||||
"jsonURI": "subJsonURI",
|
||||
"enable": "subEnable",
|
||||
"jsonEnable": "subJsonEnable",
|
||||
"clashEnable": "subClashEnable",
|
||||
"listen": "subListen",
|
||||
"port": "subPort",
|
||||
"path": "subPath",
|
||||
"jsonPath": "subJsonPath",
|
||||
"clashPath": "subClashPath",
|
||||
"domain": "subDomain",
|
||||
"certFile": "subCertFile",
|
||||
"keyFile": "subKeyFile",
|
||||
"updates": "subUpdates",
|
||||
"encrypt": "subEncrypt",
|
||||
"showInfo": "subShowInfo",
|
||||
"uri": "subURI",
|
||||
"jsonURI": "subJsonURI",
|
||||
"clashURI": "subClashURI",
|
||||
},
|
||||
"subscriptionBranding": {
|
||||
"title": "subTitle",
|
||||
|
|
@ -271,6 +274,7 @@ var legacySettingGroups = map[string]map[string]string{
|
|||
"sub": {
|
||||
"enable": "subEnable",
|
||||
"jsonEnable": "subJsonEnable",
|
||||
"clashEnable": "subClashEnable",
|
||||
"title": "subTitle",
|
||||
"supportUrl": "subSupportUrl",
|
||||
"profileUrl": "subProfileUrl",
|
||||
|
|
@ -280,6 +284,8 @@ var legacySettingGroups = map[string]map[string]string{
|
|||
"listen": "subListen",
|
||||
"port": "subPort",
|
||||
"path": "subPath",
|
||||
"jsonPath": "subJsonPath",
|
||||
"clashPath": "subClashPath",
|
||||
"domain": "subDomain",
|
||||
"certFile": "subCertFile",
|
||||
"keyFile": "subKeyFile",
|
||||
|
|
@ -287,8 +293,8 @@ var legacySettingGroups = map[string]map[string]string{
|
|||
"encrypt": "subEncrypt",
|
||||
"showInfo": "subShowInfo",
|
||||
"uri": "subURI",
|
||||
"jsonPath": "subJsonPath",
|
||||
"jsonURI": "subJsonURI",
|
||||
"clashURI": "subClashURI",
|
||||
"jsonFragment": "subJsonFragment",
|
||||
"jsonNoises": "subJsonNoises",
|
||||
"jsonMux": "subJsonMux",
|
||||
|
|
|
|||
Loading…
Reference in a new issue