diff --git a/js/component/file-tile.js b/js/component/file-tile.js new file mode 100644 index 000000000..8778d3755 --- /dev/null +++ b/js/component/file-tile.js @@ -0,0 +1,87 @@ +import React from 'react'; +import lbry from '../lbry.js'; +import {Link, DownloadLink, WatchLink} from '../component/link.js'; +import {Thumbnail, TruncatedText, CreditAmount} from '../component/common.js'; + +let FileTile = React.createClass({ + getInitialState: function() { + return { + downloading: false, + isHovered: false, + cost: null, + costIncludesData: null, + } + }, + handleMouseOver: function() { + this.setState({ + isHovered: true, + }); + }, + handleMouseOut: function() { + this.setState({ + isHovered: false, + }); + }, + componentWillMount: function() { + if ('cost' in this.props) { + this.setState({ + cost: this.props.cost, + costIncludesData: this.props.costIncludesData, + }); + } else { + lbry.getCostInfoForName(this.props.name, ({cost, includesData}) => { + this.setState({ + cost: cost, + costIncludesData: includesData, + }); + }); + } + }, + render: function() { + var obscureNsfw = !lbry.getClientSetting('showNsfw') && this.props.nsfw; + return ( + <section className={ 'file-tile card ' + (obscureNsfw ? 'card-obscured ' : '') + (this.props.compact ? 'file-tile--compact' : '')} onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}> + <div className="row-fluid card-content file-tile__row"> + <div className="span3"> + <a href={'/?show=' + this.props.name}><Thumbnail className="file-tile__thumbnail" src={this.props.imgUrl} alt={'Photo for ' + (this.props.title || this.props.name)} /></a> + </div> + <div className="span9"> + {this.state.cost !== null + ? <span className="file-tile__cost"> + <CreditAmount amount={this.state.cost} isEstimate={!this.state.costIncludesData}/> + </span> + : null} + <div className="meta"><a href={'/?show=' + this.props.name}>lbry://{this.props.name}</a></div> + <h3 className={'file-tile__title ' + (this.props.compact ? 'file-tile__title--compact' : '')}> + <a href={'/?show=' + this.props.name}> + <TruncatedText lines={3}> + {this.props.title} + </TruncatedText> + </a> + </h3> + <div> + {this.props.mediaType == 'video' ? <WatchLink streamName={this.props.name} button="primary" /> : null} + <DownloadLink streamName={this.props.name} button="text" /> + </div> + <p className="file-tile__description"> + <TruncatedText lines={3}> + {this.props.description} + </TruncatedText> + </p> + </div> + </div> + { + !obscureNsfw || !this.state.isHovered ? null : + <div className='card-overlay'> + <p> + This content is Not Safe For Work. + To view adult content, please change your <Link href="?settings" label="Settings" />. + </p> + </div> + } + </section> + ); + } +}); + +export default FileTile; \ No newline at end of file diff --git a/js/page/discover.js b/js/page/discover.js index af9792236..9bb26827d 100644 --- a/js/page/discover.js +++ b/js/page/discover.js @@ -1,6 +1,7 @@ import React from 'react'; import lbry from '../lbry.js'; import lighthouse from '../lighthouse.js'; +import FileTile from '../component/file-tile.js'; import {Link, ToolTipLink, DownloadLink, WatchLink} from '../component/link.js'; import {Thumbnail, CreditAmount, TruncatedText, BusyMessage} from '../component/common.js'; @@ -222,9 +223,9 @@ var FeaturedContentItem = React.createClass({ } return (<div style={featuredContentItemContainerStyle}> - <SearchResultRow name={this.props.name} title={this.state.title} imgUrl={this.state.metadata.thumbnail} - description={this.state.metadata.description} mediaType={lbry.getMediaType(this.state.metadata.content_type)} - nsfw={this.state.metadata.nsfw} compact /> + <FileTile name={this.props.name} title={this.state.title} imgUrl={this.state.metadata.thumbnail} + description={this.state.metadata.description} mediaType={lbry.getMediaType(this.state.metadata.content_type)} + nsfw={this.state.metadata.nsfw} compact /> </div>); } }); diff --git a/scss/_gui.scss b/scss/_gui.scss index 965d2eb9e..5b64a29f0 100644 --- a/scss/_gui.scss +++ b/scss/_gui.scss @@ -367,3 +367,39 @@ input[type="text"], input[type="search"] word-break: break-all; } + +.file-tile--compact { + height: 180px; +} + +.file-tile__row { + height: 24px * 7; + overflow-y: hidden; +} + +.file-tile__thumbnail { + max-width: 100%; + max-height: 24px * 7; + display: block; + margin-left: auto; + margin-right: auto; +} + +.file-tile__title { + font-weight: bold; +} + +.file-tile__title--compact { + font-size: 1.25em; + line-height: 1.15; +} + +.file-tile__cost { + float: right; +} + +.file-tile__description { + color: #444; + margin-top: 12px; + font-size: 0.9em; +}