Merged with master

This commit is contained in:
mistikk 2018-10-02 19:53:19 -04:00
commit 43d7aebc5b
84 changed files with 5331 additions and 4840 deletions

49
package-lock.json generated
View File

@ -2426,7 +2426,7 @@
},
"browserify-aes": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"requires": {
"buffer-xor": "^1.0.3",
@ -2979,7 +2979,7 @@
},
"create-hash": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"requires": {
"cipher-base": "^1.0.1",
@ -2991,7 +2991,7 @@
},
"create-hmac": {
"version": "1.1.7",
"resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"requires": {
"cipher-base": "^1.0.3",
@ -7710,6 +7710,15 @@
"graceful-fs": "^4.1.2",
"jsonfile": "^2.1.0"
}
},
"react-native-keyboard-aware-scroll-view": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.5.0.tgz",
"integrity": "sha512-nGXsACZBCiWuwRrZy+UjiSJqb4tZ/6ePHUSY8M+09g4VfNm/ogvvWpwBa6B999NZ6DwhZTKBjVWeZxX9XG8bbQ==",
"requires": {
"prop-types": "^15.6.0",
"react-native-iphone-x-helper": "^1.0.1"
}
}
}
},
@ -8867,17 +8876,17 @@
}
},
"react-native-iphone-x-helper": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.3.tgz",
"integrity": "sha512-QHzpx4fv9u30VVU1DMgotiZsUB+m4BRjypca2rOczyj3cZBny5I+QDplrpFIBhzsa1iADNkziWa7kInzmKs00Q=="
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.0.tgz",
"integrity": "sha512-xIeTo4s77wwKgBZLVRIZC9tM9/PkXS46Ul76NXmvmixEb3ZwqGdQesR3zRiLMOoIdfOURB6N9bba9po7+x9Bag=="
},
"react-native-keyboard-aware-scroll-view": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.5.0.tgz",
"integrity": "sha512-nGXsACZBCiWuwRrZy+UjiSJqb4tZ/6ePHUSY8M+09g4VfNm/ogvvWpwBa6B999NZ6DwhZTKBjVWeZxX9XG8bbQ==",
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/react-native-keyboard-aware-scroll-view/-/react-native-keyboard-aware-scroll-view-0.7.2.tgz",
"integrity": "sha512-FCVKAmM5jHwbWZFW/zUOhid18OoSGcbyx2jGk+q6eVjjtj+RPomeqX0aAHf2ALXYJ1BuC5+OtXhFA/hp8ombcQ==",
"requires": {
"prop-types": "^15.6.0",
"react-native-iphone-x-helper": "^1.0.1"
"prop-types": "^15.6.2",
"react-native-iphone-x-helper": "^1.0.3"
}
},
"react-native-lightbox": {
@ -8914,6 +8923,14 @@
"react-native-animatable": "^1.2.4"
}
},
"react-native-modal-dropdown": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/react-native-modal-dropdown/-/react-native-modal-dropdown-0.6.2.tgz",
"integrity": "sha512-1jzByA+ME+q0mZJ2rZrLsf6jVwJhNxNHdg7I50xYZ9oYJsmmKwF9r/ks95tZxxks4Zvd7/FnaveNtyd+uevXAw==",
"requires": {
"prop-types": "^15.6.0"
}
},
"react-native-modal-popover": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/react-native-modal-popover/-/react-native-modal-popover-0.0.10.tgz",
@ -8956,14 +8973,6 @@
"prop-types": "^15.5.10"
}
},
"react-native-theming": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/react-native-theming/-/react-native-theming-1.0.16.tgz",
"integrity": "sha512-f8P7F3yKW9i+PmsmZo98V933Ggsu6YpsBw8pvNEAOENnNqbFmeDL6K+89F0WmkpF6bSs/qqSbyGUWKvCgNhBkw==",
"requires": {
"prop-types": "^15.6.0"
}
},
"react-native-vector-icons": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-4.6.0.tgz",
@ -9915,7 +9924,7 @@
},
"sha.js": {
"version": "2.4.11",
"resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"requires": {
"inherits": "^2.0.1",

View File

@ -25,13 +25,14 @@
"react-native-extended-stylesheet": "^0.10.0",
"react-native-fast-image": "^4.0.14",
"react-native-html-renderer": "^1.0.0",
"react-native-keyboard-aware-scroll-view": "^0.7.2",
"react-native-markdown-editor": "^1.0.1",
"react-native-modal": "^6.5.0",
"react-native-modal-dropdown": "^0.6.2",
"react-native-modal-popover": "0.0.10",
"react-native-navigation": "^2.0.2519",
"react-native-restart": "0.0.6",
"react-native-slider": "^0.11.0",
"react-native-theming": "^1.0.16",
"react-native-vector-icons": "^4.6.0",
"react-redux": "^5.0.7",
"realm": "^2.15.3",

View File

@ -0,0 +1,43 @@
import React, { Component } from "react";
import { connect } from "react-redux";
// Services and Actions
// Middleware
// Constants
// Utilities
// Component
import { ExampleView } from "../";
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class ExampleContainer extends Component {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycle Functions
// Component Functions
render() {
// eslint-disable-next-line
const {} = this.props;
return <ExampleView />;
}
}
const mapStateToProps = state => ({
user: state.user.user,
});
export default connect(mapStateToProps)(ExampleContainer);

View File

@ -0,0 +1,5 @@
import ExampleView from "./view/exampleView";
import ExampleContainer from "./container/exampleContainer";
export { ExampleView, ExampleContainer };
export default ExampleContainer;

View File

@ -0,0 +1,7 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
styleName: {
// TODO: If we need default style. We can put there.
},
});

View File

@ -11,11 +11,10 @@ import styles from "./_styles";
class ExampleView extends Component {
/* Props
* ------------------------------------------------ TODO: Fill fallowlines
* @prop { type } name - Description.
* @prop { type } name - Description.
*
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
this.state = {};

View File

@ -0,0 +1,7 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
styleName: {
// TODO: If we need default style. We can put there.
},
});

View File

@ -0,0 +1,12 @@
import React from "react";
import { View } from "react-native";
import styles from "./exampleStyles";
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
const ExampleView = ({ x, y, z }) => <View />;
export default ExampleView;

View File

@ -1,5 +0,0 @@
import ExampleView from "./exampleView";
import ExampleContainer from "./exampleContainer";
export { ExampleView, ExampleContainer };
export default ExampleContainer;

View File

@ -1,3 +0,0 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({});

View File

@ -1,3 +0,0 @@
import Exmaple from "./example/example.container";
export { Exmaple };

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -5,5 +5,6 @@ export default EStyleSheet.create({
width: "$deviceWidth",
backgroundColor: "#f6f6f6",
height: 10,
justifyContent: "center",
},
});

View File

@ -2,6 +2,10 @@ import React from "react";
import { View } from "react-native";
import styles from "./lineBreakStyles";
const LineBreak = ({ color }) => <View style={[styles.lineBreak]} />;
const LineBreak = ({ color, children, height }) => (
<View style={[styles.lineBreak, { height: height, color: color }]}>
{children}
</View>
);
export default LineBreak;

View File

@ -1,5 +1,5 @@
import GreetingHeaderButton from "./views/greetingHeaderButtonView";
import CircularButton from "./views/circularButtonView";
import IconButton from "./views/iconButtomView";
import TextButton from "./views/textButtonView";
export { GreetingHeaderButton, CircularButton, IconButton };
export { CircularButton, IconButton, TextButton };

View File

@ -1,17 +0,0 @@
import React, { Fragment } from "react";
import { TouchableWithoutFeedback, Text } from "react-native";
import styles from "./greetingHeaderButtonStyles";
const GreetingHeaderButtonView = ({ text, onPress, style }) => (
<Fragment>
<TouchableWithoutFeedback
style={[styles.button, style]}
onPress={() => onPress && onPress()}
>
<Text style={styles.buttonText}>{text}</Text>
</TouchableWithoutFeedback>
</Fragment>
);
export default GreetingHeaderButtonView;

View File

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

View File

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

View File

@ -0,0 +1,4 @@
import ContainerHeader from "./view/containerHeaderView";
export { ContainerHeader };
export default ContainerHeader;

View File

@ -0,0 +1,20 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
wrapper: {
width: "$deviceWidth",
height: 50,
backgroundColor: "$white",
borderTopColor: "#cfcfcf",
justifyContent: "center",
borderTopColor: "#e7e7e7",
borderTopWidth: 1,
},
title: {
alignSelf: "flex-start",
fontSize: 14,
color: "$primaryGray",
fontWeight: "bold",
marginLeft: 26,
},
});

View File

@ -0,0 +1,37 @@
import React, { Component } from "react";
import { View, Text } from "react-native";
// Constants
// Components
// Styles
import styles from "./containerHeaderStyles";
class ContainerHeaderView extends Component {
/* Props
* ------------------------------------------------
* @prop { type } title - Renderable title for header.
*
*/
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycles
// Component Functions
render() {
const { title } = this.props;
return (
<View style={styles.wrapper}>
<Text style={styles.title}>{title}</Text>
</View>
);
}
}
export default ContainerHeaderView;

View File

@ -0,0 +1,4 @@
import DropdownButton from "./view/dropdownButtonView";
export { DropdownButton };
export default DropdownButton;

View File

@ -0,0 +1,85 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
alignSelf: "flex-start",
height: 35,
},
dropdownText: {
fontSize: 9,
color: "$primaryGray",
marginLeft: 25,
},
dropdownIcon: {
fontSize: 18,
color: "#c1c5c7",
marginLeft: 7,
marginTop: 1,
},
dropdown: {
marginTop: 5,
marginLeft: -2,
paddingTop: 10,
paddingBottom: 10,
minWidth: "$deviceWidth / 2",
borderColor: "#e7e7e7",
borderRadius: 5,
shadowOpacity: 0.8,
shadowColor: "#e7e7e7",
},
iconWrapper: {
justifyContent: "center",
alignItems: "center",
},
dropdownText: {
fontSize: 9,
color: "$primaryGray",
padding: 5,
borderColor: "#e7e7e7",
},
dropdownTextHighlight: {
backgroundColor: "#387be5",
width: "$deviceWidth / 3",
},
button: {
marginLeft: 25,
},
buttonText: {
fontSize: 9,
alignSelf: "center",
color: "$primaryGray",
fontWeight: "normal",
},
rowWrapper: {
height: 35,
justifyContent: "center",
borderTopRightRadius: 20,
borderBottomRightRadius: 20,
width: "$deviceWidth / 2.5",
padding: 5,
},
dropdownRow: {
marginLeft: 30,
justifyContent: "center",
},
highlightedRow: {
borderRadius: 20,
height: 35,
backgroundColor: "$primaryBlue",
alignSelf: "flex-start",
paddingLeft: 11,
paddingRight: 11,
marginLeft: 20,
},
highlightedRowText: {
color: "$white",
fontWeight: "bold",
},
rowText: {
fontSize: 9,
color: "$primaryGray",
},
});

View File

@ -0,0 +1,70 @@
import React from "react";
import { View, Text, TouchableHighlight } from "react-native";
import { Dimensions } from "react-native";
// Constants
const DEVICE_HEIGHT = Dimensions.get("window").height;
// External components
import ModalDropdown from "react-native-modal-dropdown";
import Ionicons from "react-native-vector-icons/Ionicons";
// Styles
import styles from "./dropdownButtonStyles";
/* Props TODO: Fill all description
* ------------------------------------------------
* @prop { string } defaultText - Description....
* @prop { string } iconName - Description....
* @prop { array } options - Description....
* @prop { function } onSelect - Description....
*
*/
const renderDropdownRow = (rowData, rowID, highlighted) => {
return (
<TouchableHighlight style={styles.rowWrapper} underlayColor="#E9F2FC">
<View style={[styles.dropdownRow, highlighted && styles.highlightedRow]}>
<Text
style={[styles.rowText, highlighted && styles.highlightedRowText]}
>
{rowData}
</Text>
</View>
</TouchableHighlight>
);
};
const DropdownButtonView = ({
defaultText,
iconName,
options,
onSelect,
defaultIndex,
}) => (
<View style={styles.container}>
<ModalDropdown
style={styles.button}
textStyle={styles.buttonText}
dropdownStyle={[styles.dropdown, { height: 35 * (options.length + 1) }]}
dropdownTextStyle={styles.dropdownText}
dropdownTextHighlightStyle={styles.dropdownTextHighlight}
options={options}
onSelect={e => onSelect && onSelect(e)}
defaultIndex={defaultIndex}
defaultValue={defaultText}
renderSeparator={() => null}
renderRow={(rowData, rowID, highlighted) =>
renderDropdownRow(rowData, rowID, highlighted)
}
/>
<View style={styles.iconWrapper}>
<Ionicons
style={styles.dropdownIcon}
name={!iconName ? "md-arrow-dropdown" : iconName}
/>
</View>
</View>
);
export default DropdownButtonView;

View File

@ -0,0 +1,4 @@
import FilterBar from "./view/filterBarView";
export { FilterBar };
export default FilterBar;

View File

@ -0,0 +1,20 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
justifyContent: "center",
},
filterBarWrapper: {
flexDirection: "row",
justifyContent: "space-between",
},
rightIconWrapper: {
marginRight: 32,
},
rightIcon: {
color: "#c1c5c7",
fontSize: 32,
textAlign: "center",
width: 32,
},
});

View File

@ -0,0 +1,47 @@
import React from "react";
import { View, TouchableOpacity, Text } from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
// External Components
import { DropdownButton } from "../../../components/dropdownButton";
// Components
import { LineBreak } from "../../basicUIElements";
// Styles
import styles from "./filterBarStyles";
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
const FilterBarView = ({
rightIconName,
options,
defaultText,
dropdownIconName,
onDropdownSelect,
onRightIconPress,
}) => (
<View style={styles.container}>
<LineBreak color="#f6f6f6" height={35}>
<View style={styles.filterBarWrapper}>
<DropdownButton
iconName={dropdownIconName}
options={options}
defaultText={defaultText}
onSelect={onDropdownSelect}
/>
<TouchableOpacity
onPress={onRightIconPress && onRightIconPress()}
style={styles.rightIconWrapper}
>
<Ionicons style={styles.rightIcon} name={rightIconName} />
</TouchableOpacity>
</View>
</LineBreak>
</View>
);
export default FilterBarView;

