Merge branch 'my-files-page'
This commit is contained in:
commit
1609cc0e3f
16 changed files with 390 additions and 78 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
||||||
dist/css/*
|
dist/css/*
|
||||||
dist/js/*
|
dist/js/*
|
||||||
|
!dist/js/flowplayer/
|
||||||
|
!dist/js/flowplayer/
|
||||||
node_modules
|
node_modules
|
||||||
.sass-cache
|
.sass-cache
|
||||||
.idea
|
.idea
|
||||||
|
|
2
dist/index.html
vendored
2
dist/index.html
vendored
|
@ -21,6 +21,7 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.7.4/polyfill.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.7.4/polyfill.js"></script>
|
||||||
|
<script src="./js/flowplayer/flowplayer-3.2.13.min.js"></script>
|
||||||
<script src="./js/lbry.js"></script>
|
<script src="./js/lbry.js"></script>
|
||||||
<script src="./js/component/common.js"></script>
|
<script src="./js/component/common.js"></script>
|
||||||
<script src="./js/component/splash.js"></script>
|
<script src="./js/component/splash.js"></script>
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
<script src="./js/page/help.js"></script>
|
<script src="./js/page/help.js"></script>
|
||||||
<script src="./js/page/watch.js"></script>
|
<script src="./js/page/watch.js"></script>
|
||||||
<script src="./js/page/report.js"></script>
|
<script src="./js/page/report.js"></script>
|
||||||
|
<script src="./js/page/my_files.js"></script>
|
||||||
<script src="./js/page/start.js"></script>
|
<script src="./js/page/start.js"></script>
|
||||||
<script src="./js/app.js"></script>
|
<script src="./js/app.js"></script>
|
||||||
<script src="./js/main.js"></script>
|
<script src="./js/main.js"></script>
|
||||||
|
|
22
dist/js/flowplayer/flowplayer-3.2.13.min.js
vendored
Normal file
22
dist/js/flowplayer/flowplayer-3.2.13.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
dist/js/flowplayer/flowplayer-3.2.18.swf
vendored
Normal file
BIN
dist/js/flowplayer/flowplayer-3.2.18.swf
vendored
Normal file
Binary file not shown.
BIN
dist/js/flowplayer/flowplayer.controls-3.2.16.swf
vendored
Normal file
BIN
dist/js/flowplayer/flowplayer.controls-3.2.16.swf
vendored
Normal file
Binary file not shown.
33
js/app.js
33
js/app.js
|
@ -1,15 +1,10 @@
|
||||||
var appStyles = {
|
|
||||||
width: '800px',
|
|
||||||
marginLeft: 'auto',
|
|
||||||
marginRight: 'auto',
|
|
||||||
};
|
|
||||||
var App = React.createClass({
|
var App = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
// For now, routes are in format ?page or ?page=args
|
// For now, routes are in format ?page or ?page=args
|
||||||
var match, param, val;
|
var match, param, val;
|
||||||
[match, param, val] = window.location.search.match(/\??([^=]*)(?:=(.*))?/);
|
[match, param, val] = window.location.search.match(/\??([^=]*)(?:=(.*))?/);
|
||||||
|
|
||||||
if (['settings', 'help', 'start', 'watch', 'report'].indexOf(param) != -1) {
|
if (['settings', 'help', 'start', 'watch', 'report', 'files'].indexOf(param) != -1) {
|
||||||
var viewingPage = param;
|
var viewingPage = param;
|
||||||
} else {
|
} else {
|
||||||
var viewingPage = 'home';
|
var viewingPage = 'home';
|
||||||
|
@ -44,31 +39,21 @@ var App = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
|
||||||
lbry.getStartNotice(function(notice) {
|
|
||||||
if (notice) {
|
|
||||||
alert(notice);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.state.viewingPage == 'home') {
|
if (this.state.viewingPage == 'home') {
|
||||||
var content = <HomePage />;
|
return <HomePage />;
|
||||||
} else if (this.state.viewingPage == 'settings') {
|
} else if (this.state.viewingPage == 'settings') {
|
||||||
var content = <SettingsPage />;
|
return <SettingsPage />;
|
||||||
} else if (this.state.viewingPage == 'help') {
|
} else if (this.state.viewingPage == 'help') {
|
||||||
var content = <HelpPage />;
|
return <HelpPage />;
|
||||||
} else if (this.state.viewingPage == 'watch') {
|
} else if (this.state.viewingPage == 'watch') {
|
||||||
var content = <WatchPage name={this.state.pageArgs}/>;
|
return <WatchPage name={this.state.pageArgs}/>;
|
||||||
} else if (this.state.viewingPage == 'report') {
|
} else if (this.state.viewingPage == 'report') {
|
||||||
var content = <ReportPage />;
|
return <ReportPage />;
|
||||||
|
} else if (this.state.viewingPage == 'files') {
|
||||||
|
return <MyFilesPage />;
|
||||||
} else if (this.state.viewingPage == 'start') {
|
} else if (this.state.viewingPage == 'start') {
|
||||||
var content = <StartPage />;
|
return <StartPage />;
|
||||||
}
|
}
|
||||||
return (
|
|
||||||
<div style={appStyles}>
|
|
||||||
{content}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -3,9 +3,10 @@
|
||||||
var Icon = React.createClass({
|
var Icon = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
style: React.PropTypes.object,
|
style: React.PropTypes.object,
|
||||||
|
fixed: React.PropTypes.boolean,
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var className = 'icon ' + this.props.icon;
|
var className = 'icon ' + ('fixed' in this.props ? 'icon-fixed-width ' : '') + this.props.icon;
|
||||||
return <span className={className} style={this.props.style}></span>
|
return <span className={className} style={this.props.style}></span>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -18,7 +19,8 @@ var Link = React.createClass({
|
||||||
className = (this.props.button ? 'button-block button-' + this.props.button : 'button-text') +
|
className = (this.props.button ? 'button-block button-' + this.props.button : 'button-text') +
|
||||||
(this.props.hidden ? ' hidden' : '') + (this.props.disabled ? ' disabled' : '');
|
(this.props.hidden ? ' hidden' : '') + (this.props.disabled ? ' disabled' : '');
|
||||||
return (
|
return (
|
||||||
<a className={className} href={href} style={this.props.style ? this.props.style : {}} onClick={this.props.onClick}>
|
<a className={className} href={href} style={this.props.style ? this.props.style : {}}
|
||||||
|
title={this.props.title} onClick={this.props.onClick}>
|
||||||
{this.props.icon ? icon : '' }
|
{this.props.icon ? icon : '' }
|
||||||
{this.props.label}
|
{this.props.label}
|
||||||
</a>
|
</a>
|
||||||
|
@ -26,6 +28,79 @@ var Link = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Generic menu styles
|
||||||
|
var menuStyle = {
|
||||||
|
border: '1px solid #aaa',
|
||||||
|
padding: '4px',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
};
|
||||||
|
|
||||||
|
var Menu = React.createClass({
|
||||||
|
handleWindowClick: function(e) {
|
||||||
|
if (this.props.toggleButton && ReactDOM.findDOMNode(this.props.toggleButton).contains(e.target)) {
|
||||||
|
// Toggle button was clicked
|
||||||
|
this.setState({
|
||||||
|
open: !this.state.open
|
||||||
|
});
|
||||||
|
} else if (this.state.open && !this.refs.div.contains(e.target)) {
|
||||||
|
// Menu is open and user clicked outside of it
|
||||||
|
this.setState({
|
||||||
|
open: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
propTypes: {
|
||||||
|
openButton: React.PropTypes.element,
|
||||||
|
},
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
open: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
componentDidMount: function() {
|
||||||
|
window.addEventListener('click', this.handleWindowClick, false);
|
||||||
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
window.removeEventListener('click', this.handleWindowClick, false);
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div ref='div' style={menuStyle} className={this.state.open ? '' : 'hidden'}>
|
||||||
|
{this.props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var menuItemStyle = {
|
||||||
|
display: 'block',
|
||||||
|
};
|
||||||
|
var MenuItem = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
href: React.PropTypes.string,
|
||||||
|
label: React.PropTypes.string,
|
||||||
|
icon: React.PropTypes.string,
|
||||||
|
onClick: React.PropTypes.function,
|
||||||
|
},
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
iconPosition: 'left',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var icon = (this.props.icon ? <Icon icon={this.props.icon} fixed /> : null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a style={menuItemStyle} href={this.props.href} label={this.props.label} title={this.props.label}
|
||||||
|
className="button-text no-underline">
|
||||||
|
{this.props.iconPosition == 'left' ? icon : null}
|
||||||
|
{this.props.label}
|
||||||
|
{this.props.iconPosition == 'left' ? null : icon}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var creditAmountStyle = {
|
var creditAmountStyle = {
|
||||||
color: '#216C2A',
|
color: '#216C2A',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
|
@ -48,4 +123,16 @@ var CreditAmount = React.createClass({
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var subPageLogoStyle = {
|
||||||
|
maxWidth: '150px',
|
||||||
|
display: 'block',
|
||||||
|
marginTop: '36px',
|
||||||
|
};
|
||||||
|
|
||||||
|
var SubPageLogo = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
return <img src="img/lbry-dark-1600x528.png" style={subPageLogoStyle} />;
|
||||||
|
}
|
||||||
});
|
});
|
36
js/lbry.js
36
js/lbry.js
|
@ -103,6 +103,22 @@ lbry.getFileStatus = function(name, callback) {
|
||||||
lbry.call('get_lbry_file', { 'name': name }, callback);
|
lbry.call('get_lbry_file', { 'name': name }, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lbry.getFilesInfo = function(callback) {
|
||||||
|
lbry.call('get_lbry_files', {}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry.startFile = function(name, callback) {
|
||||||
|
lbry.call('start_lbry_file', { name: name }, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry.stopFile = function(name, callback) {
|
||||||
|
lbry.call('stop_lbry_file', { name: name }, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry.deleteFile = function(name, callback) {
|
||||||
|
lbry.call('delete_lbry_file', { name: name }, callback)
|
||||||
|
}
|
||||||
|
|
||||||
lbry.getVersionInfo = function(callback) {
|
lbry.getVersionInfo = function(callback) {
|
||||||
lbry.call('version', {}, callback);
|
lbry.call('version', {}, callback);
|
||||||
};
|
};
|
||||||
|
@ -154,6 +170,26 @@ lbry.imagePath = function(file)
|
||||||
return lbry.rootPath + '/img/' + file;
|
return lbry.rootPath + '/img/' + file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lbry.getMediaType = function(filename) {
|
||||||
|
var dotIndex = filename.lastIndexOf('.');
|
||||||
|
if (dotIndex == -1) {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
var ext = filename.substr(dotIndex + 1);
|
||||||
|
if (/^mp4|mov|m4v|flv|f4v$/i.test(ext)) {
|
||||||
|
return 'video';
|
||||||
|
} else if (/^mp3|m4a|aac|wav|flac|ogg$/i.test(ext)) {
|
||||||
|
return 'audio';
|
||||||
|
} else if (/^html|htm|pdf|odf|doc|docx|md|markdown|txt$/i.test(ext)) {
|
||||||
|
return 'document';
|
||||||
|
} else {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lbry.stop = function(callback) {
|
lbry.stop = function(callback) {
|
||||||
lbry.call('stop', {}, callback);
|
lbry.call('stop', {}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
var HelpPage = React.createClass({
|
var HelpPage = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main className="page">
|
||||||
|
<SubPageLogo />
|
||||||
<h1>Troubleshooting</h1>
|
<h1>Troubleshooting</h1>
|
||||||
<p>Here are the most commonly encountered problems and what to try doing about them.</p>
|
<p>Here are the most commonly encountered problems and what to try doing about them.</p>
|
||||||
|
|
||||||
|
|
|
@ -228,23 +228,41 @@ var Header = React.createClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
var topBarStyle = {
|
var topBarStyle = {
|
||||||
'float': 'right'
|
'float': 'right',
|
||||||
|
'position': 'relative',
|
||||||
|
'height': '26px',
|
||||||
},
|
},
|
||||||
balanceStyle = {
|
balanceStyle = {
|
||||||
'marginRight': '5px'
|
'marginRight': '5px'
|
||||||
},
|
|
||||||
closeIconStyle = {
|
|
||||||
'color': '#ff5155'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var mainMenuStyle = {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '26px',
|
||||||
|
right: '0px',
|
||||||
|
};
|
||||||
|
|
||||||
|
var MainMenu = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
var isLinux = /linux/i.test(navigator.userAgent); // @TODO: find a way to use getVersionInfo() here without messy state management
|
||||||
|
return (
|
||||||
|
<div style={mainMenuStyle}>
|
||||||
|
<Menu {...this.props}>
|
||||||
|
<MenuItem href='/?files' label="My Files" icon='icon-cloud-download' />
|
||||||
|
<MenuItem href='/?settings' label="Settings" icon='icon-gear' />
|
||||||
|
<MenuItem href='/?help' label="Help" icon='icon-question-circle' />
|
||||||
|
{isLinux ? <MenuItem href="/?start" label="Exit LBRY" icon="icon-close" />
|
||||||
|
: null}
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var TopBar = React.createClass({
|
var TopBar = React.createClass({
|
||||||
onClose: function() {
|
|
||||||
window.location.href = "?start";
|
|
||||||
},
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
balance: 0,
|
balance: 0,
|
||||||
showClose: /linux/i.test(navigator.userAgent) // @TODO: find a way to use getVersionInfo() here without messy state management
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -254,27 +272,34 @@ var TopBar = React.createClass({
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
onClose: function() {
|
||||||
|
window.location.href = "?start";
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<span className='top-bar' style={topBarStyle}>
|
<span className='top-bar' style={topBarStyle}>
|
||||||
<span style={balanceStyle}>
|
<span style={balanceStyle}>
|
||||||
<CreditAmount amount={this.state.balance}/>
|
<CreditAmount amount={this.state.balance}/>
|
||||||
</span>
|
</span>
|
||||||
<Link href='/?settings' icon='icon-gear' />
|
|
||||||
{ ' ' }
|
<Link ref="menuButton" title="LBRY Menu" icon="icon-bars" />
|
||||||
<Link href='/?help' icon='icon-question-circle' />
|
<MainMenu toggleButton={this.refs.menuButton} />
|
||||||
{ ' ' }
|
|
||||||
<Link href="/?start" onClick={this.onClose} icon="icon-close" style={closeIconStyle} hidden={!this.state.showClose} />
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var HomePage = React.createClass({
|
var HomePage = React.createClass({
|
||||||
|
componentDidMount: function() {
|
||||||
|
lbry.getStartNotice(function(notice) {
|
||||||
|
if (notice) {
|
||||||
|
alert(notice);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="page">
|
||||||
<Header />
|
<Header />
|
||||||
<Discover />
|
<Discover />
|
||||||
</div>
|
</div>
|
||||||
|
|
138
js/page/my_files.js
Normal file
138
js/page/my_files.js
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
var removeIconColumnStyle = {
|
||||||
|
fontSize: '1.3em',
|
||||||
|
height: '120px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
progressBarStyle = {
|
||||||
|
height: '15px',
|
||||||
|
width: '230px',
|
||||||
|
backgroundColor: '#444',
|
||||||
|
border: '2px solid #eee',
|
||||||
|
display: 'inline-block',
|
||||||
|
},
|
||||||
|
myFilesRowImgStyle = {
|
||||||
|
maxHeight: '100px',
|
||||||
|
display: 'block',
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
float: 'left'
|
||||||
|
};
|
||||||
|
|
||||||
|
var MyFilesRow = React.createClass({
|
||||||
|
onRemoveClicked: function() {
|
||||||
|
var alertText = 'Are you sure you\'d like to remove "' + this.props.title + '?" This will ' +
|
||||||
|
(this.completed ? ' stop the download and ' : '') +
|
||||||
|
'permanently remove the file from your system.';
|
||||||
|
|
||||||
|
if (confirm(alertText)) {
|
||||||
|
lbry.deleteFile(this.props.lbryUri);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPauseResumeClicked: function() {
|
||||||
|
if (this.props.stopped) {
|
||||||
|
lbry.startFile(this.props.lbryUri);
|
||||||
|
} else {
|
||||||
|
lbry.stopFile(this.props.lbryUri);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
if (this.props.completed) {
|
||||||
|
var pauseLink = null;
|
||||||
|
var curProgressBarStyle = {display: 'none'};
|
||||||
|
} else {
|
||||||
|
var pauseLink = <Link icon={this.props.stopped ? 'icon-play' : 'icon-pause'}
|
||||||
|
label={this.props.stopped ? 'Resume download' : 'Pause download'}
|
||||||
|
onClick={() => { this.onPauseResumeClicked() }} />;
|
||||||
|
|
||||||
|
var curProgressBarStyle = Object.assign({}, progressBarStyle);
|
||||||
|
curProgressBarStyle.width = this.props.ratioLoaded * 230;
|
||||||
|
curProgressBarStyle.borderRightWidth = 230 - (this.props.ratioLoaded * 230) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.showWatchButton) {
|
||||||
|
// No support for lbry:// URLs in Windows or on Chrome yet
|
||||||
|
if (/windows|win32/i.test(navigator.userAgent) || (window.chrome && window.navigator.vendor == "Google Inc.")) {
|
||||||
|
var watchUri = "/?watch=" + this.props.lbryUri;
|
||||||
|
} else {
|
||||||
|
var watchUri = 'lbry://' + this.props.lbryUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
var watchLink = <Link href={watchUri} label="Watch" icon="icon-play" button="primary" />;
|
||||||
|
} else {
|
||||||
|
var watchLink = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row-fluid">
|
||||||
|
<div className="span3">
|
||||||
|
<img src={this.props.imgUrl} alt={'Photo for ' + this.props.title} style={myFilesRowImgStyle} />
|
||||||
|
</div>
|
||||||
|
<div className="span6">
|
||||||
|
<h2>{this.props.title}</h2>
|
||||||
|
<div className={this.props.completed ? 'hidden' : ''} style={curProgressBarStyle}></div>
|
||||||
|
{ ' ' }
|
||||||
|
{this.props.completed ? 'Download complete' : (parseInt(this.props.ratioLoaded * 100) + '%')}
|
||||||
|
<div>{ pauseLink }</div>
|
||||||
|
<div>{ watchLink }</div>
|
||||||
|
</div>
|
||||||
|
<div className="span1" style={removeIconColumnStyle}>
|
||||||
|
<Link icon="icon-close" title="Remove file" onClick={() => { this.onRemoveClicked() } } /><br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var MyFilesPage = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
filesInfo: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
componentWillMount: function() {
|
||||||
|
this.updateFilesInfo();
|
||||||
|
},
|
||||||
|
updateFilesInfo: function() {
|
||||||
|
lbry.getFilesInfo((filesInfo) => {
|
||||||
|
this.setState({
|
||||||
|
filesInfo: (filesInfo ? filesInfo : []),
|
||||||
|
});
|
||||||
|
setTimeout(() => { this.updateFilesInfo() }, 1000);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
if (this.state.filesInfo === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.state.filesInfo.length) {
|
||||||
|
var content = <span>You haven't downloaded anything from LBRY yet. Go <Link href="/" label="search for your first download" />!</span>;
|
||||||
|
} else {
|
||||||
|
var content = [];
|
||||||
|
for (let fileInfo of this.state.filesInfo) {
|
||||||
|
let {completed, written_bytes, total_bytes, lbry_uri, file_name, stopped, metadata} = fileInfo;
|
||||||
|
let {name, stream_name, thumbnail} = metadata;
|
||||||
|
|
||||||
|
var title = (name || stream_name || ('lbry://' + lbry_uri));
|
||||||
|
var ratioLoaded = written_bytes / total_bytes;
|
||||||
|
var showWatchButton = (lbry.getMediaType(file_name) == 'video');
|
||||||
|
|
||||||
|
content.push(<MyFilesRow lbryUri={lbry_uri} title={title} completed={completed} stopped={stopped}
|
||||||
|
ratioLoaded={ratioLoaded} imgUrl={thumbnail}
|
||||||
|
showWatchButton={showWatchButton}/>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<main className="page">
|
||||||
|
<SubPageLogo />
|
||||||
|
<h1>My files</h1>
|
||||||
|
{content}
|
||||||
|
<section>
|
||||||
|
<Link href="/" label="<< Return" />
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -20,7 +20,8 @@ var ReportPage = React.createClass({
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main className="page">
|
||||||
|
<SubPageLogo />
|
||||||
<h1>Report a bug</h1>
|
<h1>Report a bug</h1>
|
||||||
<section>
|
<section>
|
||||||
<p>Please describe the problem you experienced and any information you think might be useful to us. Links to screenshots are great!</p>
|
<p>Please describe the problem you experienced and any information you think might be useful to us. Links to screenshots are great!</p>
|
||||||
|
|
|
@ -73,7 +73,8 @@ var SettingsPage = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main className="page">
|
||||||
|
<SubPageLogo />
|
||||||
<h1>Settings</h1>
|
<h1>Settings</h1>
|
||||||
<section>
|
<section>
|
||||||
<h4>Run on startup</h4>
|
<h4>Run on startup</h4>
|
||||||
|
|
|
@ -4,7 +4,8 @@ var StartPage = React.createClass({
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main className="page">
|
||||||
|
<SubPageLogo />
|
||||||
<h1>LBRY has closed</h1>
|
<h1>LBRY has closed</h1>
|
||||||
<Link href="lbry://lbry" label="Click here to start LBRY" />
|
<Link href="lbry://lbry" label="Click here to start LBRY" />
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var videoStyle = {
|
var videoStyle = {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
// height: '100%',
|
||||||
backgroundColor: '#000'
|
backgroundColor: '#000'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,19 +19,6 @@ var WatchPage = React.createClass({
|
||||||
lbry.getStream(this.props.name);
|
lbry.getStream(this.props.name);
|
||||||
this.updateLoadStatus();
|
this.updateLoadStatus();
|
||||||
},
|
},
|
||||||
reloadIfNeeded: function() {
|
|
||||||
// Fallback option for loading problems: every 15 seconds, if the video hasn't reported being
|
|
||||||
// playable yet, ask it to reload.
|
|
||||||
if (!this.state.readyToPlay) {
|
|
||||||
this._video.load()
|
|
||||||
setTimeout(() => { this.reloadIfNeeded() }, 15000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCanPlay: function() {
|
|
||||||
this.setState({
|
|
||||||
readyToPlay: true
|
|
||||||
});
|
|
||||||
},
|
|
||||||
updateLoadStatus: function() {
|
updateLoadStatus: function() {
|
||||||
lbry.getFileStatus(this.props.name, (status) => {
|
lbry.getFileStatus(this.props.name, (status) => {
|
||||||
if (!status || status.code != 'running' || status.written_bytes == 0) {
|
if (!status || status.code != 'running' || status.written_bytes == 0) {
|
||||||
|
@ -44,31 +31,20 @@ var WatchPage = React.createClass({
|
||||||
setTimeout(() => { this.updateLoadStatus() }, 250);
|
setTimeout(() => { this.updateLoadStatus() }, 250);
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
loadStatusMessage: "Buffering",
|
readyToPlay: true
|
||||||
downloadStarted: true,
|
})
|
||||||
});
|
flowplayer('player', 'js/flowplayer/flowplayer-3.2.18.swf');
|
||||||
setTimeout(() => { this.reloadIfNeeded() }, 15000);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
if (!this.state.downloadStarted) {
|
|
||||||
var video = null;
|
|
||||||
} else {
|
|
||||||
// If the download has started, render the <video> behind the scenes so it can start loading.
|
|
||||||
// When the video is actually ready to play, the loading text is hidden and the video shown.
|
|
||||||
var video = <video src={"/view?name=" + this.props.name} style={videoStyle}
|
|
||||||
className={this.state.readyToPlay ? '' : 'hidden'} controls
|
|
||||||
onCanPlay={this.onCanPlay} ref={(video) => {this._video = video}}/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main className="page full-width">
|
||||||
<div className={this.state.readyToPlay ? 'hidden' : ''}>
|
<div className={this.state.readyToPlay ? 'hidden' : ''}>
|
||||||
<h3>Loading lbry://{this.props.name}</h3>
|
<h3>Loading lbry://{this.props.name}</h3>
|
||||||
{this.state.loadStatusMessage}...
|
{this.state.loadStatusMessage}...
|
||||||
</div>
|
</div>
|
||||||
{video}
|
<a id="player" href={"/view?name=" + this.props.name} style={videoStyle} />
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,22 @@ body
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 800px;
|
||||||
|
|
||||||
|
&.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-fixed-width {
|
||||||
|
/* This borrowed is from a component of Font Awesome we're not using, maybe add it? */
|
||||||
|
width: (18em / 14);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
section
|
section
|
||||||
{
|
{
|
||||||
margin-bottom: $spacing-vertical;
|
margin-bottom: $spacing-vertical;
|
||||||
|
@ -22,7 +38,7 @@ section
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 { font-size: 2.0em; margin-bottom: $spacing-vertical / 2; margin-top: $spacing-vertical * 1.5; }
|
h1 { font-size: 2.0em; margin-bottom: $spacing-vertical / 2; margin-top: $spacing-vertical; }
|
||||||
h2 { font-size: 1.75em; }
|
h2 { font-size: 1.75em; }
|
||||||
h3 { font-size: 1.4em; }
|
h3 { font-size: 1.4em; }
|
||||||
h4 { font-size: 1.2em; }
|
h4 { font-size: 1.2em; }
|
||||||
|
@ -127,15 +143,34 @@ input[type="search"]
|
||||||
.button-text
|
.button-text
|
||||||
{
|
{
|
||||||
color: $color-primary;
|
color: $color-primary;
|
||||||
text-decoration: underline;
|
.icon
|
||||||
|
{
|
||||||
|
&:first-child {
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
&:last-child:not(:only-child) {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.no-underline) {
|
||||||
|
text-decoration: underline;
|
||||||
|
.icon {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
opacity: 0.70;
|
opacity: 0.70;
|
||||||
transition: opacity .225s ease;
|
transition: opacity .225s ease;
|
||||||
|
text-decoration: underline;
|
||||||
|
.icon {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon:only-child {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0.16em;
|
top: 0.16em;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue