feat: add /sub/clash/latest and /sub/singbox/latest public subscription APIs and display them on the web dashboard UI
This commit is contained in:
@@ -262,6 +262,32 @@
|
||||
<div class="muted" id="summary">正在加载...</div>
|
||||
</div>
|
||||
</header>
|
||||
<div style="padding: 20px 24px; border-bottom: 1px solid var(--line); background: #fafbfc; display: flex; flex-direction: column; gap: 12px;">
|
||||
<h3 style="margin: 0; font-size: 0.95rem; font-weight: 700; color: #374151;">最新订阅地址 (无Token/持久链接)</h3>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 16px;">
|
||||
<div style="flex: 1; min-width: 280px; display: flex; align-items: center; justify-content: space-between; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 10px 14px;">
|
||||
<div style="display: flex; flex-direction: column; gap: 4px;">
|
||||
<span style="font-size: 0.78rem; font-weight: 750; color: var(--primary); text-transform: uppercase;">Clash (YAML)</span>
|
||||
<span style="font-size: 0.85rem; font-family: monospace; color: var(--muted); word-break: break-all;" id="latest-clash-link">加载中...</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 8px; align-items: center;">
|
||||
<button type="button" class="btn btn-secondary" onclick="copyLatestLink('clash')">复制</button>
|
||||
<a class="btn btn-green" id="latest-clash-import" href="#">导入 Clash</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="flex: 1; min-width: 280px; display: flex; align-items: center; justify-content: space-between; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 10px 14px;">
|
||||
<div style="display: flex; flex-direction: column; gap: 4px;">
|
||||
<span style="font-size: 0.78rem; font-weight: 750; color: var(--primary); text-transform: uppercase;">Sing-box (JSON)</span>
|
||||
<span style="font-size: 0.85rem; font-family: monospace; color: var(--muted); word-break: break-all;" id="latest-singbox-link">加载中...</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 8px; align-items: center;">
|
||||
<button type="button" class="btn btn-secondary" onclick="copyLatestLink('singbox')">复制</button>
|
||||
<a class="btn btn-primary" id="latest-singbox-import" href="#">导入 Sing-box</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -339,6 +365,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
let latestClashUrl = '';
|
||||
let latestSingboxUrl = '';
|
||||
|
||||
function updateLatestUrls() {
|
||||
const clientOrigin = getClientImportOrigin();
|
||||
latestClashUrl = `${clientOrigin}/sub/clash/latest`;
|
||||
latestSingboxUrl = `${clientOrigin}/sub/singbox/latest`;
|
||||
|
||||
const clashLinkEl = document.getElementById('latest-clash-link');
|
||||
const singboxLinkEl = document.getElementById('latest-singbox-link');
|
||||
if (clashLinkEl) clashLinkEl.textContent = latestClashUrl;
|
||||
if (singboxLinkEl) singboxLinkEl.textContent = latestSingboxUrl;
|
||||
|
||||
const clashImportEl = document.getElementById('latest-clash-import');
|
||||
const singboxImportEl = document.getElementById('latest-singbox-import');
|
||||
if (clashImportEl) {
|
||||
clashImportEl.href = `clash://install-config?url=${encodeURIComponent(latestClashUrl)}&name=${encodeURIComponent('CatMata-Latest')}`;
|
||||
}
|
||||
if (singboxImportEl) {
|
||||
singboxImportEl.href = `sing-box://import-remote-profile?url=${encodeURIComponent(latestSingboxUrl)}#${encodeURIComponent('CatMata-Latest')}`;
|
||||
}
|
||||
}
|
||||
|
||||
function copyLatestLink(type) {
|
||||
const link = type === 'clash' ? latestClashUrl : latestSingboxUrl;
|
||||
copyLinkToClipboard(link);
|
||||
}
|
||||
|
||||
|
||||
async function loadAppConfig() {
|
||||
try {
|
||||
const res = await fetch('/api/app-config', { credentials: 'same-origin' });
|
||||
@@ -469,6 +524,7 @@
|
||||
|
||||
(async function init() {
|
||||
await loadAppConfig();
|
||||
updateLatestUrls();
|
||||
if (await checkSession()) {
|
||||
showHistory();
|
||||
await loadHistory();
|
||||
|
||||
Reference in New Issue
Block a user