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:
Andrey Goncharov
2021-11-26 08:28:50 -08:00
committed by Facebook GitHub Bot
parent b77cb0d6c3
commit 3491926d17
5 changed files with 101 additions and 16 deletions

View File

@@ -111,27 +111,46 @@ export function initializeElectron() {
return undefined;
});
},
async importFile({defaultPath, extensions} = {}) {
const {filePaths} = await remote.dialog.showOpenDialog({
importFile: (async ({
defaultPath,
extensions,
title,
encoding = 'utf-8',
multi,
} = {}) => {
let {filePaths} = await remote.dialog.showOpenDialog({
defaultPath,
properties: ['openFile'],
properties: [
'openFile',
...(multi ? (['multiSelections'] as const) : []),
],
filters: extensions ? [{extensions, name: ''}] : undefined,
title,
});
if (!filePaths.length) {
return;
}
const filePath = filePaths[0];
const fileName = path.basename(filePath);
if (!multi) {
filePaths = [filePaths[0]];
}
const data = await fs.promises.readFile(filePath, {encoding: 'utf-8'});
return {
data,
name: fileName,
};
},
async exportFile(data, {defaultPath} = {}) {
const descriptors = await Promise.all(
filePaths.map(async (filePath) => {
const fileName = path.basename(filePath);
const data = await fs.promises.readFile(filePath, {encoding});
return {
data,
name: fileName,
};
}),
);
return multi ? descriptors : descriptors[0];
}) as RenderHost['importFile'],
async exportFile(data, {defaultPath, encoding = 'utf-8'} = {}) {
const {filePath} = await remote.dialog.showSaveDialog({
defaultPath,
});
@@ -140,7 +159,7 @@ export function initializeElectron() {
return;
}
await fs.promises.writeFile(filePath, data);
await fs.promises.writeFile(filePath, data, {encoding});
return filePath;
},
openLink(url: string) {

View File

@@ -98,6 +98,7 @@ test('Correct top level API exposed', () => {
"ElementsInspectorElement",
"ElementsInspectorProps",
"FileDescriptor",
"FileEncoding",
"FlipperLib",
"HighlightManager",
"Idler",

View File

@@ -38,6 +38,7 @@ export {
getFlipperLib,
setFlipperLibImplementation as _setFlipperLibImplementation,
FileDescriptor,
FileEncoding,
} from './plugin/FlipperLib';
export {
MenuEntry,

View File

@@ -14,9 +14,12 @@ import {RealFlipperClient} from './Plugin';
import {Notification} from './Notification';
import {DetailSidebarProps} from '../ui/DetailSidebar';
export type FileEncoding = 'utf-8' | 'base64';
export interface FileDescriptor {
data: string;
name: string;
path?: string;
}
/**
@@ -40,6 +43,10 @@ export interface FlipperLib {
DetailsSidebarImplementation?(
props: DetailSidebarProps,
): React.ReactElement | null;
/**
* @deprecated
* Will be removed in subsequent commits
*/
showOpenDialog?(options: {
defaultPath?: string;
filter?: {
@@ -52,19 +59,64 @@ export interface FlipperLib {
* Imported file data.
* 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;
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
* An exported file path (if available) or a file name.
* If user cancelled a file selection - undefined.
*/
exportFile(
/**
* New file data
*/
data: string,
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;
/**
* File encoding
*/
encoding?: FileEncoding;
},
): Promise<string | undefined>;
paths: {

View File

@@ -59,6 +59,9 @@ export interface RenderHost {
writeTextToClipboard(text: string): void;
/**
* @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"
*/
showSaveDialog?(options: {
@@ -68,9 +71,18 @@ export interface RenderHost {
}): Promise<string | undefined>;
/**
* @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"
*/
showOpenDialog?: FlipperLib['showOpenDialog'];
showOpenDialog?(options: {
defaultPath?: string;
filter?: {
extensions: string[];
name: string;
};
}): Promise<string | undefined>;
showSelectDirectoryDialog?(defaultPath?: string): Promise<string | undefined>;
importFile: FlipperLib['importFile'];
exportFile: FlipperLib['exportFile'];