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