diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index 80466dc9..23f5342a 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.7.16 -PKG_RELEASE:=182 +PKG_RELEASE:=183 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua index ffb01c33..cb8e92ec 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua @@ -808,6 +808,9 @@ o:value("UseIPv6v4", translate("Prefer IPv6")) o:value("UseIPv4", translate("IPv4 Only")) o:value("UseIPv6", translate("IPv6 Only")) +o = s:option(Flag, _n("happy_eyeballs"), translate("Enable Happy Eyeballs"), translate("Attempts IPv4 and IPv6 simultaneously; automatically uses the faster connection.")) +o.default = 0 + local protocols = s.fields[_n("protocol")].keylist if #protocols > 0 then for i, v in ipairs(protocols) do @@ -819,7 +822,11 @@ if #protocols > 0 then s.fields[_n("address")]:depends(depends_condition) s.fields[_n("port")]:depends(depends_condition) s.fields[_n("domain_resolver")]:depends(depends_condition) - s.fields[_n("domain_strategy")]:depends(depends_condition) + s.fields[_n("happy_eyeballs")]:depends(depends_condition) + + local strategy_depends = api.clone(depends_condition) + strategy_depends[_n("happy_eyeballs")] = false + s.fields[_n("domain_strategy")]:depends(strategy_depends) if v ~= "hysteria2" then s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v }) diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua index a6454928..438bde06 100644 --- a/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -146,7 +146,13 @@ function gen_outbound(flag, node, tag, proxy_table) mark = 255, domainStrategy = node.domain_strategy or "UseIP", tcpFastOpen = (node.tcp_fast_open == "1") and true or nil, - tcpMptcp = (node.tcpMptcp == "1") and true or nil + tcpMptcp = (node.tcpMptcp == "1") and true or nil, + happyEyeballs = (node.happy_eyeballs == "1") and { + TryDelayMs = 250, + PrioritizeIPv6 = false, + Interleave = 1, + MaxConcurrentTry = 4 + } or nil }, network = node.transport, security = node.stream_security, diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po index 548ca2fd..d27b2950 100644 --- a/luci-app-passwall/po/zh-cn/passwall.po +++ b/luci-app-passwall/po/zh-cn/passwall.po @@ -1964,6 +1964,12 @@ msgstr "如果节点地址是域名,则将使用此 DNS 进行解析。" msgid "Note: For node-specific DNS only. Keep Auto to avoid extra overhead." msgstr "注意:仅用于节点专用 DNS,通常请保持自动,以免增加开销。" +msgid "Enable Happy Eyeballs" +msgstr "启用 Happy Eyeballs" + +msgid "Attempts IPv4 and IPv6 simultaneously; automatically uses the faster connection." +msgstr "同时尝试 IPv4 和 IPv6 连接,自动使用更快的连接。" + msgid "Supports only Xray or Sing-box node types." msgstr "仅支持 Xray 或 Sing-box 类型节点。" diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile index 746a3ae9..34d88597 100644 --- a/luci-app-ssr-plus/Makefile +++ b/luci-app-ssr-plus/Makefile @@ -4,7 +4,7 @@ LUCI_TITLE:=luci-app-ssr-plus LUCI_PKGARCH:=all PKG_NAME:=luci-app-ssr-plus PKG_VERSION:=196 -PKG_RELEASE:=46 +PKG_RELEASE:=47 PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm index 8451c3d5..66fa41b6 100644 --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm @@ -157,10 +157,52 @@ font-size: 0.96rem !important; } + .ssr-schedule-inline { + display: flex !important; + flex-direction: row !important; + align-items: center !important; + gap: 1rem !important; + width: 50% !important; + box-sizing: border-box !important; + } + + .ssr-schedule-item { + flex: 1 !important; + display: flex !important; + flex-direction: column !important; + min-width: 0 !important; + } + + .ssr-schedule-subtitle { + text-align: center !important; + margin-bottom: 0.35rem !important; + line-height: 1.2 !important; + } + + select[name^="cbid.shadowsocksr."][name*="_time"] { + width: 100% !important; + min-width: 0 !important; + max-width: 100% !important; + height: 2.1rem !important; + padding: 0 0.35rem !important; + box-sizing: border-box !important; + } + @media (max-width: 900px) { #cbi-shadowsocksr-server_subscribe_item > .table { - display: block; - overflow-x: auto; + display: block !important; + overflow-x: auto !important; + white-space: nowrap !important; + } + + .ssr-schedule-inline { + width: 100% !important; + gap: 1rem !important; + } + + .ssr-schedule-item select { + width: 100% !important; + min-width: 0 !important; } } diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm index d2ffde75..16b6c6b1 100644 --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm @@ -531,27 +531,62 @@ end #cbi-shadowsocksr-server_subscribe_item .cbi-section-table td.cbi-section-actions { width: 100% !important; max-width: 100% !important; + min-width: 0 !important; display: block !important; box-sizing: border-box !important; } + /* 重置操作列内可能存在的 div 包装层,强行让其拉满 100% */ + #cbi-shadowsocksr-server_subscribe_item .td.cbi-section-actions > div { + display: flex !important; + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; + } + /* 按钮区域 */ #cbi-shadowsocksr-server_subscribe_item .ssr-subscribe-actions { display: flex !important; - gap: 8px; - width: 100%; + gap: 8px !important; + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; } /* 保存、删除、更新 三个按钮均分 */ - #cbi-shadowsocksr-server_subscribe_item .ssr-subscribe-actions .btn { - flex: 1; + #cbi-shadowsocksr-server_subscribe_item .ssr-subscribe-actions .btn, + #cbi-shadowsocksr-server_subscribe_item .td.cbi-section-actions .btn { + flex: 1 1 0% !important; + width: 100% !important; margin: 0 !important; - white-space: nowrap; + white-space: nowrap !important; + text-align: center !important; } /* 修复手机端卡片化布局中 placeholder 行的显示问题 */ #cbi-shadowsocksr-server_subscribe_item .placeholder td { display: table-cell !important; } + + #ssr-subscribe-modal { + top: 8px; + left: 8px; + width: calc(100vw - 16px); + max-height: calc(100vh - 24px); + min-height: min(420px, calc(100vh - 24px)); + padding: 10px 12px 12px; + transform: none; + border-radius: 8px; + } + + #ssr-subscribe-modal-header { + flex-direction: column; + align-items: flex-start; + } + + #ssr-subscribe-log { + max-height: calc(100vh - 260px); + min-height: 280px; + } }