View File

@ -5,7 +5,7 @@ export default EStyleSheet.create({
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
marginHorizontal: 30,
marginVertical: 20,
marginVertical: 10,
flexDirection: "row",
backgroundColor: "#f5f5f5",
height: 60,

View File

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

View File

@ -1,6 +1,6 @@
import Logo from "./logo/logo";
import Comment from "./comment/comment";
import PostCard from "./post-card/postCard";
import PostCard from "./postCard";
import Reply from "./reply/reply";
import Search from "./search/search";
import { FormInput } from "./formInput";

View File

@ -5,7 +5,7 @@ export default EStyleSheet.create({
flexDirection: "row",
paddingLeft: 50,
paddingRight: 32,
marginTop: 10,
marginTop: 20,
},
infoIcon: {
flex: 0.125,
@ -15,6 +15,6 @@ export default EStyleSheet.create({
infoText: {
flex: 0.875,
fontSize: 12,
color: "#788187",
color: "$primaryGray",
},
});

View File

@ -0,0 +1,4 @@
import LeaderBoard from "./view/leaderBoardView";
export { LeaderBoard };
export default LeaderBoard;

View File

@ -0,0 +1,7 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
styleName: {
// TODO: If we need default style. We can put there.
},
});

View File

@ -0,0 +1,37 @@
import React, { Component } from "react";
import { View } from "react-native";
// Constants
// Components
// Styles
// eslint-disable-next-line
import styles from "./leaderBoardStyles";
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class LeaderBoardView extends Component {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycles
// Component Functions
render() {
// eslint-disable-next-line
const {} = this.props;
// eslint-disable-next-line
return <ElementName />;
}
}
export default LeaderBoardView;

View File

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

View File

@ -3,7 +3,7 @@ import { View, Text, Image } from "react-native";
// Constants
// Components
import { GreetingHeaderButton } from "../../buttons";
import { TextButton } from "../../buttons";
import { LineBreak } from "../../basicUIElements";
// Styles
// eslint-disable-next-line
@ -26,7 +26,7 @@ class LoginHeaderView extends Component {
// Component Functions
render() {
const { description, title } = this.props;
const { description, title, onPress, isKeyboardOpen } = this.props;
return (
<View styles={styles.container}>
@ -36,21 +36,23 @@ class LoginHeaderView extends Component {
source={require("../../../assets/esteem.png")}
/>
<View style={styles.headerButton}>
<GreetingHeaderButton text="Sign up" />
<TextButton onPress={onPress} text="Sign up" />
</View>
</View>
<View style={styles.body}>
<View style={styles.titleText}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.description}>{description}</Text>
{!isKeyboardOpen && (
<View style={styles.body}>
<View style={styles.titleText}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.description}>{description}</Text>
</View>
<View style={{ flex: 0.7 }}>
<Image
style={styles.mascot}
source={require("../../../assets/love_mascot.png")}
/>
</View>
</View>
<View style={{ flex: 0.7 }}>
<Image
style={styles.mascot}
source={require("../../../assets/love_mascot.png")}
/>
</View>
</View>
)}
<LineBreak />
</View>
);

View File

@ -0,0 +1,3 @@
import MainButton from "./view/mainButtonView";
export { MainButton };

View File

@ -0,0 +1,51 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
wrapper: {},
touchable: {
maxWidth: 200,
minWidth: 56,
height: 56,
borderRadius: 30,
backgroundColor: "$primaryBlue",
flexDirection: "row",
margin: 5,
shadowOffset: {
height: 5,
},
shadowColor: "#5f5f5fbf",
shadowOpacity: 0.3,
},
icon: {
alignSelf: "center",
fontSize: 25,
marginLeft: 20,
},
text: {
color: "white",
fontWeight: "400",
alignSelf: "center",
fontSize: 14,
paddingLeft: 10,
paddingRight: 20,
},
secondText: {
fontWeight: "bold",
},
activityIndicator: {
minWidth: 56,
height: 56,
},
body: {
flexDirection: "row",
},
image: {
marginLeft: 20,
alignSelf: "center",
width: 20,
height: 20,
},
disableTouchable: {
backgroundColor: "#c1c5c7",
},
});

View File

@ -0,0 +1,108 @@
import React, { Component, Fragment } from "react";
import {
ActivityIndicator,
Image,
Text,
TouchableOpacity,
View,
} from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
// Constants
// Components
// Styles
import styles from "./mainButtonStyles";
class MainButton extends Component {
/* Props
* ------------------------------------------------
* @prop { string } isLoading - TODO:
* @prop { string } text - TODO:
* @prop { boolean } secondText - TODO:
* @prop { boolean } iconColor - TODO:
* @prop { boolean } iconName - TODO:
* @prop { boolean } isDisable - TODO:
*
*
*/
constructor(props) {
super(props);
this.state = {
isDisable: !props.isLoading && props.isDisable,
};
}
// Component Life Cycles
componentWillReceiveProps(nextProps) {
const { isLoading, isDisable } = this.props;
if (
nextProps.isLoading !== isLoading ||
nextProps.isDisable !== isDisable
) {
this.setState({
isDisable: !nextProps.isLoading && nextProps.isDisable,
});
}
}
// Component Functions
_handleOnPress = () => {
const { onPress } = this.props;
onPress && onPress();
};
_getBody = () => {
const {
isLoading,
text,
secondText,
iconColor,
iconName,
source,
} = this.props;
if (isLoading) {
return (
<ActivityIndicator color="white" style={styles.activityIndicator} />
);
} else if (text) {
return (
<Fragment>
{source ? (
<Image source={source} style={styles.image} resizeMode="contain" />
) : (
<Ionicons color={iconColor} name={iconName} style={styles.icon} />
)}
<Text style={styles.text}>
{text}
{secondText && <Text style={styles.secondText}>{secondText}</Text>}
</Text>
</Fragment>
);
}
return <Ionicons color={iconColor} name={iconName} style={styles.icon} />;
};
render() {
const { wrapperStyle } = this.props;
const { isDisable } = this.state;
return (
<View style={wrapperStyle}>
<TouchableOpacity
disabled={isDisable}
onPress={() => this._handleOnPress()}
style={[styles.touchable, isDisable && styles.disableTouchable]}
>
<View style={styles.body}>{this._getBody()}</View>
</TouchableOpacity>
</View>
);
}
}
export default MainButton;

View File

@ -0,0 +1,4 @@
import Notification from "./view/notificationView";
export { Notification };
export default Notification;

View File

@ -0,0 +1,62 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
container: {
backgroundColor: "#fff",
},
notificationWrapper: {
flex: 1,
flexDirection: "row",
width: "$deviceWidth",
justifyContent: "space-between",
alignItems: "center",
height: 64,
},
avatar: {
width: 32,
height: 32,
borderRadius: 32 / 2,
marginLeft: 24,
},
image: {
width: 32,
height: 32,
borderRadius: 32 / 4,
marginRight: 24,
},
body: {
flexDirection: "column",
flexGrow: 1,
fontSize: 12,
marginRight: 28,
marginLeft: 16,
alignSelf: "center",
width: "$deviceWidth / 1.76",
},
titleWrapper: {
flexDirection: "row",
},
name: {
fontWeight: "bold",
},
title: {
color: "$primaryGray",
},
description: {
color: "#3c4449",
fontSize: 12,
fontWeight: "500",
},
scrollView: {
height: "$deviceHeight / 1.35",
},
isNewNotification: {
backgroundColor: "#eaf2fc",
borderTopWidth: 0.3,
borderBottomWidth: 0.3,
borderColor: "#e7e7e7",
},
hasNoAvatar: {
backgroundColor: "#d8d8d8",
},
});

View File

@ -0,0 +1,147 @@
import React, { Component } from "react";
import { View, ScrollView, Text, FlatList, Image } from "react-native";
import { ContainerHeader } from "../../containerHeader";
// Constants
// Components
import { FilterBar } from "../../../components/filterBar";
// Styles
import styles from "./notificationStyles";
class NotificationView extends Component {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
this.state = {
// NOTE: DOMI DATA! them gonna remove!
notification: [
{
name: "esteemapp",
title: "25% likes your post:",
avatar: "https://steemitimages.com/u/feruz/avatar/small",
description: "My own Top 5 eSteem Surfer Featuressasasaasasas",
image: "https://steemitimages.com/u/feruz/avatar/small",
date: "yesterday",
isNew: true,
},
{
name: "esteemapp",
title: "25% likes your post:",
avatar: "https://steemitimages.com/u/feruz/avatar/small",
description: "My own Top 5 eSteem Surfer Features",
image: "https://steemitimages.com/u/feruz/avatar/small",
date: "yesterday",
isNew: true,
},
{
name: "esteemapp",
title: "25% likes your post:",
description: "My own Top 5 eSteem Surfer Features",
image: "https://steemitimages.com/u/feruz/avatar/small",
date: "yesterday",
},
{
name: "esteemapp",
title: "25% likes your post:",
avatar: "https://steemitimages.com/u/feruz/avatar/small",
description: "My own Top 5 eSteem Surfer Featuresasassasasaasas",
date: "yesterday",
},
{
name: "esteemapp",
title: "25% likes your post:",
avatar: "https://steemitimages.com/u/feruz/avatar/small",
description: "My own Top 5 eSteem Surfer Features",
image: "https://steemitimages.com/u/feruz/avatar/small",
date: "yesterday",
},
],
};
}
// Component Life Cycles
// Component Functions
_handleOnDropdownSelect = index => {
console.log("selected index is:" + index);
};
_getRenderItem = item => {
return (
<View
key={Math.random()}
style={[
styles.notificationWrapper,
item.isNew && styles.isNewNotification,
]}
>
<Image
style={[styles.avatar, !item.avatar && styles.hasNoAvatar]}
source={{
uri: item.avatar,
}}
/>
<View style={styles.body}>
<View style={styles.titleWrapper}>
<Text style={styles.name}>{item.name} </Text>
<Text style={styles.title}>{item.title}</Text>
</View>
<Text numberOfLines={1} style={styles.description}>
{item.description}
</Text>
</View>
{item.image && (
<Image
style={styles.image}
source={{ uri: item.image }}
defaultSource={require("../../../assets/no_image.png")}
/>
)}
</View>
);
};
render() {
const { notification } = this.state;
return (
<View style={styles.container}>
<FilterBar
dropdownIconName="md-arrow-dropdown"
options={[
"ALL ACTIVITIES",
"VOTES",
"REPLIES",
"MENTIONS",
"FOLLOWS",
"REBLOGS",
]}
defaultText="ALL NOTIFICATION"
onDropdownSelect={this._handleOnDropdownSelect}
rightIconName="ios-checkmark"
/>
<ScrollView style={styles.scrollView}>
<ContainerHeader title="Recent" />
<FlatList
data={notification}
renderItem={({ item }) => this._getRenderItem(item)}
keyExtractor={item => item.email}
/>
{/* Will remove follow lines */}
<ContainerHeader title="Yesterday" />
<FlatList
data={notification}
renderItem={({ item }) => this._getRenderItem(item)}
keyExtractor={item => item.email}
/>
</ScrollView>
</View>
);
}
}
export default NotificationView;

View File

