rewards flow changes

This commit is contained in:
Jeremy Kauffman 2017-04-17 08:27:39 -04:00
parent 8d67d36ad9
commit e9c8abd307
12 changed files with 106 additions and 51 deletions

View file

@ -186,6 +186,9 @@ export let Thumbnail = React.createClass({
this._isMounted = false; this._isMounted = false;
}, },
render: function() { render: function() {
return <img ref="img" onError={this.handleError} {... this.props} src={this.state.imageUri} /> const className = this.props.className ? this.props.className : '',
otherProps = Object.assign({}, this.props)
delete otherProps.className;
return <img ref="img" onError={this.handleError} {...otherProps} className={className} src={this.state.imageUri} />
}, },
}); });

View file

@ -81,14 +81,14 @@ export let FileTileStream = React.createClass({
return ( return (
<section className={ 'file-tile card ' + (obscureNsfw ? 'card--obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}> <section className={ 'file-tile card ' + (obscureNsfw ? 'card--obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
<div className={"row-fluid card__inner file-tile__row"}> <div className={"row-fluid card__inner file-tile__row"}>
<div className="span3"> <div className="span3 file-tile__thumbnail-container">
<a href={'?show=' + lbryUri}><Thumbnail className="file-tile__thumbnail" {... metadata && metadata.thumbnail ? {src: metadata.thumbnail} : {}} alt={'Photo for ' + (title || this.props.uri)} /></a> <a href={'?show=' + lbryUri}><Thumbnail className="file-tile__thumbnail" {... metadata && metadata.thumbnail ? {src: metadata.thumbnail} : {}} alt={'Photo for ' + (title || this.props.uri)} /></a>
</div> </div>
<div className="span9"> <div className="span9">
<div className="card__title-primary">
{ !this.props.hidePrice { !this.props.hidePrice
? <FilePrice uri={this.props.uri} /> ? <FilePrice uri={this.props.uri} />
: null} : null}
<div className="card__title-primary">
<div className="meta"><a href={'?show=' + this.props.uri}>{lbryUri}</a></div> <div className="meta"><a href={'?show=' + this.props.uri}>{lbryUri}</a></div>
<h3> <h3>
<a href={'?show=' + this.props.uri}> <a href={'?show=' + this.props.uri}>
@ -103,7 +103,7 @@ export let FileTileStream = React.createClass({
</div> </div>
<div className="card__content"> <div className="card__content">
<p className="file-tile__description"> <p className="file-tile__description">
<TruncatedText lines={3}> <TruncatedText lines={2}>
{isConfirmed {isConfirmed
? metadata.description ? metadata.description
: <span className="empty">This file is pending confirmation.</span>} : <span className="empty">This file is pending confirmation.</span>}

View file

@ -7,7 +7,7 @@ const lbryio = {
_accessToken: getLocal('accessToken'), _accessToken: getLocal('accessToken'),
_authenticationPromise: null, _authenticationPromise: null,
_user : null, _user : null,
enabled: false enabled: true
}; };
const CONNECTION_STRING = 'http://localhost:8080/'; const CONNECTION_STRING = 'http://localhost:8080/';

View file

@ -4,6 +4,8 @@ import uri from '../uri.js';
import {Link} from '../component/link.js'; import {Link} from '../component/link.js';
import {FormField} from '../component/form.js'; import {FormField} from '../component/form.js';
import {FileTileStream} from '../component/file-tile.js'; import {FileTileStream} from '../component/file-tile.js';
import rewards from '../rewards.js';
import lbryio from '../lbryio.js';
import {BusyMessage, Thumbnail} from '../component/common.js'; import {BusyMessage, Thumbnail} from '../component/common.js';
@ -32,6 +34,9 @@ export let FileListDownloaded = React.createClass({
}); });
}); });
}, },
componentWillUnmount: function() {
this._isMounted = false;
},
render: function() { render: function() {
if (this.state.fileInfos === null) { if (this.state.fileInfos === null) {
return ( return (
@ -63,8 +68,22 @@ export let FileListPublished = React.createClass({
fileInfos: null, fileInfos: null,
}; };
}, },
_requestPublishReward: function() {
lbryio.call('reward', 'list', {}).then(function(userRewards) {
//already rewarded
if (userRewards.filter(function (reward) {
return reward.RewardType == rewards.TYPE_FIRST_PUBLISH && reward.TransactionID;
}).length) {
return;
}
else {
rewards.claimReward(rewards.TYPE_FIRST_PUBLISH).catch(() => {})
}
});
},
componentDidMount: function () { componentDidMount: function () {
this._isMounted = true; this._isMounted = true;
this._requestPublishReward();
document.title = "Published Files"; document.title = "Published Files";
lbry.claim_list_mine().then((claimInfos) => { lbry.claim_list_mine().then((claimInfos) => {
@ -80,6 +99,9 @@ export let FileListPublished = React.createClass({
}); });
}); });
}, },
componentWillUnmount: function() {
this._isMounted = false;
},
render: function () { render: function () {
if (this.state.fileInfos === null) { if (this.state.fileInfos === null) {
return ( return (

View file

@ -10,19 +10,6 @@ import Modal from '../component/modal.js';
var PublishPage = React.createClass({ var PublishPage = React.createClass({
_requiredFields: ['meta_title', 'name', 'bid', 'tos_agree'], _requiredFields: ['meta_title', 'name', 'bid', 'tos_agree'],
_requestPublishReward: function() {
lbryio.call('reward', 'list', {}).then(function(userRewards) {
//already rewarded
if (userRewards.filter(function (reward) {
return reward.RewardType == rewards.TYPE_FIRST_PUBLISH && reward.TransactionID;
}).length) {
return;
}
else {
rewards.claimReward(rewards.TYPE_FIRST_PUBLISH)
}
});
},
_updateChannelList: function(channel) { _updateChannelList: function(channel) {
// Calls API to update displayed list of channels. If a channel name is provided, will select // Calls API to update displayed list of channels. If a channel name is provided, will select
// that channel at the same time (used immediately after creating a channel) // that channel at the same time (used immediately after creating a channel)
@ -361,7 +348,6 @@ var PublishPage = React.createClass({
}, },
componentWillMount: function() { componentWillMount: function() {
this._updateChannelList(); this._updateChannelList();
// this._requestPublishReward();
}, },
componentDidMount: function() { componentDidMount: function() {
document.title = "Publish"; document.title = "Publish";
@ -574,7 +560,7 @@ var PublishPage = React.createClass({
<Modal isOpen={this.state.modal == 'publishStarted'} contentLabel="File published" <Modal isOpen={this.state.modal == 'publishStarted'} contentLabel="File published"
onConfirmed={this.handlePublishStartedConfirmed}> onConfirmed={this.handlePublishStartedConfirmed}>
<p>Your file has been published to LBRY at the address <code>lbry://{this.state.name}</code>!</p> <p>Your file has been published to LBRY at the address <code>lbry://{this.state.name}</code>!</p>
You will now be taken to your My Files page, where your newly published file will be listed. The file will take a few minutes to appear for other LBRY users; until then it will be listed as "pending." <p>The file will take a few minutes to appear for other LBRY users. Until then it will be listed as "pending" under your published files.</p>
</Modal> </Modal>
<Modal isOpen={this.state.modal == 'error'} contentLabel="Error publishing file" <Modal isOpen={this.state.modal == 'error'} contentLabel="Error publishing file"
onConfirmed={this.closeModal}> onConfirmed={this.closeModal}>

View file

@ -55,6 +55,7 @@ var RewardsPage = React.createClass({
}); });
}, },
render: function() { render: function() {
console.log(this.state.userRewards);
return ( return (
<main> <main>
<form onSubmit={this.handleSubmit}> <form onSubmit={this.handleSubmit}>

View file

@ -4,6 +4,7 @@ import {Link} from '../component/link.js';
import lbry from '../lbry.js'; import lbry from '../lbry.js';
import Modal from '../component/modal.js'; import Modal from '../component/modal.js';
import lbryio from '../lbryio.js'; import lbryio from '../lbryio.js';
import rewards from '../rewards.js';
import LoadScreen from '../component/load_screen.js' import LoadScreen from '../component/load_screen.js'
const fs = require('fs'); const fs = require('fs');
@ -182,6 +183,9 @@ export let Video = React.createClass({
return fs.createReadStream(status.download_path, opts) return fs.createReadStream(status.download_path, opts)
} }
}; };
rewards.claimNextPurchaseReward()
var elem = this.refs.video; var elem = this.refs.video;
var videostream = VideoStream(mediaFile, elem); var videostream = VideoStream(mediaFile, elem);
elem.play(); elem.play();

View file

@ -3,12 +3,13 @@ import lbryio from './lbryio.js';
function rewardMessage(type, amount) { function rewardMessage(type, amount) {
return { return {
new_developer: "You received ${amount} for registering as a new developer.", new_developer: `You earned ${amount} for registering as a new developer.`,
new_user: `You received ${amount} LBC new user reward.`, new_user: `You earned ${amount} LBC new user reward.`,
confirm_email: "You received ${amount} LBC for verifying your email address.", confirm_email: `You earned ${amount} LBC for verifying your email address.`,
first_channel: "You received ${amount} LBC for creating a publisher identity.", new_channel: `You earned ${amount} LBC for creating a publisher identity.`,
first_purchase: "You received ${amount} LBC for making your first purchase.", first_stream: `You earned ${amount} LBC for streaming your first video.`,
first_publish: "You received ${amount} LBC for making your first publication.", many_downloads: `You earned ${amount} LBC for downloading some of the things.`,
first_publish: `You earned ${amount} LBC for making your first publication.`,
}[type]; }[type];
} }
@ -17,8 +18,9 @@ const rewards = {};
rewards.TYPE_NEW_DEVELOPER = "new_developer", rewards.TYPE_NEW_DEVELOPER = "new_developer",
rewards.TYPE_NEW_USER = "new_user", rewards.TYPE_NEW_USER = "new_user",
rewards.TYPE_CONFIRM_EMAIL = "confirm_email", rewards.TYPE_CONFIRM_EMAIL = "confirm_email",
rewards.TYPE_FIRST_CHANNEL = "first_channel", rewards.TYPE_FIRST_CHANNEL = "new_channel",
rewards.TYPE_FIRST_PURCHASE = "first_purchase", rewards.TYPE_FIRST_STREAM = "first_stream",
rewards.TYPE_MANY_DOWNLOADS = "many_downloads",
rewards.TYPE_FIRST_PUBLISH = "first_publish"; rewards.TYPE_FIRST_PUBLISH = "first_publish";
rewards.claimReward = function (type) { rewards.claimReward = function (type) {
@ -62,9 +64,13 @@ rewards.claimReward = function (type) {
switch (type) { switch (type) {
case rewards.TYPE_FIRST_CHANNEL: case rewards.TYPE_FIRST_CHANNEL:
lbry.claim_list_mine().then(function(channels) { lbry.claim_list_mine().then(function(claims) {
if (channels.length) { let claim = claims.find(function(claim) {
params.transaction_id = channels[0].txid; return claim.name.length && claim.name[0] == '@' && claim.txid.length
})
console.log(claim);
if (claim) {
params.transaction_id = claim.txid;
requestReward(resolve, reject, params) requestReward(resolve, reject, params)
} else { } else {
reject(new Error("Please create a channel identity first.")) reject(new Error("Please create a channel identity first."))
@ -72,18 +78,24 @@ rewards.claimReward = function (type) {
}).catch(reject) }).catch(reject)
break; break;
case 'first_purchase': case rewards.TYPE_FIRST_PUBLISH:
// lbry.claim_list_mine().then(function(channels) { lbry.claim_list_mine().then((claims) => {
// if (channels.length) { let claim = claims.find(function(claim) {
// requestReward(resolve, reject, {transaction_id: channels[0].txid}) return claim.name.length && claim.name[0] != '@' && claim.txid.length
// } })
// }).catch(reject) if (claim) {
break; params.transaction_id = claim.txid
requestReward(resolve, reject, params)
case 'first_channel': } else {
//params.transaction_id = RelevantTransactionID; reject(claims.length ?
new Error("Please publish something and wait for confirmation by the network to claim this reward.") :
new Error("Please publish something to claim this reward."))
}
}).catch(reject)
break; break;
case rewards.TYPE_FIRST_STREAM:
case rewards.TYPE_NEW_USER:
default: default:
requestReward(resolve, reject, params); requestReward(resolve, reject, params);
} }
@ -91,4 +103,23 @@ rewards.claimReward = function (type) {
}); });
} }
rewards.claimNextPurchaseReward = function() {
let types = {}
types[rewards.TYPE_FIRST_STREAM] = false
types[rewards.TYPE_MANY_DOWNLOADS] = false
lbryio.call('reward', 'list', {}).then((userRewards) => {
userRewards.forEach((reward) => {
if (types[reward.RewardType] === false && reward.TransactionID) {
types[reward.RewardType] = true
}
})
let unclaimedType = Object.keys(types).find((type) => {
return types[type] === false;
})
if (unclaimedType) {
rewards.claimReward(unclaimedType);
}
}, () => { });
}
export default rewards; export default rewards;

View file

@ -28,10 +28,11 @@ $mobile-width-threshold: 801px;
$max-content-width: 1000px; $max-content-width: 1000px;
$max-text-width: 660px; $max-text-width: 660px;
$width-page-constrained: 800px;
$height-header: $spacing-vertical * 2.5; $height-header: $spacing-vertical * 2.5;
$height-button: $spacing-vertical * 1.5; $height-button: $spacing-vertical * 1.5;
$height-video-embedded: $width-page-constrained * 9 / 16;
$width-page-constrained: 800px;
$default-box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); $default-box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
$focus-box-shadow: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12); $focus-box-shadow: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12);

View file

@ -1,6 +1,8 @@
@import "../global"; @import "../global";
$height-file-tile: $spacing-vertical * 8;
.file-tile__row { .file-tile__row {
height: $height-file-tile;
.credit-amount { .credit-amount {
float: right; float: right;
} }
@ -12,12 +14,17 @@
.file-tile__thumbnail { .file-tile__thumbnail {
max-width: 100%; max-width: 100%;
max-height: $spacing-vertical * 7; max-height: $height-file-tile;
vertical-align: middle; vertical-align: middle;
display: block; display: block;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.file-tile__thumbnail-container
{
height: $height-file-tile;
@include absolute-center();
}
.file-tile__title { .file-tile__title {
font-weight: bold; font-weight: bold;

View file

@ -12,17 +12,17 @@ video {
.video-embedded { .video-embedded {
$height-embedded: $width-page-constrained * 9 / 16;
max-width: $width-page-constrained; max-width: $width-page-constrained;
max-height: $height-embedded; max-height: $height-video-embedded;
height: $height-video-embedded;
video { video {
height: 100%; height: 100%;
} }
&.video--hidden { &.video--hidden {
height: $height-embedded; height: $height-video-embedded;
} }
&.video--active { &.video--active {
background: none; /*background: none;*/
} }
} }