Skip to content

Commit d3af3e9

Browse files
Merge pull request #15 from youyeke/feature_asyncReadFilePath
[feat]: 将目录的读取方式改成异步
2 parents c78624d + 67d265e commit d3af3e9

File tree

9 files changed

+128
-12
lines changed

9 files changed

+128
-12
lines changed

.vscode/settings.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"editor.bracketPairColorization.enabled": true,
33
"editor.guides.bracketPairs": true,
4-
"editor.formatOnSave": true,
4+
"editor.formatOnSave": false,
55
"editor.defaultFormatter": "esbenp.prettier-vscode",
66
"editor.codeActionsOnSave": ["source.fixAll.eslint"],
77
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
@@ -15,5 +15,8 @@
1515
"pswp",
1616
"todos",
1717
"viewerjs"
18-
]
18+
],
19+
"[vue]": {
20+
"editor.defaultFormatter": "vscode.typescript-language-features"
21+
}
1922
}

src-electron/AsyncReadFilePath.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import fs from 'fs-extra'
2+
import path from 'path'
3+
import imageSize from 'image-size'
4+
import { promisify } from 'util'
5+
import type { WImage } from './traverseFolder'
6+
import { mainWindow } from './electron-main'
7+
8+
const sizeOf = promisify(imageSize)
9+
10+
export default class AsyncReadFilePath {
11+
picLinks = [] as WImage[]
12+
/** 有效的图片格式 */
13+
picFormats = [] as string[]
14+
/** 任务名称 */
15+
taskName
16+
/** 每页分割的大小 */
17+
pageSize = 20
18+
19+
constructor(taskName: string, picFormats: string[], pageSize: number) {
20+
this.taskName = taskName
21+
this.picFormats = picFormats
22+
this.pageSize = pageSize || 20
23+
}
24+
25+
async readDirectory(dir: string) {
26+
const stack = [dir]
27+
const pageStack = [] as WImage[]
28+
29+
while (stack.length) {
30+
// 深度优先
31+
const currentPath = stack.pop()
32+
if (!currentPath) {
33+
continue
34+
}
35+
const files = await fs.readdir(currentPath, { withFileTypes: true })
36+
files.sort((a, b) => b.name.localeCompare(a.name, undefined, { sensitivity: 'base' }))
37+
38+
const result = [] as WImage[]
39+
for (const file of files) {
40+
const fullPath = path.join(currentPath, file.name)
41+
if (file.isDirectory()) {
42+
stack.push(fullPath)
43+
} else if (file.isFile()) {
44+
const extname = path.extname(fullPath).toLowerCase()
45+
if (this.picFormats.includes(extname)) {
46+
await sizeOf(fullPath).then(dimensions => {
47+
result.push({
48+
source: fullPath,
49+
src: 'atom://' + fullPath,
50+
srcThumb: 'atom://' + fullPath,
51+
width: dimensions?.width,
52+
height: dimensions?.height,
53+
})
54+
55+
}).catch(err => {
56+
console.log('sizeOf error', err)
57+
})
58+
}
59+
}
60+
}
61+
pageStack.push(...result.reverse())
62+
if (pageStack.length >= this.pageSize) {
63+
this.picLinks.push(...pageStack.splice(0, this.pageSize))
64+
this.taskReport()
65+
}
66+
}
67+
68+
if (pageStack.length) {
69+
this.picLinks.push(...pageStack.splice(0, pageStack.length - 1))
70+
this.taskReport()
71+
}
72+
73+
}
74+
75+
taskReport() {
76+
if (mainWindow && this.picLinks.length) {
77+
mainWindow.webContents.send('async:imageLinks-append', this.taskName, this.picLinks)
78+
}
79+
}
80+
}