@ -1,653 +0,0 @@
/* eslint-disable no-unused-vars */
import React from "react";
import {
StyleSheet,
Image,
TouchableOpacity,
Dimensions,
FlatList,
ActivityIndicator,
} from "react-native";
import {
Card,
CardItem,
Left,
Right,
Thumbnail,
View,
Icon,
Body,
Text,
} from "native-base";
import { Navigation } from "react-native-navigation";
import Modal from "react-native-modal";
import { Popover, PopoverController } from "react-native-modal-popover";
import Slider from "react-native-slider";
// STEEM
import { upvote, upvoteAmount } from "../../providers/steem/dsteem";
import { decryptKey } from "../../utils/crypto";
import { getUserData } from "../../realm/realm";
/* eslint-enable no-unused-vars */
class PostCard extends React.PureComponent {
constructor(props) {
super(props);
this.upvoteContent = this.upvoteContent.bind(this);
this.calculateEstimatedAmount = this.calculateEstimatedAmount.bind(
this
);
this.state = {
value: 0.0,
isVoting: false,
isVoted: this.props.content.isVoted,
amount: "0.00",
isModalVisible: false,
};
}
componentDidMount() {
if (this.props.isLoggedIn == true) {
this.calculateEstimatedAmount();
}
}
calculateEstimatedAmount = async () => {
// Calculate total vesting shares
let total_vests =
parseFloat(this.props.user.vesting_shares) +
parseFloat(this.props.user.received_vesting_shares) -
parseFloat(this.props.user.delegated_vesting_shares);
let final_vest = total_vests * 1e6;
let power =
(this.props.user.voting_power * (this.state.value * 10000)) /
10000 /
50;
let rshares = (power * final_vest) / 10000;
let estimated = await upvoteAmount(rshares);
this.setState({
amount: estimated.toFixed(3),
});
};
upvoteContent = async () => {
let postingKey;
let userData;
if (this.props.isLoggedIn) {
await this.setState({
isVoting: true,
});
await getUserData().then(result => {
userData = Array.from(result);
postingKey = decryptKey(userData[0].postingKey, "pinCode");
});
upvote(
{
voter: this.props.user.name,
author: this.props.content.author,
permlink: this.props.content.permlink,
weight: (this.state.value * 100).toFixed(0) * 100,
},
postingKey
)
.then(res => {
console.log(res);
this.setState({
isVoted: true,
isVoting: false,
});
})
.catch(err => {
console.log(err);
this.setState({
isVoted: false,
isVoting: false,
});
});
}
};
toggleModal = () => {
this.setState({
isModalVisible: !this.state.isModalVisible,
});
};
render() {
return (
<Card style={styles.post}>
<CardItem style={styles.header}>
<Left>
<TouchableOpacity
onPress={() =>
Navigation.push("tab1Stack", {
component: {
name: "navigation.eSteem.Author",
passProps: {
author: this.props.content.author,
isLoggedIn: this.props.isLoggedIn,
user: this.props.user,
},
options: {
topBar: {},
},
},
})
}
>
<Thumbnail
style={styles.avatar}
source={{ uri: this.props.content.avatar }}
/>
</TouchableOpacity>
<Body style={styles.body}>
<View style={styles.author}>
<Text style={styles.authorName}>
{this.props.content.author}
</Text>
</View>
<View style={styles.badge}>
<Text style={styles.text}>
{this.props.content.author_reputation}
</Text>
</View>
<View style={styles.category}>
<Text style={styles.categoryText}>
{this.props.content.category}
</Text>
</View>
<Text style={styles.timeAgo} note>
{" "}
{this.props.content.created}{" "}
</Text>
</Body>
</Left>
<Right>
<Icon name="md-more" />
</Right>
</CardItem>
<Image
source={{ uri: this.props.content.image }}
defaultSource={require("../../assets/no_image.png")}
style={styles.image}
/>
<TouchableOpacity
onPress={() =>
Navigation.push("tab1Stack", {
component: {
name: "navigation.eSteem.Post",
passProps: {
content: this.props.content,
isLoggedIn: this.props.isLoggedIn,
user: this.props.user,
},
options: {
topBar: {},
},
},
})
}
>
<CardItem>
<Body>
<Text style={styles.title}>
{this.props.content.title}
</Text>
<Text style={styles.summary}>
{this.props.content.summary}
</Text>
</Body>
</CardItem>
</TouchableOpacity>
<CardItem>
<Left>
<PopoverController>
{({
openPopover,
closePopover,
popoverVisible,
setPopoverAnchor,
popoverAnchorRect,
}) => (
<React.Fragment>
<TouchableOpacity
start
ref={setPopoverAnchor}
onPress={openPopover}
style={styles.upvoteButton}
>
{this.state.isVoting ? (
<ActivityIndicator />
) : (
<View>
{this.state.isVoted ? (
<Icon
style={{
color: "#007ee5",
}}
style={
styles.upvoteIcon
}
active
name="ios-arrow-dropup-circle"
/>
) : (
<Icon
style={{
color: "#007ee5",
}}
style={
styles.upvoteIcon
}
active
name="ios-arrow-dropup-outline"
/>
)}
</View>
)}
</TouchableOpacity>
<Popover
contentStyle={styles.popover}
arrowStyle={styles.arrow}
backgroundStyle={styles.background}
visible={popoverVisible}
onClose={closePopover}
fromRect={popoverAnchorRect}
placement={"top"}
supportedOrientations={[
"portrait",
"landscape",
]}
>
<Text>${this.state.amount}</Text>
<View
style={{
flex: 1,
flexDirection: "row",
}}
>
<TouchableOpacity
onPress={() => {
closePopover();
this.upvoteContent();
}}
style={{
flex: 0.1,
alignSelf: "center",
}}
>
<Icon
style={{ color: "#007ee5" }}
active
name="ios-arrow-dropup-outline"
/>
</TouchableOpacity>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={styles.track}
thumbStyle={styles.thumb}
thumbTintColor="#007ee5"
value={this.state.value}
onValueChange={value => {
this.setState(
{ value },
() => {
this.calculateEstimatedAmount();
}
);
}}
/>
<Text
style={{
flex: 0.15,
alignSelf: "center",
marginLeft: 10,
}}
>
{(
this.state.value * 100
).toFixed(0)}
%
</Text>
</View>
</Popover>
</React.Fragment>
)}
</PopoverController>
<TouchableOpacity
onPress={this.toggleModal}
style={styles.payoutButton}
>
<Text style={styles.payout}>
${this.props.content.pending_payout_value}
</Text>
<Icon
name="md-arrow-dropdown"
style={styles.payoutIcon}
/>
<Modal isVisible={this.state.isModalVisible}>
<View
style={{
flex: 0.8,
backgroundColor: "white",
borderRadius: 10,
}}
>
<TouchableOpacity
onPress={this.toggleModal}
>
<Text>Tap to close!</Text>
</TouchableOpacity>
<FlatList
data={this.props.content.active_votes}
keyExtractor={item =>
item.voter.toString()
}
renderItem={({ item }) => (
<View
style={{
flexDirection: "row",
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 10,
}}
>
<Thumbnail
style={{
width: 34,
height: 34,
borderRadius: 17,
flex: 0.1,
}}
source={{
uri: item.avatar,
}}
/>
<Text style={{ flex: 0.5 }}>
{" "}
{item.voter} (
{item.reputation})
</Text>
<Text style={{ flex: 0.2 }}>
{item.value}$
</Text>
<Text style={{ flex: 0.2 }}>
{item.percent}%
</Text>
</View>
)}
/>
</View>
</Modal>
</TouchableOpacity>
</Left>
<Right>
<TouchableOpacity start style={styles.commentButton}>
<Icon
style={styles.commentIcon}
active
name="ios-chatbubbles-outline"
/>
<Text style={styles.comment}>
{this.props.content.children}
</Text>
</TouchableOpacity>
</Right>
</CardItem>
{this.props.content.top_likers ? (
<CardItem style={styles.topLikers}>
<Thumbnail
source={{
uri: `https://steemitimages.com/u/${
this.props.content.top_likers[0]
}/avatar/small`,
}}
style={styles.likers_1}
/>
<Thumbnail
source={{
uri: `https://steemitimages.com/u/${
this.props.content.top_likers[1]
}/avatar/small`,
}}
style={styles.likers_2}
/>
<Thumbnail
source={{
uri: `https://steemitimages.com/u/${
this.props.content.top_likers[2]
}/avatar/small`,
}}
style={styles.likers_3}
/>
<Text style={styles.footer}>
@{this.props.content.top_likers[0]}, @
{this.props.content.top_likers[1]}, @
{this.props.content.top_likers[2]}
<Text style={styles.footer}> & </Text>
{this.props.content.vote_count -
this.props.content.top_likers.length}{" "}
others like this
</Text>
</CardItem>
) : (
<CardItem>
<Text style={styles.footer}>
{this.props.content.vote_count} likes
</Text>
</CardItem>
)}
</Card>
);
}
}
const styles = StyleSheet.create({
post: {
shadowColor: "white",
padding: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
marginBottom: 0,
borderWidth: 1,
borderColor: "#e5e5e5",
borderRadius: 5,
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
borderColor: "lightgray",
borderWidth: 1,
},
author: {
backgroundColor: "white",
alignSelf: "flex-start",
paddingVertical: 5,
},
timeAgo: {
alignSelf: "center",
fontSize: 9,
fontWeight: "100",
marginHorizontal: 3,
},
authorName: {
color: "#222",
fontWeight: "600",
fontSize: 10,
},
upvoteButton: {
margin: 0,
flexDirection: "row",
paddingVertical: 0,
},
upvoteIcon: {
alignSelf: "flex-start",
fontSize: 20,
color: "#007ee5",
margin: 0,
width: 18,
},
payout: {
alignSelf: "center",
fontSize: 10,
color: "#626262",
marginLeft: 3,
},
payoutIcon: {
fontSize: 15,
marginHorizontal: 3,
color: "#a0a0a0",
alignSelf: "center",
},
payoutButton: {
flexDirection: "row",
alignSelf: "flex-start",
paddingVertical: 2,
},
commentButton: {
padding: 0,
margin: 0,
flexDirection: "row",
},
comment: {
alignSelf: "center",
fontSize: 10,
color: "#626262",
marginLeft: 3,
},
commentIcon: {
alignSelf: "flex-start",
fontSize: 20,
color: "#007ee5",
margin: 0,
width: 20,
},
title: {
fontSize: 12,
fontWeight: "500",
marginVertical: 5,
},
summary: {
fontSize: 10,
fontWeight: "200",
overflow: "hidden",
},
header: {
shadowColor: "white",
height: 50,
borderRadius: 5,
},
body: {
justifyContent: "flex-start",
flexDirection: "row",
},
image: {
margin: 0,
width: "100%",
height: 160,
},
badge: {
alignSelf: "center",
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 10,
width: 15,
height: 15,
padding: 2,
backgroundColor: "lightgray",
marginHorizontal: 5,
},
category: {
alignSelf: "center",
borderRadius: 10,
height: 15,
backgroundColor: "#007EE5",
paddingHorizontal: 5,
paddingVertical: 1.5,
},
categoryText: {
fontSize: 9,
color: "white",
fontWeight: "600",
},
text: {
fontSize: 7,
alignSelf: "center",
textAlignVertical: "center",
color: "white",
fontWeight: "bold",
},
topLikers: {
shadowColor: "white",
backgroundColor: "#f8f8f8",
borderWidth: 0,
padding: 0,
borderRadius: 5,
},
likers_1: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: "lightgray",
marginVertical: -5,
},
likers_2: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: "lightgray",
marginVertical: -5,
marginLeft: -3,
},
likers_3: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: "lightgray",
marginVertical: -5,
marginLeft: -3,
},
footer: {
shadowColor: "white",
paddingLeft: 5,
borderRadius: 5,
fontSize: 7,
fontWeight: "100",
color: "#777777",
},
popover: {
width: Dimensions.get("window").width - 20,
borderRadius: 5,
padding: 10,
},
track: {
height: 2,
borderRadius: 1,
},
thumb: {
width: 30,
height: 30,
borderRadius: 30 / 2,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
},
});
export default PostCard;

View File

@ -0,0 +1,35 @@
import React, { Component } from "react";
// Services and Actions
// Middleware
// Constants
// Utilities
// Component
import { PostCardView } from "../";
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class PostCardContainer extends Component {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycle Functions
// Component Functions
render() {
return <PostCardView {...this.props} />;
}
}
export default PostCardContainer;

View File

@ -0,0 +1,5 @@
import PostCardView from "./view/postCardView";
import PostCard from "./container/postCardContainer";
export { PostCardView, PostCard };
export default PostCard;

View File

@ -0,0 +1,200 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({
post: {
shadowColor: "white",
padding: 0,
marginRight: 0,
marginLeft: 0,
marginTop: 10,
marginBottom: 0,
borderWidth: 1,
borderColor: "#e5e5e5",
borderRadius: 5,
},
avatar: {
width: 30,
height: 30,
borderRadius: 15,
borderColor: "lightgray",
borderWidth: 1,
},
author: {
backgroundColor: "white",
alignSelf: "flex-start",
paddingVertical: 5,
},
timeAgo: {
alignSelf: "center",
fontSize: 9,
fontWeight: "100",
marginHorizontal: 3,
},
authorName: {
color: "#222",
fontWeight: "600",
fontSize: 10,
},
upvoteButton: {
margin: 0,
flexDirection: "row",
paddingVertical: 0,
},
upvoteIcon: {
alignSelf: "flex-start",
fontSize: 20,
color: "#007ee5",
margin: 0,
width: 18,
},
payout: {
alignSelf: "center",
fontSize: 10,
color: "#626262",
marginLeft: 3,
},
payoutIcon: {
fontSize: 15,
marginHorizontal: 3,
color: "#a0a0a0",
alignSelf: "center",
},
payoutButton: {
flexDirection: "row",
alignSelf: "flex-start",
paddingVertical: 2,
},
commentButton: {
padding: 0,
margin: 0,
flexDirection: "row",
},
comment: {
alignSelf: "center",
fontSize: 10,
color: "#626262",
marginLeft: 3,
},
commentIcon: {
alignSelf: "flex-start",
fontSize: 20,
color: "#007ee5",
margin: 0,
width: 20,
},
title: {
fontSize: 12,
fontWeight: "500",
marginVertical: 5,
},
summary: {
fontSize: 10,
fontWeight: "200",
overflow: "hidden",
},
header: {
shadowColor: "white",
height: 50,
borderRadius: 5,
},
body: {
justifyContent: "flex-start",
flexDirection: "row",
},
image: {
margin: 0,
width: "100%",
height: 160,
},
badge: {
alignSelf: "center",
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 10,
width: 15,
height: 15,
padding: 2,
backgroundColor: "lightgray",
marginHorizontal: 5,
},
category: {
alignSelf: "center",
borderRadius: 10,
height: 15,
backgroundColor: "#007EE5",
paddingHorizontal: 5,
paddingVertical: 1.5,
},
categoryText: {
fontSize: 9,
color: "white",
fontWeight: "600",
},
text: {
fontSize: 7,
alignSelf: "center",
textAlignVertical: "center",
color: "white",
fontWeight: "bold",
},
topLikers: {
shadowColor: "white",
backgroundColor: "#f8f8f8",
borderWidth: 0,
padding: 0,
borderRadius: 5,
},
likers_1: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: "lightgray",
marginVertical: -5,
},
likers_2: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: "lightgray",
marginVertical: -5,
marginLeft: -3,
},
likers_3: {
width: 14,
height: 14,
borderRadius: 7,
borderWidth: 0.5,
borderColor: "lightgray",
marginVertical: -5,
marginLeft: -3,
},
footer: {
shadowColor: "white",
paddingLeft: 5,
borderRadius: 5,
fontSize: 7,
fontWeight: "100",
color: "#777777",
},
popover: {
width: "$deviceWidth - 20",
borderRadius: 5,
padding: 10,
},
track: {
height: 2,
borderRadius: 1,
},
thumb: {
width: 30,
height: 30,
borderRadius: 30 / 2,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 2,
shadowOpacity: 0.35,
},
});

View File

