mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-19 03:11:38 +03:00
created image upload
This commit is contained in:
parent
7b9f8af42c
commit
81af8d4f03
@ -9,7 +9,14 @@ import { IconButton } from '../iconButton';
|
||||
// Styles
|
||||
import styles from './avatarHeaderStyles';
|
||||
|
||||
const AvatarHeader = ({ username, name, reputation, navigation, avatarUrl }) => (
|
||||
const AvatarHeader = ({
|
||||
username,
|
||||
name,
|
||||
reputation,
|
||||
navigation,
|
||||
avatarUrl,
|
||||
showImageUploadActions,
|
||||
}) => (
|
||||
<LinearGradient
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 0 }}
|
||||
@ -25,13 +32,19 @@ const AvatarHeader = ({ username, name, reputation, navigation, avatarUrl }) =>
|
||||
size={25}
|
||||
/>
|
||||
<View style={styles.wrapper}>
|
||||
<UserAvatar noAction size="xl" username={username} avatarUrl={avatarUrl} />
|
||||
<UserAvatar
|
||||
key={avatarUrl || username}
|
||||
noAction
|
||||
size="xl"
|
||||
username={username}
|
||||
avatarUrl={avatarUrl}
|
||||
/>
|
||||
<IconButton
|
||||
iconStyle={styles.addIcon}
|
||||
style={styles.addButton}
|
||||
iconType="MaterialCommunityIcons"
|
||||
name="plus"
|
||||
onPress={() => alert('upload')}
|
||||
onPress={() => showImageUploadActions()}
|
||||
size={15}
|
||||
/>
|
||||
<View style={styles.textWrapper}>
|
||||
|
@ -1,12 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import { Icon } from '../../icon';
|
||||
|
||||
// Constants
|
||||
|
||||
// Components
|
||||
import { TextInput } from '../../textInput';
|
||||
import { Icon } from '../../icon';
|
||||
|
||||
// Styles
|
||||
import styles from './formInputStyles';
|
||||
|
||||
@ -19,16 +18,13 @@ class FormInputView extends Component {
|
||||
* @prop { boolean } isEditable - Can permission edit.
|
||||
* @prop { boolean } isValid - This delegate input valit or not.
|
||||
* @prop { boolean } secureTextEntry - For hiding password value.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
value: props.value || '',
|
||||
inputBorderColor: '#c1c5c7',
|
||||
inputBorderColor: '#e7e7e7',
|
||||
isValid: true,
|
||||
};
|
||||
}
|
||||
@ -47,14 +43,11 @@ class FormInputView extends Component {
|
||||
const { onChange } = this.props;
|
||||
|
||||
this.setState({ value });
|
||||
onChange && onChange(value);
|
||||
if (onChange) onChange(value);
|
||||
};
|
||||
|
||||
_handleOnFocus = () => {
|
||||
const { inputBorderColor } = this.state;
|
||||
if (inputBorderColor !== '#357ce6') {
|
||||
this.setState({ inputBorderColor: '#357ce6' });
|
||||
}
|
||||
this.setState({ inputBorderColor: '#357ce6' });
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -101,7 +94,8 @@ class FormInputView extends Component {
|
||||
<View style={styles.textInput}>
|
||||
<TextInput
|
||||
style={inputStyle}
|
||||
onFocus={() => this._handleOnFocus()}
|
||||
onFocus={() => this.setState({ inputBorderColor: '#357ce6' })}
|
||||
onBlur={() => this.setState({ inputBorderColor: '#e7e7e7' })}
|
||||
autoCapitalize="none"
|
||||
secureTextEntry={secureTextEntry}
|
||||
height={height}
|
||||
|
@ -65,5 +65,7 @@ export default EStyleSheet.create({
|
||||
fontSize: 14,
|
||||
color: '$primaryDarkText',
|
||||
alignSelf: 'flex-start',
|
||||
width: '100%',
|
||||
height: 30,
|
||||
},
|
||||
});
|
||||
|
@ -14,21 +14,29 @@ import { IconButton } from '../iconButton';
|
||||
// Styles
|
||||
import styles from './profileEditFormStyles';
|
||||
|
||||
const ProfileEditFormView = ({ avatarUrl, coverUrl, isDarkTheme, formData, intl, ...props }) => (
|
||||
const ProfileEditFormView = ({
|
||||
coverUrl,
|
||||
isDarkTheme,
|
||||
formData,
|
||||
intl,
|
||||
handleOnItemChange,
|
||||
showImageUploadActions,
|
||||
...props
|
||||
}) => (
|
||||
<View style={styles.container}>
|
||||
<IconButton
|
||||
iconStyle={styles.saveIcon}
|
||||
style={styles.saveButton}
|
||||
iconType="MaterialIcons"
|
||||
name="save"
|
||||
onPress={() => alert('upload')}
|
||||
onPress={() => alert('asd')}
|
||||
size={30}
|
||||
/>
|
||||
<KeyboardAwareScrollView
|
||||
enableAutoAutomaticScroll={Platform.OS === 'ios'}
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
>
|
||||
<TouchableOpacity style={styles.coverImgWrapper} onPress={() => alert('upload')}>
|
||||
<TouchableOpacity style={styles.coverImgWrapper} onPress={showImageUploadActions}>
|
||||
<Image
|
||||
style={styles.coverImg}
|
||||
source={{ uri: `https://steemitimages.com/400x0/${coverUrl}` }}
|
||||
@ -40,7 +48,7 @@ const ProfileEditFormView = ({ avatarUrl, coverUrl, isDarkTheme, formData, intl,
|
||||
style={styles.addButton}
|
||||
iconType="MaterialCommunityIcons"
|
||||
name="plus"
|
||||
onPress={() => alert('upload')}
|
||||
onPress={showImageUploadActions}
|
||||
size={15}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
@ -56,7 +64,7 @@ const ProfileEditFormView = ({ avatarUrl, coverUrl, isDarkTheme, formData, intl,
|
||||
wrapperStyle={styles.formStyle}
|
||||
isValid
|
||||
height={30}
|
||||
onChange={value => console.log(value, item.valueKey)}
|
||||
onChange={value => handleOnItemChange(value, item.valueKey)}
|
||||
placeholder={item.placeholder}
|
||||
isEditable
|
||||
type={item.type}
|
||||
@ -65,51 +73,6 @@ const ProfileEditFormView = ({ avatarUrl, coverUrl, isDarkTheme, formData, intl,
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
{/*
|
||||
<View style={styles.formItem}>
|
||||
<Text style={styles.label}>About</Text>
|
||||
<FormInput
|
||||
wrapperStyle={styles.formStyle}
|
||||
isValid
|
||||
height={30}
|
||||
onChange={value => console.log('changed')}
|
||||
placeholder="About"
|
||||
isEditable
|
||||
type="text"
|
||||
value={about}
|
||||
inputStyle={styles.input}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formItem}>
|
||||
<Text style={styles.label}>Location</Text>
|
||||
<FormInput
|
||||
wrapperStyle={styles.formStyle}
|
||||
isValid
|
||||
height={30}
|
||||
onChange={value => console.log('changed')}
|
||||
placeholder="Location"
|
||||
isEditable
|
||||
type="text"
|
||||
value={location}
|
||||
inputStyle={styles.input}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formItem}>
|
||||
<Text style={styles.label}>Website</Text>
|
||||
<FormInput
|
||||
wrapperStyle={styles.formStyle}
|
||||
isValid
|
||||
height={30}
|
||||
onChange={value => console.log('changed')}
|
||||
placeholder="Website"
|
||||
isEditable
|
||||
type="text"
|
||||
value={website}
|
||||
inputStyle={styles.input}
|
||||
/>
|
||||
</View> */}
|
||||
</KeyboardAwareScrollView>
|
||||
</View>
|
||||
);
|
||||
|
@ -46,8 +46,8 @@ class UserAvatarView extends Component {
|
||||
const imageSize = size === 'xl' ? 'large' : 'small';
|
||||
let _size;
|
||||
const _avatar = username
|
||||
? { uri: `https://steemitimages.com/u/${username}/avatar/${imageSize}` }
|
||||
: avatarUrl || DEFAULT_IMAGE;
|
||||
? { uri: avatarUrl || `https://steemitimages.com/u/${username}/avatar/${imageSize}` }
|
||||
: DEFAULT_IMAGE;
|
||||
|
||||
if (!disableSize) {
|
||||
_size = 32;
|
||||
|
@ -101,7 +101,7 @@
|
||||
"edit": {
|
||||
"display_name": "Display Name",
|
||||
"about": "About",
|
||||
"location": "location",
|
||||
"location": "Location",
|
||||
"website": "Website"
|
||||
}
|
||||
},
|
||||
|
@ -1,6 +1,11 @@
|
||||
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 { uploadImage } from '../providers/esteem/esteem';
|
||||
// import ROUTES from '../constants/routeNames';
|
||||
|
||||
const FORM_DATA = [
|
||||
@ -38,7 +43,15 @@ class ProfileEditContainer extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
this.state = {
|
||||
isUploading: 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
|
||||
@ -47,8 +60,87 @@ class ProfileEditContainer extends Component {
|
||||
|
||||
_handleOnSave = () => {};
|
||||
|
||||
_handleOnItemChange = (val, item) => {
|
||||
console.log(val, item);
|
||||
};
|
||||
|
||||
_uploadImage = (media, action) => {
|
||||
const { intl } = this.props;
|
||||
uploadImage(media)
|
||||
.then(res => {
|
||||
if (res.data && res.data.url) {
|
||||
this.setState({ [action]: res.data.url, isUploading: false });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (error) {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'alert.fail',
|
||||
}),
|
||||
error.message || error.toString(),
|
||||
);
|
||||
}
|
||||
this.setState({ isUploading: 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({ isUploading: 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',
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { children, currentAccount, isDarkTheme } = this.props;
|
||||
const { isUploading, name, location, website, about, coverUrl, avatarUrl } = this.state;
|
||||
|
||||
return (
|
||||
children &&
|
||||
@ -56,6 +148,15 @@ class ProfileEditContainer extends Component {
|
||||
currentAccount,
|
||||
isDarkTheme,
|
||||
formData: FORM_DATA,
|
||||
isUploading,
|
||||
handleMediaAction: this._handleMediaAction,
|
||||
handleOnItemChange: this._handleOnItemChange,
|
||||
name,
|
||||
location,
|
||||
website,
|
||||
about,
|
||||
coverUrl,
|
||||
avatarUrl,
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -66,4 +167,4 @@ const mapStateToProps = state => ({
|
||||
isDarkTheme: state.application.isDarkTheme,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ProfileEditContainer);
|
||||
export default connect(mapStateToProps)(injectIntl(ProfileEditContainer));
|
||||
|
@ -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 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();
|
||||
fData.append('postimage', file);
|
||||
|
||||
|
@ -42,7 +42,6 @@ class EditorContainer extends Component {
|
||||
autoFocusText: false,
|
||||
draftId: null,
|
||||
draftPost: null,
|
||||
isCameraOrPickerOpen: false,
|
||||
isDraftSaved: false,
|
||||
isDraftSaving: false,
|
||||
isEdit: false,
|
||||
@ -141,8 +140,6 @@ class EditorContainer extends Component {
|
||||
};
|
||||
|
||||
_handleRoutingAction = routingAction => {
|
||||
this.setState({ isCameraOrPickerOpen: true });
|
||||
|
||||
if (routingAction === 'camera') {
|
||||
this._handleOpenCamera();
|
||||
} else if (routingAction === 'image') {
|
||||
@ -175,7 +172,7 @@ class EditorContainer extends Component {
|
||||
};
|
||||
|
||||
_handleMediaOnSelected = media => {
|
||||
this.setState({ isCameraOrPickerOpen: false, isUploading: true }, () => {
|
||||
this.setState({ isUploading: true }, () => {
|
||||
this._uploadImage(media);
|
||||
});
|
||||
// For new image api
|
||||
@ -189,33 +186,27 @@ class EditorContainer extends Component {
|
||||
_uploadImage = media => {
|
||||
const { intl } = this.props;
|
||||
|
||||
const file = {
|
||||
uri: media.path,
|
||||
type: media.mime,
|
||||
name: media.filename || `IMG_${Math.random()}.JPG`,
|
||||
size: media.size,
|
||||
};
|
||||
|
||||
uploadImage(file)
|
||||
uploadImage(media)
|
||||
.then(res => {
|
||||
if (res.data && res.data.url) {
|
||||
this.setState({ uploadedImage: res.data, isUploading: false });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'alert.fail',
|
||||
}),
|
||||
error.message || error.toString(),
|
||||
);
|
||||
if (error) {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'alert.fail',
|
||||
}),
|
||||
error.message || error.toString(),
|
||||
);
|
||||
}
|
||||
this.setState({ isUploading: false });
|
||||
});
|
||||
};
|
||||
|
||||
_handleMediaOnSelectFailure = error => {
|
||||
const { intl } = this.props;
|
||||
this.setState({ isCameraOrPickerOpen: false });
|
||||
|
||||
if (get(error, 'code') === 'E_PERMISSION_MISSING') {
|
||||
Alert.alert(
|
||||
@ -567,7 +558,6 @@ class EditorContainer extends Component {
|
||||
const {
|
||||
autoFocusText,
|
||||
draftPost,
|
||||
isCameraOrPickerOpen,
|
||||
isDraftSaved,
|
||||
isDraftSaving,
|
||||
isEdit,
|
||||
@ -589,7 +579,6 @@ class EditorContainer extends Component {
|
||||
handleOnImagePicker={this._handleRoutingAction}
|
||||
handleOnSubmit={this._handleSubmit}
|
||||
initialEditor={this._initialEditor}
|
||||
isCameraOrPickerOpen={isCameraOrPickerOpen}
|
||||
isDarkTheme={isDarkTheme}
|
||||
isDraftSaved={isDraftSaved}
|
||||
isDraftSaving={isDraftSaving}
|
||||
|
@ -1,6 +1,7 @@
|
||||
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';
|
||||
|
||||
@ -15,33 +16,79 @@ class ProfileEditScreen extends PureComponent {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
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 }) => (
|
||||
{({
|
||||
currentAccount,
|
||||
isDarkTheme,
|
||||
formData,
|
||||
handleOnItemChange,
|
||||
handleMediaAction,
|
||||
name,
|
||||
location,
|
||||
website,
|
||||
about,
|
||||
avatarUrl,
|
||||
coverUrl,
|
||||
}) => (
|
||||
<Fragment>
|
||||
<AvatarHeader
|
||||
username={get(currentAccount, 'name')}
|
||||
name={get(currentAccount, 'about.profile.name')}
|
||||
name={name}
|
||||
reputation={get(currentAccount, 'reputation')}
|
||||
avatarUrl={get(currentAccount, 'avatar')}
|
||||
avatarUrl={avatarUrl}
|
||||
showImageUploadActions={() => this._showImageUploadActions('avatarUrl')}
|
||||
/>
|
||||
<ProfileEditForm
|
||||
formData={formData}
|
||||
isDarkTheme={isDarkTheme}
|
||||
about={get(currentAccount, 'about.profile.about')}
|
||||
name={get(currentAccount, 'about.profile.name')}
|
||||
location={get(currentAccount, 'about.profile.profile.location')}
|
||||
website={get(currentAccount, 'about.profile.profile.website')}
|
||||
coverUrl={get(currentAccount, 'about.profile.cover_image')}
|
||||
avatarUrl={get(currentAccount, 'avatar')}
|
||||
about={about}
|
||||
name={name}
|
||||
location={location}
|
||||
website={website}
|
||||
coverUrl={coverUrl}
|
||||
showImageUploadActions={() => this._showImageUploadActions('coverUrl')}
|
||||
handleOnItemChange={handleOnItemChange}
|
||||
/>
|
||||
<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>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user