bug修复
This commit is contained in:
+21
-1
@@ -351,9 +351,29 @@ ipcMain.on('myreader:allow-close', (event) => {
|
|||||||
win.close()
|
win.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let pendingOpenPaths: string[] = []
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
Menu.setApplicationMenu(buildMenu())
|
Menu.setApplicationMenu(buildMenu())
|
||||||
createWindow()
|
|
||||||
|
const args = process.argv.slice(1)
|
||||||
|
for (const arg of args) {
|
||||||
|
if (existsSync(arg) && isMarkdownFile(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', () => {
|
app.on('activate', () => {
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
createWindow()
|
createWindow()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export interface MyReaderApi {
|
|||||||
allowClose: () => void
|
allowClose: () => void
|
||||||
onRequestClose: (handler: () => void) => () => void
|
onRequestClose: (handler: () => void) => () => void
|
||||||
onMenuAction: (handler: (action: string) => void) => () => void
|
onMenuAction: (handler: (action: string) => void) => () => void
|
||||||
|
onOpenFiles: (handler: (paths: string[]) => void) => () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const api: MyReaderApi = {
|
const api: MyReaderApi = {
|
||||||
@@ -64,6 +65,15 @@ const api: MyReaderApi = {
|
|||||||
return () => {
|
return () => {
|
||||||
ipcRenderer.removeListener('myreader:menu', listener)
|
ipcRenderer.removeListener('myreader:menu', listener)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onOpenFiles: (handler: (paths: string[]) => void) => {
|
||||||
|
const listener = (_e: unknown, paths: string[]): void => {
|
||||||
|
handler(paths)
|
||||||
|
}
|
||||||
|
ipcRenderer.on('myreader:open-files', listener)
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeListener('myreader:open-files', listener)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,10 @@ export default function App(): React.ReactElement {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let cancelled = false
|
let cancelled = false
|
||||||
|
const timeoutPromise = new Promise<void>((_, reject) => {
|
||||||
|
setTimeout(() => reject(new Error('timeout')), 5000)
|
||||||
|
})
|
||||||
|
|
||||||
void (async () => {
|
void (async () => {
|
||||||
try {
|
try {
|
||||||
const raw = localStorage.getItem(SESSION_KEY)
|
const raw = localStorage.getItem(SESSION_KEY)
|
||||||
@@ -181,16 +185,17 @@ export default function App(): React.ReactElement {
|
|||||||
if (data.v !== 1 || !Array.isArray(data.tabs)) return
|
if (data.v !== 1 || !Array.isArray(data.tabs)) return
|
||||||
const restored: Tab[] = []
|
const restored: Tab[] = []
|
||||||
for (const row of data.tabs) {
|
for (const row of data.tabs) {
|
||||||
|
if (cancelled) break
|
||||||
if (!row || typeof row !== 'object') continue
|
if (!row || typeof row !== 'object') continue
|
||||||
const id = crypto.randomUUID()
|
const id = crypto.randomUUID()
|
||||||
const content = typeof row.content === 'string' ? row.content : ''
|
const content = typeof row.content === 'string' ? row.content : ''
|
||||||
const saved = typeof row.saved === 'string' ? row.saved : content
|
const saved = typeof row.saved === 'string' ? row.saved : content
|
||||||
if (row.path) {
|
if (row.path) {
|
||||||
try {
|
try {
|
||||||
await api.readFile(row.path)
|
await Promise.race([api.readFile(row.path), timeoutPromise])
|
||||||
restored.push({ id, filePath: row.path, content, savedContent: saved })
|
restored.push({ id, filePath: row.path, content, savedContent: saved })
|
||||||
} catch {
|
} catch {
|
||||||
/* missing or unreadable */
|
/* missing or unreadable or timeout */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
restored.push({ id, filePath: null, content, savedContent: saved })
|
restored.push({ id, filePath: null, content, savedContent: saved })
|
||||||
@@ -326,6 +331,20 @@ export default function App(): React.ReactElement {
|
|||||||
if (textPrompt) setTextPromptInput(textPrompt.defaultValue)
|
if (textPrompt) setTextPromptInput(textPrompt.defaultValue)
|
||||||
}, [textPrompt])
|
}, [textPrompt])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!api || !sessionHydrated) return
|
||||||
|
|
||||||
|
const handleOpenFiles = (paths: string[]) => {
|
||||||
|
paths.forEach(path => {
|
||||||
|
void openPathInTab(path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsubscribe = api.onOpenFiles(handleOpenFiles)
|
||||||
|
|
||||||
|
return unsubscribe
|
||||||
|
}, [api, sessionHydrated])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (imageInsert) {
|
if (imageInsert) {
|
||||||
setImageUrlInput('')
|
setImageUrlInput('')
|
||||||
|
|||||||
Vendored
+1
@@ -25,6 +25,7 @@ export interface MyReaderApi {
|
|||||||
allowClose: () => void
|
allowClose: () => void
|
||||||
onRequestClose: (handler: () => void) => () => void
|
onRequestClose: (handler: () => void) => () => void
|
||||||
onMenuAction: (handler: (action: string) => void) => () => void
|
onMenuAction: (handler: (action: string) => void) => () => void
|
||||||
|
onOpenFiles: (handler: (paths: string[]) => void) => () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
Reference in New Issue
Block a user