@ -0,0 +1,423 @@
import React, { Component } from "react";
import {
Image,
TouchableOpacity,
FlatList,
ActivityIndicator,
} from "react-native";
import {
Card,
CardItem,
Left,
Right,
Thumbnail,
View,
Icon,
Body,
Text,
} from "native-base";
import { Navigation } from "react-native-navigation";
import Modal from "react-native-modal";
import { Popover, PopoverController } from "react-native-modal-popover";
import Slider from "react-native-slider";
// STEEM
import { upvote, upvoteAmount } from "../../../providers/steem/dsteem";
import { decryptKey } from "../../../utils/crypto";
import { getUserData } from "../../../realm/realm";
// Styles
import styles from "./postCardStyles";
class PostCard extends Component {
/* Props
* ------------------------------------------------
* @prop { string } description - Description texts.
* @prop { string } iconName - For icon render name.
*
*/
constructor(props) {
super(props);
this.upvoteContent = this.upvoteContent.bind(this);
this.calculateEstimatedAmount = this.calculateEstimatedAmount.bind(this);
this.state = {
value: 0.0,
isVoting: false,
isVoted: props.content && props.content.isVoted,
amount: "0.00",
isModalVisible: false,
};
}
// Component Lifecycle Functions
componentDidMount() {
const { isLoggedIn } = this.props;
isLoggedIn && this.calculateEstimatedAmount();
}
// Component Functions
calculateEstimatedAmount = async () => {
const { user } = this.props;
const { value } = this.state;
// Calculate total vesting shares
const total_vests =
parseFloat(user.vesting_shares) +
parseFloat(user.received_vesting_shares) -
parseFloat(user.delegated_vesting_shares);
const final_vest = total_vests * 1e6;
const power = (user.voting_power * (value * 10000)) / 10000 / 50;
const rshares = (power * final_vest) / 10000;
const estimated = await upvoteAmount(rshares);
this.setState({
amount: estimated.toFixed(3),
});
};
upvoteContent = async () => {
const { isLoggedIn, user, content } = this.prop;
const { value } = this.state;
let postingKey;
let userData;
if (isLoggedIn) {
await this.setState({
isVoting: true,
});
await getUserData().then(result => {
userData = Array.from(result);
postingKey = decryptKey(userData[0].postingKey, "pinCode");
});
upvote(
{
voter: user && user.name,
author: content && content.author,
permlink: content && content.permlink,
weight: (value * 100).toFixed(0) * 100,
},
postingKey
)
.then(res => {
console.log(res);
this.setState({
isVoted: true,
isVoting: false,
});
})
.catch(err => {
console.log(err);
this.setState({
isVoted: false,
isVoting: false,
});
});
}
};
toggleModal = () => {
const { isModalVisible } = this.state;
this.setState({
isModalVisible: !isModalVisible,
});
};
render() {
const { content, isLoggedIn, user } = this.props;
const { isVoted, isVoting, isModalVisible, value } = this.state;
// TODO: Should seperate bunch of component REFACTOR ME!
return (
<Card style={styles.post}>
<CardItem style={styles.header}>
<Left>
<TouchableOpacity
onPress={() =>
Navigation.push("tab1Stack", {
component: {
name: "navigation.eSteem.Author",
passProps: {
author: content && content.author,
isLoggedIn: isLoggedIn,
user: user,
},
options: {
topBar: {},
},
},
})
}
>
<Thumbnail
style={styles.avatar}
source={{ uri: content && content.avatar }}
/>
</TouchableOpacity>
<Body style={styles.body}>
<View style={styles.author}>
<Text style={styles.authorName}>{content.author}</Text>
</View>
<View style={styles.badge}>
<Text style={styles.text}>{content.author_reputation}</Text>
</View>
<View style={styles.category}>
<Text style={styles.categoryText}>{content.category}</Text>
</View>
<Text style={styles.timeAgo} note>
{" "}
{content.created}{" "}
</Text>
</Body>
</Left>
<Right>
<Icon name="md-more" />
</Right>
</CardItem>
<Image
source={{ uri: content && content.image }}
defaultSource={require("../../../assets/no_image.png")}
style={styles.image}
/>
<TouchableOpacity
onPress={() =>
Navigation.push("tab1Stack", {
component: {
name: "navigation.eSteem.Post",
passProps: {
content: content,
isLoggedIn: isLoggedIn,
user: user,
},
options: {
topBar: {},
},
},
})
}
>
<CardItem>
<Body>
<Text style={styles.title}>{content.title}</Text>
<Text style={styles.summary}>{content.summary}</Text>
</Body>
</CardItem>
</TouchableOpacity>
<CardItem>
<Left>
<PopoverController>
{({
openPopover,
closePopover,
popoverVisible,
setPopoverAnchor,
popoverAnchorRect,
}) => (
<React.Fragment>
<TouchableOpacity
start
ref={setPopoverAnchor}
onPress={openPopover}
style={styles.upvoteButton}
>
{isVoting ? (
<ActivityIndicator />
) : (
<View>
{isVoted ? (
<Icon
style={{
color: "#007ee5",
}}
style={styles.upvoteIcon}
active
name="ios-arrow-dropup-circle"
/>
) : (
<Icon
style={{
color: "#007ee5",
}}
style={styles.upvoteIcon}
active
name="ios-arrow-dropup-outline"
/>
)}
</View>
)}
</TouchableOpacity>
<Popover
contentStyle={styles.popover}
arrowStyle={styles.arrow}
backgroundStyle={styles.background}
visible={popoverVisible}
onClose={closePopover}
fromRect={popoverAnchorRect}
placement={"top"}
supportedOrientations={["portrait", "landscape"]}
>
<Text>${this.state.amount}</Text>
<View
style={{
flex: 1,
flexDirection: "row",
}}
>
<TouchableOpacity
onPress={() => {
closePopover();
this.upvoteContent();
}}
style={{
flex: 0.1,
alignSelf: "center",
}}
>
<Icon
style={{ color: "#007ee5" }}
active
name="ios-arrow-dropup-outline"
/>
</TouchableOpacity>
<Slider
style={{ flex: 0.75 }}
minimumTrackTintColor="#13a9d6"
trackStyle={styles.track}
thumbStyle={styles.thumb}
thumbTintColor="#007ee5"
value={value}
onValueChange={value => {
this.setState({ value }, () => {
this.calculateEstimatedAmount();
});
}}
/>
<Text
style={{
flex: 0.15,
alignSelf: "center",
marginLeft: 10,
}}
>
{(value * 100).toFixed(0)}%
</Text>
</View>
</Popover>
</React.Fragment>
)}
</PopoverController>
<TouchableOpacity
onPress={this.toggleModal}
style={styles.payoutButton}
>
<Text style={styles.payout}>${content.pending_payout_value}</Text>
<Icon name="md-arrow-dropdown" style={styles.payoutIcon} />
<Modal isVisible={isModalVisible}>
<View
style={{
flex: 0.8,
backgroundColor: "white",
borderRadius: 10,
}}
>
<TouchableOpacity onPress={this.toggleModal}>
<Text>Tap to close!</Text>
</TouchableOpacity>
<FlatList
data={this.props.content.active_votes}
keyExtractor={item => item.voter.toString()}
renderItem={({ item }) => (
<View
style={{
flexDirection: "row",
borderColor: "lightgray",
borderWidth: 1,
borderRadius: 10,
}}
>
<Thumbnail
style={{
width: 34,
height: 34,
borderRadius: 17,
flex: 0.1,
}}
source={{
uri: item.avatar,
}}
/>
<Text style={{ flex: 0.5 }}>
{" "}
{item.voter} ({item.reputation})
</Text>
<Text style={{ flex: 0.2 }}>{item.value}$</Text>
<Text style={{ flex: 0.2 }}>{item.percent}%</Text>
</View>
)}
/>
</View>
</Modal>
</TouchableOpacity>
</Left>
<Right>
<TouchableOpacity start style={styles.commentButton}>
<Icon
style={styles.commentIcon}
active
name="ios-chatbubbles-outline"
/>
<Text style={styles.comment}>{content.children}</Text>
</TouchableOpacity>
</Right>
</CardItem>
{content.top_likers ? (
<CardItem style={styles.topLikers}>
<Thumbnail
source={{
uri: `https://steemitimages.com/u/${
content.top_likers[0]
}/avatar/small`,
}}
style={styles.likers_1}
/>
<Thumbnail
source={{
uri: `https://steemitimages.com/u/${
content.top_likers[1]
}/avatar/small`,
}}
style={styles.likers_2}
/>
<Thumbnail
source={{
uri: `https://steemitimages.com/u/${
content.top_likers[2]
}/avatar/small`,
}}
style={styles.likers_3}
/>
<Text style={styles.footer}>
@{content.top_likers[0]}, @{content.top_likers[1]}, @
{content.top_likers[2]}
<Text style={styles.footer}> & </Text>
{content.vote_count - content.top_likers.length} others like this
</Text>
</CardItem>
) : (
<CardItem>
<Text style={styles.footer}>{content.vote_count} likes</Text>
</CardItem>
)}
</Card>
);
}
}
export default PostCard;

View File

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

View File

