Merge branch 'master' of github.com:esteemapp/esteem-mobile

This commit is contained in:
Feruz 2018-08-17 11:21:55 +03:00
commit bf5f96771f
14 changed files with 3301 additions and 2653 deletions

View File

@ -1,5 +1,5 @@
{
"tabWidth": 4,
"singleQuote": true,
"singleQuote": false,
"trailingComma": "es5"
}

4713
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,12 @@
"react-native-circular-action-menu": "^0.5.0",
"react-native-fast-image": "^4.0.14",
"react-native-htmlview": "^0.12.1",
"react-native-markdown-editor": "^1.0.1",
"react-native-modal-popover": "0.0.10",
"react-native-render-html": "^3.10.0",
"react-native-restart": "0.0.6",
"react-native-scrollable-tab-view": "git+https://github.com/happypancake/react-native-scrollable-tab-view.git",
"react-native-slider": "^0.11.0",
"react-native-theming": "^1.0.16",
"react-native-vector-icons": "^4.6.0",
"react-navigation": "^2.8.0",

View File

@ -0,0 +1,219 @@
/* eslint-disable no-unused-vars */
import React from "react";
import {
StyleSheet,
Image,
TouchableOpacity,
Dimensions,
ActivityIndicator,
} from "react-native";
import {
Card,
CardItem,
Left,
Right,
Thumbnail,
View,
Icon,
Body,
Text,
Button,
} from "native-base";
import { Popover, PopoverController } from "react-native-modal-popover";
import Slider from "react-native-slider";
import { upvote, upvoteAmount } from "../../providers/steem/Dsteem";
import { decryptKey } from "../../utils/Crypto";
import { getUserData } from "../../realm/Realm";
import { parsePost } from "../../utils/PostParser";
import { getComments, getPost } from "../../providers/steem/Dsteem";
import HTML from "react-native-render-html";
/* eslint-enable no-unused-vars */
class Comment extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
replies: [],
};
}
componentDidMount() {
if (this.props.comment.children > 1) {
getComments(this.props.comment.author, this.props.comment.permlink)
.then(replies => {
this.setState({
replies: replies,
});
})
.catch(error => {
console.log(error);
});
}
}
onLinkPress(evt, href, attribs) {
let steemPost = href.match(
/^https?:\/\/(.*)\/(.*)\/(@[\w\.\d-]+)\/(.*)/i
);
if (attribs.class === "markdown-author-link") {
this.props.navigation.navigate("Author", { author: href });
} else if (steemPost != null) {
steemPost[3] = steemPost[3].replace("@", "");
getPost(steemPost[3], steemPost[4])
.then(result => {
let content = parsePost(result);
this.props.navigation.push("Post", { content: content });
})
.catch(err => {
alert(err);
});
} else {
console.log(href);
console.log(attribs);
}
}
alterNode(node) {
if (node.name == "img") {
node.attribs.style = "width: auto; object-fit: cover";
} else if (node.name == "iframe") {
node.attribs.style = `max-width: ${Dimensions.get("window").width}`;
//node.attribs.style = `width: ${Dimensions.get("window").width}`;
node.attribs.height = 200;
}
}
render() {
return (
<View>
<View style={styles.comment}>
<Thumbnail
style={styles.avatar}
source={{
uri: `https://steemitimages.com/u/${
this.props.comment.author
}/avatar/small`,
}}
/>
<Card style={{ flex: 0.91, borderRadius: 10 }}>
<CardItem style={{ borderRadius: 10 }}>
<Left>
<View style={styles.author}>
<Text style={styles.authorName}>
{this.props.comment.author}
</Text>
</View>
</Left>
<Text style={styles.timeAgo} note>
{this.props.comment.created}
</Text>
</CardItem>
<CardItem>
<HTML
html={this.props.comment.body}
onLinkPress={(evt, href, hrefatr) =>
this.onLinkPress(evt, href, hrefatr)
}
containerStyle={{ padding: 0 }}
textSelectable={true}
tagsStyles={styles}
ignoredTags={["script"]}
debug={false}
removeClippedSubviews={false}
alterNode={node => {
this.alterNode(node);
}}
imagesMaxWidth={Dimensions.get("window").width}
/>
</CardItem>
<CardItem style={{ borderRadius: 10 }}>
<Left>
<Text>
<Icon
style={{ color: "blue" }}
name="arrow-dropup"
/>
{"$ "}
{this.props.comment.pending_payout_value}
</Text>
</Left>
<Body>
<TouchableOpacity>
<Text>
<Icon
style={{ color: "blue" }}
name="ios-chatbubbles-outline"
/>
Reply
</Text>
</TouchableOpacity>
</Body>
</CardItem>
</Card>
</View>
{this.props.comment.children > 0 ? (
// Replies
<View>
{this.state.replies.map(reply => {
return (
<View style={{ paddingLeft: 30 }}>
<Comment
comment={reply}
navigation={this.props.navigation}
/>
</View>
);
})}
</View>
) : (
<View />
)}
</View>
);
}
}
const styles = StyleSheet.create({
comment: {
alignSelf: "center",
color: "#626262",
borderRadius: 10,
width: "98%",
marginHorizontal: 10,
flexDirection: "row",
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
borderColor: "lightgray",
borderWidth: 1,
flex: 0.09,
marginTop: 10,
},
author: {
backgroundColor: "white",
alignSelf: "flex-start",
paddingVertical: 5,
},
timeAgo: {
alignSelf: "center",
fontSize: 9,
fontWeight: "100",
marginHorizontal: 3,
},
authorName: {
color: "#222",
fontWeight: "600",
fontSize: 13,
marginHorizontal: 5,
},
body: {
justifyContent: "flex-start",
flexDirection: "row",
},
});
export default Comment;

View File

