mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-22 12:51:42 +03:00
commit
b127e797aa
Binary file not shown.
@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"@esteemapp/esteem-render-helpers": "^1.2.9",
|
"@esteemapp/esteem-render-helpers": "^1.3.0",
|
||||||
"@esteemapp/react-native-autocomplete-input": "^4.2.1",
|
"@esteemapp/react-native-autocomplete-input": "^4.2.1",
|
||||||
"@esteemapp/react-native-multi-slider": "^1.1.0",
|
"@esteemapp/react-native-multi-slider": "^1.1.0",
|
||||||
"@esteemapp/react-native-render-html": "^4.1.5",
|
"@esteemapp/react-native-render-html": "^4.1.5",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { withNavigation } from 'react-navigation';
|
import { withNavigation } from 'react-navigation';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { injectIntl } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
@ -17,31 +17,49 @@ import ROUTES from '../../../constants/routeNames';
|
|||||||
// Component
|
// Component
|
||||||
import CommentsView from '../view/commentsView';
|
import CommentsView from '../view/commentsView';
|
||||||
|
|
||||||
/*
|
const CommentsContainer = ({
|
||||||
* Props Name Description Value
|
author,
|
||||||
*@props --> props name here description here Value Type Here
|
permlink,
|
||||||
*
|
selectedFilter,
|
||||||
*/
|
currentAccount: { name },
|
||||||
|
isOwnProfile,
|
||||||
|
fetchPost,
|
||||||
|
navigation,
|
||||||
|
content,
|
||||||
|
currentAccount,
|
||||||
|
pinCode,
|
||||||
|
comments,
|
||||||
|
dispatch,
|
||||||
|
intl,
|
||||||
|
commentCount,
|
||||||
|
isLoggedIn,
|
||||||
|
commentNumber,
|
||||||
|
isShowMoreButton,
|
||||||
|
mainAuthor,
|
||||||
|
selectedPermlink: _selectedPermlink,
|
||||||
|
isHideImage,
|
||||||
|
isShowSubComments,
|
||||||
|
hasManyComments,
|
||||||
|
showAllComments,
|
||||||
|
hideManyCommentsButton,
|
||||||
|
}) => {
|
||||||
|
const [lcomments, setLComments] = useState([]);
|
||||||
|
const [selectedPermlink, setSelectedPermlink] = useState('');
|
||||||
|
|
||||||
class CommentsContainer extends Component {
|
useEffect(() => {
|
||||||
constructor(props) {
|
_getComments();
|
||||||
super(props);
|
}, []);
|
||||||
this.state = {
|
|
||||||
comments: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Component Life Cycle Functions
|
useEffect(() => {
|
||||||
componentDidMount() {
|
_getComments();
|
||||||
this._getComments();
|
const shortedComments = _shortComments(selectedFilter);
|
||||||
}
|
setLComments(shortedComments);
|
||||||
|
}, [commentCount, selectedFilter]);
|
||||||
|
|
||||||
// Component Functions
|
// Component Functions
|
||||||
|
|
||||||
_shortComments = (sortOrder, comments) => {
|
const _shortComments = (sortOrder, _comments) => {
|
||||||
const { comments: parent } = this.state;
|
const sortedComments = _comments || lcomments;
|
||||||
|
|
||||||
const sortedComments = comments || parent;
|
|
||||||
|
|
||||||
const allPayout = c =>
|
const allPayout = c =>
|
||||||
parseFloat(get(c, 'pending_payout_value').split(' ')[0]) +
|
parseFloat(get(c, 'pending_payout_value').split(' ')[0]) +
|
||||||
@ -122,39 +140,24 @@ class CommentsContainer extends Component {
|
|||||||
return sortedComments;
|
return sortedComments;
|
||||||
};
|
};
|
||||||
|
|
||||||
_getComments = async () => {
|
const _getComments = async () => {
|
||||||
const {
|
|
||||||
author,
|
|
||||||
permlink,
|
|
||||||
selectedFilter,
|
|
||||||
currentAccount: { name },
|
|
||||||
isOwnProfile,
|
|
||||||
fetchPost,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (isOwnProfile) {
|
if (isOwnProfile) {
|
||||||
fetchPost();
|
fetchPost();
|
||||||
} else if (author && permlink) {
|
} else if (author && permlink) {
|
||||||
await getComments(author, permlink, name)
|
await getComments(author, permlink, name)
|
||||||
.then(comments => {
|
.then(__comments => {
|
||||||
if (selectedFilter) {
|
if (selectedFilter) {
|
||||||
const sortComments = this._shortComments(selectedFilter, comments);
|
const sortComments = _shortComments(selectedFilter, __comments);
|
||||||
this.setState({
|
setLComments(sortComments);
|
||||||
comments: sortComments,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
setLComments(__comments);
|
||||||
comments,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleOnReplyPress = item => {
|
const _handleOnReplyPress = item => {
|
||||||
const { navigation, fetchPost } = this.props;
|
|
||||||
|
|
||||||
navigation.navigate({
|
navigation.navigate({
|
||||||
routeName: ROUTES.SCREENS.EDITOR,
|
routeName: ROUTES.SCREENS.EDITOR,
|
||||||
params: {
|
params: {
|
||||||
@ -165,9 +168,7 @@ class CommentsContainer extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleOnVotersPress = activeVotes => {
|
const _handleOnVotersPress = activeVotes => {
|
||||||
const { navigation, content } = this.props;
|
|
||||||
|
|
||||||
navigation.navigate({
|
navigation.navigate({
|
||||||
routeName: ROUTES.SCREENS.VOTERS,
|
routeName: ROUTES.SCREENS.VOTERS,
|
||||||
params: {
|
params: {
|
||||||
@ -177,38 +178,32 @@ class CommentsContainer extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleOnEditPress = item => {
|
const _handleOnEditPress = item => {
|
||||||
const { navigation } = this.props;
|
|
||||||
|
|
||||||
navigation.navigate({
|
navigation.navigate({
|
||||||
routeName: ROUTES.SCREENS.EDITOR,
|
routeName: ROUTES.SCREENS.EDITOR,
|
||||||
params: {
|
params: {
|
||||||
isEdit: true,
|
isEdit: true,
|
||||||
isReply: true,
|
isReply: true,
|
||||||
post: item,
|
post: item,
|
||||||
fetchPost: this._getComments,
|
fetchPost: _getComments,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleDeleteComment = permlink => {
|
const _handleDeleteComment = _permlink => {
|
||||||
const { currentAccount, pinCode, comments } = this.props;
|
|
||||||
const { comments: _comments } = this.state;
|
|
||||||
let filteredComments;
|
let filteredComments;
|
||||||
|
|
||||||
deleteComment(currentAccount, pinCode, permlink).then(() => {
|
deleteComment(currentAccount, pinCode, _permlink).then(() => {
|
||||||
if (_comments.length > 0) {
|
if (lcomments.length > 0) {
|
||||||
filteredComments = _comments.filter(item => item.permlink !== permlink);
|
filteredComments = lcomments.filter(item => item.permlink !== _permlink);
|
||||||
} else {
|
} else {
|
||||||
filteredComments = comments.filter(item => item.permlink !== permlink);
|
filteredComments = comments.filter(item => item.permlink !== _permlink);
|
||||||
}
|
}
|
||||||
this.setState({ comments: filteredComments });
|
setLComments(filteredComments);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleOnPressCommentMenu = (index, selectedComment) => {
|
const _handleOnPressCommentMenu = (index, selectedComment) => {
|
||||||
const { dispatch, intl, navigation, isOwnProfile } = this.props;
|
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
writeToClipboard(`https://esteem.app${get(selectedComment, 'url')}`).then(() => {
|
writeToClipboard(`https://esteem.app${get(selectedComment, 'url')}`).then(() => {
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -231,70 +226,34 @@ class CommentsContainer extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
return (
|
||||||
const { commentCount, selectedFilter } = this.props;
|
<CommentsView
|
||||||
|
key={selectedFilter}
|
||||||
if (nextProps.commentCount > commentCount) {
|
hasManyComments={hasManyComments}
|
||||||
this._getComments();
|
hideManyCommentsButton={hideManyCommentsButton}
|
||||||
}
|
selectedFilter={selectedFilter}
|
||||||
|
selectedPermlink={_selectedPermlink || selectedPermlink}
|
||||||
if (selectedFilter !== get(nextProps, 'selectedFilter') && get(nextProps, 'selectedFilter')) {
|
author={author}
|
||||||
const shortedComments = this._shortComments(get(nextProps, 'selectedFilter'));
|
mainAuthor={mainAuthor}
|
||||||
this.setState({ comments: shortedComments });
|
isShowMoreButton={isShowMoreButton}
|
||||||
}
|
commentNumber={commentNumber || 1}
|
||||||
}
|
commentCount={commentCount}
|
||||||
|
comments={lcomments.length > 0 ? lcomments : comments}
|
||||||
render() {
|
currentAccountUsername={currentAccount.name}
|
||||||
const { comments: _comments, selectedPermlink } = this.state;
|
handleOnEditPress={_handleOnEditPress}
|
||||||
const {
|
handleOnReplyPress={_handleOnReplyPress}
|
||||||
isLoggedIn,
|
isLoggedIn={isLoggedIn}
|
||||||
commentCount,
|
fetchPost={fetchPost}
|
||||||
author,
|
handleDeleteComment={_handleDeleteComment}
|
||||||
currentAccount,
|
handleOnPressCommentMenu={_handleOnPressCommentMenu}
|
||||||
commentNumber,
|
isOwnProfile={isOwnProfile}
|
||||||
comments,
|
isHideImage={isHideImage}
|
||||||
fetchPost,
|
handleOnVotersPress={_handleOnVotersPress}
|
||||||
isShowMoreButton,
|
isShowSubComments={isShowSubComments}
|
||||||
selectedFilter,
|
showAllComments={showAllComments}
|
||||||
mainAuthor,
|
/>
|
||||||
selectedPermlink: _selectedPermlink,
|
);
|
||||||
isOwnProfile,
|
};
|
||||||
isHideImage,
|
|
||||||
isShowSubComments,
|
|
||||||
hasManyComments,
|
|
||||||
showAllComments,
|
|
||||||
hideManyCommentsButton,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommentsView
|
|
||||||
key={selectedFilter}
|
|
||||||
hasManyComments={hasManyComments}
|
|
||||||
hideManyCommentsButton={hideManyCommentsButton}
|
|
||||||
selectedFilter={selectedFilter}
|
|
||||||
selectedPermlink={_selectedPermlink || selectedPermlink}
|
|
||||||
author={author}
|
|
||||||
mainAuthor={mainAuthor}
|
|
||||||
isShowMoreButton={isShowMoreButton}
|
|
||||||
commentNumber={commentNumber || 1}
|
|
||||||
commentCount={commentCount}
|
|
||||||
comments={_comments.length > 0 ? _comments : comments}
|
|
||||||
currentAccountUsername={currentAccount.name}
|
|
||||||
handleOnEditPress={this._handleOnEditPress}
|
|
||||||
handleOnReplyPress={this._handleOnReplyPress}
|
|
||||||
isLoggedIn={isLoggedIn}
|
|
||||||
fetchPost={fetchPost}
|
|
||||||
handleDeleteComment={this._handleDeleteComment}
|
|
||||||
handleOnPressCommentMenu={this._handleOnPressCommentMenu}
|
|
||||||
isOwnProfile={isOwnProfile}
|
|
||||||
isHideImage={isHideImage}
|
|
||||||
handleOnVotersPress={this._handleOnVotersPress}
|
|
||||||
isShowSubComments={isShowSubComments}
|
|
||||||
showAllComments={showAllComments}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
isLoggedIn: state.application.isLoggedIn,
|
isLoggedIn: state.application.isLoggedIn,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import SummaryArea from './summaryArea/view/summaryAreaView';
|
import SummaryArea from './summaryArea/view/summaryAreaView';
|
||||||
import TagArea from './tagArea/view/tagAreaView';
|
import TagArea from './tagArea/view/tagAreaView';
|
||||||
import TitleArea from './titleArea/view/titleAreaView';
|
import TitleArea from './titleArea/view/titleAreaView';
|
||||||
|
import TagInput from './tagInput/view/tagInputView';
|
||||||
|
|
||||||
export { SummaryArea, TagArea, TitleArea };
|
export { SummaryArea, TagArea, TitleArea, TagInput };
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||||
|
|
||||||
|
export default EStyleSheet.create({
|
||||||
|
textInput: {
|
||||||
|
color: '$primaryBlack',
|
||||||
|
fontSize: 15,
|
||||||
|
fontFamily: '$editorFont',
|
||||||
|
backgroundColor: '$primaryBackgroundColor',
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderTopColor: '$primaryLightGray',
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: '$primaryLightGray',
|
||||||
|
},
|
||||||
|
});
|
115
src/components/editorElements/tagInput/view/tagInputView.js
Normal file
115
src/components/editorElements/tagInput/view/tagInputView.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { View, Alert } from 'react-native';
|
||||||
|
// Constants
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import { TextInput } from '../../../textInput';
|
||||||
|
|
||||||
|
// Styles
|
||||||
|
import styles from './tagInputStyles';
|
||||||
|
import globalStyles from '../../../../globalStyles';
|
||||||
|
|
||||||
|
const TagInput = ({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
handleIsValid,
|
||||||
|
componentID,
|
||||||
|
handleTagChanged,
|
||||||
|
intl,
|
||||||
|
isPreviewActive,
|
||||||
|
autoFocus,
|
||||||
|
}) => {
|
||||||
|
const [text, setText] = useState('');
|
||||||
|
const [height, setHeight] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
setText(value);
|
||||||
|
} else {
|
||||||
|
setText(value.join(' '));
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
// Component Functions
|
||||||
|
const _handleOnChange = _text => {
|
||||||
|
setText(_text.replace(/,/g, ' ').replace(/#/g, ''));
|
||||||
|
};
|
||||||
|
const _handleOnBlur = () => {
|
||||||
|
if (onChange) {
|
||||||
|
let cats = text.trim().split(' ');
|
||||||
|
if (handleTagChanged && cats.length > 0) {
|
||||||
|
cats.length > 10
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_tags' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => c.length > 24)
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_length' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => c.split('-').length > 2)
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_dash' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => c.indexOf(',') >= 0)
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_space' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => /[A-Z]/.test(c))
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_lowercase' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => !/^[a-z0-9-#]+$/.test(c))
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_characters' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => !/^[a-z-#]/.test(c))
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_firstchar' }),
|
||||||
|
)
|
||||||
|
: cats.find(c => !/[a-z0-9]$/.test(c))
|
||||||
|
? Alert.alert(
|
||||||
|
intl.formatMessage({ id: 'alert.error' }),
|
||||||
|
intl.formatMessage({ id: 'editor.limited_lastchar' }),
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
handleTagChanged([...cats]);
|
||||||
|
}
|
||||||
|
onChange(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handleIsValid) {
|
||||||
|
handleIsValid(componentID, !!(text && text.length));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<View style={[globalStyles.containerHorizontal16, { height: Math.max(35, height) }]}>
|
||||||
|
<TextInput
|
||||||
|
style={[styles.textInput, { height: Math.max(35, height) }]}
|
||||||
|
placeholderTextColor="#c1c5c7"
|
||||||
|
editable={!isPreviewActive}
|
||||||
|
maxLength={100}
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'editor.tags',
|
||||||
|
})}
|
||||||
|
multiline
|
||||||
|
numberOfLines={2}
|
||||||
|
onContentSizeChange={event => {
|
||||||
|
setHeight(event.nativeEvent.contentSize.height);
|
||||||
|
}}
|
||||||
|
autoFocus={autoFocus}
|
||||||
|
onChangeText={textT => _handleOnChange(textT)}
|
||||||
|
onBlur={() => _handleOnBlur()}
|
||||||
|
value={text}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TagInput;
|
@ -38,7 +38,7 @@ import { SearchModal } from './searchModal';
|
|||||||
import { SettingsItem } from './settingsItem';
|
import { SettingsItem } from './settingsItem';
|
||||||
import { SideMenu } from './sideMenu';
|
import { SideMenu } from './sideMenu';
|
||||||
|
|
||||||
import { SummaryArea, TagArea, TitleArea } from './editorElements';
|
import { SummaryArea, TagArea, TitleArea, TagInput } from './editorElements';
|
||||||
import { TabBar } from './tabBar';
|
import { TabBar } from './tabBar';
|
||||||
import { TextInput } from './textInput';
|
import { TextInput } from './textInput';
|
||||||
import { ToastNotification } from './toastNotification';
|
import { ToastNotification } from './toastNotification';
|
||||||
@ -170,6 +170,7 @@ export {
|
|||||||
TabBar,
|
TabBar,
|
||||||
Tag,
|
Tag,
|
||||||
TagArea,
|
TagArea,
|
||||||
|
TagInput,
|
||||||
Tags,
|
Tags,
|
||||||
TextButton,
|
TextButton,
|
||||||
TextInput,
|
TextInput,
|
||||||
|
@ -156,7 +156,7 @@ const CommentBody = ({
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
br: (htmlAttribs, children, passProps) => {
|
br: (htmlAttribs, children, convertedCSSStyles, passProps) => {
|
||||||
return <Text {...passProps}>{'\n'}</Text>;
|
return <Text {...passProps}>{'\n'}</Text>;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -166,7 +166,6 @@ const CommentBody = ({
|
|||||||
return (
|
return (
|
||||||
<HTML
|
<HTML
|
||||||
html={body}
|
html={body}
|
||||||
key={`key-${created.toString()}`}
|
|
||||||
onLinkPress={(evt, href, hrefAtr) => _handleOnLinkPress(evt, href, hrefAtr)}
|
onLinkPress={(evt, href, hrefAtr) => _handleOnLinkPress(evt, href, hrefAtr)}
|
||||||
containerStyle={styles.commentContainer}
|
containerStyle={styles.commentContainer}
|
||||||
textSelectable={textSelectable}
|
textSelectable={textSelectable}
|
||||||
|
@ -7,6 +7,7 @@ for (i = 0; i < images.length; i++) {
|
|||||||
}
|
}
|
||||||
var resultStr = JSON.stringify(JSON.stringify(result)); // workaround
|
var resultStr = JSON.stringify(JSON.stringify(result)); // workaround
|
||||||
var message = 'window.ReactNativeWebView.postMessage(' + resultStr + ')';
|
var message = 'window.ReactNativeWebView.postMessage(' + resultStr + ')';
|
||||||
|
|
||||||
images[i].setAttribute("onClick", message);
|
images[i].setAttribute("onClick", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,10 +260,26 @@ const PostBody = ({
|
|||||||
}
|
}
|
||||||
.markdown-video-link {
|
.markdown-video-link {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
.markdown-video-play {
|
||||||
|
position: absolute;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: url('data:image/png;base64,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') no-repeat center center;
|
||||||
|
z-index: 20;
|
||||||
|
opacity: 0.9;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -100px;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
-webkit-transform: translateX(-50%) translateY(-50%);
|
||||||
|
-moz-transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 320px;
|
height: 240px;
|
||||||
}
|
}
|
||||||
.pull-right {
|
.pull-right {
|
||||||
float: right;
|
float: right;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useRef, useState, Fragment } from 'react';
|
import React, { useCallback, useEffect, useRef, useState, Fragment } from 'react';
|
||||||
import { View, Text, ScrollView, Dimensions, SafeAreaView } from 'react-native';
|
import { View, Text, ScrollView, Dimensions, SafeAreaView, RefreshControl } from 'react-native';
|
||||||
import { injectIntl } from 'react-intl';
|
import { injectIntl } from 'react-intl';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import ActionSheet from 'react-native-actionsheet';
|
import ActionSheet from 'react-native-actionsheet';
|
||||||
@ -43,6 +43,7 @@ const PostDisplayView = ({
|
|||||||
const [scrollHeight, setScrollHeight] = useState(0);
|
const [scrollHeight, setScrollHeight] = useState(0);
|
||||||
const [isLoadedComments, setIsLoadedComments] = useState(false);
|
const [isLoadedComments, setIsLoadedComments] = useState(false);
|
||||||
const actionSheet = useRef(null);
|
const actionSheet = useRef(null);
|
||||||
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
|
|
||||||
// Component Life Cycles
|
// Component Life Cycles
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -52,6 +53,11 @@ const PostDisplayView = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Component Functions
|
// Component Functions
|
||||||
|
const onRefresh = useCallback(() => {
|
||||||
|
setRefreshing(true);
|
||||||
|
fetchPost().then(() => setRefreshing(false));
|
||||||
|
}, [refreshing]);
|
||||||
|
|
||||||
const _handleOnScroll = event => {
|
const _handleOnScroll = event => {
|
||||||
const { y } = event.nativeEvent.contentOffset;
|
const { y } = event.nativeEvent.contentOffset;
|
||||||
|
|
||||||
@ -164,6 +170,7 @@ const PostDisplayView = ({
|
|||||||
style={styles.scroll}
|
style={styles.scroll}
|
||||||
onScroll={event => _handleOnScroll(event)}
|
onScroll={event => _handleOnScroll(event)}
|
||||||
scrollEventThrottle={16}
|
scrollEventThrottle={16}
|
||||||
|
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
|
||||||
>
|
>
|
||||||
{parentPost && <ParentPost post={parentPost} />}
|
{parentPost && <ParentPost post={parentPost} />}
|
||||||
|
|
||||||
|
@ -246,13 +246,21 @@
|
|||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"tags": "tags",
|
"tags": "Tags (separate by space)",
|
||||||
"default_placeholder": "What would you like to write about today?",
|
"default_placeholder": "What would you like to write about today?",
|
||||||
"reply_placeholder": "What would you like to write about above post?",
|
"reply_placeholder": "What would you like to write about above post?",
|
||||||
"publish": "Publish",
|
"publish": "Publish",
|
||||||
"reply": "Reply",
|
"reply": "Reply",
|
||||||
"open_gallery": "Open Gallery",
|
"open_gallery": "Open Gallery",
|
||||||
"capture_photo": "Capture a photo"
|
"capture_photo": "Capture a photo",
|
||||||
|
"limited_tags": "Only 10 tags allowed, remove some",
|
||||||
|
"limited_length": "Maximum length of each tag should be 24",
|
||||||
|
"limited_dash": "Use one dash in each tag",
|
||||||
|
"limited_space": "Use space to separate tags",
|
||||||
|
"limited_lowercase": "Only use lower letters in tag",
|
||||||
|
"limited_characters": "Use only allowed characters in tag",
|
||||||
|
"limited_firstchar": "Tag must start with a letter",
|
||||||
|
"limited_lastchar": "Tag must end with letter or number"
|
||||||
},
|
},
|
||||||
"pincode": {
|
"pincode": {
|
||||||
"enter_text": "Enter PIN to unlock",
|
"enter_text": "Enter PIN to unlock",
|
||||||
|
@ -79,11 +79,10 @@ import lightTheme from '../../../themes/lightTheme';
|
|||||||
let previousAppState = 'background';
|
let previousAppState = 'background';
|
||||||
export const setPreviousAppState = () => {
|
export const setPreviousAppState = () => {
|
||||||
previousAppState = AppState.currentState;
|
previousAppState = AppState.currentState;
|
||||||
/*const appStateTimeout = setTimeout(() => {
|
const appStateTimeout = setTimeout(() => {
|
||||||
console.log('current appstate timeout', AppState.currentState);
|
|
||||||
previousAppState = AppState.currentState;
|
previousAppState = AppState.currentState;
|
||||||
clearTimeout(appStateTimeout);
|
clearTimeout(appStateTimeout);
|
||||||
}, 2000);*/
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ApplicationContainer extends Component {
|
class ApplicationContainer extends Component {
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
BasicHeader,
|
BasicHeader,
|
||||||
TitleArea,
|
TitleArea,
|
||||||
TagArea,
|
TagArea,
|
||||||
|
TagInput,
|
||||||
SummaryArea,
|
SummaryArea,
|
||||||
PostForm,
|
PostForm,
|
||||||
MarkdownEditor,
|
MarkdownEditor,
|
||||||
@ -44,7 +45,6 @@ class EditorScreen extends Component {
|
|||||||
// Component Life Cycles
|
// Component Life Cycles
|
||||||
UNSAFE_componentWillReceiveProps = async nextProps => {
|
UNSAFE_componentWillReceiveProps = async nextProps => {
|
||||||
const { draftPost, isUploading } = this.props;
|
const { draftPost, isUploading } = this.props;
|
||||||
|
|
||||||
if (nextProps.draftPost && draftPost !== nextProps.draftPost) {
|
if (nextProps.draftPost && draftPost !== nextProps.draftPost) {
|
||||||
await this.setState(prevState => ({
|
await this.setState(prevState => ({
|
||||||
fields: {
|
fields: {
|
||||||
@ -147,6 +147,8 @@ class EditorScreen extends Component {
|
|||||||
fields.body = content;
|
fields.body = content;
|
||||||
} else if (componentID === 'title') {
|
} else if (componentID === 'title') {
|
||||||
fields.title = content;
|
fields.title = content;
|
||||||
|
} else if (componentID === 'tag-area') {
|
||||||
|
fields.tags = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -167,11 +169,11 @@ class EditorScreen extends Component {
|
|||||||
const { fields: _fields } = this.state;
|
const { fields: _fields } = this.state;
|
||||||
const _tags = tags.filter(tag => tag && tag !== ' ');
|
const _tags = tags.filter(tag => tag && tag !== ' ');
|
||||||
const __tags = _tags.map(t => t.toLowerCase());
|
const __tags = _tags.map(t => t.toLowerCase());
|
||||||
|
const __fields = { ..._fields, tags: [...__tags] };
|
||||||
|
|
||||||
const fields = { ..._fields, tags: [...__tags] };
|
this.setState({ fields: __fields, isRemoveTag: false }, () => {
|
||||||
await this.setState({ fields, isRemoveTag: false });
|
this._handleFormUpdate('tag-area', __fields.tags);
|
||||||
|
});
|
||||||
this._handleFormUpdate();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -222,14 +224,15 @@ class EditorScreen extends Component {
|
|||||||
isPreviewActive={isPreviewActive}
|
isPreviewActive={isPreviewActive}
|
||||||
>
|
>
|
||||||
{isReply && !isEdit && <SummaryArea summary={post.summary} />}
|
{isReply && !isEdit && <SummaryArea summary={post.summary} />}
|
||||||
{!isReply && <TitleArea value={fields.title} componentID="title" intl={intl} />}
|
|
||||||
{!isReply && (
|
{!isReply && (
|
||||||
<TagArea
|
<TitleArea value={fields.title} componentID="title" intl={intl} autoFocus={true} />
|
||||||
draftChips={fields.tags.length > 0 ? fields.tags : null}
|
)}
|
||||||
isRemoveTag={isRemoveTag}
|
{!isReply && (
|
||||||
|
<TagInput
|
||||||
|
value={fields.tags}
|
||||||
componentID="tag-area"
|
componentID="tag-area"
|
||||||
handleTagChanged={this._handleOnTagAdded}
|
|
||||||
intl={intl}
|
intl={intl}
|
||||||
|
handleTagChanged={this._handleOnTagAdded}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
@ -253,3 +256,12 @@ class EditorScreen extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(EditorScreen);
|
export default injectIntl(EditorScreen);
|
||||||
|
/*
|
||||||
|
<TagArea
|
||||||
|
draftChips={fields.tags.length > 0 ? fields.tags : null}
|
||||||
|
isRemoveTag={isRemoveTag}
|
||||||
|
componentID="tag-area"
|
||||||
|
handleTagChanged={this._handleOnTagAdded}
|
||||||
|
intl={intl}
|
||||||
|
/>
|
||||||
|
*/
|
||||||
|
@ -1113,10 +1113,10 @@
|
|||||||
exec-sh "^0.3.2"
|
exec-sh "^0.3.2"
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
|
|
||||||
"@esteemapp/esteem-render-helpers@^1.2.9":
|
"@esteemapp/esteem-render-helpers@^1.3.0":
|
||||||
version "1.2.9"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@esteemapp/esteem-render-helpers/-/esteem-render-helpers-1.2.9.tgz#b4b6bd7e346e323a8d99bfce84928770443316b1"
|
resolved "https://registry.yarnpkg.com/@esteemapp/esteem-render-helpers/-/esteem-render-helpers-1.3.0.tgz#a109eb8ff045aae7dd0bc7462a79123928c3f8ff"
|
||||||
integrity sha512-mQ/rweQQYiVfMU++SkAILrn8s34PtaKR+5wVmfq1qh1JHDVFLqw0PjIPjw/kNphKo55J4zIooKMNKYfkwmzlfQ==
|
integrity sha512-hIe5Q6e6rw4y7nHfVcryeKJFrlyW5JXnhxcg65gMHE29fqV4M+iH4wzrMLQuFZFA9SSKL1yYZHuVVrN2/MMdHQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
he "^1.2.0"
|
he "^1.2.0"
|
||||||
path "^0.12.7"
|
path "^0.12.7"
|
||||||
|
Loading…
Reference in New Issue
Block a user