diff --git a/ui/js/component/auth.js b/ui/js/component/auth.js index aa3937e63..a42d3cc06 100644 --- a/ui/js/component/auth.js +++ b/ui/js/component/auth.js @@ -104,21 +104,45 @@ const ConfirmEmailStage = React.createClass({ }); const WelcomeStage = React.createClass({ + propTypes: { + endAuth: React.PropTypes.func, + }, + getInitialState: function() { + return { + hasReward: false, + rewardAmount: null, + } + }, + onRewardClaim: function(reward) { + this.setState({ + hasReward: true, + rewardAmount: reward + }) + }, render: function() { - //

Thank you return ( -

-

Welcome to LBRY.

-

LBRY is kind of like a centaur. Totally normal up top, and way different underneath.

-

On the upper level, LBRY is like other popular video and media sites.

-

Below, LBRY is like nothing else. Through blockchain and decentralization, LBRY is controlled by it's users -- that is, you.

-

Here is a reward for reading our weird centaur metaphor:

-
- -
-

This reward earned you LBC. LBC is used to watch stuff and to have say in how the network works.

-

But no need to understand it all just yet! Try watching something next.

-
+ !this.state.hasReward ? + +
+

Welcome to LBRY.

+

LBRY is kind of like a centaur. Totally normal up top, and way different underneath.

+

On the upper level, LBRY is like other popular video and media sites.

+

Below, LBRY is like nothing else. Using blockchain and decentralization, LBRY is controlled by its users -- that is, you -- and no one else.

+

Thanks for being a part of it! Here's a nickel, kid.

+
+ +
+
+
: + +
+

About Your Reward

+

You earned a reward of 5 LBRY credits, or LBC.

+

This reward will show in your Wallet momentarily, likely while you are reading this message.

+

LBC is used to compensate creators, to publish, and to have say in how the network works.

+

No need to understand it all just yet! Try watching or downloading something next.

+
+
); } }); @@ -152,12 +176,11 @@ export const AuthOverlay = React.createClass({ error: ErrorStage, email: SubmitEmailStage, confirm: ConfirmEmailStage, - welcome: WelcomeStage, + welcome: WelcomeStage }, - getInitialState: function() { return { - stage: null, + stage: "pending", stageProps: {} }; }, @@ -183,7 +206,13 @@ export const AuthOverlay = React.createClass({ } }) } else { - this.endAuth() + lbryio.call('reward', 'list', {}).then(function(userRewards) { + userRewards.filter(function(reward) { + return reward.RewardType == "new_user" && reward.TransactionID; + }).length ? + this.endAuth() : + this.setState({ stage: "welcome" }) + }.bind(this)); } }.bind(this)).catch((err) => { this.setState({ @@ -199,21 +228,17 @@ export const AuthOverlay = React.createClass({ }) }, render: function() { - if (!this.state.stage || lbryio.user && lbryio.user.HasVerifiedEmail) { - if (this.state.stage != "welcome") { + if (!this.state.stage) { return null; - } } const StageContent = this._stages[this.state.stage]; return ( this.state.stage != "welcome" ? - +

LBRY Early Access

: - - - + ); } }); \ No newline at end of file diff --git a/ui/js/component/link.js b/ui/js/component/link.js index 8bcaddd48..88e60bf7e 100644 --- a/ui/js/component/link.js +++ b/ui/js/component/link.js @@ -60,7 +60,8 @@ export let RewardLink = React.createClass({ propTypes: { type: React.PropTypes.string.isRequired, claimed: React.PropTypes.bool, - onRewardClaim: React.PropTypes.func + onRewardClaim: React.PropTypes.func, + onRewardFailure: React.PropTypes.func }, refreshClaimable: function() { switch(this.props.type) { @@ -92,7 +93,6 @@ export let RewardLink = React.createClass({ pending: true }) rewards.claimReward(this.props.type).then(function(reward) { - console.log(reward); this.setState({ pending: false, errorMessage: null @@ -108,6 +108,9 @@ export let RewardLink = React.createClass({ }.bind(this)) }, clearError: function() { + if (this.props.onRewardFailure) { + this.props.onRewardFailure() + } this.setState({ errorMessage: null }) @@ -117,7 +120,7 @@ export let RewardLink = React.createClass({
{this.props.claimed ? Reward claimed. - : } + : } {this.state.errorMessage ? {this.state.errorMessage} diff --git a/ui/js/component/modal-page.js b/ui/js/component/modal-page.js index d0def4b82..12826a81e 100644 --- a/ui/js/component/modal-page.js +++ b/ui/js/component/modal-page.js @@ -6,7 +6,7 @@ export const ModalPage = React.createClass({ return ( + overlayClassName="modal-overlay">
{this.props.children}
diff --git a/ui/js/component/modal.js b/ui/js/component/modal.js index bd534ecea..dbb8ff646 100644 --- a/ui/js/component/modal.js +++ b/ui/js/component/modal.js @@ -6,6 +6,7 @@ import {Link} from './link.js'; export const Modal = React.createClass({ propTypes: { type: React.PropTypes.oneOf(['alert', 'confirm', 'custom']), + overlay: React.PropTypes.bool, onConfirmed: React.PropTypes.func, onAborted: React.PropTypes.func, confirmButtonLabel: React.PropTypes.string, @@ -16,6 +17,7 @@ export const Modal = React.createClass({ getDefaultProps: function() { return { type: 'alert', + overlay: true, confirmButtonLabel: 'OK', abortButtonLabel: 'Cancel', confirmButtonDisabled: false, @@ -26,7 +28,7 @@ export const Modal = React.createClass({ return ( + overlayClassName={[null, undefined, ""].indexOf(this.props.overlayClassName) === -1 ? this.props.overlayClassName : 'modal-overlay'}>
{this.props.children}
diff --git a/ui/js/component/snack-bar.js b/ui/js/component/snack-bar.js index e1ddb01b0..a993c3b75 100644 --- a/ui/js/component/snack-bar.js +++ b/ui/js/component/snack-bar.js @@ -13,7 +13,6 @@ export const SnackBar = React.createClass({ } }, handleSnackReceived: function(event) { - // console.log(event); // if (this._hideTimeout) { // clearTimeout(this._hideTimeout); // } diff --git a/ui/js/lbry.js b/ui/js/lbry.js index 51abc311b..0360453b7 100644 --- a/ui/js/lbry.js +++ b/ui/js/lbry.js @@ -204,13 +204,6 @@ lbry.resolveName = function(name, callback) { }); } -lbry.getStream = function(name, callback) { - if (!name) { - throw new Error(`Name required.`); - } - lbry.call('get', { 'name': name }, callback); -}; - lbry.getClaimInfo = function(name, callback) { if (!name) { throw new Error(`Name required.`); @@ -654,6 +647,14 @@ lbry.claim_list_mine = function(params={}) { }); } +// lbry.get = function(params={}) { +// return function(params={}) { +// return new Promise((resolve, reject) => { +// jsonrpc.call(lbry.daemonConnectionString, "get", [params], resolve, reject, reject); +// }); +// }; +// } + lbry = new Proxy(lbry, { get: function(target, name) { if (name in target) { diff --git a/ui/js/page/publish.js b/ui/js/page/publish.js index f00a30370..2709f3a8e 100644 --- a/ui/js/page/publish.js +++ b/ui/js/page/publish.js @@ -3,11 +3,25 @@ import lbry from '../lbry.js'; import uri from '../uri.js'; import {FormField, FormRow} from '../component/form.js'; import {Link} from '../component/link.js'; +import rewards from '../rewards.js'; import Modal from '../component/modal.js'; var PublishPage = React.createClass({ _requiredFields: ['meta_title', 'name', 'bid'], + _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) { // 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) @@ -334,6 +348,7 @@ var PublishPage = React.createClass({ }, componentWillMount: function() { this._updateChannelList(); + this._requestPublishReward(); }, componentDidMount: function() { document.title = "Publish"; diff --git a/ui/js/page/settings.js b/ui/js/page/settings.js index 318711d8b..d05be08fe 100644 --- a/ui/js/page/settings.js +++ b/ui/js/page/settings.js @@ -78,20 +78,21 @@ var SettingsPage = React.createClass({ if (!this.state.daemonSettings) { return null; } - +/* +
+
+

Run on Startup

+
+
+ +
+
+ */ return (
-
-
-

Run on Startup

-
-
- -
-

Download Directory

diff --git a/ui/js/rewards.js b/ui/js/rewards.js index 29f43058c..a42ed1637 100644 --- a/ui/js/rewards.js +++ b/ui/js/rewards.js @@ -3,23 +3,44 @@ import lbryio from './lbryio.js'; function rewardMessage(type, amount) { return { - new_developer: "Your reward has been confirmed for registering as a new developer.", + new_developer: "You received ${amount} for registering as a new developer.", new_user: `You received ${amount} LBC new user reward.`, - confirm_email: "Your reward has been confirmed for verifying your email address.", - first_publish: "Your reward has been confirmed for making your first publication.", + confirm_email: "You received ${amount} LBC for verifying your email address.", + first_channel: "You received ${amount} LBC for creating a publisher identity.", + first_purchase: "You received ${amount} LBC for making your first purchase.", + first_publish: "You received ${amount} LBC for making your first publication.", }[type]; } const rewards = {}; -rewards.claimReward = function(type) { +rewards.TYPE_NEW_DEVELOPER = "new_developer", + rewards.TYPE_NEW_USER = "new_user", + rewards.TYPE_CONFIRM_EMAIL = "confirm_email", + rewards.TYPE_FIRST_CHANNEL = "first_channel", + rewards.TYPE_FIRST_PURCHASE = "first_purchase", + rewards.TYPE_FIRST_PUBLISH = "first_publish"; + +rewards.claimReward = function (type) { return new Promise((resolve, reject) => { - console.log('top of promise body') lbry.get_new_address().then((address) => { const params = { reward_type: type, wallet_address: address, }; + switch (type) { + case 'first_channel': + //params.transaction_id = RelevantTransactionID; + break; + + case 'first_purchase': + //params.transaction_id = RelevantTransactionID; + break; + + case 'first_channel': + //params.transaction_id = RelevantTransactionID; + break; + } lbryio.call('reward', 'new', params, 'post').then(({RewardAmount}) => { const message = rewardMessage(type, RewardAmount), diff --git a/ui/scss/_gui.scss b/ui/scss/_gui.scss index 15246c7f6..da32d3ac5 100644 --- a/ui/scss/_gui.scss +++ b/ui/scss/_gui.scss @@ -147,79 +147,3 @@ p font-size: 0.85em; color: $color-help; } - -.modal-overlay { - position: fixed; - display: flex; - justify-content: center; - align-items: center; - - top: 0px; - left: 0px; - right: 0px; - bottom: 0px; - background-color: rgba(255, 255, 255, 0.74902); - z-index: 9999; -} - -.modal { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - border: 1px solid rgb(204, 204, 204); - background: rgb(255, 255, 255); - overflow: auto; - border-radius: 4px; - padding: $spacing-vertical; - box-shadow: $default-box-shadow; - max-width: 400px; -} - -.modal__header { - margin-bottom: 5px; - text-align: center; -} - -.modal__buttons { - display: flex; - flex-direction: row; - justify-content: center; - margin-top: 15px; -} - -.modal__button { - margin: 0px 6px; -} - -.error-modal-overlay { - background: rgba(#000, .88); -} - -.error-modal__content { - display: flex; - padding: 0px 8px 10px 10px; -} - -.error-modal__warning-symbol { - margin-top: 6px; - margin-right: 7px; -} - -.download-started-modal__file-path { - word-break: break-all; -} - -.error-modal { - max-width: none; - width: 400px; -} -.error-modal__error-list { /*shitty hack/temp fix for long errors making modals unusable*/ - border: 1px solid #eee; - padding: 8px; - list-style: none; - max-height: 400px; - max-width: 400px; - overflow-y: hidden; -} diff --git a/ui/scss/all.scss b/ui/scss/all.scss index 18a9ec720..dcb81cb98 100644 --- a/ui/scss/all.scss +++ b/ui/scss/all.scss @@ -15,6 +15,7 @@ @import "component/_load-screen.scss"; @import "component/_channel-indicator.scss"; @import "component/_notice.scss"; +@import "component/_modal.scss"; @import "component/_modal-page.scss"; @import "component/_snack-bar.scss"; @import "page/_developer.scss"; diff --git a/ui/scss/component/_modal-page.scss b/ui/scss/component/_modal-page.scss index 2b86c5cad..d9bd0d8d5 100644 --- a/ui/scss/component/_modal-page.scss +++ b/ui/scss/component/_modal-page.scss @@ -1,16 +1,4 @@ -.modal-page-overlay { - position: fixed; - display: flex; - justify-content: center; - align-items: center; - - top: 0px; - left: 0px; - right: 0px; - bottom: 0px; - background-color: rgba(255, 255, 255, 0.74902); - z-index: 9999; -} +@import "../global"; .modal-page { position: fixed; diff --git a/ui/scss/component/_modal.scss b/ui/scss/component/_modal.scss new file mode 100644 index 000000000..13284c7ff --- /dev/null +++ b/ui/scss/component/_modal.scss @@ -0,0 +1,81 @@ +@import "../global"; + +.modal-overlay { + position: fixed; + display: flex; + justify-content: center; + align-items: center; + + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + background-color: rgba(255, 255, 255, 0.74902); + z-index: 9999; +} + +.modal-overlay--clear { + background-color: transparent; +} + +.modal { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + border: 1px solid rgb(204, 204, 204); + background: rgb(255, 255, 255); + overflow: auto; + border-radius: 4px; + padding: $spacing-vertical; + box-shadow: $default-box-shadow; + max-width: 400px; +} + +.modal__header { + margin-bottom: 5px; + text-align: center; +} + +.modal__buttons { + display: flex; + flex-direction: row; + justify-content: center; + margin-top: 15px; +} + +.modal__button { + margin: 0px 6px; +} + +.error-modal-overlay { + background: rgba(#000, .88); +} + +.error-modal__content { + display: flex; + padding: 0px 8px 10px 10px; +} + +.error-modal__warning-symbol { + margin-top: 6px; + margin-right: 7px; +} + +.download-started-modal__file-path { + word-break: break-all; +} + +.error-modal { + max-width: none; + width: 400px; +} +.error-modal__error-list { /*shitty hack/temp fix for long errors making modals unusable*/ + border: 1px solid #eee; + padding: 8px; + list-style: none; + max-height: 400px; + max-width: 400px; + overflow-y: hidden; +} \ No newline at end of file