mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-22 04:41:43 +03:00
Merge pull request #1146 from esteemapp/feature/profile-edit
Feature/profile edit
This commit is contained in:
commit
43aacb970e
46
src/components/avatarHeader/avatarHeaderStyles.js
Normal file
46
src/components/avatarHeader/avatarHeaderStyles.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||||
|
|
||||||
|
export default EStyleSheet.create({
|
||||||
|
headerContainer: {
|
||||||
|
height: 100,
|
||||||
|
flexDirection: 'row',
|
||||||
|
padding: 21,
|
||||||
|
},
|
||||||
|
backIcon: {
|
||||||
|
color: '$white',
|
||||||
|
},
|
||||||
|
wrapper: {
|
||||||
|
marginLeft: 16,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
textWrapper: {
|
||||||
|
marginLeft: 16,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
color: '$white',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
color: '$white',
|
||||||
|
fontSize: 12,
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
|
addIcon: {
|
||||||
|
color: '$white',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
addButton: {
|
||||||
|
backgroundColor: '$iconColor',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
borderRadius: 20 / 2,
|
||||||
|
borderColor: '$white',
|
||||||
|
borderWidth: 1,
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
left: 45,
|
||||||
|
},
|
||||||
|
});
|
59
src/components/avatarHeader/avatarHeaderView.js
Normal file
59
src/components/avatarHeader/avatarHeaderView.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { withNavigation } from 'react-navigation';
|
||||||
|
import { View, Text } from 'react-native';
|
||||||
|
import LinearGradient from 'react-native-linear-gradient';
|
||||||
|
|
||||||
|
import { UserAvatar } from '../userAvatar';
|
||||||
|
import { IconButton } from '../iconButton';
|
||||||
|
|
||||||
|
// Styles
|
||||||
|
import styles from './avatarHeaderStyles';
|
||||||
|
|
||||||
|
const AvatarHeader = ({
|
||||||
|
username,
|
||||||
|
name,
|
||||||
|
reputation,
|
||||||
|
navigation,
|
||||||
|
avatarUrl,
|
||||||
|
showImageUploadActions,
|
||||||
|
}) => (
|
||||||
|
<LinearGradient
|
||||||
|
start={{ x: 0, y: 0 }}
|
||||||
|
end={{ x: 1, y: 0 }}
|
||||||
|
colors={['#357ce6', '#2d5aa0']}
|
||||||
|
style={styles.headerView}
|
||||||
|
>
|
||||||
|
<View style={styles.headerContainer}>
|
||||||
|
<IconButton
|
||||||
|
iconStyle={styles.backIcon}
|
||||||
|
iconType="MaterialIcons"
|
||||||
|
name="arrow-back"
|
||||||
|
onPress={navigation.goBack}
|
||||||
|
size={25}
|
||||||
|
/>
|
||||||
|
<View style={styles.wrapper}>
|
||||||
|
<UserAvatar
|
||||||
|
key={avatarUrl || username}
|
||||||
|
noAction
|
||||||
|
size="xl"
|
||||||
|
username={username}
|
||||||
|
avatarUrl={avatarUrl}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
iconStyle={styles.addIcon}
|
||||||
|
style={styles.addButton}
|
||||||
|
iconType="MaterialCommunityIcons"
|
||||||
|
name="plus"
|
||||||
|
onPress={showImageUploadActions}
|
||||||
|
size={15}
|
||||||
|
/>
|
||||||
|
<View style={styles.textWrapper}>
|
||||||
|
{!!name && <Text style={styles.name}>{name}</Text>}
|
||||||
|
<Text style={styles.username}>{`@${username} (${reputation})`}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</LinearGradient>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default withNavigation(AvatarHeader);
|
3
src/components/avatarHeader/index.js
Normal file
3
src/components/avatarHeader/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import AvatarHeader from './avatarHeaderView';
|
||||||
|
|
||||||
|
export { AvatarHeader };
|
@ -100,7 +100,7 @@ class BasicHeaderView extends Component {
|
|||||||
<IconButton
|
<IconButton
|
||||||
iconStyle={[styles.backIcon, isModalHeader && styles.closeIcon]}
|
iconStyle={[styles.backIcon, isModalHeader && styles.closeIcon]}
|
||||||
iconType="MaterialIcons"
|
iconType="MaterialIcons"
|
||||||
name={isModalHeader ? 'arrow-back' : 'arrow-back'}
|
name="arrow-back"
|
||||||
onPress={() => (isModalHeader ? handleOnPressClose() : handleOnPressBackButton())}
|
onPress={() => (isModalHeader ? handleOnPressClose() : handleOnPressBackButton())}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
|
@ -4,8 +4,7 @@ export default EStyleSheet.create({
|
|||||||
wrapper: {
|
wrapper: {
|
||||||
borderTopLeftRadius: 8,
|
borderTopLeftRadius: 8,
|
||||||
borderTopRightRadius: 8,
|
borderTopRightRadius: 8,
|
||||||
marginHorizontal: 30,
|
marginTop: 16,
|
||||||
marginVertical: 10,
|
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
backgroundColor: '$primaryGray',
|
backgroundColor: '$primaryGray',
|
||||||
height: 60,
|
height: 60,
|
||||||
@ -21,7 +20,6 @@ export default EStyleSheet.create({
|
|||||||
textInput: {
|
textInput: {
|
||||||
flex: 0.7,
|
flex: 0.7,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
flex: 0.15,
|
flex: 0.15,
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import FastImage from 'react-native-fast-image';
|
import FastImage from 'react-native-fast-image';
|
||||||
import { Icon } from '../../icon';
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { TextInput } from '../../textInput';
|
import { TextInput } from '../../textInput';
|
||||||
|
import { Icon } from '../../icon';
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
import styles from './formInputStyles';
|
import styles from './formInputStyles';
|
||||||
|
|
||||||
@ -19,28 +18,18 @@ class FormInputView extends Component {
|
|||||||
* @prop { boolean } isEditable - Can permission edit.
|
* @prop { boolean } isEditable - Can permission edit.
|
||||||
* @prop { boolean } isValid - This delegate input valit or not.
|
* @prop { boolean } isValid - This delegate input valit or not.
|
||||||
* @prop { boolean } secureTextEntry - For hiding password value.
|
* @prop { boolean } secureTextEntry - For hiding password value.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
value: '',
|
value: props.value || '',
|
||||||
inputBorderColor: '#c1c5c7',
|
inputBorderColor: '#e7e7e7',
|
||||||
isValid: true,
|
isValid: true,
|
||||||
formInputWidth: '99%',
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component Life Cycles
|
// Component Life Cycles
|
||||||
componentWillMount() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.setState({ formInputWidth: '100%' });
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const { isValid } = this.props;
|
const { isValid } = this.props;
|
||||||
|
|
||||||
@ -54,18 +43,15 @@ class FormInputView extends Component {
|
|||||||
const { onChange } = this.props;
|
const { onChange } = this.props;
|
||||||
|
|
||||||
this.setState({ value });
|
this.setState({ value });
|
||||||
onChange && onChange(value);
|
if (onChange) onChange(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleOnFocus = () => {
|
_handleOnFocus = () => {
|
||||||
const { inputBorderColor } = this.state;
|
|
||||||
if (inputBorderColor !== '#357ce6') {
|
|
||||||
this.setState({ inputBorderColor: '#357ce6' });
|
this.setState({ inputBorderColor: '#357ce6' });
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { inputBorderColor, isValid, value, formInputWidth } = this.state;
|
const { inputBorderColor, isValid, value } = this.state;
|
||||||
const {
|
const {
|
||||||
placeholder,
|
placeholder,
|
||||||
type,
|
type,
|
||||||
@ -75,6 +61,9 @@ class FormInputView extends Component {
|
|||||||
rightIconName,
|
rightIconName,
|
||||||
secureTextEntry,
|
secureTextEntry,
|
||||||
iconType,
|
iconType,
|
||||||
|
wrapperStyle,
|
||||||
|
height,
|
||||||
|
inputStyle,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
@ -83,6 +72,7 @@ class FormInputView extends Component {
|
|||||||
{
|
{
|
||||||
borderBottomColor: isValid ? inputBorderColor : 'red',
|
borderBottomColor: isValid ? inputBorderColor : 'red',
|
||||||
},
|
},
|
||||||
|
wrapperStyle,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{isFirstImage && value && value.length > 2 ? (
|
{isFirstImage && value && value.length > 2 ? (
|
||||||
@ -97,19 +87,23 @@ class FormInputView extends Component {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
|
rightIconName && (
|
||||||
<Icon iconType={iconType || 'MaterialIcons'} name={rightIconName} style={styles.icon} />
|
<Icon iconType={iconType || 'MaterialIcons'} name={rightIconName} style={styles.icon} />
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
<View style={styles.textInput}>
|
<View style={styles.textInput}>
|
||||||
<TextInput
|
<TextInput
|
||||||
onFocus={() => this._handleOnFocus()}
|
style={inputStyle}
|
||||||
|
onFocus={() => this.setState({ inputBorderColor: '#357ce6' })}
|
||||||
|
onBlur={() => this.setState({ inputBorderColor: '#e7e7e7' })}
|
||||||
autoCapitalize="none"
|
autoCapitalize="none"
|
||||||
secureTextEntry={secureTextEntry}
|
secureTextEntry={secureTextEntry}
|
||||||
|
height={height}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
editable={isEditable || true}
|
editable={isEditable || true}
|
||||||
textContentType={type}
|
textContentType={type}
|
||||||
onChangeText={val => this._handleOnChange(val)}
|
onChangeText={this._handleOnChange}
|
||||||
value={value}
|
value={value}
|
||||||
style={{ width: formInputWidth }}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { withNavigation } from 'react-navigation';
|
import { withNavigation } from 'react-navigation';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { get, has } from 'lodash';
|
||||||
// Services and Actions
|
|
||||||
|
|
||||||
// Middleware
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
|
|
||||||
// Component
|
// Component
|
||||||
import HeaderView from '../view/headerView';
|
import HeaderView from '../view/headerView';
|
||||||
@ -30,7 +25,7 @@ class HeaderContainer extends PureComponent {
|
|||||||
_handleOpenDrawer = () => {
|
_handleOpenDrawer = () => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
|
|
||||||
if (navigation && navigation.openDrawer && typeof navigation.openDrawer === 'function') {
|
if (has(navigation, 'openDrawer') && typeof get(navigation, 'openDrawer') === 'function') {
|
||||||
navigation.openDrawer();
|
navigation.openDrawer();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -52,19 +47,11 @@ class HeaderContainer extends PureComponent {
|
|||||||
isLoginDone,
|
isLoginDone,
|
||||||
isDarkTheme,
|
isDarkTheme,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let displayName;
|
const _user = isReverse && selectedUser ? selectedUser : currentAccount;
|
||||||
let username;
|
|
||||||
let reputation;
|
|
||||||
|
|
||||||
if (isReverse && selectedUser) {
|
const displayName = get(_user, 'display_name');
|
||||||
displayName = selectedUser.display_name;
|
const username = get(_user, 'name');
|
||||||
username = selectedUser.name;
|
const reputation = get(_user, 'reputation');
|
||||||
reputation = selectedUser.reputation;
|
|
||||||
} else if (!isReverse) {
|
|
||||||
displayName = currentAccount.display_name;
|
|
||||||
username = currentAccount.name;
|
|
||||||
reputation = currentAccount.reputation;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderView
|
<HeaderView
|
||||||
|
@ -34,19 +34,20 @@ class HeaderView extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
|
avatarUrl,
|
||||||
displayName,
|
displayName,
|
||||||
handleOnPressBackButton,
|
handleOnPressBackButton,
|
||||||
handleOpenDrawer,
|
handleOpenDrawer,
|
||||||
intl,
|
intl,
|
||||||
|
isDarkTheme,
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
isLoginDone,
|
isLoginDone,
|
||||||
isReverse,
|
isReverse,
|
||||||
reputation,
|
reputation,
|
||||||
username,
|
username,
|
||||||
isDarkTheme,
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { isSearchModalOpen } = this.state;
|
const { isSearchModalOpen } = this.state;
|
||||||
let gredientColor = isDarkTheme ? ['#081c36', '#43638e'] : ['#2d5aa0', '#357ce6'];
|
let gredientColor;
|
||||||
|
|
||||||
if (isReverse) {
|
if (isReverse) {
|
||||||
gredientColor = isDarkTheme ? ['#43638e', '#081c36'] : ['#357ce6', '#2d5aa0'];
|
gredientColor = isDarkTheme ? ['#43638e', '#081c36'] : ['#357ce6', '#2d5aa0'];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import { TouchableHighlight } from 'react-native';
|
import { TouchableHighlight, ActivityIndicator } from 'react-native';
|
||||||
import { Icon } from '../../icon';
|
import { Icon } from '../../icon';
|
||||||
|
|
||||||
import styles from './iconButtonStyles';
|
import styles from './iconButtonStyles';
|
||||||
@ -22,14 +22,16 @@ const IconButton = ({
|
|||||||
onPress,
|
onPress,
|
||||||
size,
|
size,
|
||||||
style,
|
style,
|
||||||
|
isLoading,
|
||||||
}) => (
|
}) => (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<TouchableHighlight
|
<TouchableHighlight
|
||||||
style={[styles.iconButton, style]}
|
style={[styles.iconButton, style]}
|
||||||
onPress={() => onPress && onPress()}
|
onPress={() => !isLoading && onPress && onPress()}
|
||||||
underlayColor={backgroundColor || 'white'}
|
underlayColor={backgroundColor || 'white'}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
|
{!isLoading ? (
|
||||||
<Icon
|
<Icon
|
||||||
style={[
|
style={[
|
||||||
color && { color },
|
color && { color },
|
||||||
@ -44,6 +46,9 @@ const IconButton = ({
|
|||||||
iconType={iconType}
|
iconType={iconType}
|
||||||
badgeCount={badgeCount}
|
badgeCount={badgeCount}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<ActivityIndicator color="white" style={styles.activityIndicator} />
|
||||||
|
)}
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -3,15 +3,16 @@ import { FormInput } from './formInput';
|
|||||||
import { NumericKeyboard } from './numericKeyboard';
|
import { NumericKeyboard } from './numericKeyboard';
|
||||||
import { PinAnimatedInput } from './pinAnimatedInput';
|
import { PinAnimatedInput } from './pinAnimatedInput';
|
||||||
import { SideMenu } from './sideMenu';
|
import { SideMenu } from './sideMenu';
|
||||||
|
import { TextInput } from './textInput';
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
import Logo from './logo/logo';
|
import Logo from './logo/logo';
|
||||||
import Modal from './modal';
|
import Modal from './modal';
|
||||||
import { TextInput } from './textInput';
|
import PostBoost from './postBoost/postBoostView';
|
||||||
|
import PostButton from './postButton/postButtonView';
|
||||||
|
import ProfileEditForm from './profileEditForm/profileEditFormView';
|
||||||
|
import Promote from './promote/promoteView';
|
||||||
import ScaleSlider from './scaleSlider/scaleSliderView';
|
import ScaleSlider from './scaleSlider/scaleSliderView';
|
||||||
import UserListItem from './basicUIElements/view/userListItem/userListItem';
|
import UserListItem from './basicUIElements/view/userListItem/userListItem';
|
||||||
import PostButton from './postButton/postButtonView';
|
|
||||||
import Promote from './promote/promoteView';
|
|
||||||
import PostBoost from './postBoost/postBoostView';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
CircularButton,
|
CircularButton,
|
||||||
@ -22,12 +23,13 @@ export {
|
|||||||
Modal,
|
Modal,
|
||||||
NumericKeyboard,
|
NumericKeyboard,
|
||||||
PinAnimatedInput,
|
PinAnimatedInput,
|
||||||
|
PostButton,
|
||||||
|
ProfileEditForm,
|
||||||
ScaleSlider,
|
ScaleSlider,
|
||||||
SideMenu,
|
SideMenu,
|
||||||
TextButton,
|
TextButton,
|
||||||
TextInput,
|
TextInput,
|
||||||
UserListItem,
|
UserListItem,
|
||||||
PostButton,
|
|
||||||
Promote,
|
Promote,
|
||||||
PostBoost,
|
PostBoost,
|
||||||
};
|
};
|
||||||
|
71
src/components/profileEditForm/profileEditFormStyles.js
Normal file
71
src/components/profileEditForm/profileEditFormStyles.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||||
|
|
||||||
|
export default EStyleSheet.create({
|
||||||
|
container: {
|
||||||
|
paddingHorizontal: 32,
|
||||||
|
paddingVertical: 16,
|
||||||
|
backgroundColor: '$primaryBackgroundColor',
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
formStyle: {
|
||||||
|
backgroundColor: '$white',
|
||||||
|
height: 30,
|
||||||
|
marginTop: 8,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '$primaryDarkText',
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
formItem: {
|
||||||
|
marginBottom: 24,
|
||||||
|
},
|
||||||
|
coverImg: {
|
||||||
|
borderRadius: 5,
|
||||||
|
height: 60,
|
||||||
|
marginBottom: 12,
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
backgroundColor: '#296CC0',
|
||||||
|
},
|
||||||
|
coverImageWrapper: {},
|
||||||
|
addIcon: {
|
||||||
|
color: '$white',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
addButton: {
|
||||||
|
backgroundColor: '$iconColor',
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
borderRadius: 20 / 2,
|
||||||
|
borderColor: '$white',
|
||||||
|
borderWidth: 1,
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
right: 10,
|
||||||
|
},
|
||||||
|
|
||||||
|
saveButton: {
|
||||||
|
backgroundColor: '$primaryBlue',
|
||||||
|
width: 55,
|
||||||
|
height: 55,
|
||||||
|
borderRadius: 55 / 2,
|
||||||
|
position: 'absolute',
|
||||||
|
top: -25,
|
||||||
|
right: 10,
|
||||||
|
zIndex: 999,
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: '$white',
|
||||||
|
},
|
||||||
|
saveIcon: {
|
||||||
|
color: '$white',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
|
||||||
|
input: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '$primaryDarkText',
|
||||||
|
alignSelf: 'flex-start',
|
||||||
|
width: '100%',
|
||||||
|
height: 30,
|
||||||
|
},
|
||||||
|
});
|
88
src/components/profileEditForm/profileEditFormView.js
Normal file
88
src/components/profileEditForm/profileEditFormView.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { withNavigation } from 'react-navigation';
|
||||||
|
import { View, TouchableOpacity, Image, Text, Platform } from 'react-native';
|
||||||
|
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
|
||||||
|
import { injectIntl } from 'react-intl';
|
||||||
|
|
||||||
|
// Images
|
||||||
|
import LIGHT_COVER_IMAGE from '../../assets/default_cover_image.png';
|
||||||
|
import DARK_COVER_IMAGE from '../../assets/dark_cover_image.png';
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import { FormInput } from '../formInput';
|
||||||
|
import { IconButton } from '../iconButton';
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
import { getResizedImage } from '../../utils/image';
|
||||||
|
|
||||||
|
// Styles
|
||||||
|
import styles from './profileEditFormStyles';
|
||||||
|
|
||||||
|
const ProfileEditFormView = ({
|
||||||
|
avatarUrl,
|
||||||
|
coverUrl,
|
||||||
|
formData,
|
||||||
|
handleOnItemChange,
|
||||||
|
handleOnSubmit,
|
||||||
|
intl,
|
||||||
|
isDarkTheme,
|
||||||
|
isLoading,
|
||||||
|
showImageUploadActions,
|
||||||
|
...props
|
||||||
|
}) => (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<IconButton
|
||||||
|
iconStyle={styles.saveIcon}
|
||||||
|
style={styles.saveButton}
|
||||||
|
iconType="MaterialIcons"
|
||||||
|
name="save"
|
||||||
|
onPress={handleOnSubmit}
|
||||||
|
size={30}
|
||||||
|
isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
<KeyboardAwareScrollView
|
||||||
|
enableAutoAutomaticScroll={Platform.OS === 'ios'}
|
||||||
|
contentContainerStyle={{ flexGrow: 1 }}
|
||||||
|
>
|
||||||
|
<TouchableOpacity style={styles.coverImgWrapper} onPress={showImageUploadActions}>
|
||||||
|
<Image
|
||||||
|
style={styles.coverImg}
|
||||||
|
source={{ uri: getResizedImage(coverUrl, 400) }}
|
||||||
|
defaultSource={isDarkTheme ? DARK_COVER_IMAGE : LIGHT_COVER_IMAGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
iconStyle={styles.addIcon}
|
||||||
|
style={styles.addButton}
|
||||||
|
iconType="MaterialCommunityIcons"
|
||||||
|
name="plus"
|
||||||
|
onPress={showImageUploadActions}
|
||||||
|
size={15}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
{formData.map(item => (
|
||||||
|
<View style={styles.formItem} key={item.valueKey}>
|
||||||
|
<Text style={styles.label}>
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: `profile.edit.${item.label}`,
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
<FormInput
|
||||||
|
wrapperStyle={styles.formStyle}
|
||||||
|
isValid
|
||||||
|
height={30}
|
||||||
|
onChange={value => handleOnItemChange(value, item.valueKey)}
|
||||||
|
placeholder={item.placeholder}
|
||||||
|
isEditable
|
||||||
|
type="none"
|
||||||
|
value={props[item.valueKey]}
|
||||||
|
inputStyle={styles.input}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</KeyboardAwareScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default injectIntl(withNavigation(ProfileEditFormView));
|
@ -21,6 +21,7 @@ import { DropdownButton } from '../../dropdownButton';
|
|||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { makeCountFriendly } from '../../../utils/formatter';
|
import { makeCountFriendly } from '../../../utils/formatter';
|
||||||
|
import { getResizedImage } from '../../../utils/image';
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
import styles from './profileSummaryStyles';
|
import styles from './profileSummaryStyles';
|
||||||
@ -67,6 +68,7 @@ class ProfileSummaryView extends PureComponent {
|
|||||||
handleFollowUnfollowUser,
|
handleFollowUnfollowUser,
|
||||||
handleOnFavoritePress,
|
handleOnFavoritePress,
|
||||||
handleOnFollowsPress,
|
handleOnFollowsPress,
|
||||||
|
handleOnPressProfileEdit,
|
||||||
handleUIChange,
|
handleUIChange,
|
||||||
hoursRC,
|
hoursRC,
|
||||||
hoursVP,
|
hoursVP,
|
||||||
@ -94,7 +96,7 @@ class ProfileSummaryView extends PureComponent {
|
|||||||
const isColumn = rowLength && DEVICE_WIDTH / rowLength <= 7.3;
|
const isColumn = rowLength && DEVICE_WIDTH / rowLength <= 7.3;
|
||||||
|
|
||||||
const followButtonIcon = !isFollowing ? 'account-plus' : 'account-minus';
|
const followButtonIcon = !isFollowing ? 'account-plus' : 'account-minus';
|
||||||
const coverImageUrl = `https://steemitimages.com/400x0/${coverImage}`;
|
const coverImageUrl = getResizedImage(coverImage, 400);
|
||||||
|
|
||||||
dropdownOpions.push(!isMuted ? 'MUTE' : 'UNMUTE');
|
dropdownOpions.push(!isMuted ? 'MUTE' : 'UNMUTE');
|
||||||
|
|
||||||
@ -184,7 +186,7 @@ class ProfileSummaryView extends PureComponent {
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</View>
|
</View>
|
||||||
{isLoggedIn && !isOwnProfile && (
|
{isLoggedIn && !isOwnProfile ? (
|
||||||
<View style={styles.rightIcons}>
|
<View style={styles.rightIcons}>
|
||||||
<IconButton
|
<IconButton
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
@ -221,6 +223,19 @@ class ProfileSummaryView extends PureComponent {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
) : (
|
||||||
|
isOwnProfile && (
|
||||||
|
<Fragment>
|
||||||
|
<IconButton
|
||||||
|
backgroundColor="transparent"
|
||||||
|
color="#c1c5c7"
|
||||||
|
iconType="MaterialCommunityIcons"
|
||||||
|
name="pencil"
|
||||||
|
onPress={handleOnPressProfileEdit}
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -5,9 +5,9 @@ import { connect } from 'react-redux';
|
|||||||
// Styles
|
// Styles
|
||||||
import styles from './textInputStyles';
|
import styles from './textInputStyles';
|
||||||
|
|
||||||
const TextInputView = ({ isDarkTheme, innerRef, ...props }) => (
|
const TextInputView = ({ isDarkTheme, innerRef, height, ...props }) => (
|
||||||
<TextInput
|
<TextInput
|
||||||
style={styles.input}
|
style={[styles.input, { minHeight: height }]}
|
||||||
ref={innerRef}
|
ref={innerRef}
|
||||||
keyboardAppearance={isDarkTheme ? 'dark' : 'light'}
|
keyboardAppearance={isDarkTheme ? 'dark' : 'light'}
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -26,9 +26,12 @@ class UserAvatarView extends Component {
|
|||||||
|
|
||||||
// Component Functions
|
// Component Functions
|
||||||
_handleOnAvatarPress = username => {
|
_handleOnAvatarPress = username => {
|
||||||
const { dispatch, currentUsername } = this.props;
|
const {
|
||||||
|
dispatch,
|
||||||
|
currentUsername: { name },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const routeName = currentUsername === username ? ROUTES.TABBAR.PROFILE : ROUTES.SCREENS.PROFILE;
|
const routeName = name === username ? ROUTES.TABBAR.PROFILE : ROUTES.SCREENS.PROFILE;
|
||||||
|
|
||||||
const navigateAction = NavigationActions.navigate({
|
const navigateAction = NavigationActions.navigate({
|
||||||
routeName,
|
routeName,
|
||||||
@ -42,11 +45,25 @@ class UserAvatarView extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { username, size, style, disableSize, noAction } = this.props;
|
const {
|
||||||
|
username,
|
||||||
|
size,
|
||||||
|
style,
|
||||||
|
disableSize,
|
||||||
|
noAction,
|
||||||
|
avatarUrl,
|
||||||
|
currentUsername: { name, avatar },
|
||||||
|
} = this.props;
|
||||||
const imageSize = size === 'xl' ? 'large' : 'small';
|
const imageSize = size === 'xl' ? 'large' : 'small';
|
||||||
let _size;
|
let _size;
|
||||||
const _avatar = username
|
const _avatar = username
|
||||||
? { uri: `https://steemitimages.com/u/${username}/avatar/${imageSize}` }
|
? {
|
||||||
|
uri:
|
||||||
|
avatarUrl ||
|
||||||
|
(name === username
|
||||||
|
? avatar
|
||||||
|
: `https://steemitimages.com/u/${username}/avatar/${imageSize}`),
|
||||||
|
}
|
||||||
: DEFAULT_IMAGE;
|
: DEFAULT_IMAGE;
|
||||||
|
|
||||||
if (!disableSize) {
|
if (!disableSize) {
|
||||||
@ -73,7 +90,7 @@ class UserAvatarView extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
currentUsername: state.account.currentAccount.name,
|
currentUsername: state.account.currentAccount,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(UserAvatarView);
|
export default connect(mapStateToProps)(UserAvatarView);
|
||||||
|
@ -97,7 +97,13 @@
|
|||||||
"days": "days",
|
"days": "days",
|
||||||
"day": "day",
|
"day": "day",
|
||||||
"steem_dollars": "Steem Dollars",
|
"steem_dollars": "Steem Dollars",
|
||||||
"savings": "Savings"
|
"savings": "Savings",
|
||||||
|
"edit": {
|
||||||
|
"display_name": "Display Name",
|
||||||
|
"about": "About",
|
||||||
|
"location": "Location",
|
||||||
|
"website": "Website"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
|
@ -15,15 +15,15 @@ export default {
|
|||||||
LOGIN: `Login${SCREEN_SUFFIX}`,
|
LOGIN: `Login${SCREEN_SUFFIX}`,
|
||||||
PINCODE: `PinCode${SCREEN_SUFFIX}`,
|
PINCODE: `PinCode${SCREEN_SUFFIX}`,
|
||||||
POST: `Post${SCREEN_SUFFIX}`,
|
POST: `Post${SCREEN_SUFFIX}`,
|
||||||
|
PROFILE_EDIT: `ProfileEdit${SCREEN_SUFFIX}`,
|
||||||
PROFILE: `Profile${SCREEN_SUFFIX}`,
|
PROFILE: `Profile${SCREEN_SUFFIX}`,
|
||||||
PROMOTE: `Promote${SCREEN_SUFFIX}`,
|
|
||||||
REBLOGS: `Reblogs${SCREEN_SUFFIX}`,
|
REBLOGS: `Reblogs${SCREEN_SUFFIX}`,
|
||||||
|
REDEEM: `Redeem${SCREEN_SUFFIX}`,
|
||||||
SEARCH_RESULT: `SearchResult${SCREEN_SUFFIX}`,
|
SEARCH_RESULT: `SearchResult${SCREEN_SUFFIX}`,
|
||||||
SETTINGS: `Settings${SCREEN_SUFFIX}`,
|
SETTINGS: `Settings${SCREEN_SUFFIX}`,
|
||||||
STEEM_CONNECT: `SteemConnect${SCREEN_SUFFIX}`,
|
STEEM_CONNECT: `SteemConnect${SCREEN_SUFFIX}`,
|
||||||
TRANSFER: `Transfer${SCREEN_SUFFIX}`,
|
TRANSFER: `Transfer${SCREEN_SUFFIX}`,
|
||||||
VOTERS: `Voters${SCREEN_SUFFIX}`,
|
VOTERS: `Voters${SCREEN_SUFFIX}`,
|
||||||
REDEEM: `Redeem${SCREEN_SUFFIX}`,
|
|
||||||
},
|
},
|
||||||
DRAWER: {
|
DRAWER: {
|
||||||
MAIN: `Main${DRAWER_SUFFIX}`,
|
MAIN: `Main${DRAWER_SUFFIX}`,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export const steemConnectOptions = {
|
export const steemConnectOptions = {
|
||||||
base_url: 'https://app.steemconnect.com/',
|
base_url: 'https://app.steemconnect.com/',
|
||||||
client_id: 'esteemapp',
|
client_id: 'esteemapp',
|
||||||
redirect_uri: 'http://127.0.0.1:3415/', // http://127.0.0.1:3415
|
redirect_uri: 'http://127.0.0.1:3415/',
|
||||||
scope: 'vote,comment,delete_comment,comment_options,custom_json,claim_reward_balance,offline',
|
scope:
|
||||||
|
'vote,comment,delete_comment,comment_options,custom_json,claim_reward_balance,account_update,offline',
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import PointsContainer from './pointsContainer';
|
import PointsContainer from './pointsContainer';
|
||||||
import TransferContainer from './transferContainer';
|
import ProfileEditContainer from './profileEditContainer';
|
||||||
import RedeemContainer from './redeemContainer';
|
import RedeemContainer from './redeemContainer';
|
||||||
|
import TransferContainer from './transferContainer';
|
||||||
|
|
||||||
export { PointsContainer, TransferContainer, RedeemContainer };
|
export { PointsContainer, ProfileEditContainer, RedeemContainer, TransferContainer };
|
||||||
|
214
src/containers/profileEditContainer.js
Normal file
214
src/containers/profileEditContainer.js
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { injectIntl } from 'react-intl';
|
||||||
|
import ImagePicker from 'react-native-image-crop-picker';
|
||||||
|
import get from 'lodash/get';
|
||||||
|
import { withNavigation } from 'react-navigation';
|
||||||
|
|
||||||
|
import { uploadImage } from '../providers/esteem/esteem';
|
||||||
|
|
||||||
|
import { profileUpdate } from '../providers/steem/dsteem';
|
||||||
|
import { updateCurrentAccount } from '../redux/actions/accountAction';
|
||||||
|
|
||||||
|
// import ROUTES from '../constants/routeNames';
|
||||||
|
|
||||||
|
const FORM_DATA = [
|
||||||
|
{
|
||||||
|
valueKey: 'name',
|
||||||
|
type: 'text',
|
||||||
|
label: 'display_name',
|
||||||
|
placeholder: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
valueKey: 'about',
|
||||||
|
type: 'text',
|
||||||
|
label: 'about',
|
||||||
|
placeholder: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
valueKey: 'location',
|
||||||
|
type: 'text',
|
||||||
|
label: 'location',
|
||||||
|
placeholder: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
valueKey: 'website',
|
||||||
|
type: 'text',
|
||||||
|
label: 'website',
|
||||||
|
placeholder: '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
class ProfileEditContainer extends Component {
|
||||||
|
/* Props
|
||||||
|
* ------------------------------------------------
|
||||||
|
* @prop { type } name - Description....
|
||||||
|
*/
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isLoading: false,
|
||||||
|
about: get(props.currentAccount, 'about.profile.about'),
|
||||||
|
name: get(props.currentAccount, 'about.profile.name'),
|
||||||
|
location: get(props.currentAccount, 'about.profile.location'),
|
||||||
|
website: get(props.currentAccount, 'about.profile.website'),
|
||||||
|
coverUrl: get(props.currentAccount, 'about.profile.cover_image'),
|
||||||
|
avatarUrl: get(props.currentAccount, 'avatar'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Component Life Cycles
|
||||||
|
|
||||||
|
// Component Functions
|
||||||
|
|
||||||
|
_handleOnItemChange = (val, item) => {
|
||||||
|
this.setState({ [item]: val });
|
||||||
|
};
|
||||||
|
|
||||||
|
_uploadImage = (media, action) => {
|
||||||
|
const { intl } = this.props;
|
||||||
|
|
||||||
|
this.setState({ isLoading: true });
|
||||||
|
uploadImage(media)
|
||||||
|
.then(res => {
|
||||||
|
if (res.data && res.data.url) {
|
||||||
|
this.setState({ [action]: res.data.url, isLoading: false });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error) {
|
||||||
|
Alert.alert(
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'alert.fail',
|
||||||
|
}),
|
||||||
|
error.message || error.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleMediaAction = (type, uploadAction) => {
|
||||||
|
if (type === 'camera') {
|
||||||
|
this._handleOpenCamera(uploadAction);
|
||||||
|
} else if (type === 'image') {
|
||||||
|
this._handleOpenImagePicker(uploadAction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleOpenImagePicker = action => {
|
||||||
|
ImagePicker.openPicker({
|
||||||
|
includeBase64: true,
|
||||||
|
})
|
||||||
|
.then(image => {
|
||||||
|
this._handleMediaOnSelected(image, action);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this._handleMediaOnSelectFailure(e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleOpenCamera = action => {
|
||||||
|
ImagePicker.openCamera({
|
||||||
|
includeBase64: true,
|
||||||
|
})
|
||||||
|
.then(image => {
|
||||||
|
this._handleMediaOnSelected(image, action);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this._handleMediaOnSelectFailure(e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleMediaOnSelected = (media, action) => {
|
||||||
|
this.setState({ isLoading: true }, () => {
|
||||||
|
this._uploadImage(media, action);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleMediaOnSelectFailure = error => {
|
||||||
|
const { intl } = this.props;
|
||||||
|
|
||||||
|
if (get(error, 'code') === 'E_PERMISSION_MISSING') {
|
||||||
|
Alert.alert(
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'alert.permission_denied',
|
||||||
|
}),
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'alert.permission_text',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleOnSubmit = async () => {
|
||||||
|
const { currentAccount, pinCode, dispatch, navigation, intl } = this.props;
|
||||||
|
const { name, location, website, about, coverUrl, avatarUrl } = this.state;
|
||||||
|
|
||||||
|
await this.setState({ isLoading: true });
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
profile_image: avatarUrl,
|
||||||
|
cover_image: coverUrl,
|
||||||
|
name,
|
||||||
|
website,
|
||||||
|
about,
|
||||||
|
location,
|
||||||
|
};
|
||||||
|
|
||||||
|
await profileUpdate(params, pinCode, currentAccount)
|
||||||
|
.then(async () => {
|
||||||
|
const _currentAccount = { ...currentAccount, display_name: name, avatar: avatarUrl };
|
||||||
|
_currentAccount.about.profile = { ...params };
|
||||||
|
|
||||||
|
dispatch(updateCurrentAccount(_currentAccount));
|
||||||
|
|
||||||
|
navigation.state.params.fetchUser();
|
||||||
|
navigation.goBack();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Alert.alert(
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'alert.fail',
|
||||||
|
}),
|
||||||
|
get(error, 'message', error.toString()),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { children, currentAccount, isDarkTheme } = this.props;
|
||||||
|
const { isLoading, name, location, website, about, coverUrl, avatarUrl } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
children &&
|
||||||
|
children({
|
||||||
|
about,
|
||||||
|
avatarUrl,
|
||||||
|
coverUrl,
|
||||||
|
currentAccount,
|
||||||
|
formData: FORM_DATA,
|
||||||
|
handleMediaAction: this._handleMediaAction,
|
||||||
|
handleOnItemChange: this._handleOnItemChange,
|
||||||
|
handleOnSubmit: this._handleOnSubmit,
|
||||||
|
isDarkTheme,
|
||||||
|
isLoading,
|
||||||
|
location,
|
||||||
|
name,
|
||||||
|
website,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
currentAccount: state.account.currentAccount,
|
||||||
|
isDarkTheme: state.application.isDarkTheme,
|
||||||
|
pinCode: state.application.pin,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(injectIntl(withNavigation(ProfileEditContainer)));
|
@ -18,6 +18,7 @@ import {
|
|||||||
PinCode,
|
PinCode,
|
||||||
Post,
|
Post,
|
||||||
Profile,
|
Profile,
|
||||||
|
ProfileEdit,
|
||||||
Reblogs,
|
Reblogs,
|
||||||
Redeem,
|
Redeem,
|
||||||
SearchResult,
|
SearchResult,
|
||||||
@ -55,6 +56,12 @@ const stackNavigatior = createStackNavigator(
|
|||||||
header: () => null,
|
header: () => null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[ROUTES.SCREENS.PROFILE_EDIT]: {
|
||||||
|
screen: ProfileEdit,
|
||||||
|
navigationOptions: {
|
||||||
|
header: () => null,
|
||||||
|
},
|
||||||
|
},
|
||||||
[ROUTES.SCREENS.POST]: {
|
[ROUTES.SCREENS.POST]: {
|
||||||
screen: Post,
|
screen: Post,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
|
@ -300,7 +300,14 @@ export const getImages = username => api.get(`api/images/${username}`).then(resp
|
|||||||
|
|
||||||
export const addMyImage = (user, url) => api.post('/image', { username: user, image_url: url });
|
export const addMyImage = (user, url) => api.post('/image', { username: user, image_url: url });
|
||||||
|
|
||||||
export const uploadImage = file => {
|
export const uploadImage = media => {
|
||||||
|
const file = {
|
||||||
|
uri: media.path,
|
||||||
|
type: media.mime,
|
||||||
|
name: media.filename || `IMG_${Math.random()}.JPG`,
|
||||||
|
size: media.size,
|
||||||
|
};
|
||||||
|
|
||||||
const fData = new FormData();
|
const fData = new FormData();
|
||||||
fData.append('postimage', file);
|
fData.append('postimage', file);
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
import { Client, PrivateKey } from 'dsteem';
|
import { Client, PrivateKey } from 'dsteem';
|
||||||
import steemconnect from 'steemconnect';
|
import steemconnect from 'steemconnect';
|
||||||
import Config from 'react-native-config';
|
import Config from 'react-native-config';
|
||||||
@ -1167,6 +1168,63 @@ export const boost = (currentAccount, pinCode, point, permlink, author) => {
|
|||||||
return Promise.reject(new Error('Something went wrong!'));
|
return Promise.reject(new Error('Something went wrong!'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const profileUpdate = async (params, pin, currentAccount) => {
|
||||||
|
const digitPinCode = getDigitPinCode(pin);
|
||||||
|
const key = getActiveKey(get(currentAccount, 'local'), digitPinCode);
|
||||||
|
|
||||||
|
if (get(currentAccount, 'local.authType') === AUTH_TYPE.STEEM_CONNECT) {
|
||||||
|
const token = decryptKey(get(currentAccount, 'local.accessToken'), digitPinCode);
|
||||||
|
const api = new steemconnect.Client({
|
||||||
|
accessToken: token,
|
||||||
|
});
|
||||||
|
|
||||||
|
const _params = {
|
||||||
|
account: get(currentAccount, 'name'),
|
||||||
|
memo_key: get(currentAccount, 'memo_key'),
|
||||||
|
json_metadata: jsonStringify(params),
|
||||||
|
};
|
||||||
|
|
||||||
|
const opArray = [['account_update', _params]];
|
||||||
|
|
||||||
|
return api
|
||||||
|
.broadcast(opArray)
|
||||||
|
.then(resp => resp.result)
|
||||||
|
.catch(error => console.log(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
const opArray = [
|
||||||
|
[
|
||||||
|
'account_update',
|
||||||
|
{
|
||||||
|
account: get(currentAccount, 'name'),
|
||||||
|
memo_key: get(currentAccount, 'memo_key'),
|
||||||
|
json_metadata: jsonStringify({ profile: params }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
const privateKey = PrivateKey.fromString(key);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
client.broadcast
|
||||||
|
.sendOperations(opArray, privateKey)
|
||||||
|
.then(result => {
|
||||||
|
resolve(result);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (get(error, 'jse_info.code') === 4030100) {
|
||||||
|
error.message =
|
||||||
|
'We noticed that your device has incorrect date or time. Please fix Date & Time or Set Automatically and try again.';
|
||||||
|
}
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(new Error('You dont have permission!'));
|
||||||
|
};
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
|
|
||||||
const getAnyPrivateKey = (local, pin) => {
|
const getAnyPrivateKey = (local, pin) => {
|
||||||
|
@ -487,13 +487,6 @@ class ApplicationContainer extends Component {
|
|||||||
const isExistUser = await getExistUser();
|
const isExistUser = await getExistUser();
|
||||||
|
|
||||||
realmObject[0].name = currentUsername;
|
realmObject[0].name = currentUsername;
|
||||||
dispatch(
|
|
||||||
updateCurrentAccount({
|
|
||||||
name: realmObject[0].username,
|
|
||||||
avatar: realmObject[0].avatar,
|
|
||||||
authType: realmObject[0].authType,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
// If in dev mode pin code does not show
|
// If in dev mode pin code does not show
|
||||||
if ((!isExistUser || !pinCode) && _isPinCodeOpen) {
|
if ((!isExistUser || !pinCode) && _isPinCodeOpen) {
|
||||||
dispatch(openPinCodeModal());
|
dispatch(openPinCodeModal());
|
||||||
|
@ -42,7 +42,6 @@ class EditorContainer extends Component {
|
|||||||
autoFocusText: false,
|
autoFocusText: false,
|
||||||
draftId: null,
|
draftId: null,
|
||||||
draftPost: null,
|
draftPost: null,
|
||||||
isCameraOrPickerOpen: false,
|
|
||||||
isDraftSaved: false,
|
isDraftSaved: false,
|
||||||
isDraftSaving: false,
|
isDraftSaving: false,
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
@ -141,8 +140,6 @@ class EditorContainer extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_handleRoutingAction = routingAction => {
|
_handleRoutingAction = routingAction => {
|
||||||
this.setState({ isCameraOrPickerOpen: true });
|
|
||||||
|
|
||||||
if (routingAction === 'camera') {
|
if (routingAction === 'camera') {
|
||||||
this._handleOpenCamera();
|
this._handleOpenCamera();
|
||||||
} else if (routingAction === 'image') {
|
} else if (routingAction === 'image') {
|
||||||
@ -175,7 +172,7 @@ class EditorContainer extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_handleMediaOnSelected = media => {
|
_handleMediaOnSelected = media => {
|
||||||
this.setState({ isCameraOrPickerOpen: false, isUploading: true }, () => {
|
this.setState({ isUploading: true }, () => {
|
||||||
this._uploadImage(media);
|
this._uploadImage(media);
|
||||||
});
|
});
|
||||||
// For new image api
|
// For new image api
|
||||||
@ -189,33 +186,27 @@ class EditorContainer extends Component {
|
|||||||
_uploadImage = media => {
|
_uploadImage = media => {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
|
||||||
const file = {
|
uploadImage(media)
|
||||||
uri: media.path,
|
|
||||||
type: media.mime,
|
|
||||||
name: media.filename || `IMG_${Math.random()}.JPG`,
|
|
||||||
size: media.size,
|
|
||||||
};
|
|
||||||
|
|
||||||
uploadImage(file)
|
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.data && res.data.url) {
|
if (res.data && res.data.url) {
|
||||||
this.setState({ uploadedImage: res.data, isUploading: false });
|
this.setState({ uploadedImage: res.data, isUploading: false });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
if (error) {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
intl.formatMessage({
|
intl.formatMessage({
|
||||||
id: 'alert.fail',
|
id: 'alert.fail',
|
||||||
}),
|
}),
|
||||||
error.message || error.toString(),
|
error.message || error.toString(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
this.setState({ isUploading: false });
|
this.setState({ isUploading: false });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleMediaOnSelectFailure = error => {
|
_handleMediaOnSelectFailure = error => {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
this.setState({ isCameraOrPickerOpen: false });
|
|
||||||
|
|
||||||
if (get(error, 'code') === 'E_PERMISSION_MISSING') {
|
if (get(error, 'code') === 'E_PERMISSION_MISSING') {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
@ -567,7 +558,6 @@ class EditorContainer extends Component {
|
|||||||
const {
|
const {
|
||||||
autoFocusText,
|
autoFocusText,
|
||||||
draftPost,
|
draftPost,
|
||||||
isCameraOrPickerOpen,
|
|
||||||
isDraftSaved,
|
isDraftSaved,
|
||||||
isDraftSaving,
|
isDraftSaving,
|
||||||
isEdit,
|
isEdit,
|
||||||
@ -589,7 +579,6 @@ class EditorContainer extends Component {
|
|||||||
handleOnImagePicker={this._handleRoutingAction}
|
handleOnImagePicker={this._handleRoutingAction}
|
||||||
handleOnSubmit={this._handleSubmit}
|
handleOnSubmit={this._handleSubmit}
|
||||||
initialEditor={this._initialEditor}
|
initialEditor={this._initialEditor}
|
||||||
isCameraOrPickerOpen={isCameraOrPickerOpen}
|
|
||||||
isDarkTheme={isDarkTheme}
|
isDarkTheme={isDarkTheme}
|
||||||
isDraftSaved={isDraftSaved}
|
isDraftSaved={isDraftSaved}
|
||||||
isDraftSaving={isDraftSaving}
|
isDraftSaving={isDraftSaving}
|
||||||
|
@ -23,8 +23,6 @@ class HomeScreen extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const { currentAccount, intl, isLoggedIn } = this.props;
|
const { currentAccount, intl, isLoggedIn } = this.props;
|
||||||
|
|
||||||
let tag;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Header />
|
<Header />
|
||||||
@ -50,7 +48,7 @@ class HomeScreen extends PureComponent {
|
|||||||
<Posts
|
<Posts
|
||||||
filterOptions={PROFILE_FILTERS}
|
filterOptions={PROFILE_FILTERS}
|
||||||
getFor={PROFILE_FILTERS[1].toLowerCase()}
|
getFor={PROFILE_FILTERS[1].toLowerCase()}
|
||||||
tag={tag || currentAccount.name}
|
tag={currentAccount.name}
|
||||||
selectedOptionIndex={1}
|
selectedOptionIndex={1}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -14,16 +14,15 @@ import { Profile } from './profile';
|
|||||||
import { SearchResult } from './searchResult';
|
import { SearchResult } from './searchResult';
|
||||||
import { Settings } from './settings';
|
import { Settings } from './settings';
|
||||||
import Voters from './voters';
|
import Voters from './voters';
|
||||||
import BoostPost from './boostPost/screen/boostPostScreen';
|
|
||||||
import SteemConnect from './steem-connect/steemConnect';
|
import SteemConnect from './steem-connect/steemConnect';
|
||||||
import Transfer from './transfer';
|
import Transfer from './transfer';
|
||||||
import Reblogs from './reblogs';
|
import Reblogs from './reblogs';
|
||||||
|
import ProfileEdit from './profileEdit/screen/profileEditScreen';
|
||||||
import Redeem from './redeem/screen/redeemScreen';
|
import Redeem from './redeem/screen/redeemScreen';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Bookmarks,
|
Bookmarks,
|
||||||
Boost,
|
Boost,
|
||||||
BoostPost,
|
|
||||||
Drafts,
|
Drafts,
|
||||||
Editor,
|
Editor,
|
||||||
Follows,
|
Follows,
|
||||||
@ -35,11 +34,12 @@ export {
|
|||||||
Points,
|
Points,
|
||||||
Post,
|
Post,
|
||||||
Profile,
|
Profile,
|
||||||
|
ProfileEdit,
|
||||||
|
Reblogs,
|
||||||
SearchResult,
|
SearchResult,
|
||||||
Settings,
|
Settings,
|
||||||
SteemConnect,
|
SteemConnect,
|
||||||
Transfer,
|
Transfer,
|
||||||
Voters,
|
Voters,
|
||||||
Reblogs,
|
|
||||||
Redeem,
|
Redeem,
|
||||||
};
|
};
|
||||||
|
@ -102,7 +102,7 @@ class LoginScreen extends PureComponent {
|
|||||||
onKeyboardWillShow={() => this.setState({ keyboardIsOpen: true })}
|
onKeyboardWillShow={() => this.setState({ keyboardIsOpen: true })}
|
||||||
onKeyboardWillHide={() => this.setState({ keyboardIsOpen: false })}
|
onKeyboardWillHide={() => this.setState({ keyboardIsOpen: false })}
|
||||||
enableAutoAutomaticScroll={Platform.OS === 'ios'}
|
enableAutoAutomaticScroll={Platform.OS === 'ios'}
|
||||||
contentContainerStyle={{ flexGrow: 1 }}
|
contentContainerStyle={styles.formWrapper}
|
||||||
>
|
>
|
||||||
<FormInput
|
<FormInput
|
||||||
rightIconName="at"
|
rightIconName="at"
|
||||||
|
@ -34,4 +34,9 @@ export default EStyleSheet.create({
|
|||||||
cancelButton: {
|
cancelButton: {
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
},
|
},
|
||||||
|
formWrapper: {
|
||||||
|
flexGrow: 1,
|
||||||
|
marginHorizontal: 30,
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -343,6 +343,17 @@ class ProfileContainer extends Component {
|
|||||||
this.setState({ forceLoadPost: value });
|
this.setState({ forceLoadPost: value });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_handleOnPressProfileEdit = () => {
|
||||||
|
const { navigation, currentAccount } = this.props;
|
||||||
|
|
||||||
|
navigation.navigate({
|
||||||
|
routeName: ROUTES.SCREENS.PROFILE_EDIT,
|
||||||
|
params: {
|
||||||
|
fetchUser: () => this.setState({ user: currentAccount }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
avatar,
|
avatar,
|
||||||
@ -368,16 +379,19 @@ class ProfileContainer extends Component {
|
|||||||
about={get(user, 'about.profile')}
|
about={get(user, 'about.profile')}
|
||||||
activePage={activePage}
|
activePage={activePage}
|
||||||
avatar={avatar}
|
avatar={avatar}
|
||||||
|
changeForceLoadPostState={this._changeForceLoadPostState}
|
||||||
comments={comments}
|
comments={comments}
|
||||||
currency={currency}
|
currency={currency}
|
||||||
error={error}
|
error={error}
|
||||||
follows={follows}
|
follows={follows}
|
||||||
|
forceLoadPost={forceLoadPost}
|
||||||
getReplies={() => this._getReplies(username)}
|
getReplies={() => this._getReplies(username)}
|
||||||
handleFollowUnfollowUser={this._handleFollowUnfollowUser}
|
handleFollowUnfollowUser={this._handleFollowUnfollowUser}
|
||||||
handleMuteUnmuteUser={this._handleMuteUnmuteUser}
|
handleMuteUnmuteUser={this._handleMuteUnmuteUser}
|
||||||
handleOnBackPress={this._handleOnBackPress}
|
handleOnBackPress={this._handleOnBackPress}
|
||||||
handleOnFavoritePress={this._handleOnFavoritePress}
|
handleOnFavoritePress={this._handleOnFavoritePress}
|
||||||
handleOnFollowsPress={this._handleFollowsPress}
|
handleOnFollowsPress={this._handleFollowsPress}
|
||||||
|
handleOnPressProfileEdit={this._handleOnPressProfileEdit}
|
||||||
isDarkTheme={isDarkTheme}
|
isDarkTheme={isDarkTheme}
|
||||||
isFavorite={isFavorite}
|
isFavorite={isFavorite}
|
||||||
isFollowing={isFollowing}
|
isFollowing={isFollowing}
|
||||||
@ -389,8 +403,6 @@ class ProfileContainer extends Component {
|
|||||||
selectedQuickProfile={selectedQuickProfile}
|
selectedQuickProfile={selectedQuickProfile}
|
||||||
selectedUser={user}
|
selectedUser={user}
|
||||||
username={username}
|
username={username}
|
||||||
forceLoadPost={forceLoadPost}
|
|
||||||
changeForceLoadPostState={this._changeForceLoadPostState}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -62,15 +62,19 @@ class ProfileScreen extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
about,
|
about,
|
||||||
|
activePage,
|
||||||
|
changeForceLoadPostState,
|
||||||
comments,
|
comments,
|
||||||
currency,
|
currency,
|
||||||
follows,
|
follows,
|
||||||
|
forceLoadPost,
|
||||||
getReplies,
|
getReplies,
|
||||||
handleFollowUnfollowUser,
|
handleFollowUnfollowUser,
|
||||||
handleMuteUnmuteUser,
|
handleMuteUnmuteUser,
|
||||||
handleOnBackPress,
|
handleOnBackPress,
|
||||||
handleOnFavoritePress,
|
handleOnFavoritePress,
|
||||||
handleOnFollowsPress,
|
handleOnFollowsPress,
|
||||||
|
handleOnPressProfileEdit,
|
||||||
intl,
|
intl,
|
||||||
isDarkTheme,
|
isDarkTheme,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
@ -83,9 +87,6 @@ class ProfileScreen extends PureComponent {
|
|||||||
selectedQuickProfile,
|
selectedQuickProfile,
|
||||||
selectedUser,
|
selectedUser,
|
||||||
username,
|
username,
|
||||||
activePage,
|
|
||||||
forceLoadPost,
|
|
||||||
changeForceLoadPostState,
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -175,6 +176,7 @@ class ProfileScreen extends PureComponent {
|
|||||||
location={location}
|
location={location}
|
||||||
percentRC={resourceCredits}
|
percentRC={resourceCredits}
|
||||||
percentVP={votingPower}
|
percentVP={votingPower}
|
||||||
|
handleOnPressProfileEdit={handleOnPressProfileEdit}
|
||||||
/>
|
/>
|
||||||
</CollapsibleCard>
|
</CollapsibleCard>
|
||||||
)}
|
)}
|
||||||
|
104
src/screens/profileEdit/screen/profileEditScreen.js
Normal file
104
src/screens/profileEdit/screen/profileEditScreen.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import React, { PureComponent, Fragment } from 'react';
|
||||||
|
import { injectIntl } from 'react-intl';
|
||||||
|
import get from 'lodash/get';
|
||||||
|
import ActionSheet from 'react-native-actionsheet';
|
||||||
|
|
||||||
|
import { ProfileEditContainer } from '../../../containers';
|
||||||
|
|
||||||
|
import AvatarHeader from '../../../components/avatarHeader/avatarHeaderView';
|
||||||
|
import ProfileEditForm from '../../../components/profileEditForm/profileEditFormView';
|
||||||
|
|
||||||
|
class ProfileEditScreen extends PureComponent {
|
||||||
|
/* Props
|
||||||
|
* ------------------------------------------------
|
||||||
|
* @prop { type } name - Description....
|
||||||
|
*/
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
selectedUploadAction: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
this.galleryRef = React.createRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Component Life Cycles
|
||||||
|
|
||||||
|
// Component Functions
|
||||||
|
_showImageUploadActions = async action => {
|
||||||
|
await this.setState({ selectedUploadAction: action });
|
||||||
|
this.galleryRef.current.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { intl } = this.props;
|
||||||
|
const { selectedUploadAction } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProfileEditContainer>
|
||||||
|
{({
|
||||||
|
currentAccount,
|
||||||
|
isDarkTheme,
|
||||||
|
formData,
|
||||||
|
handleOnItemChange,
|
||||||
|
handleMediaAction,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
website,
|
||||||
|
about,
|
||||||
|
avatarUrl,
|
||||||
|
coverUrl,
|
||||||
|
isLoading,
|
||||||
|
handleOnSubmit,
|
||||||
|
}) => (
|
||||||
|
<Fragment>
|
||||||
|
<AvatarHeader
|
||||||
|
username={get(currentAccount, 'name')}
|
||||||
|
name={name}
|
||||||
|
reputation={get(currentAccount, 'reputation')}
|
||||||
|
avatarUrl={avatarUrl}
|
||||||
|
showImageUploadActions={() => this._showImageUploadActions('avatarUrl')}
|
||||||
|
/>
|
||||||
|
<ProfileEditForm
|
||||||
|
formData={formData}
|
||||||
|
isDarkTheme={isDarkTheme}
|
||||||
|
about={about}
|
||||||
|
name={name}
|
||||||
|
location={location}
|
||||||
|
website={website}
|
||||||
|
coverUrl={coverUrl}
|
||||||
|
showImageUploadActions={() => this._showImageUploadActions('coverUrl')}
|
||||||
|
handleOnItemChange={handleOnItemChange}
|
||||||
|
isLoading={isLoading}
|
||||||
|
handleOnSubmit={handleOnSubmit}
|
||||||
|
/>
|
||||||
|
<ActionSheet
|
||||||
|
ref={this.galleryRef}
|
||||||
|
options={[
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'editor.open_gallery',
|
||||||
|
}),
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'editor.capture_photo',
|
||||||
|
}),
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'alert.cancel',
|
||||||
|
}),
|
||||||
|
]}
|
||||||
|
cancelButtonIndex={2}
|
||||||
|
onPress={index => {
|
||||||
|
handleMediaAction(
|
||||||
|
index === 0 ? 'image' : index === 1 && 'camera',
|
||||||
|
selectedUploadAction,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
</ProfileEditContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default injectIntl(ProfileEditScreen);
|
@ -84,15 +84,6 @@ class SettingsScreen extends PureComponent {
|
|||||||
})}
|
})}
|
||||||
titleStyle={styles.cardTitle}
|
titleStyle={styles.cardTitle}
|
||||||
/>
|
/>
|
||||||
<SettingsItem
|
|
||||||
title={intl.formatMessage({
|
|
||||||
id: 'settings.dark_theme',
|
|
||||||
})}
|
|
||||||
type="toggle"
|
|
||||||
actionType="theme"
|
|
||||||
isOn={isDarkTheme}
|
|
||||||
handleOnChange={handleOnChange}
|
|
||||||
/>
|
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id: 'settings.currency',
|
id: 'settings.currency',
|
||||||
@ -143,6 +134,15 @@ class SettingsScreen extends PureComponent {
|
|||||||
selectedOptionIndex={parseInt(nsfw, 10)}
|
selectedOptionIndex={parseInt(nsfw, 10)}
|
||||||
handleOnChange={handleOnChange}
|
handleOnChange={handleOnChange}
|
||||||
/>
|
/>
|
||||||
|
<SettingsItem
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id: 'settings.dark_theme',
|
||||||
|
})}
|
||||||
|
type="toggle"
|
||||||
|
actionType="theme"
|
||||||
|
isOn={isDarkTheme}
|
||||||
|
handleOnChange={handleOnChange}
|
||||||
|
/>
|
||||||
{!!isLoggedIn && (
|
{!!isLoggedIn && (
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export const steemConnectOptions = {
|
|
||||||
base_url: 'https://steemconnect.com/oauth2/authorize',
|
|
||||||
client_id: 'esteem-app',
|
|
||||||
redirect_uri: 'http://127.0.0.1:3415/', // http://127.0.0.1:3415
|
|
||||||
scope: 'vote,comment,delete_comment,comment_options,custom_json,claim_reward_balance,offline',
|
|
||||||
};
|
|
@ -5,7 +5,7 @@ import { injectIntl } from 'react-intl';
|
|||||||
import { withNavigation } from 'react-navigation';
|
import { withNavigation } from 'react-navigation';
|
||||||
|
|
||||||
import { loginWithSC2 } from '../../providers/steem/auth';
|
import { loginWithSC2 } from '../../providers/steem/auth';
|
||||||
import { steemConnectOptions } from './config';
|
import { steemConnectOptions } from '../../constants/steemConnectOptions';
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import { addOtherAccount, updateCurrentAccount } from '../../redux/actions/accountAction';
|
import { addOtherAccount, updateCurrentAccount } from '../../redux/actions/accountAction';
|
||||||
@ -79,7 +79,7 @@ class SteemConnect extends PureComponent {
|
|||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<WebView
|
<WebView
|
||||||
source={{
|
source={{
|
||||||
uri: `${steemConnectOptions.base_url}?client_id=${
|
uri: `${steemConnectOptions.base_url}oauth2/authorize?client_id=${
|
||||||
steemConnectOptions.client_id
|
steemConnectOptions.client_id
|
||||||
}&redirect_uri=${encodeURIComponent(
|
}&redirect_uri=${encodeURIComponent(
|
||||||
steemConnectOptions.redirect_uri,
|
steemConnectOptions.redirect_uri,
|
||||||
|
@ -63,3 +63,12 @@ export const catchDraftImage = body => {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getResizedImage = (url, size) => {
|
||||||
|
if (!url) return '';
|
||||||
|
const _size = size || 400;
|
||||||
|
|
||||||
|
if (url.includes('img.esteem')) return `https://img.esteem.ws/${_size}x0/${url}`;
|
||||||
|
|
||||||
|
return `https://steemitimages.com/${size}x0/${url}`;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user