From 776223aa95d762468700c3874113719988f80ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Furkan=20K=C4=B1l=C4=B1c=CC=A7?= Date: Tue, 5 Jan 2021 00:30:25 +0300 Subject: [PATCH] Fix schedule post feature according to the updated endpoint --- ios/Podfile.lock | 6 ++ package.json | 2 +- .../basicHeader/view/basicHeaderStyles.js | 4 + .../basicHeader/view/basicHeaderView.js | 48 ++++++++-- .../view/dateTimePickerStyles.js | 2 +- .../dateTimePicker/view/dateTimePickerView.js | 91 ++++--------------- src/components/modal/view/modalStyles.js | 5 + src/components/modal/view/modalView.js | 16 +++- src/config/locales/en-US.json | 3 +- src/providers/ecency/ecency.js | 10 +- .../editor/container/editorContainer.js | 72 ++++++++++----- yarn.lock | 11 +-- 12 files changed, 144 insertions(+), 126 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e58eed367..929a14e0d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -315,6 +315,8 @@ PODS: - react-native-config/App (= 1.3.3) - react-native-config/App (1.3.3): - React + - react-native-date-picker (3.2.7): + - React-Core - react-native-matomo-sdk (0.4.1): - MatomoTracker (~> 7) - React (~> 0.60) @@ -446,6 +448,7 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - "react-native-cameraroll (from `../node_modules/@react-native-community/cameraroll`)" - react-native-config (from `../node_modules/react-native-config`) + - react-native-date-picker (from `../node_modules/react-native-date-picker`) - react-native-matomo-sdk (from `../node_modules/react-native-matomo-sdk`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-receive-sharing-intent (from `../node_modules/react-native-receive-sharing-intent`) @@ -555,6 +558,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/cameraroll" react-native-config: :path: "../node_modules/react-native-config" + react-native-date-picker: + :path: "../node_modules/react-native-date-picker" react-native-matomo-sdk: :path: "../node_modules/react-native-matomo-sdk" react-native-netinfo: @@ -668,6 +673,7 @@ SPEC CHECKSUMS: React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 react-native-cameraroll: e2917a5e62da9f10c3d525e157e25e694d2d6dfa react-native-config: 9a061347e0136fdb32d43a34d60999297d672361 + react-native-date-picker: 5b66e04e7ed02478feb77a41d254ba24f120f956 react-native-matomo-sdk: 025c54f92e1e26a4d0acee7c3f28cb0fc7e4729c react-native-netinfo: a53b00d949b6456913aaf507d9dba90c4008c611 react-native-receive-sharing-intent: feba0a332a07977549a85aa58b496eb44368366a diff --git a/package.json b/package.json index e6d4c9e0f..66b5ae62d 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "react-native-autoheight-webview": "^1.5.2", "react-native-config": "luggit/react-native-config#master", "react-native-dark-mode": "^0.2.2", - "react-native-datepicker": "ecency/react-native-datepicker", + "react-native-date-picker": "^3.2.7", "react-native-extended-stylesheet": "^0.10.0", "react-native-fast-image": "^8.3.2", "react-native-gesture-handler": "^1.4.1", diff --git a/src/components/basicHeader/view/basicHeaderStyles.js b/src/components/basicHeader/view/basicHeaderStyles.js index 5d7ab8139..b34b05052 100644 --- a/src/components/basicHeader/view/basicHeaderStyles.js +++ b/src/components/basicHeader/view/basicHeaderStyles.js @@ -80,4 +80,8 @@ export default EStyleSheet.create({ fontWeight: '500', width: '$deviceWidth / 1.4', }, + dateTimeModal: { + backgroundColor: '$primaryBackgroundColor', + alignItems: 'center', + }, }); diff --git a/src/components/basicHeader/view/basicHeaderView.js b/src/components/basicHeader/view/basicHeaderView.js index 4b0e87a12..5cd77a9c3 100644 --- a/src/components/basicHeader/view/basicHeaderView.js +++ b/src/components/basicHeader/view/basicHeaderView.js @@ -3,6 +3,7 @@ import { View, Text, ActivityIndicator, SafeAreaView } from 'react-native'; import { injectIntl } from 'react-intl'; import ActionSheet from 'react-native-actionsheet'; import { useSelector } from 'react-redux'; +import moment from 'moment'; // Components import { TextButton, Modal, BeneficiaryModal } from '../..'; @@ -48,6 +49,8 @@ const BasicHeaderView = ({ }) => { const [isInputVisible, setIsInputVisible] = useState(false); const [beneficiaryModal, setBeneficiaryModal] = useState(false); + const [showScheduleModal, setShowScheduleModal] = useState(false); + const [scheduledDate, setScheduledDate] = useState(''); const username = useSelector((state) => state.account.currentAccount.name); @@ -78,7 +81,7 @@ const BasicHeaderView = ({ const _handleSettingMenuSelect = (index) => { switch (index) { case 0: - scheduleRef.current.onPressDate(); + setShowScheduleModal(true); break; case 1: rewardMenuRef.current.show(); @@ -123,9 +126,19 @@ const BasicHeaderView = ({ }; const _handleDatePickerChange = (datePickerValue) => { - if (handleDatePickerChange) { - handleDatePickerChange(datePickerValue); + setScheduledDate(datePickerValue); + }; + + const _onPressDone = () => { + let dateString = scheduledDate; + + if (dateString === '') { + dateString = moment().format(); } + + setScheduledDate(''); + handleDatePickerChange(dateString); + setShowScheduleModal(false); }; return ( @@ -149,18 +162,11 @@ const BasicHeaderView = ({ disabled={disabled} /> )} - {!isInputVisible && ( {quickTitle || title} )} - {isHasDropdown && ( {dropdownComponent ? ( @@ -264,6 +270,28 @@ const BasicHeaderView = ({ handleOnSaveBeneficiaries={_handleOnSaveBeneficiaries} /> + setShowScheduleModal(false)} + > + + + + { - const [date, setDate] = useState(''); - const [time, setTime] = useState(''); - let _type; - let _format; - let _minDate; +const DateTimePickerView = React.forwardRef(({ type, iconName, disabled, onChanged }, ref) => { + const [androidDate, setAndroidDate] = useState(moment(Date.now())); - const intl = useIntl(); - const innerRef = useRef(null); - const datePickerRef = useCombinedRefs(ref, innerRef); + const _setDate = (date) => { + if (date) { + if (Platform.OS === 'android') { + setAndroidDate(date); + } - if (type === 'date-time') { - _type = date ? 'time' : 'date'; - _format = date ? 'HH:mm' : 'YYYY-MM-DD'; - _minDate = date ? null : moment().format('YYYY-MM-DD'); - } else { - _type = type; - _format = type === 'date' ? 'YYYY-MM-DD' : 'HH:mm'; - _minDate = type === 'date' ? moment().format('YYYY-MM-DD') : null; - } + const formattedDate = moment(date).format(); - const _initState = () => { - setDate(''); - setTime(''); - }; - - const _setValue = (setFunc, value) => { - const _value = value === 'Invalid date' ? moment().format('HH:mm:ss') : value; - setFunc(_value); - let timePickerTimeout; - - if (!time && !date) { - timePickerTimeout = setTimeout(() => { - datePickerRef.onPressDate(); - }, 500); - } else { - clearTimeout(timePickerTimeout); - } - - if (date && _value) { - const formatedDateTime = moment(`${date} ${_value}`, 'YYYY-MM-DD HH:mm').toISOString(); - onSubmit(formatedDateTime); - _initState(); + onChanged(formattedDate); } }; return ( _setValue(!date ? setDate : setTime, _datePickerValue)} - hideText - is24Hour - ref={datePickerRef} - disabled={disabled} - customStyles={{ - ...styles, - }} - showIcon={false} - // iconComponent={ - // // eslint-disable-next-line react/jsx-wrap-multilines - // - // } + minimumDate={Platform.OS === 'ios' ? new Date() : moment(Date.now())} + androidVariant="iosClone" + is24hourSource="device" /> ); }); -DateTimePickerView.defaultProps = { - iconName: 'timer', - type: 'date', -}; - export default DateTimePickerView; diff --git a/src/components/modal/view/modalStyles.js b/src/components/modal/view/modalStyles.js index a63af276c..6460ec8f5 100644 --- a/src/components/modal/view/modalStyles.js +++ b/src/components/modal/view/modalStyles.js @@ -18,6 +18,7 @@ export default EStyleSheet.create({ flexDirection: 'row', padding: 16, justifyContent: 'center', + alignItems: 'center', }, headerTitle: { color: '$primaryBlack', @@ -41,4 +42,8 @@ export default EStyleSheet.create({ margin: 0, backgroundColor: 'rgba(0,0,0,0.35)', }, + rightText: { + color: '$primaryBlack', + padding: 10, + }, }); diff --git a/src/components/modal/view/modalView.js b/src/components/modal/view/modalView.js index ac2480242..27183cdda 100644 --- a/src/components/modal/view/modalView.js +++ b/src/components/modal/view/modalView.js @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { View, Text, SafeAreaView } from 'react-native'; +import { View, Text, TouchableOpacity } from 'react-native'; import ModalBox from 'react-native-modal'; import { IconButton } from '../../iconButton'; import styles from './modalStyles'; @@ -50,6 +50,9 @@ export default class Modal extends PureComponent { animationType = 'fade', isCloseButton, isBottomModal = false, + hasRightText = false, + rightText, + onPressRightText, } = this.props; return ( {title && ( - {title} + + {title} + {isCloseButton && ( this._handleOnClose()} /> )} + {hasRightText && ( + + {rightText} + + )} )} {children} diff --git a/src/config/locales/en-US.json b/src/config/locales/en-US.json index 2fa5ae0ca..4dcc2e1a4 100644 --- a/src/config/locales/en-US.json +++ b/src/config/locales/en-US.json @@ -297,7 +297,8 @@ "options": "Options", "my_blog": "My Blog", "my_communities": "My Communities", - "top_communities": "Top Communities" + "top_communities": "Top Communities", + "schedule_modal_title": "Schedule Post" }, "pincode": { "enter_text": "Enter PIN to unlock", diff --git a/src/providers/ecency/ecency.js b/src/providers/ecency/ecency.js index b74c52b85..9fa12ebc3 100644 --- a/src/providers/ecency/ecency.js +++ b/src/providers/ecency/ecency.js @@ -307,20 +307,18 @@ export const schedule = ( operationType, upvote, scheduleDate, + options = null, ) => api .post('/schedules', { username: user, - category: tags[0], title, permlink, - json: jsonStringify(json), - tags, + meta: json, body, - post_type: operationType, - upvote_this: upvote, schedule: scheduleDate, - chain: 'hive', + options, + reblog: 0, }) .then((resp) => resp.data); diff --git a/src/screens/editor/container/editorContainer.js b/src/screens/editor/container/editorContainer.js index 0997a4d08..a69915af6 100644 --- a/src/screens/editor/container/editorContainer.js +++ b/src/screens/editor/container/editorContainer.js @@ -336,6 +336,7 @@ class EditorContainer extends Component { permlink, fields, scheduleDate, + jsonMeta, }); } else { await postContent( @@ -595,46 +596,67 @@ class EditorContainer extends Component { _handleDatePickerChange = async (datePickerValue, fields) => { const { currentAccount, pinCode, intl } = this.props; - const json = get(currentAccount, 'posting_json_metadata', ''); - - let hasPostingPerm = false; - - if (currentAccount && currentAccount.posting) { - hasPostingPerm = - currentAccount.posting.account_auths.filter((x) => x[0] === 'ecency.app').length > 0; - } - - if (hasPostingPerm) { - this._submitPost(fields, datePickerValue); + if (fields.title === '' && fields.body === '') { + const timer = setTimeout(() => { + Alert.alert( + intl.formatMessage({ + id: 'alert.fail', + }), + 'Title and body can not be empty', + ); + clearTimeout(timer); + }, 100); } else { - await grantPostingPermission(json, pinCode, currentAccount) - .then(() => { - this._submitPost(fields, datePickerValue); - }) - .catch((error) => { - Alert.alert( - intl.formatMessage({ - id: 'alert.fail', - }), - get(error, 'message', error.toString()), - ); - }); + const json = get(currentAccount, 'posting_json_metadata', ''); + + let hasPostingPerm = false; + + if (currentAccount && currentAccount.posting) { + hasPostingPerm = + currentAccount.posting.account_auths.filter((x) => x[0] === 'ecency.app').length > 0; + } + + if (hasPostingPerm) { + this._submitPost(fields, datePickerValue); + } else { + await grantPostingPermission(json, pinCode, currentAccount) + .then(() => { + this._submitPost(fields, datePickerValue); + }) + .catch((error) => { + Alert.alert( + intl.formatMessage({ + id: 'alert.fail', + }), + get(error, 'message', error.toString()), + ); + }); + } } }; _setScheduledPost = (data) => { const { dispatch, intl, currentAccount, navigation } = this.props; + const { rewardType, beneficiaries } = this.state; + + const options = makeOptions({ + author: data.author, + permlink: data.permlink, + operationType: rewardType, + beneficiaries: beneficiaries, + }); schedule( data.author, data.fields.title, data.permlink, - '', + data.jsonMeta, data.fields.tags, data.fields.body, '', '', data.scheduleDate, + options, ) .then(() => { this.setState({ @@ -662,7 +684,7 @@ class EditorContainer extends Component { }); }, 3000); }) - .catch(() => { + .catch((err) => { this.setState({ isPostSending: false, }); diff --git a/yarn.lock b/yarn.lock index 8004bf2aa..6d3da8f86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6440,7 +6440,7 @@ mkdirp@~1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -moment@^2.22.0, moment@^2.22.2: +moment@^2.22.2: version "2.27.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== @@ -7493,11 +7493,10 @@ react-native-dark-mode@^0.2.2: events "^3.0.0" toolkit.ts "^0.0.2" -react-native-datepicker@ecency/react-native-datepicker: - version "1.7.2" - resolved "https://codeload.github.com/ecency/react-native-datepicker/tar.gz/844955f20ede921e6a8b83d95c58167970f9279b" - dependencies: - moment "^2.22.0" +react-native-date-picker@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/react-native-date-picker/-/react-native-date-picker-3.2.7.tgz#1708c2fc712c09ce6eaca007635a036dba4ca107" + integrity sha512-7JXwnEF4TxST6+yKYzscCxx8BWQLBpNVxUmVYbaXkhdLSTO1QlypukVeQMZ9QtuRAhf4zs3NDiYqZDu9JdeGAA== react-native-extended-stylesheet@^0.10.0: version "0.10.0"