src-electron/IPC-main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function isFileSync (path) {
2626
let store = new Store();
2727
// 重构判断是否为空并
2828

29-
import { imageRetrieval } from './traverseFolder';
29+
import { imageRetrieval, imageRetrievalAsync } from './traverseFolder';
3030

3131
export function data_init () {
3232
if (!store.get('itemNum')) store = new Store({ schema });
@@ -62,6 +62,10 @@ export function ipcMains (value: void): any {
6262
return imageRetrieval(path, pFormats);
6363
});
6464

65+
ipcMain.handle('tool-traverseFolder-async', (event, path, pFormats, pPageNum) => {
66+
return imageRetrievalAsync(path, pFormats, pPageNum);
67+
});
68+
6569
ipcMain.handle('tool-openLink', (event, link) => {
6670
console.log(link);
6771
return shell.openExternal(link);

src-electron/electron-main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ initialize();
77
// needed in case process is undefined under Linux
88
const platform = process.platform || os.platform();
99

10-
let mainWindow: BrowserWindow | undefined;
10+
export let mainWindow: BrowserWindow | undefined;
1111

1212
function createWindow () {
1313
/**

src-electron/electron-preload.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,28 @@ export type myWindowAPI = {
5151

5252
export type myToolAPI = {
5353
traverseFolder: (path: string, pFormats: any) => any;
54+
traverseFolderAsync: (path: string, pFormats: string[], perPageNum: number) => any;
5455
openLink: (link: string) => any;
5556
delPic: (src: string) => any;
5657
openPath: (src: string) => any;
5758
showItemInFolder: (src: string) => any;
59+
onAsyncImageLinksAppend: (handle: (event: IpcRendererEvent, taskName: string, paths: WImage[]) => void) => void;
5860
};
5961

6062
import { contextBridge, ipcRenderer } from 'electron';
63+
import type { IpcRendererEvent } from 'electron';
6164
import { BrowserWindow, app, shell } from '@electron/remote';
65+
import type { WImage } from './traverseFolder';
6266

6367
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6468

6569
const myToolAPIs: myToolAPI = {
6670
async traverseFolder (path, pFormats) {
6771
return await ipcRenderer.invoke('tool-traverseFolder', path, pFormats);
6872
},
73+
async traverseFolderAsync (path, pFormats, perPageNum) {
74+
return await ipcRenderer.invoke('tool-traverseFolder-async', path, pFormats, perPageNum);
75+
},
6976
async openLink (link) {
7077
return await ipcRenderer.invoke('tool-openLink', link);
7178
},
@@ -77,6 +84,9 @@ const myToolAPIs: myToolAPI = {
7784
},
7885
async showItemInFolder (src) {
7986
shell.showItemInFolder(src);
87+
},
88+
onAsyncImageLinksAppend(handle) {
89+
ipcRenderer.on('async:imageLinks-append', handle);
8090
}
8191
};
8292

src-electron/traverseFolder.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// import remote from '@electron/remote'
44
import fs from 'fs-extra';
55
import * as path from 'path';
6+
import AsyncReadFilePath from './AsyncReadFilePath';
67

78
// import { promisify } from 'util';
89
const sizeOf = require('image-size');
@@ -27,7 +28,7 @@ let picFormats: any[] = [
2728
'.jfif'
2829
];
2930

30-
interface WImage {
31+
export interface WImage {
3132
source: string;
3233
src: string;
3334
srcThumb: string;
@@ -121,6 +122,12 @@ export function imageRetrieval (thepath, pFormats) {
121122
console.log('Finish traverseFolderObjects!');
122123
return picLinks;
123124
}
125+
126+
export function imageRetrievalAsync(thepath, pFormats, pageSize) {
127+
if (pFormats) picFormats = pFormats;
128+
const asyncReadFilePath = new AsyncReadFilePath(thepath, picFormats, pageSize)
129+
asyncReadFilePath.readDirectory(thepath)
130+
}
124131
// // 开始遍历
125132
// traverseFolder(rootPath);
126133

src/components/WaterFall.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ const props = defineProps({
6161
})
6262
6363
let oImgs = ref(props.imgs) // 啥玩意《
64+
watch(() => props.imgs.length, (newImgs) => {
65+
oImgs.value = props.imgs
66+
})
6467
const inputPageValue = ref(1)
6568
// import { LazyImg, Waterfall } from 'vue-waterfall-plugin-next'
6669
// import 'vue-waterfall-plugin-next/dist/style.css'

src/pages/IndexPage.vue

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ import type { UploadInst } from 'naive-ui'
6565
6666
import WaterFall from 'components/WaterFall.vue'
6767
import SetComponent from 'components/SetComponent.vue'
68+
import type { WImage } from 'app/src-electron/traverseFolder'
6869
6970
const upload = ref<UploadInst | null>()
7071
const ifImgPreOK = ref<boolean>(false)
71-
const imgs = ref([])
72+
const imgs = ref<WImage[]>([])
7273
7374
import { useSettingStore } from 'stores/viewerSet-store';
7475
const setStore = useSettingStore()
@@ -101,11 +102,18 @@ async function querydb() {
101102
102103
async function picInfoInit(fpath) {
103104
console.log('picInfoInit')
104-
let aa = JSON.parse(JSON.stringify(setStore.getPFormat))
105-
console.log(aa)
106-
imgs.value = await window.myToolAPI.traverseFolder(fpath, aa)
107-
// console.log(imgs.value)
108-
ifImgPreOK.value = true
105+
const pFormat = JSON.parse(JSON.stringify(setStore.getPFormat))
106+
const perPageNum = JSON.parse(JSON.stringify(setStore.getPerPageNum))
107+
108+
// imgs.value = await window.myToolAPI.traverseFolder(fpath, pFormat)
109+
110+
window.myToolAPI.traverseFolderAsync(fpath, pFormat, perPageNum)
111+
window.myToolAPI.onAsyncImageLinksAppend((event, taskName, paths) => {
112+
if (taskName === fpath) {
113+
imgs.value = paths
114+
ifImgPreOK.value = true
115+
}
116+
})
109117
}
110118
111119
import { normalizePath } from './normalize-path'

src/stores/viewerSet-store.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export const useSettingStore = defineStore('setting', {
3737
}),
3838
getters: {
3939
// doubleCount: state => state.counter * 2
40-
getPFormat: state => state.imageFormat
40+
getPFormat: state => state.imageFormat,
41+
getPerPageNum: state => state.perPageNum,
4142
},
4243
actions: {
4344
increment () {

0 commit comments

Comments
 (0)