diff --git a/doc/lucky1.png b/doc/lucky1.png new file mode 100644 index 00000000..a5b41b6e Binary files /dev/null and b/doc/lucky1.png differ diff --git a/doc/lucky2.png b/doc/lucky2.png new file mode 100644 index 00000000..ba4c026f Binary files /dev/null and b/doc/lucky2.png differ diff --git a/doc/lucky3.png b/doc/lucky3.png new file mode 100644 index 00000000..6fa7982f Binary files /dev/null and b/doc/lucky3.png differ diff --git a/doc/taskplan1.png b/doc/taskplan1.png deleted file mode 100644 index 1f8db7be..00000000 Binary files a/doc/taskplan1.png and /dev/null differ diff --git a/doc/taskplan2.png b/doc/taskplan2.png deleted file mode 100644 index edb45d6d..00000000 Binary files a/doc/taskplan2.png and /dev/null differ diff --git a/doc/taskplan3.png b/doc/taskplan3.png deleted file mode 100644 index d4794702..00000000 Binary files a/doc/taskplan3.png and /dev/null differ diff --git a/doc/view.png b/doc/view.png deleted file mode 100644 index 169e112f..00000000 Binary files a/doc/view.png and /dev/null differ diff --git a/doc/view2.png b/doc/view2.png deleted file mode 100644 index 9058c632..00000000 Binary files a/doc/view2.png and /dev/null differ diff --git a/luci-app-passwall/htdocs/luci-static/resources/view/passwall/cbi.js b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/cbi.js new file mode 100644 index 00000000..3f9d6470 --- /dev/null +++ b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/cbi.js @@ -0,0 +1,38 @@ +function is_json(str) { + try { + const result = JSON.parse(str); + return typeof result === 'object' && result !== null; + } catch (e) { + return false; + } +} + +function is_timehhmm(str) { + const match = String(str).match(/^(\d?\d):(\d\d)$/); + if (match) { + const hour = parseInt(match[1], 10); + const minute = parseInt(match[2], 10); + if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59) { + return true; + } + } + return false; +} + +if (typeof cbi_validators !== 'undefined' && cbi_validators !== null) { + cbi_validators['json'] = function() { + return is_json(this); + } + cbi_validators['timehhmm'] = function() { + return is_timehhmm(this); + } +} else { + L.require('validation').then(function(validation) { + validation.types['json'] = function() { + return this.assert(is_json(this.value), _('Must be JSON text!')); + } + validation.types['timehhmm'] = function() { + return this.assert(is_timehhmm(this.value), _('valid time (hh:mm)')); + } + }); +} diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua index 9d5edc7e..860f9106 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local appname = "passwall" local sys = api.sys +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -101,4 +103,4 @@ o:value("1:65535", translate("All")) o:value("53", "53") ]]-- -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua index d908e37d..4dec1580 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua @@ -1,6 +1,8 @@ local api = require "luci.passwall.api" local appname = "passwall" +api.set_default_cbi() + m = Map(appname) m.redirect = api.url("acl") api.set_apply_on_parse(m) @@ -601,4 +603,4 @@ for k, v in pairs(nodes_table) do end end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua index 5f573a9e..3f2a7760 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local com = require "luci.passwall.com" local appname = "passwall" +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -34,4 +36,4 @@ o.cfgvalue = function(t, n) return string.format('%s', translate("if you want to run from memory, change the path, /tmp beginning then save the application and update it manually.")) end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua index ebbf3395..7a012136 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -8,6 +8,8 @@ local has_gfwlist = fs.access("/usr/share/passwall/rules/gfwlist") local has_chnlist = fs.access("/usr/share/passwall/rules/chnlist") local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute") +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -839,4 +841,4 @@ footer.global_cfgid = global_cfgid footer.shunt_list = api.jsonc.stringify(shunt_list) m:append(footer) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua index 972a96a7..abff0091 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua @@ -15,6 +15,8 @@ for k, e in ipairs(api.get_valid_nodes()) do end end +api.set_default_cbi() + m = Map(appname, "HAPROXY " .. translate("Load Balancing")) api.set_apply_on_parse(m) @@ -179,4 +181,4 @@ o.rmempty = false m:append(Template(appname .. "/haproxy/js")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua index 9cbb3a9e..1f8ba7af 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -1,6 +1,8 @@ api = require "luci.passwall.api" appname = "passwall" +api.set_default_cbi() + m = Map(appname, translate("Node Config")) m.redirect = api.url("node_list") api.set_apply_on_parse(m) @@ -120,7 +122,6 @@ local footer = Template(appname .. "/node_config/footer") footer.api = api footer.config = m.config footer.section = arg[1] - m:append(footer) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua index 3bdf8fcc..8c16f598 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -3,6 +3,8 @@ local appname = "passwall" local sys = api.sys local datatypes = api.datatypes +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -33,4 +35,4 @@ s:append(Template(appname .. "/node_list/link_add_node")) m:append(Template(appname .. "/node_list/node_list")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua index 481477aa..326b2df0 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -38,6 +38,8 @@ if has_hysteria2 then table.insert(hysteria2_type, s) end +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -225,4 +227,4 @@ end m:append(Template(appname .. "/node_subscribe/js")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua index e3d2c44c..98e52f7e 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local uci = api.uci local appname = "passwall" +api.set_default_cbi() + m = Map(appname) m.redirect = api.url("node_subscribe") api.set_apply_on_parse(m) @@ -244,13 +246,7 @@ o:value(0, translate("Every Sunday")) o = s:option(Value, "update_time_mode", translate("Update Time")) for t = 0, 23 do o:value(t .. ":00") end o.default = "0:00" -o.validate = function(self, value) - local b = api.is_timehhmm(value) - if b then - return value - end - return nil -end +o.datatype = "timehhmm" o:depends("update_week_mode", "0") o:depends("update_week_mode", "1") o:depends("update_week_mode", "2") @@ -321,4 +317,4 @@ for k, v in pairs(nodes_table) do end end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua index 2f53c6ae..efe0cccc 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua @@ -8,6 +8,8 @@ local port_validate = function(self, value, t) return value:gsub("-", ":") end +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -43,13 +45,7 @@ for index, value in ipairs({"stop", "start", "restart"}) do o = s:option(Value, value .. "_time_mode", translate(value .. " Time")) for t = 0, 23 do o:value(t .. ":00") end o.default = "0:00" - o.validate = function(self, value) - local b = api.is_timehhmm(value) - if b then - return value - end - return nil - end + o.datatype = "timehhmm" o:depends(value .. "_week_mode", "0") o:depends(value .. "_week_mode", "1") o:depends(value .. "_week_mode", "2") @@ -271,4 +267,4 @@ if has_singbox then o.default = 0 end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua index c6e12ed8..8ad9e7e1 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua @@ -3,6 +3,8 @@ local appname = "passwall" local has_xray = api.finded_com("xray") local has_singbox = api.finded_com("sing-box") +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -112,13 +114,7 @@ o:value(0, translate("Every Sunday")) o = s:option(Value, "update_time_mode", translate("Update Time")) for t = 0, 23 do o:value(t .. ":00") end o.default = "0:00" -o.validate = function(self, value) - local b = api.is_timehhmm(value) - if b then - return value - end - return nil -end +o.datatype = "timehhmm" o:depends("update_week_mode", "0") o:depends("update_week_mode", "1") o:depends("update_week_mode", "2") @@ -169,4 +165,4 @@ if has_xray or has_singbox then o = s:option(DummyValue, "remarks", translate("Remarks")) end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua index 6ad3f058..030874b3 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua @@ -1,5 +1,5 @@ local api = require "luci.passwall.api" -local appname = "passwall" +local appname = api.appname local fs = api.fs local sys = api.sys local uci = api.uci diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua index 85596c9b..4b45eba4 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local appname = "passwall" local datatypes = api.datatypes +api.set_default_cbi() + m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule")) m.redirect = api.url("rule") api.set_apply_on_parse(m) @@ -245,4 +247,4 @@ ip_list.description = "