approaching acceptable

This commit is contained in:
Jeremy Kauffman 2017-04-11 22:01:45 -04:00
parent 0ba69ff32b
commit 0313ba941a
13 changed files with 126 additions and 158 deletions

View file

@ -106,6 +106,8 @@ var App = React.createClass({
if (target.matches('a[href^="?"]')) {
event.preventDefault();
if (this._isMounted) {
history.pushState({}, document.title, target.getAttribute('href'));
this.registerHistoryPop();
this.setState(this.getViewingPageAndArgs(target.getAttribute('href')));
}
}
@ -147,6 +149,11 @@ var App = React.createClass({
componentWillUnmount: function() {
this._isMounted = false;
},
registerHistoryPop: function() {
window.addEventListener("popstate", function() {
this.setState(this.getViewingPageAndArgs(location.pathname));
}.bind(this));
},
handleUpgradeClicked: function() {
// Make a new directory within temp directory so the filename is guaranteed to be available
const dir = fs.mkdtempSync(app.getPath('temp') + require('path').sep);
@ -261,7 +268,7 @@ var App = React.createClass({
case 'start':
return <StartPage />;
case 'rewards':
return <RewardsPage />;
return <RewardsPage />;
case 'wallet':
case 'send':
case 'receive':

View file

@ -3,20 +3,18 @@ import lbry from '../lbry.js';
import uri from '../uri.js';
import {Icon} from './common.js';
const ChannelIndicator = React.createClass({
const UriIndicator = React.createClass({
propTypes: {
uri: React.PropTypes.string.isRequired,
hasSignature: React.PropTypes.bool.isRequired,
signatureIsValid: React.PropTypes.bool,
},
render: function() {
if (!this.props.hasSignature) {
return null;
}
const uriObj = uri.parseLbryUri(this.props.uri);
if (!uriObj.isChannel) {
return null;
if (!this.props.hasSignature || !uriObj.isChannel) {
return <span className="empty">Anonymous</span>;
}
const channelUriObj = Object.assign({}, uriObj);
@ -25,7 +23,6 @@ const ChannelIndicator = React.createClass({
let icon, modifier;
if (this.props.signatureIsValid) {
icon = 'icon-check-circle';
modifier = 'valid';
} else {
icon = 'icon-times-circle';
@ -33,11 +30,13 @@ const ChannelIndicator = React.createClass({
}
return (
<span>
by <strong>{channelUri}</strong> {' '}
<Icon icon={icon} className={`channel-indicator__icon channel-indicator__icon--${modifier}`} />
{channelUri} {' '}
{ !this.props.signatureIsValid ?
<Icon icon={icon} className={`channel-indicator__icon channel-indicator__icon--${modifier}`} /> :
'' }
</span>
);
}
});
export default ChannelIndicator;
export default UriIndicator;

View file

@ -54,15 +54,6 @@ export let BusyMessage = React.createClass({
}
});
var creditAmountStyle = {
color: '#216C2A',
fontWeight: 'bold',
fontSize: '0.8em'
}, estimateStyle = {
fontSize: '0.8em',
color: '#aaa',
};
export let CurrencySymbol = React.createClass({
render: function() { return <span>LBC</span>; }
});
@ -76,8 +67,8 @@ export let CreditAmount = React.createClass({
var formattedAmount = lbry.formatCredits(this.props.amount, this.props.precision ? this.props.precision : 1);
return (
<span className="credit-amount">
<span style={creditAmountStyle}>{formattedAmount} {parseFloat(formattedAmount) == 1.0 ? 'credit' : 'credits'}</span>
{ this.props.isEstimate ? <span style={estimateStyle}> (est)</span> : null }
<span>{formattedAmount} {parseFloat(formattedAmount) == 1.0 ? 'credit' : 'credits'}</span>
{ this.props.isEstimate ? <span style={estimateStyle}>*</span> : null }
</span>
);
}

View file

@ -4,7 +4,7 @@ import uri from '../uri.js';
import {Link} from '../component/link.js';
import {FileActions} from '../component/file-actions.js';
import {Thumbnail, TruncatedText, CreditAmount} from '../component/common.js';
import ChannelIndicator from '../component/channel-indicator.js';
import UriIndicator from '../component/channel-indicator.js';
let FilePrice = React.createClass({
_isMounted: false,
@ -41,15 +41,10 @@ let FilePrice = React.createClass({
},
render: function() {
if (this.state.cost === null)
{
return null;
}
return (
<span className="file-price">
<CreditAmount amount={this.state.cost} isEstimate={!this.state.costIncludesData}/>
</span>
this.state.cost !== null ?
<CreditAmount amount={this.state.cost} isEstimate={!this.state.costIncludesData}/> :
<span className="credit-amount">...</span>
);
}
});
@ -117,14 +112,10 @@ export let FileTileStream = React.createClass({
}
},
render: function() {
console.log('rendering.')
if (this.state.isHidden) {
console.log('hidden, so returning null')
return null;
}
console.log("inside FileTileStream. metadata is", this.props.metadata)
const lbryUri = uri.normalizeLbryUri(this.props.uri);
const metadata = this.props.metadata;
const isConfirmed = typeof metadata == 'object';
@ -140,7 +131,6 @@ export let FileTileStream = React.createClass({
{ !this.props.hidePrice
? <FilePrice uri={this.props.uri} />
: null}
<<<<<<< dd3f3ec4d00066633b136925111bae7193b3c6a8
<div className="card__title-primary">
<div className="meta"><a href={'?show=' + this.props.uri}>{lbryUri}</a></div>
<h3>
@ -158,27 +148,11 @@ export let FileTileStream = React.createClass({
<p className="file-tile__description">
<TruncatedText lines={3}>
{isConfirmed
? metadata.description
: <span className="empty">This file is pending confirmation.</span>}
=======
<div className="meta"><a href={'?show=' + this.props.uri}>{'lbry://' + this.props.uri}</a></div>
<h3 className="file-tile__title">
<a href={'?show=' + this.props.uri}>
<TruncatedText lines={1}>
{title}
>>>>>>> more
? metadata.description
: <span className="empty">This file is pending confirmation.</span>}
</TruncatedText>
</a>
</h3>
<ChannelIndicator uri={this.props.uri} claimInfo={this.props.claimInfo} />
<FileActions uri={this.props.uri} outpoint={this.props.outpoint} metadata={metadata} contentType={this._contentType} />
<p className="file-tile__description">
<TruncatedText lines={3}>
{isConfirmed
? metadata.description
: <span className="empty">This file is pending confirmation.</span>}
</TruncatedText>
</p>
</p>
</div>
</div>
</div>
{this.state.showNsfwHelp
@ -218,7 +192,8 @@ export let FileCardStream = React.createClass({
getDefaultProps: function() {
return {
obscureNsfw: !lbry.getClientSetting('showNsfw'),
hidePrice: false
hidePrice: false,
hasSignature: false,
}
},
componentDidMount: function() {
@ -227,11 +202,6 @@ export let FileCardStream = React.createClass({
this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
}
},
componentWillMount: function() {
const {value: {stream: {metadata, source: {contentType}}}} = this.props.claimInfo;
this._metadata = metadata;
this._contentType = contentType;
},
componentWillUnmount: function() {
if (this._fileInfoSubscribeId) {
lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId);
@ -245,79 +215,56 @@ export let FileCardStream = React.createClass({
}
},
handleMouseOver: function() {
if (this.props.obscureNsfw && this.props.metadata && this._metadata.nsfw) {
this.setState({
showNsfwHelp: true,
});
}
this.setState({
hovered: true,
});
},
handleMouseOut: function() {
if (this.state.showNsfwHelp) {
this.setState({
showNsfwHelp: false,
});
}
this.setState({
hovered: false,
});
},
render: function() {
if (this.state.isHidden) {
return null;
}
<<<<<<< dd3f3ec4d00066633b136925111bae7193b3c6a8
const lbryUri = uri.normalizeLbryUri(this.props.uri);
const metadata = this.props.metadata;
=======
const metadata = this._metadata;
>>>>>>> more
const isConfirmed = typeof metadata == 'object';
const title = isConfirmed ? metadata.title : lbryUri;
const obscureNsfw = this.props.obscureNsfw && isConfirmed && metadata.nsfw;
console.log(this.props);
const primaryUrl = '?watch=' + lbryUri;
return (
<section className={ 'card card--small ' + (obscureNsfw ? 'card--obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
<section className={ 'card card--small card--link ' + (obscureNsfw ? 'card--obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
<div className="card__inner">
<div className="card__title-identity">
<h4>
<a href={'?show=' + this.props.uri}>
<TruncatedText lines={1}>
{title}
<a href={primaryUrl} className="card__link">
<div className="card__title-identity">
<h5><TruncatedText lines={1}>{title}</TruncatedText></h5>
<div className="card__subtitle">
{ !this.props.hidePrice ? <span style={{float: "right"}}><FilePrice uri={this.props.uri} /></span> : null}
<UriIndicator uri={lbryUri} metadata={metadata} contentType={this.props.contentType}
hasSignature={this.props.hasSignature} signatureIsValid={this.props.signatureIsValid} />
</div>
</div>
<div className="card__media" style={{ backgroundImage: "url('" + metadata.thumbnail + "')" }}></div>
<div className="card__content card__subtext card__subtext--two-lines">
<TruncatedText lines={2}>
{isConfirmed
? metadata.description
: <span className="empty">This file is pending confirmation.</span>}
</TruncatedText>
</a>
</h4>
<<<<<<< dd3f3ec4d00066633b136925111bae7193b3c6a8
<div className="card__subtitle"><a href={'?show=' + lbryUri}>{lbryUri}</a></div></div>
<ChannelIndicator uri={lbryUri} metadata={metadata} contentType={this.props.contentType}
hasSignature={this.props.hasSignature} signatureIsValid={this.props.signatureIsValid} />
=======
<ChannelIndicator uri={this.props.uri} claimInfo={this.props.claimInfo} />
</div>
>>>>>>> more
<div className="card__media">
<a href={'?show=' + this.props.uri}><Thumbnail src={metadata.thumbnail} alt={'Photo for ' + (title || this.props.uri)} /></a>
</div>
{ !this.props.hidePrice
? <FilePrice uri={this.props.uri} />
</div>
</a>
{this.state.showNsfwHelp && this.state.hovered
? <div className='card-overlay'>
<p>
This content is Not Safe For Work.
To view adult content, please change your <Link className="button-text" href="?settings" label="Settings" />.
</p>
</div>
: null}
<div className="card__content card__subtext card__subtext--two-lines">
<TruncatedText lines={2}>
{isConfirmed
? metadata.description
: <span className="empty">This file is pending confirmation.</span>}
</TruncatedText>
</div>
<div className="card__actions card__actions--bottom">
<FileActions uri={this.props.uri} outpoint={this.props.outpoint} metadata={metadata} contentType={this.props.contentType} />
</div>
</div>
{this.state.showNsfwHelp
? <div className='card-overlay'>
<p>
This content is Not Safe For Work.
To view adult content, please change your <Link className="button-text" href="?settings" label="Settings" />.
</p>
</div>
: null}
</section>
);
}
@ -360,7 +307,7 @@ export let FileTile = React.createClass({
const {txid, nout, has_signature, signature_is_valid,
value: {stream: {metadata, source: {contentType}}}} = this.state.claimInfo;
return
return this.props.displayStyle == 'card' ?
<FileCardStream outpoint={txid + ':' + nout} metadata={metadata} contentType={contentType}
hasSignature={has_signature} signatureIsValid={signature_is_valid} {... this.props}/> :

View file

@ -250,10 +250,6 @@ lbry.getCostInfo = function(lbryUri, callback, errorCallback) {
* - includes_data: Boolean; indicates whether or not the data fee info
* from Lighthouse is included.
*/
if (!name) {
throw new Error(`Name required.`);
}
function getCostWithData(name, size, callback, errorCallback) {
lbry.stream_cost_estimate({name, size}).then((cost) => {
callback({
@ -507,7 +503,7 @@ lbry.stop = function(callback) {
lbry.fileInfo = {};
lbry._subscribeIdCount = 0;
lbry._fileInfoSubscribeCallbacks = {};
lbry._fileInfoSubscribeInterval = 5000;
lbry._fileInfoSubscribeInterval = 500000;
lbry._balanceSubscribeCallbacks = {};
lbry._balanceSubscribeInterval = 5000;
lbry._removedFiles = [];
@ -519,6 +515,7 @@ lbry._updateClaimOwnershipCache = function(claimId) {
return match || claimInfo.claim_id == claimId;
});
});
};
lbry._updateFileInfoSubscribers = function(outpoint) {

View file

@ -65,7 +65,7 @@ const communityCategoryToolTipText = ('Community Content is a public space where
var FeaturedCategory = React.createClass({
render: function() {
return (<div className="card-row">
return (<div className="card-row card-row--small">
{ this.props.category ?
<h3 className="card-row__header">{this.props.category}
{ this.props.category == "community" ?
@ -80,21 +80,28 @@ var FeaturedCategory = React.createClass({
var FeaturedContent = React.createClass({
getInitialState: function() {
return {
featuredNames: {},
featuredUris: {},
};
},
componentWillMount: function() {
lbryio.call('discover', 'list', { version: "early-access" } ).then((featuredNames) => {
this.setState({ featuredNames: featuredNames });
lbryio.call('discover', 'list', { version: "early-access" } ).then(({Categories, Uris}) => {
let featuredUris = {}
Categories.forEach((category) => {
if (Uris[category] && Uris[category].length) {
featuredUris[category] = Uris[category]
}
})
this.setState({ featuredUris: featuredUris });
});
},
render: function() {
console.log(this.state.featuredNames);
return (
<div>
{
Object.keys(this.state.featuredNames).map(function(category) {
return <FeaturedCategory key={category} category={category} names={this.state.featuredNames[category]} />
Object.keys(this.state.featuredUris).map(function(category) {
return this.state.featuredUris[category].length ?
<FeaturedCategory key={category} category={category} names={this.state.featuredUris[category]} /> :
'';
}.bind(this))
}
</div>

View file

@ -373,8 +373,6 @@ var PublishPage = React.createClass({
</div>
</div>
<div className="card__content">
<FormRow label="lbry://" type="text" ref="name" placeholder="lbry://myname" value={this.state.rawName} onChange={this.handleNameChange}
helper={(<div>What LBRY name would you like to claim for this file? <Link label="Read more" href="https://lbry.io/faq/naming" />.</div>)} />
<FormRow name="file" label="File" ref="file" type="file" onChange={this.onFileChange}
helper={this.state.myClaimExists ? "If you don't choose a file, the file from your existing claim will be used." : null}/>
</div>

View file

@ -88,8 +88,9 @@ var FormatsSection = React.createClass({
return (
<div>
{ this.props.metadata.thumbnail ? <div style={{backgroundImage: this.props.metadata.thumbnail}}></div> : '' }
<h1>{this.props.metadata.title}</h1>
<div className="meta">{this.props.uri}</div>
<h2>{this.props.metadata.title}</h2>
{/* In future, anticipate multiple formats, just a guess at what it could look like
// var formats = this.props.metadata.formats
// return (<tbody>{formats.map(function(format,i){ */}
@ -141,7 +142,6 @@ var ShowPage = React.createClass({
return (
<main>
<section className="card">
{this.state.uriLookupComplete ? (
<FormatsSection uri={this._uri} outpoint={this.state.outpoint} metadata={this.state.metadata} cost={this.state.cost} costIncludesData={this.state.costIncludesData} contentType={this.state.contentType} />
) : (
@ -150,7 +150,6 @@ var ShowPage = React.createClass({
There is no content available at <strong>{this._uri}</strong>. If you reached this page from a link within the LBRY interface, please <Link href="?report" label="report a bug" />. Thanks!
</div>
)}
</section>
</main>);
}
});

View file

@ -11,7 +11,7 @@ body
line-height: $font-line-height;
}
$drawer-width: 240px;
$drawer-width: 220px;
#drawer
{
@ -39,12 +39,8 @@ $drawer-width: 240px;
.badge
{
float: right;
background: $color-money;
display: inline-block;
padding: 2px;
color: white;
margin-top: $spacing-vertical * 0.25 - 2;
border-radius: 2px;
background: $color-money;
}
}
.drawer-item-selected
@ -53,6 +49,19 @@ $drawer-width: 240px;
color: $color-primary;
}
}
.badge
{
background: $color-money;
display: inline-block;
padding: 2px;
color: white;
border-radius: 2px;
}
.credit-amount
{
font-weight: bold;
color: $color-money;
}
#drawer-handle
{
padding: $spacing-vertical / 2;

View file

@ -52,13 +52,6 @@ section
}
*/
main h1 {
font-size: 2.0em;
margin-bottom: $spacing-vertical;
margin-top: $spacing-vertical*2;
font-family: 'Raleway', sans-serif;
}
h2 {
font-size: 1.75em;
}

View file

@ -76,22 +76,36 @@ $padding-card-horizontal: $spacing-vertical * 2/3;
font-weight: 600;
}
.card__media img {
max-width: 100%;;
$card-link-scaling: 1.1;
.card__link {
display: block;
margin-left: auto;
margin-right: auto;
}
.card--link:hover {
position: relative;
z-index: 1;
box-shadow: $focus-box-shadow;
transform: scale($card-link-scaling);
transform-origin: 50% 50%;
overflow-x: visible;
overflow-y: visible;
}
.card__media {
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
}
$width-card-small: $spacing-vertical * 12;
$height-card-small: $spacing-vertical * 15;
.card--small {
width: $width-card-small;
overflow-x: hidden;
white-space: normal;
}
.card--small .card__media {
max-height: $width-card-small * 9 / 16;
img {
max-height: $width-card-small * 9 / 16;
}
height: $width-card-small * 9 / 16;
}
.card__subtitle {
@ -118,6 +132,13 @@ $width-card-small: $spacing-vertical * 12;
margin-top: $spacing-vertical * 1/3;
}
}
.card-row--small {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding-left: 20px;
margin-left: -20px; /*hacky way to give space for hover */
}
.card-row__header {
margin-bottom: $spacing-vertical / 3;
}

View file

@ -1,5 +1,5 @@
@import "../global";
.channel-indicator__icon--invalid {
color: #b01c2e;
color: $color-error;
}

View file

@ -3,7 +3,7 @@
.file-tile__row {
height: $spacing-vertical * 7;
.file-price {
.credit-amount {
float: right;
}
}