vitepress-plugin-filelist 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,8 @@
6
6
 
7
7
  - 📁 树形目录,文件夹按需加载
8
8
  - ✅ 勾选文件;选中文件夹会自动加载并选中其下所有层级的文件
9
- - 📦 批量打包 ZIP(基于 `fflate`),带进度;保留目录结构,不同目录的同名文件不会互相覆盖
9
+ - 📦 批量打包 ZIP(基于 `client-zip`),带进度、可取消;Chrome / Edge 边下载边写入磁盘,不受大小限制;保留目录结构,不同目录的同名文件不会互相覆盖
10
+ - 📄 大目录每个文件夹先显示 200 条,可“显示更多 / 全部显示”
10
11
  - ⬇️ 单文件下载(`fs/get` 的 `raw_url`,回退 `/d/`)
11
12
  - 👁️ 弹窗预览(不跳转):图片、音视频、文本、PDF;Office 等其它类型显示文件信息与下载
12
13
  - 🔐 目录密码输入,可选只读 token
@@ -81,6 +82,9 @@ export default {
81
82
  | `token` | `string` | `''` | 可选只读 token;不传则以游客身份请求 |
82
83
  | `password` | `string` | `''` | 目录密码,也可以在运行时输入 |
83
84
  | `rememberPassword` | `boolean` | `true` | 输入密码时是否提供“在此标签页中记住”开关;`false` 时不写入 sessionStorage |
85
+ | `pageSize` | `number` | `200` | 每个文件夹先显示的条数,之后显示“显示更多 / 全部显示”;`0` 全部显示 |
86
+ | `zipWarnSize` | `number` | `500`(触屏 `200`) | 需在内存中打包的浏览器(Firefox、Safari)超过该大小(MB)先确认;`0` 不提示 |
87
+ | `zipMaxSize` | `number` | `2048`(触屏 `1024`) | 同上,超过该大小(MB)不打包;`0` 不限制 |
84
88
  | `title` | `string` | `''` | 工具栏标题;为空时回退到 OpenList 的 `site_title` |
85
89
  | `locale` | `'zh-CN' \| 'en-US'` | `'zh-CN'` | 内置文案预设 |
86
90
  | `labels` | `Partial<FileListLabels>` | `undefined` | 按 key 覆盖单条文案 |
@@ -126,6 +130,19 @@ interface FileListSource {
126
130
  - 勾选后操作条吸附在组件顶部,位于 VitePress 导航栏 / “On this page” 栏下方,只在本组件范围内吸附
127
131
  - 颜色全部取自 VitePress 主题变量,暗色模式自动适配
128
132
 
133
+ ## 批量下载
134
+
135
+ - Chrome / Edge(含较新的 Android Chrome):点“下载 ZIP”先弹出系统“另存为”窗口,之后边下载边写入,内存占用很小,不受大小限制
136
+ - Firefox、Safari、iPhone:浏览器只能先把文件放进内存再打包。按已选总大小判断:超过 `zipWarnSize` 先确认,超过 `zipMaxSize` 不打包并建议分批
137
+ - 打包期间操作条显示进度(大小与文件数),可随时取消;勾选暂时锁定。任一文件失败会整体取消并提示文件名
138
+ - ZIP 只存储不压缩(网盘文件多为已压缩格式),支持超过 4 GB(Zip64)
139
+
140
+ ## 大目录
141
+
142
+ - 每个文件夹(以及单路径模式的顶层列表)先显示 `pageSize` 条,末尾一行“还有 X 项 · 显示更多 · 全部显示”;剩余不足一页时只显示“显示剩余 X 项”
143
+ - 数据一次全部取回,只减少渲染:排序后再截取,勾选文件夹 / 全选包含未显示的文件,输入筛选词时显示全部匹配
144
+ - 刷新后保留已展开的条数
145
+
129
146
  ## 刷新与目录密码
130
147
 
131
148
  - **刷新**:保留当前列表并调暗,表头下方显示进度条;完成后整体替换,已展开的目录和仍存在的勾选会保留。刷新失败时保留旧数据并提示。刷新只重新读取 OpenList 的目录缓存(游客没有写权限,无法强制刷新存储)
@@ -203,7 +220,7 @@ import { fileListLocales, formatLabel, resolveLabels } from 'vitepress-plugin-fi
203
220
  | 入口 | 内容 |
204
221
  | --- | --- |
205
222
  | `vitepress-plugin-filelist` | `fileList` 插件(默认导出) |
206
- | `vitepress-plugin-filelist/client` | `FileList`、`VPFileList`、`enhanceAppWithFileList`、类型 |
223
+ | `vitepress-plugin-filelist/client` | `FileList`、`VPFileList`、`enhanceAppWithFileList`、文案工具(`fileListLocales`、`formatLabel`、`resolveLabels`)、格式与文件类型工具(`formatSize`、`formatDate`、`fileKind`、`previewKind` 等)、类型 |
207
224
  | `vitepress-plugin-filelist/style.css` | 组件样式 |
208
225
 
209
226
  ## 兼容性
@@ -237,11 +254,25 @@ Deno 可以安装 npm 依赖,但目前用 Deno 构建 VitePress 会在 rolldow
237
254
  ```bash
238
255
  pnpm install
239
256
  pnpm run build # 生成 dist/node、dist/client/ssr、dist/client/browser、style.css
240
- pnpm run typecheck
241
- pnpm test # Vitest:utils、locale helpers、FileList 组件
257
+ pnpm run typecheck # vue-tsc,包含 .vue 模板与测试
258
+ pnpm test # Vitest:工具函数、密码、下载、FileList 组件
242
259
  pnpm run pack:check
243
260
  ```
244
261
 
262
+ 源码结构(`src/client`):
263
+
264
+ | 文件 | 职责 |
265
+ | --- | --- |
266
+ | `FileList.vue` | 组件:把下列模块接到界面 |
267
+ | `api.ts` | OpenList 接口、文件地址缓存、错误判断 |
268
+ | `demo.ts` | 演示数据(与 `api.ts` 同一接口) |
269
+ | `tree.ts` | 树节点、排序、目录统计 |
270
+ | `usePasswords.ts` / `passwords.ts` | 目录密码的选择顺序 / 标签页内记住 |
271
+ | `download.ts` | 单文件下载、批量 ZIP |
272
+ | `PreviewDialog.vue` | 预览弹窗 |
273
+ | `Icon.vue` / `icons.ts` | 图标 |
274
+ | `utils.ts` | 路径、格式化、文件类型表 |
275
+
245
276
  仓库统一使用 pnpm(`pnpm-lock.yaml`),CI 与发布流程执行 `pnpm install --frozen-lockfile`。
246
277
 
247
278
  `demo/` 下的演示站通过 `file:..` 安装本地包:
@@ -18,6 +18,8 @@ interface FileListLabels {
18
18
  loading: string;
19
19
  loadFailed: string;
20
20
  guestHint: string;
21
+ /** Shown (and appended to toasts) for browser network errors, usually CORS. */
22
+ /** Shown (and appended to toasts) for browser network errors, usually CORS. */
21
23
  corsHint: string;
22
24
  retry: string;
23
25
  empty: string;
@@ -75,7 +77,7 @@ interface FileListLabels {
75
77
  /** Refresh failed; the old rows stay. `{message}` */
76
78
  refreshFailed: string;
77
79
  cancel: string;
78
- /** Placeholder / accessible name of a folder's password input. `{name}` */
80
+ /** Accessible name of a folder's password input. `{name}` */
79
81
  passwordFor: string;
80
82
  /** OpenList cannot tell a wrong password from missing permission. */
81
83
  passwordWrong: string;
@@ -88,8 +90,31 @@ interface FileListLabels {
88
90
  forgetPassword: string;
89
91
  /** Lock button on a folder that needs a password. `{name}` */
90
92
  unlockFolder: string;
91
- /** Appended to failure toasts for browser network errors (usually CORS). */
93
+ /** @deprecated Network failures now append `corsHint`. */
92
94
  networkHint: string;
95
+ /** Batch progress detail. `{done}` `{total}` sizes, `{files}` `{count}` file counts */
96
+ batchProgress: string;
97
+ /** Batch finished. `{name}` `{count}` `{size}` */
98
+ batchDone: string;
99
+ batchCanceled: string;
100
+ /** In-memory ZIP over `zipWarnSize`. `{size}` */
101
+ zipWarnTitle: string;
102
+ /** `{limit}` */
103
+ zipWarnText: string;
104
+ /** Desktop browsers that cannot stream: point to one that can. */
105
+ zipStreamTip: string;
106
+ zipContinue: string;
107
+ /** In-memory ZIP over `zipMaxSize`. `{size}` */
108
+ zipBlockTitle: string;
109
+ /** `{limit}` */
110
+ zipBlockText: string;
111
+ gotIt: string;
112
+ /** Last row of a long folder. `{count}` */
113
+ moreRemaining: string;
114
+ showMore: string;
115
+ showAll: string;
116
+ /** Fewer than a page left. `{count}` */
117
+ showRest: string;
93
118
  }
94
119
  interface FileListSource {
95
120
  /** OpenList path, directory or single file. */
@@ -121,6 +146,21 @@ interface FileListProps {
121
146
  * cleared when the tab closes). Defaults to `true`; `false` hides the option.
122
147
  */
123
148
  rememberPassword?: boolean;
149
+ /**
150
+ * Rows shown per folder before “Show more”. Defaults to `200`; `0` shows
151
+ * everything. Data is still loaded in full; only rendering is limited.
152
+ */
153
+ pageSize?: number;
154
+ /**
155
+ * Browsers that must build the ZIP in memory (Firefox, Safari) ask first above
156
+ * this many MB. Defaults to 500 (200 on touch devices); `0` never asks.
157
+ */
158
+ zipWarnSize?: number;
159
+ /**
160
+ * …and refuse above this many MB. Defaults to 2048 (1024 on touch devices);
161
+ * `0` means no limit. Chrome and Edge stream to disk and skip both checks.
162
+ */
163
+ zipMaxSize?: number;
124
164
  /** Built-in locale. Defaults to `zh-CN`. */
125
165
  locale?: FileListLocale;
126
166
  /** Per-key label overrides on top of the locale preset. */
@@ -146,6 +186,7 @@ declare const _default: import("vue").DefineComponent<FileListProps, {}, {}, {},
146
186
  password: string;
147
187
  title: string;
148
188
  rememberPassword: boolean;
189
+ pageSize: number;
149
190
  locale: FileListLocale;
150
191
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
151
192
  declare global {
@@ -225,13 +266,13 @@ declare global {
225
266
  export declare const fileListLocales: Record<FileListLocale, FileListLabels>;
226
267
  export declare function formatLabel(template: string, values?: Record<string, string | number>): string;
227
268
  export declare function resolveLabels(locale?: FileListLocale, overrides?: Partial<FileListLabels>): FileListLabels;
228
- export interface SortableNode {
269
+ interface SortableNode {
229
270
  name: string;
230
271
  size: number;
231
272
  is_dir: boolean;
232
273
  modified: string;
233
274
  }
234
- export type SortKey = 'name' | 'size' | 'modified';
275
+ type SortKey = 'name' | 'size' | 'modified';
235
276
  export declare function joinPath(parent: string, name: string): string;
236
277
  export declare function encodePath(path: string): string;
237
278
  /**
@@ -246,24 +287,26 @@ export declare function zipEntryName(segments: string[]): string;
246
287
  * The suffix goes before the extension of the last segment. Adds the result to `used`.
247
288
  */
248
289
  export declare function uniqueEntryName(name: string, used: Set<string>): string;
290
+ /** Human-readable size. `0` reads `0 B`; missing, negative or invalid sizes read `-`. */
249
291
  export declare function formatSize(size: number): string;
250
292
  export declare function formatDate(iso: string): string;
293
+ /** Upper-case extension for the type badge, e.g. `PDF`. */
251
294
  export declare function extOf(name: string): string;
252
- export type FileKind = 'doc' | 'sheet' | 'slide' | 'pdf' | 'image' | 'media' | 'archive' | 'code' | 'other';
295
+ type FileKind = 'doc' | 'sheet' | 'slide' | 'pdf' | 'image' | 'media' | 'archive' | 'code' | 'other';
296
+ type PreviewKind = 'image' | 'video' | 'audio' | 'text' | 'pdf' | 'none';
253
297
  /** Rough file family, used to colour the type badge. */
254
298
  export declare function fileKind(name: string): FileKind;
255
- /** Sum of the `size` of the given entries, ignoring missing or invalid sizes. */
256
- export declare function totalSize(items: Array<{
257
- size?: number;
258
- }>): number;
259
- export declare function compareNodes(a: SortableNode, b: SortableNode, key: SortKey, ascending?: boolean): number;
260
- export type PreviewKind = 'image' | 'video' | 'audio' | 'text' | 'pdf' | 'none';
261
299
  /**
262
300
  * How a file is shown in the preview dialog. Office documents and anything
263
301
  * else the browser cannot render are `none` (info + download).
264
302
  */
265
303
  export declare function previewKind(name: string): PreviewKind;
266
- export interface IframePreview {
304
+ /** Sum of the `size` of the given entries, ignoring missing or invalid sizes. */
305
+ export declare function totalSize(items: Array<{
306
+ size?: number;
307
+ }>): number;
308
+ export declare function compareNodes(a: SortableNode, b: SortableNode, key: SortKey, ascending?: boolean): number;
309
+ interface IframePreview {
267
310
  label: string;
268
311
  scheme: string;
269
312
  }
@@ -300,4 +343,4 @@ export declare function fillPreviewUrl(scheme: string, args: {
300
343
  * ```
301
344
  */
302
345
  export declare function enhanceAppWithFileList({ app }: EnhanceAppContext): void;
303
- export { _default as FileList, _default as VPFileList, type FileListLabels, type FileListLocale, type FileListProps, type FileListSource, type OpenListEntry };
346
+ export { type FileKind, _default as FileList, _default as VPFileList, type FileListLabels, type FileListLocale, type FileListProps, type FileListSource, type IframePreview, type OpenListEntry, type PreviewKind, type SortKey, type SortableNode };