375 lines
18 KiB
HTML
375 lines
18 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https: http: data: file:; style-src 'self' 'unsafe-inline';" />
|
||
<title>PeopleLib</title>
|
||
<link rel="stylesheet" href="style.css" />
|
||
<link rel="stylesheet" href="vendor/quill/quill.snow.css" />
|
||
<link rel="stylesheet" href="rich-note.css" />
|
||
</head>
|
||
<body>
|
||
<div class="titlebar">
|
||
<div class="titlebar-left">
|
||
<span class="brand">
|
||
<img class="brand-logo brand-logo-dark" src="../../icons/dist/dark/icon-32.png" alt="" />
|
||
<img class="brand-logo brand-logo-light" src="../../icons/dist/light/icon-32.png" alt="" />
|
||
<span>人民阅读器</span>
|
||
<span class="brand-sub">PeopleLib</span>
|
||
</span>
|
||
</div>
|
||
<nav class="tabs">
|
||
<button class="tab active" data-tab="library">我的书库</button>
|
||
<button class="tab" data-tab="notes">我的笔记</button>
|
||
<button class="tab" data-tab="browse">检索</button>
|
||
</nav>
|
||
<div class="titlebar-spacer"></div>
|
||
<div class="titlebar-controls">
|
||
<div class="task-center-wrap">
|
||
<button id="taskCenterBtn" class="win-btn task-center-btn" title="任务中心" aria-label="任务中心" aria-expanded="false" aria-controls="taskCenterPanel">
|
||
<svg class="titlebar-icon" viewBox="0 0 24 24" aria-hidden="true">
|
||
<path d="M6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z"></path>
|
||
<path d="M8 9h8M8 13h5M8 17h3"></path>
|
||
</svg>
|
||
<span id="taskCenterBadge" class="task-center-badge hidden">0</span>
|
||
</button>
|
||
<section id="taskCenterPanel" class="task-center-panel hidden" aria-label="下载任务">
|
||
<div class="task-center-head">
|
||
<div>
|
||
<div class="task-center-title">任务中心</div>
|
||
<div id="taskCenterSummary" class="task-center-summary">下载任务会显示在这里</div>
|
||
</div>
|
||
<button id="taskCenterClear" class="task-center-clear hidden">清除已结束</button>
|
||
</div>
|
||
<div id="taskCenterList" class="task-center-list"></div>
|
||
</section>
|
||
</div>
|
||
<button id="uiThemeBtn" class="win-btn ui-theme-btn" title="切换到明亮主题" aria-label="切换到明亮主题">
|
||
<svg class="titlebar-icon ui-theme-sun" viewBox="0 0 24 24" aria-hidden="true">
|
||
<circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.66 6.34l1.41-1.41"></path>
|
||
</svg>
|
||
<svg class="titlebar-icon ui-theme-moon" viewBox="0 0 24 24" aria-hidden="true">
|
||
<path d="M20 15.5A8.5 8.5 0 0 1 8.5 4 8.5 8.5 0 1 0 20 15.5Z"></path>
|
||
</svg>
|
||
</button>
|
||
<button class="win-btn tab" data-tab="settings" title="设置">⚙</button>
|
||
<button id="minBtn" class="win-btn" title="最小化">─</button>
|
||
<button id="maxBtn" class="win-btn" title="最大化">□</button>
|
||
<button id="closeBtn" class="win-btn win-close" title="关闭">✕</button>
|
||
</div>
|
||
</div>
|
||
|
||
<main id="main">
|
||
<!-- 我的书库 -->
|
||
<section id="libraryTab" class="tab-panel">
|
||
<div class="library-page">
|
||
<aside class="library-sidebar">
|
||
<div class="library-sidebar-head">
|
||
<h2>书架</h2>
|
||
<button id="addShelfBtn" class="notes-icon-btn" title="新建书架" aria-label="新建书架">+</button>
|
||
</div>
|
||
<div class="library-filter-list">
|
||
<button class="library-filter active" data-shelf="">全部书籍</button>
|
||
<button class="library-filter" data-shelf="__uncategorized__">未分类</button>
|
||
<div id="libraryShelfList" class="library-filter-list"></div>
|
||
</div>
|
||
<div class="library-sidebar-section">
|
||
<div class="library-sidebar-section-head">
|
||
<h3>标签</h3>
|
||
<button id="addTagBtn" class="notes-icon-btn" title="新建标签" aria-label="新建标签">+</button>
|
||
</div>
|
||
<div id="libraryTagList" class="library-filter-list"></div>
|
||
</div>
|
||
</aside>
|
||
<div class="library-content">
|
||
<div class="toolbar">
|
||
<div class="library-search" role="search">
|
||
<input id="librarySearchInput" type="search" placeholder="搜索标题或作者..." autocomplete="off" />
|
||
<button id="librarySearchBtn" class="tb-btn">搜索</button>
|
||
<button id="libraryClearSearchBtn" class="tb-btn ghost hidden">清除</button>
|
||
</div>
|
||
<span id="libStatus" class="status-bar"></span>
|
||
<div class="spacer"></div>
|
||
<button id="librarySelectModeBtn" class="tb-btn ghost" aria-pressed="false">选择</button>
|
||
<button id="rescanBtn" class="tb-btn ghost">重新扫描</button>
|
||
<button id="addLocalBtn" class="tb-btn">+ 添加本地</button>
|
||
</div>
|
||
<div id="librarySelectionBar" class="library-selection-bar hidden">
|
||
<label class="library-select-all">
|
||
<input type="checkbox" id="librarySelectAll" />
|
||
<span id="librarySelectAllLabel">全选</span>
|
||
</label>
|
||
<span id="librarySelectionCount" class="status-bar">未选择</span>
|
||
<div class="spacer"></div>
|
||
<button id="libraryBulkOrganizeBtn" class="tb-btn ghost" disabled>批量整理</button>
|
||
<button id="libraryBulkRemoveBtn" class="tb-btn danger" disabled>批量移除</button>
|
||
<button id="librarySelectExitBtn" class="tb-btn ghost">退出选择</button>
|
||
</div>
|
||
<div id="libGrid" class="grid"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 我的笔记 -->
|
||
<section id="notesTab" class="tab-panel hidden">
|
||
<div class="notes-page">
|
||
<aside class="notes-sidebar">
|
||
<div class="notes-sidebar-head">
|
||
<h2>笔记本</h2>
|
||
<button id="addCollectionBtn" class="notes-icon-btn" title="新建笔记本" aria-label="新建笔记本">+</button>
|
||
</div>
|
||
<button class="notes-collection active" data-collection="">全部笔记</button>
|
||
<button class="notes-collection" data-collection="__uncategorized__">未分类</button>
|
||
<div id="notesCollectionList"></div>
|
||
</aside>
|
||
<div class="notes-content">
|
||
<div class="notes-toolbar">
|
||
<div class="notes-search">
|
||
<input id="notesSearchInput" type="search" placeholder="搜索笔记、摘录或书名..." autocomplete="off" />
|
||
<button id="notesSearchBtn" class="tb-btn">搜索</button>
|
||
<button id="notesClearSearchBtn" class="tb-btn ghost hidden">清除</button>
|
||
</div>
|
||
<select id="notesSourceSelect" class="source-select" aria-label="按来源筛选">
|
||
<option value="">全部来源</option>
|
||
</select>
|
||
<button id="addGlobalNoteBtn" class="tb-btn">+ 新建笔记</button>
|
||
</div>
|
||
<div id="notesTypeTabs" class="notes-type-tabs" role="tablist" aria-label="笔记类型">
|
||
<button class="notes-type-tab active" data-note-type="" role="tab" aria-selected="true">全部</button>
|
||
<button class="notes-type-tab" data-note-type="canvas" role="tab" aria-selected="false">画布笔记</button>
|
||
<button class="notes-type-tab" data-note-type="reading" role="tab" aria-selected="false">读书笔记</button>
|
||
</div>
|
||
<div id="notesTagFilters" class="notes-tag-filters hidden"></div>
|
||
<div id="notesStatus" class="status-bar"></div>
|
||
<div id="notesList" class="notes-list"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 检索 -->
|
||
<section id="browseTab" class="tab-panel hidden">
|
||
<div id="browseGridView">
|
||
<div class="browse-head">
|
||
<div class="toolbar">
|
||
<select id="sourceSelect" class="source-select"></select>
|
||
<div class="search-inline">
|
||
<input id="searchInput" type="text" placeholder="搜索标题 / 作者 / 关键词..." />
|
||
<button id="searchBtn" class="tb-btn">搜索</button>
|
||
<button id="clearSearchBtn" class="tb-btn ghost hidden">✕ 清除</button>
|
||
</div>
|
||
</div>
|
||
<div id="statusBar" class="status-bar"></div>
|
||
</div>
|
||
<div id="grid" class="grid"></div>
|
||
<div id="pager" class="pager hidden">
|
||
<button id="prevBtn" class="page-btn">← 上一页</button>
|
||
<span id="pageInfo" class="page-info"></span>
|
||
<button id="nextBtn" class="page-btn">下一页 →</button>
|
||
<span class="page-jump">
|
||
跳转到
|
||
<input id="jumpInput" type="number" min="1" class="jump-input" />
|
||
<button id="jumpBtn" class="page-btn">跳转</button>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<div id="detailView" class="hidden">
|
||
<button id="backBtn" class="back-btn" aria-label="返回">← 返回</button>
|
||
<div id="detailContent"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 设置 -->
|
||
<section id="settingsTab" class="tab-panel hidden">
|
||
<div class="settings-page">
|
||
<h2 class="settings-title">设置</h2>
|
||
<div class="settings-group">
|
||
<div class="settings-item settings-item-block">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">数据源管理</div>
|
||
<div class="settings-item-desc">选择在检索页显示的数据源</div>
|
||
</div>
|
||
<div id="sourceList" class="source-list"></div>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">书库目录</div>
|
||
<div class="settings-item-desc">元数据、下载文件与封面都存放在此目录;启动时自动扫描 files 子目录导入新书</div>
|
||
<div class="settings-path" id="libDirPath">-</div>
|
||
</div>
|
||
<button id="libDirPickBtn" class="tb-btn">更改</button>
|
||
<button id="libDirOpenBtn" class="tb-btn ghost">打开</button>
|
||
</div>
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">下载前询问保存位置</div>
|
||
<div class="settings-item-desc">关闭时直接存入书库目录并自动入库;开启则每次弹出另存为对话框</div>
|
||
</div>
|
||
<label class="switch"><input type="checkbox" id="askSaveChk" /></label>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">书库默认排序</div>
|
||
<div class="settings-item-desc">控制书库条目的排列顺序</div>
|
||
</div>
|
||
<select id="sortSelect" class="source-select">
|
||
<option value="recent">最近阅读</option>
|
||
<option value="added">添加时间</option>
|
||
<option value="title">标题</option>
|
||
<option value="author">作者</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">网络代理</div>
|
||
<div class="settings-item-desc">对所有数据源与下载统一生效;访问 LibGen / Z-Library 通常需要代理(留空表示直连)</div>
|
||
</div>
|
||
<input id="proxyInput" class="settings-input" type="text" placeholder="留空表示直连,例如 http://localhost:7897" />
|
||
<button id="proxySaveBtn" class="tb-btn">保存</button>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">残留阅读资料</div>
|
||
<div class="settings-item-desc">书籍移除时默认保留笔记、批注与进度。笔记仍可在「我的笔记」中查看,批注则没有查看入口。</div>
|
||
<div class="settings-path" id="orphanStatus">未检查</div>
|
||
</div>
|
||
<button id="orphanScanBtn" class="tb-btn">检查</button>
|
||
<button id="orphanPurgeBtn" class="tb-btn danger hidden">清理</button>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">Semantic Scholar API Key</div>
|
||
<div class="settings-item-desc" id="semanticKeyStatus">未配置(匿名请求容易被限流)</div>
|
||
</div>
|
||
<input id="semanticKeyInput" class="settings-input" type="password" placeholder="可选 API Key" autocomplete="off" />
|
||
<button id="semanticKeySaveBtn" class="tb-btn">保存</button>
|
||
<button id="semanticKeyClearBtn" class="tb-btn ghost hidden">清除</button>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item settings-item-block">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">阅读器 AI 助手</div>
|
||
<div class="settings-item-desc" id="aiStatus">未配置</div>
|
||
</div>
|
||
<div class="ai-form">
|
||
<label class="ai-row">
|
||
<span>接口类型</span>
|
||
<select id="aiProtocol" class="settings-input ai-protocol">
|
||
<option value="anthropic">Anthropic 接口(/v1/messages)</option>
|
||
<option value="openai-responses">OpenAI 接口(/v1/responses)</option>
|
||
<option value="chat-completions">OpenAI 兼容接口(/v1/chat/completions)</option>
|
||
</select>
|
||
</label>
|
||
<label class="ai-row">
|
||
<span>接口地址</span>
|
||
<input id="aiBaseUrl" class="settings-input" type="text" placeholder="https://api.openai.com/v1" autocomplete="off" />
|
||
</label>
|
||
<label class="ai-row">
|
||
<span>模型名称</span>
|
||
<input id="aiModel" class="settings-input" type="text" placeholder="gpt-4o-mini" autocomplete="off" />
|
||
</label>
|
||
<label class="ai-row">
|
||
<span>API Key</span>
|
||
<input id="aiKey" class="settings-input" type="password" placeholder="本地模型可留空" autocomplete="off" />
|
||
</label>
|
||
<label class="ai-row ai-vision-row">
|
||
<span>图像输入</span>
|
||
<input id="aiVision" type="checkbox" />
|
||
<small>仅在模型明确支持图片时开启</small>
|
||
</label>
|
||
<div class="ai-row ai-actions">
|
||
<span id="aiProtocolHint" class="ai-hint">服务地址填写到版本根路径,PeopleLib 会按接口类型调用对应端点。</span>
|
||
<button id="aiSaveBtn" class="tb-btn">保存</button>
|
||
<button id="aiClearBtn" class="tb-btn ghost hidden">清除</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">Z-Library 账号</div>
|
||
<div class="settings-item-desc" id="zlibStatus">未登录</div>
|
||
</div>
|
||
<button id="zlibLoginBtn" class="tb-btn">登录</button>
|
||
<button id="zlibLogoutBtn" class="tb-btn ghost hidden">退出</button>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group">
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">检查更新</div>
|
||
<div class="settings-item-desc">当前版本 <span id="appVersion">-</span> · <span id="updateStatus">从 GitHub 获取最新版本</span></div>
|
||
</div>
|
||
<button id="checkUpdateBtn" class="tb-btn">检查更新</button>
|
||
</div>
|
||
<div class="settings-item">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">启动时自动检查更新</div>
|
||
<div class="settings-item-desc">发现新版本后可前往 GitHub Releases 下载二进制文件</div>
|
||
</div>
|
||
<label class="switch">
|
||
<input type="checkbox" id="autoCheckUpdate" />
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="settings-group" aria-label="关于 PeopleLib">
|
||
<div class="settings-item settings-item-block">
|
||
<div class="settings-item-info">
|
||
<div class="settings-item-label">关于 PeopleLib</div>
|
||
<div class="settings-item-desc">人民阅读器支持的本地图书格式</div>
|
||
</div>
|
||
<div class="about-formats">
|
||
<div>
|
||
<span class="about-format-label">内置阅读</span>
|
||
<span>PDF、EPUB、MOBI、AZW、AZW3、TXT、MD</span>
|
||
</div>
|
||
<div>
|
||
<span class="about-format-label">书库导入与管理</span>
|
||
<span>PDF、EPUB、MOBI、AZW、AZW3、TXT、MD、DJVU、FB2、CBZ、CBR</span>
|
||
</div>
|
||
<div class="settings-item-desc">
|
||
MOBI、AZW 与 AZW3 由 Foliate 解析,支持无 DRM 的 MOBI/KF7/KF8 内容;DRM、KFX 与损坏文件可改用系统应用打开。
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- 通用弹窗 -->
|
||
<div id="modal" class="modal hidden">
|
||
<div class="modal-box">
|
||
<div id="modalTitle" class="modal-title"></div>
|
||
<div id="modalBody" class="modal-body"></div>
|
||
<div class="modal-actions">
|
||
<button id="modalCancel" class="tb-btn ghost">取消</button>
|
||
<button id="modalOk" class="tb-btn">确定</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="util.js"></script>
|
||
<script src="download-center.js"></script>
|
||
<script src="views/browse.js"></script>
|
||
<script src="views/library.js"></script>
|
||
<script src="vendor/quill/quill.js"></script>
|
||
<script src="vendor/jspdf.umd.min.js"></script>
|
||
<script src="rich-note.js"></script>
|
||
<script src="mixed-note.js"></script>
|
||
<script src="views/notes.js"></script>
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|