mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-09-13 20:04:23 +08:00
192 lines
5.8 KiB
HTML
192 lines
5.8 KiB
HTML
<%
|
||
local api = require "luci.passwall.api"
|
||
local fs = api.fs
|
||
local has_old_geoip = fs.access("/tmp/bak_v2ray/geoip.dat")
|
||
local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat")
|
||
-%>
|
||
|
||
<style>
|
||
div.cbi-value[id$="-gfwlist_update"],
|
||
div.cbi-value[id$="-chnroute_update"],
|
||
div.cbi-value[id$="-chnroute6_update"],
|
||
div.cbi-value[id$="-chnlist_update"],
|
||
div.cbi-value[id$="-geoip_update"],
|
||
div.cbi-value[id$="-geosite_update"] {
|
||
display: none !important;
|
||
}
|
||
</style>
|
||
|
||
<div class="cbi-value" id="_rule_div">
|
||
<label class="cbi-value-title">
|
||
<%:Update Options%>
|
||
</label>
|
||
<div class="cbi-value-field">
|
||
<div>
|
||
<label>
|
||
<input class="cbi-input-checkbox" type="checkbox" name="gfwlist" value="1" />
|
||
gfwlist
|
||
</label>
|
||
<label>
|
||
<input class="cbi-input-checkbox" type="checkbox" name="chnroute" value="1" />
|
||
chnroute
|
||
</label>
|
||
<label>
|
||
<input class="cbi-input-checkbox" type="checkbox" name="chnroute6" value="1" />
|
||
chnroute6
|
||
</label>
|
||
<label>
|
||
<input class="cbi-input-checkbox" type="checkbox" name="chnlist" value="1" />
|
||
chnlist
|
||
</label>
|
||
<label>
|
||
<input class="cbi-input-checkbox" type="checkbox" name="geoip" value="1" />
|
||
geoip
|
||
</label>
|
||
<label>
|
||
<input class="cbi-input-checkbox" type="checkbox" name="geosite" value="1" />
|
||
geosite
|
||
</label>
|
||
<br><br>
|
||
<input class="btn cbi-button cbi-button-apply" type="button" id="update_rules_btn" onclick="update_rules(this)" value="<%:Manually update%>" />
|
||
<% if has_old_geoip then %>
|
||
<input class="btn cbi-button cbi-button-reset" type="button" onclick="rollback_rules(this, 'geoip')" value="<%:Rollback%> GeoIP" />
|
||
<% end %>
|
||
<% if has_old_geosite then %>
|
||
<input class="btn cbi-button cbi-button-reset" type="button" onclick="rollback_rules(this, 'geosite')" value="<%:Rollback%> Geosite" />
|
||
<% end %>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
//<![CDATA[
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
const flags = [
|
||
"gfwlist_update","chnroute_update","chnroute6_update",
|
||
"chnlist_update","geoip_update","geosite_update"
|
||
];
|
||
const bindFlags = () => {
|
||
let allBound = true;
|
||
flags.forEach(flag => {
|
||
const orig = Array.from(document.querySelectorAll(`input[name$=".${flag}"]`)).find(i => i.type === 'checkbox');
|
||
if (!orig) { allBound = false; return; }
|
||
// 隐藏最外层 div
|
||
const wrapper = orig.closest('.cbi-value');
|
||
if (wrapper && wrapper.style.display !== 'none') {
|
||
wrapper.style.display = 'none';
|
||
}
|
||
const custom = document.querySelector(`.cbi-input-checkbox[name="${flag.replace('_update','')}"]`);
|
||
if (!custom) { allBound = false; return; }
|
||
custom.checked = orig.checked;
|
||
// 自定义选择框与原生Flag双向绑定
|
||
if (!custom._binded) {
|
||
custom._binded = true;
|
||
orig.addEventListener('change', () => {
|
||
custom.checked = orig.checked;
|
||
});
|
||
custom.addEventListener('change', () => {
|
||
orig.checked = custom.checked;
|
||
orig.dispatchEvent(new Event('change', { bubbles: true }));
|
||
});
|
||
}
|
||
});
|
||
return allBound;
|
||
};
|
||
|
||
const geo2ruleFlag = () => {
|
||
const geoEl = document.querySelector('input[type="checkbox"][name*="passwall"][name*="geo2rule"]');
|
||
if (!geoEl) return;
|
||
const updateCheckboxes = (disabled) => {
|
||
flags.filter(flag => !flag.includes('geo')).forEach(flag => {
|
||
const custom = document.querySelector(`.cbi-input-checkbox[name="${flag.replace('_update','')}"]`);
|
||
if (custom) {
|
||
//if (disabled) custom.checked = true;
|
||
custom.parentElement.style.display = disabled ? 'none' : '';
|
||
}
|
||
});
|
||
};
|
||
updateCheckboxes(geoEl.checked);
|
||
geoEl.addEventListener("change", () => {
|
||
geoEl.blur();
|
||
updateCheckboxes(geoEl.checked);
|
||
});
|
||
};
|
||
|
||
const bindAll = () => {
|
||
bindFlags();
|
||
geo2ruleFlag();
|
||
};
|
||
|
||
const target = document.querySelector('form') || document.body;
|
||
const observer = new MutationObserver(() => bindAll() ? observer.disconnect() : 0);
|
||
observer.observe(target, { childList: true, subtree: true });
|
||
const timer = setInterval(() => bindAll() ? (clearInterval(timer), observer.disconnect()) : 0, 300);
|
||
setTimeout(() => { clearInterval(timer); observer.disconnect(); }, 5000);
|
||
});
|
||
|
||
function update_rules(btn) {
|
||
btn.disabled = true;
|
||
btn.value = '<%:Updating...%>';
|
||
var div = document.getElementById('_rule_div');
|
||
var domList = div.getElementsByTagName('input');
|
||
var checkBoxList = [];
|
||
var len = domList.length;
|
||
while(len--) {
|
||
var dom = domList[len];
|
||
if(dom.type == 'checkbox' && dom.checked) {
|
||
checkBoxList.push(dom.name);
|
||
}
|
||
}
|
||
XHR.get('<%=api.url("update_rules")%>', {
|
||
update: checkBoxList.join(",")
|
||
},
|
||
function(x, data) {
|
||
if(x && x.status == 200) {
|
||
window.location.href = '<%=api.url("log")%>';
|
||
} else {
|
||
alert("<%:Error%>");
|
||
btn.disabled = false;
|
||
btn.value = '<%:Manually update%>';
|
||
}
|
||
}
|
||
);
|
||
}
|
||
|
||
function rollback_rules(btn, type) {
|
||
let ori_val = btn.value;
|
||
btn.disabled = true;
|
||
btn.value = '<%:Rollbacking...%>';
|
||
var div = document.getElementById('_rule_div');
|
||
var domList = div.getElementsByTagName('input');
|
||
var checkBoxList = [];
|
||
var len = domList.length;
|
||
while(len--) {
|
||
var dom = domList[len];
|
||
if(dom.type == 'checkbox' && dom.checked) {
|
||
if(type == 'geoip' && (dom.name === 'chnroute' || dom.name === 'chnroute6')) {
|
||
checkBoxList.push(dom.name);
|
||
}
|
||
if(type == 'geosite' && (dom.name === 'gfwlist' || dom.name === 'chnlist')) {
|
||
checkBoxList.push(dom.name);
|
||
}
|
||
}
|
||
}
|
||
XHR.get('<%=api.url("rollback_rules")%>', {
|
||
type: type,
|
||
rules: checkBoxList.join(",")
|
||
},
|
||
function(x, data) {
|
||
if(x && x.status == 200 && data.code == 1) {
|
||
alert("<%:Success%>");
|
||
btn.style.display = "none";
|
||
} else {
|
||
alert("<%:Error%>");
|
||
btn.disabled = false;
|
||
btn.value = ori_val;
|
||
}
|
||
}
|
||
);
|
||
}
|
||
//]]>
|
||
</script>
|