Merge pull request #943 from esteemapp/feature/boost-promote

Feature/boost promote
This commit is contained in:
Mustafa Buyukcelebi 2019-07-18 09:32:58 +03:00 committed by GitHub
commit e2ddf4e402
25 changed files with 875 additions and 57 deletions

View File

@ -23,6 +23,7 @@
"dependencies": {
"@babel/runtime": "^7.1.2",
"@esteemapp/esteem-render-helpers": "^1.0.9",
"@ptomasroos/react-native-multi-slider": "^1.0.0",
"appcenter": "^1.10.0",
"appcenter-analytics": "^1.10.0",
"appcenter-crashes": "^1.10.0",
@ -43,6 +44,7 @@
"react-intl": "^2.7.2",
"react-native": "0.59.8",
"react-native-actionsheet": "^2.4.2",
"react-native-autocomplete-input": "^4.1.0",
"react-native-code-push": "esteemapp/react-native-code-push",
"react-native-config": "^0.11.5",
"react-native-datepicker": "^1.7.2",

View File

@ -1,23 +1,27 @@
import Logo from './logo/logo';
import { FormInput } from './formInput';
import { CircularButton, TextButton, IconButton } from './buttons';
import { FormInput } from './formInput';
import { NumericKeyboard } from './numericKeyboard';
import { PinAnimatedInput } from './pinAnimatedInput';
import { SideMenu } from './sideMenu';
import Modal from './modal';
import { TextInput } from './textInput';
import Icon from './icon';
import Logo from './logo/logo';
import Modal from './modal';
import ScaleSlider from './scaleSlider/scaleSliderView';
import UserListItem from './basicUIElements/view/userListItem/userListItem';
export {
Logo,
UserListItem,
FormInput,
CircularButton,
TextButton,
FormInput,
Icon,
IconButton,
Logo,
Modal,
NumericKeyboard,
PinAnimatedInput,
ScaleSlider,
SideMenu,
Modal,
Icon,
TextButton,
TextInput,
UserListItem,
};

View File

@ -1,3 +1,3 @@
import Points from './container/pointsContainer';
import Points from './view/pointsView';
export { Points };

View File

@ -88,7 +88,7 @@ class PointsView extends Component {
<DropdownButton
isHasChildIcon
iconName="arrow-drop-down"
options={['Transfer']}
options={['Transfer', 'Promote']}
noHighlight
dropdownButtonStyle={styles.dropdownButtonStyle}
onSelect={handleOnPressTransfer}

View File

@ -0,0 +1,51 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
active: {
textAlign: 'center',
fontSize: 17,
bottom: 10,
color: '$primaryDarkText',
},
inactive: {
flex: 1,
textAlignVertical: 'center',
textAlign: 'center',
fontWeight: 'normal',
color: '$primaryLightBackground',
},
line: {
width: 14,
height: 14,
backgroundColor: '$primaryBlue',
borderRadius: 7,
borderWidth: 0,
top: 12,
zIndex: 999,
},
container: {
justifyContent: 'center',
alignItems: 'center',
},
column: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
bottom: -20,
},
marker: {
width: 35,
height: 35,
borderRadius: 17,
backgroundColor: '$white',
borderWidth: 1,
position: 'absolute',
borderColor: '$primaryBlue',
},
selected: {
backgroundColor: '$primaryBlue',
},
track: {
backgroundColor: '$primaryLightGray',
},
});

View File

