feat: 完善本地书库与发布更新流程
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
parent
de3e1d8a44
commit
b8c8d24107
+29
-7
@@ -13,9 +13,21 @@ const Library = (() => {
|
||||
grid = $('libGrid');
|
||||
statusEl = $('libStatus');
|
||||
$('addLocalBtn').onclick = addLocal;
|
||||
$('rescanBtn').onclick = rescan;
|
||||
window.api.library.onChanged(() => { dirty = true; refresh(true); });
|
||||
}
|
||||
|
||||
async function rescan() {
|
||||
const btn = $('rescanBtn');
|
||||
btn.disabled = true;
|
||||
btn.textContent = '扫描中...';
|
||||
const r = await window.api.library.scan();
|
||||
btn.textContent = r.ok && r.data && r.data.added ? `新增 ${r.data.added} 本 ✓` : '已是最新 ✓';
|
||||
dirty = true;
|
||||
await refresh(true);
|
||||
setTimeout(() => { btn.textContent = '重新扫描'; btn.disabled = false; }, 2000);
|
||||
}
|
||||
|
||||
function getSortMode() { return sortMode; }
|
||||
function setSortMode(m) {
|
||||
sortMode = m;
|
||||
@@ -30,16 +42,20 @@ const Library = (() => {
|
||||
dirty = false;
|
||||
if (!res.ok) { statusEl.textContent = '加载失败:' + res.error; return; }
|
||||
const items = res.data.slice().sort(SORTERS[sortMode] || SORTERS.added);
|
||||
statusEl.textContent = `共 ${items.length} 条`;
|
||||
const missingCount = items.filter((it) => it.missing).length;
|
||||
statusEl.textContent = `共 ${items.length} 条` + (missingCount ? `,${missingCount} 条文件缺失` : '');
|
||||
if (!items.length) {
|
||||
grid.innerHTML = '<div class="empty">书库为空,去「检索」页添加文献 / 图书吧</div>';
|
||||
return;
|
||||
}
|
||||
grid.innerHTML = items.map((it) => {
|
||||
const hasFile = (it.files || []).some((f) => f.path);
|
||||
const badge = hasFile
|
||||
// exists 由主进程按实际磁盘状态给出:文件被手动删掉时要如实反映
|
||||
const openable = (it.files || []).some((f) => f.exists);
|
||||
const badge = openable
|
||||
? '<span class="card-badge">已下载</span>'
|
||||
: '<span class="card-badge miss">未下载</span>';
|
||||
: ((it.files || []).length
|
||||
? '<span class="card-badge miss">文件缺失</span>'
|
||||
: '<span class="card-badge miss">未下载</span>');
|
||||
return `
|
||||
<div class="card" data-id="${escapeHtml(it.id)}">
|
||||
<div class="card-cover" style="${coverStyle(it.cover)}">${it.cover ? '' : `<div class="ph">${escapeHtml(it.title)}</div>`}</div>
|
||||
@@ -47,7 +63,8 @@ const Library = (() => {
|
||||
${(it.authors && it.authors.length) ? `<div class="card-sub">${escapeHtml(it.authors.slice(0, 2).join(', '))}</div>` : ''}
|
||||
${badge}
|
||||
<div class="lib-card-actions">
|
||||
<button class="open-btn" data-act="open" ${hasFile ? '' : 'disabled'}>打开</button>
|
||||
<button class="open-btn" data-act="open" ${openable ? '' : 'disabled'}>打开</button>
|
||||
${openable ? '<button data-act="reveal">定位</button>' : ''}
|
||||
${it.url ? '<button data-act="page">页面</button>' : ''}
|
||||
<button data-act="remove">移除</button>
|
||||
</div>
|
||||
@@ -67,8 +84,13 @@ const Library = (() => {
|
||||
if (!res.ok || !res.data) return;
|
||||
const it = res.data;
|
||||
if (act === 'open') {
|
||||
const f = (it.files || []).find((x) => x.path);
|
||||
if (f) window.api.openPath(f.path);
|
||||
const f = (it.files || []).find((x) => x.exists) || (it.files || [])[0];
|
||||
if (!f) return;
|
||||
const r = await window.api.openPath(f.path);
|
||||
if (!r.ok) await confirmModal('打开失败', r.error || '无法打开该文件');
|
||||
} else if (act === 'reveal') {
|
||||
const f = (it.files || []).find((x) => x.exists);
|
||||
if (f) window.api.showItem(f.path);
|
||||
} else if (act === 'page') {
|
||||
if (it.url) window.api.openExternal(it.url);
|
||||
} else if (act === 'remove') {
|
||||
|
||||
Reference in New Issue
Block a user