changed global variable with & dropdown redesign done

This commit is contained in:
ue 2018-10-01 20:22:12 +03:00
commit c82250b6e8
40 changed files with 1620 additions and 1710 deletions

8
package-lock.json generated
View File

@ -8973,14 +8973,6 @@
"prop-types": "^15.5.10"
}
},
"react-native-theming": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/react-native-theming/-/react-native-theming-1.0.16.tgz",
"integrity": "sha512-f8P7F3yKW9i+PmsmZo98V933Ggsu6YpsBw8pvNEAOENnNqbFmeDL6K+89F0WmkpF6bSs/qqSbyGUWKvCgNhBkw==",
"requires": {
"prop-types": "^15.6.0"
}
},
"react-native-vector-icons": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-4.6.0.tgz",

View File

@ -33,7 +33,6 @@
"react-native-navigation": "^2.0.2519",
"react-native-restart": "0.0.6",
"react-native-slider": "^0.11.0",
"react-native-theming": "^1.0.16",
"react-native-vector-icons": "^4.6.0",
"react-redux": "^5.0.7",
"realm": "^2.15.3",

View File

@ -1,3 +1,3 @@
import GreetingHeaderButton from "./views/greetingHeaderButtonView";
import TextButton from "./views/textButtonView";
export { GreetingHeaderButton };
export { TextButton };

View File

