From 045d307bfe30191d6426de09bdf3d6f4bea87083 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 28 Aug 2026 19:05:48 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=81=20Sync=202026-08-28=2019:05:48?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- luci-app-jellyfin/Makefile | 4 +- .../root/usr/libexec/istorec/jellyfin.sh | 2 +- luci-app-passwall/Makefile | 2 +- .../luasrc/passwall/util_sing-box.lua | 2 +- luci-app-passwall2/Makefile | 2 +- luci-app-passwall2/po/zh-cn/passwall2.po | 4 +- .../root/usr/share/passwall2/iptables.sh | 15 +++-- .../root/usr/share/passwall2/nftables.sh | 15 +++-- luci-lib-taskd/Makefile | 4 +- luci-lib-taskd/src/po/zh-cn/lib-tasks.po | 3 + luci-theme-footstrap/Makefile | 2 +- .../luci-static/resources/fs-appearance.js | 56 ++++++++++--------- .../luci-static/resources/fs-overview.js | 16 ++++-- my-default-settings/Makefile | 2 +- .../luci/view/admin_status/index/links.htm | 2 +- 15 files changed, 79 insertions(+), 52 deletions(-) diff --git a/luci-app-jellyfin/Makefile b/luci-app-jellyfin/Makefile index b5f2d54e..e5fc7d13 100644 --- a/luci-app-jellyfin/Makefile +++ b/luci-app-jellyfin/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk -PKG_VERSION:=1.2.2-r20260804 -PKG_RELEASE:=5 +PKG_VERSION:=1.2.3-r20260828 +PKG_RELEASE:=6 LUCI_TITLE:=LuCI support for jellyfin LUCI_PKGARCH:=all diff --git a/luci-app-jellyfin/root/usr/libexec/istorec/jellyfin.sh b/luci-app-jellyfin/root/usr/libexec/istorec/jellyfin.sh index 13e861c6..2f97fc22 100755 --- a/luci-app-jellyfin/root/usr/libexec/istorec/jellyfin.sh +++ b/luci-app-jellyfin/root/usr/libexec/istorec/jellyfin.sh @@ -130,7 +130,7 @@ do_install_detail() { local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`" [ -z "$tz" ] || cmd="$cmd -e TZ=$tz" - [ -z "$cache" ] || cmd="$cmd -v \"$cache:/config/transcodes\"" + [ -z "$cache" ] || cmd="$cmd -v \"$cache:/config/transcodes\" -v \"$cache:/cache/transcodes\"" [ -z "$media" ] || cmd="$cmd -v \"$media:/media\"" cmd="$cmd -v /mnt:/mnt" diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index dad0a0bf..98ca9bf8 100644 --- a/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall PKG_VERSION:=26.8.26 -PKG_RELEASE:=249 +PKG_RELEASE:=250 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua index 419cfce5..1630bb19 100644 --- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua +++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -2098,7 +2098,7 @@ function gen_config(var) query_type = dns_rule_query_type, server = fakedns_tag, disable_cache = true, - rewrite_ttl = tonumber(remote_rewrite_ttl) + rewrite_ttl = 30 } table.insert(dns.rules, fakedns_dns_rule) end diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index ee1925e7..29f2e2c2 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 PKG_VERSION:=26.8.27 -PKG_RELEASE:=103 +PKG_RELEASE:=104 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po index e4364329..3bbcecf9 100644 --- a/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/luci-app-passwall2/po/zh-cn/passwall2.po @@ -2098,10 +2098,10 @@ msgid "Access Control:" msgstr "访问控制:" msgid "Add node to the load balancer is directly connected to %s[%s]." -msgstr "加入负载均衡的节点到%s[%s]直连完成。" +msgstr "加入负载均衡节点IP到%s[%s]直连豁免(防回环)完成。" msgid "Add all %s nodes to %s[%s] direct connection complete." -msgstr "加入所有%s节点到%s[%s]直连完成。" +msgstr "加入所有%s节点服务器IP到%s[%s]直连豁免(防回环)完成。" msgid "Starting to load %s firewall rules..." msgstr "开始加载 %s 防火墙规则..." diff --git a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh index 35cbd793..639f0206 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh @@ -557,6 +557,7 @@ load_acl() { } filter_haproxy() { + [ "$(config_n_get @global_haproxy[0] balancing_enable 0)" != "1" ] && return for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1) [ -n "$ip" ] && ipset -q add $IPSET_VPS $ip @@ -565,10 +566,16 @@ filter_haproxy() { } filter_vpsip() { - uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "ipset" "${$IPSET_VPS}")" - uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "ipset" "${$IPSET_VPS6}")" + local ipv4_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$") + [ -n "$ipv4_addrs" ] && { + echo "$ipv4_addrs" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "ipset" "${IPSET_VPS}")" + } + local ipv6_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + [ -n "$ipv6_addrs" ] && { + echo "$ipv6_addrs" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "ipset" "${IPSET_VPS6}")" + } } filter_server_port() { diff --git a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh index 7fd65246..bbbd013a 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh @@ -585,6 +585,7 @@ load_acl() { } filter_haproxy() { + [ "$(config_n_get @global_haproxy[0] balancing_enable 0)" != "1" ] && return for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1 done | insert_nftset $NFTSET_VPS "-1" @@ -602,10 +603,16 @@ filter_vps_addr() { } filter_vpsip() { - uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | insert_nftset $NFTSET_VPS "-1" - #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "nftset" "${$NFTSET_VPS}")" - uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_VPS6 "-1" - #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "nftset" "${$NFTSET_VPS6}")" + local ipv4_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$") + [ -n "$ipv4_addrs" ] && { + echo "$ipv4_addrs" | insert_nftset $NFTSET_VPS "-1" + log_i18n 1 "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "nftset" "${NFTSET_VPS}" + } + local ipv6_addrs=$(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + [ -n "$ipv6_addrs" ] && { + echo "$ipv6_addrs" | insert_nftset $NFTSET_VPS6 "-1" + log_i18n 1 "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "nftset" "${NFTSET_VPS6}" + } } filter_server_port() { diff --git a/luci-lib-taskd/Makefile b/luci-lib-taskd/Makefile index 89ebb548..0832c8c9 100644 --- a/luci-lib-taskd/Makefile +++ b/luci-lib-taskd/Makefile @@ -11,8 +11,8 @@ LUCI_DEPENDS:=+luci-lib-xterm +taskd LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3) LUCI_PKGARCH:=all -PKG_VERSION:=1.0.25 -PKG_RELEASE:=1 +PKG_VERSION:=1.0.26 +PKG_RELEASE:=2 PKG_MAINTAINER:=jjm2473 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-lib-taskd/src/po/zh-cn/lib-tasks.po b/luci-lib-taskd/src/po/zh-cn/lib-tasks.po index 895ccd6b..f9564729 100644 --- a/luci-lib-taskd/src/po/zh-cn/lib-tasks.po +++ b/luci-lib-taskd/src/po/zh-cn/lib-tasks.po @@ -48,3 +48,6 @@ msgstr "任务执行失败!" msgid "Click the button in the upper right corner of the dialog box to close it, or click here to view the log" msgstr "点击对话框右上角按钮关闭,或者点此查看日志" + +msgid "Upgrade" +msgstr "升级" diff --git a/luci-theme-footstrap/Makefile b/luci-theme-footstrap/Makefile index 498ca941..3d957f7b 100644 --- a/luci-theme-footstrap/Makefile +++ b/luci-theme-footstrap/Makefile @@ -17,7 +17,7 @@ LUCI_NAME:=luci-theme-footstrap FOOTSTRAP_VERSION?= ifneq ($(FOOTSTRAP_VERSION),) PKG_VERSION:=$(FOOTSTRAP_VERSION) -PKG_RELEASE:=39 +PKG_RELEASE:=40 endif LUCI_TITLE:=Footstrap Theme diff --git a/luci-theme-footstrap/htdocs/luci-static/resources/fs-appearance.js b/luci-theme-footstrap/htdocs/luci-static/resources/fs-appearance.js index f2a97c57..606e63ee 100644 --- a/luci-theme-footstrap/htdocs/luci-static/resources/fs-appearance.js +++ b/luci-theme-footstrap/htdocs/luci-static/resources/fs-appearance.js @@ -774,14 +774,14 @@ const MARK = 'fs-ap'; /* the built form's class, and how mount() knows it is alr const TAB_DEADLINE = 5000; const TAB = 'fs-appearance'; /* the pane's data-tab, which ui.tabs' click handler matches on */ -let _routeObserver = null, _viewObserver = null, _observedView = null, _building = false; +let _routeObserver = null, _viewObserver = null, _observedRoot = null, _building = false; function onPage() { return (document.body.getAttribute('data-page') || '') === PAGE; } function stopWatch() { if (_viewObserver) _viewObserver.disconnect(); _viewObserver = null; - _observedView = null; + _observedRoot = null; } /* The stock tab GROUP: the element whose children are the panes, which ui.tabs marks @@ -831,24 +831,20 @@ function tabGroup(view) { * * A map redraw (Save without Apply) rebuilds the group and `ui.tabs` stamps `data-initialized` as * an attribute change that can land after the last childList change, so the observer watches that - * attribute too and a miss schedules retries on a widening delay — otherwise the tab is missing - * until the next navigation (openwrt/luci#8903). */ -const RETRIES = [ 0, 60, 150, 300, 600, 1200 ]; -let _retryTimer = 0, _retryAt = 0; -function retryMount() { - if (_retryTimer) return; - if (_retryAt >= RETRIES.length) return; - const delay = RETRIES[_retryAt++]; - _retryTimer = window.setTimeout(() => { _retryTimer = 0; mount(); }, delay); -} - + * attribute too — otherwise the tab is missing until the next navigation (openwrt/luci#8903). + * + * A ladder of retries on a widening delay shipped beside that watch and is gone: instrumented over + * ten sessions on both package managers — a full load, an SPA return, a Save and a Save & Apply — + * it mounted the tab zero times, only ever arming a timer that woke to find the work done. The + * deadline below could once be seen mounting it, but only because watch() was binding the observer + * to a node the router was about to replace; with that fixed the deadline is a diagnostic again. */ function mount() { const view = document.getElementById('view'); if (!view || !onPage()) return; - if (view.querySelector('.' + MARK)) { _retryAt = 0; return; } + if (view.querySelector('.' + MARK)) return; if (_building) return; const tabs = tabGroup(view); - if (!tabs) { retryMount(); return; } + if (!tabs) return; /* not built yet; the observer calls again when it is */ _building = true; render() .then((form) => { @@ -882,13 +878,23 @@ function mount() { function watch() { const view = document.getElementById('view'); - if (_viewObserver && _observedView !== view) stopWatch(); + /* The CONTAINER, by id — not `#view`, which is not the same element for long. A client + * navigation builds a fresh one before it is in the document and swaps it in afterwards, while + * watch() runs on the `data-page` stamp, which comes first: the node bound here then reported + * `isConnected: false` while `#view` and `#maincontent` were both alive, and a Save's redraw + * produced four mutation batches that reached no callback at all. `#maincontent` outlives every + * swap, so the swap is itself a childList record. Save put the tab back in 250 ms after this, + * against 1,750-2,250 ms of waiting for the deadline before it. */ + const root = document.getElementById('maincontent') || view; + if (_viewObserver && _observedRoot !== root) stopWatch(); if (_viewObserver || !view || !onPage()) return; - _observedView = view; + _observedRoot = root; _viewObserver = new MutationObserver(mount); - /* `data-initialized` is the moment the group becomes usable, and it does not always come with - * a childList change (see retryMount above) */ - _viewObserver.observe(view, { + /* `data-initialized` is when the group becomes usable, and the filter is load-bearing — proven + * by staging openwrt/luci#8903 rather than waiting for it: tear the tab, the pane and the + * attribute down in one task, restore the attribute ALONE 1,200 ms later, and the tab is back + * 4 ms after it. Without the filter it never comes back. No ordinary Save separates the two. */ + _viewObserver.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: [ 'data-initialized' ], }); @@ -900,13 +906,11 @@ function watch() { * early on every mutation: the stock page renders, nothing throws, and every Appearance axis * is unreachable. */ window.setTimeout(() => { + /* It asks, it does not repair: with the observer on a node that survives a navigation the + * repair this used to attempt became unreachable, and the whole matrix passes without it. + * A group still found here means the observer is working, so there is nothing to report. */ const v = document.getElementById('view'); - if (!onPage() || !v || v.querySelector('.' + MARK) || _building) return; - /* one last attempt: the complaint below claims ui.tabs changed shape, which is only true - * if a fresh look still finds no group */ - _retryAt = 0; - mount(); - if (v.querySelector('.' + MARK) || _building || tabGroup(v)) return; + if (!onPage() || !v || v.querySelector('.' + MARK) || _building || tabGroup(v)) return; console.error('footstrap: the Appearance tab could not be attached — this page has tabs, but ' + 'ui.tabs no longer marks them the way fs-appearance.js looks for. Every Appearance axis ' + 'is unreachable until that is updated.'); diff --git a/luci-theme-footstrap/htdocs/luci-static/resources/fs-overview.js b/luci-theme-footstrap/htdocs/luci-static/resources/fs-overview.js index 2982ef8d..4f6b0cf4 100644 --- a/luci-theme-footstrap/htdocs/luci-static/resources/fs-overview.js +++ b/luci-theme-footstrap/htdocs/luci-static/resources/fs-overview.js @@ -104,16 +104,22 @@ function arrange() { * coalesced and one observer per #view node. The SPA router may replace #view between visits, so * re-attach when the observed node is no longer the current one — a singleton bound to the first * #view would watch a detached tree and the grid would never apply again. */ -let _observer = null, _observedView = null, _routeObserver = null; +let _observer = null, _observedRoot = null, _routeObserver = null; function stopWatch() { if (_observer) _observer.disconnect(); _observer = null; - _observedView = null; + _observedRoot = null; _wrapEl = null; /* the grid belongs to the #view we are leaving */ } function watch() { const view = document.getElementById('view'); - if (_observer && _observedView !== view) + /* `#maincontent`, not `#view`: a client navigation builds a fresh `#view` before it is in the + * document and swaps it in afterwards, and this runs on the `data-page` stamp, which comes + * first — so the observer bound here read `isConnected: false` after one round trip and the + * grid stopped being re-arranged on every poll tick, silently, until the next full load. The + * shell's column outlives every swap. Same fault, same fix as fs-appearance.js. */ + const root = document.getElementById('maincontent') || view; + if (_observer && _observedRoot !== root) stopWatch(); arrange(); /* a chrome module is alive on every page, so without the route check an observer would attach @@ -121,11 +127,11 @@ function watch() { if (_observer || !view || (document.body.getAttribute('data-page') || '') !== 'admin-status-overview') return; - _observedView = view; + _observedRoot = root; /* one arrange() per frame, however many mutations a poll tick delivers (fit.frame — the * theme's shared coalescer, fs-fit.js) */ _observer = new MutationObserver(fit.frame(arrange)); - _observer.observe(view, { childList: true, subtree: true }); + _observer.observe(root, { childList: true, subtree: true }); } /* A chrome module is instantiated once per page load, so it has to notice SPA navigation itself. diff --git a/my-default-settings/Makefile b/my-default-settings/Makefile index 4f68c472..ce42b9b1 100644 --- a/my-default-settings/Makefile +++ b/my-default-settings/Makefile @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=my-default-settings PKG_VERSION:=2 -PKG_RELEASE:=9 +PKG_RELEASE:=10 include $(INCLUDE_DIR)/package.mk diff --git a/my-default-settings/files/usr/lib/lua/luci/view/admin_status/index/links.htm b/my-default-settings/files/usr/lib/lua/luci/view/admin_status/index/links.htm index 9de13ced..0df8e453 100644 --- a/my-default-settings/files/usr/lib/lua/luci/view/admin_status/index/links.htm +++ b/my-default-settings/files/usr/lib/lua/luci/view/admin_status/index/links.htm @@ -1,7 +1,7 @@ <% if luci.sys.exec("echo -n `uci -q get base_config.@status[0].links`") ~= "0" then %>