@ -1,151 +1,143 @@
import React, { Component } from "react";
import {
Text,
View,
Animated,
TouchableNativeFeedback,
TouchableOpacity,
Platform,
Dimensions,
Text,
View,
Animated,
TouchableNativeFeedback,
TouchableOpacity,
Platform,
Dimensions,
} from "react-native";
// Styles
import styles from "./tabBarStyles";
export default class TabBar extends Component {
/* Props
/* Props
* ------------------------------------------------ TODO: Fill fallowlines
* @prop { type } name - Description.
* @prop { type } name - Description.
*
*/
constructor(props) {
super(props);
constructor(props) {
super(props);
this.state = {};
}
this.state = {};
}
_renderTab = (name, page, isTabActive, onPressHandler) => {
const { activeColor, inactiveColor } = this.props;
const textColor = isTabActive ? activeColor : inactiveColor;
const fontWeight = isTabActive ? "bold" : "normal";
const Button = Platform.OS == "ios" ? ButtonIos : ButtonAndroid;
// TODO: make generic component!!
_renderTab = (name, page, isTabActive, onPressHandler) => {
const { activeColor, inactiveColor } = this.props;
const textColor = isTabActive ? activeColor : inactiveColor;
const fontWeight = isTabActive ? "bold" : "normal";
const Button = Platform.OS == "ios" ? ButtonIos : ButtonAndroid;
// TODO: make generic component!!
return (
<Button
style={styles.tabButton}
key={name}
accessible={true}
accessibilityLabel={name}
accessibilityTraits="button"
onPress={() => onPressHandler(page)}
>
<View style={styles.tab}>
<Text style={[{ color: textColor, fontWeight }]}>
{name}
</Text>
</View>
</Button>
);
return (
<Button
style={styles.tabButton}
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 {
activeColor,
tabs,
tabUnderlineDefaultWidth,
tabUnderlineScaleX,
scrollValue,
underlineStyle,
} = this.props;
const containerWidth = Dimensions.get("window").width;
const numberOfTabs = tabs.length;
const underlineWidth =
tabUnderlineDefaultWidth || containerWidth / (numberOfTabs * 2);
const scale = tabUnderlineScaleX || 2;
const deLen = (containerWidth / numberOfTabs - underlineWidth) / 2;
const tabUnderlineStyle = {
position: "absolute",
width: underlineWidth,
height: 2,
borderRadius: 2,
backgroundColor: activeColor,
bottom: 0,
left: deLen,
};
_renderUnderline = () => {
const {
activeColor,
tabs,
tabUnderlineDefaultWidth,
tabUnderlineScaleX,
scrollValue,
underlineStyle,
} = this.props;
const translateX = scrollValue.interpolate({
inputRange: [0, 1],
outputRange: [0, containerWidth / numberOfTabs],
});
const containerWidth = Dimensions.get("window").width;
const numberOfTabs = tabs.length;
const underlineWidth =
tabUnderlineDefaultWidth || containerWidth / (numberOfTabs * 2);
const scale = tabUnderlineScaleX || 2;
const deLen = (containerWidth / numberOfTabs - underlineWidth) / 2;
const tabUnderlineStyle = {
position: "absolute",
width: underlineWidth,
height: 2,
borderRadius: 2,
backgroundColor: activeColor,
bottom: 0,
left: deLen,
};
const scaleValue = defaultScale => {
const number = 4;
const arr = new Array(number * 2);
const translateX = scrollValue.interpolate({
inputRange: [0, 1],
outputRange: [0, containerWidth / numberOfTabs],
});
const scaleValue = defaultScale => {
const number = 4;
const arr = new Array(number * 2);
return arr.fill(0).reduce(
function(pre, cur, idx) {
idx == 0
? pre.inputRange.push(cur)
: pre.inputRange.push(pre.inputRange[idx - 1] + 0.5);
idx % 2
? pre.outputRange.push(defaultScale)
: pre.outputRange.push(1);
return pre;
},
{ inputRange: [], outputRange: [] }
);
};
const scaleX = scrollValue.interpolate(scaleValue(scale));
return (
<Animated.View
style={[
tabUnderlineStyle,
{
transform: [{ translateX }, { scaleX }],
},
underlineStyle,
]}
/>
);
return arr.fill(0).reduce(
function(pre, cur, idx) {
idx == 0
? pre.inputRange.push(cur)
: pre.inputRange.push(pre.inputRange[idx - 1] + 0.5);
idx % 2
? pre.outputRange.push(defaultScale)
: pre.outputRange.push(1);
return pre;
},
{ inputRange: [], outputRange: [] }
);
};
render() {
const { activeTab, backgroundColor, goToPage, style } = this.props;
const scaleX = scrollValue.interpolate(scaleValue(scale));
return (
<View
style={[
styles.tabs,
{ backgroundColor: backgroundColor },
style,
]}
>
{this.props.tabs.map((name, page) => {
const isTabActive = activeTab === page;
return this._renderTab(name, page, isTabActive, goToPage);
})}
{this._renderUnderline()}
</View>
);
}
return (
<Animated.View
style={[
tabUnderlineStyle,
{
transform: [{ translateX }, { scaleX }],
},
underlineStyle,
]}
/>
);
};
render() {
const { activeTab, backgroundColor, goToPage, style } = this.props;
return (
<View style={[styles.tabs, { backgroundColor: backgroundColor }, style]}>
{this.props.tabs.map((name, page) => {
const isTabActive = activeTab === page;
return this._renderTab(name, page, isTabActive, goToPage);
})}
{this._renderUnderline()}
</View>
);
}
}
const ButtonAndroid = props => (
<TouchableNativeFeedback
delayPressIn={0}
background={TouchableNativeFeedback.SelectableBackground()}
{...props}
>
{props.children}
</TouchableNativeFeedback>
<TouchableNativeFeedback
delayPressIn={0}
background={TouchableNativeFeedback.SelectableBackground()}
{...props}
>
{props.children}
</TouchableNativeFeedback>
);
const ButtonIos = props => (
<TouchableOpacity {...props}>{props.children}</TouchableOpacity>
<TouchableOpacity {...props}>{props.children}</TouchableOpacity>
);

View File

@ -40,8 +40,8 @@ export const goToAuthScreens = () =>
right: 0,
},
icon: require("./assets/feed.png"),
iconColor: "gray",
selectedIconColor: "#222",
iconColor: "#c1c5c7",
selectedIconColor: "#357ce6",
},
},
},
@ -67,8 +67,13 @@ export const goToAuthScreens = () =>
right: 0,
},
icon: require("./assets/notification.png"),
iconColor: "gray",
selectedIconColor: "#222",
iconColor: "#c1c5c7",
selectedIconColor: "#357ce6",
},
topBar: {
visible: false,
noBorder: true,
elevation: 0,
},
},
},
@ -94,8 +99,8 @@ export const goToAuthScreens = () =>
right: 0,
},
icon: require("./assets/add.png"),
iconColor: "gray",
selectedIconColor: "#222",
iconColor: "#c1c5c7",
selectedIconColor: "#357ce6",
},
},
},
@ -121,8 +126,8 @@ export const goToAuthScreens = () =>
right: 0,
},
icon: require("./assets/wallet.png"),
iconColor: "gray",
selectedIconColor: "#222",
iconColor: "#c1c5c7",
selectedIconColor: "#357ce6",
},
},
},
@ -148,8 +153,8 @@ export const goToAuthScreens = () =>
right: 0,
},
icon: require("./assets/wallet.png"),
iconColor: "gray",
selectedIconColor: "#222",
iconColor: "#c1c5c7",
selectedIconColor: "#357ce6",
},
},
},
@ -161,7 +166,7 @@ export const goToAuthScreens = () =>
textColor: "#AED581",
iconColor: "#AED581",
selectedTextColor: "gray",
selectedIconColor: "gray",
selectediconColor: "#c1c5c7",
fontFamily: "HelveticaNeue-Italic",
fontSize: 13,
},
@ -188,8 +193,8 @@ export const goToAuthScreens = () =>
animate: false, // Controls whether BottomTabs visibility changes should be animated
},
bottomTab: {
iconColor: "gray",
selectedIconColor: "#222",
iconColor: "#c1c5c7",
selectedIconColor: "#357ce6",
textColor: "#1B4C77",
selectedTextColor: "#0f0",
fontFamily: "HelveticaNeue-Italic",

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,5 @@
import React from "react";
import {
StyleSheet,
FlatList,
View,
StatusBar,
Dimensions,
ActivityIndicator,
AppState,
} from "react-native";
import { FlatList, View, ActivityIndicator, AppState } from "react-native";
import {
Container,
Header,
@ -28,7 +20,9 @@ import { getPosts } from "../../providers/steem/dsteem";
import Placeholder from "rn-placeholder";
// COMPONENTS
import PostCard from "../../components/post-card/postCard";
import { PostCard } from "../../components/postCard";
import { FilterBar } from "../../components/filterBar";
/* eslint-enable no-unused-vars */
class FeedPage extends React.Component {
@ -138,6 +132,20 @@ class FeedPage extends React.Component {
render() {
return (
<View style={{ flex: 1 }}>
{this.state.isReady && (
<FilterBar
dropdownIconName="md-arrow-dropdown"
options={[
"ALL NOTIFICATION",
"LATEST NOTF",
"ESTEEMAPP",
"UGUR ERDAL",
"ONLY YESTERDAY",
]}
defaultText="NEW POST"
rightIconName="md-apps"
/>
)}
{this.state.isReady ? (
<FlatList
data={this.state.posts}

View File

@ -90,7 +90,7 @@ export default class Home extends React.PureComponent {
isLoggedIn = res;
});
if (isLoggedIn == true) {
if (isLoggedIn) {
await getUserData().then(res => {
user = Array.from(res);
});

View File

@ -1,14 +1,6 @@
/* eslint-disable no-unused-vars */
import React from "react";
import {
StyleSheet,
FlatList,
View,
Text,
TouchableOpacity,
ActivityIndicator,
} from "react-native";
import { Navigation } from "react-native-navigation";
import { FlatList, View, ActivityIndicator } from "react-native";
import styles from "../../styles/hot.styles";
@ -19,154 +11,169 @@ import { getPosts } from "../../providers/steem/dsteem";
import Placeholder from "rn-placeholder";
// COMPONENTS
import PostCard from "../../components/post-card/postCard";
import { PostCard } from "../../components/postCard";
import { FilterBar } from "../../components/filterBar";
// SCREENS
/* eslint-enable no-unused-vars */
class HotPage extends React.Component {
constructor(props) {
super(props);
constructor(props) {
super(props);
this.getHotPosts = this.getHotPosts.bind(this);
this.getMoreHot = this.getMoreHot.bind(this);
this.refreshHotPosts = this.refreshHotPosts.bind(this);
this.state = {
isReady: false,
posts: [],
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
isLoggedIn: this.props.isLoggedIn,
};
}
componentDidMount() {
console.log(this.props);
this.getHotPosts();
}
getHotPosts = () => {
getPosts("hot", { tag: "", limit: 10 }, this.props.user.name)
.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);
});
this.getHotPosts = this.getHotPosts.bind(this);
this.getMoreHot = this.getMoreHot.bind(this);
this.refreshHotPosts = this.refreshHotPosts.bind(this);
this.state = {
isReady: false,
posts: [],
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
isLoggedIn: this.props.isLoggedIn,
};
}
getMoreHot = () => {
this.setState({ loading: true });
getPosts(
"hot",
{
tag: "",
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.props.user.name
).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,
});
componentDidMount() {
console.log(this.props);
this.getHotPosts();
}
getHotPosts = () => {
getPosts("hot", { tag: "", limit: 10 }, this.props.user.name)
.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);
});
};
refreshHotPosts = () => {
this.setState(
{
refreshing: true,
},
() => {
this.getHotPosts();
}
);
};
getMoreHot = () => {
this.setState({ loading: true });
getPosts(
"hot",
{
tag: "",
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.props.user.name
).then(result => {
let posts = result;
posts.shift();
this.setState({
posts: [...this.state.posts, ...posts],
start_author: result[result.length - 1].author,
start_permlink: result[result.length - 1].permlink,
});
});
};
renderFooter = () => {
if (!this.state.loading) return null;
refreshHotPosts = () => {
this.setState(
{
refreshing: true,
},
() => {
this.getHotPosts();
}
);
};
return (
<View style={styles.flatlistFooter}>
<ActivityIndicator animating size="large" />
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View style={styles.flatlistFooter}>
<ActivityIndicator animating size="large" />
</View>
);
};
render() {
return (
<View style={{ flex: 1 }}>
{this.state.isReady && (
<FilterBar
dropdownIconName="md-arrow-dropdown"
options={[
"ALL NOTIFICATION",
"LATEST NOTF",
"ESTEEMAPP",
"UGUR ERDAL",
"ONLY YESTERDAY",
]}
defaultText="NEW POST"
rightIconName="md-apps"
/>
)}
{this.state.isReady ? (
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
componentId={this.props.componentId}
content={item}
user={this.props.user}
isLoggedIn={this.state.isLoggedIn}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={this.getMore}
removeClippedSubviews={true}
refreshing={this.state.refreshing}
onRefresh={() => this.refreshHotPosts()}
onEndThreshold={0}
initialNumToRender={10}
ListFooterComponent={this.renderFooter}
/>
) : (
<View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
);
};
render() {
return (
<View style={{ flex: 1 }}>
{this.state.isReady ? (
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
componentId={this.props.componentId}
content={item}
user={this.props.user}
isLoggedIn={this.state.isLoggedIn}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={this.getMore}
removeClippedSubviews={true}
refreshing={this.state.refreshing}
onRefresh={() => this.refreshHotPosts()}
onEndThreshold={0}
initialNumToRender={10}
ListFooterComponent={this.renderFooter}
/>
) : (
<View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
</View>
)}
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
);
}
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
</View>
)}
</View>
);
}
}
export default HotPage;

View File

@ -9,154 +9,154 @@ import { getPosts } from "../../providers/steem/dsteem";
import Placeholder from "rn-placeholder";
// COMPONENTS
import PostCard from "../../components/post-card/postCard";
import { PostCard } from "../../components/postCard";
// SCREENS
/* eslint-enable no-unused-vars */
class TrendingPage extends React.Component {
constructor(props) {
super(props);
constructor(props) {
super(props);
this.getTrending = this.getTrending.bind(this);
this.getMore = this.getMore.bind(this);
this.refreshData = this.refreshData.bind(this);
this.state = {
isReady: false,
posts: [],
user: [],
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
isLoggedIn: this.props.isLoggedIn,
};
}
componentDidMount() {
this.getTrending();
}
getTrending = () => {
getPosts("trending", { tag: "", limit: 10 }, this.props.user.name)
.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);
});
this.getTrending = this.getTrending.bind(this);
this.getMore = this.getMore.bind(this);
this.refreshData = this.refreshData.bind(this);
this.state = {
isReady: false,
posts: [],
user: [],
start_author: "",
start_permlink: "",
refreshing: false,
loading: false,
isLoggedIn: this.props.isLoggedIn,
};
}
getMore = () => {
this.setState({ loading: true });
getPosts(
"trending",
{
tag: "",
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.props.user.name
).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,
});
componentDidMount() {
this.getTrending();
}
getTrending = () => {
getPosts("trending", { tag: "", limit: 10 }, this.props.user.name)
.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);
});
};
refreshData = () => {
this.setState(
{
refreshing: true,
},
() => {
this.getTrending();
}
);
};
getMore = () => {
this.setState({ loading: true });
getPosts(
"trending",
{
tag: "",
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.props.user.name
).then(result => {
let posts = result;
posts.shift();
this.setState({
posts: [...this.state.posts, ...posts],
start_author: result[result.length - 1].author,
start_permlink: result[result.length - 1].permlink,
});
});
};
renderFooter = () => {
if (!this.state.loading) return null;
refreshData = () => {
this.setState(
{
refreshing: true,
},
() => {
this.getTrending();
}
);
};
return (
<View style={styles.flatlistFooter}>
<ActivityIndicator animating size="large" />
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View style={styles.flatlistFooter}>
<ActivityIndicator animating size="large" />
</View>
);
};
render() {
return (
<View style={{ flex: 1 }}>
{this.state.isReady ? (
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
componentId={this.props.componentId}
content={item}
user={this.props.user}
isLoggedIn={this.state.isLoggedIn}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={this.getMore}
removeClippedSubviews={true}
refreshing={this.state.refreshing}
onRefresh={() => this.refreshData()}
onEndThreshold={0}
initialNumToRender={10}
ListFooterComponent={this.renderFooter}
/>
) : (
<View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
);
};
render() {
return (
<View style={{ flex: 1 }}>
{this.state.isReady ? (
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
componentId={this.props.componentId}
content={item}
user={this.props.user}
isLoggedIn={this.state.isLoggedIn}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={this.getMore}
removeClippedSubviews={true}
refreshing={this.state.refreshing}
onRefresh={() => this.refreshData()}
onEndThreshold={0}
initialNumToRender={10}
ListFooterComponent={this.renderFooter}
/>
) : (
<View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
</View>
)}
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
);
}
<View style={styles.placeholder}>
<Placeholder.ImageContent
size={60}
animate="fade"
lineNumber={4}
lineSpacing={5}
lastLineWidth="30%"
onReady={this.state.isReady}
/>
</View>
</View>
)}
</View>
);
}
}
export default TrendingPage;

View File

