Reverted comment render system

This commit is contained in:
Mustafa Buyukcelebi 2019-12-09 17:36:07 +03:00
parent f112a100f3
commit 6bb7529ffd
6 changed files with 244 additions and 91 deletions

View File

@ -8,7 +8,7 @@ import { getTimeFromNow } from '../../../utils/time';
// Constants
// Components
import { PostBody, PostHeaderDescription } from '../../postElements';
import { CommentBody, PostHeaderDescription } from '../../postElements';
import { Upvote } from '../../upvote';
import { IconButton } from '../../iconButton';
import { Comments } from '../../comments';
@ -63,8 +63,7 @@ const CommentView = ({
isHideImage={isHideImage}
/>
<View style={[{ marginLeft: marginLeft || 29 }, styles.bodyWrapper]}>
<PostBody
isComment
<CommentBody
commentDepth={comment.depth}
handleOnUserPress={handleOnUserPress}
body={comment.body}

View File

@ -1,25 +0,0 @@
import React, { PureComponent } from 'react';
import CommentsDisplayView from '../view/commentsDisplayView';
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
*
*/
class CommentsContainer extends PureComponent {
constructor(props) {
super(props);
this.state = {};
}
// Component Life Cycle Functions
// Component Functions
render() {
return <CommentsDisplayView {...this.props} />;
}
}
export default CommentsContainer;

View File

@ -1,5 +1,4 @@
import CommentsDisplayView from './view/commentsDisplayView';
import CommentsDisplay from './container/commentsDisplayContainer';
import CommentsDisplay from './view/commentsDisplayView';
export { CommentsDisplayView, CommentsDisplay };
export { CommentsDisplay };
export default CommentsDisplay;

View File

@ -1,4 +1,4 @@
import React, { PureComponent, Fragment } from 'react';
import React, { useState, Fragment } from 'react';
import { View } from 'react-native';
import { injectIntl } from 'react-intl';
@ -10,67 +10,51 @@ import COMMENT_FILTER, { VALUE } from '../../../constants/options/comment';
// Styles
import styles from './commentDisplayStyles';
class CommentsDisplayView extends PureComponent {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
const CommentsDisplayView = ({
author,
commentCount,
fetchPost,
intl,
permlink,
mainAuthor,
handleOnVotersPress,
}) => {
const [selectedFilter, setSelectedFilter] = useState(null);
const [selectedOptionIndex, setSelectedOptionIndex] = useState(0);
constructor(props) {
super(props);
this.state = {
selectedFilter: null,
selectedOptionIndex: 0,
};
}
// Component Life Cycles
// Component Functions
_handleOnDropdownSelect = (option, index) => {
this.setState({ selectedFilter: option, selectedOptionIndex: index });
const _handleOnDropdownSelect = (option, index) => {
setSelectedFilter(option);
setSelectedOptionIndex(index);
};
render() {
const {
author,
commentCount,
fetchPost,
intl,
permlink,
mainAuthor,
handleOnVotersPress,
} = this.props;
const { selectedFilter, selectedOptionIndex } = this.state;
return (
<Fragment>
{commentCount > 0 && (
<Fragment>
<FilterBar
dropdownIconName="arrow-drop-down"
options={VALUE.map(val => intl.formatMessage({ id: `comment_filter.${val}` }))}
defaultText={intl.formatMessage({ id: `comment_filter.${VALUE[0]}` })}
onDropdownSelect={selectedIndex =>
this._handleOnDropdownSelect(COMMENT_FILTER[selectedIndex], selectedIndex)
}
selectedOptionIndex={selectedOptionIndex}
return (
<Fragment>
{commentCount > 0 && (
<Fragment>
<FilterBar
dropdownIconName="arrow-drop-down"
options={VALUE.map(val => intl.formatMessage({ id: `comment_filter.${val}` }))}
defaultText={intl.formatMessage({ id: `comment_filter.${VALUE[0]}` })}
onDropdownSelect={selectedIndex =>
_handleOnDropdownSelect(COMMENT_FILTER[selectedIndex], selectedIndex)
}
selectedOptionIndex={selectedOptionIndex}
/>
<View style={styles.commentWrapper}>
<Comments
selectedFilter={selectedFilter}
fetchPost={fetchPost}
commentCount={commentCount}
author={author}
permlink={permlink}
mainAuthor={mainAuthor}
handleOnVotersPress={handleOnVotersPress}
/>
<View style={styles.commentWrapper}>
<Comments
selectedFilter={selectedFilter}
fetchPost={fetchPost}
commentCount={commentCount}
author={author}
permlink={permlink}
mainAuthor={mainAuthor}
handleOnVotersPress={handleOnVotersPress}
/>
</View>
</Fragment>
)}
</Fragment>
);
}
}
</View>
</Fragment>
)}
</Fragment>
);
};
export default injectIntl(CommentsDisplayView);

View File

@ -0,0 +1,195 @@
import React, { Fragment } from 'react';
import { Dimensions, Linking, Alert, TouchableOpacity, Text } from 'react-native';
import { withNavigation } from 'react-navigation';
import { useIntl, injectIntl } from 'react-intl';
import HTML from 'react-native-render-html';
import { getParentsTagsRecursively } from 'react-native-render-html/src/HTMLUtils';
// Constants
import { default as ROUTES } from '../../../../constants/routeNames';
// Styles
import styles from './postBodyStyles';
const WIDTH = Dimensions.get('window').width;
const CommentBody = ({
navigation,
body,
textSelectable = true,
handleOnUserPress,
handleOnPostPress,
}) => {
const intl = useIntl();
const _handleOnLinkPress = (href, hrefAtr) => {
if (hrefAtr.class === 'markdown-author-link') {
if (!handleOnUserPress) {
_handleOnUserPress(hrefAtr['data-author']);
} else {
handleOnUserPress(hrefAtr['data-author']);
}
} else if (hrefAtr.class === 'markdown-post-link') {
if (!handleOnPostPress) {
_handleOnPostPress(hrefAtr['data-permlink'], hrefAtr['data-author']);
} else {
handleOnPostPress(hrefAtr['data-permlink']);
}
} else {
_handleBrowserLink(href);
}
};
const _handleBrowserLink = async url => {
if (!url) {
return;
}
Linking.canOpenURL(url).then(supported => {
if (supported) {
Linking.openURL(url);
} else {
Alert.alert(intl.formatMessage({ id: 'alert.failed_to_open' }));
}
});
};
const _handleOnPostPress = (permlink, author) => {
if (permlink) {
navigation.navigate({
routeName: ROUTES.SCREENS.POST,
params: {
author,
permlink,
},
key: permlink,
});
}
};
const _handleOnUserPress = username => {
if (username) {
navigation.navigate({
routeName: ROUTES.SCREENS.PROFILE,
params: {
username,
},
key: username,
});
} else {
Alert.alert('Opss!', 'Wrong link.');
}
};
const _hasParentTag = (node, name) => {
if (!node.parent) {
return false;
}
if (node.name === name) {
return true;
}
return _hasParentTag(node.parent, name);
};
const _alterNode = node => {
if (node.name === 'img') {
node.attribs.style = 'text-align: center;';
if (_hasParentTag(node, 'td')) {
node.attribs.style = `max-width: ${WIDTH / 2 - 20}px; `;
}
}
if (node.name === 'div' && node.attribs && node.attribs.class) {
const _className = node.attribs.class;
if (_className === 'pull-right') {
node.attribs.style = 'text-align: right; align-self: flex-end;';
}
if (_className === 'pull-left') {
node.attribs.style = 'text-align: left; align-self: flex-start;';
}
if (_className === 'text-justify') {
node.attribs.style = 'text-align: justify; text-justify: inter-word; letter-spacing: 0px;';
}
if (_className === 'phishy') {
node.attribs.style = 'color: red';
}
}
};
const _alterData = node => {
if (
node.type === 'text' &&
node.data.includes('markdown-author-link') &&
node.parent &&
getParentsTagsRecursively(node.parent).includes('code')
) {
return node.data.replace(/<[^>]*>/g, '');
}
};
const _customRenderer = {
a: (htmlAttribs, children, convertedCSSStyles, passProps) => {
if (passProps.parentWrapper === 'Text') {
return (
<Text
key={passProps.key}
{...htmlAttribs}
onPress={() => _handleOnLinkPress(htmlAttribs['data-href'], htmlAttribs)}
>
{children}
</Text>
);
}
return (
<TouchableOpacity
key={passProps.key}
{...htmlAttribs}
onPress={() => _handleOnLinkPress(htmlAttribs['data-href'], htmlAttribs)}
>
{children}
</TouchableOpacity>
);
},
br: (htmlAttribs, children, passProps) => {
return <Text {...passProps}>{'\n'}</Text>;
},
};
const _initialDimensions = { width: WIDTH - 50, height: 80 };
return (
<Fragment>
<HTML
html={body}
onLinkPress={(evt, href, hrefAtr) => _handleOnLinkPress(evt, href, hrefAtr)}
containerStyle={styles.commentContainer}
textSelectable={textSelectable}
tagsStyles={{ img: { height: 120 } }}
ignoredTags={['script']}
debug={false}
staticContentMaxWidth={WIDTH - 33}
imagesInitialDimensions={_initialDimensions}
baseFontStyle={styles.text}
imagesMaxWidth={WIDTH - 50}
alterNode={_alterNode}
alterData={_alterData}
renderers={_customRenderer}
/>
</Fragment>
);
};
const areEqual = (prevProps, nextProps) => {
if (prevProps.body !== nextProps.body) {
return true;
}
return false;
};
export default React.memo(injectIntl(withNavigation(CommentBody)), areEqual);

View File

@ -1,5 +1,6 @@
import PostHeaderDescription from './headerDescription/view/postHeaderDescription';
import PostBody from './body/view/postBodyView';
import CommentBody from './body/view/commentBodyView';
import Tags from './tags/view/tagsView';
export { PostHeaderDescription, PostBody, Tags };
export { PostHeaderDescription, PostBody, Tags, CommentBody };