feat(前端界面): WebUI新增字体目录导入,支持子目录识别和加载进度,保留多文件选择
build.yaml / build (push) Successful in 37s

This commit is contained in:
xiaoqidun committed 2026-09-08 09:13:28 +08:00
1 parent 2a022ba73e
commit aa860a1402
2 files changed
+34 -10

No files matched your search

+2
View File
@@ -11,6 +11,7 @@
<header class="toolbar app-bar">
<input id="ofdInput" class="file-input" type="file" accept=".ofd">
<input id="fontInput" class="file-input" type="file" accept=".ttf,.otf,.ttc,font/*" multiple>
<input id="fontDirectoryInput" class="file-input" type="file" webkitdirectory multiple>
<div class="tool-group">
<button id="ofdButton" class="button primary" type="button" data-short="打开" aria-label="打开">打开</button>
<button id="togglePagesButton" class="icon-button" type="button" title="页面栏" aria-label="页面栏" aria-pressed="true">&#9776;</button>
@@ -116,6 +117,7 @@
<span id="availableFontSummary" class="count-pill">0</span>
<button id="localFontButton" class="small-button" type="button">系统字体</button>
<button id="fontAddButton" class="small-button" type="button">添加</button>
<button id="fontDirectoryButton" class="small-button" type="button" title="添加字体目录" aria-label="添加字体目录">目录</button>
</div>
</div>
<div id="fontPermissionHint" class="font-permission-hint" hidden>需授权读取系统字体</div>
+32 -10
View File
@@ -83,9 +83,11 @@ const el = {
ofdInput: document.querySelector("#ofdInput"),
ofdButton: document.querySelector("#ofdButton"),
fontInput: document.querySelector("#fontInput"),
fontDirectoryInput: document.querySelector("#fontDirectoryInput"),
togglePagesButton: document.querySelector("#togglePagesButton"),
toggleMetaButton: document.querySelector("#toggleMetaButton"),
fontAddButton: document.querySelector("#fontAddButton"),
fontDirectoryButton: document.querySelector("#fontDirectoryButton"),
localFontButton: document.querySelector("#localFontButton"),
prevButton: document.querySelector("#prevButton"),
nextButton: document.querySelector("#nextButton"),
@@ -131,10 +133,12 @@ const el = {
el.ofdButton.addEventListener("click", openOFDFile);
el.togglePagesButton.addEventListener("click", () => toggleSidebar("pages"));
el.toggleMetaButton.addEventListener("click", () => toggleSidebar("meta"));
el.fontAddButton.addEventListener("click", openFontFile);
el.fontAddButton.addEventListener("click", () => openFontFile(el.fontInput));
el.fontDirectoryButton.addEventListener("click", () => openFontFile(el.fontDirectoryInput));
el.localFontButton.addEventListener("click", loadLocalFonts);
el.ofdInput.addEventListener("change", openSelectedOFD);
el.fontInput.addEventListener("change", openSelectedFonts);
el.fontDirectoryInput.addEventListener("change", openSelectedFonts);
el.prevButton.addEventListener("click", () => renderPage(state.pageIndex - 1));
el.nextButton.addEventListener("click", () => renderPage(state.pageIndex + 1));
el.zoomOutButton.addEventListener("click", () => setScale(state.scale - 0.1));
@@ -158,6 +162,7 @@ el.viewerPanel.addEventListener("scroll", () => {
});
el.viewerPanel.addEventListener("dblclick", openOFDFromViewer);
el.fontDirectoryButton.disabled = !("webkitdirectory" in el.fontDirectoryInput);
updateSidebarState();
boot();
@@ -177,9 +182,9 @@ async function openOFDFromViewer() {
await openOFDFile();
}
function openFontFile() {
el.fontInput.value = "";
el.fontInput.click();
function openFontFile(input) {
input.value = "";
input.click();
}
function toggleSidebar(side) {
@@ -400,17 +405,34 @@ function isOFDFile(file) {
return /\.ofd$/i.test(file.name || "");
}
async function openSelectedFonts() {
const files = Array.from(el.fontInput.files || []);
async function openSelectedFonts(event) {
const input = event.currentTarget;
const files = Array.from(input.files || []).filter((file) => (
!input.webkitdirectory || /\.(ttf|otf|ttc)$/i.test(file.name)
));
input.value = "";
if (!files.length) {
setStatus("未发现字体文件");
return;
}
const fonts = await Promise.all(files.map(async (file) => (
createFontRecord(file.name, new Uint8Array(await file.arrayBuffer()), "upload")
)));
setBusy(true, "正在读取字体", 10, STATUS.fonts);
try {
const fonts = [];
for (let i = 0; i < files.length; i += 1) {
setProgress(`正在读取字体 ${i + 1}/${files.length}`, 10 + Math.round(i / files.length * 60));
const file = files[i];
fonts.push(createFontRecord(file.name, new Uint8Array(await file.arrayBuffer()), "upload"));
}
state.userFonts.push(...fonts);
el.fontInput.value = "";
await applyFontChange();
if (!state.doc) {
setStatus(`已添加 ${fonts.length} 个字体`);
}
} catch (err) {
showError(err, false);
} finally {
setBusy(false);
}
}
async function loadLocalFonts() {