Decouple open/save dialogs, reload, shouldUseDarkColors from Electron
Summary: Per title. Less imports from Electron. Reviewed By: timur-valiev, aigoncharov Differential Revision: D31923504 fbshipit-source-id: dc7557cf7c88c0c8168ba22f7dca7b3e2d339a09
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d5e4b0c360
commit
9763af4c96
@@ -37,6 +37,7 @@ import React from 'react';
|
|||||||
import ChangelogSheet from './chrome/ChangelogSheet';
|
import ChangelogSheet from './chrome/ChangelogSheet';
|
||||||
import PluginManager from './chrome/plugin-manager/PluginManager';
|
import PluginManager from './chrome/plugin-manager/PluginManager';
|
||||||
import SettingsSheet from './chrome/SettingsSheet';
|
import SettingsSheet from './chrome/SettingsSheet';
|
||||||
|
import reloadFlipper from './utils/reloadFlipper';
|
||||||
|
|
||||||
export type DefaultKeyboardAction = keyof typeof _buildInMenuEntries;
|
export type DefaultKeyboardAction = keyof typeof _buildInMenuEntries;
|
||||||
export type TopLevelMenu = 'Edit' | 'View' | 'Window' | 'Help';
|
export type TopLevelMenu = 'Edit' | 'View' | 'Window' | 'Help';
|
||||||
@@ -294,11 +295,9 @@ function getTemplate(
|
|||||||
{
|
{
|
||||||
label: 'Reload',
|
label: 'Reload',
|
||||||
accelerator: 'CmdOrCtrl+R',
|
accelerator: 'CmdOrCtrl+R',
|
||||||
click: function (_, focusedWindow: electron.BrowserWindow | undefined) {
|
click: function (_, _focusedWindow: electron.BrowserWindow | undefined) {
|
||||||
if (focusedWindow) {
|
|
||||||
logger.track('usage', 'reload');
|
logger.track('usage', 'reload');
|
||||||
focusedWindow.reload();
|
reloadFlipper();
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
import {NotificationEvents} from './dispatcher/notifications';
|
import {NotificationEvents} from './dispatcher/notifications';
|
||||||
import {PluginNotification} from './reducers/notifications';
|
import {PluginNotification} from './reducers/notifications';
|
||||||
import type {NotificationConstructorOptions} from 'electron';
|
import type {NotificationConstructorOptions} from 'electron';
|
||||||
|
import {FlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
// 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 = {
|
||||||
@@ -44,7 +45,9 @@ type ChildProcessEvents = {
|
|||||||
export interface RenderHost {
|
export interface RenderHost {
|
||||||
readonly processId: number;
|
readonly processId: number;
|
||||||
readTextFromClipboard(): string | undefined;
|
readTextFromClipboard(): string | undefined;
|
||||||
selectDirectory?(defaultPath?: string): Promise<string | undefined>;
|
showSaveDialog?: FlipperLib['showSaveDialog'];
|
||||||
|
showOpenDialog?: FlipperLib['showOpenDialog'];
|
||||||
|
showSelectDirectoryDialog?(defaultPath?: string): Promise<string | undefined>;
|
||||||
registerShortcut(shortCut: string, callback: () => void): void;
|
registerShortcut(shortCut: string, callback: () => void): void;
|
||||||
hasFocus(): boolean;
|
hasFocus(): boolean;
|
||||||
onIpcEvent<Event extends keyof MainProcessEvents>(
|
onIpcEvent<Event extends keyof MainProcessEvents>(
|
||||||
@@ -55,6 +58,7 @@ export interface RenderHost {
|
|||||||
event: Event,
|
event: Event,
|
||||||
...args: ChildProcessEvents[Event]
|
...args: ChildProcessEvents[Event]
|
||||||
): void;
|
): void;
|
||||||
|
shouldUseDarkColors(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let renderHostInstance: RenderHost | undefined;
|
let renderHostInstance: RenderHost | undefined;
|
||||||
@@ -82,5 +86,8 @@ if (process.env.NODE_ENV === 'test') {
|
|||||||
},
|
},
|
||||||
onIpcEvent() {},
|
onIpcEvent() {},
|
||||||
sendIpcEvent() {},
|
sendIpcEvent() {},
|
||||||
|
shouldUseDarkColors() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,11 +99,11 @@ export function FilePathConfigField(props: {
|
|||||||
.catch((_) => setIsValid(false));
|
.catch((_) => setIsValid(false));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{renderHost.selectDirectory && (
|
{renderHost.showSelectDirectoryDialog && (
|
||||||
<FlexColumn
|
<FlexColumn
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
renderHost
|
renderHost
|
||||||
.selectDirectory?.()
|
.showSelectDirectoryDialog?.()
|
||||||
.then((path) => {
|
.then((path) => {
|
||||||
if (path) {
|
if (path) {
|
||||||
setValue(path);
|
setValue(path);
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ function init() {
|
|||||||
|
|
||||||
setPersistor(persistor);
|
setPersistor(persistor);
|
||||||
|
|
||||||
initializeFlipperLibImplementation(store, logger);
|
initializeFlipperLibImplementation(getRenderHostInstance(), store, logger);
|
||||||
_setGlobalInteractionReporter((r) => {
|
_setGlobalInteractionReporter((r) => {
|
||||||
logger.track('usage', 'interaction', r);
|
logger.track('usage', 'interaction', r);
|
||||||
if (!isProduction()) {
|
if (!isProduction()) {
|
||||||
@@ -230,26 +230,20 @@ function init() {
|
|||||||
sideEffect(
|
sideEffect(
|
||||||
store,
|
store,
|
||||||
{name: 'loadTheme', fireImmediately: false, throttleMs: 500},
|
{name: 'loadTheme', fireImmediately: false, throttleMs: 500},
|
||||||
(state) => {
|
(state) => state.settingsState.darkMode,
|
||||||
const theme = state.settingsState.darkMode;
|
(theme) => {
|
||||||
let shouldUseDarkMode = false;
|
let shouldUseDarkMode = false;
|
||||||
if (theme === 'dark') {
|
if (theme === 'dark') {
|
||||||
shouldUseDarkMode = true;
|
shouldUseDarkMode = true;
|
||||||
} else if (theme === 'light') {
|
} else if (theme === 'light') {
|
||||||
shouldUseDarkMode = false;
|
shouldUseDarkMode = false;
|
||||||
} else if (theme === 'system') {
|
} else if (theme === 'system') {
|
||||||
shouldUseDarkMode = remote.nativeTheme.shouldUseDarkColors;
|
shouldUseDarkMode = getRenderHostInstance().shouldUseDarkColors();
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
shouldUseDarkMode: shouldUseDarkMode,
|
|
||||||
theme: theme,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
(result) => {
|
|
||||||
(
|
(
|
||||||
document.getElementById('flipper-theme-import') as HTMLLinkElement
|
document.getElementById('flipper-theme-import') as HTMLLinkElement
|
||||||
).href = `themes/${result.shouldUseDarkMode ? 'dark' : 'light'}.css`;
|
).href = `themes/${shouldUseDarkMode ? 'dark' : 'light'}.css`;
|
||||||
getRenderHostInstance().sendIpcEvent('setTheme', result.theme);
|
getRenderHostInstance().sendIpcEvent('setTheme', theme);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -272,10 +266,21 @@ function initializeFlipperForElectron() {
|
|||||||
readTextFromClipboard() {
|
readTextFromClipboard() {
|
||||||
return clipboard.readText();
|
return clipboard.readText();
|
||||||
},
|
},
|
||||||
selectDirectory(defaultPath = path.resolve('/')) {
|
async showSaveDialog(options) {
|
||||||
|
return (await remote.dialog.showSaveDialog(options))?.filePath;
|
||||||
|
},
|
||||||
|
async showOpenDialog({filter, defaultPath}) {
|
||||||
|
const result = await remote.dialog.showOpenDialog({
|
||||||
|
defaultPath,
|
||||||
|
properties: ['openFile'],
|
||||||
|
filters: filter ? [filter] : undefined,
|
||||||
|
});
|
||||||
|
return result.filePaths?.[0];
|
||||||
|
},
|
||||||
|
showSelectDirectoryDialog(defaultPath = path.resolve('/')) {
|
||||||
return remote.dialog
|
return remote.dialog
|
||||||
.showOpenDialog({
|
.showOpenDialog({
|
||||||
properties: ['openDirectory', 'showHiddenFiles'],
|
properties: ['openDirectory'],
|
||||||
defaultPath,
|
defaultPath,
|
||||||
})
|
})
|
||||||
.then((result: SaveDialogReturnValue & {filePaths: string[]}) => {
|
.then((result: SaveDialogReturnValue & {filePaths: string[]}) => {
|
||||||
@@ -305,5 +310,8 @@ function initializeFlipperForElectron() {
|
|||||||
sendIpcEvent(event, ...args: any[]) {
|
sendIpcEvent(event, ...args: any[]) {
|
||||||
ipcRenderer.send(event, ...args);
|
ipcRenderer.send(event, ...args);
|
||||||
},
|
},
|
||||||
|
shouldUseDarkColors() {
|
||||||
|
return remote.nativeTheme.shouldUseDarkColors;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import ArchivedDevice from '../devices/ArchivedDevice';
|
|||||||
import {ClientQuery, DeviceOS} from 'flipper-common';
|
import {ClientQuery, DeviceOS} from 'flipper-common';
|
||||||
import {TestDevice} from './TestDevice';
|
import {TestDevice} from './TestDevice';
|
||||||
import {createFlipperServerMock} from './createFlipperServerMock';
|
import {createFlipperServerMock} from './createFlipperServerMock';
|
||||||
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
|
||||||
export interface AppOptions {
|
export interface AppOptions {
|
||||||
plugins?: PluginDefinition[];
|
plugins?: PluginDefinition[];
|
||||||
@@ -89,7 +90,11 @@ export default class MockFlipper {
|
|||||||
this.unsubscribePluginManager = pluginManager(this._store, this._logger, {
|
this.unsubscribePluginManager = pluginManager(this._store, this._logger, {
|
||||||
runSideEffectsSynchronously: true,
|
runSideEffectsSynchronously: true,
|
||||||
});
|
});
|
||||||
initializeFlipperLibImplementation(this._store, this._logger);
|
initializeFlipperLibImplementation(
|
||||||
|
getRenderHostInstance(),
|
||||||
|
this._store,
|
||||||
|
this._logger,
|
||||||
|
);
|
||||||
this._store.dispatch(registerPlugins(plugins ?? []));
|
this._store.dispatch(registerPlugins(plugins ?? []));
|
||||||
this._store.dispatch({
|
this._store.dispatch({
|
||||||
type: 'SET_FLIPPER_SERVER',
|
type: 'SET_FLIPPER_SERVER',
|
||||||
|
|||||||
@@ -11,12 +11,11 @@ import React, {useState} from 'react';
|
|||||||
import FlexRow from './FlexRow';
|
import FlexRow from './FlexRow';
|
||||||
import Glyph from './Glyph';
|
import Glyph from './Glyph';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
import electron from 'electron';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {colors} from './colors';
|
import {colors} from './colors';
|
||||||
import Electron from 'electron';
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import {Tooltip} from '..';
|
import {Tooltip} from '..';
|
||||||
|
import {getFlipperLib} from 'flipper-plugin';
|
||||||
|
|
||||||
const CenteredGlyph = styled(Glyph)({
|
const CenteredGlyph = styled(Glyph)({
|
||||||
margin: 'auto',
|
margin: 'auto',
|
||||||
@@ -41,40 +40,25 @@ const FileInputBox = styled(Input)<{isValid: boolean}>(({isValid}) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function strToArr<T extends string>(item: T): T[] {
|
|
||||||
return [item];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
onPathChanged: (evtArgs: {path: string; isValid: boolean}) => void;
|
onPathChanged: (evtArgs: {path: string; isValid: boolean}) => void;
|
||||||
placeholderText: string;
|
placeholderText: string;
|
||||||
defaultPath: string;
|
defaultPath: string;
|
||||||
showHiddenFiles: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultProps: Props = {
|
const defaultProps: Props = {
|
||||||
onPathChanged: (_) => {},
|
onPathChanged: (_) => {},
|
||||||
placeholderText: '',
|
placeholderText: '',
|
||||||
defaultPath: '/',
|
defaultPath: '/',
|
||||||
showHiddenFiles: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function FileSelector({
|
export default function FileSelector({
|
||||||
onPathChanged,
|
onPathChanged,
|
||||||
placeholderText,
|
placeholderText,
|
||||||
|
|
||||||
defaultPath,
|
defaultPath,
|
||||||
showHiddenFiles,
|
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [value, setValue] = useState('');
|
const [value, setValue] = useState('');
|
||||||
const [isValid, setIsValid] = useState(false);
|
const [isValid, setIsValid] = useState(false);
|
||||||
const options: Electron.OpenDialogOptions = {
|
|
||||||
properties: [
|
|
||||||
'openFile',
|
|
||||||
...(showHiddenFiles ? strToArr('showHiddenFiles') : []),
|
|
||||||
],
|
|
||||||
defaultPath,
|
|
||||||
};
|
|
||||||
const onChange = (path: string) => {
|
const onChange = (path: string) => {
|
||||||
setValue(path);
|
setValue(path);
|
||||||
let isNewPathValid = false;
|
let isNewPathValid = false;
|
||||||
@@ -103,11 +87,11 @@ export default function FileSelector({
|
|||||||
/>
|
/>
|
||||||
<GlyphContainer
|
<GlyphContainer
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
electron.remote.dialog
|
getFlipperLib()
|
||||||
.showOpenDialog(options)
|
.showOpenDialog?.({defaultPath})
|
||||||
.then((result: electron.OpenDialogReturnValue) => {
|
.then((path) => {
|
||||||
if (result && !result.canceled && result.filePaths.length) {
|
if (path) {
|
||||||
onChange(result.filePaths[0]);
|
onChange(path);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import electron from 'electron';
|
|
||||||
import {getLogger} from 'flipper-common';
|
import {getLogger} from 'flipper-common';
|
||||||
import {Store, MiddlewareAPI} from '../reducers';
|
import {Store, MiddlewareAPI} from '../reducers';
|
||||||
import {DeviceExport} from '../devices/BaseDevice';
|
import {DeviceExport} from '../devices/BaseDevice';
|
||||||
@@ -24,7 +23,6 @@ import {default as BaseDevice} from '../devices/BaseDevice';
|
|||||||
import {default as ArchivedDevice} from '../devices/ArchivedDevice';
|
import {default as ArchivedDevice} from '../devices/ArchivedDevice';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import {v4 as uuidv4} from 'uuid';
|
import {v4 as uuidv4} from 'uuid';
|
||||||
import {remote, OpenDialogOptions} from 'electron';
|
|
||||||
import {readCurrentRevision} from './packageMetadata';
|
import {readCurrentRevision} from './packageMetadata';
|
||||||
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
import {tryCatchReportPlatformFailures} from 'flipper-common';
|
||||||
import {promisify} from 'util';
|
import {promisify} from 'util';
|
||||||
@@ -45,6 +43,7 @@ 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';
|
||||||
import ExportDataPluginSheet from '../chrome/ExportDataPluginSheet';
|
import ExportDataPluginSheet from '../chrome/ExportDataPluginSheet';
|
||||||
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
|
||||||
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';
|
||||||
@@ -602,30 +601,24 @@ export const importFileToStore = (file: string, store: Store) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function showOpenDialog(store: Store) {
|
export function showOpenDialog(store: Store) {
|
||||||
const options: OpenDialogOptions = {
|
return getRenderHostInstance()
|
||||||
properties: ['openFile'],
|
.showOpenDialog?.({
|
||||||
filters: [{extensions: ['flipper', 'json', 'txt'], name: 'Flipper files'}],
|
filter: {extensions: ['flipper', 'json', 'txt'], name: 'Flipper files'},
|
||||||
};
|
})
|
||||||
remote.dialog.showOpenDialog(options).then((result) => {
|
.then((filePath) => {
|
||||||
const filePaths = result.filePaths;
|
if (filePath) {
|
||||||
if (filePaths.length > 0) {
|
|
||||||
tryCatchReportPlatformFailures(() => {
|
tryCatchReportPlatformFailures(() => {
|
||||||
importFileToStore(filePaths[0], store);
|
importFileToStore(filePath, store);
|
||||||
}, `${IMPORT_FLIPPER_TRACE_EVENT}:UI`);
|
}, `${IMPORT_FLIPPER_TRACE_EVENT}:UI`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startFileExport(dispatch: Store['dispatch']) {
|
export async function startFileExport(dispatch: Store['dispatch']) {
|
||||||
const result = await electron.remote.dialog.showSaveDialog(
|
const file = await getRenderHostInstance().showSaveDialog?.({
|
||||||
// @ts-ignore This appears to work but isn't allowed by the types
|
|
||||||
null,
|
|
||||||
{
|
|
||||||
title: 'FlipperExport',
|
title: 'FlipperExport',
|
||||||
defaultPath: path.join(os.homedir(), 'FlipperExport.flipper'),
|
defaultPath: path.join(os.homedir(), 'FlipperExport.flipper'),
|
||||||
},
|
});
|
||||||
);
|
|
||||||
const file = result.filePath;
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ import constants from '../fb-stubs/constants';
|
|||||||
import {addNotification} from '../reducers/notifications';
|
import {addNotification} from '../reducers/notifications';
|
||||||
import {deconstructPluginKey} from 'flipper-common';
|
import {deconstructPluginKey} from 'flipper-common';
|
||||||
import {DetailSidebarImpl} from '../sandy-chrome/DetailSidebarImpl';
|
import {DetailSidebarImpl} from '../sandy-chrome/DetailSidebarImpl';
|
||||||
|
import {RenderHost} from '../RenderHost';
|
||||||
|
|
||||||
export function initializeFlipperLibImplementation(
|
export function initializeFlipperLibImplementation(
|
||||||
|
renderHost: RenderHost,
|
||||||
store: Store,
|
store: Store,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
) {
|
) {
|
||||||
@@ -64,5 +66,8 @@ export function initializeFlipperLibImplementation(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
DetailsSidebarImplementation: DetailSidebarImpl,
|
DetailsSidebarImplementation: DetailSidebarImpl,
|
||||||
|
showSaveDialog: renderHost.showSaveDialog,
|
||||||
|
showOpenDialog: renderHost.showOpenDialog,
|
||||||
|
showSelectDirectoryDialog: renderHost.showSelectDirectoryDialog,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,4 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {remote} from 'electron';
|
export default () => window.location.reload();
|
||||||
export default () => remote.getCurrentWindow().reload();
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {useStore} from './useStore';
|
import {useStore} from './useStore';
|
||||||
import {remote} from 'electron';
|
import {getRenderHostInstance} from '../RenderHost';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This hook returns whether dark mode is currently being used.
|
* This hook returns whether dark mode is currently being used.
|
||||||
@@ -16,15 +16,13 @@ import {remote} from 'electron';
|
|||||||
* which will provide colors that reflect the theme
|
* which will provide colors that reflect the theme
|
||||||
*/
|
*/
|
||||||
export function useIsDarkMode(): boolean {
|
export function useIsDarkMode(): boolean {
|
||||||
return useStore((state) => {
|
const darkMode = useStore((state) => state.settingsState.darkMode);
|
||||||
const darkMode = state.settingsState.darkMode;
|
|
||||||
if (darkMode === 'dark') {
|
if (darkMode === 'dark') {
|
||||||
return true;
|
return true;
|
||||||
} else if (darkMode === 'light') {
|
} else if (darkMode === 'light') {
|
||||||
return false;
|
return false;
|
||||||
} else if (darkMode === 'system') {
|
} else if (darkMode === 'system') {
|
||||||
return remote.nativeTheme.shouldUseDarkColors;
|
return getRenderHostInstance().shouldUseDarkColors();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,19 @@ export interface FlipperLib {
|
|||||||
DetailsSidebarImplementation?(
|
DetailsSidebarImplementation?(
|
||||||
props: DetailSidebarProps,
|
props: DetailSidebarProps,
|
||||||
): React.ReactElement | null;
|
): React.ReactElement | null;
|
||||||
|
showSaveDialog?(options: {
|
||||||
|
defaultPath?: string;
|
||||||
|
message?: string;
|
||||||
|
title?: string;
|
||||||
|
}): Promise<string | undefined>;
|
||||||
|
showOpenDialog?(options: {
|
||||||
|
defaultPath?: string;
|
||||||
|
filter?: {
|
||||||
|
extensions: string[];
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
}): Promise<string | undefined>;
|
||||||
|
showSelectDirectoryDialog?(defaultPath?: string): Promise<string | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let flipperLibInstance: FlipperLib | undefined;
|
export let flipperLibInstance: FlipperLib | undefined;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
import electron, {OpenDialogOptions, remote} from 'electron';
|
import electron, {OpenDialogOptions, remote} from 'electron';
|
||||||
import {Atom, DataTableManager} from 'flipper-plugin';
|
import {Atom, DataTableManager, getFlipperLib} from 'flipper-plugin';
|
||||||
import {createContext} from 'react';
|
import {createContext} from 'react';
|
||||||
import {Header, Request} from '../types';
|
import {Header, Request} from '../types';
|
||||||
import {message} from 'antd';
|
import {message} from 'antd';
|
||||||
@@ -137,16 +137,13 @@ export function createNetworkManager(
|
|||||||
informClientMockChange(routes.get());
|
informClientMockChange(routes.get());
|
||||||
},
|
},
|
||||||
importRoutes() {
|
importRoutes() {
|
||||||
const options: OpenDialogOptions = {
|
getFlipperLib()
|
||||||
properties: ['openFile'],
|
.showOpenDialog?.({
|
||||||
filters: [{extensions: ['json'], name: 'Flipper Route Files'}],
|
filter: {extensions: ['json'], name: 'Flipper Route Files'},
|
||||||
};
|
})
|
||||||
remote.dialog
|
.then((filePath) => {
|
||||||
.showOpenDialog(options)
|
if (filePath) {
|
||||||
.then((result) => {
|
fs.readFile(filePath, 'utf8', (err, data) => {
|
||||||
const filePaths = result.filePaths;
|
|
||||||
if (filePaths.length > 0) {
|
|
||||||
fs.readFile(filePaths[0], 'utf8', (err, data) => {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
message.error('Unable to import file');
|
message.error('Unable to import file');
|
||||||
return;
|
return;
|
||||||
@@ -177,17 +174,12 @@ export function createNetworkManager(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
exportRoutes() {
|
exportRoutes() {
|
||||||
remote.dialog
|
getFlipperLib()
|
||||||
.showSaveDialog(
|
.showSaveDialog?.({
|
||||||
// @ts-ignore This appears to work but isn't allowed by the types
|
|
||||||
null,
|
|
||||||
{
|
|
||||||
title: 'Export Routes',
|
title: 'Export Routes',
|
||||||
defaultPath: 'NetworkPluginRoutesExport.json',
|
defaultPath: 'NetworkPluginRoutesExport.json',
|
||||||
},
|
})
|
||||||
)
|
.then((file) => {
|
||||||
.then((result: electron.SaveDialogReturnValue) => {
|
|
||||||
const file = result.filePath;
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user