Support importing multiple files and encoding
Summary: 1. Support importing multiple files 2. Support file encoding Reviewed By: mweststrate Differential Revision: D32540132 fbshipit-source-id: 7c2a96ac585f58d01457cb487527940e333da615
This commit is contained in:
committed by
Facebook GitHub Bot
parent
b77cb0d6c3
commit
3491926d17
@@ -111,27 +111,46 @@ export function initializeElectron() {
|
|||||||
return undefined;
|
return undefined;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async importFile({defaultPath, extensions} = {}) {
|
importFile: (async ({
|
||||||
const {filePaths} = await remote.dialog.showOpenDialog({
|
defaultPath,
|
||||||
|
extensions,
|
||||||
|
title,
|
||||||
|
encoding = 'utf-8',
|
||||||
|
multi,
|
||||||
|
} = {}) => {
|
||||||
|
let {filePaths} = await remote.dialog.showOpenDialog({
|
||||||
defaultPath,
|
defaultPath,
|
||||||
properties: ['openFile'],
|
properties: [
|
||||||
|
'openFile',
|
||||||
|
...(multi ? (['multiSelections'] as const) : []),
|
||||||
|
],
|
||||||
filters: extensions ? [{extensions, name: ''}] : undefined,
|
filters: extensions ? [{extensions, name: ''}] : undefined,
|
||||||
|
title,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!filePaths.length) {
|
if (!filePaths.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filePath = filePaths[0];
|
if (!multi) {
|
||||||
const fileName = path.basename(filePath);
|
filePaths = [filePaths[0]];
|
||||||
|
}
|
||||||
|
|
||||||
const data = await fs.promises.readFile(filePath, {encoding: 'utf-8'});
|
const descriptors = await Promise.all(
|
||||||
return {
|
filePaths.map(async (filePath) => {
|
||||||
data,
|
const fileName = path.basename(filePath);
|
||||||
name: fileName,
|
|
||||||
};
|
const data = await fs.promises.readFile(filePath, {encoding});
|
||||||
},
|
return {
|
||||||
async exportFile(data, {defaultPath} = {}) {
|
data,
|
||||||
|
name: fileName,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return multi ? descriptors : descriptors[0];
|
||||||
|
}) as RenderHost['importFile'],
|
||||||
|
async exportFile(data, {defaultPath, encoding = 'utf-8'} = {}) {
|
||||||
const {filePath} = await remote.dialog.showSaveDialog({
|
const {filePath} = await remote.dialog.showSaveDialog({
|
||||||
defaultPath,
|
defaultPath,
|
||||||
});
|
});
|
||||||
@@ -140,7 +159,7 @@ export function initializeElectron() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.promises.writeFile(filePath, data);
|
await fs.promises.writeFile(filePath, data, {encoding});
|
||||||
return filePath;
|
return filePath;
|
||||||
},
|
},
|
||||||
openLink(url: string) {
|
openLink(url: string) {
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ test('Correct top level API exposed', () => {
|
|||||||
"ElementsInspectorElement",
|
"ElementsInspectorElement",
|
||||||
"ElementsInspectorProps",
|
"ElementsInspectorProps",
|
||||||
"FileDescriptor",
|
"FileDescriptor",
|
||||||
|
"FileEncoding",
|
||||||
"FlipperLib",
|
"FlipperLib",
|
||||||
"HighlightManager",
|
"HighlightManager",
|
||||||
"Idler",
|
"Idler",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export {
|
|||||||
getFlipperLib,
|
getFlipperLib,
|
||||||
setFlipperLibImplementation as _setFlipperLibImplementation,
|
setFlipperLibImplementation as _setFlipperLibImplementation,
|
||||||
FileDescriptor,
|
FileDescriptor,
|
||||||
|
FileEncoding,
|
||||||
} from './plugin/FlipperLib';
|
} from './plugin/FlipperLib';
|
||||||
export {
|
export {
|
||||||
MenuEntry,
|
MenuEntry,
|
||||||
|
|||||||
@@ -14,9 +14,12 @@ import {RealFlipperClient} from './Plugin';
|
|||||||
import {Notification} from './Notification';
|
import {Notification} from './Notification';
|
||||||
import {DetailSidebarProps} from '../ui/DetailSidebar';
|
import {DetailSidebarProps} from '../ui/DetailSidebar';
|
||||||
|
|
||||||
|
export type FileEncoding = 'utf-8' | 'base64';
|
||||||
|
|
||||||
export interface FileDescriptor {
|
export interface FileDescriptor {
|
||||||
data: string;
|
data: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
path?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,6 +43,10 @@ export interface FlipperLib {
|
|||||||
DetailsSidebarImplementation?(
|
DetailsSidebarImplementation?(
|
||||||
props: DetailSidebarProps,
|
props: DetailSidebarProps,
|
||||||
): React.ReactElement | null;
|
): React.ReactElement | null;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* Will be removed in subsequent commits
|
||||||
|
*/
|
||||||
showOpenDialog?(options: {
|
showOpenDialog?(options: {
|
||||||
defaultPath?: string;
|
defaultPath?: string;
|
||||||
filter?: {
|
filter?: {
|
||||||
@@ -52,19 +59,64 @@ export interface FlipperLib {
|
|||||||
* Imported file data.
|
* Imported file data.
|
||||||
* If user cancelled a file selection - undefined.
|
* If user cancelled a file selection - undefined.
|
||||||
*/
|
*/
|
||||||
importFile(options: {
|
importFile(options?: {
|
||||||
|
/**
|
||||||
|
* Default directory to start the file selection from
|
||||||
|
*/
|
||||||
|
defaultPath?: string;
|
||||||
|
/**
|
||||||
|
* List of allowed file extensions
|
||||||
|
*/
|
||||||
|
extensions?: string[];
|
||||||
|
/**
|
||||||
|
* Open file dialog title
|
||||||
|
*/
|
||||||
|
title?: string;
|
||||||
|
/**
|
||||||
|
* File encoding
|
||||||
|
*/
|
||||||
|
encoding?: FileEncoding;
|
||||||
|
/**
|
||||||
|
* Allow selection of multiple files
|
||||||
|
*/
|
||||||
|
multi?: false;
|
||||||
|
}): Promise<FileDescriptor | undefined>;
|
||||||
|
importFile(options?: {
|
||||||
defaultPath?: string;
|
defaultPath?: string;
|
||||||
extensions?: string[];
|
extensions?: string[];
|
||||||
}): Promise<FileDescriptor | undefined>;
|
title?: string;
|
||||||
|
encoding?: FileEncoding;
|
||||||
|
multi: true;
|
||||||
|
}): Promise<FileDescriptor[] | undefined>;
|
||||||
|
importFile(options?: {
|
||||||
|
defaultPath?: string;
|
||||||
|
extensions?: string[];
|
||||||
|
title?: string;
|
||||||
|
encoding?: FileEncoding;
|
||||||
|
multi?: boolean;
|
||||||
|
}): Promise<FileDescriptor[] | FileDescriptor | undefined>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns
|
* @returns
|
||||||
* An exported file path (if available) or a file name.
|
* An exported file path (if available) or a file name.
|
||||||
* If user cancelled a file selection - undefined.
|
* If user cancelled a file selection - undefined.
|
||||||
*/
|
*/
|
||||||
exportFile(
|
exportFile(
|
||||||
|
/**
|
||||||
|
* New file data
|
||||||
|
*/
|
||||||
data: string,
|
data: string,
|
||||||
options?: {
|
options?: {
|
||||||
|
/**
|
||||||
|
* A file path suggestion for a new file.
|
||||||
|
* A dialog to save file will use it as a starting point.
|
||||||
|
* Either a complete path to the newly created file, a path to a directory containing the file, or the file name.
|
||||||
|
*/
|
||||||
defaultPath?: string;
|
defaultPath?: string;
|
||||||
|
/**
|
||||||
|
* File encoding
|
||||||
|
*/
|
||||||
|
encoding?: FileEncoding;
|
||||||
},
|
},
|
||||||
): Promise<string | undefined>;
|
): Promise<string | undefined>;
|
||||||
paths: {
|
paths: {
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ export interface RenderHost {
|
|||||||
writeTextToClipboard(text: string): void;
|
writeTextToClipboard(text: string): void;
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
|
* WARNING!
|
||||||
|
* It is a low-level API call that might be removed in the future.
|
||||||
|
* It is not really deprecated yet, but we'll try to make it so.
|
||||||
* TODO: Remove in favor of "exportFile"
|
* TODO: Remove in favor of "exportFile"
|
||||||
*/
|
*/
|
||||||
showSaveDialog?(options: {
|
showSaveDialog?(options: {
|
||||||
@@ -68,9 +71,18 @@ export interface RenderHost {
|
|||||||
}): Promise<string | undefined>;
|
}): Promise<string | undefined>;
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
|
* WARNING!
|
||||||
|
* It is a low-level API call that might be removed in the future.
|
||||||
|
* It is not really deprecated yet, but we'll try to make it so.
|
||||||
* TODO: Remove in favor of "importFile"
|
* TODO: Remove in favor of "importFile"
|
||||||
*/
|
*/
|
||||||
showOpenDialog?: FlipperLib['showOpenDialog'];
|
showOpenDialog?(options: {
|
||||||
|
defaultPath?: string;
|
||||||
|
filter?: {
|
||||||
|
extensions: string[];
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
}): Promise<string | undefined>;
|
||||||
showSelectDirectoryDialog?(defaultPath?: string): Promise<string | undefined>;
|
showSelectDirectoryDialog?(defaultPath?: string): Promise<string | undefined>;
|
||||||
importFile: FlipperLib['importFile'];
|
importFile: FlipperLib['importFile'];
|
||||||
exportFile: FlipperLib['exportFile'];
|
exportFile: FlipperLib['exportFile'];
|
||||||
|
|||||||
Reference in New Issue
Block a user