@ -0,0 +1,82 @@
import React, { Component } from 'react';
import { View, Dimensions, Text } from 'react-native';
import MultiSlider from '@ptomasroos/react-native-multi-slider';
import get from 'lodash/get';
import styles from './scaleSliderStyles';
export default class ScaleSliderView extends Component {
constructor(props) {
super(props);
this.state = {
activeValue: get(props, 'activeValue') || props.values[0],
activeIndex: get(props, 'values', '').indexOf(get(props, 'activeValue')) || 0,
};
}
_renderMarker = () => <View style={styles.marker} />;
_valueChange = _values => {
const { handleOnValueChange, values } = this.props;
const index = _values[0] - 1;
this.setState({
activeValue: values && values[index],
activeIndex: index,
});
if (handleOnValueChange) handleOnValueChange(values[index]);
};
_renderItem = (value, index, activeIndex) => {
const isActive = index <= activeIndex || index === 0;
return (
<View>
<Text style={[isActive ? styles.active : styles.inactive]}>{value}</Text>
<View style={[isActive ? styles.line : {}]} />
</View>
);
};
_renderScale = () => {
const { values } = this.props;
const { activeIndex } = this.state;
const items = [];
for (let i = 1; i <= values.length; i++) {
items.push(this._renderItem(values[i - 1], i - 1, activeIndex));
}
return items;
};
render() {
const { LRpadding, values } = this.props;
const { activeIndex } = this.state;
return (
<View>
<View style={[styles.column, { marginLeft: LRpadding, marginRight: LRpadding }]}>
{this._renderScale()}
</View>
<View style={styles.container}>
<MultiSlider
trackStyle={styles.track}
selectedStyle={styles.selected}
sliderLength={Dimensions.get('window').width - LRpadding * 2}
onValuesChange={this._valueChange}
values={[activeIndex + 1]}
min={1}
max={values && values.length}
step={1}
allowOverlap={false}
customMarker={this._renderMarker}
snapped
/>
</View>
</View>
);
}
}

View File

@ -0,0 +1,19 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
optionsWrapper: {
backgroundColor: '$white',
borderTopWidth: 0,
borderColor: '$black',
left: 0,
position: 'absolute',
right: 0,
top: 50,
zIndex: 999,
flex: 1,
},
input: {
flex: 1,
minHeight: 50,
},
});

View File

@ -2,8 +2,16 @@ import React from 'react';
import { TextInput } from 'react-native';
import { connect } from 'react-redux';
// Styles
import styles from './textInputStyles';
const TextInputView = ({ isDarkTheme, innerRef, ...props }) => (
<TextInput ref={innerRef} keyboardAppearance={isDarkTheme ? 'dark' : 'light'} {...props} />
<TextInput
style={styles.input}
ref={innerRef}
keyboardAppearance={isDarkTheme ? 'dark' : 'light'}
{...props}
/>
);
const mapStateToProps = state => ({

View File

@ -306,5 +306,12 @@
"incoming_funds": "Incoming Funds",
"sc_power_down_error": "Steem connect setWithdrawVestingRoute not implemented yet.",
"estimated_weekly": "Estimated Weekly"
},
"promote": {
"title": "Promote",
"days": "days",
"user": "User",
"permlink": "Permlink",
"information": "Are you sure to transfer to promote?"
}
}

View File

@ -107,3 +107,24 @@ export const POINTS_KEYS = [
type: 30,
},
];
export const PROMOTE_PRICING = [
{ duration: 1, price: 150 },
{ duration: 2, price: 250 },
{ duration: 3, price: 350 },
{ duration: 7, price: 500 },
{ duration: 14, price: 1000 },
];
export const PROMOTE_DAYS = [1, 2, 3, 7, 14];
export const PROMOTE_STATUS_PENDING = 1;
export const PROMOTE_STATUS_SUCCESS = 2;
export const PROMOTE_STATUS_USER_ERR = 3;
export const PROMOTE_STATUS_INSUFFICIENT_ERR = 4;
export const PROMOTE_STATUS_POST_ERR = 5;
export const PROMOTE_STATUS_POST_DUPLICATE = 6;
export const PROMOTE_STATUS_FORMAT_ERR = 7;
export const PROMOTED_POST_STATUS_ON = 1;
export const PROMOTED_POST_STATUS_EXPIRED = 2;
export const PROMOTED_POST_STATUS_DISABLED = 3;

View File