@ -1,7 +1,12 @@
/* eslint-disable no-unused-vars */
import React from 'react';
import { StyleSheet, Image, TouchableOpacity } from 'react-native';
import React from "react";
import {
StyleSheet,
Image,
TouchableOpacity,
Dimensions,
ActivityIndicator,
} from "react-native";
import {
Card,
CardItem,
@ -12,19 +17,95 @@ import {
Icon,
Body,
Text,
} from 'native-base';
} from "native-base";
import { Popover, PopoverController } from "react-native-modal-popover";
import Slider from "react-native-slider";
import { upvote, upvoteAmount } from "../../providers/steem/Dsteem";
import { decryptKey } from "../../utils/Crypto";
import { getUserData } from "../../realm/Realm";
/* eslint-enable no-unused-vars */
class PostCard extends React.Component {
class PostCard extends React.PureComponent {
constructor(props) {
super(props);
this.upvoteContent = this.upvoteContent.bind(this);
this.calculateEstimatedAmount = this.calculateEstimatedAmount.bind(
this
);
this.state = {};
this.state = {
value: 0.0,
isVoting: false,
isVoted: false,
amount: "0.00",
};
}
componentDidMount() {}
componentDidMount() {
this.calculateEstimatedAmount();
}
onError() {}
calculateEstimatedAmount = async () => {
// Calculate total vesting shares
let total_vests =
parseFloat(this.props.user.vesting_shares) +
parseFloat(this.props.user.received_vesting_shares) -
parseFloat(this.props.user.delegated_vesting_shares);
let final_vest = total_vests * 1e6;
let power =
(this.props.user.voting_power * (this.state.value * 10000)) /
10000 /
50;
let rshares = (power * final_vest) / 10000;
let estimated = await upvoteAmount(rshares);
this.setState({
amount: estimated.toFixed(3),
});
};
upvoteContent = async () => {
let postingKey;
let userData;
if (this.props.isLoggedIn) {
await this.setState({
isVoting: true,
});
await getUserData().then(result => {
userData = Array.from(result);
postingKey = decryptKey(userData[0].postingKey, "pinCode");
});
upvote(
{
voter: this.props.user.name,
author: this.props.content.author,
permlink: this.props.content.permlink,
weight: (this.state.value * 100).toFixed(0) * 100,
},
postingKey
)
.then(res => {
console.log(res);
this.setState({
isVoted: true,
isVoting: false,
});
})
.catch(err => {
console.log(err);
this.setState({
isVoted: false,
isVoting: false,
});
});
}
};
render() {
return (
@ -33,7 +114,7 @@ class PostCard extends React.Component {
<Left>
<TouchableOpacity
onPress={() =>
this.props.navigation.push('Author', {
this.props.navigation.push("Author", {
author: this.props.content.author,
})
}
@ -60,8 +141,8 @@ class PostCard extends React.Component {
</Text>
</View>
<Text style={styles.timeAgo} note>
{' '}
{this.props.content.created}{' '}
{" "}
{this.props.content.created}{" "}
</Text>
</Body>
</Left>
@ -71,12 +152,12 @@ class PostCard extends React.Component {
</CardItem>
<Image
source={{ uri: this.props.content.image }}
defaultSource={require('../../assets/no_image.png')}
defaultSource={require("../../assets/no_image.png")}
style={styles.image}
/>
<TouchableOpacity
onPress={() =>
this.props.navigation.push('Post', {
this.props.navigation.push("Post", {
content: this.props.content,
})
}
@ -94,13 +175,120 @@ class PostCard extends React.Component {
</TouchableOpacity>
<CardItem>
<Left>
<TouchableOpacity start style={styles.upvoteButton}>
<Icon
style={styles.upvoteIcon}
active
name="ios-arrow-dropup-outline"
/>
</TouchableOpacity>
<PopoverController>
{({
openPopover,
closePopover,
popoverVisible,
setPopoverAnchor,
popoverAnchorRect,
}) => (
<React.Fragment>
<TouchableOpacity
start
ref={setPopoverAnchor}
onPress={openPopover}
style={styles.upvoteButton}
>
{this.state.isVoting ? (
<ActivityIndicator />
) : (
<View>
{this.state.isVoted ? (
<Icon
style={{
color: "#007ee5",
}}
style={
styles.upvoteIcon
}
active
name="ios-arrow-dropup-circle"
/>
) : (
<Icon
style={{
color: "#007ee5",
}}
style={
styles.upvoteIcon
}
active
name="ios-arrow-dropup-outline"
/>
)}
</View>
)}
</TouchableOpacity>
<Popover
contentStyle={styles.popover}
arrowStyle={styles.arrow}
backgroundStyle={styles.background}
visible={popoverVisible}
onClose={closePopover}
fromRect={popoverAnchorRect}
placement={"top"}
supportedOrientations={[
"portrait",
"landscape",
]}
>
<Text>${this.state.amount}</Text>
<View
style={{
flex: 1,
flexDirection: "row",
}}
>
<TouchableOpacity
onPress={() => {
closePopover();
this.upvoteContent();
}}
style={{
flex: 0.1,
alignSelf: "center",
}}
>
<Icon
style={{ color: "#007ee5" }}
active
name="ios-arrow-dropup-outline"
/>
</TouchableOpacity>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={styles.track}
thumbStyle={styles.thumb}
thumbTintColor="#007ee5"
value={this.state.value}
onValueChange={value => {
this.setState(
{ value },
() => {
this.calculateEstimatedAmount();
}
);
}}
/>
<Text
style={{
flex: 0.15,
alignSelf: "center",
marginLeft: 10,
}}
>
{(
this.state.value * 100
).toFixed(0)}
%
</Text>
</View>
</Popover>
</React.Fragment>
)}
</PopoverController>
<TouchableOpacity style={styles.payoutButton}>
<Text style={styles.payout}>
${this.props.content.pending_payout_value}
@ -156,7 +344,7 @@ class PostCard extends React.Component {
{this.props.content.top_likers[2]}
<Text style={styles.footer}> & </Text>
{this.props.content.vote_count -
this.props.content.top_likers.length}{' '}
this.props.content.top_likers.length}{" "}
others like this
</Text>
</CardItem>
@ -173,150 +361,154 @@ class PostCard extends React.Component {
}
const styles = StyleSheet.create({
post: {
shadowColor: 'white',
shadowColor: "white",
padding: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 0,
marginTop: 10,
marginBottom: 0,
borderWidth: 0,
borderColor: 'white',
borderWidth: 1,
borderColor: "#e5e5e5",
borderRadius: 5,
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
borderColor: 'lightgray',
borderColor: "lightgray",
borderWidth: 1,
},
author: {
backgroundColor: 'white',
alignSelf: 'flex-start',
backgroundColor: "white",
alignSelf: "flex-start",
paddingVertical: 5,
},
timeAgo: {
alignSelf: 'center',
alignSelf: "center",
fontSize: 9,
fontWeight: '100',
fontWeight: "100",
marginHorizontal: 3,
},
authorName: {
color: '#222',
fontWeight: '600',
color: "#222",
fontWeight: "600",
fontSize: 10,
},
upvoteButton: {
margin: 0,
flexDirection: 'row',
flexDirection: "row",
paddingVertical: 0,
},
upvoteIcon: {
alignSelf: 'flex-start',
alignSelf: "flex-start",
fontSize: 20,
color: '#007ee5',
color: "#007ee5",
margin: 0,
width: 18,
},
payout: {
alignSelf: 'center',
alignSelf: "center",
fontSize: 10,
color: '#626262',
color: "#626262",
marginLeft: 3,
},
payoutIcon: {
fontSize: 15,
marginHorizontal: 3,
color: '#a0a0a0',
alignSelf: 'center',
color: "#a0a0a0",
alignSelf: "center",
},
payoutButton: {
flexDirection: 'row',
alignSelf: 'flex-start',
flexDirection: "row",
alignSelf: "flex-start",
paddingVertical: 2,
},
commentButton: {
padding: 0,
margin: 0,
flexDirection: 'row',
flexDirection: "row",
},
comment: {
alignSelf: 'center',
alignSelf: "center",
fontSize: 10,
color: '#626262',
color: "#626262",
marginLeft: 3,
},
commentIcon: {
alignSelf: 'flex-start',
alignSelf: "flex-start",
fontSize: 20,
color: '#007ee5',
color: "#007ee5",
margin: 0,
width: 20,
},
title: {
fontSize: 12,
fontWeight: '500',
fontWeight: "500",
marginVertical: 5,
},
summary: {
fontSize: 10,
fontWeight: '200',
overflow: 'hidden',
fontWeight: "200",
overflow: "hidden",
},
header: {
shadowColor: "white",
height: 50,
borderRadius: 5,
},
body: {
justifyContent: 'flex-start',
flexDirection: 'row',
justifyContent: "flex-start",
flexDirection: "row",
},
image: {
margin: 0,
width: '100%',
width: "100%",
height: 160,
},
badge: {
alignSelf: 'center',
borderColor: 'lightgray',
alignSelf: "center",
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 10,
width: 15,
height: 15,
padding: 2,
backgroundColor: 'lightgray',
backgroundColor: "lightgray",
marginHorizontal: 5,
},
category: {
alignSelf: 'center',
alignSelf: "center",
borderRadius: 10,
height: 15,
backgroundColor: '#007EE5',
backgroundColor: "#007EE5",
paddingHorizontal: 5,
paddingVertical: 1.5,
},
categoryText: {
fontSize: 9,
color: 'white',
fontWeight: '600',
color: "white",
fontWeight: "600",
},
text: {
fontSize: 7,
alignSelf: 'center',
textAlignVertical: 'center',
color: 'white',
fontWeight: 'bold',
alignSelf: "center",
textAlignVertical: "center",
color: "white",
fontWeight: "bold",
},
topLikers: {
backgroundColor: '#f8f8f8',
shadowColor: "white",
backgroundColor: "#f8f8f8",
borderWidth: 0,
padding: 0,
borderRadius: 5,
},
likers_1: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: 'lightgray',
borderColor: "lightgray",
marginVertical: -5,
},
likers_2: {
@ -324,7 +516,7 @@ const styles = StyleSheet.create({
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: 'lightgray',
borderColor: "lightgray",
marginVertical: -5,
marginLeft: -3,
},
@ -333,15 +525,36 @@ const styles = StyleSheet.create({
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: 'lightgray',
borderColor: "lightgray",
marginVertical: -5,
marginLeft: -3,
},
footer: {
marginLeft: 5,
shadowColor: "white",
paddingLeft: 5,
borderRadius: 5,
fontSize: 7,
fontWeight: '100',
color: '#777777',
fontWeight: "100",
color: "#777777",
},
popover: {
width: Dimensions.get("window").width - 20,
borderRadius: 5,
padding: 10,
},
track: {
height: 2,
borderRadius: 1,
},
thumb: {
width: 30,
height: 30,
borderRadius: 30 / 2,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
},
});

View File

@ -1,8 +1,8 @@
import * as dsteem from 'dsteem';
import { getAccount } from './Dsteem';
import { setUserData, setAuthStatus } from '../../realm/Realm';
import * as dsteem from "dsteem";
import { getAccount } from "./Dsteem";
import { setUserData, setAuthStatus } from "../../realm/Realm";
/*eslint-disable-next-line no-unused-vars*/
import { encryptKey, decryptKey } from '../../utils/Crypto';
import { encryptKey, decryptKey } from "../../utils/Crypto";
export const Login = (username, password) => {
let account;
@ -10,24 +10,24 @@ export const Login = (username, password) => {
let privateKeys;
let isPassword;
let isPostingKey;
let pinCode = 'pinCode';
let pinCode = "pinCode";
return new Promise((resolve, reject) => {
// Get user account data from STEEM Blockchain
getAccount(username)
.then(result => {
if (result.length < 1) {
reject(new Error('Wrong @username'));
reject(new Error("Wrong @username"));
}
account = result[0];
// Public keys of user
publicKeys = {
active: account['active'].key_auths.map(x => x[0]),
memo: account['memo_key'],
owner: account['owner'].key_auths.map(x => x[0]),
posting: account['posting'].key_auths.map(x => x[0]),
active: account["active"].key_auths.map(x => x[0]),
memo: account["memo_key"],
owner: account["owner"].key_auths.map(x => x[0]),
posting: account["posting"].key_auths.map(x => x[0]),
};
})
.then(() => {
@ -37,26 +37,26 @@ export const Login = (username, password) => {
active: dsteem.PrivateKey.fromLogin(
username,
password,
'active'
"active"
).toString(),
memo: dsteem.PrivateKey.fromLogin(
username,
password,
'memo'
"memo"
).toString(),
owner: dsteem.PrivateKey.fromLogin(
username,
password,
'owner'
"owner"
).toString(),
posting: dsteem.PrivateKey.fromLogin(
username,
password,
'posting'
"posting"
).toString(),
};
} catch (error) {
reject(new Error('Wrong Key/Password'));
reject(new Error("Wrong Key/Password"));
}
})
.then(() => {
@ -68,7 +68,7 @@ export const Login = (username, password) => {
dsteem.PrivateKey.fromLogin(
username,
password,
'posting'
"posting"
)
.createPublic()
.toString() === publicKeys.posting.toString();
@ -80,7 +80,7 @@ export const Login = (username, password) => {
*/
let userData = {
username: username,
authType: 'masterKey',
authType: "masterKey",
masterKey: encryptKey(password, pinCode),
postingKey: encryptKey(
privateKeys.posting,
@ -122,11 +122,11 @@ export const Login = (username, password) => {
*/
let userData = {
username: username,
authType: 'postingKey',
authType: "postingKey",
postingKey: privateKeys.posting,
masterKey: '',
activeKey: '',
memoKey: '',
masterKey: "",
activeKey: "",
memoKey: "",
};
let authData = {
@ -151,20 +151,20 @@ export const Login = (username, password) => {
reject(err);
});
} else {
reject(new Error('Wrong Key/Password'));
reject(new Error("Wrong Key/Password"));
}
} catch (error) {
reject(new Error('Wrong Key/Password'));
reject(new Error("Wrong Key/Password"));
}
}
} catch (error) {
reject(new Error('Wrong Key/Password'));
reject(new Error("Wrong Key/Password"));
}
})
.catch(err => {
// eslint-disable-next-line
console.log(err);
reject(new Error('Check your username'));
reject(new Error("Check your username"));
});
});
};

View File

@ -1,7 +1,11 @@
import { Client } from 'dsteem';
const client = new Client('https://api.steemit.com');
/* eslint-disable no-console */
import { Client, PrivateKey } from "dsteem";
const client = new Client("https://api.steemit.com");
import { parsePosts } from '../../utils/PostParser';
import { parsePosts, parseComments } from "../../utils/PostParser";
let rewardFund = null;
let medianPrice = null;
/**
* @method getAccount get account data
@ -38,7 +42,7 @@ export const getUser = async user => {
export const getFollows = user => {
return new Promise((resolve, reject) => {
client
.call('follow_api', 'get_follow_count', [user])
.call("follow_api", "get_follow_count", [user])
.then(result => {
resolve(result);
})
@ -71,7 +75,7 @@ export const getPosts = async (by, query) => {
export const getPost = (user, permlink) => {
return new Promise((resolve, reject) => {
try {
let post = client.database.call('get_content', [user, permlink]);
let post = client.database.call("get_content", [user, permlink]);
resolve(post);
} catch (error) {
reject(error);
@ -85,16 +89,19 @@ export const getPost = (user, permlink) => {
* @param permlink post permlink
*/
export const getComments = (user, permlink) => {
let comments;
return new Promise((resolve, reject) => {
try {
let comments = client.database.call('get_content_replies', [
user,
permlink,
]);
resolve(comments);
} catch (error) {
reject(error);
}
client.database
.call("get_content_replies", [user, permlink])
.then(result => {
comments = parseComments(result);
})
.then(() => {
resolve(comments);
})
.catch(error => {
reject(error);
});
});
};
@ -116,3 +123,48 @@ export const getPostWithComments = async (user, permlink) => {
return [post, comments];
};
/**
* @method upvote upvote a content
* @param vote vote object(author, permlink, voter, weight)
* @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);
});
});
};
/**
* @method upvoteAmount estimate upvote amount
*/
export const upvoteAmount = async input => {
if (rewardFund == null || medianPrice == null) {
rewardFund = await client.database.call("get_reward_fund", ["post"]);
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;
};

View File

@ -1,4 +1,4 @@
import * as React from 'react';
import * as React from "react";
import {
Container,
Header,
@ -8,18 +8,38 @@ import {
Button,
Icon,
Title,
} from 'native-base';
Content,
} from "native-base";
import { MarkdownEditor } from "react-native-markdown-editor";
import { StatusBar, View } from "react-native";
class EditorPage extends React.Component {
constructor(props) {
super(props);
this.onTextChange = this.onTextChange.bind(this);
this.state = {
mdData: "",
};
}
componentDidMount() {}
onTextChange = text => {
this.setState(
{
mdData: text,
},
() => {
console.log(this.state);
}
);
};
render() {
return (
<Container>
<Container style={{ flex: 1, marginTop: StatusBar.currentHeight }}>
<StatusBar translucent={true} backgroundColor={"transparent"} />
<Header>
<Left>
<Button transparent>
@ -41,6 +61,11 @@ class EditorPage extends React.Component {
</Button>
</Right>
</Header>
<MarkdownEditor
onMarkdownChange={text => {
this.onTextChange(text);
}}
/>
</Container>
);
}

View File

@ -1,4 +1,4 @@
import React from 'react';
import React from "react";
import {
StyleSheet,
FlatList,
@ -6,7 +6,7 @@ import {
StatusBar,
Dimensions,
ActivityIndicator,
} from 'react-native';
} from "react-native";
import {
Container,
Header,
@ -18,17 +18,16 @@ import {
Tab,
Icon,
ScrollableTab,
} from 'native-base';
} from "native-base";
// STEEM
import { getPosts } from '../../providers/steem/Dsteem';
import { getPosts } from "../../providers/steem/Dsteem";
// LIBRARIES
import Placeholder from 'rn-placeholder';
import Placeholder from "rn-placeholder";
// COMPONENTS
import PostCard from '../../components/post-card/PostCard';
import PostCard from "../../components/post-card/PostCard";
/* eslint-enable no-unused-vars */
class FeedPage extends React.Component {
@ -38,8 +37,8 @@ class FeedPage extends React.Component {
this.state = {
isReady: false,
posts: [],
start_author: '',
start_permlink: '',
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
};
@ -50,7 +49,7 @@ class FeedPage extends React.Component {
}
getFeed = () => {
getPosts('feed', { tag: this.props.user.name, limit: 5 })
getPosts("feed", { tag: this.props.user.name, limit: 10 })
.then(result => {
this.setState({
isReady: true,
@ -67,7 +66,7 @@ class FeedPage extends React.Component {
getMore = () => {
this.setState({ loading: true });
getPosts('feed', {
getPosts("feed", {
tag: this.props.user.name,
limit: 10,
start_author: this.state.start_author,
@ -100,10 +99,11 @@ class FeedPage extends React.Component {
return (
<View
style={{
alignContent: 'center',
alignItems: 'center',
alignContent: "center",
alignItems: "center",
marginTop: 10,
borderColor: '#CED0CE',
marginBottom: 40,
borderColor: "#CED0CE",
}}
>
<ActivityIndicator animating size="large" />
@ -120,12 +120,13 @@ class FeedPage extends React.Component {
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<View style={styles.card}>
<PostCard
navigation={this.props.navigation}
content={item}
/>
</View>
<PostCard
style={{ shadowColor: "white" }}
navigation={this.props.navigation}
content={item}
user={this.props.user}
isLoggedIn={true}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={this.getMore}
@ -175,39 +176,26 @@ class FeedPage extends React.Component {
const styles = StyleSheet.create({
container: {
backgroundColor: '#F9F9F9',
backgroundColor: "#F9F9F9",
flex: 1,
top: StatusBar.currentHeight,
},
placeholder: {
backgroundColor: 'white',
backgroundColor: "white",
padding: 20,
borderStyle: 'solid',
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: '#e2e5e8',
borderRadius: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
card: {
backgroundColor: 'white',
shadowColor: 'white',
marginRight: 0,
marginLeft: 0,
marginTop: 10,
marginBottom: 0,
borderWidth: 1,
borderColor: '#e2e5e8',
borderColor: "#e2e5e8",
borderRadius: 5,
paddingHorizontal: 0,
paddingVertical: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
tabs: {
position: 'absolute',
top: Dimensions.get('window').width / 30,
alignItems: 'center',
position: "absolute",
top: Dimensions.get("window").width / 30,
alignItems: "center",
},
});

View File

@ -1,7 +1,7 @@
/* eslint-disable no-unused-vars */
/* eslint-disable no-console */
import React from 'react';
import { StyleSheet, View, StatusBar, Dimensions } from 'react-native';
import React from "react";
import { StyleSheet, View, StatusBar, Dimensions } from "react-native";
import {
Container,
Header,
@ -10,25 +10,25 @@ import {
Right,
Text,
Icon,
} from 'native-base';
import FastImage from 'react-native-fast-image';
} from "native-base";
import FastImage from "react-native-fast-image";
// REDUX
import { connect } from 'react-redux';
import { fetchAccount } from '../../redux/actions/userActions';
import store from '../../redux/store/Store';
import { connect } from "react-redux";
import { fetchAccount } from "../../redux/actions/userActions";
import store from "../../redux/store/Store";
// STEEM
import { getUserData, getAuthStatus } from '../../realm/Realm';
import { getUserData, getAuthStatus } from "../../realm/Realm";
// SCREENS
import FeedPage from './feed';
import HotPage from './hot';
import TrendingPage from './trending';
import FeedPage from "./feed";
import HotPage from "./hot";
import TrendingPage from "./trending";
import ScrollableTabView from 'react-native-scrollable-tab-view';
import CustomTabBar from './FeedTabs';
import Placeholder from 'rn-placeholder';
import ScrollableTabView from "react-native-scrollable-tab-view";
import CustomTabBar from "./FeedTabs";
import Placeholder from "rn-placeholder";
/* eslint-enable no-unused-vars */
@ -38,7 +38,7 @@ class HomePage extends React.Component {
this.state = {
user: {
name: 'null',
name: "null",
},
isLoggedIn: false,
isLoading: true,
@ -78,13 +78,13 @@ class HomePage extends React.Component {
render() {
return (
<Container style={{ flex: 1, top: StatusBar.currentHeight }}>
<StatusBar translucent={true} backgroundColor={'transparent'} />
<StatusBar translucent={true} backgroundColor={"transparent"} />
<Header
noShadow
style={{
backgroundColor: '#284b78',
backgroundColor: "#284b78",
borderBottomWidth: 0,
borderColor: '#284b78',
borderColor: "#284b78",
}}
>
<Left>
@ -106,7 +106,7 @@ class HomePage extends React.Component {
height: 30,
borderRadius: 15,
borderWidth: 1,
borderColor: 'white',
borderColor: "white",
}}
/>
</Button>
@ -114,7 +114,7 @@ class HomePage extends React.Component {
<Right>
<Button transparent>
<Icon
style={{ color: 'white', fontWeight: 'bold' }}
style={{ color: "white", fontWeight: "bold" }}
name="search"
/>
</Button>
@ -123,20 +123,20 @@ class HomePage extends React.Component {
<ScrollableTabView
style={{
alignSelf: 'center',
backgroundColor: 'transparent',
alignSelf: "center",
backgroundColor: "transparent",
}}
renderTabBar={() => (
<CustomTabBar
style={{
alignSelf: 'center',
alignSelf: "center",
height: 40,
backgroundColor: '#284b78',
backgroundColor: "#284b78",
}}
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={3} // default 3
activeColor={'#fff'}
inactiveColor={'#fff'}
activeColor={"#fff"}
inactiveColor={"#fff"}
/>
)}
>
@ -144,9 +144,9 @@ class HomePage extends React.Component {
tabLabel="Feed"
style={{
paddingHorizontal: 7,
backgroundColor: '#f9f9f9',
backgroundColor: "#f9f9f9",
flex: 1,
minWidth: Dimensions.get('window').width / 1,
minWidth: Dimensions.get("window").width / 1,
}}
>
{this.state.isLoading ? (
@ -183,17 +183,17 @@ class HomePage extends React.Component {
</View>
</View>
) : (
<View style={{ alignItems: 'center' }}>
<View style={{ alignItems: "center" }}>
{this.state.isLoggedIn ? null : (
<Button
light
onPress={() =>
this.props.navigation.navigate(
'Login'
"Login"
)
}
style={{
alignSelf: 'center',
alignSelf: "center",
marginTop: 100,
}}
>
@ -208,6 +208,7 @@ class HomePage extends React.Component {
<FeedPage
navigation={this.props.navigation}
user={this.state.user}
isLoggedIn={this.state.isLoggedIn}
/>
) : null}
</View>
@ -215,26 +216,31 @@ class HomePage extends React.Component {
tabLabel="Hot"
style={{
paddingHorizontal: 7,
backgroundColor: '#f9f9f9',
backgroundColor: "#f9f9f9",
flex: 1,
minWidth: Dimensions.get('window').width / 1,
minWidth: Dimensions.get("window").width / 1,
}}
>
<HotPage
navigation={this.props.navigation}
account={this.props.account}
user={this.state.user}
isLoggedIn={this.state.isLoggedIn}
/>
</View>
<View
tabLabel="Trending"
style={{
paddingHorizontal: 7,
backgroundColor: '#f9f9f9',
backgroundColor: "#f9f9f9",
flex: 1,
minWidth: Dimensions.get('window').width / 1,
minWidth: Dimensions.get("window").width / 1,
}}
>
<TrendingPage navigation={this.props.navigation} />
<TrendingPage
navigation={this.props.navigation}
user={this.state.user}
isLoggedIn={this.state.isLoggedIn}
/>
</View>
</ScrollableTabView>
</Container>
@ -245,20 +251,20 @@ class HomePage extends React.Component {
/* eslint-disable no-unused-vars */
const styles = StyleSheet.create({
container: {
backgroundColor: '#F9F9F9',
backgroundColor: "#F9F9F9",
flex: 1,
},
tabs: {
flex: 1,
},
placeholder: {
backgroundColor: 'white',
backgroundColor: "white",
padding: 20,
borderStyle: 'solid',
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: '#e2e5e8',
borderRadius: 0,
borderColor: "#e2e5e8",
borderRadius: 5,
marginRight: 0,
marginLeft: 0,
marginTop: 10,

View File

@ -1,24 +1,24 @@
/* eslint-disable no-unused-vars */
import React from 'react';
import React from "react";
import {
StyleSheet,
FlatList,
View,
StatusBar,
ActivityIndicator,
} from 'react-native';
} from "react-native";
// STEEM
import { getPosts } from '../../providers/steem/Dsteem';
import { getPosts } from "../../providers/steem/Dsteem";
// LIBRARIES
import Placeholder from 'rn-placeholder';
import Placeholder from "rn-placeholder";
// COMPONENTS
import PostCard from '../../components/post-card/PostCard';
import PostCard from "../../components/post-card/PostCard";
// SCREENS
import PostPage from '../../screens/single-post/Post';
import PostPage from "../../screens/single-post/Post";
/* eslint-enable no-unused-vars */
class HotPage extends React.Component {
@ -28,11 +28,11 @@ class HotPage extends React.Component {
this.state = {
isReady: false,
posts: [],
user: [],
start_author: '',
start_permlink: '',
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
isLoggedIn: this.props.isLoggedIn,
};
}
@ -41,7 +41,7 @@ class HotPage extends React.Component {
}
getHotPosts = () => {
getPosts('hot', { tag: '', limit: 5 })
getPosts("hot", { tag: "", limit: 10 })
.then(result => {
this.setState({
isReady: true,
@ -58,8 +58,8 @@ class HotPage extends React.Component {
getMoreHot = () => {
this.setState({ loading: true });
getPosts('hot', {
tag: '',
getPosts("hot", {
tag: "",
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
@ -91,10 +91,11 @@ class HotPage extends React.Component {
return (
<View
style={{
alignContent: 'center',
alignItems: 'center',
alignContent: "center",
alignItems: "center",
marginTop: 10,
borderColor: '#CED0CE',
marginBottom: 40,
borderColor: "#CED0CE",
}}
>
<ActivityIndicator animating size="large" />
@ -111,14 +112,14 @@ class HotPage extends React.Component {
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<View style={styles.card}>
<PostCard
navigation={this.props.navigation}
content={item}
/>
</View>
<PostCard
navigation={this.props.navigation}
content={item}
user={this.props.user}
isLoggedIn={this.state.isLoggedIn}
/>
)}
keyExtractor={(post, index) => index.toString()}
keyExtractor={post => post.id.toString()}
onEndReached={this.getMoreHot}
refreshing={this.state.refreshing}
onRefresh={() => this.refreshHotPosts()}
@ -166,34 +167,21 @@ class HotPage extends React.Component {
const styles = StyleSheet.create({
container: {
backgroundColor: '#F9F9F9',
backgroundColor: "#F9F9F9",
flex: 1,
top: StatusBar.currentHeight,
},
placeholder: {
backgroundColor: 'white',
backgroundColor: "white",
padding: 20,
borderStyle: 'solid',
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: '#e2e5e8',
borderRadius: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
card: {
backgroundColor: 'white',
shadowColor: 'white',
marginRight: 0,
marginLeft: 0,
marginTop: 10,
marginBottom: 0,
borderWidth: 1,
borderColor: '#e7eaec',
borderColor: "#e2e5e8",
borderRadius: 5,
paddingHorizontal: 0,
paddingVertical: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
});

View File

@ -1,18 +1,18 @@
import React from 'react';
import React from "react";
/* eslint-disable no-unused-vars */
import { StyleSheet, FlatList, View, ActivityIndicator } from 'react-native';
import { StyleSheet, FlatList, View, ActivityIndicator } from "react-native";
// STEEM
import { getPosts } from '../../providers/steem/Dsteem';
import { getPosts } from "../../providers/steem/Dsteem";
// LIBRARIES
import Placeholder from 'rn-placeholder';
import Placeholder from "rn-placeholder";
// COMPONENTS
import PostCard from '../../components/post-card/PostCard';
import PostCard from "../../components/post-card/PostCard";
// SCREENS
import PostPage from '../../screens/single-post/Post';
import PostPage from "../../screens/single-post/Post";
/* eslint-enable no-unused-vars */
class TrendingPage extends React.Component {
@ -23,10 +23,11 @@ class TrendingPage extends React.Component {
isReady: false,
posts: [],
user: [],
start_author: '',
start_permlink: '',
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
isLoggedIn: this.props.isLoggedIn,
};
}
@ -35,7 +36,7 @@ class TrendingPage extends React.Component {
}
getTrending = () => {
getPosts('trending', { tag: '', limit: 5 })
getPosts("trending", { tag: "", limit: 10 })
.then(result => {
this.setState({
isReady: true,
@ -52,8 +53,8 @@ class TrendingPage extends React.Component {
getMore = () => {
this.setState({ loading: true });
getPosts('trending', {
tag: '',
getPosts("trending", {
tag: "",
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
@ -85,11 +86,11 @@ class TrendingPage extends React.Component {
return (
<View
style={{
alignContent: 'center',
alignItems: 'center',
alignContent: "center",
alignItems: "center",
marginTop: 10,
marginBottom: 40,
borderColor: '#CED0CE',
borderColor: "#CED0CE",
}}
>
<ActivityIndicator animating size="large" />
@ -105,12 +106,12 @@ class TrendingPage extends React.Component {
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<View style={styles.card}>
<PostCard
navigation={this.props.navigation}
content={item}
/>
</View>
<PostCard
navigation={this.props.navigation}
content={item}
user={this.props.user}
isLoggedIn={this.state.isLoggedIn}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={this.getMore}
@ -160,33 +161,20 @@ class TrendingPage extends React.Component {
const styles = StyleSheet.create({
container: {
backgroundColor: '#F9F9F9',
backgroundColor: "#F9F9F9",
flex: 1,
},
placeholder: {
backgroundColor: 'white',
backgroundColor: "white",
padding: 20,
borderStyle: 'solid',
borderStyle: "solid",
borderWidth: 1,
borderTopWidth: 1,
borderColor: '#e2e5e8',
borderRadius: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
card: {
backgroundColor: 'white',
shadowColor: 'white',
marginRight: 0,
marginLeft: 0,
marginTop: 10,
marginBottom: 0,
borderWidth: 1,
borderColor: '#e2e5e8',
borderColor: "#e2e5e8",
borderRadius: 5,
paddingHorizontal: 0,
paddingVertical: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
},
});

View File

@ -1,11 +1,14 @@
import React from 'react';
import { Dimensions, StyleSheet, StatusBar } from 'react-native';
/* eslint-disable no-console */
/* eslint-disable no-unused-vars */
import React from "react";
import { Dimensions, StyleSheet, StatusBar, FlatList } from "react-native";
import {
Container,
CardItem,
Thumbnail,
Content,
Header,
Card,
View,
Left,
Body,
@ -14,55 +17,77 @@ import {
Icon,
Text,
Title,
} from 'native-base';
import HTMLView from 'react-native-htmlview';
import HTML from 'react-native-render-html';
import { Client } from 'dsteem';
const client = new Client('https://api.steemit.com');
} from "native-base";
import HTML from "react-native-render-html";
import { Client } from "dsteem";
const client = new Client("https://api.steemit.com");
import { parsePost, protocolUrl2Obj } from '../../utils/PostParser';
import { parsePost, protocolUrl2Obj } from "../../utils/PostParser";
import { getComments } from "../../providers/steem/Dsteem";
import Comment from "../../components/comment/Comment";
/* eslint-enable no-unused-vars */
class SinglePostPage extends React.Component {
constructor(props) {
super(props);
this.state = {
comments: [],
};
}
componentDidMount() {}
componentDidMount() {
getComments(
this.props.navigation.state.params.content.author,
this.props.navigation.state.params.content.permlink
)
.then(replies => {
console.log(replies);
this.setState({
comments: replies,
});
})
.catch(error => {
console.log(error);
});
}
onLinkPress(evt, href, attribs) {
let steemPost = href.match(
/^https?:\/\/(.*)\/(.*)\/(@[\w\.\d-]+)\/(.*)/i
);
if (attribs.class === 'markdown-author-link') {
this.props.navigation.navigate('Author', { author: href });
} else if (steemPost.length > 3) {
steemPost[3] = steemPost[3].replace('@', '');
if (attribs.class === "markdown-author-link") {
this.props.navigation.navigate("Author", { author: href });
} else if (steemPost != null) {
steemPost[3] = steemPost[3].replace("@", "");
client.database
.call('get_content', [steemPost[3], steemPost[4]])
.call("get_content", [steemPost[3], steemPost[4]])
.then(result => {
let content = parsePost(result);
this.props.navigation.push('Post', { content: content });
this.props.navigation.push("Post", { content: content });
})
.catch(err => {
alert(err);
});
} else {
console.log(href);
console.log(attribs);
}
}
alterNode(node) {
if (node.name == 'img') {
node.attribs.style = `max-width: ${Dimensions.get('window').width}`;
} else if (node.name == 'iframe') {
node.attribs.style = `max-width: ${Dimensions.get('window').width}`;
node.attribs.style = `width: ${Dimensions.get('window').width}`;
if (node.name == "img") {
node.attribs.style = `max-width: ${Dimensions.get("window").width}`;
} else if (node.name == "iframe") {
node.attribs.style = `max-width: ${Dimensions.get("window").width}`;
node.attribs.style = `width: ${Dimensions.get("window").width}`;
node.attribs.height = 200;
}
}
render() {
return (
<Container style={{ top: StatusBar.currentHeight }}>
<Container style={{ top: StatusBar.currentHeight, flex: 1 }}>
<Header>
<Left>
<Button
@ -84,13 +109,13 @@ class SinglePostPage extends React.Component {
</Button>
</Right>
</Header>
<Content>
<CardItem style={{ flexDirection: 'row' }}>
<Content style={{ flex: 1 }}>
<CardItem style={{ flexDirection: "row" }}>
<View style={{ flex: 0.2 }}>
<Thumbnail
style={{
borderWidth: 1,
borderColor: 'lightgray',
borderColor: "lightgray",
}}
source={{
uri: this.props.navigation.state.params
@ -113,7 +138,7 @@ class SinglePostPage extends React.Component {
}
</Text>
</View>
<View style={{ flex: 0.4, alignItems: 'flex-end' }}>
<View style={{ flex: 0.4, alignItems: "flex-end" }}>
<Text note>
{
this.props.navigation.state.params.content
@ -123,28 +148,69 @@ class SinglePostPage extends React.Component {
</View>
</CardItem>
<CardItem>
<Text style={{ fontWeight: 'bold' }}>
<Text style={{ fontWeight: "bold" }}>
{this.props.navigation.state.params.content.title}
</Text>
</CardItem>
<HTML
html={this.props.navigation.state.params.content.body}
staticContentMaxWidth={
Dimensions.get('window').width - 20
}
onLinkPress={(evt, href, hrefatr) =>
this.onLinkPress(evt, href, hrefatr)
}
containerStyle={{ padding: 10 }}
textSelectable={true}
tagsStyles={styles}
ignoredTags={['script']}
ignoredTags={["script"]}
debug={false}
alterNode={node => {
this.alterNode(node);
}}
imagesMaxWidth={Dimensions.get('window').width}
imagesMaxWidth={Dimensions.get("window").width}
/>
<View style={{ flex: 1, flexDirection: "row" }}>
<Left>
<Text>
{
this.props.navigation.state.params.content
.vote_count
}{" "}
Votes
</Text>
</Left>
<Body>
<Text>
{
this.props.navigation.state.params.content
.children
}{" "}
Comments
</Text>
</Body>
<Right>
<Text>
$
{
this.props.navigation.state.params.content
.pending_payout_value
}
</Text>
</Right>
</View>
<View style={{ flex: 1, backgroundColor: "white" }}>
<FlatList
style={{ backgroundColor: "white" }}
removeClippedSubviews={false}
data={this.state.comments}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<Comment
comment={item}
navigation={this.props.navigation}
/>
)}
keyExtractor={item => item.permlink.toString()}
/>
</View>
</Content>
</Container>
);
@ -154,18 +220,14 @@ class SinglePostPage extends React.Component {
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
alignItems: "center",
justifyContent: "center",
},
iframe: {
maxWidth: Dimensions.get('window').width,
marginVertical: 10,
left: -10,
maxWidth: Dimensions.get("window").width,
},
p: {},
img: {
left: -10,
marginVertical: 10,
maxWidth: Dimensions.get("window").width,
},
});

View File

@ -1,7 +1,7 @@
import Remarkable from 'remarkable';
import { postSummary } from './PostSummary';
import { reputation } from './Reputation';
import moment from 'moment';
import Remarkable from "remarkable";
import { postSummary } from "./PostSummary";
import { reputation } from "./Reputation";
import moment from "moment";
const md = new Remarkable({ html: true, breaks: true, linkify: true });
@ -11,7 +11,7 @@ export const replaceAuthorNames = input => {
/(^|[^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 || '');
const preceedings = (preceeding1 || "") + (preceeding2 || "");
return `${preceedings}<a class="markdown-author-link" href="${userLower}" data-author="${userLower}">@${user}</a>`;
}
@ -21,8 +21,8 @@ export const replaceAuthorNames = input => {
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 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 (
@ -34,7 +34,7 @@ export const replaceTags = input => {
export const markDown2Html = input => {
if (!input) {
return '';
return "";
}
// Start replacing user names
@ -63,7 +63,7 @@ export const parsePosts = posts => {
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);
@ -93,7 +93,7 @@ export const parsePosts = 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.json_metadata.image ? (post.image = post.json_metadata.image[0]) : "";
post.pending_payout_value = parseFloat(post.pending_payout_value).toFixed(
2
);
@ -121,37 +121,56 @@ export const parsePost = post => {
};
export const protocolUrl2Obj = url => {
let urlPart = url.split('://')[1];
let urlPart = url.split("://")[1];
// remove last char if /
if (urlPart.endsWith('/')) {
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' };
return { type: "filter" };
}
// filter with tag
if (parts.length === 2) {
return { type: 'filter-tag', filter: parts[0], tag: parts[1] };
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('@', '') };
if (parts.length === 1 && parts[0].startsWith("@")) {
return { type: "account", account: parts[0].replace("@", "") };
}
// post
if (parts.length === 3 && parts[1].startsWith('@')) {
if (parts.length === 3 && parts[1].startsWith("@")) {
return {
type: 'post',
type: "post",
cat: parts[0],
author: parts[1].replace('@', ''),
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;
};