bug修复
This commit is contained in:
+71
-25
@@ -182,7 +182,7 @@ function buildMenu(): Menu {
|
||||
return Menu.buildFromTemplate(template)
|
||||
}
|
||||
|
||||
function createWindow(): BrowserWindow {
|
||||
function createWindow(_pendingPaths?: string[]): BrowserWindow {
|
||||
const preloadPath = getPreloadPath()
|
||||
const iconPath = resolveAppIconPath()
|
||||
let icon: NativeImage | undefined
|
||||
@@ -218,7 +218,8 @@ function createWindow(): BrowserWindow {
|
||||
})
|
||||
|
||||
if (process.env.ELECTRON_RENDERER_URL) {
|
||||
void win.loadURL(process.env.ELECTRON_RENDERER_URL)
|
||||
const url = new URL(process.env.ELECTRON_RENDERER_URL)
|
||||
void win.loadURL(url.toString())
|
||||
} else {
|
||||
void win.loadFile(getRendererIndexHtml())
|
||||
}
|
||||
@@ -353,34 +354,79 @@ ipcMain.on('myreader:allow-close', (event) => {
|
||||
|
||||
let pendingOpenPaths: string[] = []
|
||||
|
||||
app.whenReady().then(() => {
|
||||
Menu.setApplicationMenu(buildMenu())
|
||||
|
||||
const args = process.argv.slice(1)
|
||||
for (const arg of args) {
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
|
||||
function collectFilePathsFromArgv(): void {
|
||||
for (const arg of process.argv) {
|
||||
if (arg === process.argv[0]) continue
|
||||
if (arg.startsWith('--')) continue
|
||||
if (existsSync(arg) && isMarkdownFile(arg)) {
|
||||
pendingOpenPaths.push(arg)
|
||||
if (!pendingOpenPaths.includes(arg)) {
|
||||
pendingOpenPaths.push(arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const win = createWindow()
|
||||
|
||||
win.webContents.on('dom-ready', () => {
|
||||
if (pendingOpenPaths.length > 0) {
|
||||
setTimeout(() => {
|
||||
win.webContents.send('myreader:open-files', pendingOpenPaths)
|
||||
pendingOpenPaths = []
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ipcMain.handle('myreader:get-pending-files', (): string[] => {
|
||||
const paths = pendingOpenPaths.slice()
|
||||
pendingOpenPaths = []
|
||||
return paths
|
||||
})
|
||||
|
||||
ipcMain.on('myreader:get-pending-files-sync', (event) => {
|
||||
event.returnValue = pendingOpenPaths.slice()
|
||||
pendingOpenPaths = []
|
||||
})
|
||||
|
||||
if (!gotTheLock) {
|
||||
app.quit()
|
||||
} else {
|
||||
app.on('second-instance', (_evt, argv) => {
|
||||
const win = BrowserWindow.getAllWindows()[0]
|
||||
if (win) {
|
||||
if (win.isMinimized()) win.restore()
|
||||
win.focus()
|
||||
for (const arg of argv) {
|
||||
if (arg === argv[0]) continue
|
||||
if (arg.startsWith('--')) continue
|
||||
if (existsSync(arg) && isMarkdownFile(arg)) {
|
||||
if (!win.webContents.isDestroyed()) {
|
||||
win.webContents.send('myreader:open-files', [arg])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.on('open-file', (_evt, path) => {
|
||||
if (!isMarkdownFile(path)) return
|
||||
const win = BrowserWindow.getAllWindows()[0]
|
||||
if (win && !win.webContents.isDestroyed() && !win.webContents.isLoading()) {
|
||||
win.webContents.send('myreader:open-files', [path])
|
||||
return
|
||||
}
|
||||
const key = path.replace(/\\/g, '/').toLowerCase()
|
||||
if (!pendingOpenPaths.some((p) => p.replace(/\\/g, '/').toLowerCase() === key)) {
|
||||
pendingOpenPaths.push(path)
|
||||
}
|
||||
})
|
||||
|
||||
app.whenReady().then(() => {
|
||||
Menu.setApplicationMenu(buildMenu())
|
||||
|
||||
collectFilePathsFromArgv()
|
||||
|
||||
createWindow()
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
|
||||
+29
-7
@@ -7,6 +7,17 @@ import type {
|
||||
SaveDialogResult
|
||||
} from './ipc-types.js'
|
||||
|
||||
const bufferedOpenFiles: string[][] = []
|
||||
let openFilesHandler: ((paths: string[]) => void) | null = null
|
||||
|
||||
ipcRenderer.on('myreader:open-files', (_e, paths: string[]) => {
|
||||
if (openFilesHandler) {
|
||||
openFilesHandler(paths)
|
||||
} else {
|
||||
bufferedOpenFiles.push(paths)
|
||||
}
|
||||
})
|
||||
|
||||
export interface MyReaderApi {
|
||||
openFileDialog: () => Promise<OpenFileResult>
|
||||
openFolderDialog: () => Promise<OpenFolderResult>
|
||||
@@ -16,7 +27,6 @@ export interface MyReaderApi {
|
||||
writeFile: (filePath: string, content: string) => Promise<void>
|
||||
listDirectory: (dirPath: string) => Promise<ListDirResult>
|
||||
parentDirectory: (dirPath: string) => Promise<string>
|
||||
/** 相对当前 Markdown 文件解析内链 href → 绝对路径(外链原样返回) */
|
||||
resolveRelativePath: (baseFilePath: string, href: string) => Promise<string>
|
||||
openExternal: (url: string) => Promise<void>
|
||||
defaultDirectory: () => Promise<string>
|
||||
@@ -26,6 +36,7 @@ export interface MyReaderApi {
|
||||
onRequestClose: (handler: () => void) => () => void
|
||||
onMenuAction: (handler: (action: string) => void) => () => void
|
||||
onOpenFiles: (handler: (paths: string[]) => void) => () => void
|
||||
getPendingFilesIPC: () => Promise<string[]>
|
||||
}
|
||||
|
||||
const api: MyReaderApi = {
|
||||
@@ -67,13 +78,24 @@ const api: MyReaderApi = {
|
||||
}
|
||||
},
|
||||
onOpenFiles: (handler: (paths: string[]) => void) => {
|
||||
const listener = (_e: unknown, paths: string[]): void => {
|
||||
handler(paths)
|
||||
}
|
||||
ipcRenderer.on('myreader:open-files', listener)
|
||||
openFilesHandler = handler
|
||||
return () => {
|
||||
ipcRenderer.removeListener('myreader:open-files', listener)
|
||||
openFilesHandler = null
|
||||
}
|
||||
},
|
||||
getPendingFilesIPC: async (): Promise<string[]> => {
|
||||
const fromMain = await ipcRenderer.invoke('myreader:get-pending-files')
|
||||
const fromBuffer = bufferedOpenFiles.flat()
|
||||
bufferedOpenFiles.length = 0
|
||||
const seen = new Set<string>()
|
||||
const merged: string[] = []
|
||||
for (const p of [...fromMain, ...fromBuffer]) {
|
||||
const key = p.replace(/\\/g, '/').toLowerCase()
|
||||
if (seen.has(key)) continue
|
||||
seen.add(key)
|
||||
merged.push(p)
|
||||
}
|
||||
return merged
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,4 +103,4 @@ try {
|
||||
contextBridge.exposeInMainWorld('myreader', api)
|
||||
} catch (e) {
|
||||
console.error('[MyReader] preload contextBridge failed', e)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user