Mobile rewards #251
6 changed files with 97 additions and 23 deletions
app
26
app/package-lock.json
generated
26
app/package-lock.json
generated
|
@ -3966,10 +3966,10 @@
|
|||
}
|
||||
},
|
||||
"lbryinc": {
|
||||
"version": "github:lbryio/lbryinc#71fc9220e1a82f35489439b15b3cc375f44e53d7",
|
||||
"from": "github:lbryio/lbryinc#authentication-flow",
|
||||
"version": "github:lbryio/lbryinc#f5d23dc5ee80198bee8e859bb8487c1137f9fbef",
|
||||
"from": "github:lbryio/lbryinc#rewards",
|
||||
"requires": {
|
||||
"lbry-redux": "github:lbryio/lbry-redux#467e48c77b8004cef738e950bdcc67654748ae9f",
|
||||
"lbry-redux": "github:lbryio/lbry-redux#31f7afa8a37f5741dac01fc1ecdf153f3bed95dc",
|
||||
"reselect": "^3.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -5268,6 +5268,13 @@
|
|||
"which-module": "^2.0.0",
|
||||
"y18n": "^3.2.1",
|
||||
"yargs-parser": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6834,9 +6841,9 @@
|
|||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
|
@ -6861,6 +6868,13 @@
|
|||
"which-module": "^2.0.0",
|
||||
"y18n": "^3.2.1",
|
||||
"yargs-parser": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
||||
}
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"dependencies": {
|
||||
"base-64": "^0.1.0",
|
||||
"lbry-redux": "lbryio/lbry-redux",
|
||||
"lbryinc": "lbryio/lbryinc#authentication-flow",
|
||||
"lbryinc": "lbryio/lbryinc#rewards",
|
||||
"moment": "^2.22.1",
|
||||
"react": "16.2.0",
|
||||
"react-native": "0.55.3",
|
||||
|
|
|
@ -1,5 +1,29 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { doNotify } from 'lbry-redux';
|
||||
import {
|
||||
doClaimRewardType,
|
||||
doClaimRewardClearError,
|
||||
makeSelectClaimRewardError,
|
||||
makeSelectIsRewardClaimPending,
|
||||
} from 'lbryinc';
|
||||
import RewardCard from './view';
|
||||
|
||||
export default connect(null, null)(RewardCard);
|
||||
const makeSelect = () => {
|
||||
const selectIsPending = makeSelectIsRewardClaimPending();
|
||||
const selectError = makeSelectClaimRewardError();
|
||||
|
||||
const select = (state, props) => ({
|
||||
errorMessage: selectError(state, props),
|
||||
isPending: selectIsPending(state, props),
|
||||
});
|
||||
|
||||
return select;
|
||||
};
|
||||
|
||||
const perform = dispatch => ({
|
||||
claimReward: reward => dispatch(doClaimRewardType(reward.reward_type, true)),
|
||||
clearError: reward => dispatch(doClaimRewardClearError(reward)),
|
||||
notify: data => dispatch(doNotify(data))
|
||||
});
|
||||
|
||||
export default connect(makeSelect, perform)(RewardCard);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
import { ActivityIndicator, Text, TouchableOpacity, View } from 'react-native';
|
||||
import Colors from '../../styles/colors';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||
import Link from '../link';
|
||||
import rewardStyle from '../../styles/reward';
|
||||
|
@ -20,18 +21,59 @@ type Props = {
|
|||
};
|
||||
|
||||
class RewardCard extends React.PureComponent<Props> {
|
||||
state = {
|
||||
claimStarted: false
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
||||
const { errorMessage, isPending } = nextProps;
|
||||
const { clearError, notify, reward } = this.props;
|
||||
if (this.state.claimStarted && !isPending) {
|
||||
if (errorMessage && errorMessage.trim().length > 0) {
|
||||
notify({ message: errorMessage, displayType: ['toast'] });
|
||||
clearError(reward);
|
||||
} else {
|
||||
notify({ message: 'Reward successfully claimed!', displayType: ['toast'] });
|
||||
}
|
||||
this.setState({ claimStarted: false });
|
||||
}
|
||||
}
|
||||
|
||||
onClaimPress = () => {
|
||||
const {
|
||||
canClaim,
|
||||
claimReward,
|
||||
notify,
|
||||
reward
|
||||
} = this.props;
|
||||
|
||||
if (!canClaim) {
|
||||
notify({ message: 'Unfortunately, you are not eligible to claim this reward at this time.', displayType: ['toast'] });
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ claimStarted: true }, () => {
|
||||
claimReward(reward);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { canClaim, onClaimPress, reward } = this.props;
|
||||
const { canClaim, isPending, onClaimPress, reward } = this.props;
|
||||
const claimed = !!reward.transaction_id;
|
||||
|
||||
return (
|
||||
<View style={[rewardStyle.rewardCard, rewardStyle.row]}>
|
||||
<View style={rewardStyle.leftCol}>
|
||||
<TouchableOpacity onPress={() => { if (!claimed && onClaimPress) { onClaimPress(); } }}>
|
||||
{!isPending && <TouchableOpacity onPress={() => {
|
||||
if (!claimed) {
|
||||
this.onClaimPress();
|
||||
}
|
||||
}}>
|
||||
<Icon name={claimed ? "check-circle" : "circle"}
|
||||
style={claimed ? rewardStyle.claimed : (canClaim ? rewardStyle.unclaimed : rewardStyle.disabled)}
|
||||
size={20} />
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity>}
|
||||
{isPending && <ActivityIndicator size="small" color={Colors.LbryGreen} />}
|
||||
</View>
|
||||
<View style={rewardStyle.midCol}>
|
||||
<Text style={rewardStyle.rewardTitle}>{reward.reward_title}</Text>
|
||||
|
|
|
@ -121,6 +121,9 @@ persistStore(store, persistOptions, err => {
|
|||
}
|
||||
});
|
||||
|
||||
// TODO: Find i18n module that is compatible with react-native
|
||||
global.__ = (str) => str;
|
||||
|
||||
class LBRYApp extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
|
|
|
@ -80,15 +80,6 @@ class RewardsPage extends React.PureComponent {
|
|||
return null;
|
||||
}
|
||||
|
||||
onClaimRewardPress = () => {
|
||||
const { notify, user } = this.props;
|
||||
const isNotEligible = !user || !user.primary_email || !user.has_verified_email || !user.is_reward_approved;
|
||||
if (isNotEligible) {
|
||||
notify({ message: 'Unfortunately, you are not eligible to claim this reward at this time.', displayType: ['toast'] });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
phoneStatePermissionGranted = () => {
|
||||
const { notify } = this.props;
|
||||
if (NativeModules.UtilityModule) {
|
||||
|
@ -143,7 +134,7 @@ class RewardsPage extends React.PureComponent {
|
|||
{rewards.map(reward => <RewardCard key={reward.reward_type}
|
||||
canClaim={!isNotEligible}
|
||||
reward={reward}
|
||||
onClaimPress={this.onClaimRewardPress} />)}
|
||||
reward_type={reward.reward_type} />)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue
https://reactjs.org/docs/react-component.html#updating