architecture created for image and video select

This commit is contained in:
ue 2018-11-28 13:14:19 +03:00
parent ed0d58c99d
commit 6908ea07ac
13 changed files with 226 additions and 75 deletions

View File

@ -81,7 +81,9 @@ export default class TagAreaView extends Component {
}; };
render() { render() {
const { isPreviewActive, draftChips, intl } = this.props; const {
isPreviewActive, draftChips, intl, autoFocus,
} = this.props;
const { chips } = this.state; const { chips } = this.state;
return ( return (
@ -100,7 +102,7 @@ export default class TagAreaView extends Component {
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'editor.tags', id: 'editor.tags',
})} })}
autoFocus={i !== 0 && chips.length - 1 === i} autoFocus={autoFocus ? i !== 0 && chips.length - 1 === i : false}
multiline={false} multiline={false}
handleOnChange={text => this._handleOnChange(text, i)} handleOnChange={text => this._handleOnChange(text, i)}
handleOnBlur={() => this._handleOnBlur(i)} handleOnBlur={() => this._handleOnBlur(i)}

View File

@ -35,7 +35,9 @@ export default class TitleAreaView extends Component {
}; };
render() { render() {
const { value, isPreviewActive, intl } = this.props; const {
intl, isPreviewActive, value, autoFocus,
} = this.props;
return ( return (
<View style={globalStyles.containerHorizontal16}> <View style={globalStyles.containerHorizontal16}>
@ -48,7 +50,7 @@ export default class TitleAreaView extends Component {
id: 'editor.title', id: 'editor.title',
})} })}
multiline multiline
autoFocus autoFocus={autoFocus}
numberOfLines={4} numberOfLines={4}
onChangeText={text => this._handleOnChange(text)} onChangeText={text => this._handleOnChange(text)}
value={value} value={value}

View File

