Compare commits

..
5 Commits
Author SHA1 Message Date
kiddin9 f3d45a26a8 Update argon.patch
Merge-upstream / merge (push) Canceled after 0s
2026-08-29 00:53:34 +08:00
kiddin9 b341798cdd Update argon.patch 2026-08-29 00:51:14 +08:00
github-actions[bot] 04e8cdd08f 🎉 Sync 2026-08-28 21:44:02 2026-08-28 21:44:02 +08:00
kiddin9 82aaee7f65 Update upstream.yml 2026-08-28 21:41:48 +08:00
github-actions[bot] 045d307bfe 🎁 Sync 2026-08-28 19:05:48 2026-08-28 19:05:48 +08:00
44 changed files with 6155 additions and 255 deletions
+12
View File
@@ -1,3 +1,15 @@
--- a/luci-theme-argon/ucode/template/themes/argon/header.ut
+++ b/luci-theme-argon/ucode/template/themes/argon/header.ut
@@ -47,7 +47,7 @@
-%}
<!DOCTYPE html>
-<html lang="{{ dispatcher.lang }}">
+<html lang="{{ dispatcher.lang }}"{% if (mode == 'dark'): %} data-darkmode="true"{% elif (mode == 'light'): %} data-darkmode="false"{% endif %}>
<head>
{% include("themes/" + theme + "/head_meta", { hostname: hostname, node: node, bar_color: bar_color, media: media }) %}
--- a/luci-theme-argon/ucode/template/themes/argon/footer.ut --- a/luci-theme-argon/ucode/template/themes/argon/footer.ut
+++ b/luci-theme-argon/ucode/template/themes/argon/footer.ut +++ b/luci-theme-argon/ucode/template/themes/argon/footer.ut
@@ -19,13 +19,6 @@ @@ -19,13 +19,6 @@
+2 -2
View File
@@ -288,7 +288,7 @@ jobs:
git_clone https://github.com/EkkoG/luci-app-natmap git_clone https://github.com/EkkoG/luci-app-natmap
git_clone https://github.com/yichya/openwrt-hv-tools git_clone https://github.com/yichya/openwrt-hv-tools
git_clone https://github.com/ddimension/openwrt-repo && mv -f openwrt-repo/*wwand* ./;rm -rf openwrt-repo git_clone https://github.com/ddimension/openwrt-repo && mv -f openwrt-repo/*wwand* ./;rm -rf openwrt-repo
# git_clone https://github.com/papagaye744/luci-theme-design git_clone https://github.com/jerrykuku/luci-theme-argon
) & ) &
( (
git_clone https://github.com/EasyTier/luci-app-easytier luci-app-easytier1 && mvdir luci-app-easytier1 git_clone https://github.com/EasyTier/luci-app-easytier luci-app-easytier1 && mvdir luci-app-easytier1
@@ -406,7 +406,7 @@ jobs:
sound/spotifyd devel/go-rice devel/rust-bindgen admin/gotop \ sound/spotifyd devel/go-rice devel/rust-bindgen admin/gotop \
lang/lua/lua-periphery lang/lua/lua-neturl lang/lua/lua-maxminddb lang/golang devel/gn lang/lua/lua-periphery lang/lua/lua-neturl lang/lua/lua-maxminddb lang/golang devel/gn
git_clone https://github.com/koshev-msk/modemfeed && mv -n modemfeed/*/!(telephony)/!(ookla-speedtest) ./; rm -rf modemfeed git_clone https://github.com/koshev-msk/modemfeed && mv -n modemfeed/*/!(telephony)/!(ookla-speedtest) ./; rm -rf modemfeed
git_sparse_clone openwrt-25.12 "https://github.com/immortalwrt/luci" applications collections/luci-nginx protocols/luci-proto-minieap protocols/luci-proto-quectel themes/luci-theme-argon git_sparse_clone openwrt-25.12 "https://github.com/immortalwrt/luci" applications collections/luci-nginx protocols/luci-proto-minieap protocols/luci-proto-quectel
mv -f applications luciapp && rm -rf luciapp/luci-app-firewall mv -f applications luciapp && rm -rf luciapp/luci-app-firewall
git_sparse_clone openwrt-25.12 "https://github.com/coolsnowwolf/luci" applications \ git_sparse_clone openwrt-25.12 "https://github.com/coolsnowwolf/luci" applications \
modules/luci-base modules/luci-mod-network modules/luci-mod-status modules/luci-mod-system protocols/luci-proto-openvpnc themes/luci-theme-design modules/luci-base modules/luci-mod-network modules/luci-mod-status modules/luci-mod-system protocols/luci-proto-openvpnc themes/luci-theme-design
+2 -2
View File
@@ -2,8 +2,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_VERSION:=1.2.2-r20260804 PKG_VERSION:=1.2.3-r20260828
PKG_RELEASE:=5 PKG_RELEASE:=6
LUCI_TITLE:=LuCI support for jellyfin LUCI_TITLE:=LuCI support for jellyfin
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
@@ -130,7 +130,7 @@ do_install_detail() {
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`" local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz" [ -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\"" [ -z "$media" ] || cmd="$cmd -v \"$media:/media\""
cmd="$cmd -v /mnt:/mnt" cmd="$cmd -v /mnt:/mnt"
+1 -1
View File
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.8.26 PKG_VERSION:=26.8.26
PKG_RELEASE:=249 PKG_RELEASE:=250
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
@@ -2098,7 +2098,7 @@ function gen_config(var)
query_type = dns_rule_query_type, query_type = dns_rule_query_type,
server = fakedns_tag, server = fakedns_tag,
disable_cache = true, disable_cache = true,
rewrite_ttl = tonumber(remote_rewrite_ttl) rewrite_ttl = 30
} }
table.insert(dns.rules, fakedns_dns_rule) table.insert(dns.rules, fakedns_dns_rule)
end end
+1 -1
View File
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2 PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.8.27 PKG_VERSION:=26.8.27
PKG_RELEASE:=103 PKG_RELEASE:=104
PKG_PO_VERSION:=$(PKG_VERSION) PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
+2 -2
View File
@@ -2098,10 +2098,10 @@ msgid "Access Control:"
msgstr "访问控制:" msgstr "访问控制:"
msgid "Add node to the load balancer is directly connected to %s[%s]." 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." 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..." msgid "Starting to load %s firewall rules..."
msgstr "开始加载 %s 防火墙规则..." msgstr "开始加载 %s 防火墙规则..."
@@ -557,6 +557,7 @@ load_acl() {
} }
filter_haproxy() { 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 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) local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1)
[ -n "$ip" ] && ipset -q add $IPSET_VPS $ip [ -n "$ip" ] && ipset -q add $IPSET_VPS $ip
@@ -565,10 +566,16 @@ filter_haproxy() {
} }
filter_vpsip() { 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 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$")
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "ipset" "${$IPSET_VPS}")" [ -n "$ipv4_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}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R 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." "IPv6" "ipset" "${$IPSET_VPS6}")" 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() { filter_server_port() {
@@ -585,6 +585,7 @@ load_acl() {
} }
filter_haproxy() { 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 for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do
get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1 get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1
done | insert_nftset $NFTSET_VPS "-1" done | insert_nftset $NFTSET_VPS "-1"
@@ -602,10 +603,16 @@ filter_vps_addr() {
} }
filter_vpsip() { 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" 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$")
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "nftset" "${$NFTSET_VPS}")" [ -n "$ipv4_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}" | insert_nftset $NFTSET_VPS6 "-1" echo "$ipv4_addrs" | insert_nftset $NFTSET_VPS "-1"
#log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "nftset" "${$NFTSET_VPS6}")" 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() { filter_server_port() {
+2 -2
View File
@@ -11,8 +11,8 @@ LUCI_DEPENDS:=+luci-lib-xterm +taskd
LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3) LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3)
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=1.0.25 PKG_VERSION:=1.0.26
PKG_RELEASE:=1 PKG_RELEASE:=2
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com> PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk
+3
View File
@@ -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" msgid "Click the button in the upper right corner of the dialog box to close it, or click here to view the log"
msgstr "点击对话框右上角按钮关闭,或者点此查看日志" msgstr "点击对话框右上角按钮关闭,或者点此查看日志"
msgid "Upgrade"
msgstr "升级"
+2
View File
@@ -0,0 +1,2 @@
Screenshots
.DS_Store
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+4 -10
View File
@@ -7,17 +7,11 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
LUCI_TITLE:=Argon Theme LUCI_TITLE:=Argon Theme
LUCI_DEPENDS:=+wget-any +jsonfilter LUCI_DEPENDS:=+USE_APK:wget-any +!USE_APK:wget +jsonfilter
PKG_VERSION:=2.4.7
PKG_RELEASE:=4
PKG_VERSION:=2.4.3 CONFIG_LUCI_CSSTIDY:=
PKG_RELEASE:=3
LUCI_MINIFY_CSS:=0
define Package/luci-theme-argon/conffiles
/etc/config/argon
/www/luci-static/argon/background/
endef
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk
+128
View File
@@ -0,0 +1,128 @@
<!-- markdownlint-configure-file {
"MD013": {
"code_blocks": false,
"tables": false,
"line_length":200
},
"MD033": false,
"MD041": false
} -->
[license]: /LICENSE
[license-badge]: https://img.shields.io/github/license/jerrykuku/luci-theme-argon?style=flat-square&a=1
[prs]: https://github.com/jerrykuku/luci-theme-argon/pulls
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[issues]: https://github.com/jerrykuku/luci-theme-argon/issues/new
[issues-badge]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg?style=flat-square
[release]: https://github.com/jerrykuku/luci-theme-argon/releases
[release-badge]: https://img.shields.io/github/v/release/jerrykuku/luci-theme-argon?style=flat-square
[download]: https://github.com/jerrykuku/luci-theme-argon/releases
[download-badge]: https://img.shields.io/github/downloads/jerrykuku/luci-theme-argon/total?style=flat-square
[contact]: https://t.me/jerryk6
[contact-badge]: https://img.shields.io/badge/Contact-telegram-blue?style=flat-square
[en-us-link]: /README.md
[zh-cn-link]: /README_ZH.md
[en-us-release-log]: /RELEASE.md
[zh-cn-release-log]: /RELEASE_ZH.md
[config-link]: https://github.com/jerrykuku/luci-app-argon-config/releases
[official]: https://github.com/openwrt/openwrt
[immortalwrt]: https://github.com/immortalwrt/immortalwrt
<div align="center">
<img src="https://raw.githubusercontent.com/jerrykuku/staff/master/argon_title4.svg">
# A brand new OpenWrt LuCI theme
Argon is **a clean and tidy OpenWrt LuCI theme** that allows<br/>
users to customize their login interface with images or videos.
It also supports automatic and manual switching between light and dark modes.
[![license][license-badge]][license]
[![prs][prs-badge]][prs]
[![issues][issues-badge]][issues]
[![release][release-badge]][release]
[![download][download-badge]][download]
[![contact][contact-badge]][contact]
**English** |
[简体中文][zh-cn-link]
[Key Features](#key-features) •
[Compatibility](#compatibility) •
[Version History](#version-history) •
[Getting started](#getting-started) •
[Screenshots](#screenshots) •
[Contributors](#contributors) •
[Credits](#credits)
<img src="https://raw.githubusercontent.com/jerrykuku/staff/master/argon2.gif">
</div>
## Key Features
- Clean and modern Argon-style interface design.
- Fully adapted for both desktop and mobile displays.
- Supports automatic or manual switching between light and dark modes.
- Supports custom theme colors, along with adjustable blur and transparency effects.
- The login page supports local images, videos, and online wallpapers as backgrounds.
- Works with [luci-app-argon-config][config-link] for a more complete theme configuration experience.
## Compatibility
Only the `master` branch is maintained now.
Support is focused on modern LuCI environments based on [Official OpenWrt][official] and [ImmortalWrt][immortalwrt].
## Version History
The latest version is v2.4.7 [Click here][en-us-release-log] to view the full version history record.
## Getting started
### Build from source
```bash
cd openwrt/package
git clone https://github.com/jerrykuku/luci-theme-argon.git
make menuconfig #choose LUCI->Theme->Luci-theme-argon
make -j1 V=s
```
### Install release packages (`ipk`)
```bash
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-theme-argon_2.4.7-1_all.ipk
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-app-argon-config_2.4.7-1_all.ipk
opkg install ./luci-theme-argon_2.4.7-1_all.ipk ./luci-app-argon-config_2.4.7-1_all.ipk
```
### Install release packages (`apk`)
```bash
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-theme-argon-2.4.7-r1.apk
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-app-argon-config-2.4.7-r1.apk
apk add --allow-untrusted ./luci-theme-argon-2.4.7-r1.apk ./luci-app-argon-config-2.4.7-r1.apk
```
## Screenshots
![desktop](/Screenshots/screenshot_pc.jpg)
![mobile](/Screenshots/screenshot_phone.jpg)
## Contributors
<a href="https://github.com/jerrykuku/luci-theme-argon/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jerrykuku/luci-theme-argon&v=2" />
</a>
Made with [contrib.rocks](https://contrib.rocks).
## Related Projects
- [luci-app-argon-config](https://github.com/jerrykuku/luci-app-argon-config): Configuration plugin for the Argon theme
- [openwrt-package](https://github.com/jerrykuku/openwrt-package): My OpenWrt package collection
- [CasaOS](https://github.com/IceWhaleTech/CasaOS): A simple, elegant open-source personal cloud system and my current primary project
## Credits
[luci-theme-material](https://github.com/LuttyYang/luci-theme-material/)
+128
View File
@@ -0,0 +1,128 @@
<!-- markdownlint-configure-file {
"MD013": {
"code_blocks": false,
"tables": false,
"line_length":200
},
"MD033": false,
"MD041": false
} -->
[license]: /LICENSE
[license-badge]: https://img.shields.io/github/license/jerrykuku/luci-theme-argon?style=flat-square&a=1
[prs]: https://github.com/jerrykuku/luci-theme-argon/pulls
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[issues]: https://github.com/jerrykuku/luci-theme-argon/issues/new
[issues-badge]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg?style=flat-square
[release]: https://github.com/jerrykuku/luci-theme-argon/releases
[release-badge]: https://img.shields.io/github/v/release/jerrykuku/luci-theme-argon?style=flat-square
[download]: https://github.com/jerrykuku/luci-theme-argon/releases
[download-badge]: https://img.shields.io/github/downloads/jerrykuku/luci-theme-argon/total?style=flat-square
[contact]: https://t.me/jerryk6
[contact-badge]: https://img.shields.io/badge/Contact-telegram-blue?style=flat-square
[en-us-link]: /README.md
[zh-cn-link]: /README_ZH.md
[en-us-release-log]: /RELEASE.md
[zh-cn-release-log]: /RELEASE_ZH.md
[config-link]: https://github.com/jerrykuku/luci-app-argon-config/releases
[official]: https://github.com/openwrt/openwrt
[immortalwrt]: https://github.com/immortalwrt/immortalwrt
<div align="center">
<img src="https://raw.githubusercontent.com/jerrykuku/staff/master/argon_title4.svg">
# 一个全新的 OpenWrt 主题
Argon 是**一款干净整洁的 OpenWrt LuCI 主题**
允许用户使用图片或视频自定义其登录界面。
它还支持在浅色模式和深色模式之间自动或手动切换。
[![license][license-badge]][license]
[![prs][prs-badge]][prs]
[![issues][issues-badge]][issues]
[![release][release-badge]][release]
[![download][download-badge]][download]
[![contact][contact-badge]][contact]
[English][en-us-link] |
**简体中文**
[特色](#特色) •
[兼容性](#兼容性) •
[版本历史](#版本历史) •
[快速开始](#快速开始) •
[屏幕截图](#屏幕截图) •
[贡献者](#贡献者) •
[鸣谢](#鸣谢)
<img src="https://raw.githubusercontent.com/jerrykuku/staff/master/argon2.gif">
</div>
## 特色
- 简洁清爽的 Argon 风格界面设计。
- 完整适配桌面端与移动端显示。
- 支持浅色 / 深色模式自动或手动切换。
- 支持自定义主题主色,以及毛玻璃的模糊与透明度。
- 登录页支持本地图片、视频和在线壁纸背景。
- 可搭配 [luci-app-argon-config][config-link] 实现更完整的主题设置体验。
## 兼容性
目前仅维护 `master` 分支。
当前主要面向 [官方 OpenWrt][official] 和 [ImmortalWrt][immortalwrt] 的较新版本 LuCI 环境。
## 版本历史
当前最新的版本为 v2.4.7 [点击这里][zh-cn-release-log]查看完整的版本历史日志.
## 快速开始
### 从源码编译
```bash
cd openwrt/package
git clone https://github.com/jerrykuku/luci-theme-argon.git
make menuconfig #choose LUCI->Theme->Luci-theme-argon
make -j1 V=s
```
### 安装 release 包 (`ipk`)
```bash
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-theme-argon_2.4.7-1_all.ipk
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-app-argon-config_2.4.7-1_all.ipk
opkg install ./luci-theme-argon_2.4.7-1_all.ipk ./luci-app-argon-config_2.4.7-1_all.ipk
```
### 安装 release 包 (`apk`)
```bash
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-theme-argon-2.4.7-r1.apk
wget https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.4.7/luci-app-argon-config-2.4.7-r1.apk
apk add --allow-untrusted ./luci-theme-argon-2.4.7-r1.apk ./luci-app-argon-config-2.4.7-r1.apk
```
## 屏幕截图
![desktop](/Screenshots/screenshot_pc.jpg)
![mobile](/Screenshots/screenshot_phone.jpg)
## 贡献者
<a href="https://github.com/jerrykuku/luci-theme-argon/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jerrykuku/luci-theme-argon" />
</a>
Made with [contrib.rocks](https://contrib.rocks).
## 相关项目
- [luci-app-argon-config](https://github.com/jerrykuku/luci-app-argon-config): Argon 主题设置插件
- [openwrt-package](https://github.com/jerrykuku/openwrt-package): 我的 OpenWrt 软件包集合
- [CasaOS](https://github.com/IceWhaleTech/CasaOS): 一个简单、易用且优雅的开源个人云系统,也是我目前主要投入的项目
## 鸣谢
[luci-theme-material](https://github.com/LuttyYang/luci-theme-material/)
+161
View File
@@ -0,0 +1,161 @@
# Update log for master branch
## v2.4.7 [ 2026.08.24 ]
### What's Changed
* fix(openclash): correct form spacing and custom table styles by @Aethersailor in https://github.com/jerrykuku/luci-theme-argon/pull/698
* fixed: Issue where browser tabs were displayed incorrectly. by @smallprogram in https://github.com/jerrykuku/luci-theme-argon/pull/700
* refactor(openclash): unify Argon theme integration by @Aethersailor in https://github.com/jerrykuku/luci-theme-argon/pull/702
### New Contributors
* @smallprogram made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/700
**Full Changelog**: https://github.com/jerrykuku/luci-theme-argon/compare/v2.4.6...v2.4.7
## v2.4.6 [ 2026.07.31 ]
### What's Changed
* 修改警告提示对比度弱、系统设置按钮组间距,新增新版隐藏按钮样式 by @sydnkj in https://github.com/jerrykuku/luci-theme-argon/pull/688
* fix(openclash): normalize config switcher tab height by @Aethersailor in https://github.com/jerrykuku/luci-theme-argon/pull/689
* fix(pr) 修复#688,仅修改了编译产物,没有修改less源代码的问题 by @sydnkj in https://github.com/jerrykuku/luci-theme-argon/pull/692
* fix(issues) 解决#691提到的暗黑主题白色线问题 by @sydnkj in https://github.com/jerrykuku/luci-theme-argon/pull/693
**Full Changelog**: https://github.com/jerrykuku/luci-theme-argon/compare/v2.4.5...v2.4.6
## v2.4.5 [ 2026.07.18 ]
### What's Changed
* 修复输入框显示不全 by @Rain-Maple in https://github.com/jerrykuku/luci-theme-argon/pull/684
* fix(apk): avoid replacing uclient-fetch with wget-nossl by @jelipo in https://github.com/jerrykuku/luci-theme-argon/pull/685
* fix(openclash): align CBI zebra row spacing by @Aethersailor in https://github.com/jerrykuku/luci-theme-argon/pull/686
### New Contributors
* @Rain-Maple made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/684
* @jelipo made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/685
* @Aethersailor made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/686
**Full Changelog**: https://github.com/jerrykuku/luci-theme-argon/compare/v2.4.4...v2.4.5
## v2.4.4 [ 2026.07.16 ]
### What's Changed
* Dynlist indicate drop target by @jjm2473 in https://github.com/jerrykuku/luci-theme-argon/pull/590
* feat(online_wallpaper): get rid of curl by @1715173329 in https://github.com/jerrykuku/luci-theme-argon/pull/603
* chore(template): rewrite into ucode by @msylgj in https://github.com/jerrykuku/luci-theme-argon/pull/602
* fix some css style error by @msylgj in https://github.com/jerrykuku/luci-theme-argon/pull/607
* WIP: fix(css): fix some css issues by @msylgj in https://github.com/jerrykuku/luci-theme-argon/pull/617
* 修复luci-app-poweroffdevice、admin-system-reboot的按钮宽度问题,修复首页/状态页的 Hide、Show 按钮 by @yhl452493373 in https://github.com/jerrykuku/luci-theme-argon/pull/622
* 修复两处样式异常 by @guowenju in https://github.com/jerrykuku/luci-theme-argon/pull/632
* Wallhaven.cc loading fix by @AcidSlide in https://github.com/jerrykuku/luci-theme-argon/pull/634
* MWAN3 specific only - css fix by @AcidSlide in https://github.com/jerrykuku/luci-theme-argon/pull/633
* 优化openclash的公告栏边距 by @yhl452493373 in https://github.com/jerrykuku/luci-theme-argon/pull/637
* fix(nlbw): 修复`带宽监控`页面选择器并优化按钮布局 by @guowenju in https://github.com/jerrykuku/luci-theme-argon/pull/649
* fix: smartdns: fix padding loss in layout style by @sydnkj in https://github.com/jerrykuku/luci-theme-argon/pull/650
* luci-static/menu-argon: add missing ModeMenu handling by @feckert in https://github.com/jerrykuku/luci-theme-argon/pull/651
* fix(nftables): 修复`检测到旧版规则` `alert-message` 弹窗点击关闭按钮无效的问题 by @guowenju in https://github.com/jerrykuku/luci-theme-argon/pull/652
* 修复某些弹窗loading图标位置问题 by @yhl452493373 in https://github.com/jerrykuku/luci-theme-argon/pull/659
* Comment out X-Frame-Options meta tag by @yws112358 in https://github.com/jerrykuku/luci-theme-argon/pull/663
* 修复在最新openwrt上的一些问题 by @yhl452493373 in https://github.com/jerrykuku/luci-theme-argon/pull/666
* 修复OpenWrt 25.12主页样式异常 by @guowenju in https://github.com/jerrykuku/luci-theme-argon/pull/658
* 修复一些发现的问题 by @yhl452493373 in https://github.com/jerrykuku/luci-theme-argon/pull/668
* Fix Safari rendering issues on login and LuCI pages by @Nonosword in https://github.com/jerrykuku/luci-theme-argon/pull/670
* Update LUCI_DEPENDS to use wget-any by @1-1-2 in https://github.com/jerrykuku/luci-theme-argon/pull/671
* Revert "Update LUCI_DEPENDS to use wget-any" by @jerrykuku in https://github.com/jerrykuku/luci-theme-argon/pull/673
* 修复主页(dashboard)DHCP设备表格布局异常 by @guowenju in https://github.com/jerrykuku/luci-theme-argon/pull/674
* fix(css): remove transform on tooltip by @ckorber in https://github.com/jerrykuku/luci-theme-argon/pull/678
### New Contributors
* @1715173329 made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/603
* @guowenju made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/632
* @sydnkj made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/650
* @feckert made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/651
* @yws112358 made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/663
* @Nonosword made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/670
* @1-1-2 made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/671
* @ckorber made their first contribution in https://github.com/jerrykuku/luci-theme-argon/pull/678
**Full Changelog**: https://github.com/jerrykuku/luci-theme-argon/compare/v2.4.3...v2.4.4
## v2.4.3 [ 2025.07.22 ]
- **Refactor**: Remove jQuery dependency, fully replace with vanilla JavaScript
- **Modernize**: Upgrade HTML meta tags for better security and compatibility
- **Security**: Add security-related HTTP headers (CSP, XSS protection, clickjacking protection, etc.)
- **Font System**: Modernize font system with Google Sans font support
- **Font Optimization**: Replace legacy font formats (eot/svg/ttf) with woff2 for better performance
- **CSS Upgrade**: Upgrade Pure CSS to v3.0.0
- **Menu Enhancement**: Improve menu animations, remove jQuery dependency and sync animation timing
- **Style Improvement**: Add dockerman related style support
- **Mobile Optimization**: Optimize mobile and PWA related meta tag configurations
- **Icon Organization**: Reorganize website icon links following modern standards
- **Accessibility**: Improve web accessibility by allowing user scaling
- **Code Structure**: Optimize code structure with logical grouping comments
## v2.3.1 [ 2023.04.20 ]
- Fixed the issue where the dropdown menu was being clipped.
- Fixed the problem where the exit icon was replaced with the app store icon.
- Fixed the issue where some colors were out of control in dark mode.
- Fixed the problem where the local startup script textarea could not be scrolled in the startup item.
- Fixed the problem where the Passwall node list button was misaligned.
- Fixed the text overflow problem in dynlist
- Support wallpaper from Unsplashargon
- Fix menu style mis-match on macOS+Chrome
- Fixed the issue of the login page icon becoming larger
- Support wallpaper from wallhaven
> open footer links in new tab
- Remake theme icon
## v2.3 [ 2023.04.03 ]
- Updated the style of Loading.
- Fixed a large number of CSS style errors and made the overall more uniform.
- Fixed the problem of uncontrolled individual colors in dark mode.
## v2.2.9
- Unify the settings of css spacing
- Refactored the code of the login page
- Fix the problem that the Minify Css option is turned on when compiling, which causes the
- Fix the problem that the menu could not pop up in mobile mode
- Unify the settings of css spacing
- Refactored the code of the login page
## v2.2.8
- Fix the problem that the Minify Css option is turned on when compiling, which causes the frosted glass effect to be invalid and the logo font is lost.
## v2.2.5
- New config app for argon theme. You can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.[Chrome is recommended] [Download](https://github.com/jerrykuku/luci-app-argon-config/releases/download/v0.8-beta/luci-app-argon-config_0.8-beta_all.ipk)
- Automatically set as the default theme when compiling.
- Modify the file structure to adapt to luci-app-argon-config. The old method of turning on dark mode is no longer applicable, please use it with luci-app-argon-config.
- Adapt to Koolshare lede 2.3.6。
- Fix some Bug。
## v2.2.4
- Fix the problem that the login background cannot be displayed on some phones.
- Remove the dependency of luasocket.
## v2.2.3
- Fix Firmware flash page display error in dark mode.
- Update font icon, add a default icon of undefined menu.
## v2.2.2
- Add custom login background,put your image (allow png jpg gif) or MP4 video into /www/luci-static/argon/background, random change.
- Add force dark mode, login ssh and type "touch /etc/dark" to open dark mode.
- Add a volume mute button for video background, default is muted.
- fix login page when keyboard show the bottom text overlay the button on mobile.
- fix select color in dark mode,and add a style for scrollbar.
- jquery update to v3.5.1.
- change request bing api method form wget to luasocket (DEPENDS).
## v2.2.1
- Add blur effect for login form.
- New login theme, Request background imge from bing.com, Auto change everyday.
- New theme icon.
- Add more menu category icon.
- Fix font-size and padding margin.
- Restructure css file.
- Auto adapt to dark mode.
+102
View File
@@ -0,0 +1,102 @@
# Master 分支的更新日志
## v2.4.7 [ 2026.08.24 ]
- GitHub Release: https://github.com/jerrykuku/luci-theme-argon/releases/tag/v2.4.7
- 详细更新内容请以 Release 页面为准。
## v2.4.6 [ 2026.07.31 ]
- GitHub Release: https://github.com/jerrykuku/luci-theme-argon/releases/tag/v2.4.6
- 详细更新内容请以 Release 页面为准。
## v2.4.5 [ 2026.07.18 ]
- GitHub Release: https://github.com/jerrykuku/luci-theme-argon/releases/tag/v2.4.5
- 详细更新内容请以 Release 页面为准。
## v2.4.4 [ 2026.07.16 ]
- GitHub Release: https://github.com/jerrykuku/luci-theme-argon/releases/tag/v2.4.4
- 详细更新内容请以 Release 页面为准。
## v2.4.3 [ 2025.07.22 ]
- **重构**: 移除了对 jQuery 库的依赖,全面使用原生 JavaScript 替代
- **现代化**: 升级 HTML meta 标签,提升网页安全性和兼容性
- **安全增强**: 添加安全相关的 HTTP 头信息(CSP、XSS 防护、点击劫持防护等)
- **字体系统**: 现代化字体系统,新增 Google Sans 字体支持
- **字体优化**: 替换过时的字体格式(eot/svg/ttf)为 woff2,提升加载性能
- **CSS升级**: Pure CSS 升级到 v3.0.0 版本
- **菜单优化**: 改进菜单动画,移除 jQuery 依赖并同步动画时序
- **样式改进**: 新增 dockerman 相关样式支持
- **移动端优化**: 优化移动端和 PWA 相关的 meta 标签配置
- **图标整理**: 重新整理网站图标链接,按现代标准排序
- **无障碍性**: 改善网页无障碍性,允许用户缩放页面
- **代码结构**: 优化代码结构,添加逻辑分组注释
## v2.3.1 [ 2023.04.20 ]
- 修复了下拉菜单被裁切的问题
- 修复了退出图标变成了应用商店图标的问题
- 修复了暗色模式下个别颜色不受控制的问题
- 修复了启动项--本地启动脚本文本框不能滑动的问题
- 修复了Passwall节点列表按钮错位的问题
- 修复在dynlist中的文本溢出问题
- 登录页面 支持自来 Unsplash 的在线壁纸
- 修复在macOS的Chrome中,菜单的style异常
- 修复在登录页面中,主题图标变大的问题
- 登录页面 支持自来 wallhaven 的在线壁纸
> 打开页脚链接时使用新标签页
- 重制主题图标
## v2.3 [ 2023.04.03 ]
- 更新了 Loading 的样式
- 修复了大量的 CSS 样式错误,整体更加统一
- 修复了暗色模式下个别颜色不受控制的问题
## v2.2.9
- 修复了在手机模式下无法弹出菜单的 bug
- 统一 css 间距的设置
- 重构了登录页面的代码
- 为导航菜单添加滑动效果
## v2.2.8
- 【v2.2.8】修复编译时打开 Minify Css 选项,导致磨砂玻璃效果无效,logo 字体丢失的问题
## v2.2.5
- 全新的设置 app.你可以设置 argon 主题的登录页面的模糊和透明度,并管理背景图片与视频。[建议使用 Chrome][点击下载](https://github.com/jerrykuku/luci-app-argon-config/releases/download/v0.8-beta/luci-app-argon-config_0.8-beta_all.ipk)
- 当编译固件时,将自动设置为默认主题。
- 修改文件结构,以适应 luci-app-argon-config,旧的开启暗色模式方法将不再适用,请搭配 luci-app-argon-config 使用。
- 适配 Koolshare lede 2.3.6。
- 修复了一些 Bug。
## v2.2.4
- 修复了在某些手机下图片背景第一次加载不能显示的问题。
- 取消 luasocket 的依赖,无需再担心依赖问题。
## v2.2.3
- 修正了在暗色模式下,固件刷写弹窗内的显示错误。
- 更新了图标库,为未定义的菜单增加了一个默认的图标。
## v2.2.2
- 背景文件策略调整为,同时接受 jpg png gif mp4, 自行上传文件至 /www/luci-static/argon/background 图片和视频同时随机。
- 增加强制暗色模式,进入 ssh 输入 "touch /etc/dark" 进行开启。
- 视频背景加了一个音量开关,喜欢带声音的可以自行点击开启,默认为静音模式。
- 修复了手机模式下,登录页面出现键盘时,文字覆盖按钮的问题。
- 修正了暗黑模式下下拉选项的背景颜色,同时修改了滚动条的样式。
- jquery 更新到 v3.5.1。
- 获取 Bing Api 的方法从 wget 更新到 luasocket 并添加依赖。
## v2.2.1
- 登录背景添加毛玻璃效果。
- 全新的登录界面,图片背景跟随 Bing.com,每天自动切换。
- 全新的主题 icon。
- 增加多个导航 icon。
- 细致的微调了 字号大小边距等等。
- 重构了 css 文件。
- 自动适应的暗黑模式。
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

@@ -1,41 +1,11 @@
{ {
"name": "Openwrt", "name": "Openwrt",
"display": "standalone",
"icons": [ "icons": [
{ {
"src": "\/android-icon-36x36.png", "src": "android-icon-192x192.png",
"sizes": "36x36",
"type": "image\/png",
"density": "0.75"
},
{
"src": "\/android-icon-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": "1.0"
},
{
"src": "\/android-icon-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": "1.5"
},
{
"src": "\/android-icon-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": "2.0"
},
{
"src": "\/android-icon-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": "3.0"
},
{
"src": "\/android-icon-192x192.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image\/png", "type": "image/png"
"density": "4.0"
} }
] ]
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

+37 -2
View File
@@ -40,7 +40,6 @@
--gray-dark: #32325d; --gray-dark: #32325d;
--light: #ced4da; --light: #ced4da;
--lighter: #e9ecef; --lighter: #e9ecef;
--success: #2dce89; --success: #2dce89;
--info: #11cdef; --info: #11cdef;
--warning: #fb6340; --warning: #fb6340;
@@ -234,6 +233,7 @@ select[multiple="multiple"] {
&.error { &.error {
background-color: var(--warning); background-color: var(--warning);
color: var(--yellow);
} }
h4 { h4 {
@@ -275,6 +275,31 @@ select[multiple="multiple"] {
padding: .3rem .6rem; padding: .3rem .6rem;
} }
/* LuCI's ui.js dismisses notification banners by adding the .fade-out
class and removing the banner node once a transitionend event fires
on it. Without a transitioned opacity on .alert-message the Dismiss
button has no visible effect and the banner stays open forever. */
.alert-message {
transition: opacity .4s ease;
&.fade-out {
opacity: 0;
}
&.fade-in {
animation: alert-message-fade-in .4s ease;
}
}
@keyframes alert-message-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#maincontent > .alert-message { #maincontent > .alert-message {
position: fixed; position: fixed;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
@@ -486,6 +511,17 @@ body:not([data-page="admin-dashboard"]) {
} }
} }
@media (prefers-color-scheme: dark) {
body:not([data-page="admin-dashboard"]) {
tr>td,
tr>th,
.tr>.td,
.tr>.th {
border-top: thin solid #444 !important;
}
}
}
#cbi-wireless .td, #cbi-wireless .td,
.table[width="100%"]>.tr:first-child>.td, .table[width="100%"]>.tr:first-child>.td,
[data-page="admin-network-diagnostics"] .tr>.td, [data-page="admin-network-diagnostics"] .tr>.td,
@@ -2251,7 +2287,6 @@ span[data-tooltip] .label {
padding: 0.5rem; padding: 0.5rem;
opacity: 0; opacity: 0;
transition: opacity .25s ease-in; transition: opacity .25s ease-in;
transform: translate(-50%, 10%);
} }
.cbi-tooltip-container:hover .cbi-tooltip:not(:empty) { .cbi-tooltip-container:hover .cbi-tooltip:not(:empty) {
+9 -31
View File
@@ -1064,37 +1064,15 @@ input,
} }
[data-page^="admin-services-openclash"] { [data-page^="admin-services-openclash"] {
.oc { --oc-accent: var(--dark-primary);
--bg-light: #1e1e1e !important; --oc-surface: #1e1e1e;
--bg-gray: #1e1e1e !important; --oc-surface-muted: #252526;
--oc-control-bg: #1e1e1e;
.developer-container { --oc-border: #3c3c3c;
background: transparent !important; --oc-text: #ccc;
} --oc-text-muted: #a1a1aa;
--oc-neutral: #5b5b5b;
.config-upload-content{ --oc-scrollbar: #5b5b5b;
background: #1e1e1e !important;
}
}
.cbi-tabmenu::-webkit-scrollbar-thumb {
background-color: #5b5b5b;
}
.cbi-tabmenu::-webkit-scrollbar-track {
background-color: rgba(60, 60, 60, 0.75);
}
#tab {
border-color: #3c3c3c;
}
#diag-rc-output > pre,
#dns-rc-output > pre {
color: #ccc;
border: 1px solid #3c3c3c !important;
background-color: #1e1e1e;
}
img[src$="arrow-clockwise-light.svg"], img[src$="arrow-clockwise-light.svg"],
img[src$="wrench-light.svg"], img[src$="wrench-light.svg"],
+4
View File
@@ -433,6 +433,10 @@
background-color: #fff; background-color: #fff;
} }
.table {
width: 100%;
}
.settings-info { .settings-info {
padding-top: 1em; padding-top: 1em;
padding-bottom: 1em; padding-bottom: 1em;
+445 -26
View File
@@ -18,6 +18,7 @@
[data-page="admin-system-system"] { [data-page="admin-system-system"] {
.control-group { .control-group {
gap: .875rem; gap: .875rem;
margin: 0.25rem 0;
} }
.cbi-dynlist { .cbi-dynlist {
@@ -551,6 +552,10 @@
.cbi-title { .cbi-title {
position: relative; position: relative;
.label {
cursor: pointer;
}
> div:last-child { > div:last-child {
position: absolute; position: absolute;
right: 1.25rem; right: 1.25rem;
@@ -712,19 +717,355 @@
// Services - OpenClash // Services - OpenClash
[data-page^="admin-services-openclash"] { [data-page^="admin-services-openclash"] {
// One adapter contract for OpenClash's current component set.
// Semantic colours remain owned by OpenClash; primary interactions and
// neutral surfaces follow Argon's runtime-configurable palette.
--oc-accent: var(--primary);
--oc-accent-hover: var(--primary);
--oc-accent-strong: var(--primary);
--oc-accent-a5: transparent;
--oc-accent-a10: transparent;
--oc-accent-a20: transparent;
--oc-accent-a30: transparent;
--oc-accent-a40: transparent;
--oc-accent-a50: transparent;
--oc-accent-a60: transparent;
--oc-surface: #fff;
--oc-surface-muted: #f6f9fc;
--oc-control-bg: #fff;
--oc-border: #dee2e6;
--oc-text: #525f7f;
--oc-text-muted: #8898aa;
--oc-neutral: #8898aa;
--oc-scrollbar: #f6f9fc;
@supports (color: color-mix(in srgb, red, blue)) {
--oc-accent-hover: color-mix(in srgb, var(--oc-accent) 88%, black);
--oc-accent-strong: color-mix(in srgb, var(--oc-accent) 78%, black);
--oc-accent-a5: color-mix(in srgb, var(--oc-accent) 5%, transparent);
--oc-accent-a10: color-mix(in srgb, var(--oc-accent) 10%, transparent);
--oc-accent-a20: color-mix(in srgb, var(--oc-accent) 20%, transparent);
--oc-accent-a30: color-mix(in srgb, var(--oc-accent) 30%, transparent);
--oc-accent-a40: color-mix(in srgb, var(--oc-accent) 40%, transparent);
--oc-accent-a50: color-mix(in srgb, var(--oc-accent) 50%, transparent);
--oc-accent-a60: color-mix(in srgb, var(--oc-accent) 60%, transparent);
}
.oc { .oc {
--bg-light: #fff; --bg-white: var(--oc-surface) !important;
--bg-gray: #fff; --bg-light: var(--oc-surface) !important;
--bg-gray: var(--oc-surface) !important;
--bg-dark: var(--oc-surface) !important;
--hover-bg: var(--oc-surface-muted) !important;
--editor-bg: var(--oc-control-bg) !important;
--card-bg-start: var(--oc-surface) !important;
--border-color: var(--oc-border) !important;
--border-light: var(--oc-border) !important;
--border-dark: var(--oc-border) !important;
--tab-border: var(--oc-border) !important;
--divider: var(--oc-border) !important;
--text-primary: var(--oc-text) !important;
--text-secondary: var(--oc-text-muted) !important;
--text-title: var(--oc-text) !important;
--primary-color: var(--oc-accent) !important;
--primary-bright: var(--oc-accent) !important;
--btn-primary-hover: var(--oc-accent-hover) !important;
--announcement-end: var(--oc-accent-strong) !important;
--card-btn-bg: var(--oc-accent) !important;
--card-accent: var(--oc-accent) !important;
--primary-a5: var(--oc-accent-a5) !important;
--primary-a10: var(--oc-accent-a10) !important;
--primary-a20: var(--oc-accent-a20) !important;
--primary-a30: var(--oc-accent-a30) !important;
--primary-a40: var(--oc-accent-a40) !important;
--primary-a50: var(--oc-accent-a50) !important;
--primary-a60: var(--oc-accent-a60) !important;
--radio-hover-bg: var(--oc-accent-a10) !important;
--tab-hover-dark-bg: var(--oc-accent-a10) !important;
--scrollbar-thumb: var(--oc-neutral) !important;
--scrollbar-thumb-hover: var(--oc-text-muted) !important;
border-radius: 8px; border-radius: 8px;
.developer-container { .developer-container,
background: transparent; .subscription-info-container {
background: transparent !important;
} }
.announcement-card { .announcement-card {
width: auto !important; width: auto !important;
margin: 10px !important; margin: 10px !important;
} }
.config-upload-content {
background: var(--oc-surface) !important;
}
}
// Standard LuCI controls
.cbi-button.cbi-button-add,
.cbi-button.cbi-button-apply,
.cbi-button.cbi-button-edit,
.cbi-button.cbi-button-link,
.cbi-button.cbi-button-positive,
.cbi-button.cbi-button-reload,
.cbi-button.cbi-button-save,
.cbi-button.cbi-button-action,
input.cbi-input-apply,
input.cbi-input-reload,
input.cbi-input-save,
.btn.primary {
color: #fff !important;
border-color: var(--oc-accent) !important;
background: var(--oc-accent) !important;
}
.cbi-button.cbi-button-remove,
.cbi-button.cbi-button-negative,
input.cbi-input-remove {
color: #fff !important;
border-color: var(--danger) !important;
background: var(--danger) !important;
}
.cbi-button.cbi-button-reset {
color: #fff !important;
border-color: var(--warning) !important;
background: var(--warning) !important;
}
.cbi-button.cbi-button-find,
input.cbi-input-find {
color: #fff !important;
border-color: var(--oc-neutral) !important;
background-color: var(--oc-neutral) !important;
}
// Sorting controls are compact icon buttons. A neutral outline keeps the
// bundled gray arrow legible on light surfaces without implying disabled.
#cbi-openclash .cbi-button-up,
#cbi-openclash .cbi-button-down {
border-color: var(--oc-neutral) !important;
background-color: var(--oc-control-bg) !important;
}
#cbi-openclash .cbi-button-up:not(:disabled):hover,
#cbi-openclash .cbi-button-up:not(:disabled):focus,
#cbi-openclash .cbi-button-down:not(:disabled):hover,
#cbi-openclash .cbi-button-down:not(:disabled):focus {
border-color: var(--oc-accent) !important;
background-color: var(--oc-accent-a10) !important;
box-shadow: 0 0 0 2px var(--oc-accent-a10) !important;
}
input[type="checkbox"] {
border-color: var(--oc-accent) !important;
&:checked {
border-color: var(--oc-accent) !important;
background-color: var(--oc-accent) !important;
}
}
input[type="text"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="url"],
select,
textarea,
.cbi-dropdown,
.oc .oc-input-textarea,
.oc .sub-info-url-form-textarea,
.oc .select-class,
.oc .custom-option-input {
color: var(--oc-text) !important;
border-color: var(--oc-border) !important;
background-color: var(--oc-control-bg) !important;
}
input[type="text"]:focus,
input[type="password"]:focus,
input[type="number"]:focus,
input[type="search"]:focus,
input[type="url"]:focus,
select:focus,
textarea:focus,
.cbi-dropdown:focus,
.cbi-dropdown[open],
.oc .oc-input-textarea:focus,
.oc .sub-info-url-form-textarea:focus,
.oc .select-class:focus,
.oc .custom-option-input:focus {
border-color: var(--oc-accent) !important;
box-shadow: 0 0 0 2px var(--oc-accent-a10) !important;
outline: 0 !important;
}
.CodeMirror,
.oc .cm-editor {
color: var(--oc-text) !important;
border: 1px solid var(--oc-border) !important;
background: var(--oc-control-bg) !important;
}
.CodeMirror-gutters,
.oc .cm-gutters {
border-color: var(--oc-border) !important;
background: var(--oc-surface-muted) !important;
}
.CodeMirror.CodeMirror-focused,
.oc .cm-editor.cm-focused {
border-color: var(--oc-accent) !important;
box-shadow: 0 0 0 2px var(--oc-accent-a10) !important;
outline: 0 !important;
}
// Both tab classes are current component variants, not version branches.
.oc .radio-button input[type="radio"]:checked+label,
.oc #tab-header>ul.cbi-tabmenu>li.cbi-tab,
.oc #tab-header>ul.oc-tabmenu>li.oc-tab {
color: #fff !important;
border-color: var(--oc-accent) !important;
background: var(--oc-accent) !important;
}
.oc .radio-button input[type="radio"]:checked+label {
box-shadow: 0 1px 2px var(--oc-accent-a10) !important;
}
.oc .radio-button label:hover,
.oc #tab-header>ul.cbi-tabmenu>li:not(.cbi-tab):hover,
.oc #tab-header>ul.cbi-tabmenu>li:not(.cbi-tab):focus,
.oc #tab-header>ul.oc-tabmenu>li:not(.oc-tab):hover,
.oc #tab-header>ul.oc-tabmenu>li:not(.oc-tab):focus {
color: var(--oc-accent) !important;
border-color: var(--oc-accent) !important;
background: var(--oc-accent-a10) !important;
}
.oc #tab-header>ul.cbi-tabmenu>li:not(.cbi-tab):hover>a,
.oc #tab-header>ul.cbi-tabmenu>li:not(.cbi-tab):focus>a,
.oc #tab-header>ul.oc-tabmenu>li:not(.oc-tab):hover>a,
.oc #tab-header>ul.oc-tabmenu>li:not(.oc-tab):focus>a {
color: var(--oc-accent) !important;
}
.oc .card .general .btn:hover,
.oc #addCustomOption:hover {
background: var(--oc-accent-hover) !important;
}
.oc .help-link:hover {
background: var(--oc-accent-a10) !important;
}
.oc .select-option[data-value="custom"] {
border-color: var(--oc-accent-a20) !important;
background: var(--oc-accent-a10) !important;
&:hover {
background: var(--oc-accent-a20) !important;
}
}
.oc .announcement-banner,
.oc .oix-announcement {
background: linear-gradient(275deg, var(--oc-accent), var(--oc-accent-strong)) !important;
}
.oc .announcement-banner::before,
.oc .oix-announcement::before {
background: var(--oc-accent-strong) !important;
}
// The literal fill is a JavaScript state marker; change presentation only.
.oc #mode-icon rect[fill="#2F88FF"] {
fill: var(--oc-accent) !important;
}
// Argon cards use colour and shadow for hover feedback, not layout motion.
.oc .sub-card:hover,
.oc .myip-ip-item:hover,
.oc .myip-check-item:hover,
.oc .myip-card-item:hover,
.oc .card:hover,
.oc .oix-header:hover,
.oc .oix-card:hover,
.oc .config-upload-btn-large:hover {
transform: none !important;
}
// Legacy help text is primary emphasis; success and error remain semantic.
b[style*="color:green"],
b[style*="color: green"],
b[color="green"] {
color: var(--oc-accent) !important;
}
font[style*="color:green"],
font[style*="color: green"],
font[color="green"] {
color: var(--success) !important;
}
b[style*="color:red"],
b[style*="color: red"],
b[color="red"],
font[style*="color:red"],
font[style*="color: red"],
font[color="red"] {
color: var(--danger) !important;
}
// Normalize the config switcher and top-level navigation height.
.tabs>#tool_label {
padding-top: 0;
padding-bottom: 0;
vertical-align: middle;
.tool_label_span {
display: inline-flex;
align-items: center;
}
}
.cbi-section-node-tabbed>.cbi-tabcontainer {
gap: 0;
>.cbi-value {
padding-top: 0.4375rem;
padding-bottom: 0.4375rem;
}
}
&[data-page="admin-services-openclash-config"],
&[data-page="admin-services-openclash-config-subscribe"],
&[data-page^="admin-services-openclash-custom-dns-edit"],
&[data-page^="admin-services-openclash-config-subscribe-edit"],
&[data-page^="admin-services-openclash-groups-config"],
&[data-page^="admin-services-openclash-proxy-provider-config"],
&[data-page^="admin-services-openclash-servers-config"],
&[data-page^="admin-services-openclash-other-file-edit"] {
.cbi-map>.cbi-section>.cbi-section-node:not(.cbi-section-node-tabbed) {
padding-top: 1rem;
padding-bottom: 1rem;
}
}
&[data-page^="admin-services-openclash-config-subscribe-edit"] {
[id^="cbi-openclash-"][id$="-de_ex_keyword"] {
>.cbi-value-field {
>div:not([class])>span.cbi-checkbox {
display: inline-flex;
vertical-align: middle;
}
>.cbi-dropdown[multiple] {
max-width: 100%;
}
}
}
} }
#cbi-openclash>fieldset { #cbi-openclash>fieldset {
@@ -760,15 +1101,6 @@
margin-top: 5px; margin-top: 5px;
} }
.oc .sub-card:hover {
transform: none;
}
.oc .myip-ip-item:hover,
.oc .myip-check-item:hover {
transform: none;
}
.oc .main-cards-container { .oc .main-cards-container {
margin: 0 !important; margin: 0 !important;
gap: 0 !important; gap: 0 !important;
@@ -804,14 +1136,6 @@
min-width: auto !important; min-width: auto !important;
} }
.oc .config-upload-content {
background: #fff !important;
}
.oc .subscription-info-container {
background: transparent !important;
}
.cbi-tabmenu>li { .cbi-tabmenu>li {
border-right: none !important; border-right: none !important;
margin: 0 0.4rem 0 0 !important; margin: 0 0.4rem 0 0 !important;
@@ -821,10 +1145,77 @@
} }
} }
// The custom table renderer carries release-owned inline colours. Keep its
// layout, but make colour and row rhythm match ordinary Argon pages.
#cbi-openclash .cbi-section-table-row,
#cbi-openclash .cbi-rowstyle-1,
#cbi-openclash .cbi-rowstyle-2,
#cbi-openclash .cbi-tabcontainer>.cbi-value:nth-of-type(2n),
#cbi-openclash table>tbody>tr:nth-of-type(2n) {
background: var(--oc-surface) !important;
}
#cbi-openclash [id^="tab-header-openclash-"] {
border-bottom-color: var(--oc-border) !important;
background: var(--oc-surface) !important;
>ul.cbi-tabmenu {
background: var(--oc-surface) !important;
>li {
color: var(--oc-text-muted) !important;
border-color: var(--oc-border) !important;
background: var(--oc-surface) !important;
&.cbi-tab {
color: #fff !important;
border-color: var(--oc-accent) !important;
background: var(--oc-accent) !important;
>a {
color: #fff !important;
}
}
&:not(.cbi-tab):hover,
&:not(.cbi-tab):focus {
color: var(--oc-accent) !important;
border-color: var(--oc-accent) !important;
background: var(--oc-accent-a10) !important;
>a {
color: var(--oc-accent) !important;
}
}
}
}
}
[id^="tab-header-openclash-"]>ul.cbi-tabmenu>li {
margin: 0 !important;
border-right: 1px solid var(--oc-border) !important;
}
[id^="tab-header-openclash-"]+[id="tab-content"] {
.td.cbi-section-table-cell>p {
padding: 0;
}
}
#tab-content .dom { #tab-content .dom {
padding: 0 1rem 1rem 1rem; padding: 0 1rem 1rem 1rem;
} }
#cbi-openclash-dns_servers .cbi-section-table-row>
.cbi-section-table-cell:last-child {
min-width: 7.25rem;
white-space: nowrap;
>.cbi-button {
margin: 0 0.125rem !important;
}
}
.cbi-input-file { .cbi-input-file {
padding: 0.2813rem; padding: 0.2813rem;
width: 15rem !important; width: 15rem !important;
@@ -838,9 +1229,9 @@
#diag-rc-output>pre, #diag-rc-output>pre,
#dns-rc-output>pre { #dns-rc-output>pre {
font-size: 0.875rem; font-size: 0.875rem;
color: #8898aa; color: var(--oc-text-muted);
border: 1px solid #dee2e6; border: 1px solid var(--oc-border);
background-color: transparent; background-color: var(--oc-control-bg);
border-radius: 0.25rem; border-radius: 0.25rem;
font-family: 'Google Sans' !important; font-family: 'Google Sans' !important;
box-shadow: none; box-shadow: none;
@@ -850,7 +1241,8 @@
font-family: 'Google Sans' !important; font-family: 'Google Sans' !important;
} }
.CodeMirror { .CodeMirror,
.cm-editor {
font-size: inherit; font-size: inherit;
font-family: 'Google Sans' !important; font-family: 'Google Sans' !important;
} }
@@ -858,7 +1250,6 @@
.cbi-button-up, .cbi-button-up,
.cbi-button-down { .cbi-button-down {
padding: 0.8rem 1.5rem; padding: 0.8rem 1.5rem;
background-color: #f1f1f1;
font-size: 0; font-size: 0;
} }
@@ -866,6 +1257,34 @@
select#RELEASE_BRANCH { select#RELEASE_BRANCH {
width: auto; width: auto;
} }
@media screen and (max-width: 600px) {
&[data-page^="admin-services-openclash-config-subscribe-edit"] {
[id^="cbi-openclash-"][id$="-de_ex_keyword"] {
display: flex;
flex-direction: column;
>label.cbi-value-title {
display: block;
float: none;
width: 100%;
padding-right: 0;
text-align: left;
}
>.cbi-value-field {
width: 100%;
min-width: 0;
>.cbi-dropdown[multiple] {
width: 100%;
min-width: 0;
max-width: 100%;
}
}
}
}
}
} }
// 5. VPN Pages // 5. VPN Pages
@@ -26,9 +26,6 @@ fetch_pic_url() {
sed 's/1920x1080/UHD/g')" sed 's/1920x1080/UHD/g')"
[ -n "${picpath}" ] && echo "//www.bing.com${picpath}" [ -n "${picpath}" ] && echo "//www.bing.com${picpath}"
;; ;;
ghser)
echo "https://api.vvhan.com/api/wallpaper/acg"
;;
unsplash) unsplash)
if [ -z "$API_KEY" ]; then if [ -z "$API_KEY" ]; then
local pic_id="$(wget -T3 --spider \ local pic_id="$(wget -T3 --spider \
@@ -77,13 +74,14 @@ try_update() {
if flock -n 200 >"/dev/null" 2>&1; then if flock -n 200 >"/dev/null" 2>&1; then
local picurl="$(fetch_pic_url)" local picurl="$(fetch_pic_url)"
if [ -n "$picurl" ]; then if [ -n "$picurl" ]; then
# below is quirk fix for all browsers # below is quirk fix for all browsers
# for some weird reason on first load, wallhaven images needs to be # for some weird reason on first load, wallhaven images needs to be
# download or browsed first before it can be shown as a background image # download or browsed first before it can be shown as a background image
# if not, browser only displays a blank image # if not, browser only displays a blank image
# NOTE: only happens to Wallhaven.cc source images # NOTE: only happens to Wallhaven.cc source images
if [[ "$WEB_PIC_SRC" == wallhave* ]] ; then if [[ "$WEB_PIC_SRC" == wallhave* ]] ; then
wget -T3 -q "${picurl}" -O /dev/null wget -T3 -qO- "${picurl}" > /dev/null
fi fi
echo "$picurl" | tee "$CACHE" echo "$picurl" | tee "$CACHE"
@@ -0,0 +1,23 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ hostname }}{{ node?.title ? ` - ${striptags(node.title)}` : '' }} - LuCI</title>
<!-- SEO and Description -->
<meta name="robots" content="noindex, nofollow">
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
<!-- Mobile and PWA -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="{{ hostname }} - LuCI">
<!-- Theme and Colors -->
<meta name="theme-color" content="{{ bar_color }}">
<!-- Icons and Manifest -->
<link rel="icon" type="image/x-icon" href="{{ media }}/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="{{ media }}/icon/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="{{ media }}/icon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="192x192" href="{{ media }}/icon/android-icon-192x192.png">
<link rel="apple-touch-icon" sizes="144x144" href="{{ media }}/icon/apple-icon-144x144.png">
<link rel="manifest" href="{{ media }}/icon/manifest.json">
@@ -19,7 +19,6 @@
{% {%
import { readfile, access } from 'fs'; import { readfile, access } from 'fs';
import { cursor } from 'uci'; import { cursor } from 'uci';
import { srand } from 'math';
import { getuid, getspnam } from 'luci.core'; import { getuid, getspnam } from 'luci.core';
const boardinfo = ubus.call("system", "board"); const boardinfo = ubus.call("system", "board");
@@ -30,8 +29,6 @@
//send as HTML5 //send as HTML5
http.prepare_content('text/html; charset=UTF-8'); http.prepare_content('text/html; charset=UTF-8');
srand(+substr(reverse(time() + ""), 0, 8));
//Custom settings //Custom settings
let mode = 'normal'; let mode = 'normal';
let bar_color = '#5e72e4'; let bar_color = '#5e72e4';
@@ -53,42 +50,7 @@
<html lang="{{ dispatcher.lang }}"> <html lang="{{ dispatcher.lang }}">
<head> <head>
<meta charset="utf-8"> {% include("themes/" + theme + "/head_meta", { hostname: hostname, node: node, bar_color: bar_color, media: media }) %}
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>{{ hostname }}{{ node?.title ? ` - ${striptags(node.title)}` : '' }} - LuCI</title>
<!-- SEO and Description -->
<meta name="robots" content="noindex, nofollow">
<!-- Security -->
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<!-- <meta http-equiv="X-Frame-Options" content="SAMEORIGIN"> -->
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
<!-- Mobile and PWA -->
<meta name="format-detection" content="telephone=no, email=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="{{ hostname }} - LuCI">
<!-- Theme and Colors -->
<meta name="theme-color" content="{{ bar_color }}">
<meta name="msapplication-TileColor" content="{{ bar_color }}">
<meta name="msapplication-TileImage" content="{{ media }}/icon/ms-icon-144x144.png">
<meta name="application-name" content="{{ hostname }} - LuCI">
<!-- Icons and Manifest -->
<link rel="icon" type="image/x-icon" href="{{ media }}/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="{{ media }}/icon/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="{{ media }}/icon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="{{ media }}/icon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="192x192" href="{{ media }}/icon/android-icon-192x192.png">
<link rel="apple-touch-icon" sizes="60x60" href="{{ media }}/icon/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="{{ media }}/icon/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="144x144" href="{{ media }}/icon/apple-icon-144x144.png">
<link rel="manifest" href="{{ media }}/icon/manifest.json" crossorigin="use-credentials">
<link rel="stylesheet" href="{{ media }}/css/cascade.css{# ?v=PKG_VERSION #}"> <link rel="stylesheet" href="{{ media }}/css/cascade.css{# ?v=PKG_VERSION #}">
<style title="text/css"> <style title="text/css">
@@ -19,7 +19,6 @@
{% {%
import { readfile, access } from 'fs'; import { readfile, access } from 'fs';
import { cursor } from 'uci'; import { cursor } from 'uci';
import { srand } from 'math';
const boardinfo = ubus.call("system", "board"); const boardinfo = ubus.call("system", "board");
const hostname = striptags(boardinfo?.hostname ?? '?'); const hostname = striptags(boardinfo?.hostname ?? '?');
@@ -29,8 +28,6 @@
//send as HTML5 //send as HTML5
http.prepare_content('text/html; charset=UTF-8'); http.prepare_content('text/html; charset=UTF-8');
srand(+substr(reverse(time() + ""), 0, 8));
//Custom settings //Custom settings
let mode = 'normal'; let mode = 'normal';
let bar_color = '#5e72e4'; let bar_color = '#5e72e4';
@@ -52,42 +49,7 @@
<html lang="{{ dispatcher.lang }}"> <html lang="{{ dispatcher.lang }}">
<head> <head>
<meta charset="utf-8"> {% include("themes/" + theme + "/head_meta", { hostname: hostname, node: node, bar_color: bar_color, media: media }) %}
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>{{ hostname }}{{ node?.title ? ` - ${striptags(node.title)}` : '' }} - LuCI</title>
<!-- SEO and Description -->
<meta name="robots" content="noindex, nofollow">
<!-- Security -->
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<meta http-equiv="X-Frame-Options" content="SAMEORIGIN">
<meta http-equiv="X-XSS-Protection" content="1; mode=block">
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
<!-- Mobile and PWA -->
<meta name="format-detection" content="telephone=no, email=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="{{ hostname }} - LuCI">
<!-- Theme and Colors -->
<meta name="theme-color" content="{{ bar_color }}">
<meta name="msapplication-TileColor" content="{{ bar_color }}">
<meta name="msapplication-TileImage" content="{{ media }}/icon/ms-icon-144x144.png">
<meta name="application-name" content="{{ hostname }} - LuCI">
<!-- Icons and Manifest -->
<link rel="icon" type="image/x-icon" href="{{ media }}/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="{{ media }}/icon/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="{{ media }}/icon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="{{ media }}/icon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="192x192" href="{{ media }}/icon/android-icon-192x192.png">
<link rel="apple-touch-icon" sizes="60x60" href="{{ media }}/icon/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="{{ media }}/icon/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="144x144" href="{{ media }}/icon/apple-icon-144x144.png">
<link rel="manifest" href="{{ media }}/icon/manifest.json" crossorigin="use-credentials">
<link rel="stylesheet" href="{{ media }}/css/cascade.css{# ?v=PKG_VERSION #}"> <link rel="stylesheet" href="{{ media }}/css/cascade.css{# ?v=PKG_VERSION #}">
<style title="text/css"> <style title="text/css">
@@ -110,7 +72,6 @@
} }
{% endif -%} {% endif -%}
</style> </style>
<link rel="shortcut icon" href="{{ media }}/favicon.ico">
{% if (node?.css): %} {% if (node?.css): %}
<link rel="stylesheet" href="{{ resource }}/{{ node.css}}"> <link rel="stylesheet" href="{{ resource }}/{{ node.css}}">
{% endif -%} {% endif -%}
@@ -25,9 +25,16 @@
{% {%
import * as fs from 'fs'; import * as fs from 'fs';
import { cursor } from 'uci'; import { cursor } from 'uci';
import { rand } from 'math';
let cfg = cursor(); let cfg = cursor();
// Per-request pseudo-random state for selecting local backgrounds.
let lcgState = (+time()) % 2147483648;
function randomIndex(limit) {
lcgState = (lcgState * 1103515245 + 12345) % 2147483648;
return lcgState % limit;
}
//Fetch Local Background Media //Fetch Local Background Media
@@ -67,7 +74,7 @@
let background = fetchMedia("/www" + themeDir, themeDir); let background = fetchMedia("/www" + themeDir, themeDir);
if ( length(background) > 0 ) { if ( length(background) > 0 ) {
let currentBg = background[(rand() % length(background))]; let currentBg = background[randomIndex(length(background))];
bgUrl = currentBg.url; bgUrl = currentBg.url;
if (index(videoTypes, " " + currentBg.type + " ") != -1) { if (index(videoTypes, " " + currentBg.type + " ") != -1) {
backgroundType = "Video"; backgroundType = "Video";
@@ -47,6 +47,10 @@
& div[style*="display:grid"] { & div[style*="display:grid"] {
@apply max-md:grid-cols-2! max-md:gap-3; @apply max-md:grid-cols-2! max-md:gap-3;
&:has(> .ifacebox) {
@apply place-items-center;
}
} }
& .network-status-table { & .network-status-table {
@@ -63,7 +67,7 @@
} }
.ifacebox { .ifacebox {
@apply border-hairline bg-surface-overlay hover:border-hairline max-md:border-hairline relative inline-flex min-w-40 flex-col items-stretch overflow-visible rounded-2xl border text-center text-base leading-5 shadow-md hover:shadow-xl max-md:min-w-30 max-md:flex-1 max-md:rounded-3xl max-md:shadow-sm; @apply border-hairline bg-surface-overlay hover:border-hairline max-md:border-hairline relative inline-flex min-w-28 flex-col items-stretch overflow-visible rounded-2xl border text-center text-base leading-5 shadow-md hover:shadow-xl max-md:min-w-30 max-md:flex-1 max-md:rounded-3xl max-md:shadow-sm;
td & { td & {
@apply max-md:flex-row; @apply max-md:flex-row;
+2 -2
View File
@@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=Aurora Theme (A modern browser theme built with Vite and Tailwind CSS) LUCI_TITLE:=Aurora Theme (A modern browser theme built with Vite and Tailwind CSS)
LUCI_DEPENDS:=+luci-base LUCI_DEPENDS:=+luci-base
PKG_VERSION:=1.2.6 PKG_VERSION:=1.2.7
PKG_RELEASE:=73 PKG_RELEASE:=74
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
LUCI_MINIFY_CSS:= LUCI_MINIFY_CSS:=
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -17,7 +17,7 @@ LUCI_NAME:=luci-theme-footstrap
FOOTSTRAP_VERSION?= FOOTSTRAP_VERSION?=
ifneq ($(FOOTSTRAP_VERSION),) ifneq ($(FOOTSTRAP_VERSION),)
PKG_VERSION:=$(FOOTSTRAP_VERSION) PKG_VERSION:=$(FOOTSTRAP_VERSION)
PKG_RELEASE:=39 PKG_RELEASE:=40
endif endif
LUCI_TITLE:=Footstrap Theme LUCI_TITLE:=Footstrap Theme
@@ -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_DEADLINE = 5000;
const TAB = 'fs-appearance'; /* the pane's data-tab, which ui.tabs' click handler matches on */ 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 onPage() { return (document.body.getAttribute('data-page') || '') === PAGE; }
function stopWatch() { function stopWatch() {
if (_viewObserver) _viewObserver.disconnect(); if (_viewObserver) _viewObserver.disconnect();
_viewObserver = null; _viewObserver = null;
_observedView = null; _observedRoot = null;
} }
/* The stock tab GROUP: the element whose children are the panes, which ui.tabs marks /* 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 * 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 * 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 * attribute too otherwise the tab is missing until the next navigation (openwrt/luci#8903).
* until the next navigation (openwrt/luci#8903). */ *
const RETRIES = [ 0, 60, 150, 300, 600, 1200 ]; * A ladder of retries on a widening delay shipped beside that watch and is gone: instrumented over
let _retryTimer = 0, _retryAt = 0; * ten sessions on both package managers a full load, an SPA return, a Save and a Save & Apply
function retryMount() { * it mounted the tab zero times, only ever arming a timer that woke to find the work done. The
if (_retryTimer) return; * deadline below could once be seen mounting it, but only because watch() was binding the observer
if (_retryAt >= RETRIES.length) return; * to a node the router was about to replace; with that fixed the deadline is a diagnostic again. */
const delay = RETRIES[_retryAt++];
_retryTimer = window.setTimeout(() => { _retryTimer = 0; mount(); }, delay);
}
function mount() { function mount() {
const view = document.getElementById('view'); const view = document.getElementById('view');
if (!view || !onPage()) return; if (!view || !onPage()) return;
if (view.querySelector('.' + MARK)) { _retryAt = 0; return; } if (view.querySelector('.' + MARK)) return;
if (_building) return; if (_building) return;
const tabs = tabGroup(view); const tabs = tabGroup(view);
if (!tabs) { retryMount(); return; } if (!tabs) return; /* not built yet; the observer calls again when it is */
_building = true; _building = true;
render() render()
.then((form) => { .then((form) => {
@@ -882,13 +878,23 @@ function mount() {
function watch() { function watch() {
const view = document.getElementById('view'); 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; if (_viewObserver || !view || !onPage()) return;
_observedView = view; _observedRoot = root;
_viewObserver = new MutationObserver(mount); _viewObserver = new MutationObserver(mount);
/* `data-initialized` is the moment the group becomes usable, and it does not always come with /* `data-initialized` is when the group becomes usable, and the filter is load-bearing proven
* a childList change (see retryMount above) */ * by staging openwrt/luci#8903 rather than waiting for it: tear the tab, the pane and the
_viewObserver.observe(view, { * 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, childList: true, subtree: true,
attributes: true, attributeFilter: [ 'data-initialized' ], 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 * early on every mutation: the stock page renders, nothing throws, and every Appearance axis
* is unreachable. */ * is unreachable. */
window.setTimeout(() => { 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'); const v = document.getElementById('view');
if (!onPage() || !v || v.querySelector('.' + MARK) || _building) return; if (!onPage() || !v || v.querySelector('.' + MARK) || _building || tabGroup(v)) 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;
console.error('footstrap: the Appearance tab could not be attached — this page has tabs, but ' 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 ' + 'ui.tabs no longer marks them the way fs-appearance.js looks for. Every Appearance axis '
+ 'is unreachable until that is updated.'); + 'is unreachable until that is updated.');
@@ -104,16 +104,22 @@ function arrange() {
* coalesced and one observer per #view node. The SPA router may replace #view between visits, so * 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 * 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. */ * #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() { function stopWatch() {
if (_observer) _observer.disconnect(); if (_observer) _observer.disconnect();
_observer = null; _observer = null;
_observedView = null; _observedRoot = null;
_wrapEl = null; /* the grid belongs to the #view we are leaving */ _wrapEl = null; /* the grid belongs to the #view we are leaving */
} }
function watch() { function watch() {
const view = document.getElementById('view'); 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(); stopWatch();
arrange(); arrange();
/* a chrome module is alive on every page, so without the route check an observer would attach /* 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 || if (_observer || !view ||
(document.body.getAttribute('data-page') || '') !== 'admin-status-overview') (document.body.getAttribute('data-page') || '') !== 'admin-status-overview')
return; return;
_observedView = view; _observedRoot = root;
/* one arrange() per frame, however many mutations a poll tick delivers (fit.frame the /* one arrange() per frame, however many mutations a poll tick delivers (fit.frame the
* theme's shared coalescer, fs-fit.js) */ * theme's shared coalescer, fs-fit.js) */
_observer = new MutationObserver(fit.frame(arrange)); _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. /* A chrome module is instantiated once per page load, so it has to notice SPA navigation itself.
+1 -1
View File
@@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=my-default-settings PKG_NAME:=my-default-settings
PKG_VERSION:=2 PKG_VERSION:=2
PKG_RELEASE:=9 PKG_RELEASE:=10
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk
@@ -1,7 +1,7 @@
<% if luci.sys.exec("echo -n `uci -q get base_config.@status[0].links`") ~= "0" then %> <% if luci.sys.exec("echo -n `uci -q get base_config.@status[0].links`") ~= "0" then %>
<script> <script>
var links = document.createElement('div'); var links = document.createElement('div');
links.innerHTML ='<table class="table"><tr class="tr"><td class="td left"><a href="https://openwrt.ai/" target="_blank">固件下载与定制</a></td><td class="td left" width="25%"><a href="https://openwrt.ai/fadian/" target="_blank" style="color:orangered">赞助</a></td><td class="td left" width="25%"><a href="https://t.me/opwrt" target="_blank">TG频道</a></td><td class="td left" width="25%"><a href="https://github.com/kiddin9/OpenWrt_x86-r2s-r4s" target="_blank">源码与反馈</a></td></tr></table>'; links.innerHTML ='<table class="table"><tr class="tr"><td class="td left"><a href="https://openwrt.ai/" target="_blank">固件下载与定制</a></td><td class="td left" width="25%"><a href="https://openwrt.ai/fadian/" target="_blank" style="color:orangered">赞助</a></td><td class="td left" width="25%"><a href="https://github.com/kiddin9/Kwrt" target="_blank">源码与反馈</a></td><td class="td left" width="25%"><a href="https://t.me/opkwrt" target="_blank">TG交流</a></td></tr></table>';
setTimeout(function(){ setTimeout(function(){
var telegram = document.querySelectorAll(".cbi-section")[0]; var telegram = document.querySelectorAll(".cbi-section")[0];
telegram.appendChild(links); telegram.appendChild(links);