Merge pull request #374 from lbryio/custom-reward-codes
Custom reward codes
This commit is contained in:
commit
1560e44d36
7 changed files with 125 additions and 3 deletions
26
app/src/component/customRewardCard/index.js
Normal file
26
app/src/component/customRewardCard/index.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doToast } from 'lbry-redux';
|
||||||
|
import {
|
||||||
|
doClaimRewardType,
|
||||||
|
doClaimRewardClearError,
|
||||||
|
makeSelectClaimRewardError,
|
||||||
|
makeSelectIsRewardClaimPending,
|
||||||
|
rewards as REWARD_TYPES
|
||||||
|
} from 'lbryinc';
|
||||||
|
import CustomRewardCard from './view';
|
||||||
|
|
||||||
|
const select = state => ({
|
||||||
|
rewardIsPending: makeSelectIsRewardClaimPending()(state, {
|
||||||
|
reward_type: REWARD_TYPES.TYPE_REWARD_CODE,
|
||||||
|
}),
|
||||||
|
error: makeSelectClaimRewardError()(state, { reward_type: REWARD_TYPES.TYPE_REWARD_CODE }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
claimReward: reward => dispatch(doClaimRewardType(reward.reward_type, true)),
|
||||||
|
clearError: reward => dispatch(doClaimRewardClearError(reward)),
|
||||||
|
notify: data => dispatch(doToast(data)),
|
||||||
|
submitRewardCode: code => dispatch(doClaimRewardType(REWARD_TYPES.TYPE_REWARD_CODE, { params: { code } }))
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select, perform)(CustomRewardCard);
|
83
app/src/component/customRewardCard/view.js
Normal file
83
app/src/component/customRewardCard/view.js
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import { ActivityIndicator, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||||
|
import Colors from '../../styles/colors';
|
||||||
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
|
import Button from '../button';
|
||||||
|
import Link from '../link';
|
||||||
|
import rewardStyle from '../../styles/reward';
|
||||||
|
|
||||||
|
class CustomRewardCard extends React.PureComponent<Props> {
|
||||||
|
state = {
|
||||||
|
claimStarted: false,
|
||||||
|
rewardCode: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
const { error, rewardIsPending } = nextProps;
|
||||||
|
const { clearError, notify } = this.props;
|
||||||
|
if (this.state.claimStarted && !rewardIsPending) {
|
||||||
|
if (error && error.trim().length > 0) {
|
||||||
|
notify({ message: error });
|
||||||
|
} else {
|
||||||
|
notify({ message: 'Reward successfully claimed!' });
|
||||||
|
this.setState({ rewardCode: '' });
|
||||||
|
}
|
||||||
|
this.setState({ claimStarted: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClaimPress = () => {
|
||||||
|
const { canClaim, notify, submitRewardCode } = this.props;
|
||||||
|
const { rewardCode } = this.state;
|
||||||
|
|
||||||
|
if (!canClaim) {
|
||||||
|
notify({ message: 'Unfortunately, you are not eligible to claim this reward at this time.' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rewardCode || rewardCode.trim().length === 0) {
|
||||||
|
notify({ message: 'Please enter a reward code to claim.' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ claimStarted: true }, () => {
|
||||||
|
submitRewardCode(rewardCode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { canClaim, rewardIsPending } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[rewardStyle.rewardCard, rewardStyle.row]} >
|
||||||
|
<View style={rewardStyle.leftCol}>
|
||||||
|
{rewardIsPending && <ActivityIndicator size="small" color={Colors.LbryGreen} />}
|
||||||
|
</View>
|
||||||
|
<View style={rewardStyle.midCol}>
|
||||||
|
<Text style={rewardStyle.rewardTitle}>Custom Code</Text>
|
||||||
|
<Text style={rewardStyle.rewardDescription}>Are you a supermodel or rockstar that received a custom reward code? Claim it here.</Text>
|
||||||
|
|
||||||
|
<View>
|
||||||
|
<TextInput style={rewardStyle.customCodeInput}
|
||||||
|
placeholder={"0123abc"}
|
||||||
|
onChangeText={text => this.setState({ rewardCode: text })}
|
||||||
|
value={this.state.rewardCode} />
|
||||||
|
<Button style={rewardStyle.redeemButton}
|
||||||
|
text={"Redeem"}
|
||||||
|
disabled={(!this.state.rewardCode || this.state.rewardCode.trim().length === 0 || rewardIsPending)}
|
||||||
|
onPress={() => {
|
||||||
|
if (!rewardIsPending) { this.onClaimPress(); }
|
||||||
|
}} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={rewardStyle.rightCol}>
|
||||||
|
<Text style={rewardStyle.rewardAmount}>?</Text>
|
||||||
|
<Text style={rewardStyle.rewardCurrency}>LBC</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CustomRewardCard;
|
|
@ -9,6 +9,7 @@ import {
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import Colors from '../../styles/colors';
|
import Colors from '../../styles/colors';
|
||||||
import Link from '../../component/link';
|
import Link from '../../component/link';
|
||||||
|
import CustomRewardCard from '../../component/customRewardCard';
|
||||||
import PhoneNumberRewardSubcard from '../../component/phoneNumberRewardSubcard';
|
import PhoneNumberRewardSubcard from '../../component/phoneNumberRewardSubcard';
|
||||||
import EmailRewardSubcard from '../../component/emailRewardSubcard';
|
import EmailRewardSubcard from '../../component/emailRewardSubcard';
|
||||||
import PageHeader from '../../component/pageHeader';
|
import PageHeader from '../../component/pageHeader';
|
||||||
|
@ -122,6 +123,7 @@ class RewardsPage extends React.PureComponent {
|
||||||
canClaim={!isNotEligible}
|
canClaim={!isNotEligible}
|
||||||
reward={reward}
|
reward={reward}
|
||||||
reward_type={reward.reward_type} />)}
|
reward_type={reward.reward_type} />)}
|
||||||
|
<CustomRewardCard canClaim={!isNotEligible} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,6 +202,17 @@ const rewardStyle = StyleSheet.create({
|
||||||
paddingLeft: 4,
|
paddingLeft: 4,
|
||||||
paddingRight: 4,
|
paddingRight: 4,
|
||||||
flex: 0.2
|
flex: 0.2
|
||||||
|
},
|
||||||
|
customCodeInput: {
|
||||||
|
fontFamily: 'Metropolis-Regular',
|
||||||
|
fontSize: 16,
|
||||||
|
letterSpacing: 1.3,
|
||||||
|
marginTop: -8,
|
||||||
|
marginBottom: 4
|
||||||
|
},
|
||||||
|
redeemButton: {
|
||||||
|
alignSelf: 'flex-end',
|
||||||
|
backgroundColor: Colors.LbryGreen
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@997b573aa4223ec6c8c01948cd2df0c6475b5f42#egg=torba, coincurve
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@python36-current-task#egg=torba, coincurve
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@997b573aa4223ec6c8c01948cd2df0c6475b5f42#egg=torba, coincurve
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@python36-current-task#egg=torba, coincurve
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@997b573aa4223ec6c8c01948cd2df0c6475b5f42#egg=torba, coincurve
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, miniupnpc==1.9, gmpy, appdirs==1.4.3, argparse==1.2.1, docopt, base58==1.0.0, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2, pyyaml, qrcode==5.2.2, requests, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, txJSON-RPC, zope.interface==4.3.3, protobuf==3.6.1, keyring==10.4.0, txupnp, git+https://github.com/lbryio/lbryschema.git#egg=lbryschema, git+https://github.com/lbryio/lbry.git#egg=lbrynet, git+https://github.com/lbryio/aioupnp.git#egg=aioupnp, asn1crypto, treq==17.8.0, funcsigs, mock, pbr, pyopenssl, twisted, idna, Automat, hyperlink, PyHamcrest, netifaces, cryptography, aiohttp, aiorpcX==0.9.0, asyncio, git+https://github.com/lbryio/torba@python36-current-task#egg=torba, coincurve
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
|
Loading…
Reference in a new issue