implement send tip functionality #366

Merged
akinwale merged 2 commits from tips into master 2018-11-28 15:44:08 +01:00
4 changed files with 124 additions and 24 deletions

View file

@ -8,15 +8,15 @@ import {
} from 'lbry-redux';
import WalletSend from './view';
const perform = dispatch => ({
sendToAddress: (address, amount) => dispatch(doSendDraftTransaction(address, amount)),
notify: (data) => dispatch(doToast(data))
});
const select = state => ({
balance: selectBalance(state),
draftTransaction: selectDraftTransaction(state),
transactionError: selectDraftTransactionError(state),
});
const perform = dispatch => ({
sendToAddress: (address, amount) => dispatch(doSendDraftTransaction(address, amount)),
notify: (data) => dispatch(doToast(data))
});
export default connect(select, perform)(WalletSend);

View file

@ -3,6 +3,7 @@ import {
doFetchFileInfo,
doFetchCostInfoForUri,
doResolveUri,
doSendTip,
doToast,
makeSelectIsUriResolving,
makeSelectCostInfoForUri,
@ -10,6 +11,7 @@ import {
makeSelectClaimForUri,
makeSelectContentTypeForUri,
makeSelectMetadataForUri,
selectBalance,
selectBlackListedOutpoints,
} from 'lbry-redux';
import { selectRewardContentClaimIds } from 'lbryinc';
@ -19,6 +21,7 @@ import FilePage from './view';
const select = (state, props) => {
const selectProps = { uri: props.navigation.state.params.uri };
return {
balance: selectBalance(state),
blackListedOutpoints: selectBlackListedOutpoints(state),
claim: makeSelectClaimForUri(selectProps.uri)(state),
isResolvingUri: makeSelectIsUriResolving(selectProps.uri)(state),
@ -40,6 +43,7 @@ const perform = dispatch => ({
fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)),
notify: data => dispatch(doToast(data)),
resolveUri: uri => dispatch(doResolveUri(uri)),
sendTip: (amount, claimId, uri, successCallback, errorCallback) => dispatch(doSendTip(amount, claimId, uri, successCallback, errorCallback)),
stopDownload: (uri, fileInfo) => dispatch(doStopDownloadingFile(uri, fileInfo)),
});

View file

@ -37,6 +37,8 @@ class FilePage extends React.PureComponent {
title: ''
};
tipAmountInput = null;
playerBackground = null;
startTime = null;
@ -55,8 +57,10 @@ class FilePage extends React.PureComponent {
pageSuspended: false,
showImageViewer: false,
showWebView: false,
showTipView: false,
playerBgHeight: 0,
playerHeight: 0,
tipAmount: null,
uri: null,
stopDownloadConfirmed: false
};
@ -310,6 +314,21 @@ class FilePage extends React.PureComponent {
this.setState({ fileViewLogged: true });
}
handleSendTip = () => {
const { claim, balance, navigation, notify, sendTip } = this.props;
const { uri } = navigation.state.params;
const { tipAmount } = this.state;
if (tipAmount > balance) {
notify({
message: 'Insufficient credits',
});
return;
}
sendTip(tipAmount, claim.claim_id, uri, () => { this.setState({ tipAmount: 0, showTipView: false }) });
}
render() {
const {
claim,
@ -378,12 +397,12 @@ class FilePage extends React.PureComponent {
const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio';
const { height, channel_name: channelName, value } = claim;
const showActions = !this.state.fullscreenMode &&
!this.state.showImageViewer &&
!this.state.showWebView &&
(completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
const showActions = !this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView;
const showFileActions = (completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
const channelClaimId =
value && value.publisherSignature && value.publisherSignature.certificateId;
const canSendTip = this.state.tipAmount > 0;
const playerStyle = [filePageStyle.player,
this.state.isLandscape ? filePageStyle.containedPlayerLandscape :
@ -473,8 +492,15 @@ class FilePage extends React.PureComponent {
onPlaybackStarted={this.onPlaybackStarted}
/>}
{fileInfo && showActions &&
{showActions &&
<View style={filePageStyle.actions}>
{<Button style={filePageStyle.actionButton}
theme={"light"}
icon={"gift"}
text={"Send a tip"}
onPress={() => this.setState({ showTipView: true })} />}
{showFileActions &&
<View style={filePageStyle.fileActions}>
{completed && <Button style={filePageStyle.actionButton}
theme={"light"}
icon={"trash"}
@ -489,6 +515,7 @@ class FilePage extends React.PureComponent {
onPress={this.onStopDownloadPressed} />
}
</View>}
</View>}
<ScrollView
style={showActions ? filePageStyle.scrollContainerActions : filePageStyle.scrollContainer}
contentContainerstyle={showActions ? null : filePageStyle.scrollContent}>
@ -507,6 +534,23 @@ class FilePage extends React.PureComponent {
<RelatedContent navigation={navigation} uri={uri} />
</ScrollView>
{this.state.showTipView && <View style={filePageStyle.tipCard}>
<View style={filePageStyle.row}>
<View style={filePageStyle.amountRow}>
<TextInput ref={ref => this.tipAmountInput = ref}
onChangeText={value => this.setState({tipAmount: value})}
keyboardType={'numeric'}
value={this.state.tipAmount}
style={[filePageStyle.input, filePageStyle.tipAmountInput]} />
<Text style={[filePageStyle.text, filePageStyle.currency]}>LBC</Text>
</View>
<Link style={[filePageStyle.link, filePageStyle.cancelTipLink]} text={'Cancel'} onPress={() => this.setState({ showTipView: false })} />
<Button text={'Send tip'}
style={[filePageStyle.button, filePageStyle.sendButton]}
disabled={!canSendTip}
onPress={this.handleSendTip} />
</View>
</View>}
</View>
)}
{!this.state.fullscreenMode && <FloatingWalletBalance navigation={navigation} />}

View file

@ -142,6 +142,8 @@ const filePageStyle = StyleSheet.create({
color: '#0c604b'
},
actions: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 16,
paddingRight: 16,
paddingTop: 16,
@ -149,6 +151,9 @@ const filePageStyle = StyleSheet.create({
marginTop: -14,
width: '100%',
},
fileActions: {
alignSelf: 'flex-end'
},
actionButton: {
alignSelf: 'flex-start',
backgroundColor: Colors.White,
@ -200,10 +205,57 @@ const filePageStyle = StyleSheet.create({
zIndex: 100
},
link: {
color: Colors.LbryGreen
color: Colors.Grey
},
linkTapped: {
color: "rgba(64, 184, 154, .2)"
},
tipCard: {
backgroundColor: Colors.White,
position: 'absolute',
top: containedMediaHeightWithControls - 16,
width: '100%',
paddingTop: 8,
paddingBottom: 8,
paddingLeft: 16,
paddingRight: 16
},
row: {
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between'
},
amountRow: {
flexDirection: 'row',
flex: 0.75
},
button: {
backgroundColor: Colors.LbryGreen,
alignSelf: 'flex-end',
marginBottom: 6
},
cancelTipLink: {
alignSelf: 'flex-end',
marginBottom: 14
},
input: {
fontFamily: 'Metropolis-Regular',
fontSize: 14
},
tipAmountInput: {
alignSelf: 'flex-start',
width: 80,
fontSize: 16,
letterSpacing: 1
},
currency: {
alignSelf: 'flex-start',
marginTop: 17
},
text: {
fontFamily: 'Metropolis-Regular',
fontSize: 16,
lineHeight: 24
}
});