@ -1,68 +1,26 @@
import React, { Component } from "react";
import {
View,
ActivityIndicator,
Text,
Image,
TouchableOpacity,
TextInput,
BackHandler,
Linking,
StatusBar,
} from "react-native";
import { Navigation } from "react-native-navigation";
import Ionicons from "react-native-vector-icons/Ionicons";
import FastImage from "react-native-fast-image";
import { TabBar } from "../../../components/tabBar";
import { LoginHeader } from "../../../components/loginHeader";
import { FormInput } from "../../../components/formInput";
import { InformationArea } from "../../../components/informationArea";
import { View, BackHandler, Linking, StatusBar } from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
// Internal Components
import { FormInput } from "../../../components/formInput";
import { TextButton } from "../../../components/buttons";
import { InformationArea } from "../../../components/informationArea";
import { Login } from "../../../providers/steem/auth";
import { LoginHeader } from "../../../components/loginHeader";
import { MainButton } from "../../../components/mainButton";
import { Navigation } from "react-native-navigation";
import { TabBar } from "../../../components/tabBar";
import { addNewAccount } from "../../../redux/actions/accountAction";
import { lookupAccounts } from "../../../providers/steem/dsteem";
import { goToAuthScreens } from "../../../navigation";
import { lookupAccounts } from "../../../providers/steem/dsteem";
import STEEM_CONNECT_LOGO from "../../../assets/steem_connect.png";
// Styles
import styles from "./loginStyles";
class LoginScreen extends Component {
static get options() {
return {
_statusBar: {
visible: true,
drawBehind: false,
},
topBar: {
animate: true,
hideOnScroll: false,
drawBehind: false,
noBorder: true,
visible: true,
elevation: 0,
leftButtons: {},
rightButtons: [
{
id: "signup",
text: "Sign Up",
color: "#a7adaf",
marginRight: 50,
},
],
},
layout: {
backgroundColor: "#f5fcff",
},
bottomTabs: {
visible: false,
drawBehind: true,
},
};
}
constructor(props) {
super(props);
Navigation.events().bindComponent(this);
@ -71,7 +29,8 @@ class LoginScreen extends Component {
username: "",
password: "",
isLoading: false,
isUsernameValid: true,
isUsernameValid: false,
keyboardIsOpen: false,
};
}
@ -112,7 +71,7 @@ class LoginScreen extends Component {
}
})
.catch(err => {
alert(err);
// alert(err);
this.setState({ isLoading: false });
});
};
@ -127,15 +86,13 @@ class LoginScreen extends Component {
this.setState({ password: value });
};
navigationButtonPressed({ buttonId }) {
if (buttonId === "signup") {
Linking.openURL("https://signup.steemit.com/?ref=esteem").catch(err =>
console.error("An error occurred", err)
);
}
}
_handleSignUp = () => {
Linking.openURL("https://signup.steemit.com/?ref=esteem").catch(err =>
console.error("An error occurred", err)
);
};
loginwithSc2 = () => {
_loginwithSc2 = () => {
Navigation.push(this.props.componentId, {
component: {
name: "navigation.eSteem.SteemConnect",
@ -152,170 +109,98 @@ class LoginScreen extends Component {
};
render() {
const {
isLoading,
username,
isUsernameValid,
keyboardIsOpen,
password,
} = this.state;
return (
<View style={{ flex: 1 }}>
<StatusBar hidden translucent />
<LoginHeader
isKeyboardOpen={keyboardIsOpen}
title="Sign in"
description="To get all the benefits using eSteem"
onPress={() => this._handleSignUp()}
/>
<ScrollableTabView
style={styles.tabView}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={100} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={2} // default 3
activeColor={"#357ce6"}
inactiveColor={"#222"}
/>
)}
<KeyboardAwareScrollView
onKeyboardWillShow={() => this.setState({ keyboardIsOpen: true })}
onKeyboardWillHide={() => this.setState({ keyboardIsOpen: false })}
>
<View tabLabel="Sign in" style={styles.tabbarItem}>
<FormInput
rightIconName="md-at"
leftIconName="md-close-circle"
isValid={this.state.isUsernameValid}
onChange={value => this.handleUsername(value)}
placeholder="Username"
isEditable
type="username"
isFirstImage
value={this.state.username}
/>
<FormInput
rightIconName="md-lock"
leftIconName="md-close-circle"
isValid={this.state.isUsernameValid}
onChange={value => this._handleOnPasswordChange(value)}
placeholder="Password or WIF"
isEditable
secureTextEntry
type="password"
/>
<InformationArea
description="User credentials are kept locally on the device. Credentials are
<ScrollableTabView
locked={isLoading}
style={styles.tabView}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={100} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={2} // default 3
activeColor={"#357ce6"}
inactiveColor={"#222"}
/>
)}
>
<View tabLabel="Sign in" style={styles.tabbarItem}>
<FormInput
rightIconName="md-at"
leftIconName="md-close-circle"
isValid={isUsernameValid}
onChange={value => this.handleUsername(value)}
placeholder="Username"
isEditable
type="username"
isFirstImage
value={username}
/>
<FormInput
rightIconName="md-lock"
leftIconName="md-close-circle"
isValid={isUsernameValid}
onChange={value => this._handleOnPasswordChange(value)}
placeholder="Password or WIF"
isEditable
secureTextEntry
type="password"
/>
<InformationArea
description="User credentials are kept locally on the device. Credentials are
removed upon logout!"
iconName="ios-information-circle-outline"
/>
<View style={{ flexDirection: "row", margin: 30 }}>
<View style={{ flex: 0.6 }}>
<TouchableOpacity
onPress={goToAuthScreens}
style={{
alignContent: "center",
padding: "9%",
}}
>
<Text
style={{
color: "#788187",
alignSelf: "center",
fontWeight: "bold",
}}
>
Cancel
</Text>
</TouchableOpacity>
iconName="ios-information-circle-outline"
/>
<View style={styles.footerButtons}>
<TextButton onPress={goToAuthScreens} text="cancel" />
</View>
<TouchableOpacity
<MainButton
wrapperStyle={styles.mainButtonWrapper}
onPress={this._handleOnPressLogin}
style={{
flex: 0.4,
width: 100,
height: 50,
borderRadius: 30,
backgroundColor: "#357ce6",
flexDirection: "row",
}}
>
{!this.state.isLoading ? (
<View
style={{
flex: 1,
flexDirection: "row",
}}
>
<Ionicons
color="white"
name="md-person"
style={{
alignSelf: "center",
fontSize: 25,
flex: 0.4,
left: 15,
}}
/>
<Text
style={{
color: "white",
fontWeight: "600",
alignSelf: "center",
fontSize: 16,
flex: 0.6,
}}
>
LOGIN
</Text>
</View>
) : (
<ActivityIndicator
color="white"
style={{ alignSelf: "center", flex: 1 }}
/>
)}
</TouchableOpacity>
iconName="md-person"
iconColor="white"
text="LOGIN"
isDisable={
!isUsernameValid || password.length < 2 || username.length < 2
}
isLoading={isLoading}
/>
</View>
</View>
<View tabLabel="SteemConnect" style={styles.steemConnectTab}>
<InformationArea
description="If you don't want to keep your password encrypted and saved on your device, you can use Steemconnect."
iconName="ios-information-circle-outline"
/>
<View
style={{
alignItems: "flex-end",
backgroundColor: "#ffffff",
}}
>
<TouchableOpacity
onPress={this.loginwithSc2}
style={{
width: 200,
height: 50,
borderRadius: 30,
backgroundColor: "#357ce6",
flexDirection: "row",
margin: 20,
}}
>
<View style={{ flex: 1, flexDirection: "row" }}>
<Ionicons
color="white"
name="md-person"
style={{
alignSelf: "center",
fontSize: 25,
marginHorizontal: 20,
}}
/>
<Text
style={{
color: "white",
fontWeight: "400",
alignSelf: "center",
fontSize: 16,
}}
>
steem
<Text style={{ fontWeight: "800" }}>connect</Text>
</Text>
</View>
</TouchableOpacity>
<View tabLabel="SteemConnect" style={styles.steemConnectTab}>
<InformationArea
description="If you don't want to keep your password encrypted and saved on your device, you can use Steemconnect."
iconName="ios-information-circle-outline"
/>
<MainButton
wrapperStyle={styles.mainButtonWrapper}
onPress={this._loginwithSc2}
iconName="md-person"
source={STEEM_CONNECT_LOGO}
text="steem"
secondText="connect"
/>
</View>
</View>
</ScrollableTabView>
</ScrollableTabView>
</KeyboardAwareScrollView>
</View>
);
}

View File

@ -36,9 +36,28 @@ export default EStyleSheet.create({
flex: 1,
backgroundColor: "#ffffff",
minWidth: "$deviceWidth",
height: "$deviceHeight / 1.95",
},
steemConnectTab: {
backgroundColor: "#fff",
minWidth: "$deviceWidth",
flex: 1,
height: "$deviceHeight / 1.95",
},
mainButtonWrapper: {
position: "absolute",
right: 24,
bottom: 24,
flexDirection: "row",
},
footerButtons: {
flex: 1,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
alignSelf: "flex-end",
position: "absolute",
bottom: 45,
left: "$deviceWidth / 2.3",
},
});

View File

@ -1,20 +1,36 @@
import React from "react";
import { Container, Text } from "native-base";
import React, { Fragment } from "react";
import { Text, View, SafeAreaView } from "react-native";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
import { TabBar } from "../../../components/tabBar";
import { Notification } from "../../../components/notification";
// Styles
//import styles from "./notificationStyles";
import styles from "./notificationStyles";
class NotificationScreen extends React.Component {
static navigationOptions = {
title: "Notifications",
};
render() {
return (
<Container>
<Text>Notifications</Text>
</Container>
);
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "#fff" }}>
<ScrollableTabView
style={styles.tabView}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={100}
tabUnderlineScaleX={2}
activeColor={"#357ce6"}
inactiveColor={"#222"}
/>
)}
>
<View tabLabel="Notification" style={styles.notificationTab}>
<Notification />
</View>
<View tabLabel="Leaderboard" style={styles.leaderboardTab}>
<Text>Leaderboard</Text>
</View>
</ScrollableTabView>
</SafeAreaView>
);
}
}
export default NotificationScreen;

View File

@ -1,3 +1,23 @@
import EStyleSheet from "react-native-extended-stylesheet";
export default EStyleSheet.create({});
export default EStyleSheet.create({
tabbar: {
alignSelf: "center",
height: 55,
backgroundColor: "white",
borderBottomColor: "#f1f1f1",
},
tabView: {
alignSelf: "center",
backgroundColor: "transparent",
},
notificationTab: {
backgroundColor: "#fff",
minWidth: "$deviceWidth",
},
leaderboardTab: {
flex: 1,
backgroundColor: "#ffffff",
minWidth: "$deviceWidth",
},
});

View File

@ -1,387 +1,336 @@
/* eslint-disable no-unused-vars */
import React from "react";
import {
StatusBar,
Dimensions,
FlatList,
ActivityIndicator,
} from "react-native";
import { FlatList, ActivityIndicator } from "react-native";
import moment from "moment";
import { getTimeFromNow } from "../../utils/time";
import FastImage from "react-native-fast-image";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
import { TabBar } from "../../../components/tabBar";
import DiscoverPage from "../discover/discover";
import PostCard from "../../components/post-card/postCard";
import { PostCard } from "../../components/postCard";
import Comment from "../../components/comment/comment";
import {
Content,
Card,
CardItem,
View,
Header,
Left,
Body,
Right,
Button,
Icon,
Title,
Text,
Container,
} from "native-base";
import { Card, CardItem, View, Body } from "native-base";
import { getUserData, getAuthStatus } from "../../realm/realm";
import {
getUser,
getFollows,
getPosts,
getUserComments,
getUserReplies,
getUser,
getFollows,
getPosts,
getUserComments,
} from "../../providers/steem/dsteem";
import store from "../../redux/store/store";
import styles from "../../styles/profile.styles";
/* eslint-enable no-unused-vars */
class ProfilePage extends React.Component {
static get options() {
return {
_statusBar: {
visible: true,
drawBehind: false,
},
topBar: {
animate: true,
hideOnScroll: false,
drawBehind: false,
leftButtons: {
id: "back",
},
},
layout: {
backgroundColor: "#f5fcff",
},
bottomTabs: {
visible: false,
drawBehind: true,
},
};
}
static get options() {
return {
_statusBar: {
visible: true,
drawBehind: false,
},
topBar: {
animate: true,
hideOnScroll: false,
drawBehind: false,
leftButtons: {
id: "back",
},
},
layout: {
backgroundColor: "#f5fcff",
},
bottomTabs: {
visible: false,
drawBehind: true,
},
};
}
constructor() {
super();
this.getBlog = this.getBlog.bind(this);
this.getMore = this.getMore.bind(this);
this.getComments = this.getComments.bind(this);
this.state = {
user: [],
posts: [],
commments: [],
replies: [],
about: {},
follows: {},
isLoggedIn: false,
};
}
constructor() {
super();
this.getBlog = this.getBlog.bind(this);
this.getMore = this.getMore.bind(this);
this.getComments = this.getComments.bind(this);
this.state = {
user: [],
posts: [],
commments: [],
replies: [],
about: {},
follows: {},
isLoggedIn: false,
};
}
async componentDidMount() {
let isLoggedIn;
let user;
let userData;
let follows;
let about;
async componentDidMount() {
let isLoggedIn;
let user;
let userData;
let follows;
let about;
await getAuthStatus().then(res => {
isLoggedIn = res;
});
await getAuthStatus().then(res => {
isLoggedIn = res;
});
if (isLoggedIn == true) {
await getUserData().then(res => {
userData = Array.from(res);
});
if (isLoggedIn) {
await getUserData().then(res => {
userData = Array.from(res);
});
await getFollows(userData[0].username).then(res => {
follows = res;
});
await getFollows(userData[0].username).then(res => {
follows = res;
});
user = await getUser(userData[0].username);
about = JSON.parse(user.json_metadata);
this.setState(
{
user: user,
isLoggedIn: isLoggedIn,
follows: follows,
about: about.profile,
},
() => {
this.getBlog(userData[0].username);
this.getComments(userData[0].username);
}
);
user = await getUser(userData[0].username);
about = JSON.parse(user.json_metadata);
this.setState(
{
user: user,
isLoggedIn: isLoggedIn,
follows: follows,
about: about.profile,
},
() => {
this.getBlog(userData[0].username);
this.getComments(userData[0].username);
}
);
}
}
renderFooter = () => {
if (!this.state.loading == false) return null;
renderFooter = () => {
if (this.state.loading) return null;
return (
<View style={{ marginVertical: 20 }}>
<ActivityIndicator animating size="large" />
</View>
);
};
return (
<View style={{ marginVertical: 20 }}>
<ActivityIndicator animating size="large" />
</View>
);
};
getBlog = user => {
this.setState({ loading: true });
getPosts("blog", { tag: user, limit: 10 }, user)
.then(result => {
this.setState({
isReady: true,
posts: result,
start_author: result[result.length - 1].author,
start_permlink: result[result.length - 1].permlink,
refreshing: false,
loading: false,
});
})
.catch(err => {
alert(err);
});
};
getMore = async () => {
console.log("get more");
await getPosts(
"blog",
{
tag: this.state.user.name,
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.state.user.name
).then(result => {
console.log(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,
loading: false,
});
getBlog = user => {
this.setState({ loading: true });
getPosts("blog", { tag: user, limit: 10 }, user)
.then(result => {
this.setState({
isReady: true,
posts: result,
start_author: result[result.length - 1].author,
start_permlink: result[result.length - 1].permlink,
refreshing: false,
loading: false,
});
};
})
.catch(err => {
alert(err);
});
};
getComments = async user => {
await getUserComments({ start_author: user, limit: 10 })
.then(result => {
this.setState({
isReady: true,
commments: result,
refreshing: false,
loading: false,
});
})
.catch(err => {
console.log(err);
});
};
getMore = async () => {
console.log("get more");
await getPosts(
"blog",
{
tag: this.state.user.name,
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.state.user.name
).then(result => {
console.log(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,
loading: false,
});
});
};
render() {
return (
<View style={styles.container}>
{this.state.isLoggedIn ? (
<View style={{ flex: 1 }}>
<View style={styles.content}>
<FastImage
style={styles.cover}
source={{
uri: this.state.about.cover_image,
priority: FastImage.priority.high,
}}
/>
<FastImage
style={styles.avatar}
source={{
uri: this.state.about.profile_image,
priority: FastImage.priority.high,
}}
/>
<Body style={{ top: -40 }}>
<Text style={{ fontWeight: "bold" }}>
{this.state.user.name}
</Text>
<Text>{this.state.about.about}</Text>
</Body>
<Card style={{ margin: 0 }}>
<CardItem style={styles.about}>
<View style={{ flex: 0.3 }}>
<Text>
{this.state.user.post_count} Posts
</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>
{this.state.follows.follower_count}{" "}
Followers
</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>
{this.state.follows.following_count}{" "}
Following
</Text>
</View>
</CardItem>
getComments = async user => {
await getUserComments({ start_author: user, limit: 10 })
.then(result => {
this.setState({
isReady: true,
commments: result,
refreshing: false,
loading: false,
});
})
.catch(err => {
console.log(err);
});
};
<CardItem style={styles.info}>
<View style={{ flex: 0.5 }}>
<Text
style={{
marginLeft: 20,
alignSelf: "flex-start",
}}
>
<Icon
style={{
fontSize: 20,
alignSelf: "flex-start",
}}
name="md-pin"
/>
{this.state.about.location}
</Text>
</View>
<View style={{ flex: 0.5 }}>
<Text>
<Icon
style={{
fontSize: 20,
marginRight: 10,
}}
name="md-calendar"
/>
{moment
.utc(this.state.user.created)
.local()
.fromNow()}
</Text>
</View>
</CardItem>
</Card>
</View>
<ScrollableTabView
style={styles.tabs}
style={{ flex: 1 }}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={3} // default 3
activeColor={"#222"}
inactiveColor={"#222"}
/>
)}
>
<View tabLabel="Blog" style={styles.tabbarItem}>
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
style={{ shadowColor: "white" }}
content={item}
user={this.state.user}
isLoggedIn={true}
/>
)}
keyExtractor={(post, index) =>
index.toString()
}
onEndReached={info => {
if (this.state.loading == false) {
console.log(info);
this.getMore();
}
}}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
render() {
return (
<View style={styles.container}>
{this.state.isLoggedIn ? (
<View style={{ flex: 1 }}>
<View style={styles.content}>
<FastImage
style={styles.cover}
source={{
uri: this.state.about.cover_image,
priority: FastImage.priority.high,
}}
/>
<FastImage
style={styles.avatar}
source={{
uri: this.state.about.profile_image,
priority: FastImage.priority.high,
}}
/>
<Body style={{ top: -40 }}>
<Text style={{ fontWeight: "bold" }}>
{this.state.user.name}
</Text>
<Text>{this.state.about.about}</Text>
</Body>
<Card style={{ margin: 0 }}>
<CardItem style={styles.about}>
<View style={{ flex: 0.3 }}>
<Text>{this.state.user.post_count} Posts</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>{this.state.follows.follower_count} Followers</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>{this.state.follows.following_count} Following</Text>
</View>
</CardItem>
<View tabLabel="Comments" style={styles.tabbarItem}>
<FlatList
data={this.state.commments}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<Comment
comment={item}
isLoggedIn={true}
user={this.state.user}
/>
)}
keyExtractor={(post, index) =>
index.toString()
}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
<View
tabLabel="Replies"
style={styles.tabbarItem}
/>
<View tabLabel="Wallet" style={styles.tabbarItem}>
<Card>
<Text>
STEEM Balance: {this.state.user.balance}
</Text>
</Card>
<Card>
<Text>
SBD Balance:{" "}
{this.state.user.sbd_balance}
</Text>
</Card>
<Card>
<Text>
STEEM Power:{" "}
{this.state.user.steem_power} SP
</Text>
<Text>
Received STEEM Power:{" "}
{this.state.user.received_steem_power}{" "}
SP
</Text>
<Text>
Delegated Power Power:{" "}
{this.state.user.delegated_steem_power}{" "}
SP
</Text>
</Card>
<Card>
<Text>
Saving STEEM Balance:{" "}
{this.state.user.savings_balance}
</Text>
<Text>
Saving STEEM Balance:{" "}
{this.state.user.savings_sbd_balance}
</Text>
</Card>
</View>
</ScrollableTabView>
</View>
) : (
<DiscoverPage />
)}
<CardItem style={styles.info}>
<View style={{ flex: 0.5 }}>
<Text
style={{
marginLeft: 20,
alignSelf: "flex-start",
}}
>
<Icon
style={{
fontSize: 20,
alignSelf: "flex-start",
}}
name="md-pin"
/>
{this.state.about.location}
</Text>
</View>
<View style={{ flex: 0.5 }}>
<Text>
<Icon
style={{
fontSize: 20,
marginRight: 10,
}}
name="md-calendar"
/>
{getTimeFromNow(this.state.user.created)}
</Text>
</View>
</CardItem>
</Card>
</View>
);
}
<ScrollableTabView
style={styles.tabs}
style={{ flex: 1 }}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={3} // default 3
activeColor={"#222"}
inactiveColor={"#222"}
/>
)}
>
<View tabLabel="Blog" style={styles.tabbarItem}>
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
style={{ shadowColor: "white" }}
content={item}
user={this.state.user}
isLoggedIn={true}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={info => {
if (!this.state.loading) {
console.log(info);
this.getMore();
}
}}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
<View tabLabel="Comments" style={styles.tabbarItem}>
<FlatList
data={this.state.commments}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<Comment
comment={item}
isLoggedIn={true}
user={this.state.user}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
<View tabLabel="Replies" style={styles.tabbarItem} />
<View tabLabel="Wallet" style={styles.tabbarItem}>
<Card>
<Text>STEEM Balance: {this.state.user.balance}</Text>
</Card>
<Card>
<Text>SBD Balance: {this.state.user.sbd_balance}</Text>
</Card>
<Card>
<Text>STEEM Power: {this.state.user.steem_power} SP</Text>
<Text>
Received STEEM Power: {this.state.user.received_steem_power}{" "}
SP
</Text>
<Text>
Delegated Power Power:{" "}
{this.state.user.delegated_steem_power} SP
</Text>
</Card>
<Card>
<Text>
Saving STEEM Balance: {this.state.user.savings_balance}
</Text>
<Text>
Saving STEEM Balance: {this.state.user.savings_sbd_balance}
</Text>
</Card>
</View>
</ScrollableTabView>
</View>
) : (
<DiscoverPage />
)}
</View>
);
}
}
export default ProfilePage;

