Skip to content

Commit 99bbe44

Browse files
author
Ubuntu
committed
feat: surface freshness and follow paths
1 parent 6c9ed05 commit 99bbe44

5 files changed

Lines changed: 126 additions & 4 deletions

File tree

README.en.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ Free Clash, sing-box, and V2Ray subscription links with live node status, multi-
1111

1212
[Atom Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.xml)[JSON Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.json)[Discussions](https://github.com/Au1rxx/free-vpn-subscriptions/discussions)
1313

14+
## Check These Signals First
15+
16+
- If you want to confirm that the public side is still fresh, check the [Status Dashboard](https://au1rxx.github.io/free-vpn-subscriptions/status.html) and the latest timestamp in `output/status.json`.
17+
- If you want the newest snapshot, clean download links, and release history, go straight to [GitHub Releases](https://github.com/Au1rxx/free-vpn-subscriptions/releases).
18+
- If you want ongoing updates, do not rely on bookmarking the repo homepage alone. Star the repo, use the repository Watch menu for `Releases`, or subscribe to the [Atom Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.xml) / [JSON Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.json).
19+
1420
## Why This Repo
1521

1622
- Public subscription feed for `Clash`, `sing-box`, and `V2Ray` users.
@@ -126,7 +132,7 @@ These client-specific guides exist to improve search visibility for real user qu
126132
If this feed is useful:
127133

128134
- Star the repository to help discovery.
129-
- Watch releases if you want visible update checkpoints.
135+
- Use the repository Watch menu for `Releases` if you want visible update checkpoints, or subscribe to the Atom / JSON feed above.
130136
- Use Discussions for client requests, setup questions, and broken-link reports.
131137
- Use Issues only when a public feed artifact, release asset, or Pages route is actually broken.
132138

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313

1414
[Atom Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.xml)[JSON Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.json)[Discussions](https://github.com/Au1rxx/free-vpn-subscriptions/discussions)
1515

16+
## 先看这三个信号
17+
18+
- 想确认公开侧是不是还在更新,先看 [状态面板](https://au1rxx.github.io/free-vpn-subscriptions/status.html)`output/status.json` 的最近检查时间。
19+
- 想看最近一次快照、手动下载入口和历史版本,直接看 [GitHub Releases](https://github.com/Au1rxx/free-vpn-subscriptions/releases)
20+
- 想持续跟踪更新,不要只收藏仓库首页;请优先 `Star`、到仓库 Watch 菜单里关注 `Releases`,或直接订阅 [Atom Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.xml) / [JSON Feed](https://au1rxx.github.io/free-vpn-subscriptions/updates.json)
21+
1622
## 项目定位
1723

1824
- 面向 `Clash``sing-box``V2Ray` 用户的公开订阅分发仓库。
@@ -128,7 +134,7 @@
128134
如果这个仓库对你有帮助:
129135

130136
- 请点 `Star`,帮助仓库获得更高曝光。
131-
- 如果你想跟踪快照更新,可以 `Watch releases`
137+
- 如果你想跟踪快照更新,请到仓库的 Watch 菜单里关注 `Releases`,或者直接订阅上面的 Atom / JSON Feed
132138
- 安装问题、客户端请求、兼容性反馈请优先走 `Discussions`
133139
- 只有在公开链接、Release 资产或 Pages 页面真实异常时,再提交 `Issues`
134140

site/app.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
const RELEASES_ENDPOINT =
22
"https://api.github.com/repos/Au1rxx/free-vpn-subscriptions/releases?per_page=6";
33

4+
const dashboardState = {
5+
activeCountText: "",
6+
latestCheck: "",
7+
latestReleaseStamp: "",
8+
};
9+
410
function formatUtcStamp(value) {
511
return value ? value.replace("T", " ").replace("Z", " UTC") : "";
612
}
@@ -27,6 +33,49 @@ function extractReleaseSummary(body) {
2733
return blocks[0] || "";
2834
}
2935

36+
function renderFreshnessBanner() {
37+
const freshnessTitle = document.getElementById("freshness-title");
38+
const freshnessDetail = document.getElementById("freshness-detail");
39+
40+
if (!freshnessTitle || !freshnessDetail) {
41+
return;
42+
}
43+
44+
if (!dashboardState.latestCheck) {
45+
freshnessTitle.textContent = "公开状态时间未知";
46+
freshnessDetail.textContent =
47+
"先打开状态页确认最近检查时间,再决定是否导入、刷新,或去 Releases 看最近快照。";
48+
return;
49+
}
50+
51+
const diffHours = (Date.now() - Date.parse(dashboardState.latestCheck)) / (1000 * 60 * 60);
52+
const statusStamp = formatUtcStamp(dashboardState.latestCheck);
53+
const releaseStamp = dashboardState.latestReleaseStamp
54+
? formatUtcStamp(dashboardState.latestReleaseStamp)
55+
: "";
56+
57+
if (Number.isNaN(diffHours)) {
58+
freshnessTitle.textContent = "公开状态已发布";
59+
} else if (diffHours <= 3) {
60+
freshnessTitle.textContent = "公开状态在线";
61+
} else if (diffHours <= 12) {
62+
freshnessTitle.textContent = "公开状态略有延迟";
63+
} else {
64+
freshnessTitle.textContent = "公开状态可能滞后";
65+
}
66+
67+
const parts = [];
68+
if (dashboardState.activeCountText) {
69+
parts.push(dashboardState.activeCountText);
70+
}
71+
parts.push(`最近状态检查 ${statusStamp}`);
72+
if (releaseStamp) {
73+
parts.push(`最近快照发布 ${releaseStamp}`);
74+
}
75+
parts.push("想持续跟踪更新就去看 Releases / Watch,或订阅 Feed");
76+
freshnessDetail.textContent = `${parts.join("。")}。`;
77+
}
78+
3079
async function loadStatus() {
3180
const activeCount = document.getElementById("active-count");
3281
const statusStamp = document.getElementById("status-stamp");
@@ -50,7 +99,11 @@ async function loadStatus() {
5099
.sort()
51100
.pop();
52101

53-
activeCount.textContent = `${active.length} / ${nodes.length} active`;
102+
const activeText = `${active.length} / ${nodes.length} active`;
103+
dashboardState.activeCountText = activeText;
104+
dashboardState.latestCheck = latestCheck || "";
105+
106+
activeCount.textContent = activeText;
54107
statusStamp.textContent = latestCheck
55108
? `Last check ${formatUtcStamp(latestCheck)}`
56109
: "No recent status timestamp";
@@ -82,10 +135,14 @@ async function loadStatus() {
82135
`;
83136
})
84137
.join("");
138+
renderFreshnessBanner();
85139
} catch (error) {
140+
dashboardState.activeCountText = "";
141+
dashboardState.latestCheck = "";
86142
activeCount.textContent = "Unavailable";
87143
statusStamp.textContent = "Could not load current status";
88144
nodeList.innerHTML = `<p class="muted">The public status feed is not available yet: ${error.message}</p>`;
145+
renderFreshnessBanner();
89146
}
90147
}
91148

@@ -122,6 +179,7 @@ async function loadReleases() {
122179
const latestTitle = latest.name || latest.tag_name;
123180
const latestStamp = formatUtcStamp(latest.published_at);
124181
const latestSummary = extractReleaseSummary(latest.body);
182+
dashboardState.latestReleaseStamp = latest.published_at || "";
125183

126184
if (latestRelease) {
127185
latestRelease.textContent = latestStamp
@@ -160,7 +218,9 @@ async function loadReleases() {
160218
})
161219
.join("");
162220
}
221+
renderFreshnessBanner();
163222
} catch (error) {
223+
dashboardState.latestReleaseStamp = "";
164224
if (latestRelease) {
165225
latestRelease.textContent = "暂时无法读取最近发布记录";
166226
}
@@ -173,6 +233,7 @@ async function loadReleases() {
173233
releaseList.innerHTML =
174234
`<p class="muted">暂时无法加载更新列表:${escapeHtml(error.message)}。你可以直接打开 GitHub Releases 查看历史快照。</p>`;
175235
}
236+
renderFreshnessBanner();
176237
}
177238
}
178239

site/index.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ <h1 class="hero-title">免费 VPN 订阅链接与实时节点状态</h1>
5050
<a href="./updates.xml">订阅更新 Feed</a>
5151
<a href="https://github.com/Au1rxx/free-vpn-subscriptions/releases/latest">查看最新快照</a>
5252
</div>
53+
<div class="freshness-banner">
54+
<div class="freshness-copy">
55+
<span class="metric-label">公开更新信号</span>
56+
<strong id="freshness-title">正在读取公开状态和最近快照</strong>
57+
<span id="freshness-detail">这里会显示最近状态检查时间,以及你该去哪里跟踪后续更新。</span>
58+
</div>
59+
<div class="freshness-actions">
60+
<a class="button button-secondary" href="./status.html">检查状态是否新鲜</a>
61+
<a class="button button-secondary" href="https://github.com/Au1rxx/free-vpn-subscriptions/releases">看 Releases / Watch</a>
62+
<a class="button button-secondary" href="https://github.com/Au1rxx/free-vpn-subscriptions">Star 仓库</a>
63+
</div>
64+
</div>
5365
</div>
5466
<div class="hero-panel">
5567
<div class="metric-card">
@@ -270,7 +282,8 @@ <h3>拿完链接之后,也知道去哪里提问和反馈。</h3>
270282
通过 Star、Release 更新和 Discussions 问答,把一次性流量沉淀成持续回访和可搜索内容。
271283
</p>
272284
<div class="stack-actions">
273-
<a class="button button-primary" href="https://github.com/Au1rxx/free-vpn-subscriptions">打开 GitHub 仓库</a>
285+
<a class="button button-primary" href="https://github.com/Au1rxx/free-vpn-subscriptions">Star 仓库</a>
286+
<a class="button button-secondary" href="https://github.com/Au1rxx/free-vpn-subscriptions/releases">打开 Releases</a>
274287
<a class="button button-secondary" href="https://github.com/Au1rxx/free-vpn-subscriptions/discussions">打开 Discussions</a>
275288
</div>
276289
</div>

site/styles.css

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,37 @@ li {
127127
margin-top: 1rem;
128128
}
129129

130+
.freshness-banner {
131+
display: grid;
132+
grid-template-columns: 1.1fr auto;
133+
gap: 1rem;
134+
align-items: center;
135+
margin-top: 1.3rem;
136+
padding: 1rem 1.1rem;
137+
border-radius: 22px;
138+
border: 1px solid rgba(15, 118, 110, 0.15);
139+
background: rgba(255, 252, 247, 0.78);
140+
}
141+
142+
.freshness-copy strong {
143+
display: block;
144+
margin: 0.2rem 0 0.3rem;
145+
font-size: 1.05rem;
146+
color: var(--text);
147+
}
148+
149+
.freshness-copy span:last-child {
150+
color: var(--muted);
151+
line-height: 1.6;
152+
}
153+
154+
.freshness-actions {
155+
display: flex;
156+
flex-wrap: wrap;
157+
justify-content: flex-end;
158+
gap: 0.7rem;
159+
}
160+
130161
.signal-row a {
131162
color: var(--accent-strong);
132163
font-weight: 700;
@@ -431,6 +462,7 @@ pre {
431462
.section-grid,
432463
.content-grid,
433464
.cards-three,
465+
.freshness-banner,
434466
.release-highlight,
435467
.release-item,
436468
.node-item {
@@ -440,4 +472,8 @@ pre {
440472
h1 {
441473
max-width: none;
442474
}
475+
476+
.freshness-actions {
477+
justify-content: flex-start;
478+
}
443479
}

0 commit comments

Comments
 (0)