Add DropDown component and convert DownloadLink to use it
This commit is contained in:
parent
a2641c1a98
commit
78e9a02b70
2 changed files with 83 additions and 92 deletions
|
@ -1,6 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbry from '../lbry.js';
|
import lbry from '../lbry.js';
|
||||||
|
import FormField from './form.js';
|
||||||
import Modal from './modal.js';
|
import Modal from './modal.js';
|
||||||
|
import {Menu, MenuItem} from './menu.js';
|
||||||
import {Icon, ToolTip} from './common.js';
|
import {Icon, ToolTip} from './common.js';
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,17 +111,62 @@ export let ToolTipLink = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export let DropDown = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
onCaretClick: React.PropTypes.func,
|
||||||
|
},
|
||||||
|
handleCaretClicked: function(event) {
|
||||||
|
/**
|
||||||
|
* The menu handles caret clicks via a window event listener, so we just need to prevent clicks
|
||||||
|
* on the caret from bubbling up to the link
|
||||||
|
*/
|
||||||
|
this.setState({
|
||||||
|
menuOpen: !this.state.menuOpen,
|
||||||
|
});
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
closeMenu: function(event) {
|
||||||
|
this.setState({
|
||||||
|
menuOpen: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
menuOpen: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
const {onCaretClick, ...other} = this.props;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Link {...other}>
|
||||||
|
<span className="link-label">{this.props.label}</span>
|
||||||
|
<Icon icon="icon-caret-down" fixed={true} onClick={this.handleCaretClicked} />
|
||||||
|
</Link>
|
||||||
|
{this.state.menuOpen
|
||||||
|
? <Menu onClickOut={this.closeMenu}>
|
||||||
|
{this.props.children}
|
||||||
|
</Menu>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export let DownloadLink = React.createClass({
|
export let DownloadLink = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
type: React.PropTypes.string,
|
type: React.PropTypes.string,
|
||||||
streamName: React.PropTypes.string,
|
streamName: React.PropTypes.string,
|
||||||
sdHash: React.PropTypes.string,
|
sdHash: React.PropTypes.string,
|
||||||
|
metadata: React.PropTypes.object,
|
||||||
label: React.PropTypes.string,
|
label: React.PropTypes.string,
|
||||||
button: React.PropTypes.string,
|
button: React.PropTypes.string,
|
||||||
state: React.PropTypes.oneOf(['not-started', 'downloading', 'done']),
|
state: React.PropTypes.oneOf(['not-started', 'downloading', 'done']),
|
||||||
progress: React.PropTypes.number,
|
progress: React.PropTypes.number,
|
||||||
path: React.PropTypes.string,
|
path: React.PropTypes.string,
|
||||||
hidden: React.PropTypes.bool,
|
hidden: React.PropTypes.bool,
|
||||||
|
deleteChecked: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
tryDownload: function() {
|
tryDownload: function() {
|
||||||
lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
|
lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
|
||||||
|
@ -145,6 +192,30 @@ export let DownloadLink = React.createClass({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
openMenu: function() {
|
||||||
|
this.setState({
|
||||||
|
menuOpen: !this.state.menuOpen,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDeleteCheckboxClicked: function(event) {
|
||||||
|
this.setState({
|
||||||
|
deleteChecked: event.target.checked,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleRevealClicked: function() {
|
||||||
|
lbry.revealFile(this.props.path);
|
||||||
|
},
|
||||||
|
handleRemoveClicked: function() {
|
||||||
|
this.setState({
|
||||||
|
modal: 'confirmRemove',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleRemoveConfirmed: function() {
|
||||||
|
lbry.deleteFile(this.props.sdHash || this.props.streamName, this.state.deleteChecked);
|
||||||
|
this.setState({
|
||||||
|
modal: null,
|
||||||
|
});
|
||||||
|
},
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
state: 'not-started',
|
state: 'not-started',
|
||||||
|
@ -154,6 +225,7 @@ export let DownloadLink = React.createClass({
|
||||||
return {
|
return {
|
||||||
filePath: null,
|
filePath: null,
|
||||||
modal: null,
|
modal: null,
|
||||||
|
menuOpen: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closeModal: function() {
|
closeModal: function() {
|
||||||
|
@ -186,7 +258,10 @@ export let DownloadLink = React.createClass({
|
||||||
);
|
);
|
||||||
} else if (this.props.state == 'done') {
|
} else if (this.props.state == 'done') {
|
||||||
linkBlock = (
|
linkBlock = (
|
||||||
<Link button="alt" label="Open" icon='icon-external-link-square' onClick={this.handleClick} />
|
<DropDown button="alt" label="Open" onClick={this.handleClick} onCaretClick={this.openMenu}>
|
||||||
|
<MenuItem onClick={this.handleRevealClicked} label="Open in Folder" />
|
||||||
|
<MenuItem onClick={this.handleRemoveClicked} label="Remove..." />
|
||||||
|
</DropDown>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unknown download state ${this.props.state} passed to DownloadLink`);
|
throw new Error(`Unknown download state ${this.props.state} passed to DownloadLink`);
|
||||||
|
@ -213,6 +288,12 @@ export let DownloadLink = React.createClass({
|
||||||
onConfirmed={this.closeModal}>
|
onConfirmed={this.closeModal}>
|
||||||
LBRY was unable to download the stream <strong>lbry://{this.props.streamName}</strong>.
|
LBRY was unable to download the stream <strong>lbry://{this.props.streamName}</strong>.
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal isOpen={this.state.modal == 'confirmRemove'} type="confirm" confirmButtonLabel="Remove"
|
||||||
|
onConfirmed={this.handleRemoveConfirmed} onAborted={this.closeModal}>
|
||||||
|
<p>Are you sure you'd like to remove <cite>{this.props.metadata.title}</cite> from LBRY?</p>
|
||||||
|
|
||||||
|
<label><FormField type="checkbox" checked={this.state.deleteChecked} onClick={this.handleDeleteCheckboxClicked} /> Delete this file from my computer</label>
|
||||||
|
</Modal>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,101 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbry from '../lbry.js';
|
import lbry from '../lbry.js';
|
||||||
import {Link, WatchLink} from '../component/link.js';
|
import {Link} from '../component/link.js';
|
||||||
import {Menu, MenuItem} from '../component/menu.js';
|
|
||||||
import FormField from '../component/form.js';
|
import FormField from '../component/form.js';
|
||||||
import FileTile from '../component/file-tile.js';
|
import FileTile from '../component/file-tile.js';
|
||||||
import Modal from '../component/modal.js';
|
import Modal from '../component/modal.js';
|
||||||
import {BusyMessage, Thumbnail} from '../component/common.js';
|
import {BusyMessage, Thumbnail} from '../component/common.js';
|
||||||
|
|
||||||
var moreMenuStyle = {
|
|
||||||
position: 'absolute',
|
|
||||||
display: 'block',
|
|
||||||
top: '26px',
|
|
||||||
right: '13px',
|
|
||||||
};
|
|
||||||
var MyFilesRowMoreMenu = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
title: React.PropTypes.string.isRequired,
|
|
||||||
path: React.PropTypes.string.isRequired,
|
|
||||||
completed: React.PropTypes.bool.isRequired,
|
|
||||||
lbryUri: React.PropTypes.string.isRequired,
|
|
||||||
},
|
|
||||||
handleRevealClicked: function() {
|
|
||||||
lbry.revealFile(this.props.path);
|
|
||||||
},
|
|
||||||
handleRemoveClicked: function() {
|
|
||||||
lbry.deleteFile(this.props.lbryUri, false);
|
|
||||||
},
|
|
||||||
handleDeleteClicked: function() {
|
|
||||||
this.setState({
|
|
||||||
modal: 'confirmDelete',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleDeleteConfirmed: function() {
|
|
||||||
lbry.deleteFile(this.props.lbryUri);
|
|
||||||
this.setState({
|
|
||||||
modal: null,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
closeModal: function() {
|
|
||||||
this.setState({
|
|
||||||
modal: null,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
modal: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
return (
|
|
||||||
<div style={moreMenuStyle}>
|
|
||||||
<Menu {...this.props}>
|
|
||||||
<section className="card">
|
|
||||||
<MenuItem onClick={this.handleRevealClicked} label="Reveal file" /> {/* @TODO: Switch to OS specific wording */}
|
|
||||||
<MenuItem onClick={this.handleRemoveClicked} label="Remove from LBRY" />
|
|
||||||
<MenuItem onClick={this.handleDeleteClicked} label="Remove and delete file" />
|
|
||||||
</section>
|
|
||||||
</Menu>
|
|
||||||
<Modal isOpen={this.state.modal == 'confirmDelete'} contentLabel="Confirm delete" type="confirm" confirmButtonLabel="Delete File"
|
|
||||||
onConfirmed={this.handleDeleteConfirmed} onAborted={this.closeModal}>
|
|
||||||
Are you sure you'd like to delete <cite>{this.props.title}</cite>? This will {this.props.completed ? ' stop the download and ' : ''}
|
|
||||||
permanently remove the file from your system.
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var moreButtonColumnStyle = {
|
|
||||||
height: '120px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
moreButtonContainerStyle = {
|
|
||||||
display: 'block',
|
|
||||||
position: 'relative',
|
|
||||||
},
|
|
||||||
moreButtonStyle = {
|
|
||||||
fontSize: '1.3em',
|
|
||||||
},
|
|
||||||
progressBarStyle = {
|
|
||||||
height: '15px',
|
|
||||||
width: '230px',
|
|
||||||
backgroundColor: '#444',
|
|
||||||
border: '2px solid #eee',
|
|
||||||
display: 'inline-block',
|
|
||||||
},
|
|
||||||
artStyle = {
|
|
||||||
maxHeight: '100px',
|
|
||||||
maxWidth: '100%',
|
|
||||||
display: 'block',
|
|
||||||
marginLeft: 'auto',
|
|
||||||
marginRight: 'auto',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var MyFilesPage = React.createClass({
|
var MyFilesPage = React.createClass({
|
||||||
_fileTimeout: null,
|
_fileTimeout: null,
|
||||||
_fileInfoCheckRate: 300,
|
_fileInfoCheckRate: 300,
|
||||||
|
|
Loading…
Reference in a new issue