unavailable content cleanup
This commit is contained in:
parent
e5b4aaf175
commit
44412437ce
16 changed files with 144 additions and 171 deletions
|
@ -50,20 +50,6 @@ export let BusyMessage = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
export let ToolTip = React.createClass({
|
||||
propTypes: {
|
||||
open: React.PropTypes.bool.isRequired,
|
||||
onMouseOut: React.PropTypes.func
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className={'tooltip ' + (this.props.className || '') + (this.props.open ? '' : ' hidden')} onMouseOut={this.props.onMouseOut}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var creditAmountStyle = {
|
||||
color: '#216C2A',
|
||||
fontWeight: 'bold',
|
||||
|
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
|||
import lbry from '../lbry.js';
|
||||
import {Link} from '../component/link.js';
|
||||
import {Icon} from '../component/common.js';
|
||||
import FileUnavailableMessage from '../component/file-unavailable-message.js';
|
||||
import Modal from './modal.js';
|
||||
import FormField from './form.js';
|
||||
import {ToolTip} from '../component/tooltip.js';
|
||||
import {DropDownMenu, DropDownMenuItem} from './menu.js';
|
||||
|
||||
let WatchLink = React.createClass({
|
||||
|
@ -51,18 +51,14 @@ let WatchLink = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
export let FileActions = React.createClass({
|
||||
let FileActionsRow = React.createClass({
|
||||
_isMounted: false,
|
||||
_fileInfoSubscribeId: null,
|
||||
|
||||
propTypes: {
|
||||
streamName: React.PropTypes.string,
|
||||
sdHash: React.PropTypes.string.isRequired,
|
||||
metadata: React.PropTypes.object,
|
||||
path: React.PropTypes.string,
|
||||
hidden: React.PropTypes.bool,
|
||||
deleteChecked: React.PropTypes.bool,
|
||||
onRemove: React.PropTypes.func,
|
||||
metadata: React.PropTypes.object
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
|
@ -71,9 +67,7 @@ export let FileActions = React.createClass({
|
|||
menuOpen: false,
|
||||
deleteChecked: false,
|
||||
attemptingDownload: false,
|
||||
attemptingRemove: false,
|
||||
available: null,
|
||||
forceShowActions: false,
|
||||
attemptingRemove: false
|
||||
}
|
||||
},
|
||||
onFileInfoUpdate: function(fileInfo) {
|
||||
|
@ -139,11 +133,6 @@ export let FileActions = React.createClass({
|
|||
modal: 'confirmRemove',
|
||||
});
|
||||
},
|
||||
showActions: function() {
|
||||
this.setState({
|
||||
forceShowActions: true,
|
||||
});
|
||||
},
|
||||
handleRemoveConfirmed: function() {
|
||||
if (this.props.streamName) {
|
||||
lbry.removeFile(this.props.sdHash, this.props.streamName, this.state.deleteChecked);
|
||||
|
@ -164,15 +153,6 @@ export let FileActions = React.createClass({
|
|||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.sdHash, this.onFileInfoUpdate);
|
||||
lbry.getPeersForBlobHash(this.props.sdHash, (peers) => {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
available: peers.length > 0,
|
||||
});
|
||||
});
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
|
@ -183,15 +163,11 @@ export let FileActions = React.createClass({
|
|||
render: function() {
|
||||
if (this.state.fileInfo === null)
|
||||
{
|
||||
return <section className="file-actions--stub"></section>;
|
||||
}
|
||||
|
||||
if (this.state.available === false && !this.state.forceShowActions) {
|
||||
return <FileUnavailableMessage onShowActionsClicked={this.showActions} />;
|
||||
return null;
|
||||
}
|
||||
|
||||
const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
|
||||
showMenu = !!this.state.fileInfo;
|
||||
showMenu = !!this.state.fileInfo;
|
||||
|
||||
let linkBlock;
|
||||
if (this.state.fileInfo === false && !this.state.attemptingDownload) {
|
||||
|
@ -213,10 +189,10 @@ export let FileActions = React.createClass({
|
|||
}
|
||||
|
||||
return (
|
||||
<section className="file-actions">
|
||||
<div>
|
||||
{(this.props.metadata.content_type && this.props.metadata.content_type.startsWith('video/')) ? <WatchLink streamName={this.props.streamName} /> : null}
|
||||
{this.state.fileInfo !== null || this.state.fileInfo.isMine ?
|
||||
<div className="button-container">{linkBlock}</div>
|
||||
<div className="button-container">{linkBlock}</div>
|
||||
: null}
|
||||
{ showMenu ?
|
||||
<DropDownMenu>
|
||||
|
@ -238,7 +214,62 @@ export let FileActions = React.createClass({
|
|||
|
||||
<label><FormField type="checkbox" checked={this.state.deleteChecked} onClick={this.handleDeleteCheckboxClicked} /> Delete this file from my computer</label>
|
||||
</Modal>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export let FileActions = React.createClass({
|
||||
_isMounted: false,
|
||||
_fileInfoSubscribeId: null,
|
||||
|
||||
propTypes: {
|
||||
streamName: React.PropTypes.string,
|
||||
sdHash: React.PropTypes.string.isRequired,
|
||||
metadata: React.PropTypes.object
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
available: true,
|
||||
forceShowActions: false,
|
||||
}
|
||||
},
|
||||
onShowFileActionsRowClicked: function() {
|
||||
this.setState({
|
||||
forceShowActions: true,
|
||||
});
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
lbry.getPeersForBlobHash(this.props.sdHash, (peers) => {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
available: peers.length > 0,
|
||||
});
|
||||
});
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
},
|
||||
render: function() {
|
||||
return (<section className="file-actions">
|
||||
{
|
||||
this.state.available || this.state.forceShowActions ?
|
||||
<FileActionsRow sdHash={this.props.sdHash} metadata={this.props.metadata} streamName={this.props.streamName} /> :
|
||||
(<div>
|
||||
<div className="button-container empty">This file is not currently available.</div>
|
||||
<div className="button-container">
|
||||
<ToolTip label="Why?"
|
||||
body="The content on LBRY is hosted by its users. It appears there are no users connected that have this file at the moment" />
|
||||
</div>
|
||||
<div className="button-container">
|
||||
<Link label="Try Anyway" className="button-text" onClick={this.onShowFileActionsRowClicked} />
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
</section>);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import lbry from '../lbry.js';
|
||||
import {Link, ToolTipLink} from '../component/link.js';
|
||||
import {Link} from '../component/link.js';
|
||||
import {FileActions} from '../component/file-actions.js';
|
||||
import {Thumbnail, TruncatedText, CreditAmount} from '../component/common.js';
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import React from 'react';
|
||||
import {Link, ToolTipLink} from '../component/link.js';
|
||||
|
||||
const FileUnavailableMessage = React.createClass({
|
||||
_unavailableMessage: "The content on LBRY is hosted by its users. It appears there are no users " +
|
||||
"connected that have this file at the moment.",
|
||||
propTypes: {
|
||||
onShowActionsClicked: React.PropTypes.func,
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className="file-unavailable-message">
|
||||
<span className="empty">This file is not currently available.</span> { ' ' }
|
||||
<ToolTipLink label="Why?" tooltip={this._unavailableMessage} className="not-available-tooltip-link" /> { ' ' }
|
||||
{'onShowActionsClicked' in this.props
|
||||
? <Link label="Try Anyway" className="button-text" onClick={this.props.onShowActionsClicked} />
|
||||
: null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default FileUnavailableMessage;
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import {Icon, ToolTip} from './common.js';
|
||||
import {Icon} from './common.js';
|
||||
|
||||
export let Link = React.createClass({
|
||||
propTypes: {
|
||||
|
@ -51,49 +51,4 @@ export let Link = React.createClass({
|
|||
</a>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export let ToolTipLink = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showTooltip: false,
|
||||
};
|
||||
},
|
||||
handleClick: function() {
|
||||
if (this.props.tooltip) {
|
||||
this.setState({
|
||||
showTooltip: !this.state.showTooltip,
|
||||
});
|
||||
}
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick();
|
||||
}
|
||||
},
|
||||
handleTooltipMouseOut: function() {
|
||||
this.setState({
|
||||
showTooltip: false,
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
const linkClass = 'tooltip-link__link ' + (this.props.className ? this.props.className + '__link' : '') +
|
||||
(this.props.button ? ' button-block button-' + this.props.button : '') +
|
||||
(this.props.hidden ? ' hidden' : '') +
|
||||
(this.props.disabled ? ' disabled' : '');
|
||||
const toolTipClass = 'tooltip-link__tooltip ' + (this.props.className ? this.props.className + '__tooltip' : '');
|
||||
|
||||
return (
|
||||
<span className={'tooltip-link ' + (this.props.className || '')}>
|
||||
<a className={linkClass} href={this.props.href || 'javascript:;'}
|
||||
title={this.props.title} onClick={this.handleClick}>
|
||||
{this.props.icon ? <Icon icon={this.props.icon} /> : null }
|
||||
{this.props.label}
|
||||
</a>
|
||||
{(!this.props.tooltip ? null :
|
||||
<ToolTip className={toolTipClass} open={this.state.showTooltip} onMouseOut={this.handleTooltipMouseOut}>
|
||||
{this.props.tooltip}
|
||||
</ToolTip>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
36
js/component/tooltip.js
Normal file
36
js/component/tooltip.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
import React from 'react';
|
||||
|
||||
export let ToolTip = React.createClass({
|
||||
propTypes: {
|
||||
body: React.PropTypes.string.isRequired,
|
||||
label: React.PropTypes.string.isRequired
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
showTooltip: false,
|
||||
};
|
||||
},
|
||||
handleClick: function() {
|
||||
this.setState({
|
||||
showTooltip: !this.state.showTooltip,
|
||||
});
|
||||
},
|
||||
handleTooltipMouseOut: function() {
|
||||
this.setState({
|
||||
showTooltip: false,
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<span className={'tooltip ' + (this.props.className || '')}>
|
||||
<a className="tooltip__link" onClick={this.handleClick}>
|
||||
{this.props.label}
|
||||
</a>
|
||||
<div className={'tooltip__body ' + (this.state.showTooltip ? '' : ' hidden')}
|
||||
onMouseOut={this.handleTooltipMouseOut}>
|
||||
{this.props.body}
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import lbry from '../lbry.js';
|
||||
import lighthouse from '../lighthouse.js';
|
||||
import {FileTile} from '../component/file-tile.js';
|
||||
import {Link, ToolTipLink} from '../component/link.js';
|
||||
import {Link} from '../component/link.js';
|
||||
import {ToolTip} from '../component/tooltip.js';
|
||||
import {BusyMessage} from '../component/common.js';
|
||||
|
||||
var fetchResultsStyle = {
|
||||
|
@ -81,9 +82,8 @@ var FeaturedContent = React.createClass({
|
|||
</div>
|
||||
<div className="span6">
|
||||
<h3>
|
||||
Community Content {' '}
|
||||
<ToolTipLink label="What's this?"
|
||||
tooltip={toolTipText} />
|
||||
Community Content
|
||||
<ToolTip label="What's this?" body={toolTipText} className="tooltip--header"/>
|
||||
</h3>
|
||||
<FileTile name="one" />
|
||||
<FileTile name="two" />
|
||||
|
|
|
@ -8,7 +8,7 @@ html
|
|||
body
|
||||
{
|
||||
font-family: 'Source Sans Pro', sans-serif;
|
||||
line-height: 1.3333;
|
||||
line-height: $font-line-height;
|
||||
}
|
||||
|
||||
$drawer-width: 240px;
|
||||
|
|
|
@ -16,6 +16,7 @@ $color-money: #216C2A;
|
|||
$color-meta-light: #505050;
|
||||
|
||||
$font-size: 16px;
|
||||
$font-line-height: 1.3333;
|
||||
|
||||
$mobile-width-threshold: 801px;
|
||||
$max-content-width: 1000px;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@import "global";
|
||||
|
||||
@mixin text-link($color: $color-primary, $hover-opacity: 0.70) {
|
||||
color: $color;
|
||||
|
||||
.icon
|
||||
{
|
||||
&:first-child {
|
||||
|
@ -29,6 +29,7 @@
|
|||
}
|
||||
|
||||
color: $color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon-fixed-width {
|
||||
|
@ -200,7 +201,7 @@ input[type="text"], input[type="search"]
|
|||
}
|
||||
.button-text-help
|
||||
{
|
||||
@include text-link(#5b8c80);
|
||||
@include text-link(#aaa);
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
@import "component/_table";
|
||||
@import "component/_file-actions.scss";
|
||||
@import "component/_file-tile.scss";
|
||||
@import "component/_file-unavailable-message.scss";
|
||||
@import "component/_menu.scss";
|
||||
@import "component/_tooltiplink.scss";
|
||||
@import "component/_tooltip.scss";
|
||||
@import "page/_developer.scss";
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
$color-download: #444;
|
||||
|
||||
.file-actions--stub
|
||||
.file-actions
|
||||
{
|
||||
height: $height-button;
|
||||
line-height: $height-button;
|
||||
min-height: $height-button;
|
||||
}
|
||||
|
||||
.file-actions__download-status-bar
|
||||
|
|
|
@ -28,14 +28,4 @@
|
|||
color: #444;
|
||||
margin-top: 12px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.file-tile__not-available-message {
|
||||
height: auto;
|
||||
text-align: right;
|
||||
color: $color-notice;
|
||||
}
|
||||
|
||||
.file-tile .not-available-tooltip-link__tooltip { /* temporary */
|
||||
left: -225px;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
.file-unavailable-message {
|
||||
font-size: 14px;
|
||||
|
||||
.not-available-tooltip-link__tooltip { /* temporary */
|
||||
left: -225px;
|
||||
}
|
||||
|
||||
.not-available-tooltip-link__link {
|
||||
@include text-link();
|
||||
font-size: 14px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,35 @@
|
|||
@import "../global";
|
||||
|
||||
.tooltip {
|
||||
text-align: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tooltip__link {
|
||||
@include text-link();
|
||||
}
|
||||
|
||||
.tooltip__body {
|
||||
$tooltip-body-width: 300px;
|
||||
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 100%;
|
||||
left: -120px;
|
||||
width: 260px;
|
||||
padding: 15px;
|
||||
left: 50%;
|
||||
margin-left: $tooltip-body-width * -1 / 2;
|
||||
|
||||
box-sizing: border-box;
|
||||
padding: $spacing-vertical / 2;
|
||||
width: $tooltip-body-width;
|
||||
border: 1px solid #aaa;
|
||||
color: $color-text-dark;
|
||||
background-color: $color-bg;
|
||||
font-size: 14px;
|
||||
font-size: $font-size * 7/8;
|
||||
line-height: $font-line-height;
|
||||
box-shadow: $default-box-shadow;
|
||||
}
|
||||
|
||||
.tooltip--header .tooltip__link {
|
||||
@include text-link(#aaa);
|
||||
font-size: $font-size * 3/4;
|
||||
margin-left: $padding-button;
|
||||
vertical-align: middle;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
.tooltip-link {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tooltip-link__link {
|
||||
font-size: 12px;
|
||||
color: #aaa;
|
||||
vertical-align: 15%;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue