Merge branch 'master' into pin-code

This commit is contained in:
Feruz M 2018-10-30 21:06:05 +05:30 committed by GitHub
commit 43b85a942a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 372 additions and 258 deletions

10
package-lock.json generated
View File

@ -9918,13 +9918,13 @@
}
},
"react-native-modal-popover": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/react-native-modal-popover/-/react-native-modal-popover-0.0.10.tgz",
"integrity": "sha512-Ae7TnF9XDp19clwffRoD7qM/SfdkXdrEFpSbBEtGgZdnrqqI9kyIf626VtburNm9HAMidsvuXG4oxf/BISgy9w==",
"version": "0.0.12",
"resolved": "https://registry.npmjs.org/react-native-modal-popover/-/react-native-modal-popover-0.0.12.tgz",
"integrity": "sha512-uZQsTDcGOI8y/05L/Lb0OMBesJYYRWEc0pj2038a579LnDnJJpKay0kD654cQpA4Ozt3xbu4DMTGwenynBSEFg==",
"requires": {
"@types/prop-types": "^15.5.2",
"@types/prop-types": "^15.5.5",
"lodash.debounce": "^4.0.8",
"prop-types": "^15.6.0"
"prop-types": "^15.6.2"
}
},
"react-native-restart": {

View File

@ -38,7 +38,7 @@
"react-native-markdown-view": "^1.1.4",
"react-native-modal": "^6.5.0",
"react-native-modal-dropdown": "^0.6.2",
"react-native-modal-popover": "0.0.10",
"react-native-modal-popover": "0.0.12",
"react-native-restart": "0.0.6",
"react-native-slider": "^0.11.0",
"react-native-vector-icons": "^4.6.0",

View File

@ -37,7 +37,7 @@ class HeaderContainer extends Component {
_handleOnPressBackButton = () => {
const { navigation } = this.props;
navigation.navigate('HomeScreen');
navigation.goBack();
};
render() {

View File

@ -177,8 +177,9 @@ export default EStyleSheet.create({
shadowColor: 'white',
paddingLeft: 5,
borderRadius: 5,
fontSize: 7,
fontSize: 10,
fontWeight: '100',
fontFamily: '$primaryFont',
color: '#777777',
},
popover: {

View File

@ -1,19 +1,14 @@
import React, { Component } from 'react';
import {
Image, TouchableOpacity, FlatList, ActivityIndicator,
Image, TouchableOpacity, FlatList,
} from 'react-native';
import {
Card, CardItem, Left, Right, Thumbnail, View, Icon, Body, Text,
} from 'native-base';
import Modal from 'react-native-modal';
import { Popover, PopoverController } from 'react-native-modal-popover';
import Slider from 'react-native-slider';
// STEEM
import { upvote, upvoteAmount } from '../../../providers/steem/dsteem';
import { decryptKey } from '../../../utils/crypto';
import { getUserData } from '../../../realm/realm';
import { Upvote } from '../../upvote';
// Styles
import styles from './postCardStyles';
@ -26,88 +21,15 @@ class PostCard extends Component {
*/
constructor(props) {
super(props);
this.upvoteContent = this.upvoteContent.bind(this);
this.calculateEstimatedAmount = this.calculateEstimatedAmount.bind(this);
this.state = {
value: 0.0,
isVoting: false,
isVoted: props.content && props.content.isVoted,
amount: '0.00',
isModalVisible: false,
};
}
// Component Lifecycle Functions
componentDidMount() {
const { isLoggedIn } = this.props;
isLoggedIn && this.calculateEstimatedAmount();
}
// Component Functions
calculateEstimatedAmount = async () => {
const { user } = this.props;
const { value } = this.state;
// Calculate total vesting shares
const total_vests = parseFloat(user.vesting_shares)
+ parseFloat(user.received_vesting_shares)
- parseFloat(user.delegated_vesting_shares);
const final_vest = total_vests * 1e6;
const power = (user.voting_power * (value * 10000)) / 10000 / 50;
const rshares = (power * final_vest) / 10000;
const estimated = await upvoteAmount(rshares);
this.setState({
amount: estimated.toFixed(3),
});
};
upvoteContent = async () => {
const { isLoggedIn, user, content } = this.prop;
const { value } = this.state;
let postingKey;
let userData;
if (isLoggedIn) {
await this.setState({
isVoting: true,
});
await getUserData().then((result) => {
userData = Array.from(result);
postingKey = decryptKey(userData[0].postingKey, 'pinCode');
});
upvote(
{
voter: user && user.name,
author: content && content.author,
permlink: content && content.permlink,
weight: (value * 100).toFixed(0) * 100,
},
postingKey,
)
.then((res) => {
console.log(res);
this.setState({
isVoted: true,
isVoting: false,
});
})
.catch((err) => {
console.log(err);
this.setState({
isVoted: false,
isVoting: false,
});
});
}
};
toggleModal = () => {
const { isModalVisible } = this.state;
@ -127,25 +49,25 @@ class PostCard extends Component {
render() {
const {
content, isLoggedIn, user, handleOnUserPress,
content, isLoggedIn, user,
} = this.props;
const {
isVoted, isVoting, isModalVisible, value,
} = this.state;
const { isModalVisible } = this.state;
// TODO: Should seperate bunch of component REFACTOR ME!
return (
<Card style={styles.post}>
<CardItem style={styles.header}>
<Left>
<TouchableOpacity
onPress={() => this._handleOnUserPress()}
>
<TouchableOpacity onPress={() => this._handleOnUserPress()}>
<Thumbnail style={styles.avatar} source={{ uri: content && content.avatar }} />
</TouchableOpacity>
<Body style={styles.body}>
<View style={styles.author}>
<Text style={styles.authorName}>{content.author}</Text>
<TouchableOpacity
onPress={() => this._handleOnUserPress()}
>
<Text style={styles.authorName}>{content.author}</Text>
</TouchableOpacity>
</View>
<View style={styles.badge}>
<Text style={styles.text}>{content.author_reputation}</Text>
@ -154,9 +76,7 @@ class PostCard extends Component {
<Text style={styles.categoryText}>{content.category}</Text>
</View>
<Text style={styles.timeAgo} note>
{' '}
{content.created}
{' '}
</Text>
</Body>
</Left>
@ -179,107 +99,7 @@ class PostCard extends Component {
</TouchableOpacity>
<CardItem>
<Left>
<PopoverController>
{({
openPopover,
closePopover,
popoverVisible,
setPopoverAnchor,
popoverAnchorRect,
}) => (
<React.Fragment>
<TouchableOpacity
start
ref={setPopoverAnchor}
onPress={openPopover}
style={styles.upvoteButton}
>
{isVoting ? (
<ActivityIndicator />
) : (
<View>
{isVoted ? (
<Icon
style={{
color: '#007ee5',
}}
style={styles.upvoteIcon}
active
name="ios-arrow-dropup-circle"
/>
) : (
<Icon
style={{
color: '#007ee5',
}}
style={styles.upvoteIcon}
active
name="ios-arrow-dropup-outline"
/>
)}
</View>
)}
</TouchableOpacity>
<Popover
contentStyle={styles.popover}
arrowStyle={styles.arrow}
backgroundStyle={styles.background}
visible={popoverVisible}
onClose={closePopover}
fromRect={popoverAnchorRect}
placement="top"
supportedOrientations={['portrait', 'landscape']}
>
<Text>
$
{this.state.amount}
</Text>
<View
style={{
flex: 1,
flexDirection: 'row',
}}
>
<TouchableOpacity
onPress={() => {
closePopover();
this.upvoteContent();
}}
style={{
flex: 0.1,
alignSelf: 'center',
}}
>
<Icon style={{ color: '#007ee5' }} active name="ios-arrow-dropup-outline" />
</TouchableOpacity>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={styles.track}
thumbStyle={styles.thumb}
thumbTintColor="#007ee5"
value={value}
onValueChange={(value) => {
this.setState({ value }, () => {
this.calculateEstimatedAmount();
});
}}
/>
<Text
style={{
flex: 0.15,
alignSelf: 'center',
marginLeft: 10,
}}
>
{(value * 100).toFixed(0)}
%
</Text>
</View>
</Popover>
</React.Fragment>
)}
</PopoverController>
<Upvote content={content} user={user} isLoggedIn={!!user} />
<TouchableOpacity onPress={this.toggleModal} style={styles.payoutButton}>
<Text style={styles.payout}>
$
@ -298,7 +118,7 @@ $
<Text>Tap to close!</Text>
</TouchableOpacity>
<FlatList
data={this.props.content.active_votes}
data={content.active_votes}
keyExtractor={item => item.voter.toString()}
renderItem={({ item }) => (
<View
@ -321,9 +141,7 @@ $
}}
/>
<Text style={{ flex: 0.5 }}>
{' '}
{item.voter}
{' '}
(
{item.reputation}
)

View File

@ -5,6 +5,10 @@ export default EStyleSheet.create({
justifyContent: 'center',
flexDirection: 'row',
},
textWithIconWrapperColumn: {
justifyContent: 'center',
flexDirection: 'column',
},
longImage: {
borderRadius: 5,
height: 60,

View File

@ -0,0 +1,40 @@
import React, { Component } from 'react';
// import { connect } from 'react-redux';
// Services and Actions
// Middleware
// Constants
// Utilities
// Component
import { UpvoteView } from '..';
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class UpvoteContainer extends Component {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycle Functions
// Component Functions
render() {
return <UpvoteView {...this.props} />;
}
}
// const mapStateToProps = state => ({
// user: state.user.user,
// });
export default UpvoteContainer;

View File

@ -0,0 +1,5 @@
import UpvoteView from './view/upvoteView';
import Upvote from './container/upvoteContainer';
export { UpvoteView, Upvote };
export default Upvote;

View File

@ -0,0 +1,60 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
upvoteButton: {
flexDirection: 'row',
alignSelf: 'center',
},
upvoteIcon: {
alignSelf: 'flex-start',
fontSize: 22,
color: '$primaryBlue',
},
popover: {
flexDirection: 'row',
width: '$deviceWidth - 20',
height: 48,
borderRadius: '$deviceWidth - 20 / 2',
paddingHorizontal: 16,
backgroundColor: '$white',
},
track: {
height: 2,
borderRadius: 1,
},
thumb: {
width: 16,
height: 16,
borderRadius: 16 / 2,
backgroundColor: '$white',
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
},
amount: {
fontSize: 10,
color: '$primaryDarkGray',
marginLeft: 8,
},
percent: {
width: 40,
color: '$primaryDarkGray',
},
slider: {
flex: 1,
marginHorizontal: 10,
},
popoverWrapper: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
arrow: {
borderTopColor: 'transparent',
},
overlay: {
backgroundColor: '#403c4449',
},
});

View File

@ -0,0 +1,190 @@
import React, { Component, Fragment } from 'react';
import {
View, TouchableOpacity, ActivityIndicator, Text,
} from 'react-native';
import { Popover, PopoverController } from 'react-native-modal-popover';
import Slider from 'react-native-slider';
// Constants
// Components
import { Icon } from '../../icon';
// STEEM
import { upvote, upvoteAmount } from '../../../providers/steem/dsteem';
import { decryptKey } from '../../../utils/crypto';
import { getUserData } from '../../../realm/realm';
// Styles
import styles from './upvoteStyles';
class UpvoteView extends Component {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
this.state = {
value: 0.0,
isVoting: false,
isVoted: props.content ? props.content.is_voted : false,
amount: '0.00',
isModalVisible: false,
};
}
// Component Life Cycles
// Component Functions
_calculateEstimatedAmount = async () => {
const { user } = this.props;
// Calculate total vesting shares
if (user) {
const { value } = this.state;
const totalVests = parseFloat(user.vesting_shares)
+ parseFloat(user.received_vesting_shares)
- parseFloat(user.delegated_vesting_shares);
const finalVest = totalVests * 1e6;
const power = (user.voting_power * (value * 10000)) / 10000 / 50;
const rshares = (power * finalVest) / 10000;
const estimated = await upvoteAmount(rshares);
this.setState({
amount: estimated.toFixed(3),
});
}
};
_upvoteContent = async () => {
const { user, content } = this.props;
const { value } = this.state;
let postingKey;
let userData;
this.setState({
isVoting: true,
});
await getUserData().then((result) => {
userData = Array.from(result);
postingKey = decryptKey(userData[0].postingKey, '1234');
});
upvote(
{
voter: user && user.name,
author: content && content.author,
permlink: content && content.permlink,
weight: value ? (value * 100).toFixed(0) * 100 : 0,
},
postingKey,
)
.then((res) => {
this.setState({
isVoted: !!value,
isVoting: false,
});
alert(!!value ? "Upvoted" : "Downvoted");
})
.catch((err) => {
alert(err);
this.setState({
isVoted: false,
isVoting: false,
});
});
};
render() {
const { isLoggedIn } = this.props;
const {
isVoting, isModalVisible, amount, value, isVoted,
} = this.state;
const _percent = `${(value * 100).toFixed(0)}%`;
const _amount = `$${amount}`;
return (
<PopoverController>
{({
openPopover, closePopover, popoverVisible, setPopoverAnchor, popoverAnchorRect,
}) => (
<Fragment>
<TouchableOpacity
start
ref={setPopoverAnchor}
onPress={openPopover}
style={styles.upvoteButton}
disabled={!isLoggedIn}
>
{isVoting ? (
<ActivityIndicator />
) : (
<Icon
style={[styles.upvoteIcon, { color: '#007ee5' }]}
active={!isLoggedIn}
name={isVoted ? 'ios-arrow-dropup-circle' : 'ios-arrow-dropup-outline'}
/>
)}
</TouchableOpacity>
<Popover
contentStyle={styles.popover}
arrowStyle={styles.arrow}
backgroundStyle={styles.overlay}
visible={popoverVisible}
onClose={closePopover}
fromRect={popoverAnchorRect}
placement="top"
supportedOrientations={['portrait', 'landscape']}
>
<View style={styles.popoverWrapper}>
<TouchableOpacity
onPress={() => {
// closePopover();
this._upvoteContent();
}}
style={styles.upvoteButton}
>
{isVoting ? (
<ActivityIndicator />
) : (
<Icon
size={20}
style={[styles.upvoteIcon, { color: '#007ee5' }]}
active={!isLoggedIn}
name={isVoted ? 'ios-arrow-dropup-circle' : 'ios-arrow-dropup-outline'}
/>
)}
</TouchableOpacity>
<Text style={styles.amount}>{_amount}</Text>
<Slider
style={styles.slider}
minimumTrackTintColor="#357ce6"
trackStyle={styles.track}
thumbStyle={styles.thumb}
thumbTintColor="#007ee5"
value={value}
onValueChange={(value) => {
this.setState({ value }, () => {
this._calculateEstimatedAmount();
});
}}
/>
<Text style={styles.percent}>{_percent}</Text>
</View>
</Popover>
</Fragment>
)}
</PopoverController>
);
}
}
export default UpvoteView;

View File

@ -1,4 +1,4 @@
import { DrawerNavigator, SwitchNavigator } from 'react-navigation';
import { DrawerNavigator, SwitchNavigator, createStackNavigator } from 'react-navigation';
import { BaseNavigator } from '../navigation';
import { default as ROUTES } from '../constants/routeNames';
@ -14,13 +14,39 @@ const mainNavigation = DrawerNavigator(
{
[ROUTES.SCREENS.HOME]: {
screen: BaseNavigator,
},
},
{
contentComponent: SideMenu,
},
);
const stackNavigatior = createStackNavigator(
{
[ROUTES.DRAWER.MAIN]: {
screen: mainNavigation,
navigationOptions: {
header: () => null,
},
},
[ROUTES.SCREENS.PROFILE]: {
screen: Profile,
navigationOptions: {
header: () => null,
},
},
[ROUTES.SCREENS.EDITOR]: {
screen: Editor,
navigationOptions: {
header: () => null,
},
},
},
{
contentComponent: SideMenu,
cardStyle: {
backgroundColor: 'white',
},
},
);

View File

@ -68,14 +68,7 @@ export const getUser = async (user) => {
}
};
export const vestToSteem = (
vestingShares,
totalVestingShares,
totalVestingFundSteem,
) => (
parseFloat(totalVestingFundSteem)
* (parseFloat(vestingShares) / parseFloat(totalVestingShares))
);
export const vestToSteem = (vestingShares, totalVestingShares, totalVestingFundSteem) => parseFloat(totalVestingFundSteem) * (parseFloat(vestingShares) / parseFloat(totalVestingShares));
/**
* @method getFollows get account data
@ -222,6 +215,8 @@ export const getPostWithComments = async (user, permlink) => {
return [post, comments];
};
// export const getAccountRC = username => client.call('rc_api', 'find_rc_accounts', { accounts: [username] });
/**
* @method upvote upvote a content
* @param vote vote object(author, permlink, voter, weight)
@ -233,11 +228,9 @@ export const upvote = (vote, postingKey) => {
client.broadcast
.vote(vote, key)
.then((result) => {
console.log(result);
resolve(result);
})
.catch((err) => {
console.log(err);
reject(err);
});
});

View File

@ -22,10 +22,7 @@ export const replaceTags = input => input.replace(/(^|\s|>)(#[-a-z\d]+)/gi, (tag
tag = tag.replace('>', ''); // remove closing tag
const tag2 = tag.trim().substring(1);
const tagLower = tag2.toLowerCase();
return (
`${preceding
}<a class="markdown-tag-link" href="${tagLower}" data-tag="${tagLower}">${tag.trim()}</a>`
);
return `${preceding}<a class="markdown-tag-link" href="${tagLower}" data-tag="${tagLower}">${tag.trim()}</a>`;
});
export const markDown2Html = (input) => {
@ -49,10 +46,8 @@ export const markDown2Html = (input) => {
export const parsePosts = (posts, user) => {
posts.map((post) => {
post.json_metadata = JSON.parse(post.json_metadata);
post.json_metadata.image ? (post.image = post.json_metadata.image[0]) : '';
post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(
2,
);
post.json_metadata.image ? (post.image = post.json_metadata.image[0]) : null;
post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(2);
post.created = getTimeFromNow(post.created);
post.vote_count = post.active_votes.length;
post.author_reputation = getReputation(post.author_reputation);
@ -66,27 +61,21 @@ export const parsePosts = (posts, user) => {
+ parseFloat(post.total_payout_value)
+ parseFloat(post.curator_payout_value);
const voteRshares = post.active_votes.reduce(
(a, b) => a + parseFloat(b.rshares),
0,
);
const voteRshares = post.active_votes.reduce((a, b) => a + parseFloat(b.rshares), 0);
const ratio = totalPayout / voteRshares;
post.isVoted = false;
post.is_voted = false;
for (const i in post.active_votes) {
if (post.active_votes[i].voter == user) {
post.isVoted = true;
if (post && post.active_votes) {
for (const i in post.active_votes) {
post.is_voted = post.active_votes[i].voter === user.name && post.active_votes[i].percent > 0;
post.vote_perecent = post.active_votes[i].voter === user.name ? post.active_votes[i].percent : null;
post.active_votes[i].value = (post.active_votes[i].rshares * ratio).toFixed(2);
post.active_votes[i].reputation = getReputation(post.active_votes[i].reputation);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].avatar = `https://steemitimages.com/u/${
post.active_votes[i].voter
}/avatar/small`;
}
post.active_votes[i].value = (
post.active_votes[i].rshares * ratio
).toFixed(2);
post.active_votes[i].reputation = getReputation(
post.active_votes[i].reputation,
);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].avatar = `https://steemitimages.com/u/${
post.active_votes[i].voter
}/avatar/small`;
}
if (post.active_votes.length > 2) {
@ -116,20 +105,12 @@ export const parsePost = (post) => {
+ parseFloat(post.total_payout_value)
+ parseFloat(post.curator_payout_value);
const voteRshares = post.active_votes.reduce(
(a, b) => a + parseFloat(b.rshares),
0,
);
const voteRshares = post.active_votes.reduce((a, b) => a + parseFloat(b.rshares), 0);
const ratio = totalPayout / voteRshares;
for (const i in post.active_votes) {
post.active_votes[i].value = (post.active_votes[i].rshares * ratio).toFixed(
2,
);
post.active_votes[i].reputation = getReputation(
post.active_votes[i].reputation,
);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].value = (post.active_votes[i].rshares * ratio).toFixed(2);
post.active_votes[i].reputation = getReputation(post.active_votes[i].reputation);
post.active_votes[i].avatar = `https://steemitimages.com/u/${
post.active_votes[i].voter
}/avatar/small`;
@ -183,15 +164,11 @@ export const protocolUrl2Obj = (url) => {
export const parseComments = (comments) => {
comments.map((comment) => {
comment.pending_payout_value = parseFloat(
comment.pending_payout_value,
).toFixed(2);
comment.pending_payout_value = parseFloat(comment.pending_payout_value).toFixed(2);
comment.created = getTimeFromNow(comment.created);
comment.vote_count = comment.active_votes.length;
comment.author_reputation = getReputation(comment.author_reputation);
comment.avatar = `https://steemitimages.com/u/${
comment.author
}/avatar/small`;
comment.avatar = `https://steemitimages.com/u/${comment.author}/avatar/small`;
comment.body = markDown2Html(comment.body);
});
return comments;