created edit for draft post

This commit is contained in:
u-e 2019-01-09 02:22:48 +03:00
parent 186e35c00c
commit 705d2e7acd
14 changed files with 213 additions and 72 deletions

View File

@ -121,7 +121,7 @@ class PostDropdownContainer extends PureComponent {
/>
<ActionSheet
ref={o => (this.ActionSheet = o)}
options={['Reblog', intl.formatMessage({ id: 'post.reblog_cancel' })]}
options={['Reblog', intl.formatMessage({ id: 'alert.cancel' })]}
title={intl.formatMessage({ id: 'post.reblog_alert' })}
cancelButtonIndex={1}
onPress={(index) => {

View File

@ -2,8 +2,6 @@ import React, { PureComponent } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { withNavigation } from 'react-navigation';
import FastImage from 'react-native-fast-image';
// Components
import { Tag, TextWithIcon } from '../../../basicUIElements';
import { UserAvatar } from '../../../userAvatar';

View File

@ -40,8 +40,8 @@ export default EStyleSheet.create({
color: '$primaryBlack',
},
summary: {
fontSize: 16,
color: '$primaryDarkGray',
fontSize: 13,
color: '$primaryDarkText',
},
header: {
backgroundColor: '$primaryBackgroundColor',

View File

@ -1,13 +1,16 @@
import React, { Component } from 'react';
import React, { Component, Fragment } from 'react';
import ActionSheet from 'react-native-actionsheet';
import { View, Text, TouchableOpacity } from 'react-native';
import { injectIntl } from 'react-intl';
import FastImage from 'react-native-fast-image';
import { PostHeaderDescription } from '../../postElements';
// Utils
import { getTimeFromNow } from '../../../utils/time';
// Constants
// Components
import { PostHeaderDescription } from '../../postElements';
import { IconButton } from '../../iconButton';
// Defaults
import DEFAULT_IMAGE from '../../../assets/no_image.png';
@ -31,40 +34,66 @@ class PostListItemView extends Component {
render() {
const {
title, summary, mainTag, username, reputation, created, image,
title,
summary,
mainTag,
username,
reputation,
created,
image,
handleOnPressItem,
handleOnRemoveItem,
id,
intl,
} = this.props;
return (
<View style={styles.container}>
<View style={styles.header}>
<PostHeaderDescription
date={getTimeFromNow(created)}
name={username}
reputation={reputation}
size={32}
tag={mainTag}
/>
<IconButton
backgroundColor="transparent"
name="delete"
iconType="MaterialIcons"
size={20}
style={[styles.rightItem]}
color="#c1c5c7"
/>
<Fragment>
<View style={styles.container}>
<View style={styles.header}>
<PostHeaderDescription
date={intl.formatRelative(created)}
name={username}
reputation={reputation}
size={32}
tag={mainTag}
/>
<IconButton
backgroundColor="transparent"
name="delete"
iconType="MaterialIcons"
size={20}
onPress={() => this.ActionSheet.show()}
style={[styles.rightItem]}
color="#c1c5c7"
/>
</View>
<View style={styles.body}>
<TouchableOpacity onPress={() => handleOnPressItem(id)}>
<FastImage source={image} style={styles.image} defaultSource={DEFAULT_IMAGE} />
<View style={[styles.postDescripton]}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.summary}>{summary}</Text>
</View>
</TouchableOpacity>
</View>
</View>
<View style={styles.body}>
<TouchableOpacity >
<FastImage source={image} style={styles.image} defaultSource={DEFAULT_IMAGE} />
<View style={[styles.postDescripton]}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.summary}>{summary}</Text>
</View>
</TouchableOpacity>
</View>
</View>
<ActionSheet
ref={o => (this.ActionSheet = o)}
options={[
intl.formatMessage({ id: 'alert.delete' }),
intl.formatMessage({ id: 'alert.cancel' }),
]}
title={intl.formatMessage({ id: 'alert.remove_alert' })}
cancelButtonIndex={1}
destructiveButtonIndex={0}
onPress={(index) => {
if (index === 0) handleOnRemoveItem(id);
}}
/>
</Fragment>
);
}
}
export default PostListItemView;
export default injectIntl(PostListItemView);

View File

@ -21,9 +21,9 @@ class TransactionContainer extends PureComponent {
// Component Functions
render() {
const { intl, walletData } = this.props;
const { walletData } = this.props;
return <TransactionView intl={intl} walletData={walletData} />;
return <TransactionView walletData={walletData} />;
}
}

View File

@ -104,7 +104,7 @@ class WalletView extends PureComponent {
>
<WalletDetails intl={intl} walletData={walletData} />
</CollapsibleCard>
<Transaction intl={intl} walletData={walletData} />
<Transaction walletData={walletData} />
</Fragment>
)}
</ScrollView>

View File

@ -132,11 +132,13 @@
"success_rebloged": "Rebloged!",
"already_rebloged": "You have already reblogged!",
"warning": "Warning",
"invalid_pincode": "Invalid pin code, please check and try again."
"invalid_pincode": "Invalid pin code, please check and try again.",
"remove_alert": "Are you sure want to remove?",
"cancel": "Cancel",
"delete": "Delete"
},
"post": {
"reblog_alert": "Are you sure you want to reblog?",
"reblog_cancel": "Cancel"
"reblog_alert": "Are you sure you want to reblog?"
},
"drafts": {
"title": "Drafts",

View File

@ -132,11 +132,13 @@
"success_rebloged": "Репостнуто!",
"already_rebloged": "Вы уже делали этот репост!",
"warning": "Внимание",
"invalid_pincode": "Не верный пин, пожалуйста, попробуйте снова."
"invalid_pincode": "Не верный пин, пожалуйста, попробуйте снова.",
"remove_alert": "Вы уверены, что хотите сделать Удалить?",
"cancel": "Отмена",
"delete": "Удалить"
},
"post": {
"reblog_alert": "Вы уверены, что хотите сделать репост?",
"reblog_cancel": "Отмена"
"reblog_alert": "Вы уверены, что хотите сделать репост?"
},
"gallery": {
"title": "Галерея",

View File

@ -133,11 +133,13 @@
"already_rebloged": "Zaten reblog yapmışsınız.",
"failed_to_open": "Açılamadı.",
"warning": "Uyarı!",
"invalid_pincode": "Geçersiz pin kod, lutfen tekrar deneyin."
"invalid_pincode": "Geçersiz pin kod, lutfen tekrar deneyin.",
"remove_alert": "Silmek istediginize emin misiniz?",
"cancel": "Vazgeç",
"delete": "Sil"
},
"post": {
"reblog_alert": "Reblog yapma istediginize emin misiniz?",
"reblog_cancel": "Vazgeç"
"reblog_alert": "Reblog yapma istediginize emin misiniz?"
},
// TODO: translate here!!!
"drafts": {

View File

@ -58,4 +58,11 @@ export default EStyleSheet.create({
marginLeft: 42,
marginRight: 32,
},
hintText: {
color: '$iconColor',
alignSelf: 'center',
fontSize: 16,
marginLeft: 16,
fontWeight: '500',
},
});

View File

@ -9,6 +9,7 @@ import { getDrafts, removeDraft } from '../../../providers/esteem/esteem';
// Middleware
// Constants
import { default as ROUTES } from '../../../constants/routeNames';
// Utilities
@ -52,27 +53,38 @@ class DraftsContainer extends Component {
});
};
_removeDraft = (selectedDraft) => {
_removeDraft = (id) => {
const { currentAccount, intl } = this.props;
// getDrafts(currentAccount.name)
// .then((data) => {
// const { drafts } = this.state;
// const newDrafts = [...drafts].filter(draft => draft._id !== item._id);
removeDraft({ username: currentAccount.name, draftId: id })
.then((data) => {
const { drafts } = this.state;
const newDrafts = [...drafts].filter(draft => draft._id !== id);
// Alert.alert(intl.formatMessage({ id: 'drafts.deleted' }));
// this.setState({ drafts: this.sortData(newDrafts) });
// })
// .catch(() => {
// Alert.alert(intl.formatMessage({ id: 'alert.fail' }));
// })
// .finally(() => {
// this._getDrafts();
// });
// Alert.alert(intl.formatMessage({ id: 'drafts.deleted' }));
this.setState({ drafts: this._sortData(newDrafts) });
})
.catch(() => {
Alert.alert(intl.formatMessage({ id: 'alert.fail' }));
});
};
_editDraft = () => {
alert('edit');
_handleRemoveDraft = (id) => {
this._removeDraft(id);
};
_editDraft = (id) => {
const { navigation } = this.props;
const { drafts } = this.state;
const selectedDraft = drafts.find(draft => draft._id === id);
console.log(selectedDraft);
navigation.navigate({
routeName: ROUTES.SCREENS.EDITOR,
params: {
draft: selectedDraft,
fetchPost: this._getDrafts,
},
});
};
_sortData = data => data.sort((a, b) => {
@ -92,7 +104,7 @@ class DraftsContainer extends Component {
editDraft={this._editDraft}
currentAccount={currentAccount}
drafts={drafts}
removeDraft={this._removeDraft}
removeDraft={this._handleRemoveDraft}
/>
);
}

View File

@ -4,12 +4,14 @@ import { View, FlatList, Text } from 'react-native';
// Utils
import { getPostSummary } from '../../../utils/formatter';
import { catchDraftImage } from '../../../utils/image';
// Constants
// Components
import { BasicHeader } from '../../../components/basicHeader';
import { PostListItem } from '../../../components/postListItem';
import { PostCardPlaceHolder } from '../../../components/basicUIElements';
// Styles
import globalStyles from '../../../globalStyles';
@ -32,7 +34,7 @@ class DraftsScreen extends Component {
const { currentAccount, removeDraft, editDraft } = this.props;
const tags = item.tags ? item.tags.split(/[ ,]+/) : [];
const tag = tags[0] || '';
// const img = catchEntryImage(item) || noImage;
const image = catchDraftImage(item.body);
const summary = getPostSummary(item.body, 100);
return (
@ -41,26 +43,39 @@ class DraftsScreen extends Component {
mainTag={tag}
title={item.title}
summary={summary}
image={image ? { uri: catchDraftImage(item.body) } : null}
username={currentAccount.name}
reputation={currentAccount.reputation}
handleOnPressItem={editDraft}
handleOnRemoveItem={removeDraft}
id={item._id}
/>
);
};
render() {
const { drafts, isLoading, intl } = this.props;
const isNoDrafts = drafts && drafts.length === 0;
return (
<View style={globalStyles.lightContainer}>
<View style={isNoDrafts ? globalStyles.container : globalStyles.lightContainer}>
<BasicHeader
title={intl.formatMessage({
id: 'drafts.title',
})}
/>
{isNoDrafts && (
<Text style={globalStyles.hintText}>
{intl.formatMessage({
id: 'drafts.empty_list',
})}
</Text>
)}
{isLoading ? (
<Text>Loading daa!</Text>
<View>
<PostCardPlaceHolder />
<PostCardPlaceHolder />
</View>
) : (
<FlatList
data={drafts}

View File

@ -47,6 +47,7 @@ class EditorContainer extends Component {
isUploading: false,
post: null,
uploadedImage: null,
draftId: null,
};
}
@ -58,10 +59,20 @@ class EditorContainer extends Component {
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({
draftPost: { title: _draft.title, body: _draft.body },
draftId: _draft._id,
});
}
if (navigationParams.post) {
post = navigationParams.post;
this.setState({ post });
@ -92,7 +103,7 @@ class EditorContainer extends Component {
this.setState({ autoFocusText: true });
}
if (!isReply && !isEdit) {
if (!isReply && !isEdit && !_draft) {
this._getDraft(username);
}
}

View File

@ -17,3 +17,66 @@ export const generateSignature = (media, privateKey) => {
return key.sign(new Buffer(array)).toString();
};
export const proxifyImageSrc = (url, width = 0, height = 0) => {
if (!url) {
return '';
}
const prefix = `https://steemitimages.com/${width}x${height}/`;
if (url.startsWith(prefix)) return url;
return `${prefix}${url}`;
};
export const catchEntryImage = (entry, width = 0, height = 0) => {
// return from json metadata if exists
let meta;
try {
meta = JSON.parse(entry.json_metadata);
} catch (e) {
meta = null;
}
if (meta && meta.image && meta.image.length > 0) {
if (meta.image[0]) {
return proxifyImageSrc(meta.image[0], width, height);
}
}
// try to extract images by regex
const imgReg2 = /(http(s?):)([/|.|\w|\s|-])*\.(?:jpe?g|gif|png)/gim;
const m = entry.body.match(imgReg2);
if (m) {
return proxifyImageSrc(m[0], width, height);
}
// If no image specified in json metadata, try extract first image href from entry body
let imgReg = /<img.+src=(?:"|')(.+?)(?:"|')(.*)>/;
let bodyMatch = entry.body.match(imgReg);
if (bodyMatch) {
return proxifyImageSrc(bodyMatch[1], width, height);
}
// If there is no <img> tag, check from markdown img tag ![](image.png)
imgReg = /(?:!\[(.*?)\]\((.*?)\))/;
bodyMatch = imgReg.exec(entry.body);
if (bodyMatch) {
return proxifyImageSrc(bodyMatch[2], width, height);
}
return null;
};
export const catchDraftImage = (body) => {
const imgRegex = /(https?:\/\/.*\.(?:tiff?|jpe?g|gif|png|svg|ico|PNG|GIF|JPG))/g;
if (imgRegex.test(body)) {
const imageMatch = body.match(imgRegex);
return proxifyImageSrc(imageMatch[0]);
}
return null;
};