feat: 内置阅读器、批注笔记与 AI 助手,发布 1.3.0
新增 PDF/EPUB/MOBI/AZW 内置阅读器,PDF 分段读取支持超大文件, 批注、读书与画布笔记、封面生成与本地导入。AI 助手支持三种协议、 图像上下文与安全 Markdown 渲染,上下文范围改为 选中/当前页/全文, 页面与全文无需选中文本即可发送,全文会提示可能超出模型限制。 便携版输出目录固定为 PeopleLib-windows-x64,不再随版本号变化, 避免升级后 data/ 被遗留在旧目录。 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
b8c8d24107
commit
3ccd044527
@@ -0,0 +1,77 @@
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { app, BrowserWindow } = require('electron');
|
||||
|
||||
const ROOT = path.resolve(__dirname, '..', '..', '..');
|
||||
const TMP = fs.mkdtempSync(path.join(os.tmpdir(), 'peoplelib-startup-ui-'));
|
||||
app.setPath('appData', TMP);
|
||||
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';
|
||||
|
||||
const results = [];
|
||||
function check(name, pass, detail) {
|
||||
results.push([pass ? 'OK' : 'FAIL', name, detail || '']);
|
||||
}
|
||||
|
||||
async function waitUntil(fn, timeout = 10000) {
|
||||
const end = Date.now() + timeout;
|
||||
while (Date.now() < end) {
|
||||
try {
|
||||
const value = await fn();
|
||||
if (value) return value;
|
||||
} catch (e) { /* 窗口仍在加载 */ }
|
||||
await new Promise((resolve) => setTimeout(resolve, 25));
|
||||
}
|
||||
throw new Error(`等待条件超时(${timeout}ms)`);
|
||||
}
|
||||
|
||||
function printSummary() {
|
||||
console.log('\n========== 启动响应集成验证 ==========');
|
||||
for (const [status, name, detail] of results) {
|
||||
console.log(`${status.padEnd(5)} ${name}${detail ? ` [${detail}]` : ''}`);
|
||||
}
|
||||
const failed = results.filter((item) => item[0] === 'FAIL').length;
|
||||
console.log(`\n通过 ${results.length - failed}/${results.length}`);
|
||||
return failed;
|
||||
}
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
const library = require(path.join(ROOT, 'src', 'library', 'store'));
|
||||
let scanStartedAt = 0;
|
||||
library.scan = () => {
|
||||
scanStartedAt = Date.now();
|
||||
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 2200);
|
||||
return { added: 0, missing: 0, total: 0 };
|
||||
};
|
||||
|
||||
const startedAt = Date.now();
|
||||
require(path.join(ROOT, 'main.js'));
|
||||
const win = await waitUntil(() => (
|
||||
BrowserWindow.getAllWindows().find((item) => item.getTitle() === 'PeopleLib')
|
||||
));
|
||||
win.hide();
|
||||
await waitUntil(() => win.webContents.executeJavaScript(
|
||||
`document.readyState === 'complete'
|
||||
&& ['dark', 'light'].includes(document.documentElement.dataset.uiTheme)`
|
||||
));
|
||||
const configReadyMs = Date.now() - startedAt;
|
||||
check('慢速书库扫描不会阻塞窗口配置加载', configReadyMs < 1200, `${configReadyMs}ms`);
|
||||
|
||||
await waitUntil(() => scanStartedAt > 0, 7000);
|
||||
check('启动维护在首屏完成后延迟执行', scanStartedAt - startedAt >= 1400,
|
||||
`${scanStartedAt - startedAt}ms`);
|
||||
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
if (!window.isDestroyed()) window.destroy();
|
||||
}
|
||||
const failed = printSummary();
|
||||
app.exit(failed ? 1 : 0);
|
||||
}).catch((error) => {
|
||||
console.error('异常:', error);
|
||||
check('启动验证未发生异常', false, error.message || String(error));
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
if (!window.isDestroyed()) window.destroy();
|
||||
}
|
||||
printSummary();
|
||||
app.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user