View File

@ -2,23 +2,24 @@
import React from "react";
import { FlatList, ActivityIndicator } from "react-native";
import moment from "moment";
import { getTimeFromNow } from "../../../utils/time";
import FastImage from "react-native-fast-image";
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
import { TabBar } from "../../../components/tabBar";
import DiscoverPage from "../../discover/discover";
import PostCard from "../../../components/post-card/postCard";
import { PostCard } from "../../../components/postCard";
import Comment from "../../../components/comment/comment";
import { Card, CardItem, View, Body, Icon, Text } from "native-base";
import { getUserData, getAuthStatus } from "../../../realm/realm";
import {
getUser,
getFollows,
getPosts,
getUserComments,
getUser,
getFollows,
getPosts,
getUserComments,
} from "../../../providers/steem/dsteem";
// Styles
@ -26,344 +27,314 @@ import styles from "./profileStyles";
/* eslint-enable no-unused-vars */
class ProfileScreen extends React.Component {
static get options() {
return {
_statusBar: {
visible: true,
drawBehind: false,
},
topBar: {
animate: true,
hideOnScroll: false,
drawBehind: false,
leftButtons: {
id: "back",
},
},
layout: {
backgroundColor: "#f5fcff",
},
bottomTabs: {
visible: false,
drawBehind: true,
},
};
}
static get options() {
return {
_statusBar: {
visible: true,
drawBehind: false,
},
topBar: {
animate: true,
hideOnScroll: false,
drawBehind: false,
leftButtons: {
id: "back",
},
},
layout: {
backgroundColor: "#f5fcff",
},
bottomTabs: {
visible: false,
drawBehind: true,
},
};
}
constructor() {
super();
this.getBlog = this.getBlog.bind(this);
this.getMore = this.getMore.bind(this);
this.getComments = this.getComments.bind(this);
this.state = {
user: [],
posts: [],
commments: [],
replies: [],
about: {},
follows: {},
isLoggedIn: false,
};
}
constructor() {
super();
this.getBlog = this.getBlog.bind(this);
this.getMore = this.getMore.bind(this);
this.getComments = this.getComments.bind(this);
this.state = {
user: [],
posts: [],
commments: [],
replies: [],
about: {},
follows: {},
isLoggedIn: false,
};
}
async componentDidMount() {
await getAuthStatus().then(res => {
const isLoggedIn = res;
});
async componentDidMount() {
await getAuthStatus().then(res => {
const isLoggedIn = res;
});
if (isLoggedIn === true) {
let user;
let userData;
let follows;
let about;
if (isLoggedIn) {
let user;
let userData;
let follows;
let about;
await getUserData().then(res => {
userData = Array.from(res);
});
await getUserData().then(res => {
userData = Array.from(res);
});
await getFollows(userData[0].username).then(res => {
follows = res;
});
await getFollows(userData[0].username).then(res => {
follows = res;
});
user = await getUser(userData[0].username);
about = JSON.parse(user.json_metadata);
// BUG: json_metadata: "{}" is coming emty object!!
this.setState(
{
user: user,
isLoggedIn: isLoggedIn,
follows: follows,
about: about.profile,
},
() => {
this.getBlog(userData[0].username);
this.getComments(userData[0].username);
}
);
user = await getUser(userData[0].username);
about = JSON.parse(user.json_metadata);
// BUG: json_metadata: "{}" is coming emty object!!
this.setState(
{
user: user,
isLoggedIn: isLoggedIn,
follows: follows,
about: about.profile,
},
() => {
this.getBlog(userData[0].username);
this.getComments(userData[0].username);
}
);
}
}
renderFooter = () => {
if (!this.state.loading == false) return null;
renderFooter = () => {
if (this.state.loading) return null;
return (
<View style={{ marginVertical: 20 }}>
<ActivityIndicator animating size="large" />
</View>
);
};
return (
<View style={{ marginVertical: 20 }}>
<ActivityIndicator animating size="large" />
</View>
);
};
getBlog = user => {
this.setState({ loading: true });
getPosts("blog", { tag: user, limit: 10 }, user)
.then(result => {
this.setState({
isReady: true,
posts: result,
start_author: result[result.length - 1].author,
start_permlink: result[result.length - 1].permlink,
refreshing: false,
loading: false,
});
})
.catch(err => {
alert(err);
});
};
getMore = async () => {
console.log("get more");
await getPosts(
"blog",
{
tag: this.state.user.name,
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.state.user.name
).then(result => {
console.log(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,
loading: false,
});
getBlog = user => {
this.setState({ loading: true });
getPosts("blog", { tag: user, limit: 10 }, user)
.then(result => {
this.setState({
isReady: true,
posts: result,
start_author: result[result.length - 1].author,
start_permlink: result[result.length - 1].permlink,
refreshing: false,
loading: false,
});
};
})
.catch(err => {
alert(err);
});
};
getComments = async user => {
await getUserComments({ start_author: user, limit: 10 })
.then(result => {
this.setState({
isReady: true,
commments: result,
refreshing: false,
loading: false,
});
})
.catch(err => {
console.log(err);
});
};
getMore = async () => {
console.log("get more");
await getPosts(
"blog",
{
tag: this.state.user.name,
limit: 10,
start_author: this.state.start_author,
start_permlink: this.state.start_permlink,
},
this.state.user.name
).then(result => {
console.log(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,
loading: false,
});
});
};
render() {
//TODO: Refactor ME !
return (
<View style={styles.container}>
{this.state.isLoggedIn ? (
<View style={{ flex: 1 }}>
<View style={styles.content}>
<FastImage
style={styles.cover}
source={{
uri: this.state.about.cover_image,
priority: FastImage.priority.high,
}}
/>
<FastImage
style={styles.avatar}
source={{
uri: this.state.about.profile_image,
priority: FastImage.priority.high,
}}
/>
<Body style={{ top: -40 }}>
<Text style={{ fontWeight: "bold" }}>
{this.state.user.name}
</Text>
<Text>{this.state.about.about}</Text>
</Body>
<Card style={{ margin: 0 }}>
<CardItem style={styles.about}>
<View style={{ flex: 0.3 }}>
<Text>
{this.state.user.post_count} Posts
</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>
{this.state.follows.follower_count}{" "}
Followers
</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>
{this.state.follows.following_count}{" "}
Following
</Text>
</View>
</CardItem>
getComments = async user => {
await getUserComments({ start_author: user, limit: 10 })
.then(result => {
this.setState({
isReady: true,
commments: result,
refreshing: false,
loading: false,
});
})
.catch(err => {
console.log(err);
});
};
<CardItem style={styles.info}>
<View style={{ flex: 0.5 }}>
<Text
style={{
marginLeft: 20,
alignSelf: "flex-start",
}}
>
<Icon
style={{
fontSize: 20,
alignSelf: "flex-start",
}}
name="md-pin"
/>
{this.state.about.location}
</Text>
</View>
<View style={{ flex: 0.5 }}>
<Text>
<Icon
style={{
fontSize: 20,
marginRight: 10,
}}
name="md-calendar"
/>
{moment
.utc(this.state.user.created)
.local()
.fromNow()}
</Text>
</View>
</CardItem>
</Card>
</View>
<ScrollableTabView
style={styles.tabs}
style={{ flex: 1 }}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={3} // default 3
activeColor={"#222"}
inactiveColor={"#222"}
/>
)}
>
<View tabLabel="Blog" style={styles.tabbarItem}>
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
style={{ shadowColor: "white" }}
content={item}
user={this.state.user}
isLoggedIn={true}
/>
)}
keyExtractor={(post, index) =>
index.toString()
}
onEndReached={info => {
if (this.state.loading == false) {
console.log(info);
this.getMore();
}
}}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
render() {
//TODO: Refactor ME !
return (
<View style={styles.container}>
{this.state.isLoggedIn ? (
<View style={{ flex: 1 }}>
<View style={styles.content}>
<FastImage
style={styles.cover}
source={{
uri: this.state.about.cover_image,
priority: FastImage.priority.high,
}}
/>
<FastImage
style={styles.avatar}
source={{
uri: this.state.about.profile_image,
priority: FastImage.priority.high,
}}
/>
<Body style={{ top: -40 }}>
<Text style={{ fontWeight: "bold" }}>
{this.state.user.name}
</Text>
<Text>{this.state.about.about}</Text>
</Body>
<Card style={{ margin: 0 }}>
<CardItem style={styles.about}>
<View style={{ flex: 0.3 }}>
<Text>{this.state.user.post_count} Posts</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>{this.state.follows.follower_count} Followers</Text>
</View>
<View style={{ flex: 0.4 }}>
<Text>{this.state.follows.following_count} Following</Text>
</View>
</CardItem>
<View tabLabel="Comments" style={styles.tabbarItem}>
<FlatList
data={this.state.commments}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<Comment
comment={item}
isLoggedIn={true}
user={this.state.user}
/>
)}
keyExtractor={(post, index) =>
index.toString()
}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
<View
tabLabel="Replies"
style={styles.tabbarItem}
/>
<View tabLabel="Wallet" style={styles.tabbarItem}>
<Card>
<Text>
STEEM Balance: {this.state.user.balance}
</Text>
</Card>
<Card>
<Text>
SBD Balance:{" "}
{this.state.user.sbd_balance}
</Text>
</Card>
<Card>
<Text>
STEEM Power:{" "}
{this.state.user.steem_power} SP
</Text>
<Text>
Received STEEM Power:{" "}
{this.state.user.received_steem_power}{" "}
SP
</Text>
<Text>
Delegated Power Power:{" "}
{this.state.user.delegated_steem_power}{" "}
SP
</Text>
</Card>
<Card>
<Text>
Saving STEEM Balance:{" "}
{this.state.user.savings_balance}
</Text>
<Text>
Saving STEEM Balance:{" "}
{this.state.user.savings_sbd_balance}
</Text>
</Card>
</View>
</ScrollableTabView>
</View>
) : (
<DiscoverPage />
)}
<CardItem style={styles.info}>
<View style={{ flex: 0.5 }}>
<Text
style={{
marginLeft: 20,
alignSelf: "flex-start",
}}
>
<Icon
style={{
fontSize: 20,
alignSelf: "flex-start",
}}
name="md-pin"
/>
{this.state.about.location}
</Text>
</View>
<View style={{ flex: 0.5 }}>
<Text>
<Icon
style={{
fontSize: 20,
marginRight: 10,
}}
name="md-calendar"
/>
{getTimeFromNow(this.state.user.created)}
</Text>
</View>
</CardItem>
</Card>
</View>
);
}
<ScrollableTabView
style={styles.tabs}
style={{ flex: 1 }}
renderTabBar={() => (
<TabBar
style={styles.tabbar}
tabUnderlineDefaultWidth={30} // default containerWidth / (numberOfTabs * 4)
tabUnderlineScaleX={3} // default 3
activeColor={"#222"}
inactiveColor={"#222"}
/>
)}
>
<View tabLabel="Blog" style={styles.tabbarItem}>
<FlatList
data={this.state.posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<PostCard
style={{ shadowColor: "white" }}
content={item}
user={this.state.user}
isLoggedIn={true}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndReached={info => {
if (!this.state.loading) {
console.log(info);
this.getMore();
}
}}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
<View tabLabel="Comments" style={styles.tabbarItem}>
<FlatList
data={this.state.commments}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => (
<Comment
comment={item}
isLoggedIn={true}
user={this.state.user}
/>
)}
keyExtractor={(post, index) => index.toString()}
onEndThreshold={0}
bounces={false}
ListFooterComponent={this.renderFooter}
/>
</View>
<View tabLabel="Replies" style={styles.tabbarItem} />
<View tabLabel="Wallet" style={styles.tabbarItem}>
<Card>
<Text>STEEM Balance: {this.state.user.balance}</Text>
</Card>
<Card>
<Text>SBD Balance: {this.state.user.sbd_balance}</Text>
</Card>
<Card>
<Text>STEEM Power: {this.state.user.steem_power} SP</Text>
<Text>
Received STEEM Power: {this.state.user.received_steem_power}{" "}
SP
</Text>
<Text>
Delegated Power Power:{" "}
{this.state.user.delegated_steem_power} SP
</Text>
</Card>
<Card>
<Text>
Saving STEEM Balance: {this.state.user.savings_balance}
</Text>
<Text>
Saving STEEM Balance: {this.state.user.savings_sbd_balance}
</Text>
</Card>
</View>
</ScrollableTabView>
</View>
) : (
<DiscoverPage />
)}
</View>
);
}
}
export default ProfileScreen;

