d4bf3627fd
新增运动节拍RepClock全套小程序页面、后端API与数据库服务,新增subhub子工具汇总页面,优化全局主页样式与配置,为web静态资源添加版本缓存参数,补充配套调试脚本
85 lines
2.7 KiB
JavaScript
85 lines
2.7 KiB
JavaScript
(function () {
|
||
const api = window.__MPTA_API__
|
||
const $grid = document.getElementById('kit-grid')
|
||
const $status = document.getElementById('status-tag')
|
||
|
||
const KIT_PAGES = {
|
||
personal_collect: 'kits/personal_collect/list.html',
|
||
rep_clock: 'kits/rep_clock/cards.html',
|
||
}
|
||
|
||
const KIT_ICONS = {
|
||
personal_collect: '📁',
|
||
rep_clock: '⏱️',
|
||
}
|
||
|
||
const HERO_EMOJI = '🧘'
|
||
const HERO_TITLE = '每一次节奏,都是一次呼吸。'
|
||
const HERO_DESC = '独立工具集合,互不干扰,可独立部署,可独立关闭。'
|
||
|
||
function setStatus(text, cls) {
|
||
$status.textContent = text
|
||
$status.className = 'status-tag' + (cls ? ' ' + cls : '')
|
||
}
|
||
|
||
function escapeHtml(s) {
|
||
if (s === null || s === undefined) return ''
|
||
return String(s)
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"')
|
||
.replace(/'/g, ''')
|
||
}
|
||
|
||
function renderKits(kits) {
|
||
if (!kits || !kits.length) {
|
||
$grid.innerHTML = '<div class="kit-empty">暂无可用工具</div>'
|
||
return
|
||
}
|
||
$grid.innerHTML = kits.map((kit) => {
|
||
const page = KIT_PAGES[kit.id] || '#'
|
||
const icon = kit.icon || KIT_ICONS[kit.id] || '🧰'
|
||
const meta = kit.meta ? `<div class="kit-meta">${escapeHtml(kit.meta)}</div>` : ''
|
||
return (
|
||
`<div class="kit-card" data-kit="${escapeHtml(kit.id)}" data-page="${escapeHtml(page)}">` +
|
||
`<div class="kit-icon">${icon}</div>` +
|
||
`<div class="kit-body">` +
|
||
`<div class="kit-name">${escapeHtml(kit.name || kit.id)}</div>` +
|
||
`<div class="kit-desc">${escapeHtml(kit.description || '')}</div>` +
|
||
meta +
|
||
`</div>` +
|
||
`<div class="chevron">›</div>` +
|
||
`</div>`
|
||
)
|
||
}).join('')
|
||
Array.from($grid.querySelectorAll('.kit-card')).forEach((card) => {
|
||
card.addEventListener('click', () => {
|
||
const page = card.getAttribute('data-page')
|
||
const kitId = card.getAttribute('data-kit')
|
||
const go = () => { window.location.href = page }
|
||
if (api && api.hub && api.hub.setActiveKit) {
|
||
api.hub.setActiveKit(kitId).then(go).catch(go)
|
||
} else {
|
||
go()
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
async function main() {
|
||
try {
|
||
if (!api || !api.hub) throw new Error('API 未加载')
|
||
const meta = await api.hub.meta()
|
||
const kits = (meta && meta.kits) || []
|
||
setStatus('后端已连通', 'ok')
|
||
renderKits(kits)
|
||
} catch (e) {
|
||
setStatus('后端连通失败:' + (e.message || '未知错误'), 'err')
|
||
$grid.innerHTML = `<div class="kit-empty">❌ 加载失败:${escapeHtml(e.message || '后端无响应')}</div>`
|
||
}
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', main)
|
||
})()
|