mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-22 23:28:56 +03:00
comments, commenting & voting
This commit is contained in:
parent
f15297f6b5
commit
bb9c919e1e
@ -6,6 +6,7 @@ import {
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
ActivityIndicator,
|
||||
FlatList,
|
||||
} from "react-native";
|
||||
import {
|
||||
Card,
|
||||
@ -21,19 +22,26 @@ import {
|
||||
} from "native-base";
|
||||
import { Popover, PopoverController } from "react-native-modal-popover";
|
||||
import Slider from "react-native-slider";
|
||||
import Modal from "react-native-modal";
|
||||
import HTML from "react-native-render-html";
|
||||
|
||||
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 = {
|
||||
amount: "0.00",
|
||||
value: 0.1,
|
||||
replies: [],
|
||||
isVoting: false,
|
||||
isVoted: false,
|
||||
isModalVisible: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -84,6 +92,74 @@ class Comment extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
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.comment.author,
|
||||
permlink: this.props.comment.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,
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
toggleModal = () => {
|
||||
this.setState({
|
||||
isModalVisible: !this.state.isModalVisible,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
@ -96,7 +172,7 @@ class Comment extends React.PureComponent {
|
||||
}/avatar/small`,
|
||||
}}
|
||||
/>
|
||||
<Card style={{ flex: 0.91, borderRadius: 10 }}>
|
||||
<Card style={styles.commentBox}>
|
||||
<CardItem style={{ borderRadius: 10 }}>
|
||||
<Left>
|
||||
<View style={styles.author}>
|
||||
@ -130,26 +206,250 @@ class Comment extends React.PureComponent {
|
||||
</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
|
||||
<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: 1 }}
|
||||
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
|
||||
onPress={this.toggleModal}
|
||||
style={styles.payoutButton}
|
||||
>
|
||||
<Text style={styles.payout}>
|
||||
$
|
||||
{
|
||||
this.props.comment
|
||||
.pending_payout_value
|
||||
}
|
||||
</Text>
|
||||
<Icon
|
||||
name="md-arrow-dropdown"
|
||||
style={styles.payoutIcon}
|
||||
/>
|
||||
<Modal
|
||||
isVisible={this.state.isModalVisible}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flex: 0.8,
|
||||
backgroundColor: "white",
|
||||
borderRadius: 10,
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={this.toggleModal}
|
||||
>
|
||||
<Text>Tap to close!</Text>
|
||||
</TouchableOpacity>
|
||||
<FlatList
|
||||
data={
|
||||
this.props.comment
|
||||
.active_votes
|
||||
}
|
||||
keyExtractor={item =>
|
||||
item.voter.toString()
|
||||
}
|
||||
renderItem={({ item }) => (
|
||||
<View
|
||||
style={{
|
||||
flexDirection:
|
||||
"row",
|
||||
borderColor:
|
||||
"lightgray",
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
}}
|
||||
>
|
||||
<Thumbnail
|
||||
style={{
|
||||
width: 34,
|
||||
height: 34,
|
||||
borderRadius: 17,
|
||||
flex: 0.1,
|
||||
}}
|
||||
source={{
|
||||
uri:
|
||||
item.avatar,
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
flex: 0.5,
|
||||
}}
|
||||
>
|
||||
{" "}
|
||||
{item.voter} (
|
||||
{item.reputation})
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
flex: 0.2,
|
||||
}}
|
||||
>
|
||||
{item.value}$
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
flex: 0.2,
|
||||
}}
|
||||
>
|
||||
{item.percent}%
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
</Modal>
|
||||
</TouchableOpacity>
|
||||
</Body>
|
||||
<TouchableOpacity
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate(
|
||||
"Reply",
|
||||
{
|
||||
content: this.props.comment,
|
||||
user: this.props.user,
|
||||
}
|
||||
)
|
||||
}
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<Text style={{ fontSize: 10 }}>Reply</Text>
|
||||
<Icon
|
||||
style={{
|
||||
color: "#007ee5",
|
||||
fontSize: 15,
|
||||
left: 2,
|
||||
}}
|
||||
name={"redo"}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</Left>
|
||||
</CardItem>
|
||||
</Card>
|
||||
</View>
|
||||
@ -163,6 +463,8 @@ class Comment extends React.PureComponent {
|
||||
<Comment
|
||||
comment={reply}
|
||||
navigation={this.props.navigation}
|
||||
isLoggedIn={this.props.isLoggedIn}
|
||||
user={this.props.user}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
@ -184,13 +486,16 @@ const styles = StyleSheet.create({
|
||||
marginHorizontal: 10,
|
||||
flexDirection: "row",
|
||||
},
|
||||
commentBox: {
|
||||
borderRadius: 10,
|
||||
flex: 1,
|
||||
},
|
||||
avatar: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
borderColor: "lightgray",
|
||||
borderWidth: 1,
|
||||
flex: 0.09,
|
||||
marginTop: 10,
|
||||
},
|
||||
author: {
|
||||
@ -214,6 +519,54 @@ const styles = StyleSheet.create({
|
||||
justifyContent: "flex-start",
|
||||
flexDirection: "row",
|
||||
},
|
||||
upvoteButton: {
|
||||
margin: 0,
|
||||
flexDirection: "row",
|
||||
paddingVertical: 0,
|
||||
},
|
||||
upvoteIcon: {
|
||||
alignSelf: "flex-start",
|
||||
fontSize: 20,
|
||||
color: "#007ee5",
|
||||
margin: 0,
|
||||
width: 18,
|
||||
},
|
||||
payout: {
|
||||
alignSelf: "center",
|
||||
fontSize: 10,
|
||||
color: "#626262",
|
||||
marginLeft: 3,
|
||||
},
|
||||
payoutIcon: {
|
||||
fontSize: 15,
|
||||
marginHorizontal: 3,
|
||||
color: "#a0a0a0",
|
||||
alignSelf: "center",
|
||||
},
|
||||
payoutButton: {
|
||||
flexDirection: "row",
|
||||
alignSelf: "flex-start",
|
||||
paddingVertical: 2,
|
||||
},
|
||||
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,
|
||||
},
|
||||
});
|
||||
|
||||
export default Comment;
|
||||
|
@ -47,7 +47,9 @@ class PostCard extends React.PureComponent {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.calculateEstimatedAmount();
|
||||
if (this.props.isLoggedIn == true) {
|
||||
this.calculateEstimatedAmount();
|
||||
}
|
||||
}
|
||||
|
||||
calculateEstimatedAmount = async () => {
|
||||
@ -170,6 +172,8 @@ class PostCard extends React.PureComponent {
|
||||
onPress={() =>
|
||||
this.props.navigation.push("Post", {
|
||||
content: this.props.content,
|
||||
isLoggedIn: this.props.isLoggedIn,
|
||||
user: this.props.user,
|
||||
})
|
||||
}
|
||||
>
|
||||
|
177
src/components/reply/Reply.js
Normal file
177
src/components/reply/Reply.js
Normal file
@ -0,0 +1,177 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from "react";
|
||||
import {
|
||||
StyleSheet,
|
||||
Image,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
ActivityIndicator,
|
||||
FlatList,
|
||||
TextInput,
|
||||
} from "react-native";
|
||||
import {
|
||||
Card,
|
||||
CardItem,
|
||||
Header,
|
||||
Left,
|
||||
Right,
|
||||
Thumbnail,
|
||||
Title,
|
||||
View,
|
||||
Icon,
|
||||
Body,
|
||||
Text,
|
||||
Button,
|
||||
} from "native-base";
|
||||
import { Popover, PopoverController } from "react-native-modal-popover";
|
||||
import Slider from "react-native-slider";
|
||||
import Modal from "react-native-modal";
|
||||
import HTML from "react-native-render-html";
|
||||
|
||||
import {
|
||||
upvote,
|
||||
upvoteAmount,
|
||||
postComment,
|
||||
} 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";
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
class Reply extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
comment: "",
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(this.props.navigation.state.params);
|
||||
}
|
||||
|
||||
postComment = async () => {
|
||||
this.setState({ isLoading: true });
|
||||
let content = this.props.navigation.state.params.content;
|
||||
let user = this.props.navigation.state.params.user;
|
||||
let userData;
|
||||
let postingKey;
|
||||
|
||||
let comment = {
|
||||
parent_author: content.author,
|
||||
parent_permlink: content.permlink,
|
||||
author: user.name,
|
||||
permlink: this.commentPermlink(content.author, content.permlink),
|
||||
title: this.commentPermlink(content.author, content.permlink),
|
||||
body: this.state.comment,
|
||||
json_metadata: JSON.stringify({
|
||||
app: "eSteem",
|
||||
community: "eSteem",
|
||||
}),
|
||||
};
|
||||
|
||||
await getUserData().then(result => {
|
||||
userData = Array.from(result);
|
||||
postingKey = decryptKey(userData[0].postingKey, "pinCode");
|
||||
});
|
||||
|
||||
postComment(comment, postingKey)
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
comment: "",
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Method to format permlink for a comment
|
||||
* @param parent_author
|
||||
* @param parent_permlink
|
||||
*/
|
||||
commentPermlink = (parent_author, parent_permlink) => {
|
||||
const timeStr = new Date()
|
||||
.toISOString()
|
||||
.replace(/[^a-zA-Z0-9]+/g, "")
|
||||
.toLocaleLowerCase();
|
||||
parent_permlink = parent_permlink.replace(/(-\d{8}t\d{9}z)/g, "");
|
||||
return "re" + parent_author + "-" + parent_permlink + "-" + timeStr;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={{ backgroundColor: "white" }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
onPress={() => this.props.navigation.pop()}
|
||||
>
|
||||
<Icon name="arrow-back" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Text>Reply</Text>
|
||||
</Body>
|
||||
<Right />
|
||||
</Header>
|
||||
<View style={{ padding: 10 }}>
|
||||
<TextInput
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: "lightgray",
|
||||
borderRadius: 5,
|
||||
padding: 10,
|
||||
minHeight: 100,
|
||||
}}
|
||||
multiline={true}
|
||||
numberOfLines={4}
|
||||
placeholder={`Replying to @${
|
||||
this.props.navigation.state.params.content.author
|
||||
}`}
|
||||
onChangeText={comment => this.setState({ comment })}
|
||||
value={this.state.comment}
|
||||
/>
|
||||
<View style={{ flexDirection: "row-reverse" }}>
|
||||
<Button
|
||||
onPress={this.postComment}
|
||||
style={{
|
||||
alignSelf: "flex-end",
|
||||
marginTop: 10,
|
||||
borderRadius: 20,
|
||||
}}
|
||||
>
|
||||
{this.state.isLoading ? (
|
||||
<ActivityIndicator
|
||||
style={{ marginHorizontal: 50 }}
|
||||
/>
|
||||
) : (
|
||||
<Text>Submit</Text>
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
style={{
|
||||
alignSelf: "flex-end",
|
||||
marginRight: 10,
|
||||
borderRadius: 50,
|
||||
}}
|
||||
>
|
||||
<Icon name={"images"} />
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
reply: {},
|
||||
});
|
||||
|
||||
export default Reply;
|
@ -1,36 +1,37 @@
|
||||
import {
|
||||
createStackNavigator,
|
||||
createBottomTabNavigator,
|
||||
} from 'react-navigation';
|
||||
} from "react-navigation";
|
||||
|
||||
import React from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import React from "react";
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
// ICONS
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import Entypo from 'react-native-vector-icons/Entypo';
|
||||
import FontAwesome from 'react-native-vector-icons/FontAwesome';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||
import Entypo from "react-native-vector-icons/Entypo";
|
||||
import FontAwesome from "react-native-vector-icons/FontAwesome";
|
||||
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
|
||||
// PAGES
|
||||
import EditorPage from '../screens/editor/editor';
|
||||
import ProfilePage from '../screens/profile/profile';
|
||||
import HomePage from '../screens/home/home';
|
||||
import WalletPage from '../screens/wallet/wallet';
|
||||
import NotificationPage from '../screens/notifications/notification';
|
||||
import SinglePostPage from '../screens/single-post/Post';
|
||||
import LoginPage from '../screens/login/Login';
|
||||
import AuthorPage from '../screens/author-profile/Author';
|
||||
import DiscoverPage from '../screens/discover/Discover';
|
||||
import EditorPage from "../screens/editor/editor";
|
||||
import ProfilePage from "../screens/profile/profile";
|
||||
import HomePage from "../screens/home/home";
|
||||
import WalletPage from "../screens/wallet/wallet";
|
||||
import NotificationPage from "../screens/notifications/notification";
|
||||
import SinglePostPage from "../screens/single-post/Post";
|
||||
import LoginPage from "../screens/login/Login";
|
||||
import AuthorPage from "../screens/author-profile/Author";
|
||||
import DiscoverPage from "../screens/discover/Discover";
|
||||
import ReplyPage from "../components/reply/Reply";
|
||||
|
||||
const HomeScreen = ({ navigation }) => <HomePage navigation={navigation} />;
|
||||
|
||||
HomeScreen.navigationOptions = {
|
||||
tabBarLabel: 'Home',
|
||||
title: 'Home',
|
||||
tabBarLabel: "Home",
|
||||
title: "Home",
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<MaterialCommunityIcons
|
||||
name={focused ? 'home' : 'home'}
|
||||
name={focused ? "home" : "home"}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
@ -42,10 +43,10 @@ const ProfileScreen = ({ navigation }) => (
|
||||
);
|
||||
|
||||
ProfileScreen.navigationOptions = {
|
||||
tabBarLabel: 'Profile',
|
||||
tabBarLabel: "Profile",
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'md-contact' : 'md-contact'}
|
||||
name={focused ? "md-contact" : "md-contact"}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
@ -55,10 +56,10 @@ ProfileScreen.navigationOptions = {
|
||||
const EditorScreen = ({ navigation }) => <EditorPage navigation={navigation} />;
|
||||
|
||||
EditorScreen.navigationOptions = {
|
||||
tabBarLabel: 'Editor',
|
||||
tabBarLabel: "Editor",
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Entypo
|
||||
name={focused ? 'pencil' : 'pencil'}
|
||||
name={focused ? "pencil" : "pencil"}
|
||||
size={26}
|
||||
style={styles.post}
|
||||
style={{ color: tintColor }}
|
||||
@ -69,10 +70,10 @@ EditorScreen.navigationOptions = {
|
||||
const WalletScreen = ({ navigation }) => <WalletPage navigation={navigation} />;
|
||||
|
||||
WalletScreen.navigationOptions = {
|
||||
tabBarLabel: 'Settings',
|
||||
tabBarLabel: "Settings",
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Entypo
|
||||
name={focused ? 'wallet' : 'wallet'}
|
||||
name={focused ? "wallet" : "wallet"}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
@ -84,12 +85,12 @@ const NotificationScreen = ({ navigation }) => (
|
||||
);
|
||||
|
||||
NotificationScreen.navigationOptions = {
|
||||
tabBarLabel: 'Notifications',
|
||||
tabBarLabel: "Notifications",
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-notifications' : 'ios-notifications'}
|
||||
name={focused ? "ios-notifications" : "ios-notifications"}
|
||||
size={26}
|
||||
style={{ color: tintColor, alignSelf: 'center' }}
|
||||
style={{ color: tintColor, alignSelf: "center" }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
@ -106,37 +107,39 @@ const DiscoverScreen = ({ navigation }) => (
|
||||
<DiscoverPage navigation={navigation} />
|
||||
);
|
||||
|
||||
const ReplyScreen = ({ navigation }) => <ReplyPage navigation={navigation} />;
|
||||
|
||||
const BottomTabs = createBottomTabNavigator(
|
||||
{
|
||||
Home: {
|
||||
screen: HomeScreen,
|
||||
path: '',
|
||||
path: "",
|
||||
},
|
||||
Profile: {
|
||||
screen: ProfileScreen,
|
||||
path: 'profile',
|
||||
path: "profile",
|
||||
},
|
||||
Editor: {
|
||||
screen: EditorScreen,
|
||||
path: 'editor',
|
||||
path: "editor",
|
||||
},
|
||||
Wallet: {
|
||||
screen: WalletScreen,
|
||||
path: 'wallet',
|
||||
path: "wallet",
|
||||
},
|
||||
Notifications: {
|
||||
screen: NotificationScreen,
|
||||
path: 'settings',
|
||||
path: "settings",
|
||||
},
|
||||
},
|
||||
{
|
||||
lazy: false,
|
||||
tabBarOptions: {
|
||||
activeTintColor: '#373c3f',
|
||||
inactiveTintColor: '#AFB1B3',
|
||||
activeTintColor: "#373c3f",
|
||||
inactiveTintColor: "#AFB1B3",
|
||||
style: {
|
||||
backgroundColor: 'white',
|
||||
borderTopColor: '#dedede',
|
||||
backgroundColor: "white",
|
||||
borderTopColor: "#dedede",
|
||||
borderWidth: 0,
|
||||
},
|
||||
showLabel: false,
|
||||
@ -147,7 +150,7 @@ const BottomTabs = createBottomTabNavigator(
|
||||
BottomTabs.navigationOptions = ({ navigation }) => ({
|
||||
header: null,
|
||||
style: {
|
||||
backgroundColor: 'white',
|
||||
backgroundColor: "white",
|
||||
},
|
||||
});
|
||||
|
||||
@ -158,26 +161,30 @@ const StacksOverTabs = createStackNavigator(
|
||||
},
|
||||
Post: {
|
||||
screen: SinglePostScreen,
|
||||
path: '/:category/:user/:permlink',
|
||||
path: "/:category/:user/:permlink",
|
||||
navigationOptions: ({ navigation }) => ({
|
||||
header: null,
|
||||
}),
|
||||
},
|
||||
Login: {
|
||||
screen: LoginScreen,
|
||||
path: '/login',
|
||||
path: "/login",
|
||||
},
|
||||
Author: {
|
||||
screen: AuthorScreen,
|
||||
path: '/author',
|
||||
path: "/author",
|
||||
},
|
||||
Discover: {
|
||||
screen: DiscoverScreen,
|
||||
path: '/discover',
|
||||
path: "/discover",
|
||||
},
|
||||
Reply: {
|
||||
screen: ReplyScreen,
|
||||
path: "/reply",
|
||||
},
|
||||
},
|
||||
{
|
||||
headerMode: 'none',
|
||||
headerMode: "none",
|
||||
}
|
||||
);
|
||||
|
||||
@ -193,18 +200,18 @@ class Tabs extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
this._s0 = this.props.navigation.addListener(
|
||||
'willFocus',
|
||||
"willFocus",
|
||||
this._onAction
|
||||
);
|
||||
this._s1 = this.props.navigation.addListener(
|
||||
'didFocus',
|
||||
"didFocus",
|
||||
this._onAction
|
||||
);
|
||||
this._s2 = this.props.navigation.addListener(
|
||||
'willBlur',
|
||||
"willBlur",
|
||||
this._onAction
|
||||
);
|
||||
this._s3 = this.props.navigation.addListener('didBlur', this._onAction);
|
||||
this._s3 = this.props.navigation.addListener("didBlur", this._onAction);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this._s0.remove();
|
||||
@ -213,7 +220,7 @@ class Tabs extends React.Component {
|
||||
this._s3.remove();
|
||||
}
|
||||
_onAction = a => {
|
||||
console.log('TABS EVENT', a.type, a);
|
||||
console.log("TABS EVENT", a.type, a);
|
||||
};
|
||||
render() {
|
||||
return <StacksOverTabs navigation={this.props.navigation} />;
|
||||
@ -223,7 +230,7 @@ class Tabs extends React.Component {
|
||||
const styles = StyleSheet.create({
|
||||
post: {
|
||||
borderWidth: 22,
|
||||
borderColor: 'blue',
|
||||
borderColor: "blue",
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -168,3 +168,22 @@ export const upvoteAmount = async input => {
|
||||
parseFloat(medianPrice.base);
|
||||
return estimated;
|
||||
};
|
||||
|
||||
/**
|
||||
* @method postComment post a comment/reply
|
||||
* @param comment comment object { author, permlink, ... }
|
||||
* @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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -1,7 +1,13 @@
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from "react";
|
||||
import { Dimensions, StyleSheet, StatusBar, FlatList } from "react-native";
|
||||
import {
|
||||
Dimensions,
|
||||
ActivityIndicator,
|
||||
StatusBar,
|
||||
FlatList,
|
||||
TextInput,
|
||||
} from "react-native";
|
||||
import {
|
||||
Container,
|
||||
CardItem,
|
||||
@ -23,7 +29,9 @@ import { Client } from "dsteem";
|
||||
const client = new Client("https://api.steemit.com");
|
||||
|
||||
import { parsePost, protocolUrl2Obj } from "../../utils/PostParser";
|
||||
import { getComments } from "../../providers/steem/Dsteem";
|
||||
import { getComments, postComment } from "../../providers/steem/Dsteem";
|
||||
import { decryptKey } from "../../utils/Crypto";
|
||||
import { getUserData } from "../../realm/Realm";
|
||||
import Comment from "../../components/comment/Comment";
|
||||
import styles from "../../styles/post.styles";
|
||||
/* eslint-enable no-unused-vars */
|
||||
@ -33,10 +41,13 @@ class SinglePostPage extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
comments: [],
|
||||
comment: "",
|
||||
isLoading: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log(this.props.navigation.state.params);
|
||||
if (this.props.navigation.state.params.content.children > 0) {
|
||||
getComments(
|
||||
this.props.navigation.state.params.content.author,
|
||||
@ -88,6 +99,59 @@ class SinglePostPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
postComment = async () => {
|
||||
this.setState({ isLoading: true });
|
||||
let content = this.props.navigation.state.params.content;
|
||||
let user = this.props.navigation.state.params.user;
|
||||
let userData;
|
||||
let postingKey;
|
||||
|
||||
let comment = {
|
||||
parent_author: content.author,
|
||||
parent_permlink: content.permlink,
|
||||
author: user.name,
|
||||
permlink: this.commentPermlink(content.author, content.permlink),
|
||||
title: this.commentPermlink(content.author, content.permlink),
|
||||
body: this.state.comment,
|
||||
json_metadata: JSON.stringify({
|
||||
app: "eSteem",
|
||||
community: "eSteem",
|
||||
}),
|
||||
};
|
||||
|
||||
await getUserData().then(result => {
|
||||
userData = Array.from(result);
|
||||
postingKey = decryptKey(userData[0].postingKey, "pinCode");
|
||||
});
|
||||
|
||||
postComment(comment, postingKey)
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
comment: "",
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Method to format permlink for a comment
|
||||
* @param parent_author
|
||||
* @param parent_permlink
|
||||
*/
|
||||
commentPermlink = (parent_author, parent_permlink) => {
|
||||
const timeStr = new Date()
|
||||
.toISOString()
|
||||
.replace(/[^a-zA-Z0-9]+/g, "")
|
||||
.toLocaleLowerCase();
|
||||
parent_permlink = parent_permlink.replace(/(-\d{8}t\d{9}z)/g, "");
|
||||
return "re" + parent_author + "-" + parent_permlink + "-" + timeStr;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ top: StatusBar.currentHeight, flex: 1 }}>
|
||||
@ -199,6 +263,49 @@ class SinglePostPage extends React.Component {
|
||||
</Text>
|
||||
</Right>
|
||||
</View>
|
||||
<View style={{ padding: 10 }}>
|
||||
<TextInput
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
borderColor: "lightgray",
|
||||
borderRadius: 5,
|
||||
padding: 10,
|
||||
minHeight: 100,
|
||||
}}
|
||||
multiline={true}
|
||||
numberOfLines={4}
|
||||
placeholder={"What do you think about this story?"}
|
||||
onChangeText={comment => this.setState({ comment })}
|
||||
value={this.state.comment}
|
||||
/>
|
||||
<View style={{ flexDirection: "row-reverse" }}>
|
||||
<Button
|
||||
onPress={this.postComment}
|
||||
style={{
|
||||
alignSelf: "flex-end",
|
||||
marginTop: 10,
|
||||
borderRadius: 20,
|
||||
}}
|
||||
>
|
||||
{this.state.isLoading ? (
|
||||
<ActivityIndicator
|
||||
style={{ marginHorizontal: 50 }}
|
||||
/>
|
||||
) : (
|
||||
<Text>Post a Comment</Text>
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
style={{
|
||||
alignSelf: "flex-end",
|
||||
marginRight: 10,
|
||||
borderRadius: 50,
|
||||
}}
|
||||
>
|
||||
<Icon name={"images"} />
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.comments}>
|
||||
<FlatList
|
||||
style={{ backgroundColor: "white" }}
|
||||
@ -209,6 +316,13 @@ class SinglePostPage extends React.Component {
|
||||
<Comment
|
||||
comment={item}
|
||||
navigation={this.props.navigation}
|
||||
isLoggedIn={
|
||||
this.props.navigation.state.params
|
||||
.isLoggedIn
|
||||
}
|
||||
user={
|
||||
this.props.navigation.state.params.user
|
||||
}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={item => item.permlink.toString()}
|
||||
|
@ -59,9 +59,7 @@ export const markDown2Html = input => {
|
||||
};
|
||||
|
||||
export const parsePosts = (posts, user) => {
|
||||
console.log("user");
|
||||
posts.map(post => {
|
||||
console.log(user);
|
||||
post.json_metadata = JSON.parse(post.json_metadata);
|
||||
post.json_metadata.image
|
||||
? (post.image = post.json_metadata.image[0])
|
||||
@ -98,7 +96,6 @@ export const parsePosts = (posts, user) => {
|
||||
for (let i in post.active_votes) {
|
||||
if (post.active_votes[i].voter == user) {
|
||||
post.isVoted = true;
|
||||
console.log("yup");
|
||||
}
|
||||
post.active_votes[i].value = (
|
||||
post.active_votes[i].rshares * ratio
|
||||
@ -216,6 +213,7 @@ export const protocolUrl2Obj = url => {
|
||||
};
|
||||
|
||||
export const parseComments = comments => {
|
||||
console.log(comments);
|
||||
comments.map(comment => {
|
||||
comment.pending_payout_value = parseFloat(
|
||||
comment.pending_payout_value
|
||||
|
Loading…
Reference in New Issue
Block a user