diff --git a/package.json b/package.json index 2c0ce9cbd..08c9c8c14 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dsteem": "^0.10.1", "intl": "^1.2.5", "jsc-android": "^236355.1.1", + "lodash": "^4.17.11", "moment": "^2.22.2", "react": "^16.7.0", "react-intl": "^2.7.2", diff --git a/src/components/basicHeader/view/basicHeaderView.js b/src/components/basicHeader/view/basicHeaderView.js index 8a3dc02ef..95fc53c19 100644 --- a/src/components/basicHeader/view/basicHeaderView.js +++ b/src/components/basicHeader/view/basicHeaderView.js @@ -97,6 +97,7 @@ class BasicHeaderView extends Component { title, } = this.props; const { isInputVisible, datePickerValue } = this.state; + return ( diff --git a/src/components/editorElements/tagArea/view/tagAreaView.js b/src/components/editorElements/tagArea/view/tagAreaView.js index 7c9a1d3ba..52a30caf7 100644 --- a/src/components/editorElements/tagArea/view/tagAreaView.js +++ b/src/components/editorElements/tagArea/view/tagAreaView.js @@ -43,9 +43,11 @@ export default class TagAreaView extends Component { // Component Functions _handleOnChange = (text, i) => { this.setState({ currentText: text.replace(/\s/g, '') }); + if (text.indexOf(' ') > 0 && text) { this._handleTagAdded(); } + if (!text) { this._handleTagRemove(i); } diff --git a/src/screens/editor/container/editorContainer.js b/src/screens/editor/container/editorContainer.js index 12c05bed0..3e91770ee 100644 --- a/src/screens/editor/container/editorContainer.js +++ b/src/screens/editor/container/editorContainer.js @@ -3,6 +3,7 @@ import { connect } from 'react-redux'; import { injectIntl } from 'react-intl'; import { Alert, AsyncStorage } from 'react-native'; import ImagePicker from 'react-native-image-crop-picker'; +import get from 'lodash/get'; // Services and Actions import { Buffer } from 'buffer'; @@ -122,6 +123,7 @@ class EditorContainer extends Component { _getDraft = async (username, isReply) => { if (isReply) { const draftReply = await AsyncStorage.getItem('temp-reply'); + if (draftReply) { this.setState({ draftPost: { body: draftReply }, @@ -137,9 +139,6 @@ class EditorContainer extends Component { tags: result.tags.split(','), }, }); - }) - .catch(() => { - // alert(error); }); } }; @@ -223,7 +222,7 @@ class EditorContainer extends Component { const { intl } = this.props; this.setState({ isCameraOrPickerOpen: false }); - if (error.code === 'E_PERMISSION_MISSING') { + if (get(error, 'code') === 'E_PERMISSION_MISSING') { Alert.alert( intl.formatMessage({ id: 'alert.permission_denied', @@ -235,28 +234,30 @@ class EditorContainer extends Component { } }; - // Media select functions <- END -> - _saveDraftToDB = (fields) => { const { isDraftSaved, draftId } = this.state; + if (!isDraftSaved) { const { currentAccount } = this.props; - const username = currentAccount && currentAccount.name ? currentAccount.name : ''; + const username = get(currentAccount, 'name', ''); + let draftField; this.setState({ isDraftSaving: true }); - const draftField = { - ...fields, - tags: fields.tags.join(' '), - username, - }; + if (fields) { + draftField = { + ...fields, + tags: fields.tags.join(' '), + username, + }; + } - if (draftId) { + if (draftId && draftField) { updateDraft({ ...draftField, draftId }).then(() => { this.setState({ isDraftSaved: true, }); }); - } else { + } else if (draftField) { addDraft(draftField).then((response) => { this.setState({ isDraftSaved: true, @@ -267,6 +268,7 @@ class EditorContainer extends Component { this.setState({ isDraftSaving: false, + isDraftSaved, }); } }; @@ -346,15 +348,6 @@ class EditorContainer extends Component { 0, ) .then(() => { - // Alert.alert( - // intl.formatMessage({ - // id: 'alert.success', - // }), - // intl.formatMessage({ - // id: 'alert.success_shared', - // }), - // ); - dispatch( toastNotification( intl.formatMessage({ @@ -488,8 +481,10 @@ class EditorContainer extends Component { _handleSubmitSuccess = () => { const { navigation } = this.props; - navigation.goBack(); - navigation.state.params.fetchPost(); + if (navigation) { + navigation.goBack(); + navigation.state.params.fetchPost(); + } }; _handleOnBackPress = () => { @@ -526,7 +521,7 @@ class EditorContainer extends Component { }; _setScheduledPost = (data) => { - const { dispatch } = this.props; + const { dispatch, intl } = this.props; schedule( data.author, @@ -542,10 +537,9 @@ class EditorContainer extends Component { this.setState({ isPostSending: false }); dispatch( toastNotification( - // intl.formatMessage({ - // id: 'alert.copied', - // }), - 'Scheduled', + intl.formatMessage({ + id: 'alert.success', + }), ), ); }).catch(() => { @@ -553,6 +547,17 @@ class EditorContainer extends Component { }); } + _initialEditor = () => { + const { currentAccount: { name } } = this.props; + + setDraftPost( + { title: '', body: '', tags: '' }, + name, + ); + + this.setState({ uploadedImage: null }); + } + render() { const { isLoggedIn, isDarkTheme } = this.props; const { @@ -579,6 +584,7 @@ class EditorContainer extends Component { handleOnBackPress={this._handleOnBackPress} handleOnImagePicker={this._handleRoutingAction} handleOnSubmit={this._handleSubmit} + initialEditor={this._initialEditor} isCameraOrPickerOpen={isCameraOrPickerOpen} isDarkTheme={isDarkTheme} isDraftSaved={isDraftSaved} diff --git a/src/screens/editor/screen/editorScreen.js b/src/screens/editor/screen/editorScreen.js index d34fdca80..b34d9072b 100644 --- a/src/screens/editor/screen/editorScreen.js +++ b/src/screens/editor/screen/editorScreen.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { View } from 'react-native'; import { injectIntl } from 'react-intl'; +import get from 'lodash/get'; // Utils import { getWordsCount } from '../../../utils/editor'; @@ -57,6 +58,8 @@ class EditorScreen extends Component { // Component Functions _initialFields = () => { + const { initialEditor } = this.props; + this.setState({ fields: { title: '', @@ -66,6 +69,8 @@ class EditorScreen extends Component { }, isRemoveTag: true, }); + + if (initialEditor) initialEditor(); }; _handleOnPressPreviewButton = () => { @@ -115,24 +120,23 @@ class EditorScreen extends Component { _handleIsFormValid = (bodyText) => { const { fields } = this.state; const { isReply } = this.props; - let _isFormValid; + let isFormValid; if (isReply) { - _isFormValid = fields && fields.body && fields.body.length > 0; + isFormValid = get(fields, 'body').length > 0; } else { - _isFormValid = fields - && fields.title - && fields.title.length > 0 - && ((fields.body && fields.body.length > 0 && fields.tags.length > 0) - || (bodyText && bodyText.length > 0)); + isFormValid = get(fields, 'title', '') + && (get(fields, 'body', '') || (bodyText && bodyText > 0)) + && get(fields, 'tags', null); } - this.setState({ isFormValid: _isFormValid }); + this.setState({ isFormValid }); }; _handleFormUpdate = (componentID, content) => { - const { handleFormChanged, isReply } = this.props; - const fields = { ...this.state.fields }; + const { handleFormChanged } = this.props; + const { fields: _fields } = this.state; + const fields = { ..._fields }; if (componentID === 'body') { fields.body = content; @@ -140,20 +144,26 @@ class EditorScreen extends Component { fields.title = content; } - this.setState({ fields }); + if ((get(fields, 'body', '').trim() !== get(_fields, 'body', '').trim() + || get(fields, 'title', '').trim() !== get(_fields, 'title', '').trim() + || get(fields, 'tags') !== get(_fields, 'tags'))) { + handleFormChanged(); + } - handleFormChanged(); + this.setState({ fields }); this._handleIsFormValid(); this._saveCurrentDraft(); }; - _handleOnTagAdded = (tags) => { + _handleOnTagAdded = async (tags) => { + const { fields: _fields } = this.state; const _tags = tags.filter(tag => tag && tag !== ' '); - const fields = { ...this.state.fields }; - fields.tags = _tags; - this.setState({ fields, isRemoveTag: false }); + const fields = { ..._fields, tags: [..._tags] }; + await this.setState({ fields, isRemoveTag: false }); + + this._handleFormUpdate(); }; render() { @@ -161,7 +171,6 @@ class EditorScreen extends Component { fields, isPreviewActive, wordsCount, isFormValid, isRemoveTag, } = this.state; const { - draftPost, handleOnImagePicker, intl, isDraftSaved,