mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-22 23:28:56 +03:00
fmt
This commit is contained in:
parent
38ce6a741f
commit
ce6376d50d
@ -1,280 +1,341 @@
|
||||
import React, { Component } from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import { StyleSheet, Image, TouchableOpacity } from 'react-native';
|
||||
|
||||
import { Button, Card, CardItem,
|
||||
Left, Right, Thumbnail, View,
|
||||
Icon, Body, Text, Container, Content } from 'native-base';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardItem,
|
||||
Left,
|
||||
Right,
|
||||
Thumbnail,
|
||||
View,
|
||||
Icon,
|
||||
Body,
|
||||
Text,
|
||||
Container,
|
||||
Content,
|
||||
} from 'native-base';
|
||||
|
||||
class PostCard extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
this.state = {};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount() {}
|
||||
|
||||
}
|
||||
onError() {}
|
||||
|
||||
onError() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Card style={styles.post}>
|
||||
<CardItem style={styles.header}>
|
||||
<Left>
|
||||
<TouchableOpacity onPress={() => this.props.navigate('Author', { author: this.props.content.author })}>
|
||||
<Thumbnail
|
||||
style={styles.avatar}
|
||||
source={{ uri: this.props.content.avatar }} />
|
||||
</TouchableOpacity>
|
||||
<Body style={styles.body}>
|
||||
<View style={styles.author}>
|
||||
<Text style={styles.authorName}>{ this.props.content.author }</Text>
|
||||
</View>
|
||||
<View style={ styles.badge }>
|
||||
<Text style={styles.text}>{ this.props.content.author_reputation }</Text>
|
||||
</View>
|
||||
<View style={ styles.category }>
|
||||
<Text style={styles.categoryText}>{ this.props.content.category }</Text>
|
||||
</View>
|
||||
<Text style={styles.timeAgo} note> { this.props.content.created } </Text>
|
||||
</Body>
|
||||
</Left>
|
||||
<Right>
|
||||
<Icon name='md-more'/>
|
||||
</Right>
|
||||
</CardItem>
|
||||
<Image
|
||||
source={{ uri: this.props.content.image }}
|
||||
defaultSource={require('../assets/no_image.png')}
|
||||
style={styles.image}/>
|
||||
<CardItem>
|
||||
<Body>
|
||||
<Text style={styles.title}>
|
||||
{ this.props.content.title }
|
||||
</Text>
|
||||
<Text style={styles.summary}>
|
||||
{ this.props.content.summary }
|
||||
</Text>
|
||||
</Body>
|
||||
</CardItem>
|
||||
<CardItem>
|
||||
<Left>
|
||||
<TouchableOpacity start style={styles.upvoteButton}>
|
||||
<Icon style={styles.upvoteIcon} active name="ios-arrow-dropup-outline" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.payoutButton}>
|
||||
<Text style={styles.payout}>${ this.props.content.pending_payout_value }</Text>
|
||||
<Icon name='md-arrow-dropdown' style={styles.payoutIcon} />
|
||||
</TouchableOpacity>
|
||||
</Left>
|
||||
<Right>
|
||||
<TouchableOpacity start style={styles.commentButton}>
|
||||
<Icon style={styles.commentIcon} active name="ios-chatbubbles-outline" />
|
||||
<Text style={styles.comment}>{ this.props.content.children }</Text>
|
||||
</TouchableOpacity>
|
||||
</Right>
|
||||
</CardItem>
|
||||
{ this.props.content.top_likers ? (
|
||||
<CardItem style={styles.topLikers}>
|
||||
<Thumbnail source={{ uri: `https://steemitimages.com/u/${this.props.content.top_likers[0]}/avatar/small` }} style={styles.likers_1}/>
|
||||
<Thumbnail source={{ uri: `https://steemitimages.com/u/${this.props.content.top_likers[1]}/avatar/small` }} style={styles.likers_2}/>
|
||||
<Thumbnail source={{ uri: `https://steemitimages.com/u/${this.props.content.top_likers[2]}/avatar/small` }} style={styles.likers_3}/>
|
||||
<Text style={styles.footer}>
|
||||
@{ this.props.content.top_likers[0] },
|
||||
@{ this.props.content.top_likers[1] },
|
||||
@{ this.props.content.top_likers[2] }
|
||||
<Text style={styles.footer}> & </Text>
|
||||
{ this.props.content.vote_count - this.props.content.top_likers.length } others like this
|
||||
</Text>
|
||||
</CardItem>
|
||||
) : (
|
||||
<CardItem>
|
||||
<Text style={styles.footer}>
|
||||
{ this.props.content.vote_count } likes
|
||||
</Text>
|
||||
</CardItem>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Card style={styles.post}>
|
||||
<CardItem style={styles.header}>
|
||||
<Left>
|
||||
<TouchableOpacity
|
||||
onPress={() =>
|
||||
this.props.navigate('Author', {
|
||||
author: this.props.content.author,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Thumbnail
|
||||
style={styles.avatar}
|
||||
source={{ uri: this.props.content.avatar }}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<Body style={styles.body}>
|
||||
<View style={styles.author}>
|
||||
<Text style={styles.authorName}>
|
||||
{this.props.content.author}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.badge}>
|
||||
<Text style={styles.text}>
|
||||
{this.props.content.author_reputation}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.category}>
|
||||
<Text style={styles.categoryText}>
|
||||
{this.props.content.category}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.timeAgo} note>
|
||||
{' '}
|
||||
{this.props.content.created}{' '}
|
||||
</Text>
|
||||
</Body>
|
||||
</Left>
|
||||
<Right>
|
||||
<Icon name="md-more" />
|
||||
</Right>
|
||||
</CardItem>
|
||||
<Image
|
||||
source={{ uri: this.props.content.image }}
|
||||
defaultSource={require('../assets/no_image.png')}
|
||||
style={styles.image}
|
||||
/>
|
||||
<CardItem>
|
||||
<Body>
|
||||
<Text style={styles.title}>
|
||||
{this.props.content.title}
|
||||
</Text>
|
||||
<Text style={styles.summary}>
|
||||
{this.props.content.summary}
|
||||
</Text>
|
||||
</Body>
|
||||
</CardItem>
|
||||
<CardItem>
|
||||
<Left>
|
||||
<TouchableOpacity start style={styles.upvoteButton}>
|
||||
<Icon
|
||||
style={styles.upvoteIcon}
|
||||
active
|
||||
name="ios-arrow-dropup-outline"
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.payoutButton}>
|
||||
<Text style={styles.payout}>
|
||||
${this.props.content.pending_payout_value}
|
||||
</Text>
|
||||
<Icon
|
||||
name="md-arrow-dropdown"
|
||||
style={styles.payoutIcon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</Left>
|
||||
<Right>
|
||||
<TouchableOpacity start style={styles.commentButton}>
|
||||
<Icon
|
||||
style={styles.commentIcon}
|
||||
active
|
||||
name="ios-chatbubbles-outline"
|
||||
/>
|
||||
<Text style={styles.comment}>
|
||||
{this.props.content.children}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</Right>
|
||||
</CardItem>
|
||||
{this.props.content.top_likers ? (
|
||||
<CardItem style={styles.topLikers}>
|
||||
<Thumbnail
|
||||
source={{
|
||||
uri: `https://steemitimages.com/u/${
|
||||
this.props.content.top_likers[0]
|
||||
}/avatar/small`,
|
||||
}}
|
||||
style={styles.likers_1}
|
||||
/>
|
||||
<Thumbnail
|
||||
source={{
|
||||
uri: `https://steemitimages.com/u/${
|
||||
this.props.content.top_likers[1]
|
||||
}/avatar/small`,
|
||||
}}
|
||||
style={styles.likers_2}
|
||||
/>
|
||||
<Thumbnail
|
||||
source={{
|
||||
uri: `https://steemitimages.com/u/${
|
||||
this.props.content.top_likers[2]
|
||||
}/avatar/small`,
|
||||
}}
|
||||
style={styles.likers_3}
|
||||
/>
|
||||
<Text style={styles.footer}>
|
||||
@{this.props.content.top_likers[0]}, @
|
||||
{this.props.content.top_likers[1]}, @
|
||||
{this.props.content.top_likers[2]}
|
||||
<Text style={styles.footer}> & </Text>
|
||||
{this.props.content.vote_count -
|
||||
this.props.content.top_likers.length}{' '}
|
||||
others like this
|
||||
</Text>
|
||||
</CardItem>
|
||||
) : (
|
||||
<CardItem>
|
||||
<Text style={styles.footer}>
|
||||
{this.props.content.vote_count} likes
|
||||
</Text>
|
||||
</CardItem>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
post: {
|
||||
shadowColor: 'white',
|
||||
padding: 0,
|
||||
marginRight: 0,
|
||||
marginLeft: 0,
|
||||
marginTop: 0,
|
||||
marginBottom: 0,
|
||||
borderWidth: 0,
|
||||
borderColor: 'white',
|
||||
borderRadius: 5,
|
||||
},
|
||||
avatar: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
borderColor: 'lightgray',
|
||||
borderWidth: 1
|
||||
},
|
||||
author: {
|
||||
backgroundColor: 'white',
|
||||
alignSelf: 'flex-start',
|
||||
paddingVertical: 5
|
||||
},
|
||||
timeAgo: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 9,
|
||||
fontWeight: '100',
|
||||
marginHorizontal: 3
|
||||
},
|
||||
authorName: {
|
||||
color: '#222',
|
||||
fontWeight: '600',
|
||||
fontSize: 10
|
||||
},
|
||||
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
|
||||
},
|
||||
commentButton: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
comment: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 10,
|
||||
color: '#626262',
|
||||
marginLeft: 3
|
||||
},
|
||||
commentIcon: {
|
||||
alignSelf: 'flex-start',
|
||||
fontSize: 20,
|
||||
color: '#007ee5',
|
||||
margin:0,
|
||||
width: 20
|
||||
},
|
||||
title: {
|
||||
fontSize: 12,
|
||||
fontWeight: '500',
|
||||
marginVertical: 5
|
||||
},
|
||||
summary: {
|
||||
fontSize: 10,
|
||||
fontWeight: '200',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
header: {
|
||||
height: 50
|
||||
},
|
||||
body: {
|
||||
justifyContent: 'flex-start',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
image: {
|
||||
margin: 0,
|
||||
width: '100%',
|
||||
height: 160,
|
||||
},
|
||||
badge: {
|
||||
alignSelf: 'center',
|
||||
borderColor: 'lightgray',
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
width: 15,
|
||||
height: 15,
|
||||
padding: 2,
|
||||
backgroundColor: 'lightgray',
|
||||
marginHorizontal: 5
|
||||
},
|
||||
category: {
|
||||
alignSelf: 'center',
|
||||
borderRadius: 10,
|
||||
height: 15,
|
||||
backgroundColor: '#007EE5',
|
||||
paddingHorizontal: 5,
|
||||
paddingVertical: 1.5
|
||||
},
|
||||
categoryText: {
|
||||
fontSize: 9,
|
||||
color: 'white',
|
||||
fontWeight: '600'
|
||||
},
|
||||
text: {
|
||||
fontSize: 7,
|
||||
alignSelf: 'center',
|
||||
textAlignVertical: 'center',
|
||||
color: 'white',
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
topLikers: {
|
||||
backgroundColor: '#f8f8f8',
|
||||
borderWidth: 0,
|
||||
padding:0
|
||||
},
|
||||
likers_1: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 7,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'lightgray',
|
||||
marginVertical: -5,
|
||||
},
|
||||
likers_2: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 7,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'lightgray',
|
||||
marginVertical: -5,
|
||||
marginLeft: -3
|
||||
},
|
||||
likers_3: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 7,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'lightgray',
|
||||
marginVertical: -5,
|
||||
marginLeft: -3
|
||||
},
|
||||
footer: {
|
||||
marginLeft: 5,
|
||||
fontSize: 7,
|
||||
fontWeight: '100',
|
||||
color: '#777777'
|
||||
}
|
||||
post: {
|
||||
shadowColor: 'white',
|
||||
padding: 0,
|
||||
marginRight: 0,
|
||||
marginLeft: 0,
|
||||
marginTop: 0,
|
||||
marginBottom: 0,
|
||||
borderWidth: 0,
|
||||
borderColor: 'white',
|
||||
borderRadius: 5,
|
||||
},
|
||||
avatar: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
borderColor: 'lightgray',
|
||||
borderWidth: 1,
|
||||
},
|
||||
author: {
|
||||
backgroundColor: 'white',
|
||||
alignSelf: 'flex-start',
|
||||
paddingVertical: 5,
|
||||
},
|
||||
timeAgo: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 9,
|
||||
fontWeight: '100',
|
||||
marginHorizontal: 3,
|
||||
},
|
||||
authorName: {
|
||||
color: '#222',
|
||||
fontWeight: '600',
|
||||
fontSize: 10,
|
||||
},
|
||||
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,
|
||||
},
|
||||
commentButton: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
comment: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 10,
|
||||
color: '#626262',
|
||||
marginLeft: 3,
|
||||
},
|
||||
commentIcon: {
|
||||
alignSelf: 'flex-start',
|
||||
fontSize: 20,
|
||||
color: '#007ee5',
|
||||
margin: 0,
|
||||
width: 20,
|
||||
},
|
||||
title: {
|
||||
fontSize: 12,
|
||||
fontWeight: '500',
|
||||
marginVertical: 5,
|
||||
},
|
||||
summary: {
|
||||
fontSize: 10,
|
||||
fontWeight: '200',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
header: {
|
||||
height: 50,
|
||||
},
|
||||
body: {
|
||||
justifyContent: 'flex-start',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
image: {
|
||||
margin: 0,
|
||||
width: '100%',
|
||||
height: 160,
|
||||
},
|
||||
badge: {
|
||||
alignSelf: 'center',
|
||||
borderColor: 'lightgray',
|
||||
borderWidth: 1,
|
||||
borderRadius: 10,
|
||||
width: 15,
|
||||
height: 15,
|
||||
padding: 2,
|
||||
backgroundColor: 'lightgray',
|
||||
marginHorizontal: 5,
|
||||
},
|
||||
category: {
|
||||
alignSelf: 'center',
|
||||
borderRadius: 10,
|
||||
height: 15,
|
||||
backgroundColor: '#007EE5',
|
||||
paddingHorizontal: 5,
|
||||
paddingVertical: 1.5,
|
||||
},
|
||||
categoryText: {
|
||||
fontSize: 9,
|
||||
color: 'white',
|
||||
fontWeight: '600',
|
||||
},
|
||||
text: {
|
||||
fontSize: 7,
|
||||
alignSelf: 'center',
|
||||
textAlignVertical: 'center',
|
||||
color: 'white',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
topLikers: {
|
||||
backgroundColor: '#f8f8f8',
|
||||
borderWidth: 0,
|
||||
padding: 0,
|
||||
},
|
||||
likers_1: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 7,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'lightgray',
|
||||
marginVertical: -5,
|
||||
},
|
||||
likers_2: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 7,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'lightgray',
|
||||
marginVertical: -5,
|
||||
marginLeft: -3,
|
||||
},
|
||||
likers_3: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
borderRadius: 7,
|
||||
borderWidth: 0.5,
|
||||
borderColor: 'lightgray',
|
||||
marginVertical: -5,
|
||||
marginLeft: -3,
|
||||
},
|
||||
footer: {
|
||||
marginLeft: 5,
|
||||
fontSize: 7,
|
||||
fontWeight: '100',
|
||||
color: '#777777',
|
||||
},
|
||||
});
|
||||
|
||||
export default PostCard;
|
||||
export default PostCard;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
createStackNavigator,
|
||||
createBottomTabNavigator
|
||||
createStackNavigator,
|
||||
createBottomTabNavigator,
|
||||
} from 'react-navigation';
|
||||
|
||||
import React from 'react';
|
||||
@ -19,196 +19,196 @@ import SinglePostPage from '../screens/single-post/Post';
|
||||
import LoginPage from '../screens/login/Login';
|
||||
import AuthorPage from '../screens/author-profile/Author';
|
||||
|
||||
const HomeScreen = ({ navigation }) => (
|
||||
<HomePage navigation={navigation}></HomePage>
|
||||
);
|
||||
const HomeScreen = ({ navigation }) => <HomePage navigation={navigation} />;
|
||||
|
||||
HomeScreen.navigationOptions = {
|
||||
tabBarLabel: 'Home',
|
||||
title: 'Home',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<MaterialCommunityIcons
|
||||
name={focused ? 'home' : 'home'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
tabBarLabel: 'Home',
|
||||
title: 'Home',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<MaterialCommunityIcons
|
||||
name={focused ? 'home' : 'home'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
const ProfileScreen = ({ navigation }) => (
|
||||
<ProfilePage navigation={navigation}></ProfilePage>
|
||||
<ProfilePage navigation={navigation} />
|
||||
);
|
||||
|
||||
ProfileScreen.navigationOptions = {
|
||||
tabBarLabel: 'Profile',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'md-contact' : 'md-contact'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
tabBarLabel: 'Profile',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'md-contact' : 'md-contact'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
const EditorScreen = ({ navigation }) => (
|
||||
<EditorPage navigation={navigation}></EditorPage>
|
||||
);
|
||||
const EditorScreen = ({ navigation }) => <EditorPage navigation={navigation} />;
|
||||
|
||||
EditorScreen.navigationOptions = {
|
||||
tabBarLabel: 'Editor',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Entypo
|
||||
name={focused ? 'pencil' : 'pencil'}
|
||||
size={26}
|
||||
style={styles.post}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
tabBarLabel: 'Editor',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Entypo
|
||||
name={focused ? 'pencil' : 'pencil'}
|
||||
size={26}
|
||||
style={styles.post}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
const WalletScreen = ({ navigation }) => (
|
||||
<WalletPage navigation={navigation}></WalletPage>
|
||||
);
|
||||
const WalletScreen = ({ navigation }) => <WalletPage navigation={navigation} />;
|
||||
|
||||
WalletScreen.navigationOptions = {
|
||||
tabBarLabel: 'Settings',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Entypo
|
||||
name={focused ? 'wallet' : 'wallet'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
tabBarLabel: 'Settings',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Entypo
|
||||
name={focused ? 'wallet' : 'wallet'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
const NotificationScreen = ({ navigation }) => (
|
||||
<NotificationPage navigation={navigation}></NotificationPage>
|
||||
<NotificationPage navigation={navigation} />
|
||||
);
|
||||
|
||||
NotificationScreen.navigationOptions = {
|
||||
tabBarLabel: 'Notifications',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-notifications' : 'ios-notifications'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
tabBarLabel: 'Notifications',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-notifications' : 'ios-notifications'}
|
||||
size={26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
const SinglePostScreen = ({ navigation }) => (
|
||||
<SinglePostPage navigation={navigation}></SinglePostPage>
|
||||
<SinglePostPage navigation={navigation} />
|
||||
);
|
||||
|
||||
const LoginScreen = ({ navigation }) => (
|
||||
<LoginPage navigation={navigation}></LoginPage>
|
||||
);
|
||||
const LoginScreen = ({ navigation }) => <LoginPage navigation={navigation} />;
|
||||
|
||||
const AuthorScreen = ({ navigation }) => (
|
||||
<AuthorPage navigation={navigation}></AuthorPage>
|
||||
);
|
||||
const AuthorScreen = ({ navigation }) => <AuthorPage navigation={navigation} />;
|
||||
|
||||
const BottomTabs = createBottomTabNavigator(
|
||||
{
|
||||
Home: {
|
||||
screen: HomeScreen,
|
||||
path: '',
|
||||
{
|
||||
Home: {
|
||||
screen: HomeScreen,
|
||||
path: '',
|
||||
},
|
||||
Profile: {
|
||||
screen: ProfileScreen,
|
||||
path: 'profile',
|
||||
},
|
||||
Editor: {
|
||||
screen: EditorScreen,
|
||||
path: 'editor',
|
||||
},
|
||||
Wallet: {
|
||||
screen: WalletScreen,
|
||||
path: 'wallet',
|
||||
},
|
||||
Notifications: {
|
||||
screen: NotificationScreen,
|
||||
path: 'settings',
|
||||
},
|
||||
},
|
||||
Profile: {
|
||||
screen: ProfileScreen,
|
||||
path: 'profile',
|
||||
},
|
||||
Editor: {
|
||||
screen: EditorScreen,
|
||||
path: 'editor',
|
||||
},
|
||||
Wallet: {
|
||||
screen: WalletScreen,
|
||||
path: 'wallet',
|
||||
},
|
||||
Notifications: {
|
||||
screen: NotificationScreen,
|
||||
path: 'settings',
|
||||
{
|
||||
tabBarOptions: {
|
||||
activeTintColor: '#373c3f',
|
||||
inactiveTintColor: '#AFB1B3',
|
||||
style: {
|
||||
backgroundColor: 'white',
|
||||
borderTopColor: '#dedede',
|
||||
borderWidth: 0,
|
||||
},
|
||||
showLabel: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
tabBarOptions: {
|
||||
activeTintColor: '#373c3f',
|
||||
inactiveTintColor: '#AFB1B3',
|
||||
style: {
|
||||
backgroundColor: 'white',
|
||||
borderTopColor: '#dedede',
|
||||
borderWidth: 0
|
||||
},
|
||||
showLabel: false,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
BottomTabs.navigationOptions = ({navigation})=> ({
|
||||
header: null,
|
||||
style: {
|
||||
backgroundColor: 'white',
|
||||
BottomTabs.navigationOptions = ({ navigation }) => ({
|
||||
header: null,
|
||||
style: {
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
const StacksOverTabs = createStackNavigator({
|
||||
Root: {
|
||||
screen: BottomTabs,
|
||||
},
|
||||
Post: {
|
||||
screen: SinglePostScreen,
|
||||
path: '/:category/:user/:permlink',
|
||||
navigationOptions: ({ navigation }) => ({
|
||||
header: null
|
||||
}),
|
||||
},
|
||||
Login: {
|
||||
screen: LoginScreen,
|
||||
path: '/login',
|
||||
},
|
||||
Author: {
|
||||
screen: AuthorScreen,
|
||||
path: '/author',
|
||||
}
|
||||
}, {
|
||||
headerMode: 'none'
|
||||
});
|
||||
|
||||
const StacksOverTabs = createStackNavigator(
|
||||
{
|
||||
Root: {
|
||||
screen: BottomTabs,
|
||||
},
|
||||
Post: {
|
||||
screen: SinglePostScreen,
|
||||
path: '/:category/:user/:permlink',
|
||||
navigationOptions: ({ navigation }) => ({
|
||||
header: null,
|
||||
}),
|
||||
},
|
||||
Login: {
|
||||
screen: LoginScreen,
|
||||
path: '/login',
|
||||
},
|
||||
Author: {
|
||||
screen: AuthorScreen,
|
||||
path: '/author',
|
||||
},
|
||||
},
|
||||
{
|
||||
headerMode: 'none',
|
||||
}
|
||||
);
|
||||
|
||||
class Tabs extends React.Component {
|
||||
static router = StacksOverTabs.router;
|
||||
_s0;
|
||||
_s1;
|
||||
_s2;
|
||||
_s3;
|
||||
static router = StacksOverTabs.router;
|
||||
_s0;
|
||||
_s1;
|
||||
_s2;
|
||||
_s3;
|
||||
|
||||
componentDidMount() {
|
||||
this._s0 = this.props.navigation.addListener('willFocus', this._onAction);
|
||||
this._s1 = this.props.navigation.addListener('didFocus', this._onAction);
|
||||
this._s2 = this.props.navigation.addListener('willBlur', this._onAction);
|
||||
this._s3 = this.props.navigation.addListener('didBlur', this._onAction);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this._s0.remove();
|
||||
this._s1.remove();
|
||||
this._s2.remove();
|
||||
this._s3.remove();
|
||||
}
|
||||
_onAction = a => {
|
||||
console.log('TABS EVENT', a.type, a);
|
||||
};
|
||||
render() {
|
||||
return <StacksOverTabs navigation={this.props.navigation} />;
|
||||
}
|
||||
componentDidMount() {
|
||||
this._s0 = this.props.navigation.addListener(
|
||||
'willFocus',
|
||||
this._onAction
|
||||
);
|
||||
this._s1 = this.props.navigation.addListener(
|
||||
'didFocus',
|
||||
this._onAction
|
||||
);
|
||||
this._s2 = this.props.navigation.addListener(
|
||||
'willBlur',
|
||||
this._onAction
|
||||
);
|
||||
this._s3 = this.props.navigation.addListener('didBlur', this._onAction);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this._s0.remove();
|
||||
this._s1.remove();
|
||||
this._s2.remove();
|
||||
this._s3.remove();
|
||||
}
|
||||
_onAction = a => {
|
||||
console.log('TABS EVENT', a.type, a);
|
||||
};
|
||||
render() {
|
||||
return <StacksOverTabs navigation={this.props.navigation} />;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
post: {
|
||||
borderWidth: 22,
|
||||
borderColor: 'blue',
|
||||
}
|
||||
post: {
|
||||
borderWidth: 22,
|
||||
borderColor: 'blue',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
export default Tabs;
|
||||
|
@ -3,103 +3,129 @@ import { getAccount } from './Dsteem';
|
||||
import { AsyncStorage } from 'react-native';
|
||||
|
||||
export const Login = (username, password) => {
|
||||
let account;
|
||||
let publicKeys;
|
||||
let privateKeys;
|
||||
let isPassword;
|
||||
let isPostingKey;
|
||||
|
||||
let account;
|
||||
let publicKeys;
|
||||
let privateKeys;
|
||||
let isPassword;
|
||||
let isPostingKey;
|
||||
return new Promise((resolve, reject) => {
|
||||
getAccount(username)
|
||||
.then(result => {
|
||||
if (result.length < 1) {
|
||||
reject(new Error('Wrong @username'));
|
||||
}
|
||||
|
||||
return new Promise((resolve,reject) => {
|
||||
getAccount(username).then((result) => {
|
||||
account = result[0];
|
||||
|
||||
if (result.length < 1) {
|
||||
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])
|
||||
};
|
||||
|
||||
}).then(() => {
|
||||
|
||||
try {
|
||||
// Set private keys of user
|
||||
privateKeys = {
|
||||
active: dsteem.PrivateKey.fromLogin(username, password, 'active').toString(),
|
||||
memo: dsteem.PrivateKey.fromLogin(username, password, 'memo').toString(),
|
||||
owner: dsteem.PrivateKey.fromLogin(username, password, 'owner').toString(),
|
||||
posting: dsteem.PrivateKey.fromLogin(username, password, 'posting').toString()
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
|
||||
}).then(() => {
|
||||
|
||||
try {
|
||||
isPassword = (dsteem.PrivateKey.fromLogin(username, password, 'posting').createPublic()).toString() === (publicKeys.posting).toString()
|
||||
|
||||
if (isPassword) {
|
||||
|
||||
let authType = {
|
||||
'username': username,
|
||||
'auth_type': 'master_key',
|
||||
'posting_key': privateKeys.posting,
|
||||
'active_key': privateKeys.active,
|
||||
'memo_key': privateKeys.memo,
|
||||
'owner_key': privateKeys.owner
|
||||
}
|
||||
|
||||
AsyncStorage.setItem('isLoggedIn', 'true', () => {
|
||||
AsyncStorage.setItem('user', JSON.stringify(authType), () => {
|
||||
resolve(isPassword);
|
||||
// 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]),
|
||||
};
|
||||
})
|
||||
.then(() => {
|
||||
try {
|
||||
// Set private keys of user
|
||||
privateKeys = {
|
||||
active: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
'active'
|
||||
).toString(),
|
||||
memo: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
'memo'
|
||||
).toString(),
|
||||
owner: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
'owner'
|
||||
).toString(),
|
||||
posting: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
'posting'
|
||||
).toString(),
|
||||
};
|
||||
} catch (error) {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
try {
|
||||
isPassword =
|
||||
dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
'posting'
|
||||
)
|
||||
.createPublic()
|
||||
.toString() === publicKeys.posting.toString();
|
||||
|
||||
if (isPassword) {
|
||||
let authType = {
|
||||
username: username,
|
||||
auth_type: 'master_key',
|
||||
posting_key: privateKeys.posting,
|
||||
active_key: privateKeys.active,
|
||||
memo_key: privateKeys.memo,
|
||||
owner_key: privateKeys.owner,
|
||||
};
|
||||
|
||||
AsyncStorage.setItem('isLoggedIn', 'true', () => {
|
||||
AsyncStorage.setItem(
|
||||
'user',
|
||||
JSON.stringify(authType),
|
||||
() => {
|
||||
resolve(isPassword);
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
isPostingKey =
|
||||
publicKeys.posting.toString() ===
|
||||
dsteem.PrivateKey.fromString(password)
|
||||
.createPublic()
|
||||
.toString();
|
||||
|
||||
let authType = {
|
||||
username: username,
|
||||
auth_type: 'posting_key',
|
||||
posting_key: password,
|
||||
};
|
||||
|
||||
try {
|
||||
if (isPostingKey) {
|
||||
AsyncStorage.setItem(
|
||||
'isLoggedIn',
|
||||
'true',
|
||||
() => {
|
||||
AsyncStorage.setItem(
|
||||
'user',
|
||||
JSON.stringify(authType),
|
||||
() => {
|
||||
resolve(isPostingKey);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
reject(new Error('Check your username'));
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
isPostingKey = (publicKeys.posting).toString() === (dsteem.PrivateKey.fromString(password).createPublic()).toString();
|
||||
|
||||
let authType = {
|
||||
'username': username,
|
||||
'auth_type': 'posting_key',
|
||||
'posting_key': password
|
||||
}
|
||||
|
||||
try {
|
||||
if (isPostingKey) {
|
||||
|
||||
AsyncStorage.setItem('isLoggedIn', 'true', () => {
|
||||
AsyncStorage.setItem('user', JSON.stringify(authType), () => {
|
||||
resolve(isPostingKey)
|
||||
})
|
||||
})
|
||||
|
||||
} else {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
reject(new Error('Wrong Key/Password'));
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
reject(new Error('Check your username'));
|
||||
});
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -5,78 +5,84 @@ import { parsePosts } from '../../utils/PostParser';
|
||||
|
||||
import Remarkable from 'remarkable';
|
||||
var md = new Remarkable({
|
||||
html: true, // Enable HTML tags in source
|
||||
xhtmlOut: false, // Use '/' to close single tags (<br />)
|
||||
breaks: true, // Convert '\n' in paragraphs into <br>
|
||||
langPrefix: 'language-', // CSS language prefix for fenced blocks
|
||||
linkify: true, // Autoconvert URL-like text to links
|
||||
html: true, // Enable HTML tags in source
|
||||
xhtmlOut: false, // Use '/' to close single tags (<br />)
|
||||
breaks: true, // Convert '\n' in paragraphs into <br>
|
||||
langPrefix: 'language-', // CSS language prefix for fenced blocks
|
||||
linkify: true, // Autoconvert URL-like text to links
|
||||
|
||||
// Enable some language-neutral replacement + quotes beautification
|
||||
typographer: true,
|
||||
// Enable some language-neutral replacement + quotes beautification
|
||||
typographer: true,
|
||||
|
||||
// Double + single quotes replacement pairs, when typographer enabled,
|
||||
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
|
||||
quotes: '“”‘’'
|
||||
// Double + single quotes replacement pairs, when typographer enabled,
|
||||
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
|
||||
quotes: '“”‘’',
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @method getAccount get account data
|
||||
* @param user username
|
||||
*/
|
||||
export const getAccount = (user) => {
|
||||
/**
|
||||
* @method getAccount get account data
|
||||
* @param user username
|
||||
*/
|
||||
export const getAccount = user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let account = client.database.getAccounts([user]);
|
||||
resolve(account);
|
||||
})
|
||||
}
|
||||
let account = client.database.getAccounts([user]);
|
||||
resolve(account);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method getPosts get posts method
|
||||
* @param by get discussions by trending, created, active etc.
|
||||
* @param query tag, limit, start_author?, start_permalink?
|
||||
*/
|
||||
export const getPosts = async (by, query) => {
|
||||
/**
|
||||
* @method getPosts get posts method
|
||||
* @param by get discussions by trending, created, active etc.
|
||||
* @param query tag, limit, start_author?, start_permalink?
|
||||
*/
|
||||
export const getPosts = async (by, query) => {
|
||||
let posts = await client.database.getDiscussions(by, query);
|
||||
posts = await parsePosts(posts);
|
||||
return posts;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @method getUser get user data
|
||||
* @param user post author
|
||||
* @param permlink post permlink
|
||||
*/
|
||||
export const getPost = (user, permlink) => {
|
||||
/**
|
||||
* @method getUser get user data
|
||||
* @param user post author
|
||||
* @param permlink post permlink
|
||||
*/
|
||||
export const getPost = (user, permlink) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let post = client.database.call('get_content',[user,permlink]);
|
||||
resolve(post);
|
||||
let post = client.database.call('get_content', [user, permlink]);
|
||||
resolve(post);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @method getUser get user data
|
||||
* @param user post author
|
||||
* @param permlink post permlink
|
||||
*/
|
||||
export const getComments = (user, permlink) => {
|
||||
/**
|
||||
* @method getUser get user data
|
||||
* @param user post author
|
||||
* @param permlink post permlink
|
||||
*/
|
||||
export const getComments = (user, permlink) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let comments = client.database.call('get_content_replies',[user, permlink]);
|
||||
resolve(comments);
|
||||
let comments = client.database.call('get_content_replies', [
|
||||
user,
|
||||
permlink,
|
||||
]);
|
||||
resolve(comments);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @method getPostWithComments get user data
|
||||
* @param user post author
|
||||
* @param permlink post permlink
|
||||
*/
|
||||
export const getPostWithComments = async (user, permlink) => {
|
||||
/**
|
||||
* @method getPostWithComments get user data
|
||||
* @param user post author
|
||||
* @param permlink post permlink
|
||||
*/
|
||||
export const getPostWithComments = async (user, permlink) => {
|
||||
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];
|
||||
};
|
||||
|
@ -1,58 +1,69 @@
|
||||
import * as React from 'react';
|
||||
import { StatusBar } from 'react-native';
|
||||
import { Container, Header, Left, Body, Right, Button, Icon, Title, Content, Text } from 'native-base';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Left,
|
||||
Body,
|
||||
Right,
|
||||
Button,
|
||||
Icon,
|
||||
Title,
|
||||
Content,
|
||||
Text,
|
||||
} from 'native-base';
|
||||
import { getAccount } from '../../providers/steem/Dsteem';
|
||||
|
||||
class AuthorPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
author: 'author'
|
||||
this.state = {
|
||||
author: 'author',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
getAccount(this.props.navigation.state.params.author).then((author) => {
|
||||
this.setState({
|
||||
author: author[0]
|
||||
})
|
||||
}).catch((err) => {
|
||||
|
||||
});
|
||||
}
|
||||
componentDidMount() {
|
||||
getAccount(this.props.navigation.state.params.author)
|
||||
.then(author => {
|
||||
this.setState({
|
||||
author: author[0],
|
||||
});
|
||||
})
|
||||
.catch(err => {});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ top: StatusBar.currentHeight }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent
|
||||
onPress={() => this.props.navigation.goBack()}>
|
||||
<Icon name='arrow-back' />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title> { this.state.author.name } </Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name='heart' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='more' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ top: StatusBar.currentHeight }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
>
|
||||
<Icon name="arrow-back" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title> {this.state.author.name} </Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name="heart" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="more" />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
|
||||
<Content>
|
||||
<Text>
|
||||
{ JSON.stringify(this.state.author) }
|
||||
</Text>
|
||||
</Content>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
<Content>
|
||||
<Text>{JSON.stringify(this.state.author)}</Text>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthorPage;
|
||||
export default AuthorPage;
|
||||
|
@ -1,41 +1,49 @@
|
||||
import * as React from 'react';
|
||||
import { Container, Header, Left, Body, Right, Button, Icon, Title } from 'native-base';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Left,
|
||||
Body,
|
||||
Right,
|
||||
Button,
|
||||
Icon,
|
||||
Title,
|
||||
} from 'native-base';
|
||||
|
||||
class EditorPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
componentDidMount() {}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name='menu' />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Editor</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name='search' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='heart' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='more' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name="menu" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Editor</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name="search" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="heart" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="more" />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditorPage;
|
||||
export default EditorPage;
|
||||
|
@ -1,15 +1,14 @@
|
||||
import React,{Component} from 'react'
|
||||
import {StyleSheet,
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
Animated,
|
||||
TouchableNativeFeedback,
|
||||
TouchableOpacity,
|
||||
Platform,
|
||||
Dimensions
|
||||
} from 'react-native'
|
||||
|
||||
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
|
||||
export default class CustomTabBar extends Component {
|
||||
constructor(props) {
|
||||
@ -17,39 +16,48 @@ export default class CustomTabBar extends Component {
|
||||
|
||||
this.state = {
|
||||
activeDefaultColor: '#08086b',
|
||||
inactiveDefaultColor: '#666666'
|
||||
}
|
||||
inactiveDefaultColor: '#666666',
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
_renderTab(name, page, isTabActive, onPressHandler) {
|
||||
const { textStyle } = this.props;
|
||||
const textColor = isTabActive ? this.props.activeColor : this.props.inactiveColor;
|
||||
|
||||
const textColor = isTabActive
|
||||
? this.props.activeColor
|
||||
: this.props.inactiveColor;
|
||||
|
||||
const fontWeight = isTabActive ? 'bold' : 'normal';
|
||||
|
||||
const Button = Platform.OS == 'ios' ? ButtonIos : ButtonAndroid;
|
||||
|
||||
return (<Button
|
||||
style={{flex: 1}}
|
||||
key={name}
|
||||
accessible={true}
|
||||
accessibilityLabel={name}
|
||||
accessibilityTraits='button'
|
||||
onPress={() => onPressHandler(page)}>
|
||||
<View style={styles.tab}>
|
||||
<Text style={[{color: textColor, fontWeight } ]}>
|
||||
{name}
|
||||
</Text>
|
||||
</View>
|
||||
</Button>);
|
||||
}
|
||||
|
||||
_renderUnderline() {
|
||||
return (
|
||||
<Button
|
||||
style={{ flex: 1 }}
|
||||
key={name}
|
||||
accessible={true}
|
||||
accessibilityLabel={name}
|
||||
accessibilityTraits="button"
|
||||
onPress={() => onPressHandler(page)}
|
||||
>
|
||||
<View style={styles.tab}>
|
||||
<Text style={[{ color: textColor, fontWeight }]}>
|
||||
{name}
|
||||
</Text>
|
||||
</View>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
_renderUnderline() {
|
||||
const containerWidth = Dimensions.get('window').width / 1;
|
||||
const numberOfTabs = this.props.tabs.length;
|
||||
const underlineWidth = this.props.tabUnderlineDefaultWidth ? this.props.tabUnderlineDefaultWidth : containerWidth / (numberOfTabs * 2);
|
||||
const scale = this.props.tabUnderlineScaleX ? this.props.tabUnderlineScaleX : 3;
|
||||
const deLen = (containerWidth / numberOfTabs - underlineWidth ) / 2;
|
||||
const underlineWidth = this.props.tabUnderlineDefaultWidth
|
||||
? this.props.tabUnderlineDefaultWidth
|
||||
: containerWidth / (numberOfTabs * 2);
|
||||
const scale = this.props.tabUnderlineScaleX
|
||||
? this.props.tabUnderlineScaleX
|
||||
: 3;
|
||||
const deLen = (containerWidth / numberOfTabs - underlineWidth) / 2;
|
||||
const tabUnderlineStyle = {
|
||||
position: 'absolute',
|
||||
width: underlineWidth,
|
||||
@ -57,87 +65,98 @@ export default class CustomTabBar extends Component {
|
||||
borderRadius: 2,
|
||||
backgroundColor: this.props.activeColor,
|
||||
bottom: 3,
|
||||
left: deLen
|
||||
left: deLen,
|
||||
};
|
||||
|
||||
const translateX = this.props.scrollValue.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0, containerWidth / numberOfTabs],
|
||||
outputRange: [0, containerWidth / numberOfTabs],
|
||||
});
|
||||
|
||||
const scaleValue = (defaultScale) => {
|
||||
let number = 4
|
||||
let arr = new Array(number * 2)
|
||||
return arr.fill(0).reduce(function(pre, cur, idx){
|
||||
idx == 0 ? pre.inputRange.push(cur) : pre.inputRange.push(pre.inputRange[idx-1] + 0.5);
|
||||
idx%2 ? pre.outputRange.push(defaultScale) : pre.outputRange.push(1)
|
||||
return pre
|
||||
}, {inputRange: [], outputRange: []})
|
||||
}
|
||||
const scaleValue = defaultScale => {
|
||||
let number = 4;
|
||||
let arr = new Array(number * 2);
|
||||
return arr.fill(0).reduce(
|
||||
function(pre, cur, idx) {
|
||||
idx == 0
|
||||
? pre.inputRange.push(cur)
|
||||
: pre.inputRange.push(pre.inputRange[idx - 1] + 0.5);
|
||||
idx % 2
|
||||
? pre.outputRange.push(defaultScale)
|
||||
: pre.outputRange.push(1);
|
||||
return pre;
|
||||
},
|
||||
{ inputRange: [], outputRange: [] }
|
||||
);
|
||||
};
|
||||
|
||||
const scaleX = this.props.scrollValue.interpolate(scaleValue(scale));
|
||||
|
||||
return(
|
||||
<Animated.View
|
||||
style={[
|
||||
tabUnderlineStyle,
|
||||
{
|
||||
transform: [
|
||||
{ translateX },
|
||||
{ scaleX }
|
||||
],
|
||||
},
|
||||
this.props.underlineStyle,
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={[styles.tabs, {backgroundColor: this.props.backgroundColor}, this.props.style]}>
|
||||
<Animated.View
|
||||
style={[
|
||||
tabUnderlineStyle,
|
||||
{
|
||||
transform: [{ translateX }, { scaleX }],
|
||||
},
|
||||
this.props.underlineStyle,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.tabs,
|
||||
{ backgroundColor: this.props.backgroundColor },
|
||||
this.props.style,
|
||||
]}
|
||||
>
|
||||
{this.props.tabs.map((name, page) => {
|
||||
const isTabActive = this.props.activeTab === page;
|
||||
return this._renderTab(name, page, isTabActive, this.props.goToPage)
|
||||
const isTabActive = this.props.activeTab === page;
|
||||
return this._renderTab(
|
||||
name,
|
||||
page,
|
||||
isTabActive,
|
||||
this.props.goToPage
|
||||
);
|
||||
})}
|
||||
{
|
||||
this._renderUnderline()
|
||||
}
|
||||
{this._renderUnderline()}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const ButtonAndroid = props => (
|
||||
<TouchableNativeFeedback
|
||||
delayPressIn={0}
|
||||
background={TouchableNativeFeedback.SelectableBackground()}
|
||||
{...props}
|
||||
>
|
||||
{props.children}
|
||||
</TouchableNativeFeedback>
|
||||
);
|
||||
|
||||
|
||||
const ButtonAndroid = (props) => (
|
||||
<TouchableNativeFeedback
|
||||
delayPressIn={0}
|
||||
background={TouchableNativeFeedback.SelectableBackground()}
|
||||
{...props}
|
||||
>
|
||||
{props.children}
|
||||
</TouchableNativeFeedback>);
|
||||
|
||||
const ButtonIos = (props) => (<TouchableOpacity {...props}>
|
||||
{props.children}
|
||||
</TouchableOpacity>);
|
||||
|
||||
const ButtonIos = props => (
|
||||
<TouchableOpacity {...props}>{props.children}</TouchableOpacity>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tab: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
tabs: {
|
||||
height: 50,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
borderWidth: 1,
|
||||
borderTopWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 0,
|
||||
borderColor: '#f4f4f4',
|
||||
},
|
||||
});
|
||||
tab: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
tabs: {
|
||||
height: 50,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
borderWidth: 1,
|
||||
borderTopWidth: 0,
|
||||
borderLeftWidth: 0,
|
||||
borderRightWidth: 0,
|
||||
borderColor: '#f4f4f4',
|
||||
},
|
||||
});
|
||||
|
@ -1,10 +1,28 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, FlatList, View, AsyncStorage, StatusBar, Dimensions, TouchableHighlight, ActivityIndicator } from 'react-native';
|
||||
import { Container, Header, Button,
|
||||
Thumbnail, Right, Text, Tabs,
|
||||
Tab, Icon, ScrollableTab } from "native-base";
|
||||
import {
|
||||
StyleSheet,
|
||||
FlatList,
|
||||
View,
|
||||
AsyncStorage,
|
||||
StatusBar,
|
||||
Dimensions,
|
||||
TouchableHighlight,
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Button,
|
||||
Thumbnail,
|
||||
Right,
|
||||
Text,
|
||||
Tabs,
|
||||
Tab,
|
||||
Icon,
|
||||
ScrollableTab,
|
||||
} from 'native-base';
|
||||
|
||||
// STEEM
|
||||
// STEEM
|
||||
import { getPosts, getAccount } from '../../providers/steem/Dsteem';
|
||||
|
||||
// LIBRARIES
|
||||
@ -18,195 +36,216 @@ import HotPage from './hot';
|
||||
import TrendingPage from './trending';
|
||||
|
||||
class FeedPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
isReady: false,
|
||||
posts: [],
|
||||
user: [],
|
||||
start_author: '',
|
||||
start_permlink: '',
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
isLoggedIn: false,
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isReady: false,
|
||||
posts: [],
|
||||
user: [],
|
||||
start_author: '',
|
||||
start_permlink: '',
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
isLoggedIn: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem('isLoggedIn').then((result) => {
|
||||
let res = JSON.parse(result);
|
||||
if (res) {
|
||||
this.setState({
|
||||
isLoggedIn: true
|
||||
}, () => {
|
||||
AsyncStorage.getItem('user').then((result) => {
|
||||
let user = JSON.parse(result);
|
||||
getAccount(user.username).then((result) => {
|
||||
this.setState({
|
||||
user: result[0]
|
||||
}, () => {
|
||||
this.getFeed();
|
||||
})
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem('isLoggedIn').then(result => {
|
||||
let res = JSON.parse(result);
|
||||
if (res) {
|
||||
this.setState(
|
||||
{
|
||||
isLoggedIn: true,
|
||||
},
|
||||
() => {
|
||||
AsyncStorage.getItem('user').then(result => {
|
||||
let user = JSON.parse(result);
|
||||
getAccount(user.username).then(result => {
|
||||
this.setState(
|
||||
{
|
||||
user: result[0],
|
||||
},
|
||||
() => {
|
||||
this.getFeed();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getFeed = () => {
|
||||
getPosts('feed', { tag: this.state.user.name, limit: 5 })
|
||||
.then(result => {
|
||||
this.setState({
|
||||
isReady: true,
|
||||
posts: result,
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
refreshing: false,
|
||||
});
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
.catch(err => {
|
||||
alert(err);
|
||||
});
|
||||
};
|
||||
|
||||
getMore = () => {
|
||||
this.setState({ loading: true });
|
||||
getPosts('feed', {
|
||||
tag: this.state.user.name,
|
||||
limit: 10,
|
||||
start_author: this.state.start_author,
|
||||
start_permlink: this.state.start_permlink,
|
||||
}).then(result => {
|
||||
let posts = result;
|
||||
posts.shift();
|
||||
this.setState({
|
||||
posts: [...this.state.posts, ...posts],
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
getFeed = () => {
|
||||
getPosts('feed', { "tag": this.state.user.name, "limit": 5 }).then((result) => {
|
||||
this.setState({
|
||||
isReady: true,
|
||||
posts: result,
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
refreshing: false
|
||||
});
|
||||
}).catch((err) => {
|
||||
alert(err);
|
||||
});
|
||||
}
|
||||
refreshPosts = () => {
|
||||
this.setState(
|
||||
{
|
||||
refreshing: true,
|
||||
},
|
||||
() => {
|
||||
this.getFeed();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
getMore = () => {
|
||||
this.setState({ loading: true })
|
||||
getPosts('feed', { "tag": this.state.user.name, "limit": 10, "start_author": this.state.start_author, "start_permlink": this.state.start_permlink }).then((result) => {
|
||||
let posts = result;
|
||||
posts.shift();
|
||||
this.setState({
|
||||
posts: [...this.state.posts, ...posts],
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink
|
||||
});
|
||||
});
|
||||
}
|
||||
renderFooter = () => {
|
||||
if (!this.state.loading) return null;
|
||||
|
||||
refreshPosts = () => {
|
||||
this.setState({
|
||||
refreshing: true
|
||||
}, () => {
|
||||
this.getFeed();
|
||||
});
|
||||
}
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
borderColor: '#CED0CE',
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
renderFooter = () => {
|
||||
if (!this.state.loading) return null;
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
borderColor: "#CED0CE"
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const navigate = this.props.navigation;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{ this.state.isReady ? (
|
||||
<FlatList
|
||||
style={{ flex: 1 }}
|
||||
data={this.state.posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({item}) =>
|
||||
<View style={styles.card}>
|
||||
<TouchableHighlight
|
||||
onPress={() => { navigate('Post',{ content: item }) }}>
|
||||
<PostCard navigate={navigate} content={item}></PostCard>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={this.getMore}
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={() => this.refreshPosts()}
|
||||
onEndThreshold={0}
|
||||
ListFooterComponent={this.renderFooter}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
</View>
|
||||
) }
|
||||
</View>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
const navigate = this.props.navigation;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{this.state.isReady ? (
|
||||
<FlatList
|
||||
style={{ flex: 1 }}
|
||||
data={this.state.posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) => (
|
||||
<View style={styles.card}>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
navigate('Post', { content: item });
|
||||
}}
|
||||
>
|
||||
<PostCard
|
||||
navigate={navigate}
|
||||
content={item}
|
||||
/>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
)}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={this.getMore}
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={() => this.refreshPosts()}
|
||||
onEndThreshold={0}
|
||||
ListFooterComponent={this.renderFooter}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
top: StatusBar.currentHeight
|
||||
},
|
||||
placeholder: {
|
||||
backgroundColor: 'white',
|
||||
padding: 20,
|
||||
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',
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingVertical: 0,
|
||||
},
|
||||
tabs: {
|
||||
position: 'absolute',
|
||||
top: Dimensions.get("window").width / 30,
|
||||
alignItems: 'center'
|
||||
},
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
top: StatusBar.currentHeight,
|
||||
},
|
||||
placeholder: {
|
||||
backgroundColor: 'white',
|
||||
padding: 20,
|
||||
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',
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingVertical: 0,
|
||||
},
|
||||
tabs: {
|
||||
position: 'absolute',
|
||||
top: Dimensions.get('window').width / 30,
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default FeedPage;
|
||||
export default FeedPage;
|
||||
|
@ -1,10 +1,26 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View, AsyncStorage, StatusBar, Dimensions } from 'react-native';
|
||||
import { Container, Header, Button, Left,
|
||||
Thumbnail, Right, Text, Tabs,
|
||||
Tab, Icon, ScrollableTab } from "native-base";
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
AsyncStorage,
|
||||
StatusBar,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Button,
|
||||
Left,
|
||||
Thumbnail,
|
||||
Right,
|
||||
Text,
|
||||
Tabs,
|
||||
Tab,
|
||||
Icon,
|
||||
ScrollableTab,
|
||||
} from 'native-base';
|
||||
|
||||
// STEEM
|
||||
// STEEM
|
||||
import { getAccount } from '../../providers/steem/Dsteem';
|
||||
|
||||
// SCREENS
|
||||
@ -12,113 +28,180 @@ import FeedPage from './feed';
|
||||
import HotPage from './hot';
|
||||
import TrendingPage from './trending';
|
||||
|
||||
|
||||
import ScrollableTabView, { DefaultTabBar, ScrollableTabBar } from 'react-native-scrollable-tab-view'
|
||||
import CustomTabBar from './CustomTabBar'
|
||||
|
||||
import ScrollableTabView, {
|
||||
DefaultTabBar,
|
||||
ScrollableTabBar,
|
||||
} from 'react-native-scrollable-tab-view';
|
||||
import CustomTabBar from './CustomTabBar';
|
||||
|
||||
class HomePage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
user: [],
|
||||
isLoggedIn: false,
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
user: [],
|
||||
isLoggedIn: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem('isLoggedIn').then((result) => {
|
||||
let res = JSON.parse(result);
|
||||
if (res) {
|
||||
this.setState({
|
||||
isLoggedIn: true
|
||||
}, () => {
|
||||
AsyncStorage.getItem('user').then((result) => {
|
||||
let user = JSON.parse(result);
|
||||
getAccount(user.username).then((result) => {
|
||||
this.setState({
|
||||
user: result[0]
|
||||
}, () => {
|
||||
})
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem('isLoggedIn').then(result => {
|
||||
let res = JSON.parse(result);
|
||||
if (res) {
|
||||
this.setState(
|
||||
{
|
||||
isLoggedIn: true,
|
||||
},
|
||||
() => {
|
||||
AsyncStorage.getItem('user').then(result => {
|
||||
let user = JSON.parse(result);
|
||||
getAccount(user.username).then(result => {
|
||||
this.setState(
|
||||
{
|
||||
user: result[0],
|
||||
},
|
||||
() => {}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { navigate } = this.props.navigation;
|
||||
return (
|
||||
<Container style={{ flex: 1, top: StatusBar.currentHeight }}>
|
||||
<StatusBar translucent={true} backgroundColor={'transparent'}/>
|
||||
<Header noShadow style={{ backgroundColor: '#284b78', borderBottomWidth: 0, borderColor: '#284b78' }}>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
style={{ zIndex: 2 }}
|
||||
onPress={() => this.props.navigation.toggleDrawer()}>
|
||||
<Thumbnail square small source={{uri: `https://steemitimages.com/u/${this.state.user.name}/avatar/small` }} style={{ width: 30, height: 30, borderRadius: 15, borderWidth: 1, borderColor: 'white' }}/>
|
||||
</Button>
|
||||
</Left>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon style={{ color: 'white', fontWeight: 'bold' }} name='search' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
render() {
|
||||
const { navigate } = this.props.navigation;
|
||||
return (
|
||||
<Container style={{ flex: 1, top: StatusBar.currentHeight }}>
|
||||
<StatusBar translucent={true} backgroundColor={'transparent'} />
|
||||
<Header
|
||||
noShadow
|
||||
style={{
|
||||
backgroundColor: '#284b78',
|
||||
borderBottomWidth: 0,
|
||||
borderColor: '#284b78',
|
||||
}}
|
||||
>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
style={{ zIndex: 2 }}
|
||||
onPress={() => this.props.navigation.toggleDrawer()}
|
||||
>
|
||||
<Thumbnail
|
||||
square
|
||||
small
|
||||
source={{
|
||||
uri: `https://steemitimages.com/u/${
|
||||
this.state.user.name
|
||||
}/avatar/small`,
|
||||
}}
|
||||
style={{
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
borderWidth: 1,
|
||||
borderColor: 'white',
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
</Left>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon
|
||||
style={{ color: 'white', fontWeight: 'bold' }}
|
||||
name="search"
|
||||
/>
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
|
||||
<ScrollableTabView
|
||||
style={{ alignSelf: 'center', backgroundColor: 'transparent' }}
|
||||
renderTabBar={() => (
|
||||
<CustomTabBar
|
||||
style={{ alignSelf: 'center', height: 40, backgroundColor: '#284b78' }}
|
||||
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
|
||||
tabUnderlineScaleX={3} // default 3
|
||||
activeColor={"#fff"}
|
||||
inactiveColor={"#fff"}/>
|
||||
)}>
|
||||
|
||||
<View tabLabel='Feed'
|
||||
style={{ paddingHorizontal: 7, backgroundColor: '#f9f9f9', flex: 1, minWidth: Dimensions.get('window').width / 1 }}>
|
||||
{ this.state.isLoggedIn ?
|
||||
<FeedPage navigation={navigate}/>
|
||||
: (
|
||||
<View style={{ alignItems: 'center' }}>
|
||||
<Button light
|
||||
onPress={() => this.props.navigation.navigate('Login')}
|
||||
style={{ alignSelf: 'center', marginTop: 100 }}>
|
||||
<Text>
|
||||
Login to setup your custom Feed!
|
||||
</Text>
|
||||
</Button>
|
||||
</View> )
|
||||
}
|
||||
</View>
|
||||
<View tabLabel='Hot'
|
||||
style={{ paddingHorizontal: 7, backgroundColor: '#f9f9f9', flex: 1, minWidth: Dimensions.get('window').width / 1 }}>
|
||||
<HotPage navigation={navigate}/>
|
||||
</View>
|
||||
<View tabLabel='Trending'
|
||||
style={{ paddingHorizontal: 7, backgroundColor: '#f9f9f9', flex: 1, minWidth: Dimensions.get('window').width / 1 }}>
|
||||
<TrendingPage navigation={navigate}/>
|
||||
</View>
|
||||
</ScrollableTabView>
|
||||
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
<ScrollableTabView
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
backgroundColor: 'transparent',
|
||||
}}
|
||||
renderTabBar={() => (
|
||||
<CustomTabBar
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
height: 40,
|
||||
backgroundColor: '#284b78',
|
||||
}}
|
||||
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
|
||||
tabUnderlineScaleX={3} // default 3
|
||||
activeColor={'#fff'}
|
||||
inactiveColor={'#fff'}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<View
|
||||
tabLabel="Feed"
|
||||
style={{
|
||||
paddingHorizontal: 7,
|
||||
backgroundColor: '#f9f9f9',
|
||||
flex: 1,
|
||||
minWidth: Dimensions.get('window').width / 1,
|
||||
}}
|
||||
>
|
||||
{this.state.isLoggedIn ? (
|
||||
<FeedPage navigation={navigate} />
|
||||
) : (
|
||||
<View style={{ alignItems: 'center' }}>
|
||||
<Button
|
||||
light
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate('Login')
|
||||
}
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
marginTop: 100,
|
||||
}}
|
||||
>
|
||||
<Text>
|
||||
Login to setup your custom Feed!
|
||||
</Text>
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View
|
||||
tabLabel="Hot"
|
||||
style={{
|
||||
paddingHorizontal: 7,
|
||||
backgroundColor: '#f9f9f9',
|
||||
flex: 1,
|
||||
minWidth: Dimensions.get('window').width / 1,
|
||||
}}
|
||||
>
|
||||
<HotPage navigation={navigate} />
|
||||
</View>
|
||||
<View
|
||||
tabLabel="Trending"
|
||||
style={{
|
||||
paddingHorizontal: 7,
|
||||
backgroundColor: '#f9f9f9',
|
||||
flex: 1,
|
||||
minWidth: Dimensions.get('window').width / 1,
|
||||
}}
|
||||
>
|
||||
<TrendingPage navigation={navigate} />
|
||||
</View>
|
||||
</ScrollableTabView>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1
|
||||
},
|
||||
tabs: {
|
||||
flex: 1
|
||||
}
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
},
|
||||
tabs: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default HomePage;
|
||||
export default HomePage;
|
||||
|
@ -1,8 +1,16 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, FlatList, View, StatusBar, Dimensions, TouchableHighlight, ActivityIndicator } from 'react-native';
|
||||
import { Container } from "native-base";
|
||||
import {
|
||||
StyleSheet,
|
||||
FlatList,
|
||||
View,
|
||||
StatusBar,
|
||||
Dimensions,
|
||||
TouchableHighlight,
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { Container } from 'native-base';
|
||||
|
||||
// STEEM
|
||||
// STEEM
|
||||
import { getPosts, getAccount } from '../../providers/steem/Dsteem';
|
||||
|
||||
// LIBRARIES
|
||||
@ -15,170 +23,186 @@ import PostCard from '../../components/PostCard';
|
||||
import PostPage from '../../screens/single-post/Post';
|
||||
|
||||
class HotPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
isReady: false,
|
||||
posts: [],
|
||||
user: [],
|
||||
start_author: '',
|
||||
start_permlink: '',
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isReady: false,
|
||||
posts: [],
|
||||
user: [],
|
||||
start_author: '',
|
||||
start_permlink: '',
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getHotPosts();
|
||||
}
|
||||
componentDidMount() {
|
||||
this.getHotPosts();
|
||||
}
|
||||
|
||||
getHotPosts = () => {
|
||||
getPosts('hot', { "tag": "", "limit": 5 }).then((result) => {
|
||||
this.setState({
|
||||
isReady: true,
|
||||
posts: result,
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
refreshing: false
|
||||
});
|
||||
}).catch((err) => {
|
||||
alert(err);
|
||||
});
|
||||
}
|
||||
getHotPosts = () => {
|
||||
getPosts('hot', { tag: '', limit: 5 })
|
||||
.then(result => {
|
||||
this.setState({
|
||||
isReady: true,
|
||||
posts: result,
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
refreshing: false,
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err);
|
||||
});
|
||||
};
|
||||
|
||||
getMoreHot = () => {
|
||||
this.setState({ loading: true })
|
||||
getPosts('hot', { "tag": "", "limit": 10, "start_author": this.state.start_author, "start_permlink": this.state.start_permlink }).then((result) => {
|
||||
let posts = result;
|
||||
posts.shift();
|
||||
this.setState({
|
||||
posts: [...this.state.posts, ...posts],
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink
|
||||
});
|
||||
});
|
||||
}
|
||||
getMoreHot = () => {
|
||||
this.setState({ loading: true });
|
||||
getPosts('hot', {
|
||||
tag: '',
|
||||
limit: 10,
|
||||
start_author: this.state.start_author,
|
||||
start_permlink: this.state.start_permlink,
|
||||
}).then(result => {
|
||||
let posts = result;
|
||||
posts.shift();
|
||||
this.setState({
|
||||
posts: [...this.state.posts, ...posts],
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
refreshHotPosts = () => {
|
||||
this.setState({
|
||||
refreshing: true
|
||||
}, () => {
|
||||
this.getHotPosts();
|
||||
});
|
||||
}
|
||||
refreshHotPosts = () => {
|
||||
this.setState(
|
||||
{
|
||||
refreshing: true,
|
||||
},
|
||||
() => {
|
||||
this.getHotPosts();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
renderFooter = () => {
|
||||
if (!this.state.loading) return null;
|
||||
renderFooter = () => {
|
||||
if (!this.state.loading) return null;
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
borderColor: "#CED0CE"
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
borderColor: '#CED0CE',
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const navigate = this.props.navigation;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{ this.state.isReady ? (
|
||||
<FlatList
|
||||
style={{ flex: 1 }}
|
||||
data={this.state.posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({item}) =>
|
||||
<View style={styles.card}>
|
||||
<TouchableHighlight
|
||||
onPress={() => { navigate('Post',{ content: item }) }}>
|
||||
<PostCard navigate={navigate} content={item}></PostCard>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={this.getMoreHot}
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={() => this.refreshHotPosts()}
|
||||
onEndThreshold={0}
|
||||
ListFooterComponent={this.renderFooter}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
</View>
|
||||
) }
|
||||
</View>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
const navigate = this.props.navigation;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{this.state.isReady ? (
|
||||
<FlatList
|
||||
style={{ flex: 1 }}
|
||||
data={this.state.posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) => (
|
||||
<View style={styles.card}>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
navigate('Post', { content: item });
|
||||
}}
|
||||
>
|
||||
<PostCard
|
||||
navigate={navigate}
|
||||
content={item}
|
||||
/>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
)}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={this.getMoreHot}
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={() => this.refreshHotPosts()}
|
||||
onEndThreshold={0}
|
||||
ListFooterComponent={this.renderFooter}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
top: StatusBar.currentHeight
|
||||
},
|
||||
placeholder: {
|
||||
backgroundColor: 'white',
|
||||
padding: 20,
|
||||
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',
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingVertical: 0,
|
||||
},
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
top: StatusBar.currentHeight,
|
||||
},
|
||||
placeholder: {
|
||||
backgroundColor: 'white',
|
||||
padding: 20,
|
||||
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',
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingVertical: 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default HotPage;
|
||||
export default HotPage;
|
||||
|
@ -1,7 +1,16 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, FlatList, View, AsyncStorage, StatusBar, Dimensions, TouchableHighlight, ActivityIndicator } from 'react-native';
|
||||
import {
|
||||
StyleSheet,
|
||||
FlatList,
|
||||
View,
|
||||
AsyncStorage,
|
||||
StatusBar,
|
||||
Dimensions,
|
||||
TouchableHighlight,
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
|
||||
// STEEM
|
||||
// STEEM
|
||||
import { getPosts, getAccount } from '../../providers/steem/Dsteem';
|
||||
|
||||
// LIBRARIES
|
||||
@ -14,168 +23,185 @@ import PostCard from '../../components/PostCard';
|
||||
import PostPage from '../../screens/single-post/Post';
|
||||
|
||||
class TrendingPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
isReady: false,
|
||||
posts: [],
|
||||
user: [],
|
||||
start_author: '',
|
||||
start_permlink: '',
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isReady: false,
|
||||
posts: [],
|
||||
user: [],
|
||||
start_author: '',
|
||||
start_permlink: '',
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getTrending();
|
||||
}
|
||||
componentDidMount() {
|
||||
this.getTrending();
|
||||
}
|
||||
|
||||
getTrending = () => {
|
||||
getPosts('trending', { "tag": "", "limit": 5 }).then((result) => {
|
||||
this.setState({
|
||||
isReady: true,
|
||||
posts: result,
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
refreshing: false
|
||||
});
|
||||
}).catch((err) => {
|
||||
alert(err);
|
||||
});
|
||||
}
|
||||
getTrending = () => {
|
||||
getPosts('trending', { tag: '', limit: 5 })
|
||||
.then(result => {
|
||||
this.setState({
|
||||
isReady: true,
|
||||
posts: result,
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
refreshing: false,
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err);
|
||||
});
|
||||
};
|
||||
|
||||
getMore = () => {
|
||||
this.setState({ loading: true })
|
||||
getPosts('trending', { "tag": "", "limit": 10, "start_author": this.state.start_author, "start_permlink": this.state.start_permlink }).then((result) => {
|
||||
let posts = result;
|
||||
posts.shift();
|
||||
this.setState({
|
||||
posts: [...this.state.posts, ...posts],
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink
|
||||
});
|
||||
});
|
||||
}
|
||||
getMore = () => {
|
||||
this.setState({ loading: true });
|
||||
getPosts('trending', {
|
||||
tag: '',
|
||||
limit: 10,
|
||||
start_author: this.state.start_author,
|
||||
start_permlink: this.state.start_permlink,
|
||||
}).then(result => {
|
||||
let posts = result;
|
||||
posts.shift();
|
||||
this.setState({
|
||||
posts: [...this.state.posts, ...posts],
|
||||
start_author: result[result.length - 1].author,
|
||||
start_permlink: result[result.length - 1].permlink,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
refreshData = () => {
|
||||
this.setState({
|
||||
refreshing: true
|
||||
}, () => {
|
||||
this.getTrending();
|
||||
});
|
||||
}
|
||||
refreshData = () => {
|
||||
this.setState(
|
||||
{
|
||||
refreshing: true,
|
||||
},
|
||||
() => {
|
||||
this.getTrending();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
renderFooter = () => {
|
||||
if (!this.state.loading) return null;
|
||||
renderFooter = () => {
|
||||
if (!this.state.loading) return null;
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
marginBottom: 40,
|
||||
borderColor: "#CED0CE"
|
||||
}}>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
alignContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginTop: 10,
|
||||
marginBottom: 40,
|
||||
borderColor: '#CED0CE',
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator animating size="large" />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const navigate = this.props.navigation;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{ this.state.isReady ? (
|
||||
<FlatList
|
||||
data={this.state.posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({item}) =>
|
||||
<View style={styles.card}>
|
||||
<TouchableHighlight
|
||||
onPress={() => { navigate('Post',{ content: item }) }}>
|
||||
<PostCard navigate={navigate} content={item}></PostCard>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={this.getMore}
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={() => this.refreshData()}
|
||||
onEndThreshold={0}
|
||||
ListFooterComponent={this.renderFooter}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
<View style={styles.placeholder} >
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
></Placeholder.ImageContent>
|
||||
</View>
|
||||
</View>
|
||||
) }
|
||||
</View>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
const navigate = this.props.navigation;
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
{this.state.isReady ? (
|
||||
<FlatList
|
||||
data={this.state.posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) => (
|
||||
<View style={styles.card}>
|
||||
<TouchableHighlight
|
||||
onPress={() => {
|
||||
navigate('Post', { content: item });
|
||||
}}
|
||||
>
|
||||
<PostCard
|
||||
navigate={navigate}
|
||||
content={item}
|
||||
/>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
)}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={this.getMore}
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={() => this.refreshData()}
|
||||
onEndThreshold={0}
|
||||
ListFooterComponent={this.renderFooter}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.placeholder}>
|
||||
<Placeholder.ImageContent
|
||||
size={60}
|
||||
animate="fade"
|
||||
lineNumber={4}
|
||||
lineSpacing={5}
|
||||
lastLineWidth="30%"
|
||||
onReady={this.state.isReady}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
},
|
||||
placeholder: {
|
||||
backgroundColor: 'white',
|
||||
padding: 20,
|
||||
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',
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingVertical: 0,
|
||||
}
|
||||
container: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
flex: 1,
|
||||
},
|
||||
placeholder: {
|
||||
backgroundColor: 'white',
|
||||
padding: 20,
|
||||
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',
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingVertical: 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default TrendingPage;
|
||||
export default TrendingPage;
|
||||
|
@ -1,157 +1,317 @@
|
||||
import React, { Component } from 'react';
|
||||
import { View, ActivityIndicator, Text, StyleSheet, Image, StatusBar } from 'react-native';
|
||||
import { Item, Header, Input, Card, Button, Container, Icon, Left, Right, Body, Label, Thumbnail } from 'native-base';
|
||||
import {
|
||||
View,
|
||||
ActivityIndicator,
|
||||
Text,
|
||||
StyleSheet,
|
||||
Image,
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
import {
|
||||
Item,
|
||||
Header,
|
||||
Input,
|
||||
Card,
|
||||
Button,
|
||||
Container,
|
||||
Icon,
|
||||
Left,
|
||||
Right,
|
||||
Body,
|
||||
Label,
|
||||
Thumbnail,
|
||||
} from 'native-base';
|
||||
|
||||
import { Login } from '../../providers/steem/Auth';
|
||||
|
||||
class LoginPage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
username: '',
|
||||
password: '',
|
||||
isLoading: false
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
username: '',
|
||||
password: '',
|
||||
isLoading: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
doLogin = () => {
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
let password = this.state.password;
|
||||
let username = this.state.username;
|
||||
doLogin = () => {
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
Login(username, password).then((result) => {
|
||||
let password = this.state.password;
|
||||
let username = this.state.username;
|
||||
|
||||
if (result === true) {
|
||||
this.props.navigation.navigate('LoggedIn');
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
alert(err)
|
||||
this.setState({ isLoading: false });
|
||||
})
|
||||
}
|
||||
Login(username, password)
|
||||
.then(result => {
|
||||
if (result === true) {
|
||||
this.props.navigation.navigate('LoggedIn');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err);
|
||||
this.setState({ isLoading: false });
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Container style={styles.container}>
|
||||
<StatusBar translucent={true} backgroundColor={'transparent'}/>
|
||||
<Header style={{ backgroundColor: 'white', height: 80 }}>
|
||||
<Left>
|
||||
<Button transparent
|
||||
onPress={() => this.props.navigation.toggleDrawer()}>
|
||||
<Thumbnail
|
||||
style={{ width: 32, height: 32, borderRadius: 16, margin:10 }}
|
||||
source={require('../../assets/esteem.jpg')}/>
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
</Body>
|
||||
<Right>
|
||||
<Text style={{ color: '#a7adaf', marginHorizontal: 20, fontWeight: 'bold' }}>Sign Up</Text>
|
||||
</Right>
|
||||
</Header>
|
||||
<View style={styles.header}>
|
||||
<View style={{ flex: 0.5, alignItems: 'center', paddingLeft: 10 }}>
|
||||
<Text style={{ fontSize: 40, fontWeight: '600', color: '#626262', marginTop: 35 }}>Sign in</Text>
|
||||
<Text style={{ color: '#a7adaf', marginTop: 20 }}>with your username {"\n"} and password {"\n"} to get all the {"\n"} <Text style={{ fontWeight: 'bold',color: '#a7adaf' }}>benefits of eSteem</Text> </Text>
|
||||
|
||||
</View>
|
||||
<View style={{ flex: 0.5, overflow: 'hidden', padding: 0 }}>
|
||||
<Image
|
||||
style={{ width: 220, height: 304, marginTop: 10, marginLeft: 20 }}
|
||||
source={require('../../assets/love_mascot.png')}/>
|
||||
</View>
|
||||
</View>
|
||||
render() {
|
||||
return (
|
||||
<Container style={styles.container}>
|
||||
<StatusBar translucent={true} backgroundColor={'transparent'} />
|
||||
<Header style={{ backgroundColor: 'white', height: 80 }}>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
onPress={() => this.props.navigation.toggleDrawer()}
|
||||
>
|
||||
<Thumbnail
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
margin: 10,
|
||||
}}
|
||||
source={require('../../assets/esteem.jpg')}
|
||||
/>
|
||||
</Button>
|
||||
</Left>
|
||||
<Body />
|
||||
<Right>
|
||||
<Text
|
||||
style={{
|
||||
color: '#a7adaf',
|
||||
marginHorizontal: 20,
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Sign Up
|
||||
</Text>
|
||||
</Right>
|
||||
</Header>
|
||||
<View style={styles.header}>
|
||||
<View
|
||||
style={{
|
||||
flex: 0.5,
|
||||
alignItems: 'center',
|
||||
paddingLeft: 10,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 40,
|
||||
fontWeight: '600',
|
||||
color: '#626262',
|
||||
marginTop: 35,
|
||||
}}
|
||||
>
|
||||
Sign in
|
||||
</Text>
|
||||
<Text style={{ color: '#a7adaf', marginTop: 20 }}>
|
||||
with your username {'\n'} and password {'\n'} to get
|
||||
all the {'\n'}{' '}
|
||||
<Text
|
||||
style={{ fontWeight: 'bold', color: '#a7adaf' }}
|
||||
>
|
||||
benefits of eSteem
|
||||
</Text>{' '}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 0.5, overflow: 'hidden', padding: 0 }}>
|
||||
<Image
|
||||
style={{
|
||||
width: 220,
|
||||
height: 304,
|
||||
marginTop: 10,
|
||||
marginLeft: 20,
|
||||
}}
|
||||
source={require('../../assets/love_mascot.png')}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={{ padding: 30, backgroundColor: 'white', flex:0.4 }}>
|
||||
<View>
|
||||
<Item rounded
|
||||
style={{ margin: 5, backgroundColor: '#f6f6f6', height: 40, marginVertical: 10, overflow: 'hidden', borderColor: 'white' }}>
|
||||
<Icon
|
||||
name='at'
|
||||
style={{ backgroundColor: '#ececec', height: 40, width: 40, alignItems: 'center', padding: 8, color: '#a7adaf', fontWeight: 'bold' }}/>
|
||||
<Input
|
||||
autoCapitalize='none'
|
||||
placeholder='username'
|
||||
onChangeText={(text) => this.setState({username: text})} value={this.state.username}/>
|
||||
</Item>
|
||||
<View
|
||||
style={{ padding: 30, backgroundColor: 'white', flex: 0.4 }}
|
||||
>
|
||||
<View>
|
||||
<Item
|
||||
rounded
|
||||
style={{
|
||||
margin: 5,
|
||||
backgroundColor: '#f6f6f6',
|
||||
height: 40,
|
||||
marginVertical: 10,
|
||||
overflow: 'hidden',
|
||||
borderColor: 'white',
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name="at"
|
||||
style={{
|
||||
backgroundColor: '#ececec',
|
||||
height: 40,
|
||||
width: 40,
|
||||
alignItems: 'center',
|
||||
padding: 8,
|
||||
color: '#a7adaf',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
autoCapitalize="none"
|
||||
placeholder="username"
|
||||
onChangeText={text =>
|
||||
this.setState({ username: text })
|
||||
}
|
||||
value={this.state.username}
|
||||
/>
|
||||
</Item>
|
||||
|
||||
<Item rounded
|
||||
style={{ margin: 5, backgroundColor: '#f6f6f6', height: 40, marginVertical: 10, overflow: 'hidden', borderColor: 'white' }}>
|
||||
<Icon
|
||||
name='md-lock'
|
||||
style={{ backgroundColor: '#ececec', height: 40, width: 40, alignItems: 'center', paddingVertical: 7, paddingLeft: 13, color: '#a7adaf', fontWeight: 'bold' }}/>
|
||||
<Input secureTextEntry={true} placeholder='Password or WIF' onChangeText={(text) => this.setState({password: text})} value={this.state.password}/>
|
||||
</Item>
|
||||
<View>
|
||||
</View>
|
||||
<Item
|
||||
rounded
|
||||
style={{
|
||||
margin: 5,
|
||||
backgroundColor: '#f6f6f6',
|
||||
height: 40,
|
||||
marginVertical: 10,
|
||||
overflow: 'hidden',
|
||||
borderColor: 'white',
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name="md-lock"
|
||||
style={{
|
||||
backgroundColor: '#ececec',
|
||||
height: 40,
|
||||
width: 40,
|
||||
alignItems: 'center',
|
||||
paddingVertical: 7,
|
||||
paddingLeft: 13,
|
||||
color: '#a7adaf',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
secureTextEntry={true}
|
||||
placeholder="Password or WIF"
|
||||
onChangeText={text =>
|
||||
this.setState({ password: text })
|
||||
}
|
||||
value={this.state.password}
|
||||
/>
|
||||
</Item>
|
||||
<View />
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
borderBottomColor: 'lightgray',
|
||||
borderBottomWidth: 0.7,
|
||||
marginVertical: 20,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{ flexDirection: 'row', alignItems: 'center' }}
|
||||
>
|
||||
<Icon
|
||||
name="information-circle"
|
||||
style={{
|
||||
flex: 0.15,
|
||||
color: '#a7adaf',
|
||||
fontSize: 25,
|
||||
paddingLeft: 10,
|
||||
}}
|
||||
/>
|
||||
<Text style={{ flex: 0.85, color: '#a7adaf' }}>
|
||||
Don't worry! {'\n'}
|
||||
Your password is kept locally on your device and
|
||||
removed upon logout!
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
<View style={{ borderBottomColor: 'lightgray', borderBottomWidth: 0.7, marginVertical: 20 }}/>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
<Icon name='information-circle' style={{ flex: 0.15, color: '#a7adaf', fontSize: 25, paddingLeft: 10 }}/>
|
||||
<Text style={{ flex: 0.85, color: '#a7adaf' }}>
|
||||
Don't worry! {"\n"}
|
||||
Your password is kept locally on your device and removed upon logout!
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.footer}>
|
||||
<View style={{ flex: 0.6, alignItems: 'flex-end' }}>
|
||||
<Text
|
||||
onPress={() => { this.props.navigation.goBack() }}
|
||||
style={{ color: '#a7adaf', fontSize: 18, margin: 25 }}>
|
||||
Skip this screen
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 0.4, alignItems: 'center' }}>
|
||||
{ this.state.isLoading ? (
|
||||
<Button
|
||||
style={{ borderRadius: 25, padding: 5, backgroundColor: '#007EE5', width: 130, height: 35, marginTop: 20 }}>
|
||||
<ActivityIndicator color='white' style={{ marginHorizontal: 50 }}/>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
style={{ borderRadius: 25, padding: 5, backgroundColor: '#007EE5', width: 130, height: 35, marginTop: 20 }}
|
||||
onPress={() => { this.doLogin() }}>
|
||||
<Text
|
||||
style={{ color: 'white', fontWeight: 'bold', marginHorizontal: 40 }}>
|
||||
Login
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
<View style={styles.footer}>
|
||||
<View style={{ flex: 0.6, alignItems: 'flex-end' }}>
|
||||
<Text
|
||||
onPress={() => {
|
||||
this.props.navigation.goBack();
|
||||
}}
|
||||
style={{
|
||||
color: '#a7adaf',
|
||||
fontSize: 18,
|
||||
margin: 25,
|
||||
}}
|
||||
>
|
||||
Skip this screen
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 0.4, alignItems: 'center' }}>
|
||||
{this.state.isLoading ? (
|
||||
<Button
|
||||
style={{
|
||||
borderRadius: 25,
|
||||
padding: 5,
|
||||
backgroundColor: '#007EE5',
|
||||
width: 130,
|
||||
height: 35,
|
||||
marginTop: 20,
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color="white"
|
||||
style={{ marginHorizontal: 50 }}
|
||||
/>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
style={{
|
||||
borderRadius: 25,
|
||||
padding: 5,
|
||||
backgroundColor: '#007EE5',
|
||||
width: 130,
|
||||
height: 35,
|
||||
marginTop: 20,
|
||||
}}
|
||||
onPress={() => {
|
||||
this.doLogin();
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: 'white',
|
||||
fontWeight: 'bold',
|
||||
marginHorizontal: 40,
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
backgroundColor: '#f1f1f1',
|
||||
top: StatusBar.currentHeight,
|
||||
flexDirection: 'column'
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
padding: 0,
|
||||
backgroundColor: 'white',
|
||||
marginVertical: 10,
|
||||
height: 200,
|
||||
flex: 0.4
|
||||
},
|
||||
footer: {
|
||||
flex: 0.2,
|
||||
bottom: 0,
|
||||
marginTop: 10,
|
||||
height: 80,
|
||||
backgroundColor: 'white',
|
||||
flexDirection: 'row',
|
||||
}
|
||||
container: {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
backgroundColor: '#f1f1f1',
|
||||
top: StatusBar.currentHeight,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
padding: 0,
|
||||
backgroundColor: 'white',
|
||||
marginVertical: 10,
|
||||
height: 200,
|
||||
flex: 0.4,
|
||||
},
|
||||
footer: {
|
||||
flex: 0.2,
|
||||
bottom: 0,
|
||||
marginTop: 10,
|
||||
height: 80,
|
||||
backgroundColor: 'white',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
});
|
||||
export default LoginPage;
|
||||
export default LoginPage;
|
||||
|
@ -1,37 +1,46 @@
|
||||
import * as React from 'react';
|
||||
import { Container, Header, Left, Body, Right, Button, Icon, Title } from 'native-base';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Left,
|
||||
Body,
|
||||
Right,
|
||||
Button,
|
||||
Icon,
|
||||
Title,
|
||||
} from 'native-base';
|
||||
|
||||
class NotificationPage extends React.Component {
|
||||
static navigationOptions = {
|
||||
title: 'Notifications',
|
||||
};
|
||||
static navigationOptions = {
|
||||
title: 'Notifications',
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name='menu' />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Notifications</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name='search' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='heart' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='more' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name="menu" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Notifications</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name="search" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="heart" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="more" />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default NotificationPage;
|
||||
export default NotificationPage;
|
||||
|
@ -1,40 +1,50 @@
|
||||
import * as React from 'react';
|
||||
import { StatusBar} from 'react-native';
|
||||
import { Container, Header, Left, Body, Right, Button, Icon, Title, Text } from 'native-base';
|
||||
import { StatusBar } from 'react-native';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Left,
|
||||
Body,
|
||||
Right,
|
||||
Button,
|
||||
Icon,
|
||||
Title,
|
||||
Text,
|
||||
} from 'native-base';
|
||||
|
||||
class ProfilePage extends React.Component {
|
||||
static navigationOptions = {
|
||||
title: 'Profile',
|
||||
};
|
||||
static navigationOptions = {
|
||||
title: 'Profile',
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ flex: 1, top: StatusBar.currentHeight }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name='menu' />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Profile</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name='search' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='heart' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='more' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
<Text>Profile</Text>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ flex: 1, top: StatusBar.currentHeight }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name="menu" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Profile</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name="search" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="heart" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="more" />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
<Text>Profile</Text>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ProfilePage;
|
||||
export default ProfilePage;
|
||||
|
@ -1,33 +1,33 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
AsyncStorage,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
View,
|
||||
ActivityIndicator,
|
||||
AsyncStorage,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
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 () => {
|
||||
isLoggedIn = await AsyncStorage.getItem('isLoggedIn');
|
||||
// Fetch the login state from storage then navigate to our appropriate place
|
||||
checkAuth = async () => {
|
||||
isLoggedIn = await AsyncStorage.getItem('isLoggedIn');
|
||||
|
||||
// This will switch to the App screen or Auth screen and this loading
|
||||
// screen will be unmounted and thrown away.
|
||||
this.props.navigation.navigate(isLoggedIn ? 'LoggedIn' : 'LoggedOut');
|
||||
}
|
||||
// This will switch to the App screen or Auth screen and this loading
|
||||
// screen will be unmounted and thrown away.
|
||||
this.props.navigation.navigate(isLoggedIn ? 'LoggedIn' : 'LoggedOut');
|
||||
};
|
||||
|
||||
// Render any loading content that you like here
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ActivityIndicator />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
// Render any loading content that you like here
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ActivityIndicator />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
import React from 'react';
|
||||
import { AsyncStorage, StyleSheet, StatusBar, ActivityIndicator, View, Dimensions } from 'react-native';
|
||||
import {
|
||||
AsyncStorage,
|
||||
StyleSheet,
|
||||
StatusBar,
|
||||
ActivityIndicator,
|
||||
View,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import { createDrawerNavigator, createSwitchNavigator } from 'react-navigation';
|
||||
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
|
||||
@ -8,87 +15,91 @@ import { LoggedInSideBar } from './LoggedInMenu';
|
||||
import { LoggedOutSideBar } from './LoggedOutMenu';
|
||||
import LoginPage from '../login/Login';
|
||||
|
||||
const LoggedInMenu = createDrawerNavigator({
|
||||
Tabs: {
|
||||
screen: Tabs,
|
||||
navigationOptions: {
|
||||
drawer: () => ({
|
||||
label: 'Home',
|
||||
icon: ({ tintColor }) => (
|
||||
<MaterialIcons
|
||||
name="Home"
|
||||
size={24}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
const LoggedInMenu = createDrawerNavigator(
|
||||
{
|
||||
Tabs: {
|
||||
screen: Tabs,
|
||||
navigationOptions: {
|
||||
drawer: () => ({
|
||||
label: 'Home',
|
||||
icon: ({ tintColor }) => (
|
||||
<MaterialIcons
|
||||
name="Home"
|
||||
size={24}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
contentComponent: LoggedInSideBar,
|
||||
drawerWidth: Dimensions.get('window').width / 1.2
|
||||
});
|
||||
{
|
||||
contentComponent: LoggedInSideBar,
|
||||
drawerWidth: Dimensions.get('window').width / 1.2,
|
||||
}
|
||||
);
|
||||
|
||||
const LoggedOutMenu = createDrawerNavigator({
|
||||
Tabs: {
|
||||
screen: Tabs,
|
||||
},
|
||||
Login: {
|
||||
screen: LoginPage,
|
||||
navigationOptions: ({ navigation }) => ({
|
||||
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
contentComponent: LoggedOutSideBar,
|
||||
drawerWidth: Dimensions.get('window').width / 1.2
|
||||
});
|
||||
const LoggedOutMenu = createDrawerNavigator(
|
||||
{
|
||||
Tabs: {
|
||||
screen: Tabs,
|
||||
},
|
||||
Login: {
|
||||
screen: LoginPage,
|
||||
navigationOptions: ({ navigation }) => ({}),
|
||||
},
|
||||
},
|
||||
{
|
||||
contentComponent: LoggedOutSideBar,
|
||||
drawerWidth: Dimensions.get('window').width / 1.2,
|
||||
}
|
||||
);
|
||||
|
||||
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 () => {
|
||||
const isLoggedIn = await AsyncStorage.getItem('isLoggedIn');
|
||||
// Fetch the login state from storage then navigate to our appropriate place
|
||||
checkAuth = async () => {
|
||||
const isLoggedIn = await AsyncStorage.getItem('isLoggedIn');
|
||||
|
||||
// This will switch to the App screen or Auth screen and this loading
|
||||
// screen will be unmounted and thrown away.
|
||||
this.props.navigation.navigate(isLoggedIn === null ? 'LoggedOut' : 'LoggedIn');
|
||||
}
|
||||
// This will switch to the App screen or Auth screen and this loading
|
||||
// screen will be unmounted and thrown away.
|
||||
this.props.navigation.navigate(
|
||||
isLoggedIn === null ? 'LoggedOut' : 'LoggedIn'
|
||||
);
|
||||
};
|
||||
|
||||
// Render any loading content that you like here
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ActivityIndicator />
|
||||
<StatusBar barStyle="default" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
// Render any loading content that you like here
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ActivityIndicator />
|
||||
<StatusBar barStyle="default" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default createSwitchNavigator(
|
||||
{
|
||||
AuthLoading: AuthLoadingScreen,
|
||||
LoggedIn: LoggedInMenu,
|
||||
LoggedOut: LoggedOutMenu,
|
||||
},
|
||||
{
|
||||
initialRouteName: 'AuthLoading',
|
||||
}
|
||||
{
|
||||
AuthLoading: AuthLoadingScreen,
|
||||
LoggedIn: LoggedInMenu,
|
||||
LoggedOut: LoggedOutMenu,
|
||||
},
|
||||
{
|
||||
initialRouteName: 'AuthLoading',
|
||||
}
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
text: {
|
||||
fontSize: 32
|
||||
}
|
||||
})
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
text: {
|
||||
fontSize: 32,
|
||||
},
|
||||
});
|
||||
|
@ -1,249 +1,274 @@
|
||||
import React, { Component } from "react";
|
||||
import { Image, AsyncStorage } from "react-native";
|
||||
import React, { Component } from 'react';
|
||||
import { Image, AsyncStorage } from 'react-native';
|
||||
import {
|
||||
Content,
|
||||
Text,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
Container,
|
||||
Left,
|
||||
Right,
|
||||
View,
|
||||
Badge,
|
||||
Thumbnail
|
||||
} from "native-base";
|
||||
import styles from "./style";
|
||||
Content,
|
||||
Text,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
Container,
|
||||
Left,
|
||||
Right,
|
||||
View,
|
||||
Badge,
|
||||
Thumbnail,
|
||||
} from 'native-base';
|
||||
import styles from './style';
|
||||
|
||||
import { getAccount } from '../../providers/steem/Dsteem'
|
||||
import { getAccount } from '../../providers/steem/Dsteem';
|
||||
|
||||
const drawerCover = require("../../assets/drawer-cover.png");
|
||||
const drawerCover = require('../../assets/drawer-cover.png');
|
||||
const masterKeyMenuOptions = [
|
||||
{
|
||||
name: "Home",
|
||||
route: "Home",
|
||||
icon: "home",
|
||||
bg: "#C5F442"
|
||||
},
|
||||
{
|
||||
name: "Bookmarks",
|
||||
route: "bookmarks",
|
||||
icon: "bookmarks",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Drafts",
|
||||
route: "drafts",
|
||||
icon: "create",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Favorites",
|
||||
route: "favorites",
|
||||
icon: "heart",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Schedules",
|
||||
route: "schedules",
|
||||
icon: "time",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Transfer",
|
||||
route: "transfer",
|
||||
icon: "md-send",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Exchange",
|
||||
route: "exchange",
|
||||
icon: "repeat",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Marketplace",
|
||||
route: "marketplace",
|
||||
icon: "cube",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Settings",
|
||||
route: "settings",
|
||||
icon: "settings",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "FAQ",
|
||||
route: "faq",
|
||||
icon: "ios-information-circle-outline",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "About",
|
||||
route: "about",
|
||||
icon: "information-circle",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: 'Home',
|
||||
route: 'Home',
|
||||
icon: 'home',
|
||||
bg: '#C5F442',
|
||||
},
|
||||
{
|
||||
name: 'Bookmarks',
|
||||
route: 'bookmarks',
|
||||
icon: 'bookmarks',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Drafts',
|
||||
route: 'drafts',
|
||||
icon: 'create',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Favorites',
|
||||
route: 'favorites',
|
||||
icon: 'heart',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Schedules',
|
||||
route: 'schedules',
|
||||
icon: 'time',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Transfer',
|
||||
route: 'transfer',
|
||||
icon: 'md-send',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Exchange',
|
||||
route: 'exchange',
|
||||
icon: 'repeat',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Marketplace',
|
||||
route: 'marketplace',
|
||||
icon: 'cube',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
route: 'settings',
|
||||
icon: 'settings',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'FAQ',
|
||||
route: 'faq',
|
||||
icon: 'ios-information-circle-outline',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'About',
|
||||
route: 'about',
|
||||
icon: 'information-circle',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
];
|
||||
|
||||
const postingKeyMenuOptions = [
|
||||
{
|
||||
name: "Home",
|
||||
route: "Home",
|
||||
icon: "home",
|
||||
bg: "#C5F442"
|
||||
},
|
||||
{
|
||||
name: "Bookmarks",
|
||||
route: "bookmarks",
|
||||
icon: "bookmarks",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Drafts",
|
||||
route: "drafts",
|
||||
icon: "create",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Favorites",
|
||||
route: "favorites",
|
||||
icon: "heart",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Schedules",
|
||||
route: "schedules",
|
||||
icon: "time",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Marketplace",
|
||||
route: "marketplace",
|
||||
icon: "cube",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "Settings",
|
||||
route: "settings",
|
||||
icon: "settings",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "FAQ",
|
||||
route: "faq",
|
||||
icon: "ios-information-circle-outline",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: "About",
|
||||
route: "about",
|
||||
icon: "information-circle",
|
||||
bg: "#DA4437",
|
||||
},
|
||||
{
|
||||
name: 'Home',
|
||||
route: 'Home',
|
||||
icon: 'home',
|
||||
bg: '#C5F442',
|
||||
},
|
||||
{
|
||||
name: 'Bookmarks',
|
||||
route: 'bookmarks',
|
||||
icon: 'bookmarks',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Drafts',
|
||||
route: 'drafts',
|
||||
icon: 'create',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Favorites',
|
||||
route: 'favorites',
|
||||
icon: 'heart',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Schedules',
|
||||
route: 'schedules',
|
||||
icon: 'time',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Marketplace',
|
||||
route: 'marketplace',
|
||||
icon: 'cube',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
route: 'settings',
|
||||
icon: 'settings',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'FAQ',
|
||||
route: 'faq',
|
||||
icon: 'ios-information-circle-outline',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
{
|
||||
name: 'About',
|
||||
route: 'about',
|
||||
icon: 'information-circle',
|
||||
bg: '#DA4437',
|
||||
},
|
||||
];
|
||||
|
||||
export class LoggedInSideBar extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
shadowOffsetWidth: 1,
|
||||
shadowRadius: 4,
|
||||
user: [],
|
||||
loginType: '',
|
||||
json_metadata: {}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
shadowOffsetWidth: 1,
|
||||
shadowRadius: 4,
|
||||
user: [],
|
||||
loginType: '',
|
||||
json_metadata: {},
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem('user')
|
||||
.then(result => {
|
||||
let res = JSON.parse(result);
|
||||
if (res.auth_type === 'master_key') {
|
||||
this.setState({ loginType: 'master_key' });
|
||||
} else {
|
||||
this.setState({ loginType: 'posting_key' });
|
||||
}
|
||||
getAccount(res.username)
|
||||
.then(result => {
|
||||
let json_metadata = JSON.parse(result[0].json_metadata);
|
||||
this.setState({
|
||||
user: result[0],
|
||||
avatar: `https://steemitimages.com/u/${
|
||||
result[0].name
|
||||
}/avatar/small`,
|
||||
json_metadata: json_metadata.profile,
|
||||
});
|
||||
})
|
||||
.catch(err => {});
|
||||
})
|
||||
.catch(err => {});
|
||||
}
|
||||
|
||||
Logout = () => {
|
||||
AsyncStorage.clear().then(() => {
|
||||
this.props.navigation.navigate('LoggedOut');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem('user').then((result) => {
|
||||
let res = JSON.parse(result);
|
||||
if (res.auth_type === 'master_key') {
|
||||
this.setState({ loginType: 'master_key' });
|
||||
} else {
|
||||
this.setState({ loginType: 'posting_key' });
|
||||
}
|
||||
getAccount(res.username).then((result) => {
|
||||
let json_metadata = JSON.parse(result[0].json_metadata)
|
||||
this.setState({
|
||||
user: result[0],
|
||||
avatar:`https://steemitimages.com/u/${result[0].name}/avatar/small`,
|
||||
json_metadata: json_metadata.profile
|
||||
})
|
||||
}).catch((err) => {
|
||||
|
||||
});
|
||||
|
||||
}).catch((err) => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Logout = () => {
|
||||
AsyncStorage.clear().then(() => {
|
||||
this.props.navigation.navigate('LoggedOut');
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
bounces={false}
|
||||
style={{ flex: 1, backgroundColor: "#fff", top: -1 }}
|
||||
>
|
||||
<Image source={drawerCover} style={styles.drawerCover} />
|
||||
<Thumbnail square style={styles.drawerImage} source={{uri: this.state.avatar}} />
|
||||
<View style={styles.info}>
|
||||
<Text style={styles.userLabel}>{ this.state.json_metadata.name || '' }</Text>
|
||||
<Text style={styles.userLabel}>{ this.state.user.name }</Text>
|
||||
</View>
|
||||
<List
|
||||
dataArray={ this.state.loginType === 'master_key' ? masterKeyMenuOptions : postingKeyMenuOptions }
|
||||
renderRow={data =>
|
||||
<ListItem
|
||||
button
|
||||
noBorder
|
||||
onPress={() => this.props.navigation.navigate(data.route)}
|
||||
>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name={data.icon}
|
||||
style={{ color: "#777", fontSize: 26, width: 30 }}
|
||||
/>
|
||||
<Text style={styles.text}>
|
||||
{data.name}
|
||||
</Text>
|
||||
</Left>
|
||||
{data.types &&
|
||||
<Right style={{ flex: 1 }}>
|
||||
<Badge
|
||||
style={{
|
||||
borderRadius: 3,
|
||||
height: 25,
|
||||
width: 72,
|
||||
backgroundColor: data.bg
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={styles.badgeText}
|
||||
>{`${data.types} Types`}</Text>
|
||||
</Badge>
|
||||
</Right>}
|
||||
</ListItem>}
|
||||
/>
|
||||
<ListItem noBorder onPress={() => this.Logout() }>
|
||||
<Left>
|
||||
<Icon active name="log-out" style={{ color: "#777", fontSize: 26, width: 30 }}/>
|
||||
<Text style={styles.text}>
|
||||
Logout
|
||||
</Text>
|
||||
</Left>
|
||||
</ListItem>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
bounces={false}
|
||||
style={{ flex: 1, backgroundColor: '#fff', top: -1 }}
|
||||
>
|
||||
<Image source={drawerCover} style={styles.drawerCover} />
|
||||
<Thumbnail
|
||||
square
|
||||
style={styles.drawerImage}
|
||||
source={{ uri: this.state.avatar }}
|
||||
/>
|
||||
<View style={styles.info}>
|
||||
<Text style={styles.userLabel}>
|
||||
{this.state.json_metadata.name || ''}
|
||||
</Text>
|
||||
<Text style={styles.userLabel}>
|
||||
{this.state.user.name}
|
||||
</Text>
|
||||
</View>
|
||||
<List
|
||||
dataArray={
|
||||
this.state.loginType === 'master_key'
|
||||
? masterKeyMenuOptions
|
||||
: postingKeyMenuOptions
|
||||
}
|
||||
renderRow={data => (
|
||||
<ListItem
|
||||
button
|
||||
noBorder
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate(data.route)
|
||||
}
|
||||
>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name={data.icon}
|
||||
style={{
|
||||
color: '#777',
|
||||
fontSize: 26,
|
||||
width: 30,
|
||||
}}
|
||||
/>
|
||||
<Text style={styles.text}>{data.name}</Text>
|
||||
</Left>
|
||||
{data.types && (
|
||||
<Right style={{ flex: 1 }}>
|
||||
<Badge
|
||||
style={{
|
||||
borderRadius: 3,
|
||||
height: 25,
|
||||
width: 72,
|
||||
backgroundColor: data.bg,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.badgeText}>{`${
|
||||
data.types
|
||||
} Types`}</Text>
|
||||
</Badge>
|
||||
</Right>
|
||||
)}
|
||||
</ListItem>
|
||||
)}
|
||||
/>
|
||||
<ListItem noBorder onPress={() => this.Logout()}>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name="log-out"
|
||||
style={{
|
||||
color: '#777',
|
||||
fontSize: 26,
|
||||
width: 30,
|
||||
}}
|
||||
/>
|
||||
<Text style={styles.text}>Logout</Text>
|
||||
</Left>
|
||||
</ListItem>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,91 +1,101 @@
|
||||
import React, { Component } from "react";
|
||||
import { Image } from "react-native";
|
||||
import React, { Component } from 'react';
|
||||
import { Image } from 'react-native';
|
||||
import {
|
||||
Content,
|
||||
Text,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
Container,
|
||||
Left,
|
||||
Right,
|
||||
Badge
|
||||
} from "native-base";
|
||||
import styles from "./style";
|
||||
Content,
|
||||
Text,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
Container,
|
||||
Left,
|
||||
Right,
|
||||
Badge,
|
||||
} from 'native-base';
|
||||
import styles from './style';
|
||||
|
||||
const drawerCover = require("../../assets/drawer-cover.png");
|
||||
const drawerImage = require("../../assets/esteem.jpg");
|
||||
const drawerCover = require('../../assets/drawer-cover.png');
|
||||
const drawerImage = require('../../assets/esteem.jpg');
|
||||
const datas = [
|
||||
{
|
||||
name: "Home",
|
||||
route: "Home",
|
||||
icon: "home",
|
||||
bg: "#C5F442"
|
||||
},
|
||||
{
|
||||
name: "Login",
|
||||
route: "Login",
|
||||
icon: "log-in",
|
||||
bg: "#C5F442"
|
||||
}
|
||||
{
|
||||
name: 'Home',
|
||||
route: 'Home',
|
||||
icon: 'home',
|
||||
bg: '#C5F442',
|
||||
},
|
||||
{
|
||||
name: 'Login',
|
||||
route: 'Login',
|
||||
icon: 'log-in',
|
||||
bg: '#C5F442',
|
||||
},
|
||||
];
|
||||
|
||||
export class LoggedOutSideBar extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
shadowOffsetWidth: 1,
|
||||
shadowRadius: 4
|
||||
};
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
shadowOffsetWidth: 1,
|
||||
shadowRadius: 4,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
bounces={false}
|
||||
style={{ flex: 1, backgroundColor: "#fff", top: -1 }}
|
||||
>
|
||||
<Image source={drawerCover} style={styles.drawerCover} />
|
||||
<Image square style={styles.drawerImage} source={drawerImage} />
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
bounces={false}
|
||||
style={{ flex: 1, backgroundColor: '#fff', top: -1 }}
|
||||
>
|
||||
<Image source={drawerCover} style={styles.drawerCover} />
|
||||
<Image
|
||||
square
|
||||
style={styles.drawerImage}
|
||||
source={drawerImage}
|
||||
/>
|
||||
|
||||
<List
|
||||
dataArray={datas}
|
||||
renderRow={data =>
|
||||
<ListItem
|
||||
button
|
||||
noBorder
|
||||
onPress={() => this.props.navigation.navigate(data.route)}
|
||||
>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name={data.icon}
|
||||
style={{ color: "#777", fontSize: 26, width: 30 }}
|
||||
/>
|
||||
<Text style={styles.text}>
|
||||
{data.name}
|
||||
</Text>
|
||||
</Left>
|
||||
{data.types &&
|
||||
<Right style={{ flex: 1 }}>
|
||||
<Badge
|
||||
style={{
|
||||
borderRadius: 3,
|
||||
height: 25,
|
||||
width: 72,
|
||||
backgroundColor: data.bg
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={styles.badgeText}
|
||||
>{`${data.types} Types`}</Text>
|
||||
</Badge>
|
||||
</Right>}
|
||||
</ListItem>}
|
||||
/>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
<List
|
||||
dataArray={datas}
|
||||
renderRow={data => (
|
||||
<ListItem
|
||||
button
|
||||
noBorder
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate(data.route)
|
||||
}
|
||||
>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name={data.icon}
|
||||
style={{
|
||||
color: '#777',
|
||||
fontSize: 26,
|
||||
width: 30,
|
||||
}}
|
||||
/>
|
||||
<Text style={styles.text}>{data.name}</Text>
|
||||
</Left>
|
||||
{data.types && (
|
||||
<Right style={{ flex: 1 }}>
|
||||
<Badge
|
||||
style={{
|
||||
borderRadius: 3,
|
||||
height: 25,
|
||||
width: 72,
|
||||
backgroundColor: data.bg,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.badgeText}>{`${
|
||||
data.types
|
||||
} Types`}</Text>
|
||||
</Badge>
|
||||
</Right>
|
||||
)}
|
||||
</ListItem>
|
||||
)}
|
||||
/>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,47 @@
|
||||
const React = require("react-native");
|
||||
const React = require('react-native');
|
||||
const { Platform, Dimensions } = React;
|
||||
|
||||
const deviceHeight = Dimensions.get("window").height;
|
||||
const deviceWidth = Dimensions.get("window").width;
|
||||
const deviceHeight = Dimensions.get('window').height;
|
||||
const deviceWidth = Dimensions.get('window').width;
|
||||
|
||||
export default {
|
||||
drawerCover: {
|
||||
alignSelf: "stretch",
|
||||
height: deviceHeight / 4,
|
||||
width: null,
|
||||
position: "relative",
|
||||
marginBottom: 10
|
||||
},
|
||||
drawerImage: {
|
||||
position: "absolute",
|
||||
left: Platform.OS === "android" ? deviceWidth / 10 : deviceWidth / 30,
|
||||
top: Platform.OS === "android" ? deviceHeight / 13 : deviceHeight / 15,
|
||||
width: 60,
|
||||
height: 60,
|
||||
resizeMode: "cover",
|
||||
borderWidth: 1,
|
||||
borderColor: 'white',
|
||||
borderRadius: 30,
|
||||
},
|
||||
text: {
|
||||
fontWeight: Platform.OS === "ios" ? "500" : "400",
|
||||
fontSize: 16,
|
||||
marginLeft: 20
|
||||
},
|
||||
badgeText: {
|
||||
fontSize: Platform.OS === "ios" ? 13 : 11,
|
||||
fontWeight: "400",
|
||||
textAlign: "center",
|
||||
marginTop: Platform.OS === "android" ? -3 : undefined
|
||||
},
|
||||
info: {
|
||||
position: 'absolute',
|
||||
top: Platform.OS === "android" ? deviceHeight / 13 : deviceHeight / 5.8,
|
||||
left: Platform.OS === "android" ? deviceWidth / 10 : deviceWidth / 40,
|
||||
|
||||
},
|
||||
userLabel: {
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
marginBottom: 3
|
||||
}
|
||||
drawerCover: {
|
||||
alignSelf: 'stretch',
|
||||
height: deviceHeight / 4,
|
||||
width: null,
|
||||
position: 'relative',
|
||||
marginBottom: 10,
|
||||
},
|
||||
drawerImage: {
|
||||
position: 'absolute',
|
||||
left: Platform.OS === 'android' ? deviceWidth / 10 : deviceWidth / 30,
|
||||
top: Platform.OS === 'android' ? deviceHeight / 13 : deviceHeight / 15,
|
||||
width: 60,
|
||||
height: 60,
|
||||
resizeMode: 'cover',
|
||||
borderWidth: 1,
|
||||
borderColor: 'white',
|
||||
borderRadius: 30,
|
||||
},
|
||||
text: {
|
||||
fontWeight: Platform.OS === 'ios' ? '500' : '400',
|
||||
fontSize: 16,
|
||||
marginLeft: 20,
|
||||
},
|
||||
badgeText: {
|
||||
fontSize: Platform.OS === 'ios' ? 13 : 11,
|
||||
fontWeight: '400',
|
||||
textAlign: 'center',
|
||||
marginTop: Platform.OS === 'android' ? -3 : undefined,
|
||||
},
|
||||
info: {
|
||||
position: 'absolute',
|
||||
top: Platform.OS === 'android' ? deviceHeight / 13 : deviceHeight / 5.8,
|
||||
left: Platform.OS === 'android' ? deviceWidth / 10 : deviceWidth / 40,
|
||||
},
|
||||
userLabel: {
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
marginBottom: 3,
|
||||
},
|
||||
};
|
||||
|
@ -1,6 +1,16 @@
|
||||
import React from 'react';
|
||||
import { Dimensions, StyleSheet, StatusBar } from 'react-native';
|
||||
import { Container, Content, Header, Left, Body, Right, Button, Icon, Title } from 'native-base';
|
||||
import {
|
||||
Container,
|
||||
Content,
|
||||
Header,
|
||||
Left,
|
||||
Body,
|
||||
Right,
|
||||
Button,
|
||||
Icon,
|
||||
Title,
|
||||
} from 'native-base';
|
||||
import HTMLView from 'react-native-htmlview';
|
||||
import HTML from 'react-native-render-html';
|
||||
import { Client } from 'dsteem';
|
||||
@ -9,98 +19,106 @@ const client = new Client('https://api.steemit.com');
|
||||
import { parsePost, protocolUrl2Obj } from '../../utils/PostParser';
|
||||
|
||||
class SinglePostPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
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('@', '')
|
||||
client.database.call('get_content', [steemPost[3], steemPost[4]]).then((result) => {
|
||||
let content = parsePost(result);
|
||||
this.props.navigation.push('Post',{ content: content })
|
||||
}).catch((err) => {
|
||||
alert(err)
|
||||
});
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
}
|
||||
|
||||
alterNode(node) {
|
||||
if (node.name == 'img' || node.name == 'a') {
|
||||
// console.log(node);
|
||||
} else if (node.name == 'iframe') {
|
||||
node.attribs.height = 200
|
||||
componentDidMount() {}
|
||||
|
||||
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('@', '');
|
||||
client.database
|
||||
.call('get_content', [steemPost[3], steemPost[4]])
|
||||
.then(result => {
|
||||
let content = parsePost(result);
|
||||
this.props.navigation.push('Post', { content: content });
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ top: StatusBar.currentHeight }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent onPress={() => this.props.navigation.goBack()}>
|
||||
<Icon name='arrow-back' />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title></Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name='bookmark' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='more' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
<Content>
|
||||
<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']}
|
||||
debug={true}
|
||||
alterNode={ (node) => { this.alterNode(node) } }
|
||||
imagesMaxWidth={ Dimensions.get('window').width } />
|
||||
</Content>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
alterNode(node) {
|
||||
if (node.name == 'img' || node.name == 'a') {
|
||||
// console.log(node);
|
||||
} else if (node.name == 'iframe') {
|
||||
node.attribs.height = 200;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container style={{ top: StatusBar.currentHeight }}>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
onPress={() => this.props.navigation.goBack()}
|
||||
>
|
||||
<Icon name="arrow-back" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title />
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name="bookmark" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="more" />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
<Content>
|
||||
<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']}
|
||||
debug={true}
|
||||
alterNode={node => {
|
||||
this.alterNode(node);
|
||||
}}
|
||||
imagesMaxWidth={Dimensions.get('window').width}
|
||||
/>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
iframe: {
|
||||
maxWidth: Dimensions.get('window').width,
|
||||
marginVertical: 10,
|
||||
left: -10
|
||||
},
|
||||
p: {
|
||||
|
||||
},
|
||||
img: {
|
||||
left: -10,
|
||||
marginVertical: 10
|
||||
}
|
||||
})
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
iframe: {
|
||||
maxWidth: Dimensions.get('window').width,
|
||||
marginVertical: 10,
|
||||
left: -10,
|
||||
},
|
||||
p: {},
|
||||
img: {
|
||||
left: -10,
|
||||
marginVertical: 10,
|
||||
},
|
||||
});
|
||||
|
||||
export default SinglePostPage;
|
||||
|
||||
|
@ -1,37 +1,46 @@
|
||||
import * as React from 'react';
|
||||
import { Container, Header, Left, Body, Right, Button, Icon, Title } from 'native-base';
|
||||
import {
|
||||
Container,
|
||||
Header,
|
||||
Left,
|
||||
Body,
|
||||
Right,
|
||||
Button,
|
||||
Icon,
|
||||
Title,
|
||||
} from 'native-base';
|
||||
|
||||
class WalletPage extends React.Component {
|
||||
static navigationOptions = {
|
||||
title: 'Wallet',
|
||||
};
|
||||
static navigationOptions = {
|
||||
title: 'Wallet',
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name='menu' />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Wallet</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name='search' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='heart' />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name='more' />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Header>
|
||||
<Left>
|
||||
<Button transparent>
|
||||
<Icon name="menu" />
|
||||
</Button>
|
||||
</Left>
|
||||
<Body>
|
||||
<Title>Wallet</Title>
|
||||
</Body>
|
||||
<Right>
|
||||
<Button transparent>
|
||||
<Icon name="search" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="heart" />
|
||||
</Button>
|
||||
<Button transparent>
|
||||
<Icon name="more" />
|
||||
</Button>
|
||||
</Right>
|
||||
</Header>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default WalletPage;
|
||||
export default WalletPage;
|
||||
|
@ -1,34 +1,71 @@
|
||||
// TODO: Refactor
|
||||
export const sanitizeNode = (node) => {
|
||||
export const sanitizeNode = node => {
|
||||
const ALLOWED_TAGS = [
|
||||
'A',
|
||||
'STRONG',
|
||||
'B',
|
||||
'I',
|
||||
'EM',
|
||||
'CODE',
|
||||
'BLOCKQUOTE',
|
||||
'SUP',
|
||||
'SUB',
|
||||
'H2',
|
||||
'H1',
|
||||
'H3',
|
||||
'H4',
|
||||
'H5',
|
||||
'H6',
|
||||
'DIV',
|
||||
'P',
|
||||
'IFRAME',
|
||||
'CENTER',
|
||||
'UL',
|
||||
'OL',
|
||||
'LI',
|
||||
'TABLE',
|
||||
'THEAD',
|
||||
'TBODY',
|
||||
'TR',
|
||||
'TD',
|
||||
'TH',
|
||||
'HR',
|
||||
'BR',
|
||||
'IMG',
|
||||
];
|
||||
|
||||
const ALLOWED_TAGS = [
|
||||
'A', 'STRONG', 'B', 'I', 'EM', 'CODE', 'BLOCKQUOTE', 'SUP', 'SUB',
|
||||
'H2', 'H1', 'H3', 'H4', 'H5', 'H6',
|
||||
'DIV', 'P', 'IFRAME', 'CENTER',
|
||||
'UL', 'OL', 'LI',
|
||||
'TABLE', 'THEAD', 'TBODY', 'TR', 'TD', 'TH',
|
||||
'HR', 'BR', 'IMG'
|
||||
];
|
||||
const ALLOWED_ATTRS = [
|
||||
'data-permlink',
|
||||
'data-tag',
|
||||
'data-author',
|
||||
'data-href',
|
||||
'class',
|
||||
'src',
|
||||
'alt',
|
||||
'title',
|
||||
'width',
|
||||
'height',
|
||||
'border',
|
||||
'frameborder',
|
||||
'allowfullscreen',
|
||||
'mozallowfullscreen',
|
||||
'webkitallowfullscreen',
|
||||
];
|
||||
|
||||
const ALLOWED_ATTRS = [
|
||||
'data-permlink', 'data-tag', 'data-author', 'data-href',
|
||||
'class', 'src', 'alt', 'title', 'width', 'height', 'border',
|
||||
'frameborder', 'allowfullscreen', 'mozallowfullscreen', 'webkitallowfullscreen'
|
||||
];
|
||||
const allElems = node.querySelectorAll('*');
|
||||
allElems.forEach(el => {
|
||||
if (ALLOWED_TAGS.indexOf(el.tagName) === -1) {
|
||||
el.outerHTML = `<span>${el.innerText
|
||||
.replace('>', '>')
|
||||
.replace('<', '<')}</span>`;
|
||||
}
|
||||
|
||||
const allElems = node.querySelectorAll('*');
|
||||
allElems.forEach((el) => {
|
||||
for (let attr of el.attributes) {
|
||||
if (ALLOWED_ATTRS.indexOf(attr.name) === -1) {
|
||||
el.removeAttribute(attr.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (ALLOWED_TAGS.indexOf(el.tagName) === -1) {
|
||||
el.outerHTML = `<span>${el.innerText.replace('>', '>').replace('<', '<')}</span>`;
|
||||
}
|
||||
|
||||
for (let attr of el.attributes) {
|
||||
if (ALLOWED_ATTRS.indexOf(attr.name) === -1) {
|
||||
el.removeAttribute(attr.name)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return node;
|
||||
};
|
||||
return node;
|
||||
};
|
||||
|
@ -3,105 +3,123 @@ import { postSummary } from './PostSummary';
|
||||
import { reputation } from './Reputation';
|
||||
import moment from 'moment';
|
||||
|
||||
const md = new Remarkable({html: true, breaks: true, linkify: true});
|
||||
const md = new Remarkable({ html: true, breaks: true, linkify: true });
|
||||
|
||||
export const replaceAuthorNames = (input) => {
|
||||
return input.replace(
|
||||
/(^|[^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 || '');
|
||||
export const replaceAuthorNames = input => {
|
||||
return input.replace(
|
||||
/(^|[^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>`;
|
||||
});
|
||||
};
|
||||
|
||||
export const markDown2Html = (input) => {
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Start replacing user names
|
||||
let output = replaceAuthorNames(input);
|
||||
|
||||
// Replace tags
|
||||
output = replaceTags(output);
|
||||
|
||||
output = md.render(output);
|
||||
|
||||
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;
|
||||
|
||||
// TODO: Implement Regex
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
export const parsePosts = (posts) => {
|
||||
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
|
||||
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>`
|
||||
);
|
||||
});
|
||||
if (post.active_votes.length > 2) {
|
||||
post.top_likers = [post.active_votes[0].voter, post.active_votes[1].voter, post.active_votes[2].voter]
|
||||
};
|
||||
|
||||
export const markDown2Html = input => {
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
return posts;
|
||||
}
|
||||
|
||||
export const protocolUrl2Obj = (url) => {
|
||||
let urlPart = url.split('://')[1];
|
||||
// Start replacing user names
|
||||
let output = replaceAuthorNames(input);
|
||||
|
||||
// remove last char if /
|
||||
if(urlPart.endsWith('/')){
|
||||
urlPart = urlPart.substring(0, urlPart.length - 1);
|
||||
}
|
||||
// Replace tags
|
||||
output = replaceTags(output);
|
||||
|
||||
const parts = urlPart.split('/');
|
||||
output = md.render(output);
|
||||
|
||||
// filter
|
||||
if (parts.length === 1 && filters.includes(parts[0])) {
|
||||
return {type: 'filter', filter: parts[0]};
|
||||
}
|
||||
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;
|
||||
|
||||
// filter with tag
|
||||
if (parts.length === 2 && filters.includes(parts[0])) {
|
||||
return {type: 'filter-tag', filter: parts[0], tag: parts[1]};
|
||||
}
|
||||
// TODO: Implement Regex
|
||||
|
||||
// account
|
||||
if (parts.length === 1 && parts[0].startsWith('@')) {
|
||||
return {type: 'account', account: parts[0].replace('@', '')};
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
// post
|
||||
if (parts.length === 3 && parts[1].startsWith('@')) {
|
||||
return {type: 'post', cat: parts[0], author: parts[1].replace('@', ''), permlink: parts[2]};
|
||||
}
|
||||
};
|
||||
export const parsePosts = posts => {
|
||||
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;
|
||||
});
|
||||
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 protocolUrl2Obj = url => {
|
||||
let urlPart = url.split('://')[1];
|
||||
|
||||
// remove last char if /
|
||||
if (urlPart.endsWith('/')) {
|
||||
urlPart = urlPart.substring(0, urlPart.length - 1);
|
||||
}
|
||||
|
||||
const parts = urlPart.split('/');
|
||||
|
||||
// filter
|
||||
if (parts.length === 1 && filters.includes(parts[0])) {
|
||||
return { type: 'filter', filter: parts[0] };
|
||||
}
|
||||
|
||||
// filter with tag
|
||||
if (parts.length === 2 && filters.includes(parts[0])) {
|
||||
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('@', '') };
|
||||
}
|
||||
|
||||
// post
|
||||
if (parts.length === 3 && parts[1].startsWith('@')) {
|
||||
return {
|
||||
type: 'post',
|
||||
cat: parts[0],
|
||||
author: parts[1].replace('@', ''),
|
||||
permlink: parts[2],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -1,19 +1,19 @@
|
||||
export const postSummary = (postBody, length) => {
|
||||
if (!postBody) {
|
||||
return '';
|
||||
}
|
||||
if (!postBody) {
|
||||
return '';
|
||||
}
|
||||
|
||||
postBody = postBody
|
||||
.replace(/(<([^>]+)>)/ig, '') // 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
|
||||
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;
|
||||
};
|
||||
if (length) {
|
||||
// Truncate
|
||||
postBody = postBody.substring(0, length);
|
||||
}
|
||||
|
||||
return postBody;
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
export const reputation = (reputation) => {
|
||||
if (reputation == null) return reputation;
|
||||
reputation = parseInt(reputation);
|
||||
let log = Math.log10(reputation);
|
||||
log = log - 9;
|
||||
log = log * 9;
|
||||
log = log + 25;
|
||||
log = Math.floor(log);
|
||||
return log;
|
||||
}
|
||||
export const reputation = reputation => {
|
||||
if (reputation == null) return reputation;
|
||||
reputation = parseInt(reputation);
|
||||
let log = Math.log10(reputation);
|
||||
log = log - 9;
|
||||
log = log * 9;
|
||||
log = log + 25;
|
||||
log = Math.floor(log);
|
||||
return log;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user