diff --git a/js/component/common.js b/js/component/common.js index a342074c1..fcb7fbd0d 100644 --- a/js/component/common.js +++ b/js/component/common.js @@ -50,31 +50,6 @@ export let BusyMessage = React.createClass({ } }); -var toolTipStyle = { - position: 'absolute', - zIndex: '1', - top: '100%', - left: '-120px', - width: '260px', - padding: '15px', - border: '1px solid #aaa', - backgroundColor: '#fff', - fontSize: '14px', -}; -export let ToolTip = React.createClass({ - propTypes: { - open: React.PropTypes.bool.isRequired, - onMouseOut: React.PropTypes.func - }, - render: function() { - return ( -
- {this.props.children} -
- ); - } -}); - var creditAmountStyle = { color: '#216C2A', fontWeight: 'bold', diff --git a/js/component/file-actions.js b/js/component/file-actions.js index ec4a14e06..0ad8ba04d 100644 --- a/js/component/file-actions.js +++ b/js/component/file-actions.js @@ -4,6 +4,7 @@ import {Link} from '../component/link.js'; import {Icon} from '../component/common.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({ @@ -50,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 { @@ -70,7 +67,7 @@ export let FileActions = React.createClass({ menuOpen: false, deleteChecked: false, attemptingDownload: false, - attemptingRemove: false, + attemptingRemove: false } }, onFileInfoUpdate: function(fileInfo) { @@ -166,10 +163,11 @@ export let FileActions = React.createClass({ render: function() { if (this.state.fileInfo === null) { - return
; + 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) { @@ -180,20 +178,21 @@ export let FileActions = React.createClass({ label = this.state.fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...', labelWithIcon = {label}; - linkBlock = + linkBlock = (
{labelWithIcon}
{labelWithIcon} -
; + + ); } else { linkBlock = ; } return ( -
+
{(this.props.metadata.content_type && this.props.metadata.content_type.startsWith('video/')) ? : null} {this.state.fileInfo !== null || this.state.fileInfo.isMine ? -
{linkBlock}
+
{linkBlock}
: null} { showMenu ? @@ -215,7 +214,62 @@ export let FileActions = React.createClass({ -
+ ); } }); + +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 (
+ { + this.state.available || this.state.forceShowActions ? + : + (
+
This file is not currently available.
+
+ +
+
+ +
+
) + } +
); + } +}); diff --git a/js/component/file-tile.js b/js/component/file-tile.js index 42f79d16c..e3a4b83d1 100644 --- a/js/component/file-tile.js +++ b/js/component/file-tile.js @@ -64,7 +64,8 @@ export let FileTileStream = React.createClass({ getInitialState: function() { return { showNsfwHelp: false, - isHidden: false + isHidden: false, + available: null, } }, getDefaultProps: function() { @@ -112,11 +113,10 @@ export let FileTileStream = React.createClass({ const metadata = this.props.metadata || {}, obscureNsfw = this.props.obscureNsfw && metadata.nsfw, - title = metadata.title ? metadata.title : ('lbry://' + this.props.name); - + title = metadata.title ? metadata.title : ('lbry://' + this.props.name); return (
-
+
@@ -157,7 +157,8 @@ export let FileTile = React.createClass({ _isMounted: false, propTypes: { - name: React.PropTypes.string.isRequired + name: React.PropTypes.string.isRequired, + available: React.PropTypes.bool, }, getInitialState: function() { @@ -187,6 +188,6 @@ export let FileTile = React.createClass({ return null; } - return ; + return ; } }); \ No newline at end of file diff --git a/js/component/link.js b/js/component/link.js index 4a80ee830..d19e0b46c 100644 --- a/js/component/link.js +++ b/js/component/link.js @@ -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,54 +51,4 @@ export let Link = React.createClass({ ); } -}); - -var linkContainerStyle = { - position: 'relative', -}; - -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() { - var href = this.props.href ? this.props.href : 'javascript:;', - icon = this.props.icon ? : '', - className = this.props.className + - (this.props.button ? ' button-block button-' + this.props.button : '') + - (this.props.hidden ? ' hidden' : '') + - (this.props.disabled ? ' disabled' : ''); - - return ( - - - {this.props.icon ? icon : '' } - {this.props.label} - - {(!this.props.tooltip ? null : - - {this.props.tooltip} - - )} - - ); - } -}); +}); \ No newline at end of file diff --git a/js/component/tooltip.js b/js/component/tooltip.js new file mode 100644 index 000000000..eb7d7d4fb --- /dev/null +++ b/js/component/tooltip.js @@ -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 ( + + + {this.props.label} + +
+ {this.props.body} +
+
+ ); + } +}); \ No newline at end of file diff --git a/js/lbry.js b/js/lbry.js index 9063aca2e..96965ec99 100644 --- a/js/lbry.js +++ b/js/lbry.js @@ -10,6 +10,7 @@ var lbry = { }, defaultClientSettings: { showNsfw: false, + showUnavailable: true, debug: false, useCustomLighthouseServers: false, customLighthouseServers: [], diff --git a/js/page/discover.js b/js/page/discover.js index 3e0bf65e2..de59d09d7 100644 --- a/js/page/discover.js +++ b/js/page/discover.js @@ -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 = { @@ -47,7 +48,7 @@ var SearchResults = React.createClass({ if (!seenNames[name]) { seenNames[name] = name; rows.push( - + ); } }); @@ -65,6 +66,9 @@ var featuredContentLegendStyle = { var FeaturedContent = React.createClass({ render: function() { + const toolTipText = ('Community Content is a public space where anyone can share content with the ' + + 'rest of the LBRY community. Bid on the names "one," "two," "three," "four" and ' + + '"five" to put your content here!'); return (
@@ -77,8 +81,10 @@ var FeaturedContent = React.createClass({
-

Community Content

+

+ Community Content + +

diff --git a/js/page/settings.js b/js/page/settings.js index 81403492b..b192f15c9 100644 --- a/js/page/settings.js +++ b/js/page/settings.js @@ -51,7 +51,8 @@ var SettingsPage = React.createClass({ getInitialState: function() { return { settings: null, - showNsfw: lbry.getClientSetting('showNsfw') + showNsfw: lbry.getClientSetting('showNsfw'), + showUnavailable: lbry.getClientSetting('showUnavailable'), } }, componentDidMount: function() { @@ -69,6 +70,9 @@ var SettingsPage = React.createClass({ onShowNsfwChange: function(event) { lbry.setClientSetting('showNsfw', event.target.checked); }, + onShowUnavailableChange: function(event) { + lbry.setClientSetting('showUnavailable', event.target.checked); + }, render: function() { if (!this.state.daemonSettings) { return null; @@ -114,7 +118,7 @@ var SettingsPage = React.createClass({

Content

NSFW content may include nudity, intense sexuality, profanity, or other adult content. @@ -122,6 +126,17 @@ var SettingsPage = React.createClass({
+
+

Search

+
+
+ Would you like search results to include items that are not currently available for download? +
+ +
+

Share Diagnostic Data