diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd4f4efb6..bf84a1a32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,8 +23,8 @@ Web UI version numbers should always match the corresponding version of LBRY App
* Enable windows code signing of binary
### Changed
- *
- *
+ * Use directory selector instead of ugly text box on Settings page
+ * Use Electron's native file selector everywhere instead of WebKit file selector
### Fixed
* Error modals now display full screen properly
diff --git a/ui/js/component/file-selector.js b/ui/js/component/file-selector.js
new file mode 100644
index 000000000..4670f4830
--- /dev/null
+++ b/ui/js/component/file-selector.js
@@ -0,0 +1,58 @@
+import React from 'react';
+
+const {remote} = require('electron');
+class FileSelector extends React.Component {
+ static propTypes = {
+ type: React.PropTypes.oneOf(['file', 'directory']),
+ initPath: React.PropTypes.string,
+ onFileChosen: React.PropTypes.func,
+ }
+
+ static defaultProps = {
+ type: 'file',
+ }
+
+ componentWillMount() {
+ this.setState({
+ path: this.props.initPath || null,
+ });
+ }
+
+ handleButtonClick() {
+ remote.dialog.showOpenDialog({
+ properties: [this.props.type == 'file' ? 'openFile' : 'openDirectory'],
+ }, (paths) => {
+ if (!paths) { // User hit cancel, so do nothing
+ return;
+ }
+
+ const path = paths[0];
+ this.setState({
+ path: path,
+ });
+ if (this.props.onFileChosen) {
+ this.props.onFileChosen(path);
+ }
+ });
+ }
+
+ render() {
+ return (
+
+
+ {' '}
+
+ {this.state.path ?
+ this.state.path :
+ 'No File Chosen'}
+
+
+ );
+ }
+};
+
+export default FileSelector;
diff --git a/ui/js/component/form.js b/ui/js/component/form.js
index f75310c92..d5deaf23c 100644
--- a/ui/js/component/form.js
+++ b/ui/js/component/form.js
@@ -1,7 +1,9 @@
import React from 'react';
+import FileSelector from './file-selector.js';
import {Icon} from './common.js';
var formFieldCounter = 0,
+ formFieldFileSelectorTypes = ['file', 'directory'],
formFieldNestedLabelTypes = ['radio', 'checkbox'];
function formFieldId() {
@@ -19,6 +21,14 @@ export let FormField = React.createClass({
postfix: React.PropTypes.string,
hasError: React.PropTypes.bool
},
+ handleFileChosen: function(path) {
+ this.refs.field.value = path;
+ if (this.props.onChange) { // Updating inputs programmatically doesn't generate an event, so we have to make our own
+ const event = new Event('change', {bubbles: true})
+ this.refs.field.dispatchEvent(event); // This alone won't generate a React event, but we use it to attach the field as a target
+ this.props.onChange(event);
+ }
+ },
getInitialState: function() {
return {
isError: null,
@@ -26,17 +36,29 @@ export let FormField = React.createClass({
}
},
componentWillMount: function() {
- if (['text', 'number', 'radio', 'checkbox', 'file'].includes(this.props.type)) {
+ if (['text', 'number', 'radio', 'checkbox'].includes(this.props.type)) {
this._element = 'input';
this._type = this.props.type;
} else if (this.props.type == 'text-number') {
this._element = 'input';
this._type = 'text';
+ } else if (formFieldFileSelectorTypes.includes(this.props.type)) {
+ this._element = 'input';
+ this._type = 'hidden';
} else {
// Non field, e.g.