View File

@ -22,7 +22,7 @@ import PinCode from "./pinCode";
// COMPONENTS
import SteemConnect from "./steem-connect/steemConnect";
import PostCard from "../components/post-card/postCard";
import { PostCard } from "../components/postCard";
import Search from "../components/search/search";
export const registerScreens = () => {

View File

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

View File

@ -1,270 +1,262 @@
import React from "react";
/* eslint-disable no-unused-vars */
import {
Content,
Text,
List,
ListItem,
Icon,
Container,
Left,
Right,
View,
Badge,
Thumbnail,
Content,
Text,
List,
ListItem,
Icon,
Container,
Left,
Right,
View,
Badge,
Thumbnail,
} from "native-base";
/* eslint-enable no-unused-vars */
import styles from "./style";
import FastImage from "react-native-fast-image";
import { getAccount } from "../../providers/steem/dsteem";
import { setAuthStatus } from "../../realm/realm";
import RNRestart from "react-native-restart";
import { Navigation } from "react-native-navigation";
const masterKeyMenuOptions = [
{
name: "Profile",
route: "Profile",
icon: "contact",
bg: "#C5F442",
},
{
name: "Bookmarks",
route: "bookmarks",
icon: "bookmarks",
bg: "#DA4437",
},
{
name: "Favorites",
route: "favorites",
icon: "heart",
bg: "#DA4437",
},
{
name: "Drafts",
route: "drafts",
icon: "create",
bg: "#DA4437",
},
{
name: "Schedules",
route: "schedules",
icon: "time",
bg: "#DA4437",
},
{
name: "Gallery",
route: "galery",
icon: "images",
bg: "#DA4437",
},
{
name: "Settings",
route: "Settings",
icon: "settings",
bg: "#DA4437",
},
{
name: "Profile",
route: "Profile",
icon: "contact",
bg: "#C5F442",
},
{
name: "Bookmarks",
route: "bookmarks",
icon: "bookmarks",
bg: "#DA4437",
},
{
name: "Favorites",
route: "favorites",
icon: "heart",
bg: "#DA4437",
},
{
name: "Drafts",
route: "drafts",
icon: "create",
bg: "#DA4437",
},
{
name: "Schedules",
route: "schedules",
icon: "time",
bg: "#DA4437",
},
{
name: "Gallery",
route: "galery",
icon: "images",
bg: "#DA4437",
},
{
name: "Settings",
route: "Settings",
icon: "settings",
bg: "#DA4437",
},
];
const postingKeyMenuOptions = [
{
name: "Profile",
route: "Profile",
icon: "contact",
bg: "#C5F442",
},
{
name: "Bookmarks",
route: "bookmarks",
icon: "bookmarks",
bg: "#DA4437",
},
{
name: "Favorites",
route: "favorites",
icon: "heart",
bg: "#DA4437",
},
{
name: "Drafts",
route: "drafts",
icon: "create",
bg: "#DA4437",
},
{
name: "Schedules",
route: "schedules",
icon: "time",
bg: "#DA4437",
},
{
name: "Gallery",
route: "galery",
icon: "images",
bg: "#DA4437",
},
{
name: "Settings",
route: "Settings",
icon: "settings",
bg: "#DA4437",
},
{
name: "Profile",
route: "Profile",
icon: "contact",
bg: "#C5F442",
},
{
name: "Bookmarks",
route: "bookmarks",
icon: "bookmarks",
bg: "#DA4437",
},
{
name: "Favorites",
route: "favorites",
icon: "heart",
bg: "#DA4437",
},
{
name: "Drafts",
route: "drafts",
icon: "create",
bg: "#DA4437",
},
{
name: "Schedules",
route: "schedules",
icon: "time",
bg: "#DA4437",
},
{
name: "Gallery",
route: "galery",
icon: "images",
bg: "#DA4437",
},
{
name: "Settings",
route: "Settings",
icon: "settings",
bg: "#DA4437",
},
];
export default class LoggedInSideBar extends React.Component {
constructor(props) {
super(props);
this.state = {
shadowOffsetWidth: 1,
shadowRadius: 4,
user: [],
loginType: "",
json_metadata: {},
};
}
componentDidMount() {
getAccount(this.props.user)
.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 => {
alert(err);
});
}
hideSideMenu() {
Navigation.mergeOptions("Component14", {
sideMenu: {
["right"]: {
visible: false,
},
},
});
}
Logout = () => {
let authData = {
isLoggedIn: false,
};
setAuthStatus(authData)
.then(() => {
RNRestart.Restart();
})
.catch(err => {
alert(err);
});
constructor(props) {
super(props);
this.state = {
shadowOffsetWidth: 1,
shadowRadius: 4,
user: [],
loginType: "",
json_metadata: {},
};
}
render() {
return (
<Container>
<Content
bounces={false}
style={{ flex: 1, backgroundColor: "#fff", top: -1 }}
>
<View style={styles.drawerCover} />
<Thumbnail
style={styles.drawerImage}
source={{ uri: this.state.avatar }}
/>
<View style={styles.info}>
<Text style={styles.userLabel}>
{(this.state.json_metadata &&
this.state.json_metadata.name) ||
""}
</Text>
<Text style={styles.username}>
@{this.state.user.name}
</Text>
</View>
<List
style={{ paddingLeft: 25 }}
dataArray={
this.state.loginType === "master_key"
? masterKeyMenuOptions
: postingKeyMenuOptions
}
renderRow={data => (
<ListItem
button
noBorder
onPress={() => {
Navigation.push("tab1Stack", {
component: {
name: `navigation.eSteem.${
data.route
}`,
passProps: {},
options: {
topBar: {
title: {},
},
},
},
});
this.hideSideMenu();
}}
>
<Left>
<Icon
active
name={data.icon}
style={{
color: "#777",
fontSize: 26,
width: 30,
}}
/>
<Text style={styles.text}>{data.name}</Text>
</Left>
{data.types && (
<Right style={{ flex: 1 }}>
<Badge
style={{
borderRadius: 3,
height: 25,
width: 72,
backgroundColor: data.bg,
}}
>
<Text style={styles.badgeText}>{`${
data.types
} Types`}</Text>
</Badge>
</Right>
)}
</ListItem>
)}
/>
<ListItem
noBorder
style={{ paddingLeft: 25 }}
onPress={() => this.Logout()}
componentDidMount() {
getAccount(this.props.user)
.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 => {
alert(err);
});
}
hideSideMenu() {
Navigation.mergeOptions("Component14", {
sideMenu: {
["right"]: {
visible: false,
},
},
});
}
Logout = () => {
let authData = {
isLoggedIn: false,
};
setAuthStatus(authData)
.then(() => {
RNRestart.Restart();
})
.catch(err => {
alert(err);
});
};
render() {
return (
<Container>
<Content
bounces={false}
style={{ flex: 1, backgroundColor: "#fff", top: -1 }}
>
<View style={styles.drawerCover} />
<Thumbnail
style={styles.drawerImage}
source={{ uri: this.state.avatar }}
/>
<View style={styles.info}>
<Text style={styles.userLabel}>
{(this.state.json_metadata && this.state.json_metadata.name) ||
""}
</Text>
<Text style={styles.username}>@{this.state.user.name}</Text>
</View>
<List
style={{ paddingLeft: 25 }}
dataArray={
this.state.loginType === "master_key"
? masterKeyMenuOptions
: postingKeyMenuOptions
}
renderRow={data => (
<ListItem
button
noBorder
onPress={() => {
Navigation.push("tab1Stack", {
component: {
name: `navigation.eSteem.${data.route}`,
passProps: {},
options: {
topBar: {
title: {},
},
},
},
});
this.hideSideMenu();
}}
>
<Left>
<Icon
active
name={data.icon}
style={{
color: "#777",
fontSize: 26,
width: 30,
}}
/>
<Text style={styles.text}>{data.name}</Text>
</Left>
{data.types && (
<Right style={{ flex: 1 }}>
<Badge
style={{
borderRadius: 3,
height: 25,
width: 72,
backgroundColor: data.bg,
}}
>
<Left>
<Icon
active
name="log-out"
style={{
color: "#777",
fontSize: 26,
width: 30,
}}
/>
<Text style={styles.text}>Logout</Text>
</Left>
</ListItem>
</Content>
</Container>
);
}
<Text style={styles.badgeText}>{`${
data.types
} Types`}</Text>
</Badge>
</Right>
)}
</ListItem>
)}
/>
<ListItem
noBorder
style={{ paddingLeft: 25 }}
onPress={() => this.Logout()}
>
<Left>
<Icon
active
name="log-out"
style={{
color: "#777",
fontSize: 26,
width: 30,
}}
/>
<Text style={styles.text}>Logout</Text>
</Left>
</ListItem>
</Content>
</Container>
);
}
}

View File

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

View File

@ -14,7 +14,7 @@ class SplashContainer extends React.Component {
async componentDidMount() {
await getAuthStatus()
.then(result => {
if (result === true) {
if (result) {
goToAuthScreens();
} else {
goToNoAuthScreens();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

@ -0,0 +1,27 @@
// TODO: Move all formats functions here!
// const imgRegex = /(https?:\/\/.*\.(?:tiff?|jpe?g|gif|png|svg|ico))/gim;
// const postRegex = /^https?:\/\/(.*)\/(.*)\/(@[\w\.\d-]+)\/(.*)/i;
// const youTubeRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([^& \n<]+)(?:[^ \n<]+)?/g;
// const vimeoRegex = /(https?:\/\/)?(www\.)?(?:vimeo)\.com.*(?:videos|video|channels|)\/([\d]+)/i;
// const dTubeRegex = /(https?:\/\/d.tube.#!\/v\/)(\w+)\/(\w+)/g;
export const getPostSummary = (postBody, length) => {
if (!postBody) {
return "";
}
postBody = postBody
.replace(/(<([^>]+)>)/gi, "") // Remove html tags
.replace(/\r?\n|\r/g, " ") // Remove new lines
.replace(/(?:https?|ftp):\/\/[\n\S]+/g, "") // Remove urls
.trim()
.replace(/ +(?= )/g, ""); // Remove all multiple spaces
if (length) {
// Truncate
postBody = postBody.substring(0, length);
}
return postBody;
};

View File

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

View File

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

View File

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

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

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

862
yarn.lock

File diff suppressed because it is too large Load Diff