@ -19,6 +19,7 @@ export default {
BOOKMARKS: `Bookmarks${SCREEN_SUFFIX}`,
SEARCH_RESULT: `SearchResult${SCREEN_SUFFIX}`,
TRANSFER: `Transfer${SCREEN_SUFFIX}`,
PROMOTE: `Promote${SCREEN_SUFFIX}`,
},
DRAWER: {
MAIN: `Main${DRAWER_SUFFIX}`,

4
src/containers/index.js Normal file
View File

@ -0,0 +1,4 @@
import PointsContainer from './pointsContainer';
import TransferContainer from './transferContainer';
export { PointsContainer, TransferContainer };

View File

@ -2,19 +2,21 @@ import React, { Component } from 'react';
import { Alert } from 'react-native';
import { connect } from 'react-redux';
import get from 'lodash/get';
import { injectIntl } from 'react-intl';
import { withNavigation } from 'react-navigation';
// Services and Actions
import { getUser, getUserPoints, claim } from '../../../providers/esteem/ePoint';
import { openPinCodeModal } from '../../../redux/actions/applicationActions';
import { getUser, getUserPoints, claim } from '../providers/esteem/ePoint';
import { openPinCodeModal } from '../redux/actions/applicationActions';
import { promote, getAccount } from '../providers/steem/dsteem';
import { getUserDataWithUsername } from '../realm/realm';
import { toastNotification } from '../redux/actions/uiAction';
// Constant
import POINTS from '../../../constants/options/points';
// Component
import PointsView from '../view/pointsView';
import POINTS from '../constants/options/points';
// Constants
import ROUTES from '../../../constants/routeNames';
import ROUTES from '../constants/routeNames';
/*
* Props Name Description Value
@ -60,18 +62,37 @@ class PointsContainer extends Component {
// Component Functions
_handleOnPressTransfer = () => {
_handleOnPressTransfer = index => {
const { dispatch } = this.props;
const { userPoints } = this.state;
const { balance } = this.state;
let navigateTo;
let navigateParams;
switch (Number(index)) {
case 0:
navigateTo = ROUTES.SCREENS.TRANSFER;
navigateParams = {
transferType: 'points',
fundType: 'POINT',
balance,
};
break;
case 1:
navigateTo = ROUTES.SCREENS.PROMOTE;
navigateParams = {
balance,
};
break;
default:
break;
}
dispatch(
openPinCodeModal({
navigateTo: ROUTES.SCREENS.TRANSFER,
navigateParams: {
transferType: 'points',
fundType: 'POINT',
balance: Math.round(get(userPoints, 'points') * 1000) / 1000,
},
navigateTo,
navigateParams,
}),
);
};
@ -90,10 +111,11 @@ class PointsContainer extends Component {
await getUser(username)
.then(userPoints => {
this.setState({ userPoints });
const balance = Math.round(get(userPoints, 'points') * 1000) / 1000;
this.setState({ userPoints, balance });
})
.catch(err => {
Alert.alert(err);
Alert.alert(err.message);
});
await getUserPoints(username)
@ -114,6 +136,17 @@ class PointsContainer extends Component {
});
};
_getUserBalance = async username => {
await getUser(username)
.then(userPoints => {
const balance = Math.round(get(userPoints, 'points') * 1000) / 1000;
return balance;
})
.catch(err => {
Alert.alert(err);
});
};
_claimPoints = async () => {
const { username } = this.props;
@ -135,6 +168,26 @@ class PointsContainer extends Component {
this.setState({ isClaiming: false });
};
_promote = async (duration, permlink, author, user) => {
const { currentAccount, pinCode, dispatch, intl, navigation } = this.props;
this.setState({ isLoading: true });
await promote(user || currentAccount, pinCode, duration, permlink, author)
.then(() => {
this.setState({ isLoading: false });
dispatch(toastNotification(intl.formatMessage({ id: 'alert.successful' })));
navigation.goBack();
})
.catch(error => {
Alert.alert(
`Fetching data from server failed, please try again or notify us at info@esteem.app \n${error.message.substr(
0,
20,
)}`,
);
});
};
render() {
const {
isClaiming,
@ -143,20 +196,31 @@ class PointsContainer extends Component {
refreshing,
userActivities,
userPoints,
balance,
} = this.state;
const { children, accounts, currentAccount } = this.props;
return (
<PointsView
claimPoints={this._claimPoints}
fetchUserActivity={this._fetchuserPointActivities}
isClaiming={isClaiming}
isDarkTheme={isDarkTheme}
isLoading={isLoading}
refreshing={refreshing}
userActivities={userActivities}
userPoints={userPoints}
handleOnPressTransfer={this._handleOnPressTransfer}
/>
children &&
children({
accounts,
currentAccount,
currentAccountName: currentAccount.name,
claimPoints: this._claimPoints,
fetchUserActivity: this._fetchuserPointActivities,
isClaiming,
isDarkTheme,
isLoading,
refreshing,
userActivities,
userPoints,
handleOnPressTransfer: this._handleOnPressTransfer,
balance,
getUserBalance: this._getUserBalance,
promote: this._promote,
getAccount,
getUserDataWithUsername,
})
);
}
}
@ -165,6 +229,9 @@ const mapStateToProps = state => ({
username: state.account.currentAccount.name,
isDarkTheme: state.application.isDarkTheme,
activeBottomTab: state.ui.activeBottomTab,
accounts: state.account.otherAccounts,
currentAccount: state.account.currentAccount,
pinCode: state.account.pin,
});
export default connect(mapStateToProps)(PointsContainer);
export default withNavigation(connect(mapStateToProps)(injectIntl(PointsContainer)));

View File

@ -14,12 +14,12 @@ import {
withdrawVesting,
delegateVestingShares,
setWithdrawVestingRoute,
} from '../../../providers/steem/dsteem';
import { toastNotification } from '../../../redux/actions/uiAction';
import { getUserDataWithUsername } from '../../../realm/realm';
} from '../providers/steem/dsteem';
import { toastNotification } from '../redux/actions/uiAction';
import { getUserDataWithUsername } from '../realm/realm';
// Utils
import { countDecimals } from '../../../utils/number';
import { countDecimals } from '../utils/number';
/*
* Props Name Description Value

View File

@ -22,6 +22,7 @@ import {
Voters,
SearchResult,
Transfer,
Promote,
} from '../screens';
// Components
@ -106,6 +107,12 @@ const stackNavigatior = createStackNavigator(
header: () => null,
},
},
[ROUTES.SCREENS.PROMOTE]: {
screen: RootComponent()(Promote),
navigationOptions: {
header: () => null,
},
},
},
{
headerMode: 'none',

View File

@ -1,12 +1,6 @@
import { Alert } from 'react-native';
import { Client, PrivateKey } from 'dsteem';
import ePointApi from '../../config/ePoint';
// Utils
import { decryptKey } from '../../utils/crypto';
// const client = new Client(getItem('server', 'https://api.steemit.com'));
export const userActivity = (us, ty, bl = '', tx = '') =>
new Promise(resolve => {
const params = { us, ty };

View File

@ -226,6 +226,20 @@ export const search = data =>
});
});
export const searchPath = q =>
new Promise((resolve, reject) => {
searchApi
.post('/search-path', {
q,
})
.then(res => {
resolve(res.data);
})
.catch(error => {
reject(error);
});
});
// Schedule
export const schedule = (
user,

View File

@ -1108,6 +1108,60 @@ export const transferPoint = (currentAccount, pinCode, data) => {
return Promise.reject(new Error('Something went wrong!'));
};
export const promote = (currentAccount, pinCode, duration, permlink, author) => {
const pin = getDigitPinCode(pinCode);
const key = getActiveKey(get(currentAccount, 'local'), pin);
if (key) {
const privateKey = PrivateKey.fromString(key);
const user = get(currentAccount, 'name');
const json = {
id: 'esteem_promote',
json: JSON.stringify({
user,
author,
permlink,
duration,
}),
required_auths: [user],
required_posting_auths: [],
};
return client.broadcast.json(json, privateKey);
}
return Promise.reject(new Error('Something went wrong!'));
};
export const boost = (currentAccount, pinCode, point, permlink, author) => {
const pin = getDigitPinCode(pinCode);
const key = getActiveKey(get(currentAccount, 'local'), pin);
if (key) {
const privateKey = PrivateKey.fromString(key);
const user = get(currentAccount, 'name');
const json = {
id: 'esteem_boost',
json: JSON.stringify({
user,
author,
permlink,
amount: `${point} POINT`,
}),
required_auths: [user],
required_posting_auths: [],
};
return client.broadcast.json(json, privateKey);
}
return Promise.reject(new Error('Something went wrong!'));
};
// HELPERS
const getAnyPrivateKey = (local, pin) => {
const { postingKey, activeKey } = local;

View File

@ -16,6 +16,7 @@ import RootComponent from './root';
import SteemConnect from './steem-connect/steemConnect';
import { SearchResult } from './searchResult';
import Transfer from './transfer';
import Promote from './promote/screen/promoteScreen';
export {
Bookmarks,
@ -25,15 +26,16 @@ export {
Home,
Launch,
Login,
Points,
Notification,
PinCode,
Points,
Post,
Profile,
Promote,
RootComponent,
SearchResult,
Settings,
SteemConnect,
Voters,
SearchResult,
Transfer,
Voters,
};

View File

@ -1,7 +1,9 @@
import React, { PureComponent } from 'react';
import { injectIntl } from 'react-intl';
import { View } from 'react-native';
// Constants
// Containers
import { PointsContainer } from '../../../containers';
// Components
import { Header } from '../../../components/header';
@ -33,7 +35,31 @@ class PointsScreen extends PureComponent {
<View style={styles.container}>
<Header />
{isLoggedIn ? (
<Points />
<PointsContainer>
{({
handleOnPressTransfer,
claimPoints,
fetchUserActivity,
isClaiming,
isDarkTheme,
isLoading,
refreshing,
userActivities,
userPoints,
}) => (
<Points
claimPoints={claimPoints}
fetchUserActivity={fetchUserActivity}
isClaiming={isClaiming}
isDarkTheme={isDarkTheme}
isLoading={isLoading}
refreshing={refreshing}
userActivities={userActivities}
userPoints={userPoints}
handleOnPressTransfer={handleOnPressTransfer}
/>
)}
</PointsContainer>
) : (
<NoPost
style={styles.noPostContainer}

View File

@ -0,0 +1,282 @@
import React, { PureComponent, Fragment } from 'react';
import { injectIntl } from 'react-intl';
import { Text, View, WebView, ScrollView, TouchableOpacity, Alert } from 'react-native';
import get from 'lodash/get';
import ActionSheet from 'react-native-actionsheet';
import Autocomplete from 'react-native-autocomplete-input';
import { ScaleSlider, TextInput } from '../../../components';
import { steemConnectOptions } from '../../../constants/steemConnectOptions';
// Container
import { PointsContainer } from '../../../containers';
// Services and Actions
import { getUser } from '../../../providers/esteem/ePoint';
import { searchPath } from '../../../providers/esteem/esteem';
// Components
import { BasicHeader } from '../../../components/basicHeader';
import { TransferFormItem } from '../../../components/transferFormItem';
import { MainButton } from '../../../components/mainButton';
import { DropdownButton } from '../../../components/dropdownButton';
import { Modal } from '../../../components/modal';
import { PROMOTE_PRICING, PROMOTE_DAYS } from '../../../constants/options/points';
// Styles
import styles from './promoteStyles';
class PointsScreen extends PureComponent {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
this.state = {
permlink: '',
selectedUser: '',
balance: '',
day: 1,
isSCModalOpen: false,
SCPath: '',
permlinkSuggestions: [],
};
this.startActionSheet = React.createRef();
}
// Component Life Cycles
// Component Functions
_handleOnPermlinkChange = async text => {
searchPath(text).then(res => {
this.setState({ permlinkSuggestions: res && res.length > 10 ? res.slice(0, 7) : res });
});
if (!text || (text && text.length < 1)) this.setState({ permlinkSuggestions: [] });
this.setState({ permlink: text });
};
_renderDescription = text => <Text style={styles.description}>{text}</Text>;
_renderDropdown = (accounts, currentAccountName) => (
<DropdownButton
dropdownButtonStyle={styles.dropdownButtonStyle}
rowTextStyle={styles.rowTextStyle}
style={styles.dropdown}
dropdownStyle={styles.dropdownStyle}
textStyle={styles.dropdownText}
options={accounts.map(item => item.username)}
defaultText={currentAccountName}
selectedOptionIndex={accounts.findIndex(item => item.username === currentAccountName)}
onSelect={(index, value) => {
this.setState({ selectedUser: value });
this._getUserBalance(value);
}}
/>
);
_getUserBalance = async username => {
await getUser(username)
.then(userPoints => {
const balance = Math.round(get(userPoints, 'points') * 1000) / 1000;
this.setState({ balance });
})
.catch(err => {
Alert.alert(err);
});
};
_promote = async (promote, currentAccount, getUserDataWithUsername) => {
const { day, permlink, selectedUser } = this.state;
let _author;
let _permlink;
const seperatedPermlink = permlink.split('/');
if (seperatedPermlink && seperatedPermlink.length > 0) {
_author = seperatedPermlink[0];
_permlink = seperatedPermlink[1];
}
if (get(currentAccount, 'local.authType') === 'steemConnect') {
// const user = selectedUser;
const json = JSON.stringify({
user: selectedUser,
_author,
_permlink,
duration: day,
});
const uri = `sign/custom-json?authority=active&required_auths=%5B%22${selectedUser}%22%5D&required_posting_auths=%5B%5D&id=esteem_promote&json=${encodeURIComponent(
json,
)}`;
this.setState({
isSCModalOpen: true,
SCPath: uri,
});
} else if (promote) {
let userFromRealm;
if (selectedUser) {
userFromRealm = await getUserDataWithUsername(selectedUser);
}
const user = userFromRealm
? {
name: selectedUser,
local: userFromRealm[0],
}
: currentAccount;
promote(day, _permlink, _author, user);
}
};
render() {
const { intl } = this.props;
const {
selectedUser,
balance,
day,
SCPath,
isSCModalOpen,
permlinkSuggestions,
permlink,
} = this.state;
return (
<PointsContainer>
{({
isLoading,
accounts,
currentAccountName,
balance: _balance,
promote,
currentAccount,
getUserDataWithUsername,
}) => (
<Fragment>
<BasicHeader title={intl.formatMessage({ id: 'promote.title' })} />
<View style={styles.container}>
<ScrollView>
<View style={styles.middleContent}>
<TransferFormItem
label={intl.formatMessage({ id: 'promote.user' })}
rightComponent={() =>
this._renderDropdown(accounts, selectedUser || currentAccountName)
}
/>
<Text style={styles.balanceText}>{`${balance || _balance} eSteem Points`}</Text>
<Fragment>
<View style={styles.autocomplateLineContainer}>
<View style={styles.autocomplateLabelContainer}>
{
<Text style={styles.autocomplateLabelText}>
{intl.formatMessage({ id: 'promote.permlink' })}
</Text>
}
</View>
<Autocomplete
autoCapitalize="none"
autoCorrect={false}
inputContainerStyle={styles.autocomplate}
data={permlinkSuggestions}
listContainerStyle={styles.autocomplateListContainer}
listStyle={styles.autocomplateList}
onChangeText={text => this._handleOnPermlinkChange(text)}
renderTextInput={() => (
<TextInput
style={styles.input}
onChangeText={text => this._handleOnPermlinkChange(text)}
value={permlink}
placeholder={intl.formatMessage({ id: 'promote.permlink' })}
placeholderTextColor="#c1c5c7"
autoCapitalize="none"
/>
)}
renderItem={({ item }) => (
<TouchableOpacity
key={item}
onPress={() =>
this.setState({ permlink: item, permlinkSuggestions: [] })
}
>
<Text style={styles.autocomplateItemText}>{item}</Text>
</TouchableOpacity>
)}
/>
</View>
</Fragment>
<View style={styles.total}>
<Text style={styles.day}>
{`${day} ${intl.formatMessage({
id: 'promote.days',
})} `}
</Text>
<Text style={styles.price}>
{`${get(PROMOTE_PRICING[PROMOTE_DAYS.indexOf(day)], 'price')} eSteem points`}
</Text>
</View>
<ScaleSlider
values={[1, 2, 3, 7, 14]}
LRpadding={50}
activeValue={day}
handleOnValueChange={day => this.setState({ day })}
single
/>
</View>
<View style={styles.bottomContent}>
<MainButton
style={styles.button}
isDisable={isLoading}
onPress={() => this.startActionSheet.current.show()}
isLoading={isLoading}
>
<Text style={styles.buttonText}>
{intl.formatMessage({ id: 'transfer.next' })}
</Text>
</MainButton>
</View>
</ScrollView>
</View>
<ActionSheet
ref={this.startActionSheet}
options={[
intl.formatMessage({ id: 'alert.confirm' }),
intl.formatMessage({ id: 'alert.cancel' }),
]}
title={intl.formatMessage({ id: 'promote.information' })}
cancelButtonIndex={1}
destructiveButtonIndex={0}
onPress={index => {
index === 0
? this._promote(promote, currentAccount, getUserDataWithUsername)
: null;
}}
/>
<Modal
isOpen={isSCModalOpen}
isFullScreen
isCloseButton
handleOnModalClose={() => this.setState({ isSCModalOpen: false })}
title={intl.formatMessage({ id: 'transfer.steemconnect_title' })}
>
<WebView source={{ uri: `${steemConnectOptions.base_url}${SCPath}` }} />
</Modal>
</Fragment>
)}
</PointsContainer>
);
}
}
export default injectIntl(PointsScreen);

View File

@ -0,0 +1,162 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
backgroundColor: '$primaryBackgroundColor',
justifyContent: 'center',
},
balanceText: {
fontSize: 14,
color: '$primaryDarkGray',
alignSelf: 'center',
marginLeft: 70,
marginBottom: 10,
},
topContent: {
flexDirection: 'row',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
middleContent: {
flex: 3,
justifyContent: 'center',
},
bottomContent: {
flex: 2,
justifyContent: 'center',
alignItems: 'center',
zIndex: -1,
},
input: {
borderWidth: 1,
borderColor: '$borderColor',
borderRadius: 8,
padding: 10,
color: '$primaryBlack',
width: 172,
},
autocomplate: {
borderWidth: 0,
borderColor: '$borderColor',
borderRadius: 8,
padding: 2,
color: '$primaryBlack',
width: 172,
marginRight: 33,
},
autocomplateLineContainer: {
flexDirection: 'row',
paddingHorizontal: 20,
zIndex: 999,
},
autocomplateLabelText: {
color: '$primaryBlack',
fontWeight: '600',
},
autocomplateListContainer: {
backgroundColor: '$primaryWhiteLightBackground',
width: 172,
zIndex: 999,
},
autocomplateItemText: {
color: '$primaryBlack',
padding: 3,
},
autocomplateList: {
zIndex: 999,
backgroundColor: '$primaryWhiteLightBackground',
},
autocomplateLabelContainer: {
flex: 1,
padding: 10,
justifyContent: 'center',
color: '$primaryBlack',
},
textarea: {
borderWidth: 1,
borderColor: '$borderColor',
borderRadius: 8,
padding: 10,
color: '$primaryBlack',
width: 172,
height: 75,
},
description: {
color: '$iconColor',
},
button: {
width: '$deviceWidth / 3',
marginTop: 30,
justifyContent: 'center',
alignItems: 'center',
},
buttonText: {
color: 'white',
},
icon: {
fontSize: 40,
color: '$iconColor',
marginHorizontal: 20,
},
rowTextStyle: {
fontSize: 12,
color: '$primaryDarkGray',
padding: 5,
},
dropdownText: {
fontSize: 14,
paddingLeft: 16,
paddingHorizontal: 14,
color: '$primaryDarkGray',
},
dropdownStyle: {
marginTop: 15,
minWidth: 192,
width: 192,
maxHeight: '$deviceHeight - 200',
},
dropdownButtonStyle: {
borderColor: '$borderColor',
borderWidth: 1,
height: 44,
width: 172,
borderRadius: 8,
marginHorizontal: 2,
},
dropdown: {
flexGrow: 1,
width: 150,
},
slider: {
flex: 1,
marginHorizontal: 30,
},
amountText: {
color: '$primaryBlue',
},
iconButton: {
borderColor: 'red',
borderWidth: 1,
width: 25,
height: 25,
borderRadius: 5,
},
total: {
marginVertical: 15,
flexDirection: 'row',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
day: {
fontSize: 22,
color: '$primaryBlue',
fontWeight: 'bold',
},
price: {
fontSize: 15,
color: '$primaryBlue',
},
});

View File

@ -1,6 +1,6 @@
import React from 'react';
import TransferContainer from './container/transferContainer';
import { TransferContainer } from '../../containers';
import TransferView from './screen/transferScreen';
import PowerDownView from './screen/powerDownScreen';

View File

@ -16,6 +16,7 @@ import { Icon } from '../../../components/icon';
import { Modal } from '../../../components/modal';
import styles from './transferStyles';
/* Props
* ------------------------------------------------
* @prop { type } name - Description....

View File

@ -1256,6 +1256,11 @@
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^12.0.9"
"@ptomasroos/react-native-multi-slider@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@ptomasroos/react-native-multi-slider/-/react-native-multi-slider-1.0.0.tgz#a4ea27b1320b93a1db9f696c24789695df6c9f30"
integrity sha512-NpX22rQLArg9widwMzGf7XsInTDf6mfY/D1XaDVjglNkVphj3NSN37+nF6MofArCxC++1P+jHv0SGWbmJQwy4g==
"@react-native-community/cli@^1.2.1":
version "1.9.11"
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-1.9.11.tgz#b868b17201057b9cd16a3a20c30561176071f21a"
@ -7487,6 +7492,11 @@ react-native-actionsheet@^2.4.2:
resolved "https://registry.yarnpkg.com/react-native-actionsheet/-/react-native-actionsheet-2.4.2.tgz#6a00dd51a75ef2c8974312130e405af73191500f"
integrity sha512-DBoWIvVwuWXuptF4t46pBqkFxaUxS+rsIdHiA05t0n4BdTIDV2R4s9bLEUVOGzb94D7VxIamsXZPA/3mmw+SXg==
react-native-autocomplete-input@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/react-native-autocomplete-input/-/react-native-autocomplete-input-4.1.0.tgz#979ece28d891b245ecb967b6d31f1f924445b8ab"
integrity sha512-Yn4GulZ9F6tde74UUGZHdVFeYWVuL7+EbUZy6kt+QHrzMc5B4OuRop1FT4RyWLpvbySW/vvqYgj9LAmlzkuEqA==
react-native-code-push@esteemapp/react-native-code-push:
version "1000.0.0-beta"
resolved "https://codeload.github.com/esteemapp/react-native-code-push/tar.gz/c07b7023c1212dc5d9231a0526a869d2501cb221"