Open file import
Summary: This change only adds the PWA as capable of handling files with the ".flipper" extension. Reviewed By: aigoncharov Differential Revision: D48353437 fbshipit-source-id: fd78942ac4dffb7d26d5ca5be826290018465b93
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9728155cbf
commit
ce13ee426f
@@ -67,7 +67,7 @@ interface NotificationConstructorOptions {
|
|||||||
// Events that are emitted from the main.ts ovr the IPC process bridge in Electron
|
// Events that are emitted from the main.ts ovr the IPC process bridge in Electron
|
||||||
type MainProcessEvents = {
|
type MainProcessEvents = {
|
||||||
'flipper-protocol-handler': [query: string];
|
'flipper-protocol-handler': [query: string];
|
||||||
'open-flipper-file': [url: string];
|
'open-flipper-file': [name: string, data: string];
|
||||||
notificationEvent: [
|
notificationEvent: [
|
||||||
eventName: NotificationEvents,
|
eventName: NotificationEvents,
|
||||||
pluginNotification: PluginNotification,
|
pluginNotification: PluginNotification,
|
||||||
@@ -88,7 +88,7 @@ type ChildProcessEvents = {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
getLaunchTime: [];
|
getLaunchTime: [];
|
||||||
componentDidMount: [];
|
storeRehydrated: [];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ async function start() {
|
|||||||
const flipperServerConfig = await flipperServer.exec('get-config');
|
const flipperServerConfig = await flipperServer.exec('get-config');
|
||||||
|
|
||||||
initializeRenderHost(flipperServer, flipperServerConfig);
|
initializeRenderHost(flipperServer, flipperServerConfig);
|
||||||
|
initializePWA();
|
||||||
|
|
||||||
// By turning this in a require, we force the JS that the body of this module (init) has completed (initializeElectron),
|
// By turning this in a require, we force the JS that the body of this module (init) has completed (initializeElectron),
|
||||||
// before starting the rest of the Flipper process.
|
// before starting the rest of the Flipper process.
|
||||||
@@ -78,6 +79,7 @@ async function start() {
|
|||||||
// but not set yet, which might happen when using normal imports.
|
// but not set yet, which might happen when using normal imports.
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
window.flipperShowError?.('Connected to Flipper Server successfully');
|
window.flipperShowError?.('Connected to Flipper Server successfully');
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
// eslint-disable-next-line import/no-commonjs
|
// eslint-disable-next-line import/no-commonjs
|
||||||
require('flipper-ui-core').startFlipperDesktop(flipperServer);
|
require('flipper-ui-core').startFlipperDesktop(flipperServer);
|
||||||
@@ -89,6 +91,76 @@ start().catch((e) => {
|
|||||||
window.flipperShowError?.('Failed to start flipper-ui-browser: ' + e);
|
window.flipperShowError?.('Failed to start flipper-ui-browser: ' + e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function initializePWA() {
|
||||||
|
console.log('[PWA] Initialization');
|
||||||
|
|
||||||
|
let cachedFile: {name: string; data: string} | undefined;
|
||||||
|
let rehydrated = false;
|
||||||
|
const openFileIfAny = () => {
|
||||||
|
if (!cachedFile || !rehydrated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent('open-flipper-file', {
|
||||||
|
detail: [cachedFile.name, cachedFile.data],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
cachedFile = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register('/service-worker.js')
|
||||||
|
.then(() => {
|
||||||
|
console.log('[PWA] Service Worker has been registered');
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error('[PWA] failed to register Service Worker', e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('launchQueue' in window) {
|
||||||
|
console.log('[PWA] File Handling API is supported');
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
window.launchQueue.setConsumer(async (launchParams) => {
|
||||||
|
if (!launchParams || !launchParams.files) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('[PWA] Attempt to to open a file');
|
||||||
|
for (const file of launchParams.files) {
|
||||||
|
const blob = await file.getFile();
|
||||||
|
blob.handle = file;
|
||||||
|
|
||||||
|
const data = await blob.text();
|
||||||
|
const name = file.name;
|
||||||
|
|
||||||
|
cachedFile = {name, data};
|
||||||
|
|
||||||
|
openFileIfAny();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn('[PWA] File Handling API is not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('[PWA] Add before install prompt listener');
|
||||||
|
window.addEventListener('beforeinstallprompt', (e) => {
|
||||||
|
// Prevent Chrome 67 and earlier from automatically showing the prompt.
|
||||||
|
e.preventDefault();
|
||||||
|
// Stash the event so it can be triggered later.
|
||||||
|
// @ts-ignore
|
||||||
|
global.PWAppInstallationEvent = e;
|
||||||
|
console.log('[PWA] Installation event has been captured');
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('storeRehydrated', () => {
|
||||||
|
console.info('[PWA] Store is rehydrated');
|
||||||
|
rehydrated = true;
|
||||||
|
openFileIfAny();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// getLogger() is not yet created when the electron app starts.
|
// getLogger() is not yet created when the electron app starts.
|
||||||
// we can't create it here yet, as the real logger is wired up to
|
// we can't create it here yet, as the real logger is wired up to
|
||||||
// the redux store and the rest of the world. So we create a delegating logger
|
// the redux store and the rest of the world. So we create a delegating logger
|
||||||
|
|||||||
@@ -153,11 +153,13 @@ export function initializeRenderHost(
|
|||||||
hasFocus() {
|
hasFocus() {
|
||||||
return document.hasFocus();
|
return document.hasFocus();
|
||||||
},
|
},
|
||||||
onIpcEvent(_event) {
|
onIpcEvent(event, cb) {
|
||||||
// no-op
|
window.addEventListener(event as string, (ev) => {
|
||||||
|
cb(...((ev as CustomEvent).detail as any));
|
||||||
|
});
|
||||||
},
|
},
|
||||||
sendIpcEvent(_event, ..._args: any[]) {
|
sendIpcEvent(event, ...args: any[]) {
|
||||||
// no-op
|
window.dispatchEvent(new CustomEvent(event, {detail: args}));
|
||||||
},
|
},
|
||||||
shouldUseDarkColors() {
|
shouldUseDarkColors() {
|
||||||
return !!(
|
return !!(
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import {Store} from '../reducers/index';
|
import {Store} from '../reducers/index';
|
||||||
import {Logger} from 'flipper-common';
|
import {Logger} from 'flipper-common';
|
||||||
import {
|
import {
|
||||||
importFileToStore,
|
importDataToStore,
|
||||||
IMPORT_FLIPPER_TRACE_EVENT,
|
IMPORT_FLIPPER_TRACE_EVENT,
|
||||||
} from '../utils/exportData';
|
} from '../utils/exportData';
|
||||||
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
||||||
@@ -67,9 +67,9 @@ export default (store: Store, logger: Logger) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
renderHost.onIpcEvent('open-flipper-file', (url: string) => {
|
renderHost.onIpcEvent('open-flipper-file', (name: string, data: string) => {
|
||||||
tryCatchReportPlatformFailures(() => {
|
tryCatchReportPlatformFailures(() => {
|
||||||
return importFileToStore(url, store);
|
return importDataToStore(name, data, store);
|
||||||
}, `${IMPORT_FLIPPER_TRACE_EVENT}:Deeplink`);
|
}, `${IMPORT_FLIPPER_TRACE_EVENT}:Deeplink`);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ import {Store} from '../reducers/index';
|
|||||||
import {Dispatcher} from './types';
|
import {Dispatcher} from './types';
|
||||||
import {notNull} from '../utils/typeUtils';
|
import {notNull} from '../utils/typeUtils';
|
||||||
|
|
||||||
export default function (store: Store, logger: Logger): () => Promise<void> {
|
export default async function (
|
||||||
|
store: Store,
|
||||||
|
logger: Logger,
|
||||||
|
): Promise<() => Promise<void>> {
|
||||||
// This only runs in development as when the reload
|
// This only runs in development as when the reload
|
||||||
// kicks in it doesn't unregister the shortcuts
|
// kicks in it doesn't unregister the shortcuts
|
||||||
const dispatchers: Array<Dispatcher> = [
|
const dispatchers: Array<Dispatcher> = [
|
||||||
@@ -43,10 +46,11 @@ export default function (store: Store, logger: Logger): () => Promise<void> {
|
|||||||
pluginChangeListener,
|
pluginChangeListener,
|
||||||
pluginsSourceUpdateListener,
|
pluginsSourceUpdateListener,
|
||||||
].filter(notNull);
|
].filter(notNull);
|
||||||
const globalCleanup = dispatchers
|
const globalCleanup = await Promise.all(
|
||||||
.map((dispatcher) => dispatcher(store, logger))
|
dispatchers.map((dispatcher) => dispatcher(store, logger)).filter(Boolean),
|
||||||
.filter(Boolean);
|
);
|
||||||
return () => {
|
|
||||||
return Promise.all(globalCleanup).then(() => {});
|
return async () => {
|
||||||
|
await Promise.all(globalCleanup);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,5 +196,4 @@ function registerStartupTime(logger: Logger) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
renderHost.sendIpcEvent('getLaunchTime');
|
renderHost.sendIpcEvent('getLaunchTime');
|
||||||
renderHost.sendIpcEvent('componentDidMount');
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,9 +149,10 @@ function init(flipperServer: FlipperServer) {
|
|||||||
loadTheme(settings.darkMode);
|
loadTheme(settings.darkMode);
|
||||||
|
|
||||||
// rehydrate app state before exposing init
|
// rehydrate app state before exposing init
|
||||||
const persistor = persistStore(store, undefined, () => {
|
const persistor = persistStore(store, undefined, async () => {
|
||||||
// Make sure process state is set before dispatchers run
|
// Make sure process state is set before dispatchers run
|
||||||
dispatcher(store, logger);
|
await dispatcher(store, logger);
|
||||||
|
getRenderHostInstance().sendIpcEvent('storeRehydrated');
|
||||||
});
|
});
|
||||||
|
|
||||||
setPersistor(persistor);
|
setPersistor(persistor);
|
||||||
@@ -168,17 +169,17 @@ function init(flipperServer: FlipperServer) {
|
|||||||
|
|
||||||
connectFlipperServerToStore(flipperServer, store, logger);
|
connectFlipperServerToStore(flipperServer, store, logger);
|
||||||
|
|
||||||
|
enableConsoleHook();
|
||||||
|
enableConnectivityHook(flipperServer);
|
||||||
|
|
||||||
// TODO T116224873: Return the following code back instead of ReactDOM.react when the following issue is fixed: https://github.com/react-component/trigger/issues/288
|
// TODO T116224873: Return the following code back instead of ReactDOM.react when the following issue is fixed: https://github.com/react-component/trigger/issues/288
|
||||||
// const root = createRoot(document.getElementById('root')!);
|
// const root = createRoot(document.getElementById('root')!);
|
||||||
// root.render(<AppFrame logger={logger} persistor={persistor} />);
|
// root.render(<AppFrame logger={logger} persistor={persistor} />);
|
||||||
|
|
||||||
ReactDOM.render(
|
const root = document.getElementById('root');
|
||||||
<AppFrame logger={logger} persistor={persistor} />,
|
if (root) {
|
||||||
document.getElementById('root')!,
|
ReactDOM.render(<AppFrame logger={logger} persistor={persistor} />, root);
|
||||||
);
|
}
|
||||||
|
|
||||||
enableConsoleHook();
|
|
||||||
enableConnectivityHook(flipperServer);
|
|
||||||
|
|
||||||
const launcherMessage =
|
const launcherMessage =
|
||||||
getRenderHostInstance().serverConfig.processConfig.launcherMsg;
|
getRenderHostInstance().serverConfig.processConfig.launcherMsg;
|
||||||
@@ -193,8 +194,8 @@ function init(flipperServer: FlipperServer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startFlipperDesktop(flipperServer: FlipperServer) {
|
export function startFlipperDesktop(flipperServer: FlipperServer) {
|
||||||
getRenderHostInstance(); // renderHost instance should be set at this point!
|
getRenderHostInstance();
|
||||||
init(flipperServer);
|
init(flipperServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {TestIdler} from './Idler';
|
|||||||
import {processMessageQueue} from './messageQueue';
|
import {processMessageQueue} from './messageQueue';
|
||||||
import {getPluginTitle} from './pluginUtils';
|
import {getPluginTitle} from './pluginUtils';
|
||||||
import {capture} from './screenshot';
|
import {capture} from './screenshot';
|
||||||
import {Dialog, getFlipperLib, Idler, path} from 'flipper-plugin';
|
import {Dialog, getFlipperLib, Idler} from 'flipper-plugin';
|
||||||
import {ClientQuery} from 'flipper-common';
|
import {ClientQuery} from 'flipper-common';
|
||||||
import ShareSheetExportUrl from '../chrome/ShareSheetExportUrl';
|
import ShareSheetExportUrl from '../chrome/ShareSheetExportUrl';
|
||||||
import ShareSheetExportFile from '../chrome/ShareSheetExportFile';
|
import ShareSheetExportFile from '../chrome/ShareSheetExportFile';
|
||||||
@@ -43,6 +43,7 @@ import {safeFilename} from './safeFilename';
|
|||||||
import {getExportablePlugins} from '../selectors/connections';
|
import {getExportablePlugins} from '../selectors/connections';
|
||||||
import {notification} from 'antd';
|
import {notification} from 'antd';
|
||||||
import openSupportRequestForm from '../fb-stubs/openSupportRequestForm';
|
import openSupportRequestForm from '../fb-stubs/openSupportRequestForm';
|
||||||
|
import {getStore} from '../store';
|
||||||
|
|
||||||
export const IMPORT_FLIPPER_TRACE_EVENT = 'import-flipper-trace';
|
export const IMPORT_FLIPPER_TRACE_EVENT = 'import-flipper-trace';
|
||||||
export const EXPORT_FLIPPER_TRACE_EVENT = 'export-flipper-trace';
|
export const EXPORT_FLIPPER_TRACE_EVENT = 'export-flipper-trace';
|
||||||
@@ -526,7 +527,7 @@ export const exportStoreToFile = (
|
|||||||
export async function importDataToStore(
|
export async function importDataToStore(
|
||||||
source: string,
|
source: string,
|
||||||
data: string,
|
data: string,
|
||||||
store: Store,
|
store: Store = getStore(),
|
||||||
) {
|
) {
|
||||||
getLogger().track('usage', IMPORT_FLIPPER_TRACE_EVENT);
|
getLogger().track('usage', IMPORT_FLIPPER_TRACE_EVENT);
|
||||||
const json: ExportType = JSON.parse(data);
|
const json: ExportType = JSON.parse(data);
|
||||||
|
|||||||
@@ -138,25 +138,6 @@
|
|||||||
document.body.appendChild(script);
|
document.body.appendChild(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
navigator.serviceWorker
|
|
||||||
.register('/service-worker.js')
|
|
||||||
.then(() => {
|
|
||||||
console.log('Flipper Service Worker has been registered');
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.error('Flipper failed to register Service Worker', e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('beforeinstallprompt', (e) => {
|
|
||||||
console.log('Flipper PWA before install prompt with event', e);
|
|
||||||
// Prevent Chrome 67 and earlier from automatically showing the prompt.
|
|
||||||
e.preventDefault();
|
|
||||||
// Stash the event so it can be triggered later.
|
|
||||||
global.PWAppInstallationEvent = e;
|
|
||||||
});
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="__infinity-dev-box __infinity-dev-box-error" hidden />
|
<div class="__infinity-dev-box __infinity-dev-box-error" hidden></div>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
// FIXME: needed to make Metro work
|
// FIXME: needed to make Metro work
|
||||||
@@ -114,25 +114,6 @@
|
|||||||
|
|
||||||
document.body.appendChild(script);
|
document.body.appendChild(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
navigator.serviceWorker
|
|
||||||
.register('/service-worker.js')
|
|
||||||
.then(() => {
|
|
||||||
console.log('Flipper Service Worker has been registered');
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.error('Flipper failed to register Service Worker', e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('beforeinstallprompt', (e) => {
|
|
||||||
// Prevent Chrome 67 and earlier from automatically showing the prompt.
|
|
||||||
e.preventDefault();
|
|
||||||
// Stash the event so it can be triggered later.
|
|
||||||
global.PWAppInstallationEvent = e;
|
|
||||||
});
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -63,14 +63,6 @@ if (process.platform === 'darwin') {
|
|||||||
const argv = yargs
|
const argv = yargs
|
||||||
.usage('$0 [args]')
|
.usage('$0 [args]')
|
||||||
.options({
|
.options({
|
||||||
file: {
|
|
||||||
describe: 'Define a file to open on startup.',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
url: {
|
|
||||||
describe: 'Define a flipper:// URL to open on startup.',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
updater: {
|
updater: {
|
||||||
default: true,
|
default: true,
|
||||||
describe: 'Toggle the built-in update mechanism.',
|
describe: 'Toggle the built-in update mechanism.',
|
||||||
@@ -114,9 +106,8 @@ if (argv['disable-gpu'] || process.env.FLIPPER_DISABLE_GPU === '1') {
|
|||||||
// possible reference to main app window
|
// possible reference to main app window
|
||||||
let win: BrowserWindow;
|
let win: BrowserWindow;
|
||||||
let appReady = false;
|
let appReady = false;
|
||||||
let deeplinkURL: string | undefined = argv.url;
|
let deeplinkURL: string | undefined;
|
||||||
let filePath: string | undefined = argv.file;
|
let filePath: string | undefined;
|
||||||
let didMount = false;
|
|
||||||
|
|
||||||
// check if we already have an instance of this app open
|
// check if we already have an instance of this app open
|
||||||
const gotTheLock = app.requestSingleInstanceLock();
|
const gotTheLock = app.requestSingleInstanceLock();
|
||||||
@@ -138,6 +129,24 @@ if (!gotTheLock) {
|
|||||||
app.on('ready', () => {});
|
app.on('ready', () => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openFileIfAny = () => {
|
||||||
|
if (!filePath || !win) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fs.readFile(filePath, {encoding: 'utf-8'}, (_err, data) => {
|
||||||
|
win.webContents.send('open-flipper-file', filePath, data);
|
||||||
|
filePath = undefined;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const openURLIfAny = () => {
|
||||||
|
if (!deeplinkURL || !win) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
win.webContents.send('flipper-protocol-handler', deeplinkURL);
|
||||||
|
deeplinkURL = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
// quit app once all windows are closed
|
// quit app once all windows are closed
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
appReady = false;
|
appReady = false;
|
||||||
@@ -148,22 +157,16 @@ app.on('will-finish-launching', () => {
|
|||||||
// Protocol handler for osx
|
// Protocol handler for osx
|
||||||
app.on('open-url', function (event, url) {
|
app.on('open-url', function (event, url) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
argv.url = url;
|
|
||||||
if (win && didMount) {
|
|
||||||
win.webContents.send('flipper-protocol-handler', url);
|
|
||||||
} else {
|
|
||||||
deeplinkURL = url;
|
deeplinkURL = url;
|
||||||
}
|
openURLIfAny();
|
||||||
});
|
});
|
||||||
app.on('open-file', (event, path) => {
|
app.on('open-file', (event, path) => {
|
||||||
// When flipper app is running, and someone double clicks the import file, `componentDidMount` will not be called again and windows object will exist in that case. That's why calling `win.webContents.send('open-flipper-file', filePath);` again.
|
// When flipper app is running, and someone double clicks the import file,
|
||||||
|
// component and store is already mounted and the windows object will exist.
|
||||||
|
// In that case, the file can be immediately opened.
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
filePath = path;
|
filePath = path;
|
||||||
argv.file = path;
|
openFileIfAny();
|
||||||
if (win) {
|
|
||||||
win.webContents.send('open-flipper-file', filePath);
|
|
||||||
filePath = undefined;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -256,17 +259,9 @@ function configureSession() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcMain.on('componentDidMount', (_event) => {
|
ipcMain.on('storeRehydrated', (_event) => {
|
||||||
didMount = true;
|
openFileIfAny();
|
||||||
if (deeplinkURL) {
|
openURLIfAny();
|
||||||
win.webContents.send('flipper-protocol-handler', deeplinkURL);
|
|
||||||
deeplinkURL = undefined;
|
|
||||||
}
|
|
||||||
if (filePath) {
|
|
||||||
// When flipper app is not running, the windows object might not exist in the callback of `open-file`, but after ``componentDidMount` it will definitely exist.
|
|
||||||
win.webContents.send('open-flipper-file', filePath);
|
|
||||||
filePath = undefined;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('getLaunchTime', (event) => {
|
ipcMain.on('getLaunchTime', (event) => {
|
||||||
|
|||||||
@@ -14,5 +14,15 @@
|
|||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"sizes": "256x256"
|
"sizes": "256x256"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"file_handlers": [
|
||||||
|
{
|
||||||
|
"action": "/",
|
||||||
|
"accept": {
|
||||||
|
"text/*": [
|
||||||
|
".flipper"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,8 +52,7 @@ self.addEventListener('fetch', (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Always try the network first (try flipper server)
|
// Always try the network first (try flipper server)
|
||||||
const networkResponse = await fetch(event.request);
|
return await fetch(event.request);
|
||||||
return networkResponse;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Catch is only triggered if an exception is thrown, which is likely
|
// Catch is only triggered if an exception is thrown, which is likely
|
||||||
// due to a network error.
|
// due to a network error.
|
||||||
@@ -62,8 +61,7 @@ self.addEventListener('fetch', (event) => {
|
|||||||
console.log('Fetch failed; returning offline page instead.', error);
|
console.log('Fetch failed; returning offline page instead.', error);
|
||||||
|
|
||||||
const cache = await caches.open(CACHE_NAME);
|
const cache = await caches.open(CACHE_NAME);
|
||||||
const cachedResponse = await cache.match(OFFLINE_URL);
|
return await cache.match(OFFLINE_URL);
|
||||||
return cachedResponse;
|
|
||||||
}
|
}
|
||||||
})());
|
})());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user