From c0e0f0cd297b36f900a2d65aeda24a4fcce653a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com> Date: Mon, 1 Apr 2024 14:56:02 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E6=94=AF=E6=8C=81=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=99=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/electron/fileHandle.js | 25 +++++++++++ web/src/electron/preload.js | 7 ++- web/src/lang/en_us.js | 3 +- web/src/lang/zh_cn.js | 3 +- .../pages/Edit/components/NodeAttachment.vue | 44 ++++++++++++++++--- web/src/pages/Edit/components/Toolbar.vue | 4 +- 6 files changed, 75 insertions(+), 11 deletions(-) diff --git a/web/src/electron/fileHandle.js b/web/src/electron/fileHandle.js index a3b96fc6..74cb60f1 100644 --- a/web/src/electron/fileHandle.js +++ b/web/src/electron/fileHandle.js @@ -127,6 +127,22 @@ export const bindFileHandleEvent = ({ mainWindow }) => { } }) + // 选择本地文件 + ipcMain.handle('selectFile', event => { + const res = dialog.showOpenDialogSync({ + title: '选择' + }) + if (res && res[0]) { + console.log(111, res[0]) + return { + file: res[0], + name: path.basename(res[0]) + } + } else { + return null + } + }) + // 获取文件内容 ipcMain.handle('getFileContent', (event, id) => { return new Promise(resolve => { @@ -213,6 +229,15 @@ export const bindFileHandleEvent = ({ mainWindow }) => { shell.showItemInFolder(file) }) + // 打开指定文件 + ipcMain.handle('openPath', (event, file) => { + const exist = fs.existsSync(file) + if (!exist) { + return '文件不存在' + } + shell.openPath(file) + }) + // 删除指定文件 ipcMain.handle('deleteFile', (event, file) => { let res = '' diff --git a/web/src/electron/preload.js b/web/src/electron/preload.js index af3404e5..044a30dd 100644 --- a/web/src/electron/preload.js +++ b/web/src/electron/preload.js @@ -14,7 +14,8 @@ contextBridge.exposeInMainWorld('electronAPI', { save: (id, data, fileName) => ipcRenderer.invoke('save', id, data, fileName), rename: (id, name) => ipcRenderer.invoke('rename', id, name), openUrl: url => ipcRenderer.send('openUrl', url), - addRecentFileList: (fileList) => ipcRenderer.invoke('addRecentFileList', fileList), + addRecentFileList: fileList => + ipcRenderer.invoke('addRecentFileList', fileList), getRecentFileList: () => ipcRenderer.invoke('getRecentFileList'), clearRecentFileList: () => ipcRenderer.invoke('clearRecentFileList'), openFileInDir: file => ipcRenderer.invoke('openFileInDir', file), @@ -23,5 +24,7 @@ contextBridge.exposeInMainWorld('electronAPI', { ipcRenderer.on('refreshRecentFileList', callback), openFile: file => ipcRenderer.invoke('openFile', file), selectOpenFile: () => ipcRenderer.send('selectOpenFile'), - copyFile: file => ipcRenderer.invoke('copyFile', file) + copyFile: file => ipcRenderer.invoke('copyFile', file), + selectFile: () => ipcRenderer.invoke('selectFile'), + openPath: path => ipcRenderer.invoke('openPath', path) }) diff --git a/web/src/lang/en_us.js b/web/src/lang/en_us.js index 8eafa1e7..fcd58d07 100644 --- a/web/src/lang/en_us.js +++ b/web/src/lang/en_us.js @@ -336,6 +336,7 @@ export default { formatTip: 'Format complete' }, attachment: { - deleteAttachment: 'Delete attachment' + deleteAttachment: 'Delete attachment', + openFileInDir: 'Show in dir' } } diff --git a/web/src/lang/zh_cn.js b/web/src/lang/zh_cn.js index f0e2a546..91d3c615 100644 --- a/web/src/lang/zh_cn.js +++ b/web/src/lang/zh_cn.js @@ -330,6 +330,7 @@ export default { formatTip: '格式化完成' }, attachment: { - deleteAttachment: '删除附件' + deleteAttachment: '删除附件', + openFileInDir: '在目录中显示' } } diff --git a/web/src/pages/Edit/components/NodeAttachment.vue b/web/src/pages/Edit/components/NodeAttachment.vue index 63d92250..2bacb4e2 100644 --- a/web/src/pages/Edit/components/NodeAttachment.vue +++ b/web/src/pages/Edit/components/NodeAttachment.vue @@ -6,9 +6,14 @@ top: this.top + 'px', visibility: show ? 'visible' : 'hidden' }" - @click.stop="deleteAttachment" + @click.stop > -
+ + @@ -61,15 +66,37 @@ export default { }, methods: { // 选择附件 - onSelectAttachment(activeNodes) { + async onSelectAttachment(activeNodes) { // activeNodes.forEach(node => { // node.setAttachment('/test.md', '我去') // }) + const file = await window.electronAPI.selectFile() + if (file) { + activeNodes.forEach(node => { + node.setAttachment(file.file, file.name) + }) + } }, // 点击附件图标,一般用来打开或下载附件 - onNodeAttachmentClick(node, e, icon) { + async onNodeAttachmentClick(node, e, icon) { // console.log(node.getData('attachmentUrl')) + const file = node.getData('attachmentUrl') + if (!file) return + const error = await window.electronAPI.openPath(file) + if (error) { + this.$message.error(error) + } + }, + + // 在目录中显示 + async openFileInDir() { + if (!this.node || !this.show) return + const file = this.node.getData('attachmentUrl') + const error = await window.electronAPI.openFileInDir(file) + if (error) { + this.$message.error(error) + } }, // 显示删除浮层 @@ -116,7 +143,7 @@ export default { .nodeAttachmentContextMenu { position: fixed; background-color: #fff; - padding: 10px; + padding: 10px 0; border-radius: 5px; box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06); border: 1px solid rgba(0, 0, 0, 0.06); @@ -128,6 +155,13 @@ export default { color: #1a1a1a; cursor: pointer; user-select: none; + height: 28px; + line-height: 28px; + padding: 0 10px; + + &:hover { + background: #f5f5f5; + } } } diff --git a/web/src/pages/Edit/components/Toolbar.vue b/web/src/pages/Edit/components/Toolbar.vue index 6b91638f..b12bcf63 100644 --- a/web/src/pages/Edit/components/Toolbar.vue +++ b/web/src/pages/Edit/components/Toolbar.vue @@ -183,8 +183,8 @@ export default { 'tag', 'summary', 'associativeLine', - 'formula' - // 'attachment' + 'formula', + 'attachment' ], horizontalList: [], verticalList: [],