mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-19 11:21:41 +03:00
Merge pull request #1887 from ecency/nt/post-draft-master
Nt/post draft master
This commit is contained in:
commit
8c214a0927
File diff suppressed because one or more lines are too long
@ -1,22 +1,22 @@
|
||||
PODS:
|
||||
- appcenter-analytics (3.1.0):
|
||||
- AppCenter/Analytics
|
||||
- AppCenterReactNativeShared
|
||||
- React
|
||||
- appcenter-core (3.1.0):
|
||||
- AppCenterReactNativeShared
|
||||
- React
|
||||
- appcenter-crashes (3.1.0):
|
||||
- AppCenter/Crashes
|
||||
- AppCenterReactNativeShared
|
||||
- React
|
||||
- AppCenter/Analytics (3.3.4):
|
||||
- appcenter-analytics (4.1.0):
|
||||
- AppCenter/Analytics (~> 4.0)
|
||||
- AppCenterReactNativeShared (~> 4.0)
|
||||
- React-Core
|
||||
- appcenter-core (4.1.0):
|
||||
- AppCenterReactNativeShared (~> 4.0)
|
||||
- React-Core
|
||||
- appcenter-crashes (4.1.0):
|
||||
- AppCenter/Crashes (~> 4.0)
|
||||
- AppCenterReactNativeShared (~> 4.0)
|
||||
- React-Core
|
||||
- AppCenter/Analytics (4.1.1):
|
||||
- AppCenter/Core
|
||||
- AppCenter/Core (3.3.4)
|
||||
- AppCenter/Crashes (3.3.4):
|
||||
- AppCenter/Core (4.1.1)
|
||||
- AppCenter/Crashes (4.1.1):
|
||||
- AppCenter/Core
|
||||
- AppCenterReactNativeShared (3.1.2):
|
||||
- AppCenter/Core (= 3.3.4)
|
||||
- AppCenterReactNativeShared (4.1.0):
|
||||
- AppCenter/Core (= 4.1.1)
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BugsnagReactNative (2.23.10):
|
||||
- BugsnagReactNative/Core (= 2.23.10)
|
||||
@ -641,11 +641,11 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppCenter: 0487be185c038ed2ecc5ed38219af1dcd280af23
|
||||
appcenter-analytics: cca12b5d07593a309e99db475f6da7f1a61ae694
|
||||
appcenter-core: cd5eaa48cfc6dd87dad2912d6718f21f4955327f
|
||||
appcenter-crashes: 369cc9160392c137b791304ee96957f28ef143d1
|
||||
AppCenterReactNativeShared: 66667cd2dfad295b84bbf0f462e0e139e2128284
|
||||
AppCenter: cd53e3ed3563cc720bcb806c9731a12389b40d44
|
||||
appcenter-analytics: aa074250b2cb182d6f7d67d9c236dd4606673ab5
|
||||
appcenter-core: c97920e79eba2321a262d3733cb2a6f1097db539
|
||||
appcenter-crashes: 804ae51c5d1742ce20fdb6a68b3d06208a404ad5
|
||||
AppCenterReactNativeShared: 2d5a53b6cbd2fe7f63f0033e9f0a40757a4eacf5
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BugsnagReactNative: 98fb350df4bb0c94cce903023531a1a5cc11fa51
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
|
@ -45,9 +45,9 @@
|
||||
"@react-native-firebase/app": "^8.4.7",
|
||||
"@react-native-firebase/dynamic-links": "^7.4.2",
|
||||
"@react-native-firebase/messaging": "^7.4.2",
|
||||
"appcenter": "3.1.0",
|
||||
"appcenter-analytics": "3.1.0",
|
||||
"appcenter-crashes": "3.1.0",
|
||||
"appcenter": "^4.1.0",
|
||||
"appcenter-analytics": "^4.1.0",
|
||||
"appcenter-crashes": "^4.1.0",
|
||||
"axios": "^0.21.1",
|
||||
"buffer": "^5.4.3",
|
||||
"bugsnag-react-native": "^2.23.10",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
container: {
|
||||
@ -9,12 +10,12 @@ export default EStyleSheet.create({
|
||||
textWrapper: {
|
||||
fontSize: 12,
|
||||
paddingTop: 16,
|
||||
paddingBottom: 0, // On android side, textinput has default padding
|
||||
paddingBottom: Platform.OS === 'ios' ? 32 : 0, // On android side, textinput has default padding
|
||||
paddingHorizontal: 16,
|
||||
color: '$primaryBlack',
|
||||
backgroundColor: '$primaryBackgroundColor',
|
||||
// fontFamily: '$editorFont',
|
||||
// textAlignVertical: 'top',
|
||||
minHeight: 200,
|
||||
textAlignVertical: 'top',
|
||||
},
|
||||
previewContainer: {
|
||||
flex: 1,
|
||||
|
@ -41,6 +41,8 @@ import { ThemeContainer } from '../../../containers';
|
||||
import styles from './markdownEditorStyles';
|
||||
import applySnippet from './formats/applySnippet';
|
||||
|
||||
const MIN_BODY_INPUT_HEIGHT = 200;
|
||||
|
||||
const MarkdownEditorView = ({
|
||||
draftBody,
|
||||
handleIsFormValid,
|
||||
@ -66,7 +68,7 @@ const MarkdownEditorView = ({
|
||||
const [text, setText] = useState(draftBody || '');
|
||||
const [selection, setSelection] = useState({ start: 0, end: 0 });
|
||||
const [editable, setEditable] = useState(true);
|
||||
const [height, setHeight] = useState(0);
|
||||
const [bodyInputHeight, setBodyInputHeight] = useState(MIN_BODY_INPUT_HEIGHT);
|
||||
const [isSnippetsOpen, setIsSnippetsOpen] = useState(false);
|
||||
|
||||
const inputRef = useRef(null);
|
||||
@ -161,6 +163,11 @@ const MarkdownEditorView = ({
|
||||
setSelection(event.nativeEvent.selection);
|
||||
};
|
||||
|
||||
const _handleOnContentSizeChange = async (event) => {
|
||||
const height = Math.max(MIN_BODY_INPUT_HEIGHT, event.nativeEvent.contentSize.height + 30);
|
||||
setBodyInputHeight(height);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const _setTextAndSelection = useCallback(({ selection: _selection, text: _text }) => {
|
||||
inputRef.current.setNativeProps({
|
||||
@ -337,13 +344,14 @@ const MarkdownEditorView = ({
|
||||
})}
|
||||
placeholderTextColor={isDarkTheme ? '#526d91' : '#c1c5c7'}
|
||||
selectionColor="#357ce6"
|
||||
style={styles.textWrapper}
|
||||
style={{ ...styles.textWrapper, height: bodyInputHeight }}
|
||||
underlineColorAndroid="transparent"
|
||||
innerRef={inputRef}
|
||||
editable={editable}
|
||||
contextMenuHidden={false}
|
||||
autoGrow={false}
|
||||
scrollEnabled={false}
|
||||
onContentSizeChange={_handleOnContentSizeChange}
|
||||
/>
|
||||
)}
|
||||
</ThemeContainer>
|
||||
|
@ -301,7 +301,19 @@
|
||||
"my_communities": "My Communities",
|
||||
"top_communities": "Top Communities",
|
||||
"schedule_modal_title": "Schedule Post",
|
||||
"snippets": "Snippets"
|
||||
"snippets": "Snippets",
|
||||
"alert_init_title":"Initialize",
|
||||
"alert_init_body":"Load recent draft or create new post",
|
||||
"alert_btn_draft":"Load Draft",
|
||||
"alert_btn_new":"New Post",
|
||||
"alert_pub_edit_title":"Publishing edits",
|
||||
"alert_pub_new_title":"Publishing new post",
|
||||
"alert_pub_body":"Are you sure?",
|
||||
"alert_btn_yes":"Yes",
|
||||
"alert_btn_no":"No",
|
||||
"draft_save_success":"Draft Saved",
|
||||
"draft_save_fail":"Failed to save draft"
|
||||
|
||||
},
|
||||
"snippets":{
|
||||
"label_no_snippets":"No Snippets Found",
|
||||
@ -406,7 +418,8 @@
|
||||
"title": "Drafts",
|
||||
"load_error": "Could not load drafts",
|
||||
"empty_list": "Nothing here",
|
||||
"deleted": "Draft deleted"
|
||||
"deleted": "Draft deleted",
|
||||
|
||||
},
|
||||
"schedules": {
|
||||
"title": "Schedules",
|
||||
|
@ -79,6 +79,8 @@ export const addDraft = (data) =>
|
||||
const { drafts } = res.data;
|
||||
if (drafts) {
|
||||
resolve(drafts.pop());
|
||||
} else {
|
||||
reject(new Error('No drafts returned in response'));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -102,7 +104,11 @@ export const updateDraft = (data) =>
|
||||
tags: data.tags,
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res.data);
|
||||
if (res.data) {
|
||||
resolve(res.data);
|
||||
} else {
|
||||
reject(new Error('No data retuend in update response'));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
bugsnag.notify(error);
|
||||
|
@ -118,19 +118,31 @@ export const removeAllSCAccounts = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
export const setDraftPost = async (fields, username) => {
|
||||
export const setDraftPost = async (fields, username, draftId) => {
|
||||
try {
|
||||
let draft = await getItemFromStorage(DRAFT_SCHEMA);
|
||||
let timestamp = new Date().getTime();
|
||||
|
||||
const data = {
|
||||
username,
|
||||
draftId,
|
||||
timestamp,
|
||||
title: fields.title,
|
||||
tags: fields.tags,
|
||||
body: fields.body,
|
||||
};
|
||||
|
||||
if (draft && draft.some((e) => e.username === username)) {
|
||||
draft = draft.map((item) => (item.username === username ? { ...item, ...data } : item));
|
||||
//check if entry esist
|
||||
const draftIndex = draft.findIndex(
|
||||
(item) => draftId === undefined || item.draftId === draftId,
|
||||
);
|
||||
|
||||
if (draftIndex < 0) {
|
||||
draft.push(data);
|
||||
} else {
|
||||
draft[draftIndex] = data;
|
||||
}
|
||||
} else {
|
||||
draft = [];
|
||||
draft.push(data);
|
||||
@ -142,10 +154,13 @@ export const setDraftPost = async (fields, username) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getDraftPost = async (username) => {
|
||||
export const getDraftPost = async (username, draftId) => {
|
||||
try {
|
||||
const draft = await getItemFromStorage(DRAFT_SCHEMA);
|
||||
const draftObj = draft.filter((item) => item.username === username);
|
||||
const draftObj = draft.filter(
|
||||
(item) => item.username === username && (draftId === undefined || item.draftId === draftId),
|
||||
);
|
||||
|
||||
return draftObj[0];
|
||||
} catch (error) {
|
||||
return error;
|
||||
|
@ -22,7 +22,7 @@ const persistedReducer = persistReducer(persistConfig, reducer);
|
||||
|
||||
const middleware = [thunk];
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
middleware.push(logger);
|
||||
// middleware.push(logger);
|
||||
}
|
||||
|
||||
const store = createStore(persistedReducer, applyMiddleware(...middleware));
|
||||
|
@ -8,7 +8,13 @@ import AsyncStorage from '@react-native-community/async-storage';
|
||||
|
||||
// Services and Actions
|
||||
import { Buffer } from 'buffer';
|
||||
import { uploadImage, addDraft, updateDraft, schedule } from '../../../providers/ecency/ecency';
|
||||
import {
|
||||
uploadImage,
|
||||
addDraft,
|
||||
updateDraft,
|
||||
schedule,
|
||||
getDrafts,
|
||||
} from '../../../providers/ecency/ecency';
|
||||
import { toastNotification, setRcOffer } from '../../../redux/actions/uiAction';
|
||||
import {
|
||||
postContent,
|
||||
@ -42,6 +48,8 @@ import EditorScreen from '../screen/editorScreen';
|
||||
*/
|
||||
|
||||
class EditorContainer extends Component {
|
||||
_isMounted = false;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -63,7 +71,102 @@ class EditorContainer extends Component {
|
||||
};
|
||||
}
|
||||
|
||||
_getDraft = async (username, isReply) => {
|
||||
// Component Life Cycle Functions
|
||||
componentDidMount() {
|
||||
this._isMounted = true;
|
||||
const { currentAccount, navigation } = this.props;
|
||||
const username = currentAccount && currentAccount.name ? currentAccount.name : '';
|
||||
let isReply;
|
||||
let isEdit;
|
||||
let post;
|
||||
let _draft;
|
||||
|
||||
if (navigation.state && navigation.state.params) {
|
||||
const navigationParams = navigation.state.params;
|
||||
|
||||
if (navigationParams.draft) {
|
||||
_draft = navigationParams.draft;
|
||||
this.setState({
|
||||
draftId: _draft._id,
|
||||
isDraft: true,
|
||||
});
|
||||
this._getStorageDraft(username, isReply, _draft);
|
||||
}
|
||||
if (navigationParams.community) {
|
||||
this.setState({
|
||||
community: navigationParams.community,
|
||||
});
|
||||
}
|
||||
if (navigationParams.upload) {
|
||||
const { upload } = navigationParams;
|
||||
|
||||
upload.forEach((el) => {
|
||||
if (el.filePath && el.fileName) {
|
||||
this.setState({ isUploading: true });
|
||||
const _media = {
|
||||
path: el.filePath,
|
||||
mime: el.mimeType,
|
||||
filename: el.fileName || `img_${Math.random()}.jpg`,
|
||||
};
|
||||
|
||||
this._uploadImage(_media);
|
||||
} else if (el.text) {
|
||||
this.setState({
|
||||
draftPost: {
|
||||
title: '',
|
||||
body: el.text,
|
||||
tags: [],
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.post) {
|
||||
({ post } = navigationParams);
|
||||
this.setState({
|
||||
post,
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.isReply) {
|
||||
({ isReply } = navigationParams);
|
||||
this.setState({
|
||||
isReply,
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.isEdit) {
|
||||
({ isEdit } = navigationParams);
|
||||
this.setState({
|
||||
isEdit,
|
||||
draftPost: {
|
||||
title: get(post, 'title', ''),
|
||||
body: get(post, 'markdownBody', ''),
|
||||
tags: get(post, 'json_metadata.tags', []),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.action) {
|
||||
this._handleRoutingAction(navigationParams.action);
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
autoFocusText: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (!isEdit && !_draft) {
|
||||
this._fetchDraftsForComparison(isReply);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._isMounted = false;
|
||||
}
|
||||
|
||||
_getStorageDraft = async (username, isReply, paramDraft) => {
|
||||
if (isReply) {
|
||||
const draftReply = await AsyncStorage.getItem('temp-reply');
|
||||
|
||||
@ -75,20 +178,128 @@ class EditorContainer extends Component {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await getDraftPost(username).then((result) => {
|
||||
if (result) {
|
||||
getDraftPost(username, paramDraft && paramDraft._id).then((result) => {
|
||||
//if result is return and param draft available, compare timestamp, use latest
|
||||
//if no draft, use result anayways
|
||||
if (result && (!paramDraft || paramDraft.timestamp < result.timestamp)) {
|
||||
this.setState({
|
||||
draftPost: {
|
||||
body: get(result, 'body', ''),
|
||||
title: get(result, 'title', ''),
|
||||
tags: get(result, 'tags', '').split(','),
|
||||
isDraft: paramDraft ? true : false,
|
||||
draftId: paramDraft ? paramDraft._id : null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//if above fails with either no result returned or timestamp is old,
|
||||
// and use draft form nav param if available.
|
||||
else if (paramDraft) {
|
||||
const _tags = paramDraft.tags.includes(' ')
|
||||
? paramDraft.tags.split(' ')
|
||||
: paramDraft.tags.split(',');
|
||||
this.setState({
|
||||
draftPost: {
|
||||
title: paramDraft.title,
|
||||
body: paramDraft.body,
|
||||
tags: _tags,
|
||||
},
|
||||
isDraft: true,
|
||||
draftId: paramDraft._id,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* this fucntion is run if editor is access used mid tab or reply section
|
||||
* it fetches fresh drafts and run some comparions to load one of following
|
||||
* empty editor, load non-remote draft or most recent remote draft based on timestamps
|
||||
* prompts user as well
|
||||
* @param isReply
|
||||
**/
|
||||
_fetchDraftsForComparison = async (isReply) => {
|
||||
const { currentAccount, isLoggedIn, intl } = this.props;
|
||||
const username = get(currentAccount, 'name', '');
|
||||
|
||||
//initilizes editor with reply or non remote id less draft
|
||||
const _getStorageDraftGeneral = () => {
|
||||
this._getStorageDraft(username, isReply);
|
||||
};
|
||||
|
||||
//skip comparison if its a reply and run general function
|
||||
if (isReply) {
|
||||
_getStorageDraftGeneral();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
//if not logged in use non remote draft
|
||||
if (!isLoggedIn) {
|
||||
_getStorageDraftGeneral();
|
||||
return;
|
||||
}
|
||||
|
||||
const drafts = await getDrafts(username);
|
||||
const idLessDraft = await getDraftPost(username);
|
||||
|
||||
const loadRecentDraft = () => {
|
||||
//if no draft available means local draft is recent
|
||||
if (drafts.length == 0) {
|
||||
_getStorageDraftGeneral();
|
||||
return;
|
||||
}
|
||||
|
||||
//sort darts based on timestamps
|
||||
drafts.sort((d1, d2) =>
|
||||
new Date(d1.modified).getTime() < new Date(d2.modified).getTime() ? 1 : -1,
|
||||
);
|
||||
const _draft = drafts[0];
|
||||
|
||||
//if unsaved local draft is more latest then remote draft, use that instead
|
||||
//if editor was opened from draft screens, this code will be skipped anyways.
|
||||
if (idLessDraft && new Date(_draft.modified).getTime() < idLessDraft.timestamp) {
|
||||
_getStorageDraftGeneral();
|
||||
return;
|
||||
}
|
||||
|
||||
//initilize editor as draft
|
||||
this.setState({
|
||||
draftId: _draft._id,
|
||||
isDraft: true,
|
||||
});
|
||||
this._getStorageDraft(username, isReply, _draft);
|
||||
};
|
||||
|
||||
const leaveEmpty = () => {
|
||||
console.log('Leaving editor empty');
|
||||
};
|
||||
|
||||
if (drafts.length > 0 || (idLessDraft && idLessDraft.timestamp > 0)) {
|
||||
Alert.alert(
|
||||
intl.formatMessage({
|
||||
id: 'editor.alert_init_title',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'editor.alert_init_body',
|
||||
}),
|
||||
[
|
||||
{
|
||||
text: intl.formatMessage({ id: 'editor.alert_btn_draft' }),
|
||||
onPress: loadRecentDraft,
|
||||
},
|
||||
{ text: intl.formatMessage({ id: 'editor.alert_btn_new' }), onPress: leaveEmpty },
|
||||
],
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Failed to compare drafts, load general', err);
|
||||
_getStorageDraftGeneral();
|
||||
}
|
||||
};
|
||||
|
||||
_handleRoutingAction = (routingAction) => {
|
||||
if (routingAction === 'camera') {
|
||||
this._handleOpenCamera();
|
||||
@ -224,67 +435,122 @@ class EditorContainer extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
_saveDraftToDB = (fields) => {
|
||||
_saveDraftToDB = async (fields) => {
|
||||
const { isDraftSaved, draftId } = this.state;
|
||||
const { currentAccount, dispatch, intl } = this.props;
|
||||
|
||||
if (!isDraftSaved) {
|
||||
const { currentAccount } = this.props;
|
||||
const username = get(currentAccount, 'name', '');
|
||||
let draftField;
|
||||
try {
|
||||
if (!isDraftSaved) {
|
||||
const username = get(currentAccount, 'name', '');
|
||||
let draftField;
|
||||
|
||||
this.setState({
|
||||
isDraftSaving: true,
|
||||
});
|
||||
if (fields) {
|
||||
draftField = {
|
||||
...fields,
|
||||
tags: fields.tags.join(' '),
|
||||
username,
|
||||
};
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
isDraftSaving: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (fields) {
|
||||
draftField = {
|
||||
...fields,
|
||||
tags: fields.tags.join(' '),
|
||||
username,
|
||||
};
|
||||
}
|
||||
|
||||
//update draft is draftId is present
|
||||
if (draftId && draftField) {
|
||||
await updateDraft({
|
||||
...draftField,
|
||||
draftId,
|
||||
});
|
||||
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
isDraftSaved: true,
|
||||
isDraftSaving: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//create new darft otherwise
|
||||
else if (draftField) {
|
||||
const response = await addDraft(draftField);
|
||||
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
isDraftSaved: true,
|
||||
isDraftSaving: false,
|
||||
draftId: response._id,
|
||||
});
|
||||
}
|
||||
|
||||
//clear local copy is darft save is successful
|
||||
setDraftPost(
|
||||
{
|
||||
title: '',
|
||||
body: '',
|
||||
tags: '',
|
||||
timestamp: 0,
|
||||
},
|
||||
username,
|
||||
);
|
||||
}
|
||||
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'editor.draft_save_success',
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
//call fetch post to drafts screen
|
||||
this._navigationBackFetchDrafts();
|
||||
}
|
||||
|
||||
if (draftId && draftField) {
|
||||
updateDraft({
|
||||
...draftField,
|
||||
draftId,
|
||||
}).then(() => {
|
||||
this.setState({
|
||||
isDraftSaved: true,
|
||||
});
|
||||
});
|
||||
} else if (draftField) {
|
||||
addDraft(draftField).then((response) => {
|
||||
this.setState({
|
||||
isDraftSaved: true,
|
||||
draftId: response._id,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn('Failed to save draft to DB: ', err);
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
isDraftSaving: false,
|
||||
isDraftSaved: false,
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isDraftSaving: false,
|
||||
isDraftSaved,
|
||||
});
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'editor.draft_save_fail',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
_saveCurrentDraft = async (fields) => {
|
||||
const { draftId, isReply, isEdit, isPostSending } = this.state;
|
||||
|
||||
if (!draftId && !isEdit) {
|
||||
const { currentAccount } = this.props;
|
||||
const username = currentAccount && currentAccount.name ? currentAccount.name : '';
|
||||
const { currentAccount } = this.props;
|
||||
const username = currentAccount && currentAccount.name ? currentAccount.name : '';
|
||||
|
||||
const draftField = {
|
||||
...fields,
|
||||
tags: fields.tags && fields.tags.length > 0 ? fields.tags.toString() : '',
|
||||
};
|
||||
if (!isPostSending) {
|
||||
if (isReply && draftField.body !== null) {
|
||||
await AsyncStorage.setItem('temp-reply', draftField.body);
|
||||
} else {
|
||||
setDraftPost(draftField, username);
|
||||
}
|
||||
const draftField = {
|
||||
...fields,
|
||||
tags: fields.tags && fields.tags.length > 0 ? fields.tags.toString() : '',
|
||||
};
|
||||
|
||||
if (!isPostSending) {
|
||||
//save reply data
|
||||
if (isReply && draftField.body !== null) {
|
||||
await AsyncStorage.setItem('temp-reply', draftField.body);
|
||||
|
||||
//save existing draft data locally
|
||||
} else if (draftId) {
|
||||
setDraftPost(draftField, username, draftId);
|
||||
}
|
||||
|
||||
//update editor data locally
|
||||
else if (!isReply) {
|
||||
setDraftPost(draftField, username);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -363,6 +629,7 @@ class EditorContainer extends Component {
|
||||
title: '',
|
||||
body: '',
|
||||
tags: '',
|
||||
timestamp: 0,
|
||||
},
|
||||
currentAccount.name,
|
||||
);
|
||||
@ -410,12 +677,7 @@ class EditorContainer extends Component {
|
||||
const permlink = generateReplyPermlink(post.author);
|
||||
const author = currentAccount.name;
|
||||
const options = null;
|
||||
/*makeOptions({
|
||||
author: author,
|
||||
permlink: permlink,
|
||||
operationType: rewardType,
|
||||
beneficiaries: beneficiaries,
|
||||
});*/
|
||||
|
||||
const parentAuthor = post.author;
|
||||
const parentPermlink = post.permlink;
|
||||
const voteWeight = null;
|
||||
@ -545,45 +807,68 @@ class EditorContainer extends Component {
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
_handleOnBackPress = () => {
|
||||
_navigationBackFetchDrafts = () => {
|
||||
const { navigation } = this.props;
|
||||
const { isDraft } = this.state;
|
||||
|
||||
if (isDraft) {
|
||||
if (isDraft && navigation.state.params) {
|
||||
navigation.state.params.fetchPost();
|
||||
}
|
||||
};
|
||||
|
||||
_handleSubmit = (form) => {
|
||||
const { isReply, isEdit } = this.state;
|
||||
const { intl } = this.props;
|
||||
|
||||
if (isReply && !isEdit) {
|
||||
this._submitReply(form.fields);
|
||||
} else if (isEdit) {
|
||||
Alert.alert(
|
||||
'Publishing edits',
|
||||
'Are you sure?',
|
||||
intl.formatMessage({
|
||||
id: 'editor.alert_pub_edit_title',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'editor.alert_pub_body',
|
||||
}),
|
||||
[
|
||||
{
|
||||
text: 'No',
|
||||
text: intl.formatMessage({
|
||||
id: 'editor.alert_btn_no',
|
||||
}),
|
||||
onPress: () => console.log('Cancel Pressed'),
|
||||
style: 'cancel',
|
||||
},
|
||||
{ text: 'Yes', onPress: () => this._submitEdit(form.fields) },
|
||||
{
|
||||
text: intl.formatMessage({
|
||||
id: 'editor.alert_btn_yes',
|
||||
}),
|
||||
onPress: () => this._submitEdit(form.fields),
|
||||
},
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
} else {
|
||||
Alert.alert(
|
||||
'Publishing new post',
|
||||
'Are you sure?',
|
||||
intl.formatMessage({
|
||||
id: 'editor.alert_pub_new_title',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'editor.alert_pub_body',
|
||||
}),
|
||||
[
|
||||
{
|
||||
text: 'No',
|
||||
text: intl.formatMessage({
|
||||
id: 'editor.alert_btn_no',
|
||||
}),
|
||||
onPress: () => console.log('Cancel Pressed'),
|
||||
style: 'cancel',
|
||||
},
|
||||
{ text: 'Yes', onPress: () => this._submitPost(form.fields) },
|
||||
{
|
||||
text: intl.formatMessage({
|
||||
id: 'editor.alert_btn_yes',
|
||||
}),
|
||||
onPress: () => this._submitPost(form.fields),
|
||||
},
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
@ -683,6 +968,7 @@ class EditorContainer extends Component {
|
||||
title: '',
|
||||
body: '',
|
||||
tags: '',
|
||||
timestamp: 0,
|
||||
},
|
||||
currentAccount.name,
|
||||
);
|
||||
@ -710,6 +996,7 @@ class EditorContainer extends Component {
|
||||
title: '',
|
||||
body: '',
|
||||
tags: '',
|
||||
timestamp: 0,
|
||||
},
|
||||
name,
|
||||
);
|
||||
@ -728,100 +1015,6 @@ class EditorContainer extends Component {
|
||||
await AsyncStorage.setItem('temp-beneficiaries', JSON.stringify(value));
|
||||
};
|
||||
|
||||
// Component Life Cycle Functions
|
||||
componentDidMount() {
|
||||
const { currentAccount, navigation } = this.props;
|
||||
const username = currentAccount && currentAccount.name ? currentAccount.name : '';
|
||||
let isReply;
|
||||
let isEdit;
|
||||
let post;
|
||||
let _draft;
|
||||
if (navigation.state && navigation.state.params) {
|
||||
const navigationParams = navigation.state.params;
|
||||
|
||||
if (navigationParams.draft) {
|
||||
_draft = navigationParams.draft;
|
||||
const _tags = _draft.tags.includes(' ') ? _draft.tags.split(' ') : _draft.tags.split(',');
|
||||
this.setState({
|
||||
draftPost: {
|
||||
title: _draft.title,
|
||||
body: _draft.body,
|
||||
tags: _tags,
|
||||
},
|
||||
draftId: _draft._id,
|
||||
isDraft: true,
|
||||
});
|
||||
}
|
||||
if (navigationParams.community) {
|
||||
this.setState({
|
||||
community: navigationParams.community,
|
||||
});
|
||||
}
|
||||
if (navigationParams.upload) {
|
||||
const { upload } = navigationParams;
|
||||
|
||||
upload.forEach((el) => {
|
||||
if (el.filePath && el.fileName) {
|
||||
this.setState({ isUploading: true });
|
||||
const _media = {
|
||||
path: el.filePath,
|
||||
mime: el.mimeType,
|
||||
filename: el.fileName || `img_${Math.random()}.jpg`,
|
||||
};
|
||||
|
||||
this._uploadImage(_media);
|
||||
} else if (el.text) {
|
||||
this.setState({
|
||||
draftPost: {
|
||||
title: '',
|
||||
body: el.text,
|
||||
tags: [],
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.post) {
|
||||
({ post } = navigationParams);
|
||||
this.setState({
|
||||
post,
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.isReply) {
|
||||
({ isReply } = navigationParams);
|
||||
this.setState({
|
||||
isReply,
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.isEdit) {
|
||||
({ isEdit } = navigationParams);
|
||||
this.setState({
|
||||
isEdit,
|
||||
draftPost: {
|
||||
title: get(post, 'title', ''),
|
||||
body: get(post, 'markdownBody', ''),
|
||||
tags: get(post, 'json_metadata.tags', []),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (navigationParams.action) {
|
||||
this._handleRoutingAction(navigationParams.action);
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
autoFocusText: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (!isEdit && !_draft) {
|
||||
this._getDraft(username, isReply);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isLoggedIn, isDarkTheme, navigation, currentAccount } = this.props;
|
||||
const {
|
||||
@ -850,7 +1043,7 @@ class EditorContainer extends Component {
|
||||
handleBeneficiaries={this._handleBeneficiaries}
|
||||
handleDatePickerChange={this._handleDatePickerChange}
|
||||
handleFormChanged={this._handleFormChanged}
|
||||
handleOnBackPress={this._handleOnBackPress}
|
||||
handleOnBackPress={() => {}}
|
||||
handleOnImagePicker={this._handleRoutingAction}
|
||||
handleOnSubmit={this._handleSubmit}
|
||||
initialEditor={this._initialEditor}
|
||||
|
@ -65,6 +65,10 @@ class EditorScreen extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._saveDraftToDB();
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps = async (nextProps) => {
|
||||
const { draftPost, isUploading, community } = this.props;
|
||||
if (nextProps.draftPost && draftPost !== nextProps.draftPost) {
|
||||
@ -127,10 +131,7 @@ class EditorScreen extends Component {
|
||||
};
|
||||
|
||||
_handleOnSaveButtonPress = () => {
|
||||
const { saveDraftToDB } = this.props;
|
||||
const { fields } = this.state;
|
||||
|
||||
saveDraftToDB(fields);
|
||||
this._saveDraftToDB();
|
||||
};
|
||||
|
||||
_saveCurrentDraft = (fields) => {
|
||||
@ -252,6 +253,16 @@ class EditorScreen extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
_saveDraftToDB() {
|
||||
const { saveDraftToDB } = this.props;
|
||||
const { fields } = this.state;
|
||||
|
||||
//save draft only if any of field is valid
|
||||
if (fields.body || fields.title) {
|
||||
saveDraftToDB(fields);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
fields,
|
||||
|
38
yarn.lock
38
yarn.lock
@ -1583,24 +1583,24 @@ anymatch@^2.0.0:
|
||||
micromatch "^3.1.4"
|
||||
normalize-path "^2.1.1"
|
||||
|
||||
appcenter-analytics@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter-analytics/-/appcenter-analytics-3.1.0.tgz#ec51c79f43c58a6e6d6d5ce4c8bdb0ada3bda539"
|
||||
integrity sha512-zGJRBe39IigyT127/alNzNeOpDYSyRo8RX2RYq2AtL01LnCreOy/fpzoF4yOVPMedFMiinEN+OOqR9e7WydAwg==
|
||||
appcenter-analytics@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter-analytics/-/appcenter-analytics-4.1.0.tgz#eb3270a6894bcf3d14e1772c4ccf21d7fb88fa85"
|
||||
integrity sha512-pEsz08wer7J3+zjNV78eSB0FY1bjMxmFHukV6PimAoMpIm8E+X7saGP0QQw2cQTUFiexMujHRvZfM259ksg6hg==
|
||||
dependencies:
|
||||
appcenter "3.1.0"
|
||||
appcenter "4.1.0"
|
||||
|
||||
appcenter-crashes@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter-crashes/-/appcenter-crashes-3.1.0.tgz#6b0fb592bc5e69cbd83106b47f55c97bc33a3fa3"
|
||||
integrity sha512-2dwy7aqhSKifWg5yZVPuZdNRiHMO/XTsaQSHvvHNDA47BJ2y/cwCsK516KNgoYvp97B3Pr3Xyim7ee/n/xxO4g==
|
||||
appcenter-crashes@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter-crashes/-/appcenter-crashes-4.1.0.tgz#1d7a1a27c61f6a37d904f3d435de2f30ee0454e5"
|
||||
integrity sha512-erl7387yAPRKa7d8L7KxNd82OAZ+EQwThpsu7tZLQYn3iuIT4P98dNFCnJKO6y64li4dn4B9rCF3s0PN7tPb1A==
|
||||
dependencies:
|
||||
appcenter "3.1.0"
|
||||
appcenter "4.1.0"
|
||||
|
||||
appcenter-link-scripts@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter-link-scripts/-/appcenter-link-scripts-3.1.0.tgz#5cc9d0303f9f16b7170d56a403fa3e69379cfd36"
|
||||
integrity sha512-0ECoQLjfIJhAO8EkvRQ4fO5gZELhzwD3eRhsCD4d27k7TDPXYt32/p5ylHXUWotR7pduTE1rZ8gtETTr4oZf9g==
|
||||
appcenter-link-scripts@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter-link-scripts/-/appcenter-link-scripts-4.1.0.tgz#ff9d337fb7841c2cbf86cd5f34bd7310e945d0f5"
|
||||
integrity sha512-sTd8H4H9wNwBkUKHasvDGNBln34+dHEFlaT/P6O0gvs6TWU3JxlY8uXpB/IqAi2lSWPs3TMgQ7NGXTjvC6oZig==
|
||||
dependencies:
|
||||
debug "4.1.1"
|
||||
glob "5.0.15"
|
||||
@ -1610,12 +1610,12 @@ appcenter-link-scripts@3.1.0:
|
||||
which "1.2.11"
|
||||
xcode "2.0.0"
|
||||
|
||||
appcenter@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter/-/appcenter-3.1.0.tgz#55fb01bfedc92e732e52ab97c8b344e062ba61a7"
|
||||
integrity sha512-SvEdrqeEqK5BJizdrRmWdp/NFwwb3FJ08U5LQkRdqPoFWXQZ7d+AC2cVnemORXsiYPcpwK9xqiNxyofzEzddFA==
|
||||
appcenter@4.1.0, appcenter@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/appcenter/-/appcenter-4.1.0.tgz#d4c9b43adcaac32a328dc8e9f9f0607e0a7d5691"
|
||||
integrity sha512-JUwb/4sMw68CN2AlJEp1G5iVl/Rzv8fg8t9CzeRaEcnOku42h6+vlYbYe3P5YW18kAIA/hCH0uoDaa0kc9qfDA==
|
||||
dependencies:
|
||||
appcenter-link-scripts "3.1.0"
|
||||
appcenter-link-scripts "4.1.0"
|
||||
|
||||
aproba@^1.0.3:
|
||||
version "1.2.0"
|
||||
|
Loading…
Reference in New Issue
Block a user