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