lbry-desktop/ui/component/common/file-selector.jsx

143 lines
3.7 KiB
React
Raw Normal View History

2018-03-26 23:32:43 +02:00
// @flow
2019-02-22 06:01:59 +01:00
import * as React from 'react';
import * as remote from '@electron/remote';
import { ipcRenderer } from 'electron';
2018-03-26 23:32:43 +02:00
import Button from 'component/button';
2019-02-13 17:27:20 +01:00
import { FormField } from 'component/common/form';
2018-10-13 17:49:47 +02:00
2018-03-26 23:32:43 +02:00
type Props = {
type: string,
currentPath?: ?string,
onFileChosen: (FileWithPath) => void,
label?: string,
placeholder?: string,
accept?: string,
error?: string,
disabled?: boolean,
autoFocus?: boolean,
filters?: Array<{ name: string, extension: string[] }>,
readFile?: boolean,
2018-03-26 23:32:43 +02:00
};
class FileSelector extends React.PureComponent<Props> {
static defaultProps = {
autoFocus: false,
2018-03-26 23:32:43 +02:00
type: 'file',
readFile: true,
2018-03-26 23:32:43 +02:00
};
2019-09-27 18:22:15 +02:00
fileInput: React.ElementRef<any>;
2019-02-22 06:01:59 +01:00
2018-03-26 23:32:43 +02:00
constructor() {
super();
2019-02-22 06:01:59 +01:00
this.fileInput = React.createRef();
this.handleFileInputSelection = this.handleFileInputSelection.bind(this);
this.handleDirectoryInputSelection = this.handleDirectoryInputSelection.bind(this);
this.fileInputButton = this.fileInputButton.bind(this);
2018-03-26 23:32:43 +02:00
}
handleFileInputSelection = () => {
2019-09-27 18:22:15 +02:00
const { files } = this.fileInput.current;
if (!files) {
return;
}
const file = files[0];
2020-10-16 01:06:05 +02:00
2019-09-27 18:22:15 +02:00
if (this.props.onFileChosen) {
this.props.onFileChosen({ file, path: file.path || file.name });
2019-09-27 18:22:15 +02:00
}
this.fileInput.current.value = null; // clear the file input
};
2020-10-16 01:06:05 +02:00
handleDirectoryInputSelection = () => {
let defaultPath;
let properties;
let isWin = process.platform === 'win32';
let type = this.props.type;
if (isWin === true) {
defaultPath = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
}
if (type === 'openFile') {
properties = ['openFile'];
}
if (type === 'openDirectory') {
properties = ['openDirectory'];
}
remote.dialog
.showOpenDialog({
properties,
defaultPath,
filters: this.props.filters,
})
.then((result) => {
const path = result && result.filePaths[0];
if (path) {
return ipcRenderer.invoke('get-file-from-path', path, this.props.readFile);
}
})
.then((result) => {
if (!result) {
return;
}
const file = new File([result.buffer], result.name, {
type: result.mime,
});
this.props.onFileChosen({ file, path: result.path });
});
2020-10-16 01:06:05 +02:00
};
fileInputButton = () => {
this.fileInput.current.click();
};
2019-02-22 06:01:59 +01:00
2018-03-26 23:32:43 +02:00
input: ?HTMLInputElement;
render() {
2020-07-23 19:02:07 +02:00
const { type, currentPath, label, placeholder, accept, error, disabled, autoFocus = false } = this.props;
const placeHolder = currentPath || placeholder;
2019-12-09 19:51:00 +01:00
2018-03-26 23:32:43 +02:00
return (
2019-02-22 06:01:59 +01:00
<React.Fragment>
<FormField
label={label}
2019-03-18 06:06:41 +01:00
webkitdirectory="true"
className="form-field--with-button"
error={error}
disabled={disabled}
2019-03-18 06:06:41 +01:00
type="text"
readOnly="readonly"
value={placeHolder || __('Choose a file')}
inputButton={
<Button
autoFocus={autoFocus}
button="primary"
disabled={disabled}
onClick={
type === 'openDirectory' || type === 'openFile'
? this.handleDirectoryInputSelection
: this.fileInputButton
}
2020-07-23 19:02:07 +02:00
label={__('Browse')}
/>
}
/>
<input
type={'file'}
style={{ display: 'none' }}
accept={accept}
ref={this.fileInput}
2020-10-16 01:06:05 +02:00
onChange={() => (type === 'openDirectory' ? () => {} : this.handleFileInputSelection())}
webkitdirectory={type === 'openDirectory' ? 'True' : null}
2019-02-22 06:01:59 +01:00
/>
</React.Fragment>
2018-03-26 23:32:43 +02:00
);
}
}
export default FileSelector;