mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-06 02:30:47 -08:00
fix: binary file loading
This commit is contained in:
parent
063958adab
commit
4b217c4e66
2 changed files with 32 additions and 17 deletions
5
docs/internal/NodeDependency.md
Normal file
5
docs/internal/NodeDependency.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Node Dependency
|
||||
|
||||
Using node related dependency in scripts that will loaded in to preload script will cause error `ReferenceError: __dirname is not defined` and `Uncaught TypeError: Cannot destructure property 'descriptors' of 'window.service' as it is undefined.`.
|
||||
|
||||
What you need to do is separate ts file that requires node dependencies, from ts file that only use things available in browser environments.
|
||||
|
|
@ -5,8 +5,9 @@ import { logger } from '@services/libs/log';
|
|||
import { INativeService } from '@services/native/interface';
|
||||
import serviceIdentifier from '@services/serviceIdentifier';
|
||||
import type { IWikiService } from '@services/wiki/interface';
|
||||
import { BrowserView, shell } from 'electron';
|
||||
import { BrowserView, net, shell } from 'electron';
|
||||
import fs from 'fs-extra';
|
||||
import { pathToFileURL } from 'url';
|
||||
import { INewWindowAction } from './interface';
|
||||
import type { INewWindowContext } from './setupViewEventHandlers';
|
||||
|
||||
|
|
@ -50,36 +51,45 @@ export function handleOpenFileExternalLink(nextUrl: string, newWindowContext: IN
|
|||
};
|
||||
}
|
||||
|
||||
async function loadFileContentHandler(request: Request) {
|
||||
let { pathname } = new URL(request.url);
|
||||
pathname = decodeURIComponent(pathname);
|
||||
logger.info(`Loading file content from ${pathname}`, { function: 'handleViewFileContentLoading view.webContents.session.protocol.handle' });
|
||||
try {
|
||||
const response = await net.fetch(pathToFileURL(pathname).toString());
|
||||
logger.info(`${pathname} loaded`, { function: 'handleViewFileContentLoading view.webContents.session.protocol.handle' });
|
||||
return response;
|
||||
} catch (error) {
|
||||
return new Response(undefined, { status: 404, statusText: (error as Error).message });
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable n/no-callback-literal */
|
||||
/**
|
||||
* Handle file protocol in webview to request file content and show in the view.
|
||||
*/
|
||||
export function handleViewFileContentLoading(view: BrowserView) {
|
||||
/**
|
||||
* This function is called after `await app.whenReady()`, but electron will still throw error `Failed to register protocol: filefix` in https://github.com/tiddly-gittly/TidGi-Desktop/issues/422 , so we further delay it.
|
||||
*/
|
||||
try {
|
||||
/**
|
||||
* This function is called for every view, but seems register on two different view will throw error, so we check if it's already registered.
|
||||
*/
|
||||
if (!view.webContents.session.protocol.isProtocolHandled('filefix')) {
|
||||
/**
|
||||
* Electron's bug, file protocol is not handle-able, won't get any callback. But things like `filea://` `filefix` works.
|
||||
*/
|
||||
view.webContents.session.protocol.handle('filefix', async (request) => {
|
||||
let { pathname } = new URL(request.url);
|
||||
pathname = decodeURIComponent(pathname);
|
||||
logger.info(`Loading file content from ${pathname}`, { function: 'handleViewFileContentLoading view.webContents.session.protocol.handle' });
|
||||
try {
|
||||
const file = await fs.readFile(pathname);
|
||||
return new Response(file, { status: 200 });
|
||||
} catch (error) {
|
||||
return new Response(undefined, { status: 404, statusText: (error as Error).message });
|
||||
view.webContents.session.protocol.handle('filefix', loadFileContentHandler);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Alternative `open://` protocol for a backup if `file://` doesn't work for some reason.
|
||||
*/
|
||||
if (!view.webContents.session.protocol.isProtocolHandled('open')) {
|
||||
view.webContents.session.protocol.handle('open', loadFileContentHandler);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Failed to register protocol: ${(error as Error).message}`, { function: 'handleViewFileContentLoading' });
|
||||
}
|
||||
view.webContents.session.webRequest.onBeforeRequest((details, callback) => {
|
||||
if (details.url.startsWith('file://') || details.url.startsWith('open://')) {
|
||||
if (details.url.startsWith('file://')) {
|
||||
handleFileLink(details, callback);
|
||||
} else {
|
||||
callback({
|
||||
|
|
@ -94,7 +104,7 @@ function handleFileLink(details: Electron.OnBeforeRequestListenerDetails, callba
|
|||
let redirectURL = nativeService.formatFileUrlToAbsolutePath(details.url);
|
||||
if (redirectURL === details.url) {
|
||||
// prevent redirect loop, remove file:// prefix, so it never comes back to this function from `handleViewFileContentLoading` again.
|
||||
redirectURL = redirectURL.replace('file://', '').replace('open://', '');
|
||||
redirectURL = redirectURL.replace('file://', '');
|
||||
} else {
|
||||
redirectURL = `filefix://${redirectURL}`;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue