diff --git a/src/components/postElements/body/view/config.js b/src/components/postElements/body/view/config.js new file mode 100644 index 000000000..30c8fc2f4 --- /dev/null +++ b/src/components/postElements/body/view/config.js @@ -0,0 +1,106 @@ +export default `document.addEventListener('click', function(event) { + let el = event.target; + // A element can be wrapped with inline element. Look parent elements. + while (el.tagName !== 'A') { + if (!el.parentNode) { + break; + } + el = el.parentNode; + } + if (!el || el.tagName !== 'A') { + window.ReactNativeWebView.postMessage('4'); + if (el.tagName) window.ReactNativeWebView.postMessage(el.tagName); + return; + } + if (el.getAttribute('target') === '_external') { + const href = el.getAttribute('href'); + const result = { + type: '_external', + href + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + + return true; + } + if (el.classList.contains('markdown-external-link')) { + const href = el.getAttribute('data-href'); + const result = { + type: 'markdown-external-link', + href + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + + return true; + } + if (el.classList.contains('markdown-author-link')) { + const author = el.getAttribute('data-author'); + const result = { + type: 'markdown-author-link', + author, + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + + if (el.classList.contains('markdown-post-link')) { + let category = el.getAttribute('data-tag'); + let author = el.getAttribute('data-author'); + let permlink = el.getAttribute('data-permlink'); + const result = { + type: 'markdown-post-link', + category, + author, + permlink, + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + if (el.classList.contains('markdown-tag-link')) { + let tag = el.getAttribute('data-tag'); + const result = { + type: 'markdown-tag-link', + tag + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + if (el.classList.contains('markdown-witnesses-link')) { + + const result = { + type: 'markdown-witnesses-link' + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + if (el.classList.contains('markdown-proposal-link')) { + + let proposal = el.getAttribute('data-proposal'); + const result = { + type: 'markdown-proposal-link', + proposal + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + return false; + } + if (el.classList.contains('markdown-video-link')) { + const embedSrc = ''; + if (embedSrc) { + el.innerHTML = embedSrc; + return; + } + const videoHref = el.getAttribute('data-video-href'); + if (videoHref) { + const result = { + type: 'markdown-video-link', + videoHref + } + window.ReactNativeWebView.postMessage(JSON.stringify(result)); + + return false; + } + } + window.ReactNativeWebView.postMessage('4'); + const author = el.getAttribute('data-author').toString(); + window.ReactNativeWebView.postMessage(JSON.stringify(author)); +}) +true;`; diff --git a/src/components/postElements/body/view/postBodyView.js b/src/components/postElements/body/view/postBodyView.js index 7bc42b967..932c891c9 100644 --- a/src/components/postElements/body/view/postBodyView.js +++ b/src/components/postElements/body/view/postBodyView.js @@ -1,17 +1,16 @@ -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'; +import React, {Fragment} from 'react'; +import {Dimensions, Linking, Alert} from 'react-native'; +import {withNavigation} from 'react-navigation'; +import {useIntl, injectIntl} from 'react-intl'; import AutoHeightWebView from 'react-native-autoheight-webview'; import EStyleSheet from 'react-native-extended-stylesheet'; +import get from 'lodash/get'; + +import script from './config.js'; +import {PostPlaceHolder, ListItemPlaceHolder} from '../../../basicUIElements'; // Constants -import { default as ROUTES } from '../../../../constants/routeNames'; - -// Styles -import styles from './postBodyStyles'; +import {default as ROUTES} from '../../../../constants/routeNames'; const WIDTH = Dimensions.get('window').width; @@ -25,36 +24,81 @@ const PostBody = ({ }) => { const intl = useIntl(); - const _handleOnLinkPress = (href, hrefAtr) => { - if (hrefAtr.class === 'markdown-author-link') { - if (!handleOnUserPress) { - _handleOnUserPress(hrefAtr['data-author']); - } else { - handleOnUserPress(hrefAtr['data-author']); + const _handleOnLinkPress = event => { + if ((!event && !get(event, 'nativeEvent.data'), false)) { + return; + } + + try { + const data = JSON.parse(get(event, 'nativeEvent.data')); + + const { + type, + href, + author, + category, + permlink, + tag, + proposal, + videoHref, + } = data; + + switch (type) { + case '_external': + case 'markdown-external-link': + _handleBrowserLink(href); + break; + case 'markdown-author-link': + if (!handleOnUserPress) { + _handleOnUserPress(author); + } else { + handleOnUserPress(author); + } + break; + case 'markdown-post-link': + if (!handleOnPostPress) { + _handleOnPostPress(permlink, author); + } else { + handleOnPostPress(permlink, author); + } + break; + case 'markdown-tag-link': + _handleTagPress(tag); + break; + case 'markdown-witnesses-link': + break; + case 'markdown-proposal-link': + break; + case 'markdown-video-link': + break; + + default: + break; } - } else if (hrefAtr.class === 'markdown-post-link') { - if (!handleOnPostPress) { - _handleOnPostPress(hrefAtr['data-permlink'], hrefAtr['data-author']); - } else { - handleOnPostPress(hrefAtr['data-permlink']); - } - } else { - _handleBrowserLink(href); + } catch (error) {} + }; + + const _handleTagPress = tag => { + if (tag) { + navigation.navigate({ + routeName: ROUTES.SCREENS.SEARCH_RESULT, + params: { + tag, + }, + }); } }; const _handleBrowserLink = async url => { - if (!url) { - return; + if (url) { + Linking.canOpenURL(url).then(supported => { + if (supported) { + Linking.openURL(url); + } else { + Alert.alert(intl.formatMessage({id: 'alert.failed_to_open'})); + } + }); } - - Linking.canOpenURL(url).then(supported => { - if (supported) { - Linking.openURL(url); - } else { - Alert.alert(intl.formatMessage({ id: 'alert.failed_to_open' })); - } - }); }; const _handleOnPostPress = (permlink, author) => { @@ -84,152 +128,12 @@ const PostBody = ({ } }; - const _hasParentTag = (node, name) => { - if (!node.parent) { - return false; - } - - if (node.name === name) { - return true; - } - - return _hasParentTag(node.parent, name); - }; - - const _alterNode = (node, isComment) => { - if (isComment) { - if (node.name === 'img') { - node.attribs.style = `max-width: ${WIDTH - 50}px; height: 100px; width: ${WIDTH - - 50}px; text-align: center;`; - } - } else if (node.name === 'a') { - node.attribs.style = 'text-decoration: underline'; - } - - 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 handleWebViewNavigationStateChange = newNavState => { - console.log('newNavState :', newNavState); - if (newNavState.navigationType === 'click') { - return false; - } - return newNavState; - }; - - const _initialDimensions = isComment - ? { width: WIDTH - 50, height: 80 } - : { width: WIDTH, height: 216 }; - - const _customRenderer = { - a: (htmlAttribs, children, convertedCSSStyles, passProps) => { - if (passProps.parentWrapper === 'Text') { - return ( - _handleOnLinkPress(htmlAttribs['data-href'], htmlAttribs)} - > - {children} - - ); - } - return ( - _handleOnLinkPress(htmlAttribs['data-href'], htmlAttribs)} - > - {children} - - ); - }, - br: (htmlAttribs, children, passProps) => { - return {'\n'}; - }, - }; const test = body.replace(/ console.log('message :', m.nativeEvent.data)} - // onShouldStartLoadWithRequest={handleWebViewNavigationStateChange} - customScript={runFirst} - /> - _handleOnLinkPress(evt, href, hrefAtr)} - containerStyle={isComment ? styles.commentContainer : styles.container} - textSelectable={textSelectable} - tagsStyles={isComment ? { img: { height: 120 } } : styles} - ignoredTags={['script']} - debug={false} - staticContentMaxWidth={WIDTH - 33} - imagesInitialDimensions={_initialDimensions} - baseFontStyle={styles.text} - imagesMaxWidth={isComment ? WIDTH - 50 : WIDTH} - alterNode={e => _alterNode(e, isComment)} - alterData={e => _alterData(e)} - renderers={_customRenderer} + onMessage={_handleOnLinkPress} + renderLoading={() => + isComment ? : + } + customScript={script.toString()} + startInLoadingState={true} /> ); }; const areEqual = (prevProps, nextProps) => { - // console.log('prevProps, nextProps :', prevProps, nextProps); if (prevProps.body !== nextProps.body) { return true; }