Update for post display view

This commit is contained in:
Mustafa Buyukcelebi 2019-11-21 23:44:39 +03:00
parent 42ef794f01
commit 4bb765b9fe
2 changed files with 222 additions and 202 deletions

View File

@ -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 = '<iframe frameborder="0" allowfullscreen src="' + el.getAttribute('data-embed-src') + '"></iframe>';
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;`;

View File

@ -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 (
<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 test = body.replace(/<a/g, '<a target="_blank"');
// console.log('test :', test);
const runFirst = `
document.addEventListener('click', function(event) {
let el = event.target;
// A element can be wrapped with inline element. Look parent elements.
// alert(el.tagName.toString())
while (el.tagName !== 'A') {
if (!el.parentNode) {
break;
}
el = el.parentNode;
}
window.ReactNativeWebView.postMessage('"Hello!"')
window.ReactNativeWebView.postMessage('1')
if (!el || el.tagName !== 'A') {
// window.ReactNativeWebView.postMessage(!el)
// window.ReactNativeWebView.postMessage(el.tagName)
return;
}
window.ReactNativeWebView.postMessage('2')
if (el.getAttribute('target') === '_external') {
const href = el.getAttribute('href');
shell.openExternal(href);
event.preventDefault();
return true;
}
window.ReactNativeWebView.postMessage('3')
if (el.classList.contains('markdown-external-link')) {
const href = el.getAttribute('data-href');
shell.openExternal(href);
event.preventDefault();
return true;
}
window.ReactNativeWebView.postMessage('4')
const author = el.getAttribute('data-author').toString();
window.ReactNativeWebView.postMessage(JSON.stringify(author))
})
true; // note: this is required, or you'll sometimes get silent failures
`;
// console.log('body :', body);
// EStyleSheet.value('$contentWidth')
const customStyle = `
* {
color: ${EStyleSheet.value('$primaryBlack')};
font-family: Roboto, sans-serif;
max-width: 100%;
}
body {
color: ${EStyleSheet.value('$primaryBlack')};
@ -237,11 +141,11 @@ const PostBody = ({
a {
color: ${EStyleSheet.value('$primaryBlue')};
cursor: pointer;
text-decoration: underline;
}
img {
max-width: 100%;
margin-bottom: 30px;
align-self: 'center';
max-width: 100%;
}
center {
text-align: 'center';
@ -280,44 +184,54 @@ const PostBody = ({
text-align: 'center';
align-items: 'center';
justify-content: 'center';
}`;
console.log('EStyleSheet.value', EStyleSheet.value('$primaryBlack'));
console.log('customStyle :', customStyle);
}
.markdown-video-link {
max-width: 100%;
}
.pull-right {
float: right;
}
.pull-left {
float: left;
}
.pull-left,
.pull-right {
max-width: calc(50% - 10px);
padding-left: 10px;
margin-bottom: 10px;
box-sizing: border-box;
}
.phishy {
display: inline;
color: red;
}
.text-justify {
text-align: justify;
text-justify: inter-word;
letter-spacing: 0px;
}
`;
return (
<Fragment>
<AutoHeightWebView
style={{ maxWidth: Dimensions.get('window').width - 15, marginTop: 35 }}
source={{
html: test,
}}
// javaScriptEnabled={false}
style={{width: WIDTH - 32}}
customStyle={customStyle}
onMessage={m => console.log('message :', m.nativeEvent.data)}
// onShouldStartLoadWithRequest={handleWebViewNavigationStateChange}
customScript={runFirst}
/>
<HTML
html={body}
onLinkPress={(evt, href, hrefAtr) => _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 ? <ListItemPlaceHolder /> : <PostPlaceHolder />
}
customScript={script.toString()}
startInLoadingState={true}
/>
</Fragment>
);
};
const areEqual = (prevProps, nextProps) => {
// console.log('prevProps, nextProps :', prevProps, nextProps);
if (prevProps.body !== nextProps.body) {
return true;
}