@ -13,6 +13,14 @@ export default [
onPress: applyWrapFormat, onPress: applyWrapFormat,
// style: { fontWeight: 'bold' }, // style: { fontWeight: 'bold' },
}, },
{
key: 'I',
title: 'I',
icon: 'italic',
iconType: 'FontAwesome',
wrapper: '*',
onPress: applyWrapFormat,
},
{ {
key: 'H1', key: 'H1',
title: 'H1', title: 'H1',
@ -36,14 +44,6 @@ export default [
wrapper: '`', wrapper: '`',
onPress: applyWrapFormat, onPress: applyWrapFormat,
}, },
{
key: 'I',
title: 'I',
icon: 'italic',
iconType: 'FontAwesome',
wrapper: '*',
onPress: applyWrapFormat,
},
{ {
key: 'U', key: 'U',
title: 'U', title: 'U',

View File

@ -22,7 +22,7 @@ export default EStyleSheet.create({
marginLeft: 16, marginLeft: 16,
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
maxWidth: '$deviceWidth / 1.85', maxWidth: '$deviceWidth / 2',
}, },
rightButtonsWrapper: { rightButtonsWrapper: {
marginRight: 16, marginRight: 16,
@ -44,6 +44,6 @@ export default EStyleSheet.create({
color: '$primaryDarkGray', color: '$primaryDarkGray',
}, },
icon: { icon: {
color: '$iconColor', color: '$editorButtonColor',
}, },
}); });

View File

@ -3,7 +3,6 @@ import {
View, KeyboardAvoidingView, ScrollView, FlatList, Text, View, KeyboardAvoidingView, ScrollView, FlatList, Text,
} from 'react-native'; } from 'react-native';
import Markdown, { getUniqueID } from 'react-native-markdown-renderer'; import Markdown, { getUniqueID } from 'react-native-markdown-renderer';
import ImagePicker from 'react-native-image-crop-picker';
// Components // Components
import Formats from './formats/formats'; import Formats from './formats/formats';
import { IconButton } from '../../iconButton'; import { IconButton } from '../../iconButton';
@ -106,48 +105,52 @@ export default class MarkdownEditorView extends Component {
</View> </View>
); );
_renderEditorButtons = ({ getState, setState }) => ( _renderEditorButtons = ({ getState, setState }) => {
<StickyBar> const { handleOpenImagePicker } = this.props;
<View style={styles.leftButtonsWrapper}> return (
<FlatList <StickyBar>
data={Formats} <View style={styles.leftButtonsWrapper}>
keyboardShouldPersistTaps="always" <FlatList
renderItem={({ item, index }) => index !== 9 && this._renderMarkupButton({ item, getState, setState }) data={Formats}
} keyboardShouldPersistTaps="always"
horizontal renderItem={({ item, index }) => index !== 9 && this._renderMarkupButton({ item, getState, setState })
/> }
</View> horizontal
<View style={styles.rightButtonsWrapper}> />
<IconButton </View>
size={20} <View style={styles.rightButtonsWrapper}>
style={styles.rightIcons} <IconButton
iconStyle={styles.icon} size={20}
iconType="FontAwesome" style={styles.rightIcons}
name="link" iconStyle={styles.icon}
onPress={() => Formats[9].onPress({ getState, setState })} iconType="FontAwesome"
/> name="link"
<IconButton style={styles.rightIcons} size={20} iconType="Feather" name="image" /> onPress={() => Formats[9].onPress({ getState, setState })}
<DropdownButton />
style={styles.dropdownStyle} <IconButton
options={['option1', 'option2', 'option3', 'option4']} onPress={() => handleOpenImagePicker()}
iconName="md-more" style={styles.rightIcons}
iconStyle={styles.dropdownIconStyle} size={20}
isHasChildIcon iconStyle={styles.icon}
/> iconType="FontAwesome"
</View> name="image"
</StickyBar> />
); <DropdownButton
style={styles.dropdownStyle}
options={['option1', 'option2', 'option3', 'option4']}
iconName="md-more"
iconStyle={styles.dropdownIconStyle}
isHasChildIcon
/>
</View>
</StickyBar>
);
};
render() { render() {
const { isPreviewActive, intl } = this.props; const { isPreviewActive, intl } = this.props;
const { text, selection } = this.state; const { text, selection } = this.state;
ImagePicker.openPicker({
width: 300,
height: 400,
cropping: true
}).then(image => {
console.log(image);
});
return ( return (
<KeyboardAvoidingView style={styles.container} behavior="padding"> <KeyboardAvoidingView style={styles.container} behavior="padding">
{!isPreviewActive ? ( {!isPreviewActive ? (

View File

@ -15,4 +15,30 @@ export default EStyleSheet.create({
borderTopLeftRadius: 10, borderTopLeftRadius: 10,
borderTopRightRadius: 10, borderTopRightRadius: 10,
}, },
modalHeader: {
backgroundColor: '$primaryBackgroundColor',
flexDirection: 'row',
height: 40,
justifyContent: 'center',
},
headerTitle: {
color: '$iconColor',
alignSelf: 'center',
fontSize: 24,
marginLeft: 16,
flexGrow: 1,
fontWeight: '500',
},
closeButton: {
marginRight: 24,
justifyContent: 'center',
alignSelf: 'center',
},
closeIcon: {
fontSize: 24,
color: '$iconColor',
},
safeArea: {
backgroundColor: '$primaryBackgroundColor',
},
}); });

View File

@ -1,6 +1,8 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Modal as ModalBox } from 'react-native'; import {
Modal as ModalBox, View, Text, SafeAreaView,
} from 'react-native';
import { IconButton } from '../../iconButton';
import styles from './modalStyles'; import styles from './modalStyles';
/* /*
@ -32,7 +34,14 @@ export default class Modal extends Component {
render() { render() {
const { const {
isFullScreen, isOpen, children, isRadius, isTransparent, isFullScreen,
isOpen,
children,
isRadius,
isTransparent,
title,
animationType,
isCloseButton,
} = this.props; } = this.props;
return ( return (
<ModalBox <ModalBox
@ -47,6 +56,22 @@ export default class Modal extends Component {
onShow={() => this._handleOnOpen(this)} onShow={() => this._handleOnOpen(this)}
{...this.props} {...this.props}
> >
{title && (
<SafeAreaView style={styles.safeArea}>
<View style={styles.modalHeader}>
<Text style={styles.headerTitle}>{title}</Text>
{isCloseButton && (
<IconButton
style={styles.closeButton}
iconType="FontAwesome"
iconStyle={styles.closeIcon}
name="close"
onPress={() => this._handleOnClose()}
/>
)}
</View>
</SafeAreaView>
)}
{children} {children}
</ModalBox> </ModalBox>
); );

View File

@ -15,10 +15,17 @@ class PostButtonContainer extends Component {
// Component Functions // Component Functions
_handleSubButtonPress = (route) => { _handleSubButtonPress = (route, action) => {
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate(route); navigation.navigate({
routeName: route,
params: {
action,
},
});
// navigation.navigate(route);
}; };
render() { render() {

View File

@ -84,7 +84,7 @@ class PostButtonView extends Component {
}); });
const thirdX = this.icon3.interpolate({ const thirdX = this.icon3.interpolate({
inputRange: [0, 1], inputRange: [0, 1],
outputRange: [25, 90], outputRange: [25, 85],
}); });
const thirdY = this.icon3.interpolate({ const thirdY = this.icon3.interpolate({
inputRange: [0, 1], inputRange: [0, 1],
@ -106,8 +106,8 @@ class PostButtonView extends Component {
left: firstX, left: firstX,
top: firstY, top: firstY,
}} }}
icon="camera" icon="video-camera"
onPress={() => handleSubButtonPress(ROUTES.SCREENS.EDITOR)} onPress={() => handleSubButtonPress(ROUTES.SCREENS.EDITOR, 'camera')}
/> />
<SubPostButton <SubPostButton
size={SIZE} size={SIZE}
@ -124,8 +124,8 @@ class PostButtonView extends Component {
left: thirdX, left: thirdX,
top: thirdY, top: thirdY,
}} }}
icon="video-camera" icon="camera"
onPress={() => handleSubButtonPress(ROUTES.SCREENS.EDITOR)} onPress={() => handleSubButtonPress(ROUTES.SCREENS.EDITOR, 'image')}
/> />
<TouchableOpacity onPress={this.toggleView} activeOpacity={1}> <TouchableOpacity onPress={this.toggleView} activeOpacity={1}>
<Animated.View <Animated.View

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ImagePicker from 'react-native-image-crop-picker';
// Services and Actions // Services and Actions
import { postContent } from '../../../providers/steem/dsteem'; import { postContent } from '../../../providers/steem/dsteem';
@ -32,6 +33,8 @@ class ExampleContainer extends Component {
isDraftSaving: false, isDraftSaving: false,
isDraftSaved: false, isDraftSaved: false,
draftPost: null, draftPost: null,
isCameraOrPickerOpen: false,
autoFocusText: false,
}; };
} }
@ -39,8 +42,16 @@ class ExampleContainer extends Component {
// Component Functions // Component Functions
componentWillMount() { componentWillMount() {
const { currentAccount } = this.props; const { currentAccount, navigation } = this.props;
const username = currentAccount && currentAccount.name ? currentAccount.name : ''; const username = currentAccount && currentAccount.name ? currentAccount.name : '';
const routingAction = navigation.state && navigation.state.params;
// Routing action state ex if coming for video or image or only text
if (routingAction && routingAction.action) {
this._handleRoutingAction(routingAction.action);
} else {
this.setState({ autoFocusText: true });
}
getDraftPost(username) getDraftPost(username)
.then((result) => { .then((result) => {
@ -53,6 +64,60 @@ class ExampleContainer extends Component {
}); });
} }
_handleRoutingAction = (routingAction) => {
this.setState({ isCameraOrPickerOpen: true });
if (routingAction === 'camera') {
this._handleOpenCamera();
} else if (routingAction === 'image') {
this._handleOpenImagePicker();
}
};
// Media select functions <- START ->
_handleOpenImagePicker = () => {
ImagePicker.openPicker({
width: 300,
height: 400,
cropping: true,
// multiple: true,
})
.then((image) => {
this._handleMediaOnSelected(image);
})
.catch((e) => {
this._handleMediaOnSelectFailure(e);
});
};
_handleOpenCamera = () => {
ImagePicker.openCamera({
width: 300,
height: 400,
cropping: true,
})
.then((image) => {
this._handleMediaOnSelected(image);
})
.catch((e) => {
this._handleMediaOnSelectFailure(e);
});
};
// TODO: keyboard opening bug fixed
_handleMediaOnSelected = (media) => {
this.setState({ isCameraOrPickerOpen: false });
console.log(media);
};
_handleMediaOnSelectFailure = (error) => {
const { navigation } = this.props;
this.setState({ isCameraOrPickerOpen: false });
navigation.navigate(ROUTES.SCREENS.HOME);
};
// Media select functions <- END ->
_handleOnSaveButtonPress = (fields) => { _handleOnSaveButtonPress = (fields) => {
const { isDraftSaved } = this.state; const { isDraftSaved } = this.state;
if (!isDraftSaved) { if (!isDraftSaved) {
@ -112,13 +177,21 @@ class ExampleContainer extends Component {
_handleFormChanged = () => { _handleFormChanged = () => {
const { isDraftSaved } = this.state; const { isDraftSaved } = this.state;
isDraftSaved && this.setState({ isDraftSaved: false });
if (isDraftSaved) {
this.setState({ isDraftSaved: false });
}
}; };
render() { render() {
const { isLoggedIn, isDarkTheme } = this.props; const { isLoggedIn, isDarkTheme } = this.props;
const { const {
isPostSending, isDraftSaving, isDraftSaved, draftPost, draftPost,
isDraftSaved,
isDraftSaving,
isOpenCamera,
isCameraOrPickerOpen,
autoFocusText,
} = this.state; } = this.state;
return ( return (
@ -127,11 +200,14 @@ class ExampleContainer extends Component {
handleFormChanged={this._handleFormChanged} handleFormChanged={this._handleFormChanged}
handleOnSaveButtonPress={this._handleOnSaveButtonPress} handleOnSaveButtonPress={this._handleOnSaveButtonPress}
handleOnSubmit={this._handleSubmit} handleOnSubmit={this._handleSubmit}
handleOnImagePicker={this._handleOpenImagePicker}
isDarkTheme={isDarkTheme} isDarkTheme={isDarkTheme}
isDraftSaved={isDraftSaved} isDraftSaved={isDraftSaved}
isDraftSaving={isDraftSaving} isDraftSaving={isDraftSaving}
isLoggedIn={isLoggedIn} isLoggedIn={isLoggedIn}
isPostSending={isPostSending} isOpenCamera={isOpenCamera}
isCameraOrPickerOpen={isCameraOrPickerOpen}
autoFocusText={autoFocusText}
/> />
); );
} }

View File

@ -26,7 +26,6 @@ class EditorScreen extends Component {
isPreviewActive: false, isPreviewActive: false,
wordsCount: null, wordsCount: null,
isFormValid: false, isFormValid: false,
isChanged: false,
fields: { fields: {
title: (props.draftPost && props.draftPost.title) || '', title: (props.draftPost && props.draftPost.title) || '',
body: (props.draftPost && props.draftPost.body) || '', body: (props.draftPost && props.draftPost.body) || '',
@ -109,8 +108,6 @@ class EditorScreen extends Component {
handleFormChanged(); handleFormChanged();
this._handleIsFormValid(); this._handleIsFormValid();
this.setState({ isChanged: true });
}; };
_handleOnTagAdded = (tags) => { _handleOnTagAdded = (tags) => {
@ -123,10 +120,16 @@ class EditorScreen extends Component {
render() { render() {
const { const {
isPreviewActive, wordsCount, isFormValid, fields, isChanged, isPreviewActive, wordsCount, isFormValid, fields,
} = this.state; } = this.state;
const { const {
isLoggedIn, isPostSending, isDraftSaving, isDraftSaved, draftPost, intl isLoggedIn,
isPostSending,
isDraftSaving,
isDraftSaved,
intl,
handleOnImagePicker,
autoFocusText,
} = this.props; } = this.props;
return ( return (
@ -150,8 +153,14 @@ class EditorScreen extends Component {
isPreviewActive={isPreviewActive} isPreviewActive={isPreviewActive}
isFormValid={isFormValid} isFormValid={isFormValid}
> >
<TitleArea value={fields.title} componentID="title" intl={intl} /> <TitleArea
autoFocus={autoFocusText}
value={fields.title}
componentID="title"
intl={intl}
/>
<TagArea <TagArea
autoFocus={autoFocusText}
draftChips={fields.tags} draftChips={fields.tags}
componentID="tag-area" componentID="tag-area"
handleTagChanged={this._handleOnTagAdded} handleTagChanged={this._handleOnTagAdded}
@ -162,6 +171,7 @@ class EditorScreen extends Component {
handleOnTextChange={this._setWordsCount} handleOnTextChange={this._setWordsCount}
componentID="body" componentID="body"
intl={intl} intl={intl}
handleOpenImagePicker={handleOnImagePicker}
/> />
</PostForm> </PostForm>
</View> </View>

View File

@ -28,7 +28,7 @@ export default {
$disableButton: '#fff', $disableButton: '#fff',
$shadowColor: '#b0b0b0', $shadowColor: '#b0b0b0',
$disableGray: '#fff', $disableGray: '#fff',
$editorButtonColor: '#fff',
// Devices Sizes // Devices Sizes
$deviceHeight: Dimensions.get('window').height, $deviceHeight: Dimensions.get('window').height,
$deviceWidth: Dimensions.get('window').width, $deviceWidth: Dimensions.get('window').width,

View File

@ -28,7 +28,7 @@ export default {
$disableButton: '#fff', $disableButton: '#fff',
$shadowColor: '#b0b0b0', $shadowColor: '#b0b0b0',
$disableGray: '#fff', $disableGray: '#fff',
$editorButtonColor: '#3c4449',
// Devices Sizes // Devices Sizes
$deviceHeight: Dimensions.get('window').height, $deviceHeight: Dimensions.get('window').height,
$deviceWidth: Dimensions.get('window').width, $deviceWidth: Dimensions.get('window').width,