@ -2,6 +2,8 @@ import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
button: {
flex: 1,
flexDirection: "row",
width: 54,
backgroundColor: "transparent",
height: 19,

View File

@ -1,9 +1,9 @@
import React, { Fragment } from "react";
import { TouchableWithoutFeedback, Text, View } from "react-native";
import styles from "./greetingHeaderButtonStyles";
import styles from "./textButtonStyles";
const GreetingHeaderButtonView = ({ text, onPress, style }) => (
const TextButtonView = ({ text, onPress, style }) => (
<Fragment>
<TouchableWithoutFeedback
style={[styles.button, style]}
@ -16,4 +16,4 @@ const GreetingHeaderButtonView = ({ text, onPress, style }) => (
</Fragment>
);
export default GreetingHeaderButtonView;
export default TextButtonView;

View File

@ -13,7 +13,7 @@ export default EStyleSheet.create({
title: {
alignSelf: "flex-start",
fontSize: 14,
color: "#788187",
color: "$primaryGray",
fontWeight: "bold",
marginLeft: 26,
},

View File

@ -8,10 +8,9 @@ export default EStyleSheet.create({
alignSelf: "flex-start",
height: 35,
},
dropdownWrapper: {},
dropdownText: {
fontSize: 9,
color: "#788187",
color: "$primaryGray",
marginLeft: 25,
},
dropdownIcon: {
@ -37,7 +36,7 @@ export default EStyleSheet.create({
},
dropdownText: {
fontSize: 9,
color: "#788187",
color: "$primaryGray",
padding: 5,
borderColor: "#e7e7e7",
},
@ -51,7 +50,7 @@ export default EStyleSheet.create({
buttonText: {
fontSize: 9,
alignSelf: "center",
color: "#788187",
color: "$primaryGray",
fontWeight: "normal",
},
rowWrapper: {
@ -70,16 +69,17 @@ export default EStyleSheet.create({
borderRadius: 20,
height: 35,
backgroundColor: "$primaryBlue",
marginLeft: 5,
width: "$deviceWidth / 3.2",
alignSelf: "flex-start",
paddingLeft: 11,
paddingRight: 11,
marginLeft: 20,
},
highlightedRowText: {
textAlign: "center",
color: "#fff",
color: "$white",
fontWeight: "bold",
},
rowText: {
fontSize: 10,
color: "#788187",
fontSize: 9,
color: "$primaryGray",
},
});

View File

@ -12,7 +12,7 @@ import Ionicons from "react-native-vector-icons/Ionicons";
// Styles
import styles from "./dropdownButtonStyles";
/* Props
/* Props TODO: Fill all description
* ------------------------------------------------
* @prop { string } defaultText - Description....
* @prop { string } iconName - Description....
@ -35,13 +35,6 @@ const renderDropdownRow = (rowData, rowID, highlighted) => {
);
};
// const _dropdown_2_renderButtonText = rowData => {
// const { name, age } = rowData;
// return `${name} - ${age}`;
// };
const renderDropdownSeperator = () => null;
const DropdownButtonView = ({
defaultText,
iconName,
@ -50,24 +43,21 @@ const DropdownButtonView = ({
defaultIndex,
}) => (
<View style={styles.container}>
<View style={styles.dropdownWrapper}>
<ModalDropdown
style={styles.button}
textStyle={styles.buttonText}
dropdownStyle={[styles.dropdown, { height: 35 * (options.length + 1) }]}
dropdownTextStyle={styles.dropdownText}
dropdownTextHighlightStyle={styles.dropdownTextHighlight}
options={options}
onSelect={e => onSelect && onSelect(e)}
defaultIndex={defaultIndex}
defaultValue={defaultText}
// renderButtonText={rowData => _dropdown_2_renderButtonText(rowData)}
renderSeparator={() => renderDropdownSeperator()}
renderRow={(rowData, rowID, highlighted) =>
renderDropdownRow(rowData, rowID, highlighted)
}
/>
</View>
<ModalDropdown
style={styles.button}
textStyle={styles.buttonText}
dropdownStyle={[styles.dropdown, { height: 35 * (options.length + 1) }]}
dropdownTextStyle={styles.dropdownText}
dropdownTextHighlightStyle={styles.dropdownTextHighlight}
options={options}
onSelect={e => onSelect && onSelect(e)}
defaultIndex={defaultIndex}
defaultValue={defaultText}
renderSeparator={() => null}
renderRow={(rowData, rowID, highlighted) =>
renderDropdownRow(rowData, rowID, highlighted)
}
/>
<View style={styles.iconWrapper}>
<Ionicons
style={styles.dropdownIcon}

View File

@ -29,27 +29,34 @@ class FormInputView extends Component {
this.state = {
value: "",
inputBorderColor: "#c1c5c7",
isValid: true,
};
}
// Component Life Cycles
componentWillReceiveProps(nextProps) {
const { isValid } = this.props;
if (nextProps.isValid !== isValid) {
this.setState({ isValid: nextProps.isValid });
}
}
// Component Functions
_handleOnChange = value => {
const { onChange } = this.props;
value && this.setState({ value });
onChange && value && onChange(value);
this.setState({ value });
onChange && onChange(value);
};
render() {
const { inputBorderColor, value } = this.state;
const { inputBorderColor, isValid, value } = this.state;
const {
placeholder,
type,
isFirstImage,
isEditable,
isValid,
leftIconName,
rightIconName,
secureTextEntry,

View File

@ -15,6 +15,6 @@ export default EStyleSheet.create({
infoText: {
flex: 0.875,
fontSize: 12,
color: "#788187",
color: "$primaryGray",
},
});

View File

@ -14,7 +14,7 @@ export default EStyleSheet.create({
},
description: {
textAlignVertical: "center",
color: "#788187",
color: "$primaryGray",
fontSize: 14,
fontWeight: "400",
},
@ -22,7 +22,7 @@ export default EStyleSheet.create({
textAlignVertical: "center",
fontSize: 20,
fontWeight: "bold",
color: "#788187",
color: "$primaryGray",
marginBottom: 16,
},
mascot: {

View File

@ -3,7 +3,7 @@ import { View, Text, Image } from "react-native";
// Constants
// Components
import { GreetingHeaderButton } from "../../buttons";
import { TextButton } from "../../buttons";
import { LineBreak } from "../../basicUIElements";
// Styles
// eslint-disable-next-line
@ -36,7 +36,7 @@ class LoginHeaderView extends Component {
source={require("../../../assets/esteem.png")}
/>
<View style={styles.headerButton}>
<GreetingHeaderButton onPress={onPress} text="Sign up" />
<TextButton onPress={onPress} text="Sign up" />
</View>
</View>
{!isKeyboardOpen && (

View File

@ -45,4 +45,7 @@ export default EStyleSheet.create({
width: 20,
height: 20,
},
disableTouchable: {
backgroundColor: "#c1c5c7",
},
});

View File

@ -18,28 +18,41 @@ import styles from "./mainButtonStyles";
class MainButton extends Component {
/* Props
* ------------------------------------------------
* @prop { string } isLoading - TODO:
* @prop { string } text - TODO:
* @prop { boolean } secondText - TODO:
* @prop { boolean } iconColor - TODO:
* @prop { string } isLoading - TODO:
* @prop { string } text - TODO:
* @prop { boolean } secondText - TODO:
* @prop { boolean } iconColor - TODO:
* @prop { boolean } iconName - TODO:
* @prop { boolean } isDisable - TODO:
* @prop { boolean } isDisable - TODO:
*
*
*/
constructor(props) {
super(props);
this.state = {};
this.state = {
isDisable: !props.isLoading && props.isDisable,
};
}
// Component Life Cycles
componentWillReceiveProps(nextProps) {
const { isLoading, isDisable } = this.props;
if (
nextProps.isLoading !== isLoading ||
nextProps.isDisable !== isDisable
) {
this.setState({
isDisable: !nextProps.isLoading && nextProps.isDisable,
});
}
}
// Component Functions
_handleOnPress = () => {
const { onPress, isDisable, source } = this.props;
const { onPress } = this.props;
onPress && !isDisable && onPress();
onPress && onPress();
};
_getBody = () => {
@ -75,13 +88,15 @@ class MainButton extends Component {
};
render() {
const { wrapperStyle, isDisable } = this.props;
const { wrapperStyle } = this.props;
const { isDisable } = this.state;
return (
<View style={wrapperStyle}>
<TouchableOpacity
disabled={isDisable}
onPress={() => this._handleOnPress()}
style={styles.touchable}
style={[styles.touchable, isDisable && styles.disableTouchable]}
>
<View style={styles.body}>{this._getBody()}</View>
</TouchableOpacity>

View File

@ -40,7 +40,7 @@ export default EStyleSheet.create({
fontWeight: "bold",
},
title: {
color: "#788187",
color: "$primaryGray",
},
description: {
color: "#3c4449",
@ -48,7 +48,7 @@ export default EStyleSheet.create({
fontWeight: "500",
},
scrollView: {
height: "$deviceHeight / 1.25",
height: "$deviceHeight / 1.35",
},
isNewNotification: {
backgroundColor: "#eaf2fc",

View File

@ -1,12 +1,12 @@
import React, { Component } from "react";
import {
Text,
View,
Dimensions,
TextInput,
FlatList,
Image,
ActivityIndicator,
Text,
View,
Dimensions,
TextInput,
FlatList,
Image,
ActivityIndicator,
} from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
import { Navigation } from "react-native-navigation";
@ -14,202 +14,200 @@ import { lookupAccounts } from "../../providers/steem/dsteem";
import { SEARCH_API_TOKEN } from "../../../config";
export default class Search extends Component {
constructor() {
super();
this.handleSearch = this.handleSearch.bind(this);
this.state = {
text: "",
scroll_id: "",
posts: [],
users: [],
loading: false,
};
}
closeSearch = () => {
Navigation.dismissOverlay(this.props.componentId);
constructor() {
super();
this.handleSearch = this.handleSearch.bind(this);
this.state = {
text: "",
scroll_id: "",
posts: [],
users: [],
loading: false,
};
}
handleSearch = async text => {
if (text.length < 3) return;
let users;
let posts;
let scroll_id;
closeSearch = () => {
Navigation.dismissOverlay(this.props.componentId);
};
await this.setState({
loading: true,
text: text,
});
handleSearch = async text => {
if (text.length < 3) return;
let users;
let posts;
let scroll_id;
users = await lookupAccounts(text);
await this.setState({
loading: true,
text: text,
});
await this.setState({ users: users });
users = await lookupAccounts(text);
let data = { q: text };
await fetch("https://api.search.esteem.app/search", {
method: "POST",
headers: {
// TODO: Create a config file for authorization
await this.setState({ users: users });
Authorization: SEARCH_API_TOKEN,
"Content-Type": "application/json",
},
body: JSON.stringify(data),
})
.then(result => result.json())
.then(result => {
posts = result.results;
scroll_id = result.scroll_id;
})
.catch(error => {
console.log(error);
});
let data = { q: text };
await fetch("https://api.search.esteem.app/search", {
method: "POST",
headers: {
// TODO: Create a config file for authorization
await this.setState({ loading: false });
Authorization: SEARCH_API_TOKEN,
"Content-Type": "application/json",
},
body: JSON.stringify(data),
})
.then(result => result.json())
.then(result => {
posts = result.results;
scroll_id = result.scroll_id;
})
.catch(error => {
console.log(error);
});
await this.setState({
posts: posts,
scroll_id: scroll_id,
});
};
await this.setState({ loading: false });
render() {
return (
<View
await this.setState({
posts: posts,
scroll_id: scroll_id,
});
};
render() {
return (
<View
style={{
backgroundColor: "rgba(0, 0, 0, 0.8)",
height: Dimensions.get("window").height,
paddingTop: 25,
flex: 1,
}}
>
<View
style={{
flexDirection: "row",
borderRadius: 8,
backgroundColor: "#f5f5f5",
paddingLeft: 10,
marginHorizontal: 10,
}}
>
<Ionicons
name="md-search"
style={{
flex: 0.1,
fontSize: 18,
top: 10,
color: "$primaryGray",
}}
/>
<TextInput
style={{ flex: 0.9, height: 40 }}
autoCapitalize="none"
onChangeText={text => this.handleSearch(text)}
value={this.state.text}
/>
<Ionicons
onPress={this.closeSearch}
name="md-close-circle"
style={{
flex: 0.1,
fontSize: 15,
top: 12.5,
color: "#c1c5c7",
}}
/>
</View>
<View
style={{
paddingTop: 20,
flex: 1,
marginTop: 20,
}}
>
<FlatList
data={this.state.users}
showsVerticalScrollIndicator={false}
horizontal={true}
renderItem={({ item }) => (
<View style={{ margin: 10, flexDirection: "column" }}>
<Image
style={{
width: 50,
height: 50,
borderRadius: 25,
borderWidth: 1,
borderColor: "gray",
}}
source={{
uri: `https://steemitimages.com/u/${item}/avatar/small`,
}}
/>
<Text
style={{
color: "#fff",
fontWeight: "500",
fontSize: 10,
overflow: "scroll",
}}
>
@{item}
</Text>
</View>
)}
keyExtractor={(post, index) => index.toString()}
removeClippedSubviews={true}
onEndThreshold={0}
/>
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
// TODO: Create a component to list search results
<View
style={{
backgroundColor: "rgba(0, 0, 0, 0.8)",
height: Dimensions.get("window").height,
paddingTop: 25,
flex: 1,
backgroundColor: "white",
borderRadius: 5,
marginHorizontal: 10,
marginVertical: 5,
}}
>
>
<View
style={{
flexDirection: "row",
borderRadius: 8,
backgroundColor: "#f5f5f5",
paddingLeft: 10,
marginHorizontal: 10,
}}
style={{
flexDirection: "row",
}}
>
<Ionicons
name="md-search"
style={{
flex: 0.1,
fontSize: 18,
top: 10,
color: "#788187",
}}
/>
<TextInput
style={{ flex: 0.9, height: 40 }}
autoCapitalize="none"
onChangeText={text => this.handleSearch(text)}
value={this.state.text}
/>
<Ionicons
onPress={this.closeSearch}
name="md-close-circle"
style={{
flex: 0.1,
fontSize: 15,
top: 12.5,
color: "#c1c5c7",
}}
/>
</View>
<View
style={{
paddingTop: 20,
flex: 1,
marginTop: 20,
<Image
source={{
uri: `https://steemitimages.com/u/${
item.author
}/avatar/small`,
}}
>
<FlatList
data={this.state.users}
showsVerticalScrollIndicator={false}
horizontal={true}
renderItem={({ item }) => (
<View
style={{ margin: 10, flexDirection: "column" }}
>
<Image
style={{
width: 50,
height: 50,
borderRadius: 25,
borderWidth: 1,
borderColor: "gray",
}}
source={{
uri: `https://steemitimages.com/u/${item}/avatar/small`,
}}
/>
<Text
style={{
color: "#fff",
fontWeight: "500",
fontSize: 10,
overflow: "scroll",
}}
>
@{item}
</Text>
</View>
)}
keyExtractor={(post, index) => index.toString()}
removeClippedSubviews={true}
onEndThreshold={0}
/>
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
// TODO: Create a component to list search results
<View
style={{
backgroundColor: "white",
borderRadius: 5,
marginHorizontal: 10,
marginVertical: 5,
}}
>
<View
style={{
flexDirection: "row",
}}
>
<Image
source={{
uri: `https://steemitimages.com/u/${
item.author
}/avatar/small`,
}}
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 1,
borderColor: "gray",
}}
/>
<Text>
{item.author} ({item.author_rep})
</Text>
</View>
</View>
)}
keyExtractor={(post, index) => index.toString()}
removeClippedSubviews={true}
onEndThreshold={0}
initialNumToRender={20}
/>
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 1,
borderColor: "gray",
}}
/>
<Text>
{item.author} ({item.author_rep})
</Text>
</View>
</View>
);
}
</View>
)}
keyExtractor={(post, index) => index.toString()}
removeClippedSubviews={true}
onEndThreshold={0}
initialNumToRender={20}
/>
</View>
</View>
);
}
}

View File

@ -12,13 +12,13 @@ let medianPrice = null;
let client = new Client("https://api.steemit.com");
getClient = async () => {
let server = await AsyncStorage.getItem("server");
let server = await AsyncStorage.getItem("server");
if (server === null || server === undefined || server === "") {
client = new Client("https://api.steemit.com");
} else {
client = new Client(`${server}`);
}
if (server === null || server === undefined || server === "") {
client = new Client("https://api.steemit.com");
} else {
client = new Client(`${server}`);
}
};
getClient();
@ -27,14 +27,14 @@ getClient();
* @param user username
*/
export const getAccount = user => {
return new Promise((resolve, reject) => {
try {
let account = client.database.getAccounts([user]);
resolve(account);
} catch (error) {
reject(error);
}
});
return new Promise((resolve, reject) => {
try {
let account = client.database.getAccounts([user]);
resolve(account);
} catch (error) {
reject(error);
}
});
};
/**
@ -42,43 +42,43 @@ export const getAccount = user => {
* @param user username
*/
export const getUser = async user => {
try {
let account = await client.database.getAccounts([user]);
// get global properties to calculate Steem Power
let global_properties = await client.database.getDynamicGlobalProperties();
try {
let account = await client.database.getAccounts([user]);
// get global properties to calculate Steem Power
let global_properties = await client.database.getDynamicGlobalProperties();
// calculate Steem Power (own, received, delegated)
account[0].steem_power = vestToSteem(
account[0].vesting_shares,
global_properties.total_vesting_shares,
global_properties.total_vesting_fund_steem
).toFixed(0);
account[0].received_steem_power = vestToSteem(
account[0].received_vesting_shares,
global_properties.total_vesting_shares,
global_properties.total_vesting_fund_steem
).toFixed(0);
account[0].delegated_steem_power = vestToSteem(
account[0].delegated_vesting_shares,
global_properties.total_vesting_shares,
global_properties.total_vesting_fund_steem
).toFixed(0);
// calculate Steem Power (own, received, delegated)
account[0].steem_power = vestToSteem(
account[0].vesting_shares,
global_properties.total_vesting_shares,
global_properties.total_vesting_fund_steem
).toFixed(0);
account[0].received_steem_power = vestToSteem(
account[0].received_vesting_shares,
global_properties.total_vesting_shares,
global_properties.total_vesting_fund_steem
).toFixed(0);
account[0].delegated_steem_power = vestToSteem(
account[0].delegated_vesting_shares,
global_properties.total_vesting_shares,
global_properties.total_vesting_fund_steem
).toFixed(0);
return account[0];
} catch (error) {
return error;
}
return account[0];
} catch (error) {
return error;
}
};
export const vestToSteem = (
vestingShares,
totalVestingShares,
totalVestingFundSteem
vestingShares,
totalVestingShares,
totalVestingFundSteem
) => {
return (
parseFloat(totalVestingFundSteem) *
(parseFloat(vestingShares) / parseFloat(totalVestingShares))
);
return (
parseFloat(totalVestingFundSteem) *
(parseFloat(vestingShares) / parseFloat(totalVestingShares))
);
};
/**
@ -86,16 +86,16 @@ export const vestToSteem = (
* @param user username
*/
export const getFollows = user => {
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_follow_count", [user])
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_follow_count", [user])
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
};
/**
@ -104,16 +104,16 @@ export const getFollows = user => {
* TODO: Pagination
*/
export const getFollowers = user => {
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_followers", [user, "", "blog", 50])
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_followers", [user, "", "blog", 50])
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
};
/**
@ -122,33 +122,33 @@ export const getFollowers = user => {
* TODO: Pagination
*/
export const getFollowing = user => {
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_following", [user, "", "blog", 50])
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_following", [user, "", "blog", 50])
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
};
export const isFolllowing = (author, user) => {
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_followers", [author, user, "blog", 10])
.then(result => {
if (result[0].follower === user) {
resolve(true);
} else {
resolve(false);
}
})
.catch(err => {
reject(err);
});
});
return new Promise((resolve, reject) => {
client
.call("follow_api", "get_followers", [author, user, "blog", 10])
.then(result => {
if (result[0].follower === user) {
resolve(true);
} else {
resolve(false);
}
})
.catch(err => {
reject(err);
});
});
};
/**
@ -157,26 +157,26 @@ export const isFolllowing = (author, user) => {
* @param query tag, limit, start_author?, start_permalink?
*/
export const getPosts = async (by, query, user) => {
try {
let posts = await client.database.getDiscussions(by, query);
console.log("comments");
console.log(posts);
posts = await parsePosts(posts, user);
return posts;
} catch (error) {
return error;
}
try {
let posts = await client.database.getDiscussions(by, query);
console.log("comments");
console.log(posts);
posts = await parsePosts(posts, user);
return posts;
} catch (error) {
return error;
}
};
export const getUserComments = async query => {
try {
let comments = await client.database.getDiscussions("comments", query);
comments = parseComments(comments);
console.log(comments);
return comments;
} catch (error) {
return error;
}
try {
let comments = await client.database.getDiscussions("comments", query);
comments = parseComments(comments);
console.log(comments);
return comments;
} catch (error) {
return error;
}
};
/**
@ -185,14 +185,14 @@ export const getUserComments = async query => {
* @param permlink post permlink
*/
export const getPost = (user, permlink) => {
return new Promise((resolve, reject) => {
try {
let post = client.database.call("get_content", [user, permlink]);
resolve(post);
} catch (error) {
reject(error);
}
});
return new Promise((resolve, reject) => {
try {
let post = client.database.call("get_content", [user, permlink]);
resolve(post);
} catch (error) {
reject(error);
}
});
};
/**
@ -201,20 +201,20 @@ export const getPost = (user, permlink) => {
* @param permlink post permlink
*/
export const getComments = (user, permlink) => {
let comments;
return new Promise((resolve, reject) => {
client.database
.call("get_content_replies", [user, permlink])
.then(result => {
comments = parseComments(result);
})
.then(() => {
resolve(comments);
})
.catch(error => {
reject(error);
});
});
let comments;
return new Promise((resolve, reject) => {
client.database
.call("get_content_replies", [user, permlink])
.then(result => {
comments = parseComments(result);
})
.then(() => {
resolve(comments);
})
.catch(error => {
reject(error);
});
});
};
/**
@ -223,17 +223,17 @@ export const getComments = (user, permlink) => {
* @param permlink post permlink
*/
export const getPostWithComments = async (user, permlink) => {
let post;
let comments;
let post;
let comments;
await getPost(user, permlink).then(result => {
post = result;
});
await getComments(user, permlink).then(result => {
comments = result;
});
await getPost(user, permlink).then(result => {
post = result;
});
await getComments(user, permlink).then(result => {
comments = result;
});
return [post, comments];
return [post, comments];
};
/**
@ -242,43 +242,43 @@ export const getPostWithComments = async (user, permlink) => {
* @param postingKey private posting key
*/
export const upvote = (vote, postingKey) => {
let key = PrivateKey.fromString(postingKey);
return new Promise((resolve, reject) => {
client.broadcast
.vote(vote, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
let key = PrivateKey.fromString(postingKey);
return new Promise((resolve, reject) => {
client.broadcast
.vote(vote, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
};
/**
* @method upvoteAmount estimate upvote amount
*/
export const upvoteAmount = async input => {
if (rewardFund == null || medianPrice == null) {
rewardFund = await client.database.call("get_reward_fund", ["post"]);
if (!rewardFund || !medianPrice) {
rewardFund = await client.database.call("get_reward_fund", ["post"]);
await client.database
.getCurrentMedianHistoryPrice()
.then(res => {
medianPrice = res;
})
.catch(err => {
console.log(err);
});
}
await client.database
.getCurrentMedianHistoryPrice()
.then(res => {
medianPrice = res;
})
.catch(err => {
console.log(err);
});
}
let estimated =
(input / parseFloat(rewardFund.recent_claims)) *
parseFloat(rewardFund.reward_balance) *
parseFloat(medianPrice.base);
return estimated;
let estimated =
(input / parseFloat(rewardFund.recent_claims)) *
parseFloat(rewardFund.reward_balance) *
parseFloat(medianPrice.base);
return estimated;
};
/**
@ -287,258 +287,255 @@ export const upvoteAmount = async input => {
* @param PrivateKey Private posting key
*/
export const postComment = (comment, postingKey) => {
let key = PrivateKey.fromString(postingKey);
return new Promise((resolve, reject) => {
try {
client.broadcast.comment(comment, key).then(result => {
resolve(result);
});
} catch (error) {
console.log(error);
reject(error);
}
});
let key = PrivateKey.fromString(postingKey);
return new Promise((resolve, reject) => {
try {
client.broadcast.comment(comment, key).then(result => {
resolve(result);
});
} catch (error) {
console.log(error);
reject(error);
}
});
};
export const transferToken = (data, activeKey) => {
let key = PrivateKey.fromString(activeKey);
return new Promise((resolve, reject) => {
client.broadcast
.transfer(data, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
let key = PrivateKey.fromString(activeKey);
return new Promise((resolve, reject) => {
client.broadcast
.transfer(data, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
};
export const followUser = (data, postingKey) => {
let key;
try {
key = PrivateKey.fromString(postingKey);
} catch (error) {
console.log(error);
}
let json = {
id: "follow",
json: JSON.stringify([
"follow",
{
follower: `${data.follower}`,
following: `${data.following}`,
what: ["blog"],
},
]),
required_auths: [],
required_posting_auths: [`${data.follower}`],
};
let key;
try {
key = PrivateKey.fromString(postingKey);
} catch (error) {
console.log(error);
}
let json = {
id: "follow",
json: JSON.stringify([
"follow",
{
follower: `${data.follower}`,
following: `${data.following}`,
what: ["blog"],
},
]),
required_auths: [],
required_posting_auths: [`${data.follower}`],
};
return new Promise((resolve, reject) => {
client.broadcast
.json(json, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
return new Promise((resolve, reject) => {
client.broadcast
.json(json, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
};
export const unfollowUser = (data, postingKey) => {
let key;
try {
key = PrivateKey.fromString(postingKey);
} catch (error) {
console.log(error);
}
let json = {
id: "follow",
json: JSON.stringify([
"follow",
{
follower: `${data.follower}`,
following: `${data.following}`,
what: [""],
},
]),
required_auths: [],
required_posting_auths: [`${data.follower}`],
};
let key;
try {
key = PrivateKey.fromString(postingKey);
} catch (error) {
console.log(error);
}
let json = {
id: "follow",
json: JSON.stringify([
"follow",
{
follower: `${data.follower}`,
following: `${data.following}`,
what: [""],
},
]),
required_auths: [],
required_posting_auths: [`${data.follower}`],
};
return new Promise((resolve, reject) => {
client.broadcast
.json(json, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
return new Promise((resolve, reject) => {
client.broadcast
.json(json, key)
.then(result => {
console.log(result);
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
};
export const delegate = (data, activeKey) => {
let key;
try {
key = PrivateKey.fromString(activeKey);
} catch (error) {
console.log(error);
}
let key;
try {
key = PrivateKey.fromString(activeKey);
} catch (error) {
console.log(error);
}
return new Promise((resolve, reject) => {
client.broadcast
.delegateVestingShares(data, key)
.then(result => {
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
return new Promise((resolve, reject) => {
client.broadcast
.delegateVestingShares(data, key)
.then(result => {
resolve(result);
})
.catch(err => {
console.log(err);
reject(err);
});
});
};
export const globalProps = async () => {
try {
let global_properties = await client.database.getDynamicGlobalProperties();
return global_properties;
} catch (error) {
console.log(error);
return error;
}
try {
let global_properties = await client.database.getDynamicGlobalProperties();
return global_properties;
} catch (error) {
console.log(error);
return error;
}
};
export const transferToVesting = (data, activeKey) => {
let key;
try {
key = PrivateKey.fromString(activeKey);
console.log(key);
} catch (error) {
let key;
try {
key = PrivateKey.fromString(activeKey);
console.log(key);
} catch (error) {
console.log(error);
}
const op = [
"transfer_to_vesting",
{
from: data.from,
to: data.to,
amount: data.amount,
},
];
return new Promise((resolve, reject) => {
client.broadcast
.sendOperations([op], key)
.then(result => {
resolve(result);
})
.catch(error => {
console.log(error);
}
const op = [
"transfer_to_vesting",
{
from: data.from,
to: data.to,
amount: data.amount,
},
];
return new Promise((resolve, reject) => {
client.broadcast
.sendOperations([op], key)
.then(result => {
resolve(result);
})
.catch(error => {
console.log(error);
reject(error);
});
});
reject(error);
});
});
};
export const withdrawVesting = (data, activeKey) => {
let key;
try {
key = PrivateKey.fromString(activeKey);
console.log(key);
} catch (error) {
let key;
try {
key = PrivateKey.fromString(activeKey);
console.log(key);
} catch (error) {
console.log(error);
}
const op = [
"withdraw_vesting",
{
account: data.account,
vesting_shares: data.vesting_shares,
},
];
return new Promise((resolve, reject) => {
client.broadcast
.sendOperations([op], key)
.then(result => {
resolve(result);
})
.catch(error => {
console.log(error);
}
const op = [
"withdraw_vesting",
{
account: data.account,
vesting_shares: data.vesting_shares,
},
];
return new Promise((resolve, reject) => {
client.broadcast
.sendOperations([op], key)
.then(result => {
resolve(result);
})
.catch(error => {
console.log(error);
reject(error);
});
});
reject(error);
});
});
};
export const postContent = (data, postingKey) => {
let key;
let key;
try {
key = PrivateKey.fromString(postingKey);
} catch (error) {
try {
key = PrivateKey.fromString(postingKey);
} catch (error) {
console.log(error);
}
let post = {
author: data.author,
body: data.body,
parent_author: "",
parent_permlink: data.tags[0],
permlink: data.permlink,
title: data.title,
json_metadata: JSON.stringify({
app: "esteem/2.0.0-mobile",
community: "esteem.app",
tags: data.tags,
}),
};
let op = {
author: data.author,
permlink: data.permlink,
max_accepted_payout: "1000000.000 SBD",
percent_steem_dollars: 10000,
allow_votes: true,
allow_curation_rewards: true,
extensions: [
[
0,
{
beneficiaries: [{ account: "esteemapp", weight: 1000 }],
},
],
],
};
return new Promise((resolve, reject) => {
client.broadcast
.commentWithOptions(post, op, key)
.then(result => {
resolve(result);
})
.catch(error => {
console.log(error);
}
let post = {
author: data.author,
body: data.body,
parent_author: "",
parent_permlink: data.tags[0],
permlink: data.permlink,
title: data.title,
json_metadata: JSON.stringify({
app: "esteem/2.0.0-mobile",
community: "esteem.app",
tags: data.tags,
}),
};
let op = {
author: data.author,
permlink: data.permlink,
max_accepted_payout: "1000000.000 SBD",
percent_steem_dollars: 10000,
allow_votes: true,
allow_curation_rewards: true,
extensions: [
[
0,
{
beneficiaries: [{ account: "esteemapp", weight: 1000 }],
},
],
],
};
return new Promise((resolve, reject) => {
client.broadcast
.commentWithOptions(post, op, key)
.then(result => {
resolve(result);
})
.catch(error => {
console.log(error);
reject(error);
});
});
reject(error);
});
});
};
export const lookupAccounts = async username => {
try {
let users = await client.database.call("lookup_accounts", [
username,
20,
]);
return users;
} catch (error) {
throw error;
}
try {
let users = await client.database.call("lookup_accounts", [username, 20]);
return users;
} catch (error) {
throw error;
}
};

View File

@ -22,15 +22,11 @@ import { PostCard } from "../../../components/postCard";
import Comment from "../../../components/comment/comment";
// TODO: Make utils for all using moment.
import moment from "moment";
//import Icon from "react-native-vector-icons/FontAwesome";
import { getTimeFromNow } from "../../../utils/time";
// Styles
import styles from "./authorStyles";
//import themes from "../../styles/themes";
import {
followUser,
unfollowUser,
@ -114,7 +110,7 @@ class AuthorScreen extends Component {
isLoggedIn = res;
});
if (isLoggedIn == true) {
if (isLoggedIn) {
getUserData()
.then(res => {
user = Array.from(res);
@ -184,7 +180,7 @@ class AuthorScreen extends Component {
};
getMore = () => {
if (this.state.loading == true) {
if (this.state.loading) {
return false;
} else {
getPosts(
@ -299,7 +295,7 @@ class AuthorScreen extends Component {
};
renderFooter = () => {
if (!this.state.loading == false) return null;
if (this.state.loading) return null;
return (
<View style={{ marginVertical: 20 }}>
@ -343,7 +339,7 @@ class AuthorScreen extends Component {
{this.state.author.name}
</Text>
<Text>{this.state.about.about}</Text>
{this.state.isFolllowing == true ? (
{this.state.isFolllowing ? (
<Button
onPress={() => {
this.unfollow();
@ -421,10 +417,7 @@ class AuthorScreen extends Component {
}}
name="md-calendar"
/>
{moment
.utc(this.state.author.created)
.local()
.fromNow()}
{getTimeFromNow(this.state.author.created)}
</Text>
</View>
</CardItem>
@ -458,7 +451,7 @@ class AuthorScreen extends Component {
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={info => {
if (this.state.loading == false) {
if (!this.state.loading) {
console.log(info);
this.getMore();
}

View File

@ -90,7 +90,7 @@ export default class Home extends React.PureComponent {
isLoggedIn = res;
});
if (isLoggedIn == true) {
if (isLoggedIn) {
await getUserData().then(res => {
user = Array.from(res);
});
@ -118,7 +118,7 @@ export default class Home extends React.PureComponent {
style={styles.tabbar}
tabUnderlineDefaultWidth={80} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={2} // default 3
activeColor={"$primaryBlue"}
activeColor={"#357ce6"}
inactiveColor={"#222"}
tabBarPosition="overlayTop"
/>

View File

@ -5,7 +5,7 @@ import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
// Internal Components
import { FormInput } from "../../../components/formInput";
import { GreetingHeaderButton } from "../../../components/buttons";
import { TextButton } from "../../../components/buttons";
import { InformationArea } from "../../../components/informationArea";
import { Login } from "../../../providers/steem/auth";
import { LoginHeader } from "../../../components/loginHeader";
@ -29,7 +29,7 @@ class LoginScreen extends Component {
username: "",
password: "",
isLoading: false,
isUsernameValid: true,
isUsernameValid: false,
keyboardIsOpen: false,
};
}
@ -109,7 +109,14 @@ class LoginScreen extends Component {
};
render() {
const { isLoading, username, isUsernameValid, keyboardIsOpen } = this.state;
const {
isLoading,
username,
isUsernameValid,
keyboardIsOpen,
password,
} = this.state;
return (
<View style={{ flex: 1 }}>
<StatusBar hidden translucent />
@ -131,7 +138,7 @@ class LoginScreen extends Component {
style={styles.tabbar}
tabUnderlineDefaultWidth={100} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={2} // default 3
activeColor={"$primaryBlue"}
activeColor={"#357ce6"}
inactiveColor={"#222"}
/>
)}
@ -163,14 +170,18 @@ class LoginScreen extends Component {
removed upon logout!"
iconName="ios-information-circle-outline"
/>
{/* It will remove */}
<GreetingHeaderButton onPress={goToAuthScreens} text="cancel" />
<View style={styles.footerButtons}>
<TextButton onPress={goToAuthScreens} text="cancel" />
</View>
<MainButton
wrapperStyle={styles.mainButtonWrapper}
onPress={this._handleOnPressLogin}
iconName="md-person"
iconColor="white"
text="LOGIN"
isDisable={
!isUsernameValid || password.length < 2 || username.length < 2
}
isLoading={isLoading}
/>
</View>
@ -179,7 +190,6 @@ class LoginScreen extends Component {
description="If you don't want to keep your password encrypted and saved on your device, you can use Steemconnect."
iconName="ios-information-circle-outline"
/>
<MainButton
wrapperStyle={styles.mainButtonWrapper}
onPress={this._loginwithSc2}

View File

@ -50,4 +50,14 @@ export default EStyleSheet.create({
bottom: 24,
flexDirection: "row",
},
footerButtons: {
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
alignSelf: "flex-end",
position: "absolute",
bottom: 45,
left: "$deviceWidth / 2.3",
},
});

View File

@ -1,5 +1,5 @@
import React, { Fragment } from "react";
import { Text, View } from "react-native";
import { Text, View, SafeAreaView } from "react-native";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
import { TabBar } from "../../../components/tabBar";
import { Notification } from "../../../components/notification";
@ -9,7 +9,7 @@ import styles from "./notificationStyles";
class NotificationScreen extends React.Component {
render() {
return (
<Fragment>
<SafeAreaView style={{ flex: 1, backgroundColor: "#fff" }}>
<ScrollableTabView
style={styles.tabView}
renderTabBar={() => (
@ -17,7 +17,7 @@ class NotificationScreen extends React.Component {
style={styles.tabbar}
tabUnderlineDefaultWidth={100}
tabUnderlineScaleX={2}
activeColor={"$primaryBlue"}
activeColor={"#357ce6"}
inactiveColor={"#222"}
/>
)}
@ -29,7 +29,7 @@ class NotificationScreen extends React.Component {
<Text>Leaderboard</Text>
</View>
</ScrollableTabView>
</Fragment>
</SafeAreaView>
);
}
}

View File

@ -2,7 +2,7 @@
import React from "react";
import { FlatList, ActivityIndicator } from "react-native";
import moment from "moment";
import { getTimeFromNow } from "../../utils/time";
import FastImage from "react-native-fast-image";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
@ -11,7 +11,7 @@ import DiscoverPage from "../discover/discover";
import { PostCard } from "../../components/postCard";
import Comment from "../../components/comment/comment";
import { Card, CardItem, View, Body, Title, Container } from "native-base";
import { Card, CardItem, View, Body } from "native-base";
import { getUserData, getAuthStatus } from "../../realm/realm";
import {
@ -19,7 +19,6 @@ import {
getFollows,
getPosts,
getUserComments,
getUserReplies,
} from "../../providers/steem/dsteem";
import styles from "../../styles/profile.styles";
/* eslint-enable no-unused-vars */
@ -76,7 +75,7 @@ class ProfilePage extends React.Component {
isLoggedIn = res;
});
if (isLoggedIn == true) {
if (isLoggedIn) {
await getUserData().then(res => {
userData = Array.from(res);
});
@ -103,7 +102,7 @@ class ProfilePage extends React.Component {
}
renderFooter = () => {
if (!this.state.loading == false) return null;
if (this.state.loading) return null;
return (
<View style={{ marginVertical: 20 }}>
@ -235,10 +234,7 @@ class ProfilePage extends React.Component {
}}
name="md-calendar"
/>
{moment
.utc(this.state.user.created)
.local()
.fromNow()}
{getTimeFromNow(this.state.user.created)}
</Text>
</View>
</CardItem>
@ -271,7 +267,7 @@ class ProfilePage extends React.Component {
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={info => {
if (this.state.loading == false) {
if (!this.state.loading) {
console.log(info);
this.getMore();
}

View File

@ -2,7 +2,7 @@
import React from "react";
import { FlatList, ActivityIndicator } from "react-native";
import moment from "moment";
import { getTimeFromNow } from "../../../utils/time";
import FastImage from "react-native-fast-image";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
@ -72,7 +72,7 @@ class ProfileScreen extends React.Component {
const isLoggedIn = res;
});
if (isLoggedIn === true) {
if (isLoggedIn) {
let user;
let userData;
let follows;
@ -105,7 +105,7 @@ class ProfileScreen extends React.Component {
}
renderFooter = () => {
if (!this.state.loading == false) return null;
if (this.state.loading) return null;
return (
<View style={{ marginVertical: 20 }}>
@ -238,10 +238,7 @@ class ProfileScreen extends React.Component {
}}
name="md-calendar"
/>
{moment
.utc(this.state.user.created)
.local()
.fromNow()}
{getTimeFromNow(this.state.user.created)}
</Text>
</View>
</CardItem>
@ -274,7 +271,7 @@ class ProfileScreen extends React.Component {
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={info => {
if (this.state.loading == false) {
if (!this.state.loading) {
console.log(info);
this.getMore();
}

View File

@ -5,54 +5,54 @@ import { ActivityIndicator, StatusBar, StyleSheet, View } from "react-native";
import { getAuthStatus, getUserData } from "../../realm/realm";
export class AuthLoadingScreen extends React.Component {
constructor(props) {
super(props);
this.checkAuth();
}
constructor(props) {
super(props);
this.checkAuth();
}
// Fetch the login state from storage then navigate to our appropriate place
checkAuth = async () => {
await getAuthStatus()
.then(result => {
if (result === true) {
getUserData()
.then(userData => {
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate("LoggedIn", {
account: userData["0"].username,
});
})
.catch(err => {
alert(err);
});
} else {
this.props.navigation.navigate("LoggedOut");
}
// Fetch the login state from storage then navigate to our appropriate place
checkAuth = async () => {
await getAuthStatus()
.then(result => {
if (result) {
getUserData()
.then(userData => {
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate("LoggedIn", {
account: userData["0"].username,
});
})
.catch(err => {
alert(err);
alert(err);
});
};
} else {
this.props.navigation.navigate("LoggedOut");
}
})
.catch(err => {
alert(err);
});
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<StatusBar barStyle="default" />
<ActivityIndicator />
</View>
);
}
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<StatusBar barStyle="default" />
<ActivityIndicator />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
text: {
fontSize: 32,
},
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
text: {
fontSize: 32,
},
});

View File

@ -7,57 +7,57 @@ import LoggedOutMenu from "./side-menu/loggedOutMenu";
import { getAuthStatus, getUserData } from "../realm/realm";
class SideMenuScreen extends Component {
constructor() {
super();
constructor() {
super();
this.state = {
isLoggedIn: false,
username: "",
};
this.state = {
isLoggedIn: false,
username: "",
};
}
async componentDidMount() {
let user;
let isLoggedIn;
await getAuthStatus().then(res => {
isLoggedIn = res;
});
if (isLoggedIn) {
await getUserData().then(res => {
user = Array.from(res);
});
this.setState({
username: user[0].username,
isLoggedIn: isLoggedIn,
isLoading: false,
});
} else {
await this.setState({
isLoggedIn: false,
});
}
}
async componentDidMount() {
let user;
let isLoggedIn;
await getAuthStatus().then(res => {
isLoggedIn = res;
});
if (isLoggedIn == true) {
await getUserData().then(res => {
user = Array.from(res);
});
this.setState({
username: user[0].username,
isLoggedIn: isLoggedIn,
isLoading: false,
});
} else {
await this.setState({
isLoggedIn: false,
});
}
}
render() {
return (
<View style={styles.root}>
{this.state.isLoggedIn ? (
<LoggedInMenu user={this.state.username} />
) : (
<LoggedOutMenu />
)}
</View>
);
}
render() {
return (
<View style={styles.root}>
{this.state.isLoggedIn ? (
<LoggedInMenu user={this.state.username} />
) : (
<LoggedOutMenu />
)}
</View>
);
}
}
module.exports = SideMenuScreen;
const styles = {
root: {
flexGrow: 1,
backgroundColor: "#f5fcff",
},
root: {
flexGrow: 1,
backgroundColor: "#f5fcff",
},
};

View File

@ -7,28 +7,28 @@ import { getAuthStatus } from "../../realm/realm";
import SplashScreen from "./splashScreen";
class SplashContainer extends React.Component {
constructor(props) {
super(props);
}
constructor(props) {
super(props);
}
async componentDidMount() {
await getAuthStatus()
.then(result => {
if (result === true) {
goToAuthScreens();
} else {
goToNoAuthScreens();
}
})
.catch(error => {
console.log(error);
goToAuthScreens();
});
}
async componentDidMount() {
await getAuthStatus()
.then(result => {
if (result) {
goToAuthScreens();
} else {
goToNoAuthScreens();
}
})
.catch(error => {
console.log(error);
goToAuthScreens();
});
}
render() {
return <SplashScreen />;
}
render() {
return <SplashScreen />;
}
}
export default SplashContainer;

View File

@ -7,58 +7,54 @@ import { Navigation } from "react-native-navigation";
import { goToAuthScreens } from "../../navigation";
export default class SteemConnect extends Component {
constructor(props) {
super(props);
this.state = {};
}
constructor(props) {
super(props);
this.state = {};
}
onNavigationStateChange(event) {
let access_token;
if (event.url.indexOf("?access_token=") > -1) {
this.webview.stopLoading();
try {
access_token = event.url.match(
/\?(?:access_token)\=([\S\s]*?)\&/
)[1];
} catch (error) {
console.log(error);
}
onNavigationStateChange(event) {
let access_token;
if (event.url.indexOf("?access_token=") > -1) {
this.webview.stopLoading();
try {
access_token = event.url.match(/\?(?:access_token)\=([\S\s]*?)\&/)[1];
} catch (error) {
console.log(error);
}
loginWithSC2(access_token, "pinCode")
.then(result => {
if (result === true) {
// TODO: Handle pinCode and navigate to home page
goToAuthScreens();
} else {
// TODO: Error alert (Toast Message)
console.log("loginWithSC2 error");
}
})
.catch(error => {
console.log(error);
});
}
loginWithSC2(access_token, "pinCode")
.then(result => {
if (result) {
// TODO: Handle pinCode and navigate to home page
goToAuthScreens();
} else {
// TODO: Error alert (Toast Message)
console.log("loginWithSC2 error");
}
})
.catch(error => {
console.log(error);
});
}
}
render() {
return (
<View style={{ flex: 1 }}>
<WebView
source={{
uri: `${steemConnectOptions.base_url}?client_id=${
steemConnectOptions.client_id
}&redirect_uri=${encodeURIComponent(
steemConnectOptions.redirect_uri
)}&${encodeURIComponent(steemConnectOptions.scope)}`,
}}
onNavigationStateChange={this.onNavigationStateChange.bind(
this
)}
ref={ref => {
this.webview = ref;
}}
/>
</View>
);
}
render() {
return (
<View style={{ flex: 1 }}>
<WebView
source={{
uri: `${steemConnectOptions.base_url}?client_id=${
steemConnectOptions.client_id
}&redirect_uri=${encodeURIComponent(
steemConnectOptions.redirect_uri
)}&${encodeURIComponent(steemConnectOptions.scope)}`,
}}
onNavigationStateChange={this.onNavigationStateChange.bind(this)}
ref={ref => {
this.webview = ref;
}}
/>
</View>
);
}
}

View File

@ -4,496 +4,447 @@ import Slider from "react-native-slider";
import { Container, Button, Content, Card, Input } from "native-base";
import { getUserData, getAuthStatus } from "../../realm/realm";
import {
getUser,
transferToken,
delegate,
globalProps,
transferToVesting,
withdrawVesting,
getUser,
transferToken,
delegate,
globalProps,
transferToVesting,
withdrawVesting,
} from "../../providers/steem/dsteem";
import { decryptKey } from "../../utils/crypto";
class WalletPage extends Component {
constructor(props) {
super(props);
constructor(props) {
super(props);
this.state = {
receiver: "",
amount: "",
asset: "STEEM",
memo: "",
user: {},
avail: "",
globalProps: "",
vestSteem: "",
percent: 0.05,
value: 0.0,
};
this.state = {
receiver: "",
amount: "",
asset: "STEEM",
memo: "",
user: {},
avail: "",
globalProps: "",
vestSteem: "",
percent: 0.05,
value: 0.0,
};
}
async componentDidMount() {
let isLoggedIn;
let user;
let userData;
let avail;
let vestSteem;
let globalProperties;
await getAuthStatus().then(res => {
isLoggedIn = res;
});
if (isLoggedIn) {
await getUserData().then(res => {
userData = Array.from(res);
});
user = await getUser(userData[0].username);
await this.setState({
user: user,
});
globalProperties = await globalProps();
avail =
parseFloat(this.state.user.vesting_shares) -
(parseFloat(this.state.user.to_withdraw) -
parseFloat(this.state.user.withdrawn)) /
1e6 -
parseFloat(this.state.user.delegated_vesting_shares);
vestSteem = parseFloat(
parseFloat(globalProperties.total_vesting_fund_steem) *
(parseFloat(avail) /
parseFloat(globalProperties.total_vesting_shares)),
6
);
console.log(avail);
console.log(vestSteem);
console.log(globalProperties);
console.log(
(parseFloat(globalProperties.total_vesting_fund_steem) /
parseFloat(globalProperties.total_vesting_shares)) *
parseFloat(avail * this.state.value)
);
await this.setState({
avail: avail,
vestSteem: vestSteem,
globalProps: globalProperties,
});
}
async componentDidMount() {
let isLoggedIn;
let user;
let userData;
let avail;
let vestSteem;
let globalProperties;
}
await getAuthStatus().then(res => {
isLoggedIn = res;
});
sendSteem = async () => {
let userData;
let activeKey;
if (isLoggedIn == true) {
await getUserData().then(res => {
userData = Array.from(res);
});
user = await getUser(userData[0].username);
await this.setState({
user: user,
});
globalProperties = await globalProps();
avail =
parseFloat(this.state.user.vesting_shares) -
(parseFloat(this.state.user.to_withdraw) -
parseFloat(this.state.user.withdrawn)) /
1e6 -
parseFloat(this.state.user.delegated_vesting_shares);
vestSteem = parseFloat(
parseFloat(globalProperties.total_vesting_fund_steem) *
(parseFloat(avail) /
parseFloat(globalProperties.total_vesting_shares)),
6
);
console.log(avail);
console.log(vestSteem);
console.log(globalProperties);
console.log(
(parseFloat(globalProperties.total_vesting_fund_steem) /
parseFloat(globalProperties.total_vesting_shares)) *
parseFloat(avail * this.state.value)
);
await this.setState({
avail: avail,
vestSteem: vestSteem,
globalProps: globalProperties,
});
}
}
sendSteem = async () => {
let userData;
let activeKey;
transferData = {
from: this.state.user.name,
to: this.state.receiver,
amount: this.state.amount + " " + this.state.asset,
memo: this.state.memo,
};
await getUserData()
.then(result => {
userData = Array.from(result);
activeKey = userData[0].activeKey;
console.log(userData);
console.log(activeKey);
})
.then(() => {
activeKey = decryptKey(activeKey, "pinCode");
transferToken(transferData, activeKey);
})
.catch(error => {
console.log(error);
});
transferData = {
from: this.state.user.name,
to: this.state.receiver,
amount: this.state.amount + " " + this.state.asset,
memo: this.state.memo,
};
delegateSP = async () => {
let userData;
let activeKey;
await getUserData()
.then(result => {
userData = Array.from(result);
activeKey = userData[0].activeKey;
console.log(userData);
console.log(activeKey);
})
.then(() => {
activeKey = decryptKey(activeKey, "pinCode");
transferToken(transferData, activeKey);
})
.catch(error => {
console.log(error);
});
};
vestSteem = parseFloat(
parseFloat(this.state.globalProps.total_vesting_fund_steem) *
(parseFloat(this.state.avail * this.state.value) /
parseFloat(this.state.globalProps.total_vesting_shares)),
6
);
let toWithdraw =
(vestSteem * 1e6) /
(parseFloat(this.state.globalProps.total_vesting_fund_steem) /
(parseFloat(this.state.globalProps.total_vesting_shares) /
1e6));
console.log(toWithdraw);
data = {
delegator: this.state.user.name,
delegatee: "demo",
vesting_shares: `${toWithdraw.toFixed(6)} VESTS`,
};
await getUserData().then(res => {
userData = Array.from(res);
});
delegateSP = async () => {
let userData;
let activeKey;
activeKey = decryptKey(userData[0].activeKey, "pinCode");
vestSteem = parseFloat(
parseFloat(this.state.globalProps.total_vesting_fund_steem) *
(parseFloat(this.state.avail * this.state.value) /
parseFloat(this.state.globalProps.total_vesting_shares)),
6
);
let toWithdraw =
(vestSteem * 1e6) /
(parseFloat(this.state.globalProps.total_vesting_fund_steem) /
(parseFloat(this.state.globalProps.total_vesting_shares) / 1e6));
console.log(toWithdraw);
data = {
delegator: this.state.user.name,
delegatee: "demo",
vesting_shares: `${toWithdraw.toFixed(6)} VESTS`,
};
await getUserData().then(res => {
userData = Array.from(res);
});
delegate(data, activeKey)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
activeKey = decryptKey(userData[0].activeKey, "pinCode");
delegate(data, activeKey)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
};
powerUpSteem = async () => {
let userData;
let activeKey;
await getUserData().then(res => {
userData = Array.from(res);
});
activeKey = decryptKey(userData[0].activeKey, "pinCode");
let data = {
from: this.state.user.name,
to: "hsynterkr",
amount: "001.000 STEEM",
};
powerUpSteem = async () => {
let userData;
let activeKey;
transferToVesting(data, activeKey)
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
};
await getUserData().then(res => {
userData = Array.from(res);
});
powerDownSteem = async () => {
let userData;
let activeKey;
let avail;
activeKey = decryptKey(userData[0].activeKey, "pinCode");
await getUserData().then(res => {
userData = Array.from(res);
});
let data = {
from: this.state.user.name,
to: "hsynterkr",
amount: "001.000 STEEM",
};
activeKey = decryptKey(userData[0].activeKey, "pinCode");
transferToVesting(data, activeKey)
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
avail =
parseFloat(this.state.user.vesting_shares) -
(parseFloat(this.state.user.to_withdraw) -
parseFloat(this.state.user.withdrawn)) /
1e6 -
parseFloat(this.state.user.delegated_vesting_shares);
let vestSteem = parseFloat(
parseFloat(this.state.globalProps.total_vesting_fund_steem) *
(parseFloat(avail * this.state.value) /
parseFloat(this.state.globalProps.total_vesting_shares)),
6
);
let toWithdraw =
(vestSteem * 1e6) /
(parseFloat(this.state.globalProps.total_vesting_fund_steem) /
(parseFloat(this.state.globalProps.total_vesting_shares) / 1e6));
let data = {
account: this.state.user.name,
vesting_shares: `${toWithdraw.toFixed(6)} VESTS`,
};
powerDownSteem = async () => {
let userData;
let activeKey;
let avail;
withdrawVesting(data, activeKey)
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
};
await getUserData().then(res => {
userData = Array.from(res);
});
render() {
return (
<Container>
<Content>
<Card>
<Text>STEEM Balance: {this.state.user.balance}</Text>
</Card>
<Card>
<Text>SBD Balance: {this.state.user.sbd_balance}</Text>
</Card>
<Card>
<Text>STEEM Power: {this.state.user.steem_power} SP</Text>
<Text>
Received STEEM Power: {this.state.user.received_steem_power} SP
</Text>
<Text>
Delegated Power Power: {this.state.user.delegated_steem_power} SP
</Text>
</Card>
<Card>
<Text>Saving STEEM Balance: {this.state.user.savings_balance}</Text>
<Text>
Saving STEEM Balance: {this.state.user.savings_sbd_balance}
</Text>
</Card>
activeKey = decryptKey(userData[0].activeKey, "pinCode");
<Card>
<Input
style={{
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 20,
margin: 10,
}}
autoCapitalize="none"
placeholder="Recipient"
onChangeText={user => this.setState({ receiver: user })}
value={this.state.receiver}
/>
<Input
style={{
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 20,
margin: 10,
}}
placeholder="amount"
onChangeText={amount => this.setState({ amount: amount })}
value={this.state.amount}
/>
<Input
style={{
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 20,
margin: 10,
}}
placeholder="memo"
onChangeText={memo => this.setState({ memo: memo })}
value={this.state.memo}
/>
<View style={{ flexDirection: "row" }}>
<Picker
note
mode="dropdown"
style={{ width: 120, flex: 0.5 }}
selectedValue={this.state.asset}
onValueChange={(itemValue, itemIndex) =>
this.setState({ asset: itemValue })
}
>
<Picker.Item label="STEEM" value="STEEM" />
<Picker.Item label="SBD" value="SBD" />
</Picker>
<Button onPress={this.sendSteem} style={{ margin: 10 }}>
<Text style={{ color: "white" }}>Send</Text>
</Button>
</View>
avail =
parseFloat(this.state.user.vesting_shares) -
(parseFloat(this.state.user.to_withdraw) -
parseFloat(this.state.user.withdrawn)) /
1e6 -
parseFloat(this.state.user.delegated_vesting_shares);
let vestSteem = parseFloat(
parseFloat(this.state.globalProps.total_vesting_fund_steem) *
(parseFloat(avail * this.state.value) /
parseFloat(this.state.globalProps.total_vesting_shares)),
6
);
let toWithdraw =
(vestSteem * 1e6) /
(parseFloat(this.state.globalProps.total_vesting_fund_steem) /
(parseFloat(this.state.globalProps.total_vesting_shares) /
1e6));
<View
style={{
margin: 5,
padding: 5,
borderWidth: 1,
borderColor: "gray",
borderRadius: 10,
}}
>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={{ height: 2, borderRadius: 1 }}
thumbStyle={{
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
}}
thumbTintColor="#007ee5"
value={this.state.value}
onValueChange={value => {
this.setState({
value: value,
percent: Math.floor(value.toFixed(2) * 100),
});
}}
/>
<Text>
Total:{" "}
{(parseInt(this.state.vestSteem) * this.state.percent) / 100} SP
</Text>
<Text>{Math.floor(this.state.value * 100)}%</Text>
<Button
onPress={this.delegateSP}
style={{ margin: 10, alignSelf: "flex-end" }}
>
<Text style={{ color: "white" }}>Delegate</Text>
</Button>
</View>
let data = {
account: this.state.user.name,
vesting_shares: `${toWithdraw.toFixed(6)} VESTS`,
};
<View
style={{
margin: 5,
padding: 5,
borderWidth: 1,
borderColor: "gray",
borderRadius: 10,
}}
>
<Button
onPress={this.powerUpSteem}
style={{ margin: 10, alignSelf: "flex-start" }}
>
<Text style={{ color: "white" }}>Power Up</Text>
</Button>
</View>
withdrawVesting(data, activeKey)
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
};
render() {
return (
<Container>
<Content>
<Card>
<Text>STEEM Balance: {this.state.user.balance}</Text>
</Card>
<Card>
<Text>SBD Balance: {this.state.user.sbd_balance}</Text>
</Card>
<Card>
<Text>
STEEM Power: {this.state.user.steem_power} SP
</Text>
<Text>
Received STEEM Power:{" "}
{this.state.user.received_steem_power} SP
</Text>
<Text>
Delegated Power Power:{" "}
{this.state.user.delegated_steem_power} SP
</Text>
</Card>
<Card>
<Text>
Saving STEEM Balance:{" "}
{this.state.user.savings_balance}
</Text>
<Text>
Saving STEEM Balance:{" "}
{this.state.user.savings_sbd_balance}
</Text>
</Card>
<Card>
<Input
style={{
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 20,
margin: 10,
}}
autoCapitalize="none"
placeholder="Recipient"
onChangeText={user =>
this.setState({ receiver: user })
}
value={this.state.receiver}
/>
<Input
style={{
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 20,
margin: 10,
}}
placeholder="amount"
onChangeText={amount =>
this.setState({ amount: amount })
}
value={this.state.amount}
/>
<Input
style={{
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 20,
margin: 10,
}}
placeholder="memo"
onChangeText={memo => this.setState({ memo: memo })}
value={this.state.memo}
/>
<View style={{ flexDirection: "row" }}>
<Picker
note
mode="dropdown"
style={{ width: 120, flex: 0.5 }}
selectedValue={this.state.asset}
onValueChange={(itemValue, itemIndex) =>
this.setState({ asset: itemValue })
}
>
<Picker.Item label="STEEM" value="STEEM" />
<Picker.Item label="SBD" value="SBD" />
</Picker>
<Button
onPress={this.sendSteem}
style={{ margin: 10 }}
>
<Text style={{ color: "white" }}>Send</Text>
</Button>
</View>
<View
style={{
margin: 5,
padding: 5,
borderWidth: 1,
borderColor: "gray",
borderRadius: 10,
}}
>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={{ height: 2, borderRadius: 1 }}
thumbStyle={{
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
}}
thumbTintColor="#007ee5"
value={this.state.value}
onValueChange={value => {
this.setState({
value: value,
percent: Math.floor(
value.toFixed(2) * 100
),
});
}}
/>
<Text>
Total:{" "}
{(parseInt(this.state.vestSteem) *
this.state.percent) /
100}{" "}
SP
</Text>
<Text>{Math.floor(this.state.value * 100)}%</Text>
<Button
onPress={this.delegateSP}
style={{ margin: 10, alignSelf: "flex-end" }}
>
<Text style={{ color: "white" }}>Delegate</Text>
</Button>
</View>
<View
style={{
margin: 5,
padding: 5,
borderWidth: 1,
borderColor: "gray",
borderRadius: 10,
}}
>
<Button
onPress={this.powerUpSteem}
style={{ margin: 10, alignSelf: "flex-start" }}
>
<Text style={{ color: "white" }}>Power Up</Text>
</Button>
</View>
<View
style={{
margin: 5,
padding: 5,
borderWidth: 1,
borderColor: "gray",
borderRadius: 10,
}}
>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={{ height: 2, borderRadius: 1 }}
thumbStyle={{
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
}}
thumbTintColor="#007ee5"
value={this.state.value}
onValueChange={value => {
this.setState(
{
value: value,
percent: Math.floor(
value.toFixed(2) * 100
),
},
() => {
let avail =
parseFloat(
this.state.user
.vesting_shares
) -
(parseFloat(
this.state.user.to_withdraw
) -
parseFloat(
this.state.user
.withdrawn
)) /
1e6 -
parseFloat(
this.state.user
.delegated_vesting_shares
);
let vestSteem = parseFloat(
parseFloat(
this.state.globalProps
.total_vesting_fund_steem
) *
(parseFloat(
avail * this.state.value
) /
parseFloat(
this.state
.globalProps
.total_vesting_shares
)),
6
);
console.log(vestSteem);
console.log(
(vestSteem * 1e6) /
(parseFloat(
this.state.globalProps
.total_vesting_fund_steem
) /
(parseFloat(
this.state
.globalProps
.total_vesting_shares
) /
1e6))
);
}
);
}}
/>
<Text>
Total Steem Power:{" "}
{(parseInt(this.state.vestSteem) *
this.state.percent) /
100}{" "}
SP
</Text>
<Text>
Estimated Weekly:{" "}
{Math.floor(
((
(parseInt(this.state.vestSteem) *
this.state.percent) /
100
).toFixed(0) /
13) *
100
) / 100}{" "}
SP
</Text>
<Text>{Math.floor(this.state.value * 100)}%</Text>
<Button
onPress={this.powerDownSteem}
style={{ margin: 10, alignSelf: "flex-end" }}
>
<Text style={{ color: "white" }}>
Power Down
</Text>
</Button>
</View>
</Card>
</Content>
</Container>
);
}
<View
style={{
margin: 5,
padding: 5,
borderWidth: 1,
borderColor: "gray",
borderRadius: 10,
}}
>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={{ height: 2, borderRadius: 1 }}
thumbStyle={{
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
}}
thumbTintColor="#007ee5"
value={this.state.value}
onValueChange={value => {
this.setState(
{
value: value,
percent: Math.floor(value.toFixed(2) * 100),
},
() => {
let avail =
parseFloat(this.state.user.vesting_shares) -
(parseFloat(this.state.user.to_withdraw) -
parseFloat(this.state.user.withdrawn)) /
1e6 -
parseFloat(this.state.user.delegated_vesting_shares);
let vestSteem = parseFloat(
parseFloat(
this.state.globalProps.total_vesting_fund_steem
) *
(parseFloat(avail * this.state.value) /
parseFloat(
this.state.globalProps.total_vesting_shares
)),
6
);
console.log(vestSteem);
console.log(
(vestSteem * 1e6) /
(parseFloat(
this.state.globalProps.total_vesting_fund_steem
) /
(parseFloat(
this.state.globalProps.total_vesting_shares
) /
1e6))
);
}
);
}}
/>
<Text>
Total Steem Power:{" "}
{(parseInt(this.state.vestSteem) * this.state.percent) / 100} SP
</Text>
<Text>
Estimated Weekly:{" "}
{Math.floor(
((
(parseInt(this.state.vestSteem) * this.state.percent) /
100
).toFixed(0) /
13) *
100
) / 100}{" "}
SP
</Text>
<Text>{Math.floor(this.state.value * 100)}%</Text>
<Button
onPress={this.powerDownSteem}
style={{ margin: 10, alignSelf: "flex-end" }}
>
<Text style={{ color: "white" }}>Power Down</Text>
</Button>
</View>
</Card>
</Content>
</Container>
);
}
}
export default WalletPage;

View File

@ -1,36 +1,34 @@
import { createStyle } from "react-native-theming";
import { StatusBar, Dimensions } from "react-native";
import EStyleSheet from "react-native-extended-stylesheet";
import { StatusBar } from "react-native";
const styles = createStyle({
container: {
backgroundColor: "#F9F9F9",
flex: 1,
top: StatusBar.currentHeight,
},
placeholder: {
backgroundColor: "white",
padding: 20,
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
tabs: {
position: "absolute",
top: Dimensions.get("window").width / 30,
alignItems: "center",
},
flatlistFooter: {
alignContent: "center",
alignItems: "center",
marginTop: 10,
marginBottom: 40,
borderColor: "#CED0CE",
},
export default EStyleSheet.create({
container: {
backgroundColor: "#F9F9F9",
flex: 1,
top: StatusBar.currentHeight,
},
placeholder: {
backgroundColor: "white",
padding: 20,
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
tabs: {
position: "absolute",
top: "$deviceWidth / 30",
alignItems: "center",
},
flatlistFooter: {
alignContent: "center",
alignItems: "center",
marginTop: 10,
marginBottom: 40,
borderColor: "#CED0CE",
},
});
export default styles;

View File

@ -1,18 +1,15 @@
import { createStyle } from "react-native-theming";
import { Dimensions } from "react-native";
import EStyleSheet from "react-native-extended-stylesheet";
const deviceWidth = Dimensions.get("window").width;
export default createStyle({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
input: {
backgroundColor: "#f5f5f5",
borderRadius: 5,
padding: 15,
minWidth: deviceWidth / 2,
},
export default EStyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
input: {
backgroundColor: "#f5f5f5",
borderRadius: 5,
padding: 15,
minWidth: "$deviceWidth / 2",
},
});

View File

@ -1,61 +1,58 @@
import { createStyle } from "react-native-theming";
import { StatusBar, Dimensions } from "react-native";
import EStyleSheet from "react-native-extended-stylesheet";
const styles = createStyle({
container: {
backgroundColor: "#F9F9F9",
flex: 1,
},
tabs: {
flex: 1,
},
placeholder: {
backgroundColor: "white",
padding: 20,
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
header: {
backgroundColor: "#284b78",
borderBottomWidth: 0,
borderColor: "#284b78",
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
borderWidth: 1,
borderColor: "white",
},
searchButton: {
color: "white",
fontWeight: "bold",
},
tabView: {
alignSelf: "center",
backgroundColor: "transparent",
},
tabbar: {
alignSelf: "center",
height: 40,
backgroundColor: "#284b78",
},
tabbarItem: {
flex: 1,
paddingHorizontal: 7,
backgroundColor: "#f9f9f9",
minWidth: Dimensions.get("window").width,
},
loginButton: {
alignSelf: "center",
marginTop: 100,
},
export default EStyleSheet.create({
container: {
backgroundColor: "#F9F9F9",
flex: 1,
},
tabs: {
flex: 1,
},
placeholder: {
backgroundColor: "white",
padding: 20,
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
header: {
backgroundColor: "#284b78",
borderBottomWidth: 0,
borderColor: "#284b78",
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
borderWidth: 1,
borderColor: "white",
},
searchButton: {
color: "white",
fontWeight: "bold",
},
tabView: {
alignSelf: "center",
backgroundColor: "transparent",
},
tabbar: {
alignSelf: "center",
height: 40,
backgroundColor: "#284b78",
},
tabbarItem: {
flex: 1,
paddingHorizontal: 7,
backgroundColor: "#f9f9f9",
minWidth: "$deviceWidth",
},
loginButton: {
alignSelf: "center",
marginTop: 100,
},
});
export default styles;

View File

@ -1,36 +1,33 @@
import { createStyle } from "react-native-theming";
import { StatusBar, Dimensions } from "react-native";
const styles = createStyle({
container: {
backgroundColor: "#F9F9F9",
flex: 1,
top: StatusBar.currentHeight,
},
placeholder: {
backgroundColor: "white",
padding: 20,
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
tabs: {
position: "absolute",
top: Dimensions.get("window").width / 30,
alignItems: "center",
},
flatlistFooter: {
alignContent: "center",
alignItems: "center",
marginTop: 10,
marginBottom: 40,
borderColor: "#CED0CE",
},
import EStyleSheet from "react-native-extended-stylesheet";
import { StatusBar } from "react-native";
export default EStyleSheet.create({
container: {
backgroundColor: "#F9F9F9",
flex: 1,
top: StatusBar.currentHeight,
},
placeholder: {
backgroundColor: "white",
padding: 20,
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
tabs: {
position: "absolute",
top: "$deviceWidth / 30",
alignItems: "center",
},
flatlistFooter: {
alignContent: "center",
alignItems: "center",
marginTop: 10,
marginBottom: 40,
borderColor: "#CED0CE",
},
});
export default styles;

View File

@ -13,7 +13,7 @@ export default EStyleSheet.create({
marginTop: "$deviceHeight / 8",
},
forgotButtonText: {
color: "#788187",
color: "$primaryGray",
fontSize: 14,
marginTop: 25,
alignSelf: "center",

View File

@ -1,37 +0,0 @@
import { createTheme } from 'react-native-theming';
const fonts = {
FONT_SIZE_SMALL: '12',
FONT_SIZE_MEDIUM: '14',
FONT_SIZE_LARGE: '16',
FONT_WEIGHT_LIGHT: '200',
FONT_WEIGHT_MEDIUM: '600',
FONT_WEIGHT_HEAVY: '800',
};
const themes = [
createTheme(
{
backgroundColor: 'white',
textColor: 'black',
buttonColor: 'blue',
buttonText: 'white',
statusBar: 'dark-content',
fontSize: fonts.FONT_SIZE_MEDIUM,
fontWeight: fonts.FONT_WEIGHT_MEDIUM,
},
'Light'
),
createTheme(
{
backgroundColor: 'black',
textColor: 'white',
buttonColor: 'yellow',
buttonText: 'black',
statusBar: 'light-content',
fontSize: fonts.FONT_SIZE_MEDIUM,
fontWeight: fonts.FONT_WEIGHT_MEDIUM,
},
'Dark'
),
];

27
src/utils/formatter.js Normal file
View File

@ -0,0 +1,27 @@
// 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) => {
if (!postBody) {
return "";
}
postBody = postBody
.replace(/(<([^>]+)>)/gi, "") // Remove html tags
.replace(/\r?\n|\r/g, " ") // Remove new lines
.replace(/(?:https?|ftp):\/\/[\n\S]+/g, "") // Remove urls
.trim()
.replace(/ +(?= )/g, ""); // Remove all multiple spaces
if (length) {
// Truncate
postBody = postBody.substring(0, length);
}
return postBody;
};

View File

@ -1,231 +1,210 @@
import Remarkable from "remarkable";
import { postSummary } from "./postSummary";
import { reputation } from "./reputation";
import moment from "moment";
import { getPostSummary } from "../utils/formatter";
import { getReputation } from "./reputation";
import { getTimeFromNow } from "../utils/time";
const md = new Remarkable({ html: true, breaks: true, linkify: true });
export const replaceAuthorNames = input => {
return input.replace(
/* eslint-disable-next-line */
/(^|[^a-zA-Z0-9_!#$%&*@\/]|(^|[^a-zA-Z0-9_+~.-\/]))[@]([a-z][-\.a-z\d]+[a-z\d])/gi,
(match, preceeding1, preceeding2, user) => {
const userLower = user.toLowerCase();
const preceedings = (preceeding1 || "") + (preceeding2 || "");
return input.replace(
/* eslint-disable-next-line */
/(^|[^a-zA-Z0-9_!#$%&*@\/]|(^|[^a-zA-Z0-9_+~.-\/]))[@]([a-z][-\.a-z\d]+[a-z\d])/gi,
(match, preceeding1, preceeding2, user) => {
const userLower = user.toLowerCase();
const preceedings = (preceeding1 || "") + (preceeding2 || "");
return `${preceedings}<a class="markdown-author-link" href="${userLower}" data-author="${userLower}">@${user}</a>`;
}
);
return `${preceedings}<a class="markdown-author-link" href="${userLower}" data-author="${userLower}">@${user}</a>`;
}
);
};
export const replaceTags = input => {
return input.replace(/(^|\s|>)(#[-a-z\d]+)/gi, tag => {
if (/#[\d]+$/.test(tag)) return tag; // do not allow only numbers (like #1)
const preceding = /^\s|>/.test(tag) ? tag[0] : ""; // space or closing tag (>)
tag = tag.replace(">", ""); // remove closing tag
const tag2 = tag.trim().substring(1);
const tagLower = tag2.toLowerCase();
return (
preceding +
`<a class="markdown-tag-link" href="${tagLower}" data-tag="${tagLower}">${tag.trim()}</a>`
);
});
return input.replace(/(^|\s|>)(#[-a-z\d]+)/gi, tag => {
if (/#[\d]+$/.test(tag)) return tag; // do not allow only numbers (like #1)
const preceding = /^\s|>/.test(tag) ? tag[0] : ""; // space or closing tag (>)
tag = tag.replace(">", ""); // remove closing tag
const tag2 = tag.trim().substring(1);
const tagLower = tag2.toLowerCase();
return (
preceding +
`<a class="markdown-tag-link" href="${tagLower}" data-tag="${tagLower}">${tag.trim()}</a>`
);
});
};
export const markDown2Html = input => {
if (!input) {
return "";
}
if (!input) {
return "";
}
// Start replacing user names
let output = replaceAuthorNames(input);
// Start replacing user names
let output = replaceAuthorNames(input);
// Replace tags
output = replaceTags(output);
// Replace tags
output = replaceTags(output);
output = md.render(output);
output = md.render(output);
/* eslint-disable */
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;
/* eslint-enable */
// TODO: Implement Regex --> Look at utls/formatter.js
// TODO: Implement Regex
return output;
return output;
};
export const parsePosts = (posts, user) => {
posts.map(post => {
post.json_metadata = JSON.parse(post.json_metadata);
post.json_metadata.image
? (post.image = post.json_metadata.image[0])
: "";
post.pending_payout_value = parseFloat(
post.pending_payout_value
).toFixed(2);
post.created = moment
.utc(post.created)
.local()
.fromNow();
post.vote_count = post.active_votes.length;
post.author_reputation = reputation(post.author_reputation);
post.avatar = `https://steemitimages.com/u/${post.author}/avatar/small`;
post.body = markDown2Html(post.body);
post.summary = postSummary(post.body, 100);
post.raw_body = post.body;
post.active_votes.sort((a, b) => {
return b.rshares - a.rshares;
});
let totalPayout =
parseFloat(post.pending_payout_value) +
parseFloat(post.total_payout_value) +
parseFloat(post.curator_payout_value);
let voteRshares = post.active_votes.reduce(
(a, b) => a + parseFloat(b.rshares),
0
);
let ratio = totalPayout / voteRshares;
post.isVoted = false;
for (let i in post.active_votes) {
if (post.active_votes[i].voter == user) {
post.isVoted = true;
}
post.active_votes[i].value = (
post.active_votes[i].rshares * ratio
).toFixed(2);
post.active_votes[i].reputation = reputation(
post.active_votes[i].reputation
);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].avatar =
"https://steemitimages.com/u/" +
post.active_votes[i].voter +
"/avatar/small";
}
if (post.active_votes.length > 2) {
post.top_likers = [
post.active_votes[0].voter,
post.active_votes[1].voter,
post.active_votes[2].voter,
];
}
});
return posts;
};
export const parsePost = post => {
posts.map(post => {
post.json_metadata = JSON.parse(post.json_metadata);
post.json_metadata.image ? (post.image = post.json_metadata.image[0]) : "";
post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(
2
2
);
post.created = moment
.utc(post.created)
.local()
.fromNow();
post.created = getTimeFromNow(post.created);
post.vote_count = post.active_votes.length;
post.author_reputation = reputation(post.author_reputation);
post.author_reputation = getReputation(post.author_reputation);
post.avatar = `https://steemitimages.com/u/${post.author}/avatar/small`;
post.body = markDown2Html(post.body);
post.summary = postSummary(post.body, 100);
post.summary = getPostSummary(post.body, 100);
post.raw_body = post.body;
post.active_votes.sort((a, b) => {
return b.rshares - a.rshares;
return b.rshares - a.rshares;
});
let totalPayout =
parseFloat(post.pending_payout_value) +
parseFloat(post.total_payout_value) +
parseFloat(post.curator_payout_value);
parseFloat(post.pending_payout_value) +
parseFloat(post.total_payout_value) +
parseFloat(post.curator_payout_value);
let voteRshares = post.active_votes.reduce(
(a, b) => a + parseFloat(b.rshares),
0
(a, b) => a + parseFloat(b.rshares),
0
);
let ratio = totalPayout / voteRshares;
post.isVoted = false;
for (let i in post.active_votes) {
post.active_votes[i].value = (
post.active_votes[i].rshares * ratio
).toFixed(2);
post.active_votes[i].reputation = reputation(
post.active_votes[i].reputation
);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].avatar =
"https://steemitimages.com/u/" +
post.active_votes[i].voter +
"/avatar/small";
if (post.active_votes[i].voter == user) {
post.isVoted = true;
}
post.active_votes[i].value = (
post.active_votes[i].rshares * ratio
).toFixed(2);
post.active_votes[i].reputation = getReputation(
post.active_votes[i].reputation
);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].avatar =
"https://steemitimages.com/u/" +
post.active_votes[i].voter +
"/avatar/small";
}
if (post.active_votes.length > 2) {
post.top_likers = [
post.active_votes[0].voter,
post.active_votes[1].voter,
post.active_votes[2].voter,
];
post.top_likers = [
post.active_votes[0].voter,
post.active_votes[1].voter,
post.active_votes[2].voter,
];
}
return post;
});
return posts;
};
export const parsePost = post => {
post.json_metadata = JSON.parse(post.json_metadata);
post.json_metadata.image ? (post.image = post.json_metadata.image[0]) : "";
post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(2);
post.created = getTimeFromNow(post.created);
post.vote_count = post.active_votes.length;
post.author_reputation = getReputation(post.author_reputation);
post.avatar = `https://steemitimages.com/u/${post.author}/avatar/small`;
post.body = markDown2Html(post.body);
post.summary = getPostSummary(post.body, 100);
post.raw_body = post.body;
post.active_votes.sort((a, b) => {
return b.rshares - a.rshares;
});
let totalPayout =
parseFloat(post.pending_payout_value) +
parseFloat(post.total_payout_value) +
parseFloat(post.curator_payout_value);
let voteRshares = post.active_votes.reduce(
(a, b) => a + parseFloat(b.rshares),
0
);
let ratio = totalPayout / voteRshares;
for (let i in post.active_votes) {
post.active_votes[i].value = (post.active_votes[i].rshares * ratio).toFixed(
2
);
post.active_votes[i].reputation = getReputation(
post.active_votes[i].reputation
);
post.active_votes[i].percent = post.active_votes[i].percent / 100;
post.active_votes[i].avatar =
"https://steemitimages.com/u/" +
post.active_votes[i].voter +
"/avatar/small";
}
if (post.active_votes.length > 2) {
post.top_likers = [
post.active_votes[0].voter,
post.active_votes[1].voter,
post.active_votes[2].voter,
];
}
return post;
};
export const protocolUrl2Obj = url => {
let urlPart = url.split("://")[1];
let urlPart = url.split("://")[1];
// remove last char if /
if (urlPart.endsWith("/")) {
urlPart = urlPart.substring(0, urlPart.length - 1);
}
// remove last char if /
if (urlPart.endsWith("/")) {
urlPart = urlPart.substring(0, urlPart.length - 1);
}
const parts = urlPart.split("/");
const parts = urlPart.split("/");
// filter
if (parts.length === 1) {
return { type: "filter" };
}
// filter
if (parts.length === 1) {
return { type: "filter" };
}
// filter with tag
if (parts.length === 2) {
return { type: "filter-tag", filter: parts[0], tag: parts[1] };
}
// filter with tag
if (parts.length === 2) {
return { type: "filter-tag", filter: parts[0], tag: parts[1] };
}
// account
if (parts.length === 1 && parts[0].startsWith("@")) {
return { type: "account", account: parts[0].replace("@", "") };
}
// account
if (parts.length === 1 && parts[0].startsWith("@")) {
return { type: "account", account: parts[0].replace("@", "") };
}
// post
if (parts.length === 3 && parts[1].startsWith("@")) {
return {
type: "post",
cat: parts[0],
author: parts[1].replace("@", ""),
permlink: parts[2],
};
}
// post
if (parts.length === 3 && parts[1].startsWith("@")) {
return {
type: "post",
cat: parts[0],
author: parts[1].replace("@", ""),
permlink: parts[2],
};
}
};
export const parseComments = comments => {
comments.map(comment => {
comment.pending_payout_value = parseFloat(
comment.pending_payout_value
).toFixed(2);
comment.created = moment
.utc(comment.created)
.local()
.fromNow();
comment.vote_count = comment.active_votes.length;
comment.author_reputation = reputation(comment.author_reputation);
comment.avatar = `https://steemitimages.com/u/${
comment.author
}/avatar/small`;
comment.body = markDown2Html(comment.body);
});
return comments;
comments.map(comment => {
comment.pending_payout_value = parseFloat(
comment.pending_payout_value
).toFixed(2);
comment.created = getTimeFromNow(comment.created);
comment.vote_count = comment.active_votes.length;
comment.author_reputation = getReputation(comment.author_reputation);
comment.avatar = `https://steemitimages.com/u/${
comment.author
}/avatar/small`;
comment.body = markDown2Html(comment.body);
});
return comments;
};

View File

@ -1,19 +0,0 @@
export const postSummary = (postBody, length) => {
if (!postBody) {
return "";
}
postBody = postBody
.replace(/(<([^>]+)>)/gi, "") // Remove html tags
.replace(/\r?\n|\r/g, " ") // Remove new lines
.replace(/(?:https?|ftp):\/\/[\n\S]+/g, "") // Remove urls
.trim()
.replace(/ +(?= )/g, ""); // Remove all multiple spaces
if (length) {
// Truncate
postBody = postBody.substring(0, length);
}
return postBody;
};

View File

@ -1,18 +1,23 @@
export const reputation = reputation => {
if (reputation == null) return reputation;
reputation = parseInt(reputation);
let rep = String(reputation);
const neg = rep.charAt(0) === "-";
rep = neg ? rep.substring(1) : rep;
const str = rep;
const leadingDigits = parseInt(str.substring(0, 4));
const log = Math.log(leadingDigits) / Math.log(10);
const n = str.length - 1;
let out = n + (log - parseInt(log));
if (isNaN(out)) out = 0;
out = Math.max(out - 9, 0);
out = (neg ? -1 : 1) * out;
out = out * 9 + 25;
out = parseInt(out);
return out;
export const getReputation = reputation => {
if (reputation === null) return reputation;
let _reputation = String(parseInt(reputation));
const neg = _reputation.charAt(0) === "-";
_reputation = neg ? _reputation.substring(1) : _reputation;
const str = _reputation;
const leadingDigits = parseInt(str.substring(0, 4));
const log = Math.log(leadingDigits) / Math.log(10);
const n = str.length - 1;
let out = n + (log - parseInt(log));
if (isNaN(out)) out = 0;
out = Math.max(out - 9, 0);
out = (neg ? -1 : 1) * out;
out = out * 9 + 25;
out = parseInt(out);
return out;
};

10
src/utils/time.js Normal file
View File

@ -0,0 +1,10 @@
import moment from "moment";
export const getTimeFromNow = value => {
if (!value) return null;
return moment
.utc(value)
.local()
.fromNow();
};