mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-24 08:55:14 +03:00
Merge branch 'master' of https://github.com/esteemapp/esteem-mobile into markdownToHtml
This commit is contained in:
commit
4562771a83
@ -4,4 +4,5 @@ NEW_IMAGE_API=
|
||||
OLD_IMAGE_API=
|
||||
SEARCH_API_TOKEN=
|
||||
SEARCH_API_URL=
|
||||
SERVER_LIST_API=
|
||||
SERVER_LIST_API=
|
||||
PIN_KEY=
|
@ -2,6 +2,8 @@
|
||||
|
||||
printf "post-clone.sh\n"
|
||||
|
||||
node -v
|
||||
|
||||
# please specify required Node.js version
|
||||
NODE_VERSION=8.12.0
|
||||
|
||||
@ -9,4 +11,8 @@ NODE_VERSION=8.12.0
|
||||
npm config delete prefix
|
||||
. ~/.bashrc
|
||||
nvm install "$NODE_VERSION"
|
||||
nvm alias node8 "$NODE_VERSION"
|
||||
nvm alias node8 "$NODE_VERSION"
|
||||
nvm alias default v8.12.0
|
||||
node -v
|
||||
|
||||
printf "end of post-clone.sh\n"
|
@ -3,7 +3,7 @@
|
||||
printf "Old .env file:\n"
|
||||
cat .env
|
||||
printf "Started script:\n"
|
||||
ENV_WHITELIST=${ENV_WHITELIST:-"/ACTIVITY|WEBSOCKET|BACKEND|API|TOKEN|URL/"}
|
||||
ENV_WHITELIST=${ENV_WHITELIST:-"/ACTIVITY|WEBSOCKET|BACKEND|API|TOKEN|PIN|URL/"}
|
||||
printf "Creating an .env file with the following whitelist:\n"
|
||||
printf "%s\n\n" $ENV_WHITELIST
|
||||
set | egrep -e $ENV_WHITELIST | egrep -v "^_" | egrep -v "WHITELIST" | egrep -v "USER-DEFINED" > .env
|
||||
|
@ -4,19 +4,27 @@ import { Icon } from '../../../icon';
|
||||
import styles from './textWithIconStyles';
|
||||
|
||||
const TextWithIcon = ({
|
||||
iconName, text, isClickable, onPress, iconStyle, iconType,
|
||||
iconName, text, isClickable, onPress, iconStyle, iconType, iconSize,
|
||||
}) => (
|
||||
<View style={styles.container}>
|
||||
{isClickable || onPress ? (
|
||||
<TouchableHighlight underlayColor="transparent" onPress={() => onPress && onPress()}>
|
||||
<View style={styles.wrapper}>
|
||||
<Icon style={[styles.icon, iconStyle]} name={iconName} iconType={iconType} />
|
||||
<Icon
|
||||
style={[styles.icon, iconStyle, iconSize && { fontSize: iconSize }]}
|
||||
name={iconName}
|
||||
iconType={iconType}
|
||||
/>
|
||||
<Text style={[styles.text]}>{text}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
) : (
|
||||
<View style={styles.wrapper}>
|
||||
<Icon style={[styles.icon, iconStyle]} name={iconName} iconType={iconType} />
|
||||
<Icon
|
||||
style={[styles.icon, iconStyle, iconSize && { fontSize: iconSize }]}
|
||||
name={iconName}
|
||||
iconType={iconType}
|
||||
/>
|
||||
<Text style={styles.text}>{text}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
@ -54,7 +54,7 @@ const WalletLineItem = ({
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{description && (
|
||||
{!!description && (
|
||||
<Text style={[styles.description, !iconName && styles.onlyText]}>{description}</Text>
|
||||
)}
|
||||
</View>
|
||||
|
@ -57,9 +57,9 @@ class CollapsibleCardView extends PureComponent {
|
||||
_getMinValue = () => 0;
|
||||
|
||||
_toggleOnPress = () => {
|
||||
const { handleOnExpanded } = this.props;
|
||||
const { handleOnExpanded, moreHeight } = this.props;
|
||||
Animated.timing(this.anime.height, {
|
||||
toValue: this.anime.expanded ? this._getMinValue() : this._getMaxValue(),
|
||||
toValue: this.anime.expanded ? this._getMinValue() : this._getMaxValue() + moreHeight,
|
||||
duration: 200,
|
||||
}).start();
|
||||
this.anime.expanded = !this.anime.expanded;
|
||||
|
@ -9,7 +9,6 @@ export default EStyleSheet.create({
|
||||
backgroundColor: '$primaryBlue',
|
||||
},
|
||||
input: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: 18,
|
||||
margin: 10,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Animated } from 'react-native';
|
||||
import { Animated, Easing, View } from 'react-native';
|
||||
|
||||
// Styles
|
||||
import styles from './pinAnimatedInputStyles';
|
||||
@ -13,38 +13,73 @@ class PinAnimatedInput extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
|
||||
this.dots = [];
|
||||
|
||||
this.dots[0] = new Animated.Value(0);
|
||||
this.dots[1] = new Animated.Value(0);
|
||||
this.dots[2] = new Animated.Value(0);
|
||||
this.dots[3] = new Animated.Value(0);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { loading } = this.props;
|
||||
if (loading !== nextProps.loading) {
|
||||
if (nextProps.loading) {
|
||||
this._startLoadingAnimation();
|
||||
} else {
|
||||
this._stopLoadingAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_startLoadingAnimation = () => {
|
||||
const { loading } = this.props;
|
||||
[...Array(4)].map((item, index) => {
|
||||
this.dots[index].setValue(0);
|
||||
});
|
||||
Animated.sequence([
|
||||
...this.dots.map(item => Animated.timing(item, {
|
||||
toValue: 1,
|
||||
duration: 250,
|
||||
easing: Easing.linear,
|
||||
})),
|
||||
]).start(() => {
|
||||
if (loading) this._startLoadingAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
_stopLoadingAnimation = () => {
|
||||
[...Array(4)].map((item, index) => {
|
||||
this.dots[index].stopAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { pin } = this.props;
|
||||
const test = new Animated.Value(0);
|
||||
const tilt = test.interpolate({
|
||||
inputRange: [0, 0.3, 0.6, 0.9],
|
||||
outputRange: [0, -50, 50, 0],
|
||||
const marginBottom = [];
|
||||
|
||||
[...Array(4)].map((item, index) => {
|
||||
marginBottom[index] = this.dots[index].interpolate({
|
||||
inputRange: [0, 0.5, 1],
|
||||
outputRange: [0, 20, 0],
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
transform: [{ translateX: tilt }],
|
||||
},
|
||||
styles.container,
|
||||
]}
|
||||
>
|
||||
{[...Array(4)].map((val, index) => {
|
||||
<View style={[styles.container]}>
|
||||
{this.dots.map((val, index) => {
|
||||
if (pin.length > index) {
|
||||
return (
|
||||
<Animated.View key={`passwordItem-${index}`} style={styles.input}>
|
||||
<Animated.View
|
||||
key={`passwordItem-${index}`}
|
||||
style={[styles.input, styles.inputWithBackground]}
|
||||
/>
|
||||
</Animated.View>
|
||||
<Animated.View
|
||||
key={`passwordItem-${index}`}
|
||||
style={[styles.input, styles.inputWithBackground, { bottom: marginBottom[index] }]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <Animated.View key={`passwordItem-${index}`} style={styles.input} />;
|
||||
return <View key={`passwordItem-${index}`} style={styles.input} />;
|
||||
})}
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,9 @@ import { PostHeaderDescription } from '../../postElements';
|
||||
import { PostDropdown } from '../../postDropdown';
|
||||
import { Icon } from '../../icon';
|
||||
|
||||
// Utils
|
||||
import { makeCountFriendly } from '../../../utils/formatter';
|
||||
|
||||
// STEEM
|
||||
import { Upvote } from '../../upvote';
|
||||
// Styles
|
||||
@ -59,6 +62,9 @@ class PostCard extends Component {
|
||||
const _image = content && content.image
|
||||
? { uri: content.image, priority: FastImage.priority.high }
|
||||
: DEFAULT_IMAGE;
|
||||
const reblogedBy = content.reblogged_by && content.reblogged_by[0];
|
||||
// repeat icon
|
||||
// text rebloged by ${reblogedBy}
|
||||
|
||||
return (
|
||||
<View style={styles.post}>
|
||||
@ -72,6 +78,7 @@ class PostCard extends Component {
|
||||
reputation={content.author_reputation}
|
||||
size={32}
|
||||
tag={content.category}
|
||||
reblogedBy={reblogedBy}
|
||||
/>
|
||||
<View style={styles.dropdownWrapper}>
|
||||
<PostDropdown content={content} />
|
||||
@ -103,12 +110,12 @@ class PostCard extends Component {
|
||||
iconType="MaterialIcons"
|
||||
name="people"
|
||||
/>
|
||||
<Text style={styles.comment}>{content.vote_count}</Text>
|
||||
<Text style={styles.comment}>{makeCountFriendly(content.vote_count)}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<TouchableOpacity style={styles.commentButton}>
|
||||
<Icon style={[styles.commentIcon]} iconType="MaterialIcons" name="comment" />
|
||||
<Text style={styles.comment}>{content.children}</Text>
|
||||
<Text style={styles.comment}>{makeCountFriendly(content.children)}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -55,10 +55,12 @@ class PostDropdownContainer extends PureComponent {
|
||||
};
|
||||
|
||||
_reblog = () => {
|
||||
const { currentAccount, content, isLoggedIn } = this.props;
|
||||
const {
|
||||
currentAccount, content, isLoggedIn, pinCode,
|
||||
} = this.props;
|
||||
if (isLoggedIn) {
|
||||
reblog(currentAccount, content.author, content.permlink)
|
||||
.then((result) => {
|
||||
reblog(currentAccount, pinCode, content.author, content.permlink)
|
||||
.then(() => {
|
||||
Alert.alert('Success', 'Rebloged!');
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -98,5 +100,6 @@ class PostDropdownContainer extends PureComponent {
|
||||
const mapStateToProps = state => ({
|
||||
isLoggedIn: state.application.isLoggedIn,
|
||||
currentAccount: state.account.currentAccount,
|
||||
pinCode: state.account.pin,
|
||||
});
|
||||
export default withNavigation(connect(mapStateToProps)(PostDropdownContainer));
|
||||
|
@ -5,7 +5,7 @@ import { withNavigation } from 'react-navigation';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
// Components
|
||||
import { Tag } from '../../../basicUIElements';
|
||||
import { Tag, TextWithIcon } from '../../../basicUIElements';
|
||||
|
||||
// Styles
|
||||
import styles from './postHeaderDescriptionStyles';
|
||||
@ -43,7 +43,15 @@ class PostHeaderDescription extends PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
date, avatar, name, reputation, size, tag, tagOnPress, isHideImage,
|
||||
avatar,
|
||||
date,
|
||||
isHideImage,
|
||||
name,
|
||||
reblogedBy,
|
||||
reputation,
|
||||
size,
|
||||
tag,
|
||||
tagOnPress,
|
||||
} = this.props;
|
||||
|
||||
const _reputationText = `(${reputation})`;
|
||||
@ -77,6 +85,7 @@ class PostHeaderDescription extends PureComponent {
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<Text style={styles.date}>{date}</Text>
|
||||
{!!reblogedBy && <TextWithIcon text={reblogedBy} iconType="MaterialIcons" iconName="repeat" />}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ export default EStyleSheet.create({
|
||||
width: '$deviceWidth - 24',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 17,
|
||||
marginTop: 10,
|
||||
marginVertical: 10,
|
||||
height: 30,
|
||||
},
|
||||
leftIcons: {
|
||||
flexDirection: 'row',
|
||||
@ -35,10 +35,11 @@ export default EStyleSheet.create({
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
insetIconStyle: {
|
||||
marginRight: 12,
|
||||
marginRight: 20,
|
||||
color: '$primaryDarkText',
|
||||
},
|
||||
activityIndicator: {
|
||||
marginRight: 12,
|
||||
marginRight: 20,
|
||||
width: 30,
|
||||
},
|
||||
followCountWrapper: {
|
||||
@ -58,6 +59,13 @@ export default EStyleSheet.create({
|
||||
},
|
||||
// TODO: look at here
|
||||
dropdownIconStyle: {
|
||||
marginBottom: 7,
|
||||
width: 25,
|
||||
height: 25,
|
||||
left: -5,
|
||||
marginBottom: 3,
|
||||
color: '#c1c5c7',
|
||||
},
|
||||
dropdownStyle: {
|
||||
maxWidth: 150,
|
||||
},
|
||||
});
|
||||
|
@ -17,6 +17,10 @@ import DARK_COVER_IMAGE from '../../../assets/dark_cover_image.png';
|
||||
import { TextWithIcon } from '../../basicUIElements';
|
||||
import { PercentBar } from '../../percentBar';
|
||||
import { IconButton } from '../../iconButton';
|
||||
import { DropdownButton } from '../../dropdownButton';
|
||||
|
||||
// Utils
|
||||
import { makeCountFriendly } from '../../../utils/formatter';
|
||||
|
||||
// Styles
|
||||
import styles from './profileSummaryStyles';
|
||||
@ -43,6 +47,16 @@ class ProfileSummaryView extends PureComponent {
|
||||
Linking.openURL(url);
|
||||
};
|
||||
|
||||
_handleOnDropdownSelect = (index) => {
|
||||
const { isMuted, handleMuteUnmuteUser } = this.props;
|
||||
|
||||
// This funciton should have switch case but now only has one option therefor
|
||||
// temporarily I created with if statments
|
||||
if (index === '0' && handleMuteUnmuteUser) {
|
||||
handleMuteUnmuteUser(!isMuted);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { isShowPercentText } = this.state;
|
||||
const {
|
||||
@ -51,8 +65,8 @@ class ProfileSummaryView extends PureComponent {
|
||||
followerCount,
|
||||
followingCount,
|
||||
handleFollowUnfollowUser,
|
||||
handleMuteUnmuteUser,
|
||||
handleOnFollowsPress,
|
||||
handleUIChange,
|
||||
hoursRC,
|
||||
hoursVP,
|
||||
intl,
|
||||
@ -66,40 +80,43 @@ class ProfileSummaryView extends PureComponent {
|
||||
location,
|
||||
percentRC,
|
||||
percentVP,
|
||||
handleUIChange,
|
||||
} = this.props;
|
||||
const dropdownOpions = [];
|
||||
const votingPowerHoursText = hoursVP && `• Full in ${hoursVP} hours`;
|
||||
const votingPowerText = `Voting power: ${percentVP}% ${votingPowerHoursText || ''}`;
|
||||
const rcPowerHoursText = hoursRC && `• Full in ${hoursRC} hours`;
|
||||
const rcPowerText = `RCs: ${percentRC}% ${rcPowerHoursText || ''}`;
|
||||
|
||||
/* eslint-disable */
|
||||
const rowLength = location
|
||||
? location.length
|
||||
: null + link
|
||||
? link.length
|
||||
: null + date
|
||||
? date.length
|
||||
: null;
|
||||
const rowLength = (location ? location.length : 0) + (link ? link.length : 0) + (date ? date.length : 0);
|
||||
const isColumn = rowLength && DEVICE_WIDTH / rowLength <= 7.3;
|
||||
|
||||
const isColumn = rowLength && DEVICE_WIDTH / rowLength <= 15;
|
||||
const followButtonIcon = !isFollowing ? 'user-follow' : 'user-unfollow';
|
||||
const ignoreButtonIcon = !isMuted ? 'ban' : 'minus';
|
||||
const followButtonIcon = !isFollowing ? 'account-plus' : 'account-minus';
|
||||
const coverImageUrl = `http://img.esteem.app/400x0/${coverImage}`;
|
||||
|
||||
dropdownOpions.push(!isMuted ? 'MUTE' : 'UNMUTE');
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<View style={[isColumn ? styles.textWithIconWrapperColumn : styles.textWithIconWrapper]}>
|
||||
{!!location && <TextWithIcon text={location} iconName="md-navigate" />}
|
||||
{!!location && (
|
||||
<TextWithIcon
|
||||
text={location}
|
||||
iconName="near-me"
|
||||
iconType="MaterialIcons"
|
||||
iconSize={14}
|
||||
/>
|
||||
)}
|
||||
{!!link && (
|
||||
<TextWithIcon
|
||||
isClickable
|
||||
onPress={() => this._handleOnPressLink(link)}
|
||||
text={link}
|
||||
iconName="md-globe"
|
||||
iconSize={14}
|
||||
iconName="earth"
|
||||
iconType="MaterialCommunityIcons"
|
||||
/>
|
||||
)}
|
||||
{!!date && <TextWithIcon text={date} iconName="md-calendar" />}
|
||||
{!!date && <TextWithIcon text={date} iconName="md-calendar" iconSize={14} />}
|
||||
</View>
|
||||
<Image
|
||||
style={styles.longImage}
|
||||
@ -107,10 +124,9 @@ class ProfileSummaryView extends PureComponent {
|
||||
defaultSource={isDarkTheme ? DARK_COVER_IMAGE : LIGHT_COVER_IMAGE}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
onPress={() =>
|
||||
this.setState({ isShowPercentText: !isShowPercentText }, () => {
|
||||
handleUIChange(isShowPercentText ? 0 : 30);
|
||||
})
|
||||
onPress={() => this.setState({ isShowPercentText: !isShowPercentText }, () => {
|
||||
handleUIChange(!isShowPercentText ? 30 : 0);
|
||||
})
|
||||
}
|
||||
>
|
||||
<PercentBar
|
||||
@ -136,7 +152,7 @@ class ProfileSummaryView extends PureComponent {
|
||||
<Fragment>
|
||||
<TouchableOpacity onPress={() => handleOnFollowsPress(false)}>
|
||||
<View style={styles.followCountWrapper}>
|
||||
<Text style={styles.followCount}>{followerCount}</Text>
|
||||
<Text style={styles.followCount}>{makeCountFriendly(followerCount)}</Text>
|
||||
<Text style={styles.followText}>
|
||||
{' '}
|
||||
{intl.formatMessage({
|
||||
@ -147,7 +163,7 @@ class ProfileSummaryView extends PureComponent {
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleOnFollowsPress(true)}>
|
||||
<View style={styles.followCountWrapper}>
|
||||
<Text style={styles.followCount}>{followingCount}</Text>
|
||||
<Text style={styles.followCount}>{makeCountFriendly(followingCount)}</Text>
|
||||
<Text style={styles.followText}>
|
||||
{intl.formatMessage({
|
||||
id: 'profile.following',
|
||||
@ -163,9 +179,9 @@ class ProfileSummaryView extends PureComponent {
|
||||
<Fragment>
|
||||
<IconButton
|
||||
backgroundColor="transparent"
|
||||
name="heart"
|
||||
iconType="SimpleLineIcons"
|
||||
size={16}
|
||||
name="favorite-border"
|
||||
iconType="MaterialIcons"
|
||||
size={20}
|
||||
style={[styles.insetIconStyle]}
|
||||
color="#c1c5c7"
|
||||
/>
|
||||
@ -175,24 +191,23 @@ class ProfileSummaryView extends PureComponent {
|
||||
<IconButton
|
||||
backgroundColor="transparent"
|
||||
name={followButtonIcon}
|
||||
iconType="SimpleLineIcons"
|
||||
onPress={() => handleFollowUnfollowUser(isFollowing ? false : true)}
|
||||
size={16}
|
||||
style={styles.insetIconStyle}
|
||||
iconType="MaterialCommunityIcons"
|
||||
onPress={() => handleFollowUnfollowUser(!isFollowing)}
|
||||
size={20}
|
||||
color="#c1c5c7"
|
||||
/>
|
||||
)}
|
||||
{isProfileLoading ? (
|
||||
<ActivityIndicator style={styles.activityIndicator} />
|
||||
) : (
|
||||
<IconButton
|
||||
backgroundColor="transparent"
|
||||
name={ignoreButtonIcon}
|
||||
iconType="SimpleLineIcons"
|
||||
onPress={() => handleMuteUnmuteUser(isMuted ? false : true)}
|
||||
size={16}
|
||||
style={styles.insetIconStyle}
|
||||
color="#c1c5c7"
|
||||
<DropdownButton
|
||||
isHasChildIcon
|
||||
iconName="more-vert"
|
||||
options={dropdownOpions}
|
||||
onSelect={this._handleOnDropdownSelect}
|
||||
noHighlight
|
||||
iconStyle={styles.dropdownIconStyle}
|
||||
dropdownStyle={styles.dropdownStyle}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
|
@ -43,6 +43,7 @@ class UpvoteContainer extends PureComponent {
|
||||
isLoggedIn,
|
||||
isShowPayoutValue,
|
||||
upvotePercent,
|
||||
pinCode,
|
||||
} = this.props;
|
||||
let author;
|
||||
let isVoted;
|
||||
@ -50,10 +51,10 @@ class UpvoteContainer extends PureComponent {
|
||||
let permlink;
|
||||
|
||||
if (content) {
|
||||
author = content.author;
|
||||
({ author } = content);
|
||||
isVoted = content.is_voted;
|
||||
pendingPayoutValue = content.pending_payout_value;
|
||||
permlink = content.permlink;
|
||||
({ permlink } = content);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -68,6 +69,7 @@ class UpvoteContainer extends PureComponent {
|
||||
pendingPayoutValue={pendingPayoutValue}
|
||||
permlink={permlink}
|
||||
upvotePercent={upvotePercent}
|
||||
pinCode={pinCode}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -76,7 +78,7 @@ class UpvoteContainer extends PureComponent {
|
||||
const mapStateToProps = state => ({
|
||||
isLoggedIn: state.application.isLoggedIn,
|
||||
upvotePercent: state.application.upvotePercent,
|
||||
|
||||
pinCode: state.account.pin,
|
||||
currentAccount: state.account.currentAccount,
|
||||
});
|
||||
|
||||
|
@ -75,7 +75,7 @@ class UpvoteView extends Component {
|
||||
|
||||
_upvoteContent = async () => {
|
||||
const {
|
||||
author, currentAccount, fetchPost, handleSetUpvotePercent, permlink,
|
||||
author, currentAccount, fetchPost, handleSetUpvotePercent, permlink, pinCode,
|
||||
} = this.props;
|
||||
const { sliderValue } = this.state;
|
||||
|
||||
@ -92,6 +92,7 @@ class UpvoteView extends Component {
|
||||
|
||||
vote(
|
||||
currentAccount,
|
||||
pinCode,
|
||||
author,
|
||||
permlink,
|
||||
weight,
|
||||
|
@ -6,6 +6,7 @@
|
||||
"claim_reward_balance": "Claim Reward Balance",
|
||||
"transfer": "Transfer",
|
||||
"transfer_to_vesting": "Transfer To Vesting",
|
||||
"transfer_from_savings": "Transfer From Savings",
|
||||
"withdraw_vesting": "Power Down",
|
||||
"fill_order": "Fill Order"
|
||||
},
|
||||
|
@ -1,13 +1,16 @@
|
||||
{
|
||||
"wallet": {
|
||||
"curation_reward": "Curation Reward",
|
||||
"author_reward": "Author Reward",
|
||||
"comment_benefactor_reward": "Comment Benefactor Reward",
|
||||
"claim_reward_balance_ok": "Reward balance claimed",
|
||||
"claim_reward_balance": "Claim Reward Balance",
|
||||
"transfer": "Transfer",
|
||||
"comment_benefactor_reward": "Comment Benefactor Reward",
|
||||
"curation_reward": "Curation Reward",
|
||||
"fill_order": "Fill Order",
|
||||
"transactions": "Transactions",
|
||||
"transfer_from_savings": "Tasarruflardan Transfer",
|
||||
"transfer_to_vesting": "Transfer To Vesting",
|
||||
"withdraw_vesting": "withdraw_vesting",
|
||||
"fill_order": "Fill Order"
|
||||
"transfer": "Transfer",
|
||||
"withdraw_vesting": "Withdraw Vesting"
|
||||
},
|
||||
"notification": {
|
||||
"vote": "beğendi",
|
||||
|
@ -5,17 +5,13 @@ import {
|
||||
setAuthStatus,
|
||||
getUserDataWithUsername,
|
||||
updateUserData,
|
||||
setPinCode,
|
||||
getPinCode,
|
||||
updateCurrentUsername,
|
||||
getUserData,
|
||||
} from '../../realm/realm';
|
||||
import { encryptKey, decryptKey } from '../../utils/crypto';
|
||||
import steemConnect from './steemConnectAPI';
|
||||
|
||||
export const Login = (username, password) => {
|
||||
let publicKeys;
|
||||
let privateKeys;
|
||||
export const login = async (username, password) => {
|
||||
const resultKeys = {
|
||||
active: null,
|
||||
memo: null,
|
||||
@ -24,75 +20,63 @@ export const Login = (username, password) => {
|
||||
};
|
||||
let loginFlag = false;
|
||||
let avatar = '';
|
||||
// Get user account data from STEEM Blockchain
|
||||
const account = await getUser(username);
|
||||
if (!account) {
|
||||
return Promise.reject(new Error('Invalid pin code, please check and try again'));
|
||||
}
|
||||
if (isLoggedInUser(username)) {
|
||||
return Promise.reject(new Error('You are already logged in, please try to add another account'));
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// Get user account data from STEEM Blockchain
|
||||
getUser(username)
|
||||
.then((account) => {
|
||||
if (isLoggedInUser(username)) {
|
||||
reject(new Error('You are already logged in, please try to add another account'));
|
||||
}
|
||||
// Public keys of user
|
||||
const publicKeys = {
|
||||
active: account.active.key_auths.map(x => x[0]),
|
||||
memo: account.memo_key,
|
||||
owner: account.owner.key_auths.map(x => x[0]),
|
||||
posting: account.posting.key_auths.map(x => x[0]),
|
||||
};
|
||||
|
||||
// Public keys of user
|
||||
publicKeys = {
|
||||
active: account.active.key_auths.map(x => x[0]),
|
||||
memo: account.memo_key,
|
||||
owner: account.owner.key_auths.map(x => x[0]),
|
||||
posting: account.posting.key_auths.map(x => x[0]),
|
||||
};
|
||||
// Set private keys of user
|
||||
const privateKeys = getPrivateKeys(username, password);
|
||||
|
||||
// Set private keys of user
|
||||
privateKeys = getPrivateKeys(username, password);
|
||||
|
||||
// Check all keys
|
||||
Object.keys(publicKeys).map((pubKey) => {
|
||||
if (publicKeys[pubKey] === privateKeys[pubKey].createPublic().toString()) {
|
||||
loginFlag = true;
|
||||
resultKeys[pubKey] = publicKeys[pubKey];
|
||||
}
|
||||
});
|
||||
let jsonMetadata;
|
||||
try {
|
||||
jsonMetadata = JSON.parse(account.json_metadata) || '';
|
||||
} catch (err) {
|
||||
jsonMetadata = '';
|
||||
// TODO: handle wrong json format properly
|
||||
// reject(new Error(err));
|
||||
}
|
||||
if (Object.keys(jsonMetadata).length !== 0) {
|
||||
avatar = jsonMetadata.profile.profile_image || '';
|
||||
}
|
||||
if (loginFlag) {
|
||||
const userData = {
|
||||
username,
|
||||
avatar,
|
||||
authType: 'masterKey',
|
||||
masterKey: '',
|
||||
postingKey: '',
|
||||
activeKey: '',
|
||||
memoKey: '',
|
||||
accessToken: '',
|
||||
};
|
||||
|
||||
account.local = userData;
|
||||
|
||||
// Save user data to Realm DB
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
resolve({ ...account, password });
|
||||
updateCurrentUsername(account.name);
|
||||
})
|
||||
.catch(() => {
|
||||
reject(new Error('Invalid credentials, please check and try again'));
|
||||
});
|
||||
} else {
|
||||
reject(new Error('Invalid credentials, please check and try again'));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
reject(new Error('Invalid credentials, please check and try again'));
|
||||
});
|
||||
// Check all keys
|
||||
Object.keys(publicKeys).map((pubKey) => {
|
||||
if (publicKeys[pubKey] === privateKeys[pubKey].createPublic().toString()) {
|
||||
loginFlag = true;
|
||||
resultKeys[pubKey] = publicKeys[pubKey];
|
||||
}
|
||||
});
|
||||
|
||||
let jsonMetadata;
|
||||
try {
|
||||
jsonMetadata = JSON.parse(account.json_metadata) || '';
|
||||
} catch (err) {
|
||||
jsonMetadata = '';
|
||||
}
|
||||
if (Object.keys(jsonMetadata).length !== 0) {
|
||||
avatar = jsonMetadata.profile.profile_image || '';
|
||||
}
|
||||
if (loginFlag) {
|
||||
const userData = {
|
||||
username,
|
||||
avatar,
|
||||
authType: 'masterKey',
|
||||
masterKey: '',
|
||||
postingKey: '',
|
||||
activeKey: '',
|
||||
memoKey: '',
|
||||
accessToken: '',
|
||||
};
|
||||
|
||||
account.local = userData;
|
||||
|
||||
// Save user data to Realm DB
|
||||
await setUserData(userData);
|
||||
await updateCurrentUsername(account.name);
|
||||
return ({ ...account, password });
|
||||
}
|
||||
return Promise.reject(new Error('Invalid pin code, please check and try again'));
|
||||
};
|
||||
|
||||
export const loginWithSC2 = async (accessToken) => {
|
||||
@ -104,7 +88,7 @@ export const loginWithSC2 = async (accessToken) => {
|
||||
try {
|
||||
const jsonMetadata = JSON.parse(account.account.json_metadata);
|
||||
if (Object.keys(jsonMetadata).length !== 0) {
|
||||
avatar = jsonMetadata.profile.profile_image;
|
||||
avatar = jsonMetadata.profile.profile_image || '';
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error('Invalid credentials, please check and try again'));
|
||||
@ -120,26 +104,15 @@ export const loginWithSC2 = async (accessToken) => {
|
||||
accessToken: '',
|
||||
};
|
||||
|
||||
const authData = {
|
||||
isLoggedIn: true,
|
||||
currentUsername: account.account.name,
|
||||
};
|
||||
|
||||
if (isLoggedInUser(account.account.name)) {
|
||||
reject(new Error('You are already logged in, please try to add another account'));
|
||||
}
|
||||
|
||||
setAuthStatus(authData)
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
account.account.username = account.account.name;
|
||||
resolve({ ...account.account, accessToken });
|
||||
updateCurrentUsername(account.account.name);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
account.account.username = account.account.name;
|
||||
updateCurrentUsername(account.account.name);
|
||||
resolve({ ...account.account, accessToken });
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
@ -147,90 +120,53 @@ export const loginWithSC2 = async (accessToken) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const setUserDataWithPinCode = data => new Promise((resolve, reject) => {
|
||||
let updatedUserData;
|
||||
export const setUserDataWithPinCode = async (data) => {
|
||||
const result = getUserDataWithUsername(data.username);
|
||||
const userData = result[0];
|
||||
|
||||
const privateKeys = getPrivateKeys(userData.username, data.password);
|
||||
|
||||
if (userData.authType === 'masterKey') {
|
||||
updatedUserData = {
|
||||
username: userData.username,
|
||||
authType: 'masterKey',
|
||||
masterKey: encryptKey(data.password, data.pinCode),
|
||||
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
|
||||
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
|
||||
};
|
||||
} else if (userData.authType === 'steemConnect') {
|
||||
updatedUserData = {
|
||||
username: userData.username,
|
||||
authType: 'steemConnect',
|
||||
accessToken: encryptKey(data.accessToken, data.pinCode),
|
||||
masterKey: '',
|
||||
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
|
||||
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
|
||||
};
|
||||
}
|
||||
const updatedUserData = {
|
||||
username: userData.username,
|
||||
authType: userData.authType,
|
||||
accessToken: userData.authType === 'steemConnect' ? encryptKey(data.accessToken, data.pinCode) : '',
|
||||
masterKey: userData.authType === 'masterKey' ? encryptKey(data.password, data.pinCode) : '',
|
||||
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
|
||||
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
|
||||
};
|
||||
|
||||
updateUserData(updatedUserData)
|
||||
.then((response) => {
|
||||
const authData = {
|
||||
isLoggedIn: true,
|
||||
currentUsername: userData.username,
|
||||
};
|
||||
const response = await updateUserData(updatedUserData);
|
||||
const authData = {
|
||||
isLoggedIn: true,
|
||||
currentUsername: userData.username,
|
||||
};
|
||||
|
||||
setAuthStatus(authData)
|
||||
.then(() => {
|
||||
const encriptedPinCode = encryptKey(data.pinCode, 'pin-code');
|
||||
setPinCode(encriptedPinCode)
|
||||
.then(() => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
await setAuthStatus(authData);
|
||||
return (response);
|
||||
};
|
||||
|
||||
export const updatePinCode = async (data) => {
|
||||
let updatedUserData;
|
||||
|
||||
let password = null;
|
||||
let accessToken = null;
|
||||
const users = await getUserData();
|
||||
if (users.length > 0) {
|
||||
users.forEach(async (userData) => {
|
||||
const password = decryptKey(userData.masterKey, data.oldPinCode);
|
||||
const privateKeys = getPrivateKeys(userData.username, password);
|
||||
if (userData.authType === 'masterKey') {
|
||||
updatedUserData = {
|
||||
username: userData.username,
|
||||
authType: 'masterKey',
|
||||
masterKey: encryptKey(password, data.pinCode),
|
||||
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
|
||||
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
|
||||
};
|
||||
password = decryptKey(userData.masterKey, data.oldPinCode);
|
||||
} else if (userData.authType === 'steemConnect') {
|
||||
updatedUserData = {
|
||||
username: userData.username,
|
||||
authType: 'steemConnect',
|
||||
accessToken: encryptKey(data.accessToken, data.pinCode),
|
||||
masterKey: '',
|
||||
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
|
||||
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
|
||||
};
|
||||
accessToken = decryptKey(userData.accessToken, data.oldPinCode);
|
||||
}
|
||||
|
||||
const privateKeys = getPrivateKeys(userData.username, password);
|
||||
const updatedUserData = {
|
||||
username: userData.username,
|
||||
authType: userData.authType,
|
||||
accessToken: userData.authType === 'steemConnect' ? encryptKey(accessToken, data.pinCode) : '',
|
||||
masterKey: userData.authType === 'masterKey' ? encryptKey(password, data.pinCode) : '',
|
||||
postingKey: encryptKey(privateKeys.posting.toString(), data.pinCode),
|
||||
activeKey: encryptKey(privateKeys.active.toString(), data.pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo.toString(), data.pinCode),
|
||||
};
|
||||
const response = await updateUserData(updatedUserData);
|
||||
const authData = {
|
||||
isLoggedIn: true,
|
||||
@ -238,9 +174,6 @@ export const updatePinCode = async (data) => {
|
||||
};
|
||||
|
||||
await setAuthStatus(authData);
|
||||
const encriptedPinCode = encryptKey(data.pinCode, 'pin-code');
|
||||
await setPinCode(encriptedPinCode);
|
||||
|
||||
return response;
|
||||
});
|
||||
}
|
||||
@ -252,72 +185,55 @@ export const verifyPinCode = async (data) => {
|
||||
let account = null;
|
||||
let loginFlag = false;
|
||||
if (result.length > 0) {
|
||||
if (userData.masterKey || userData.accessToken) {
|
||||
if (userData.authType === 'steemConnect') {
|
||||
const accessToken = decryptKey(userData.accessToken, data.pinCode);
|
||||
await steemConnect.setAccessToken(accessToken);
|
||||
account = await steemConnect.me();
|
||||
if (account) {
|
||||
if (userData.authType === 'steemConnect') {
|
||||
let accessToken;
|
||||
try {
|
||||
accessToken = decryptKey(userData.accessToken, data.pinCode);
|
||||
} catch (error) {
|
||||
return Promise.reject(new Error('Invalid pin code, please check and try again'));
|
||||
}
|
||||
await steemConnect.setAccessToken(accessToken);
|
||||
account = await steemConnect.me();
|
||||
if (account) {
|
||||
loginFlag = true;
|
||||
}
|
||||
} else if (userData.authType === 'masterKey') {
|
||||
const password = decryptKey(userData.masterKey, data.pinCode);
|
||||
account = await getUser(data.username);
|
||||
// Public keys of user
|
||||
const publicKeys = {
|
||||
active: account.active.key_auths.map(x => x[0]),
|
||||
memo: account.memo_key,
|
||||
owner: account.owner.key_auths.map(x => x[0]),
|
||||
posting: account.posting.key_auths.map(x => x[0]),
|
||||
};
|
||||
// Set private keys of user
|
||||
const privateKeys = getPrivateKeys(data.username, password);
|
||||
|
||||
// Check all keys
|
||||
Object.keys(publicKeys).map((pubKey) => {
|
||||
if (publicKeys[pubKey] === privateKeys[pubKey].createPublic().toString()) {
|
||||
loginFlag = true;
|
||||
}
|
||||
} else if (userData.authType === 'masterKey') {
|
||||
const password = decryptKey(userData.masterKey, data.pinCode);
|
||||
account = await getUser(data.username);
|
||||
|
||||
// Public keys of user
|
||||
const publicKeys = {
|
||||
active: account.active.key_auths.map(x => x[0]),
|
||||
memo: account.memo_key,
|
||||
owner: account.owner.key_auths.map(x => x[0]),
|
||||
posting: account.posting.key_auths.map(x => x[0]),
|
||||
};
|
||||
// Set private keys of user
|
||||
const privateKeys = getPrivateKeys(data.username, password);
|
||||
|
||||
// Check all keys
|
||||
Object.keys(publicKeys).map((pubKey) => {
|
||||
if (publicKeys[pubKey] === privateKeys[pubKey].createPublic().toString()) {
|
||||
loginFlag = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const encriptedPinCode = await getPinCode();
|
||||
const pinCode = decryptKey(encriptedPinCode, 'pin-code');
|
||||
if (pinCode === data.pinCode) {
|
||||
const res = await setUserDataWithPinCode(data);
|
||||
if (res) {
|
||||
loginFlag = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (loginFlag) {
|
||||
const authData = {
|
||||
isLoggedIn: true,
|
||||
currentUsername: data.username,
|
||||
};
|
||||
const response = {
|
||||
accessToken: decryptKey(userData.accessToken, data.pinCode),
|
||||
postingKey: decryptKey(userData.postingKey, data.pinCode),
|
||||
masterKey: decryptKey(userData.masterKey, data.pinCode),
|
||||
activeKey: decryptKey(userData.activeKey, data.pinCode),
|
||||
memoKey: decryptKey(userData.memoKey, data.pinCode),
|
||||
};
|
||||
setAuthStatus(authData)
|
||||
.then(() => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: create function for throw error
|
||||
reject(new Error('Unknown error, please contact to eSteem.'));
|
||||
});
|
||||
} else {
|
||||
reject(new Error('Invalid pin code, please check and try again'));
|
||||
}
|
||||
});
|
||||
if (loginFlag) {
|
||||
const authData = {
|
||||
isLoggedIn: true,
|
||||
currentUsername: data.username,
|
||||
};
|
||||
const response = {
|
||||
accessToken: decryptKey(userData.accessToken, data.pinCode),
|
||||
postingKey: decryptKey(userData.postingKey, data.pinCode),
|
||||
masterKey: decryptKey(userData.masterKey, data.pinCode),
|
||||
activeKey: decryptKey(userData.activeKey, data.pinCode),
|
||||
memoKey: decryptKey(userData.memoKey, data.pinCode),
|
||||
};
|
||||
await setAuthStatus(authData);
|
||||
return (response);
|
||||
}
|
||||
return Promise.reject(new Error('Invalid pin code, please check and try again'));
|
||||
};
|
||||
|
||||
export const switchAccount = username => new Promise((resolve, reject) => {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { Client, PrivateKey } from 'dsteem';
|
||||
import steemConnect from 'steemconnect';
|
||||
import Config from 'react-native-config';
|
||||
|
||||
import { getServer, getPinCode } from '../../realm/realm';
|
||||
import { getUnreadActivityCount } from '../esteem/esteem';
|
||||
|
||||
@ -31,7 +33,7 @@ const _getClient = async () => {
|
||||
|
||||
_getClient();
|
||||
|
||||
export const getDigitPinCode = async () => decryptKey(await getPinCode(), 'pin-code');
|
||||
export const getDigitPinCode = pin => decryptKey(pin, Config.PIN_KEY);
|
||||
|
||||
/**
|
||||
* @method getAccount get account data
|
||||
@ -194,8 +196,8 @@ export const getIsMuted = async (username, targetUsername) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
export const ignoreUser = async (currentAccount, data) => {
|
||||
const digitPinCode = await getDigitPinCode();
|
||||
export const ignoreUser = async (currentAccount, pin, data) => {
|
||||
const digitPinCode = getDigitPinCode(pin);
|
||||
|
||||
if (currentAccount.local.authType === AUTH_TYPE.MASTER_KEY) {
|
||||
const key = decryptKey(currentAccount.local.postingKey, digitPinCode);
|
||||
@ -358,8 +360,8 @@ export const getPostWithComments = async (user, permlink) => {
|
||||
* @param vote vote object(author, permlink, voter, weight)
|
||||
* @param postingKey private posting key
|
||||
*/
|
||||
export const vote = async (currentAccount, author, permlink, weight) => {
|
||||
const digitPinCode = await getDigitPinCode();
|
||||
export const vote = async (currentAccount, pin, author, permlink, weight) => {
|
||||
const digitPinCode = getDigitPinCode(pin);
|
||||
|
||||
if (currentAccount.local.authType === AUTH_TYPE.MASTER_KEY) {
|
||||
const key = decryptKey(currentAccount.local.postingKey, digitPinCode);
|
||||
@ -443,8 +445,8 @@ export const transferToken = (data, activeKey) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const followUser = async (currentAccount, data) => {
|
||||
const digitPinCode = await getDigitPinCode();
|
||||
export const followUser = async (currentAccount, pin, data) => {
|
||||
const digitPinCode = getDigitPinCode(pin);
|
||||
|
||||
if (currentAccount.local.authType === AUTH_TYPE.MASTER_KEY) {
|
||||
const key = decryptKey(currentAccount.local.postingKey, digitPinCode);
|
||||
@ -484,8 +486,8 @@ export const followUser = async (currentAccount, data) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const unfollowUser = async (currentAccount, data) => {
|
||||
const digitPinCode = await getDigitPinCode();
|
||||
export const unfollowUser = async (currentAccount, pin, data) => {
|
||||
const digitPinCode = getDigitPinCode(pin);
|
||||
|
||||
if (currentAccount.local.authType === AUTH_TYPE.MASTER_KEY) {
|
||||
const key = decryptKey(currentAccount.local.postingKey, digitPinCode);
|
||||
@ -620,6 +622,7 @@ export const lookupAccounts = async (username) => {
|
||||
*/
|
||||
export const postContent = async (
|
||||
account,
|
||||
pin,
|
||||
parentAuthor,
|
||||
parentPermlink,
|
||||
permlink,
|
||||
@ -630,7 +633,7 @@ export const postContent = async (
|
||||
voteWeight = null,
|
||||
) => {
|
||||
const { name: author } = account;
|
||||
const digitPinCode = await getDigitPinCode();
|
||||
const digitPinCode = getDigitPinCode(pin);
|
||||
|
||||
if (account.local.authType === AUTH_TYPE.MASTER_KEY) {
|
||||
const opArray = [
|
||||
@ -722,8 +725,8 @@ export const postContent = async (
|
||||
};
|
||||
|
||||
// Re-blog
|
||||
export const reblog = async (account, author, permlink) => {
|
||||
const pin = await getDigitPinCode();
|
||||
export const reblog = async (account, pinCode, author, permlink) => {
|
||||
const pin = getDigitPinCode(pinCode);
|
||||
|
||||
if (account.local.authType === AUTH_TYPE.MASTER_KEY) {
|
||||
const key = decryptKey(account.local.postingKey, pin);
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
UPDATE_CURRENT_ACCOUNT,
|
||||
UPDATE_UNREAD_ACTIVITY_COUNT,
|
||||
REMOVE_OTHER_ACCOUNT,
|
||||
SET_PIN_CODE,
|
||||
} from '../constants/constants';
|
||||
|
||||
export const fetchAccountFromSteem = (username, password) => (dispatch) => {
|
||||
@ -43,3 +44,8 @@ export const removeOtherAccount = data => ({
|
||||
type: REMOVE_OTHER_ACCOUNT,
|
||||
payload: data,
|
||||
});
|
||||
|
||||
export const setPinCode = data => ({
|
||||
type: SET_PIN_CODE,
|
||||
payload: data,
|
||||
});
|
||||
|
@ -28,6 +28,7 @@ export const FETCHING_ACCOUNT = 'FETCHING_ACCOUNT';
|
||||
export const REMOVE_OTHER_ACCOUNT = 'REMOVE_OTHER_ACCOUNT';
|
||||
export const UPDATE_CURRENT_ACCOUNT = 'UPDATE_CURRENT_ACCOUNT';
|
||||
export const UPDATE_UNREAD_ACTIVITY_COUNT = 'UPDATE_UNREAD_ACTIVITY_COUNT';
|
||||
export const SET_PIN_CODE = 'SET_PIN_CODE';
|
||||
|
||||
// UI
|
||||
export const IS_COLLAPSE_POST_BUTTON = 'IS_COLLAPSE_POST_BUTTON';
|
||||
|
@ -4,9 +4,9 @@ import {
|
||||
ADD_OTHER_ACCOUNT,
|
||||
UPDATE_CURRENT_ACCOUNT,
|
||||
UPDATE_UNREAD_ACTIVITY_COUNT,
|
||||
LOGOUT,
|
||||
REMOVE_OTHER_ACCOUNT,
|
||||
LOGOUT_FAIL,
|
||||
SET_PIN_CODE,
|
||||
} from '../constants/constants';
|
||||
|
||||
const initialState = {
|
||||
@ -16,6 +16,7 @@ const initialState = {
|
||||
hasError: false,
|
||||
errorMessage: null,
|
||||
isLogingOut: false,
|
||||
pin: null,
|
||||
};
|
||||
|
||||
export default function (state = initialState, action) {
|
||||
@ -77,11 +78,12 @@ export default function (state = initialState, action) {
|
||||
...state,
|
||||
isLogingOut: true,
|
||||
};
|
||||
// case LOGOUT_SUCCESS:
|
||||
// return {
|
||||
// ...state,
|
||||
// initialState,
|
||||
// };
|
||||
|
||||
case SET_PIN_CODE:
|
||||
return {
|
||||
...state,
|
||||
pin: action.payload,
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
|
@ -91,38 +91,39 @@ class ApplicationContainer extends Component {
|
||||
};
|
||||
|
||||
_getUserData = async () => {
|
||||
const { dispatch } = this.props;
|
||||
const { dispatch, pinCode } = this.props;
|
||||
let realmData;
|
||||
let authStatus;
|
||||
let currentUsername;
|
||||
|
||||
await getAuthStatus().then((res) => {
|
||||
authStatus = res;
|
||||
currentUsername = res.currentUsername;
|
||||
getUserData().then((userData) => {
|
||||
if (userData.length > 0) {
|
||||
realmData = userData;
|
||||
({ currentUsername } = res);
|
||||
if (res) {
|
||||
getUserData().then((userData) => {
|
||||
if (userData.length > 0) {
|
||||
realmData = userData;
|
||||
|
||||
userData.forEach((accountData) => {
|
||||
dispatch(
|
||||
addOtherAccount({ username: accountData.username }),
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
userData.forEach((accountData) => {
|
||||
dispatch(addOtherAccount({ username: accountData.username }));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (realmData) {
|
||||
await getUser(currentUsername)
|
||||
.then((accountData) => {
|
||||
.then(async (accountData) => {
|
||||
dispatch(login(true));
|
||||
|
||||
const isExistUser = await getExistUser();
|
||||
|
||||
const realmObject = realmData.filter(data => data.username === currentUsername);
|
||||
accountData.local = realmObject[0];
|
||||
[accountData.local] = realmObject;
|
||||
|
||||
dispatch(updateCurrentAccount(accountData));
|
||||
// If in dev mode pin code does not show
|
||||
if (__DEV__ === false) {
|
||||
// eslint-disable-next-line
|
||||
if (!isExistUser || !pinCode) {
|
||||
dispatch(openPinCodeModal());
|
||||
}
|
||||
this._connectNotificationServer(accountData.name);
|
||||
@ -142,12 +143,12 @@ class ApplicationContainer extends Component {
|
||||
|
||||
getSettings().then((response) => {
|
||||
if (response) {
|
||||
response.isDarkTheme && dispatch(isDarkTheme(response.isDarkTheme));
|
||||
response.language && dispatch(setLanguage(response.language));
|
||||
response.currency && dispatch(setCurrency(response.currency));
|
||||
response.notification && dispatch(isNotificationOpen(response.notification));
|
||||
response.server && dispatch(setApi(response.server));
|
||||
response.upvotePercent && dispatch(setUpvotePercent(Number(response.upvotePercent)));
|
||||
if (response.isDarkTheme) dispatch(isDarkTheme(response.isDarkTheme));
|
||||
if (response.language) dispatch(setLanguage(response.language));
|
||||
if (response.currency) dispatch(setCurrency(response.currency));
|
||||
if (response.notification) dispatch(isNotificationOpen(response.notification));
|
||||
if (response.server) dispatch(setApi(response.server));
|
||||
if (response.upvotePercent) dispatch(setUpvotePercent(Number(response.upvotePercent)));
|
||||
|
||||
this.setState({ isReady: true });
|
||||
}
|
||||
@ -158,7 +159,7 @@ class ApplicationContainer extends Component {
|
||||
const { dispatch, unreadActivityCount } = this.props;
|
||||
const ws = new WebSocket(`${Config.ACTIVITY_WEBSOCKET_URL}?user=${username}`);
|
||||
|
||||
ws.onmessage = (e) => {
|
||||
ws.onmessage = () => {
|
||||
// a message was received
|
||||
dispatch(updateUnreadActivityCount(unreadActivityCount + 1));
|
||||
};
|
||||
@ -188,9 +189,7 @@ class ApplicationContainer extends Component {
|
||||
};
|
||||
|
||||
_logout = () => {
|
||||
const {
|
||||
otherAccounts, currentAccountUsername, dispatch,
|
||||
} = this.props;
|
||||
const { otherAccounts, currentAccountUsername, dispatch } = this.props;
|
||||
|
||||
removeUserData(currentAccountUsername)
|
||||
.then(() => {
|
||||
@ -210,8 +209,7 @@ class ApplicationContainer extends Component {
|
||||
dispatch(removeOtherAccount(currentAccountUsername));
|
||||
dispatch(logoutDone());
|
||||
})
|
||||
.catch((err) => {
|
||||
alert('err');
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
@ -222,11 +220,11 @@ class ApplicationContainer extends Component {
|
||||
const realmData = getUserDataWithUsername(targetAccountUsername);
|
||||
const _currentAccount = accountData;
|
||||
_currentAccount.username = accountData.name;
|
||||
_currentAccount.local = realmData[0];
|
||||
[_currentAccount.local] = realmData;
|
||||
|
||||
dispatch(updateCurrentAccount(_currentAccount));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { selectedLanguage } = this.props;
|
||||
@ -256,6 +254,7 @@ const mapStateToProps = state => ({
|
||||
unreadActivityCount: state.account.currentAccount.unread_activity_count,
|
||||
currentAccountUsername: state.account.currentAccount.name,
|
||||
otherAccounts: state.account.otherAccounts,
|
||||
pinCode: state.account.pin,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ApplicationContainer);
|
||||
|
@ -203,7 +203,7 @@ class EditorContainer extends Component {
|
||||
};
|
||||
|
||||
_submitPost = async (fields) => {
|
||||
const { navigation, currentAccount } = this.props;
|
||||
const { navigation, currentAccount, pinCode } = this.props;
|
||||
|
||||
if (currentAccount) {
|
||||
this.setState({ isPostSending: true });
|
||||
@ -217,6 +217,7 @@ class EditorContainer extends Component {
|
||||
|
||||
await postContent(
|
||||
currentAccount,
|
||||
pinCode,
|
||||
'',
|
||||
parentPermlink,
|
||||
permlink,
|
||||
@ -237,7 +238,7 @@ class EditorContainer extends Component {
|
||||
};
|
||||
|
||||
_submitReply = async (fields) => {
|
||||
const { currentAccount } = this.props;
|
||||
const { currentAccount, pinCode } = this.props;
|
||||
|
||||
if (currentAccount) {
|
||||
this.setState({ isPostSending: true });
|
||||
@ -253,6 +254,7 @@ class EditorContainer extends Component {
|
||||
|
||||
await postContent(
|
||||
currentAccount,
|
||||
pinCode,
|
||||
parentAuthor,
|
||||
parentPermlink,
|
||||
permlink,
|
||||
@ -343,7 +345,7 @@ class EditorContainer extends Component {
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
isLoggedIn: state.application.isLoggedIn,
|
||||
|
||||
pinCode: state.account.pin,
|
||||
currentAccount: state.account.currentAccount,
|
||||
});
|
||||
|
||||
|
@ -1,11 +1,21 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Alert, Linking } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
// Services and Actions
|
||||
import { login } from '../../../providers/steem/auth';
|
||||
import { lookupAccounts } from '../../../providers/steem/dsteem';
|
||||
import {
|
||||
failedAccount,
|
||||
addOtherAccount,
|
||||
updateCurrentAccount,
|
||||
} from '../../../redux/actions/accountAction';
|
||||
import { login as loginAction, openPinCodeModal } from '../../../redux/actions/applicationActions';
|
||||
|
||||
// Middleware
|
||||
|
||||
// Constants
|
||||
import ROUTES from '../../../constants/routeNames';
|
||||
|
||||
// Utilities
|
||||
|
||||
@ -21,15 +31,61 @@ import LoginScreen from '../screen/loginScreen';
|
||||
class LoginContainer extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
|
||||
this.state = {
|
||||
isLoading: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Component Life Cycle Functions
|
||||
|
||||
// Component Functions
|
||||
|
||||
_handleOnPressLogin = (username, password) => {
|
||||
const { dispatch, setPinCodeState } = this.props;
|
||||
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
login(username, password)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
dispatch(updateCurrentAccount({ ...result }));
|
||||
dispatch(addOtherAccount({ username: result.name }));
|
||||
dispatch(openPinCodeModal());
|
||||
setPinCodeState({ navigateTo: ROUTES.DRAWER.MAIN });
|
||||
dispatch(loginAction(true));
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
// TODO: Change with global error handling
|
||||
Alert.alert('Error', err.message);
|
||||
dispatch(failedAccount(err.message));
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
};
|
||||
|
||||
_getAccountsWithUsername = async (username) => {
|
||||
const validUsers = await lookupAccounts(username);
|
||||
return validUsers;
|
||||
};
|
||||
|
||||
_handleSignUp = () => {
|
||||
Linking.openURL('https://signup.steemit.com/?ref=esteem').catch(err => alert('An error occurred', err));
|
||||
};
|
||||
|
||||
render() {
|
||||
return <LoginScreen {...this.props} />;
|
||||
const { isLoading } = this.state;
|
||||
const { navigation, setPinCodeState } = this.props;
|
||||
return (
|
||||
<LoginScreen
|
||||
handleOnPressLogin={this._handleOnPressLogin}
|
||||
getAccountsWithUsername={this._getAccountsWithUsername}
|
||||
handleSignUp={this._handleSignUp}
|
||||
isLoading={isLoading}
|
||||
navigation={navigation}
|
||||
setPinCodeState={setPinCodeState}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,30 +1,20 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import {
|
||||
View, Linking, StatusBar, Platform, Alert,
|
||||
} from 'react-native';
|
||||
import { View, StatusBar, Platform } from 'react-native';
|
||||
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
|
||||
import ScrollableTabView from '@esteemapp/react-native-scrollable-tab-view';
|
||||
import { injectIntl } from 'react-intl';
|
||||
|
||||
// Actions
|
||||
import {
|
||||
failedAccount,
|
||||
addOtherAccount,
|
||||
updateCurrentAccount,
|
||||
} from '../../../redux/actions/accountAction';
|
||||
import { login as loginAction, openPinCodeModal } from '../../../redux/actions/applicationActions';
|
||||
import SteemConnect from '../../steem-connect/steemConnect';
|
||||
|
||||
// Internal Components
|
||||
import { FormInput } from '../../../components/formInput';
|
||||
import { InformationArea } from '../../../components/informationArea';
|
||||
import { Login } from '../../../providers/steem/auth';
|
||||
import { LoginHeader } from '../../../components/loginHeader';
|
||||
import { lookupAccounts } from '../../../providers/steem/dsteem';
|
||||
import { MainButton } from '../../../components/mainButton';
|
||||
import { Modal } from '../../../components';
|
||||
import { TabBar } from '../../../components/tabBar';
|
||||
import { TextButton } from '../../../components/buttons';
|
||||
import SteemConnect from '../../steem-connect/steemConnect';
|
||||
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../constants/routeNames';
|
||||
@ -40,51 +30,26 @@ class LoginScreen extends PureComponent {
|
||||
this.state = {
|
||||
username: '',
|
||||
password: '',
|
||||
isLoading: false,
|
||||
isUsernameValid: true,
|
||||
keyboardIsOpen: false,
|
||||
isModalOpen: false,
|
||||
};
|
||||
}
|
||||
|
||||
_handleOnPressLogin = () => {
|
||||
const { dispatch, setPinCodeState } = this.props;
|
||||
const { password, username } = this.state;
|
||||
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
Login(username, password)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
dispatch(updateCurrentAccount({ ...result }));
|
||||
dispatch(addOtherAccount({ username: result.name }));
|
||||
dispatch(openPinCodeModal());
|
||||
setPinCodeState({ navigateTo: ROUTES.DRAWER.MAIN });
|
||||
dispatch(loginAction(true));
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
// TODO: Change with global error handling
|
||||
Alert.alert('Error', err.message);
|
||||
dispatch(failedAccount(err.message));
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
};
|
||||
|
||||
_handleUsernameChange = async (username) => {
|
||||
await this.setState({ username });
|
||||
const validUsers = await lookupAccounts(username);
|
||||
const isValid = validUsers.includes(username);
|
||||
|
||||
this.setState({ isUsernameValid: isValid });
|
||||
};
|
||||
|
||||
_handleOnPasswordChange = (value) => {
|
||||
this.setState({ password: value });
|
||||
};
|
||||
|
||||
_handleSignUp = () => {
|
||||
Linking.openURL('https://signup.steemit.com/?ref=esteem').catch(err => alert('An error occurred', err));
|
||||
_handleUsernameChange = (username) => {
|
||||
const { getAccountsWithUsername } = this.props;
|
||||
|
||||
this.setState({ username });
|
||||
|
||||
getAccountsWithUsername(username).then((res) => {
|
||||
const isValid = res.includes(username);
|
||||
|
||||
this.setState({ isUsernameValid: isValid });
|
||||
});
|
||||
};
|
||||
|
||||
_handleOnModalToggle = () => {
|
||||
@ -93,14 +58,16 @@ class LoginScreen extends PureComponent {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { navigation, intl, setPinCodeState } = this.props;
|
||||
const {
|
||||
navigation,
|
||||
intl,
|
||||
setPinCodeState,
|
||||
handleOnPressLogin,
|
||||
handleSignUp,
|
||||
isLoading,
|
||||
username,
|
||||
isUsernameValid,
|
||||
keyboardIsOpen,
|
||||
password,
|
||||
isModalOpen,
|
||||
} = this.props;
|
||||
const {
|
||||
username, isUsernameValid, keyboardIsOpen, password, isModalOpen,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
@ -114,7 +81,7 @@ class LoginScreen extends PureComponent {
|
||||
description={intl.formatMessage({
|
||||
id: 'login.signin_title',
|
||||
})}
|
||||
onPress={() => this._handleSignUp()}
|
||||
onPress={() => handleSignUp()}
|
||||
rightButtonText={intl.formatMessage({
|
||||
id: 'login.signup',
|
||||
})}
|
||||
@ -125,7 +92,7 @@ class LoginScreen extends PureComponent {
|
||||
renderTabBar={() => (
|
||||
<TabBar
|
||||
style={styles.tabbar}
|
||||
tabUnderlineDefaultWidth={100} // default containerWidth / (numberOfTabs * 4)
|
||||
tabUnderlineDefaultWidth={100}
|
||||
tabUnderlineScaleX={2} // default 3
|
||||
activeColor="#357ce6"
|
||||
inactiveColor="#222"
|
||||
@ -187,7 +154,7 @@ class LoginScreen extends PureComponent {
|
||||
})}
|
||||
/>
|
||||
<MainButton
|
||||
onPress={this._handleOnPressLogin}
|
||||
onPress={() => handleOnPressLogin(username, password)}
|
||||
iconName="md-person"
|
||||
iconColor="white"
|
||||
text={intl.formatMessage({
|
||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import { Alert } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import Config from 'react-native-config';
|
||||
|
||||
import {
|
||||
setUserDataWithPinCode,
|
||||
@ -12,7 +13,10 @@ import {
|
||||
// Actions & Services
|
||||
import { closePinCodeModal } from '../../../redux/actions/applicationActions';
|
||||
import { getExistUser, setExistUser, getUserDataWithUsername } from '../../../realm/realm';
|
||||
import { updateCurrentAccount } from '../../../redux/actions/accountAction';
|
||||
import { updateCurrentAccount, setPinCode as savePinCode } from '../../../redux/actions/accountAction';
|
||||
|
||||
// Utils
|
||||
import { encryptKey, decryptKey } from '../../../utils/crypto';
|
||||
|
||||
// Component
|
||||
import PinCodeScreen from '../screen/pinCodeScreen';
|
||||
@ -33,9 +37,10 @@ class PinCodeContainer extends Component {
|
||||
// TODO: these text should move to view!
|
||||
componentDidMount() {
|
||||
this._getDataFromStorage().then(() => {
|
||||
const { intl, isReset } = this.props;
|
||||
const { intl } = this.props;
|
||||
const { isExistUser } = this.state;
|
||||
if (isExistUser || !isReset) {
|
||||
|
||||
if (isExistUser) {
|
||||
this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.enter_text',
|
||||
@ -62,144 +67,203 @@ class PinCodeContainer extends Component {
|
||||
});
|
||||
});
|
||||
|
||||
_setPinCode = pin => new Promise((resolve, reject) => {
|
||||
_resetPinCode = pin => new Promise((resolve, reject) => {
|
||||
const {
|
||||
currentAccount,
|
||||
dispatch,
|
||||
accessToken,
|
||||
setWrappedComponentState,
|
||||
navigateTo,
|
||||
navigation,
|
||||
intl,
|
||||
isReset,
|
||||
} = this.props;
|
||||
const {
|
||||
isExistUser, pinCode, isOldPinVerified, oldPinCode,
|
||||
} = this.state;
|
||||
const { isOldPinVerified, oldPinCode } = this.state;
|
||||
|
||||
if (isReset) {
|
||||
const pinData = {
|
||||
pinCode: pin,
|
||||
password: currentAccount ? currentAccount.password : '',
|
||||
username: currentAccount ? currentAccount.name : '',
|
||||
accessToken,
|
||||
oldPinCode,
|
||||
};
|
||||
const pinData = {
|
||||
pinCode: pin,
|
||||
password: currentAccount ? currentAccount.password : '',
|
||||
username: currentAccount ? currentAccount.name : '',
|
||||
accessToken,
|
||||
oldPinCode,
|
||||
};
|
||||
|
||||
if (isOldPinVerified) {
|
||||
updatePinCode(pinData).then((response) => {
|
||||
const _currentAccount = currentAccount;
|
||||
_currentAccount.local = response;
|
||||
if (isOldPinVerified) {
|
||||
updatePinCode(pinData).then((response) => {
|
||||
const _currentAccount = currentAccount;
|
||||
_currentAccount.local = response;
|
||||
|
||||
dispatch(updateCurrentAccount({ ..._currentAccount }));
|
||||
dispatch(updateCurrentAccount({ ..._currentAccount }));
|
||||
this._savePinCode(pin);
|
||||
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
navigation.navigate(navigateTo);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
verifyPinCode(pinData)
|
||||
.then(() => {
|
||||
this.setState({ isOldPinVerified: true });
|
||||
this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.set_new',
|
||||
}),
|
||||
pinCode: null,
|
||||
oldPinCode: pin,
|
||||
});
|
||||
resolve();
|
||||
})
|
||||
.catch((err) => {
|
||||
Alert.alert('Warning', err.message);
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
} else if (isExistUser) {
|
||||
// If the user is exist, we are just checking to pin and navigating to home screen
|
||||
const pinData = {
|
||||
pinCode: pin,
|
||||
password: currentAccount ? currentAccount.password : '',
|
||||
username: currentAccount ? currentAccount.name : '',
|
||||
accessToken,
|
||||
};
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
navigation.navigate(navigateTo);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
verifyPinCode(pinData)
|
||||
.then((res) => {
|
||||
setWrappedComponentState(res);
|
||||
dispatch(closePinCodeModal());
|
||||
|
||||
const realmData = getUserDataWithUsername(currentAccount.name);
|
||||
const _currentAccount = currentAccount;
|
||||
_currentAccount.username = _currentAccount.name;
|
||||
_currentAccount.local = realmData[0];
|
||||
dispatch(updateCurrentAccount({ ..._currentAccount }));
|
||||
|
||||
if (navigateTo) {
|
||||
navigation.navigate(navigateTo);
|
||||
}
|
||||
.then(() => {
|
||||
this.setState({ isOldPinVerified: true });
|
||||
this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.set_new',
|
||||
}),
|
||||
pinCode: null,
|
||||
oldPinCode: pin,
|
||||
});
|
||||
resolve();
|
||||
})
|
||||
.catch((err) => {
|
||||
Alert.alert('Warning', err.message);
|
||||
reject(err);
|
||||
});
|
||||
} else if (!pinCode) {
|
||||
// If the user is logging in for the first time, the user should set to pin
|
||||
this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.write_again',
|
||||
}),
|
||||
pinCode: pin,
|
||||
});
|
||||
resolve();
|
||||
} else if (pinCode === pin) {
|
||||
const pinData = {
|
||||
pinCode: pin,
|
||||
password: currentAccount ? currentAccount.password : '',
|
||||
username: currentAccount ? currentAccount.name : '',
|
||||
accessToken,
|
||||
};
|
||||
setUserDataWithPinCode(pinData).then((response) => {
|
||||
const _currentAccount = currentAccount;
|
||||
_currentAccount.local = response;
|
||||
|
||||
dispatch(updateCurrentAccount({ ..._currentAccount }));
|
||||
|
||||
setExistUser(true).then(() => {
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
navigation.navigate(navigateTo);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.write_again',
|
||||
}),
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
informationText: 'setup screen',
|
||||
pinCode: null,
|
||||
});
|
||||
resolve();
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
_setFirstPinCode = pin => new Promise((resolve) => {
|
||||
const {
|
||||
currentAccount,
|
||||
dispatch,
|
||||
accessToken,
|
||||
navigateTo,
|
||||
navigation,
|
||||
} = this.props;
|
||||
|
||||
const pinData = {
|
||||
pinCode: pin,
|
||||
password: currentAccount ? currentAccount.password : '',
|
||||
username: currentAccount ? currentAccount.name : '',
|
||||
accessToken,
|
||||
};
|
||||
setUserDataWithPinCode(pinData).then((response) => {
|
||||
const _currentAccount = currentAccount;
|
||||
_currentAccount.local = response;
|
||||
|
||||
dispatch(updateCurrentAccount({ ..._currentAccount }));
|
||||
|
||||
setExistUser(true).then(() => {
|
||||
this._savePinCode(pin);
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
navigation.navigate(navigateTo);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
_verifyPinCode = pin => new Promise((resolve, reject) => {
|
||||
const {
|
||||
currentAccount,
|
||||
dispatch,
|
||||
accessToken,
|
||||
navigateTo,
|
||||
navigation,
|
||||
setWrappedComponentState,
|
||||
} = this.props;
|
||||
|
||||
// If the user is exist, we are just checking to pin and navigating to home screen
|
||||
const pinData = {
|
||||
pinCode: pin,
|
||||
password: currentAccount ? currentAccount.password : '',
|
||||
username: currentAccount ? currentAccount.name : '',
|
||||
accessToken,
|
||||
};
|
||||
verifyPinCode(pinData)
|
||||
.then((res) => {
|
||||
setWrappedComponentState(res);
|
||||
this._savePinCode(pin);
|
||||
|
||||
const realmData = getUserDataWithUsername(currentAccount.name);
|
||||
const _currentAccount = currentAccount;
|
||||
_currentAccount.username = _currentAccount.name;
|
||||
[_currentAccount.local] = realmData;
|
||||
dispatch(updateCurrentAccount({ ..._currentAccount }));
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
navigation.navigate(navigateTo);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
Alert.alert('Warning', err.message);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
_savePinCode = (pin) => {
|
||||
const { dispatch } = this.props;
|
||||
const encryptedPin = encryptKey(pin, Config.PIN_KEY);
|
||||
dispatch(savePinCode(encryptedPin));
|
||||
}
|
||||
|
||||
_setPinCode = async (pin, isReset) => {
|
||||
const {
|
||||
intl, currentAccount, applicationPinCode,
|
||||
} = this.props;
|
||||
const {
|
||||
isExistUser, pinCode,
|
||||
} = this.state;
|
||||
|
||||
const realmData = getUserDataWithUsername(currentAccount.name);
|
||||
const userData = realmData[0];
|
||||
|
||||
// For exist users
|
||||
if (isReset) { await this._resetPinCode(pin); return true; }
|
||||
if (isExistUser) {
|
||||
if (!userData.accessToken && !userData.masterKey && applicationPinCode) {
|
||||
const verifiedPin = decryptKey(applicationPinCode, Config.PIN_KEY);
|
||||
if (verifiedPin === pin) {
|
||||
await this._setFirstPinCode(pin);
|
||||
} else {
|
||||
Alert.alert('Warning', 'Invalid pin code, please check and try again');
|
||||
}
|
||||
} else {
|
||||
await this._verifyPinCode(pin);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// For new users
|
||||
if (pinCode === pin) { await this._setFirstPinCode(pin); return true; }
|
||||
|
||||
if (!pinCode) {
|
||||
// If the user is logging in for the first time, the user should set to pin
|
||||
await this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.write_again',
|
||||
}),
|
||||
pinCode: pin,
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
await this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.write_again',
|
||||
}),
|
||||
});
|
||||
await setTimeout(() => {
|
||||
this.setState({
|
||||
informationText: intl.formatMessage({
|
||||
id: 'pincode.set_new',
|
||||
}),
|
||||
pinCode: null,
|
||||
});
|
||||
return Promise.resolve();
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { currentAccount, intl } = this.props;
|
||||
const { currentAccount, intl, isReset } = this.props;
|
||||
const { informationText, isExistUser } = this.state;
|
||||
return (
|
||||
<PinCodeScreen
|
||||
informationText={informationText}
|
||||
setPinCode={this._setPinCode}
|
||||
setPinCode={pin => this._setPinCode(pin, isReset)}
|
||||
showForgotButton={isExistUser}
|
||||
username={currentAccount.name}
|
||||
intl={intl}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -207,6 +271,7 @@ class PinCodeContainer extends Component {
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
currentAccount: state.account.currentAccount,
|
||||
applicationPinCode: state.account.pin,
|
||||
});
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(PinCodeContainer));
|
||||
|
@ -11,6 +11,7 @@ class PinCodeScreen extends PureComponent {
|
||||
super(props);
|
||||
this.state = {
|
||||
pin: '',
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -18,10 +19,12 @@ class PinCodeScreen extends PureComponent {
|
||||
|
||||
// Component Functions
|
||||
|
||||
_handleKeyboardOnPress = (value) => {
|
||||
_handleKeyboardOnPress = async (value) => {
|
||||
const { setPinCode } = this.props;
|
||||
const { pin } = this.state;
|
||||
|
||||
const { pin, loading } = this.state;
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
if (value === 'clear') {
|
||||
this.setState({ pin: '' });
|
||||
return;
|
||||
@ -31,14 +34,15 @@ class PinCodeScreen extends PureComponent {
|
||||
if (pin.length < 3) {
|
||||
this.setState({ pin: newPin });
|
||||
} else if (pin.length === 3) {
|
||||
this.setState({ pin: newPin });
|
||||
await this.setState({ pin: newPin, loading: true });
|
||||
|
||||
setPinCode(`${pin}${value}`)
|
||||
.then(() => {
|
||||
// TODO: fix unmounted component error
|
||||
this.setState({ pin: '' });
|
||||
this.setState({ pin: '', loading: false });
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({ pin: '' });
|
||||
this.setState({ pin: '', loading: false });
|
||||
});
|
||||
} else if (pin.length > 3) {
|
||||
this.setState({ pin: `${value}` });
|
||||
@ -49,7 +53,7 @@ class PinCodeScreen extends PureComponent {
|
||||
const {
|
||||
informationText, showForgotButton, username, intl,
|
||||
} = this.props;
|
||||
const { pin } = this.state;
|
||||
const { pin, loading } = this.state;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
@ -63,7 +67,7 @@ class PinCodeScreen extends PureComponent {
|
||||
<Text style={styles.informationText}>{informationText}</Text>
|
||||
</View>
|
||||
<View style={styles.animatedView}>
|
||||
<PinAnimatedInput pin={pin} />
|
||||
<PinAnimatedInput pin={pin} loading={loading} />
|
||||
</View>
|
||||
<View style={styles.numericKeyboardView}>
|
||||
<NumericKeyboard onPress={this._handleKeyboardOnPress} />
|
||||
|
@ -62,8 +62,12 @@ class ProfileContainer extends Component {
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { navigation, currentAccount, activeBottomTab, isLoggedIn } = this.props;
|
||||
const currentUsername = currentAccount.name !== nextProps.currentAccount.name && nextProps.currentAccount.name;
|
||||
const {
|
||||
navigation, currentAccount, activeBottomTab, isLoggedIn,
|
||||
} = this.props;
|
||||
const currentUsername = currentAccount.name
|
||||
!== nextProps.currentAccount.name
|
||||
&& nextProps.currentAccount.name;
|
||||
const isParamsChange = nextProps.navigation.state
|
||||
&& navigation.state
|
||||
&& nextProps.navigation.state.params
|
||||
@ -88,10 +92,6 @@ class ProfileContainer extends Component {
|
||||
|
||||
this._loadProfile(selectedUser && selectedUser.username);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
_getReplies = async (user) => {
|
||||
@ -102,39 +102,39 @@ class ProfileContainer extends Component {
|
||||
comments: result,
|
||||
});
|
||||
})
|
||||
.catch((err) => {});
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
_handleFollowUnfollowUser = async (isFollowAction) => {
|
||||
const { username, isFollowing } = this.state;
|
||||
const { currentAccount } = this.props;
|
||||
const { currentAccount, pinCode } = this.props;
|
||||
|
||||
this.setState({
|
||||
isProfileLoading: true,
|
||||
});
|
||||
|
||||
if (isFollowAction && !isFollowing) {
|
||||
this._followUser(currentAccount, currentAccount.name, username);
|
||||
this._followUser(currentAccount, pinCode, currentAccount.name, username);
|
||||
} else {
|
||||
this._unfollowUser(currentAccount, currentAccount.name, username);
|
||||
this._unfollowUser(currentAccount, pinCode, currentAccount.name, username);
|
||||
}
|
||||
};
|
||||
|
||||
_handleMuteUnmuteUser = async (isMuteAction) => {
|
||||
const { username, isMuted } = this.state;
|
||||
const { currentAccount } = this.props;
|
||||
const { username } = this.state;
|
||||
const { currentAccount, pinCode } = this.props;
|
||||
|
||||
this.setState({
|
||||
isProfileLoading: true,
|
||||
});
|
||||
|
||||
if (isMuteAction) {
|
||||
this._muteUser(currentAccount, currentAccount.name, username);
|
||||
this._muteUser(currentAccount, pinCode, currentAccount.name, username);
|
||||
}
|
||||
};
|
||||
|
||||
_unfollowUser = (currentAccount, follower, following) => {
|
||||
unfollowUser(currentAccount, {
|
||||
_unfollowUser = (currentAccount, pinCode, follower, following) => {
|
||||
unfollowUser(currentAccount, pinCode, {
|
||||
follower,
|
||||
following,
|
||||
})
|
||||
@ -146,8 +146,8 @@ class ProfileContainer extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
_followUser = (currentAccount, follower, following) => {
|
||||
followUser(currentAccount, {
|
||||
_followUser = (currentAccount, pinCode, follower, following) => {
|
||||
followUser(currentAccount, pinCode, {
|
||||
follower,
|
||||
following,
|
||||
})
|
||||
@ -159,8 +159,8 @@ class ProfileContainer extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
_muteUser = async (currentAccount, follower, following) => {
|
||||
ignoreUser(currentAccount, {
|
||||
_muteUser = async (currentAccount, pinCode, follower, following) => {
|
||||
ignoreUser(currentAccount, pinCode, {
|
||||
follower,
|
||||
following,
|
||||
})
|
||||
@ -307,6 +307,7 @@ class ProfileContainer extends Component {
|
||||
const mapStateToProps = state => ({
|
||||
isLoggedIn: state.application.isLoggedIn,
|
||||
currentAccount: state.account.currentAccount,
|
||||
pinCode: state.account.pin,
|
||||
isDarkTheme: state.application.isDarkTheme,
|
||||
activeBottomTab: state.ui.activeBottomTab,
|
||||
});
|
||||
|
@ -85,7 +85,7 @@ class SettingsContainer extends Component {
|
||||
};
|
||||
|
||||
_handleToggleChanged = (action, actionType) => {
|
||||
const { dispatch, setPinCodeState } = this.props;
|
||||
const { dispatch } = this.props;
|
||||
|
||||
switch (actionType) {
|
||||
case 'notification':
|
||||
@ -97,11 +97,6 @@ class SettingsContainer extends Component {
|
||||
dispatch(isDarkTheme(action));
|
||||
setTheme(action);
|
||||
break;
|
||||
case 'pincode':
|
||||
// test
|
||||
dispatch(openPinCodeModal());
|
||||
setPinCodeState({ isReset: true });
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -111,8 +106,8 @@ class SettingsContainer extends Component {
|
||||
const { dispatch, setPinCodeState } = this.props;
|
||||
switch (actionType) {
|
||||
case 'pincode':
|
||||
dispatch(openPinCodeModal());
|
||||
setPinCodeState({ isReset: true });
|
||||
dispatch(openPinCodeModal());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -39,7 +39,7 @@ class SteemConnect extends PureComponent {
|
||||
if (result) {
|
||||
dispatch(updateCurrentAccount({ ...result }));
|
||||
dispatch(addOtherAccount({ username: result.name }));
|
||||
dispatch(loginAction());
|
||||
dispatch(loginAction(true));
|
||||
dispatch(openPinCodeModal());
|
||||
setPinCodeState({ accessToken, navigateTo: ROUTES.DRAWER.MAIN });
|
||||
} else {
|
||||
|
@ -1,11 +1,3 @@
|
||||
// TODO: Move all formats functions here!
|
||||
|
||||
// const imgRegex = /(https?:\/\/.*\.(?:tiff?|jpe?g|gif|png|svg|ico))/gim;
|
||||
// const postRegex = /^https?:\/\/(.*)\/(.*)\/(@[\w\.\d-]+)\/(.*)/i;
|
||||
// const youTubeRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([^& \n<]+)(?:[^ \n<]+)?/g;
|
||||
// const vimeoRegex = /(https?:\/\/)?(www\.)?(?:vimeo)\.com.*(?:videos|video|channels|)\/([\d]+)/i;
|
||||
// const dTubeRegex = /(https?:\/\/d.tube.#!\/v\/)(\w+)\/(\w+)/g;
|
||||
|
||||
export const getPostSummary = (postBody, length, isQuote) => {
|
||||
if (!postBody) {
|
||||
return '';
|
||||
@ -24,3 +16,13 @@ export const getPostSummary = (postBody, length, isQuote) => {
|
||||
}
|
||||
return isQuote ? `"${postBody}..."` : `${postBody}...`;
|
||||
};
|
||||
|
||||
export const makeCountFriendly = (value) => {
|
||||
if (!value) return value;
|
||||
if (value >= 1000000) return `${intlFormat(value / 1000000)}M`;
|
||||
if (value >= 1000) return `${intlFormat(value / 1000)}K`;
|
||||
|
||||
return intlFormat(value);
|
||||
};
|
||||
|
||||
const intlFormat = num => new Intl.NumberFormat().format(Math.round(num * 10) / 10);
|
||||
|
@ -14,7 +14,7 @@ export const parsePost = (post, currentUserName, isSummary = false) => {
|
||||
|
||||
_post.json_metadata = JSON.parse(post.json_metadata);
|
||||
_post.image = postImage(post.json_metadata, post.body);
|
||||
_post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(2);
|
||||
_post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(3);
|
||||
_post.created = getTimeFromNow(post.created);
|
||||
_post.vote_count = post.active_votes.length;
|
||||
_post.author_reputation = getReputation(post.author_reputation);
|
||||
@ -121,7 +121,7 @@ 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(3);
|
||||
comment.created = getTimeFromNow(comment.created);
|
||||
comment.vote_count = comment.active_votes.length;
|
||||
comment.author_reputation = getReputation(comment.author_reputation);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// import parseDate from './parseDate';
|
||||
import parseToken from './parseToken';
|
||||
import parseDate from './parseDate';
|
||||
import { vestsToSp } from './conversions';
|
||||
|
||||
export const getTransactionData = (transaction, walletData, formatNumber) => {
|
||||
@ -14,7 +14,7 @@ export const getTransactionData = (transaction, walletData, formatNumber) => {
|
||||
const opData = transaction[1].op[1];
|
||||
const { timestamp } = transaction[1];
|
||||
|
||||
result.transDate = parseDate(timestamp);
|
||||
result.transDate = timestamp;
|
||||
result.icon = 'local-activity';
|
||||
|
||||
switch (result.opName) {
|
||||
@ -85,7 +85,7 @@ export const getTransactionData = (transaction, walletData, formatNumber) => {
|
||||
result.value = `${formatNumber(vestsToSp(opVestingShares, walletData.steemPerMVests), {
|
||||
minimumFractionDigits: 3,
|
||||
})} SP`;
|
||||
result.icon = 'money';
|
||||
result.icon = 'attach-money';
|
||||
result.details = `@${acc}`;
|
||||
break;
|
||||
case 'fill_order':
|
||||
|
Loading…
Reference in New Issue
Block a user