mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-29 22:07:46 +03:00
Merge pull request #2053 from ecency/nt/native-render
WIP - Nt/native render
This commit is contained in:
commit
fcd8bd7b56
@ -33,7 +33,6 @@
|
||||
"@esteemapp/dhive": "0.15.0",
|
||||
"@esteemapp/react-native-autocomplete-input": "^4.2.1",
|
||||
"@esteemapp/react-native-multi-slider": "^1.1.0",
|
||||
"@esteemapp/react-native-render-html": "^4.1.5",
|
||||
"@esteemapp/react-native-slider": "^0.12.0",
|
||||
"@hiveio/dhive": "^1.0.1",
|
||||
"@react-native-community/async-storage": "^1.11.0",
|
||||
@ -111,6 +110,7 @@
|
||||
"react-native-randombytes": "^3.6.1",
|
||||
"react-native-reanimated": "^1",
|
||||
"react-native-receive-sharing-intent": "ecency/react-native-receive-sharing-intent",
|
||||
"react-native-render-html": "^6.0.5",
|
||||
"react-native-restart": "0.0.17",
|
||||
"react-native-safe-area-context": "^3.1.9",
|
||||
"react-native-screens": "^2.9.0",
|
||||
|
217
src/components/postElements/body/view/commentBodyStyles.ts
Normal file
217
src/components/postElements/body/view/commentBodyStyles.ts
Normal file
@ -0,0 +1,217 @@
|
||||
import { ImageStyle } from 'react-native';
|
||||
import { ViewStyle, TextStyle } from 'react-native';
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
baseStyle: {
|
||||
color: '$primaryBlack',
|
||||
fontFamily: '$primaryFont',
|
||||
maxWidth: '100%',
|
||||
fontSize: 16,
|
||||
} as TextStyle,
|
||||
body: {
|
||||
color: '$primaryBlack',
|
||||
} as TextStyle,
|
||||
a:{
|
||||
color: '$primaryBlue'
|
||||
} as TextStyle,
|
||||
img:{
|
||||
alignSelf:'center',
|
||||
} as ImageStyle,
|
||||
th:{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
fontWeight: 'bold',
|
||||
color: '$primaryBlack',
|
||||
fontSize: 14,
|
||||
padding: 10,
|
||||
} as TextStyle,
|
||||
tr:{
|
||||
backgroundColor:'$darkIconColor',
|
||||
flexDirection:'row',
|
||||
} as ViewStyle,
|
||||
td:{
|
||||
flex:1,
|
||||
borderWidth: 0.5,
|
||||
padding:10,
|
||||
borderColor: '$tableBorderColor',
|
||||
backgroundColor: '$tableTrColor'
|
||||
} as ViewStyle,
|
||||
blockquote: {
|
||||
borderLeftWidth: 5,
|
||||
borderStyle:'solid',
|
||||
marginLeft:5,
|
||||
paddingLeft:5,
|
||||
borderColor: '$darkIconColor',
|
||||
} as ViewStyle,
|
||||
code:{
|
||||
backgroundColor:'$darkIconColor',
|
||||
fontFamily:'$editorFont',
|
||||
} as TextStyle,
|
||||
textCenter: {
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
} as TextStyle,
|
||||
phishy:{
|
||||
color:'red',
|
||||
flexDirection:'row',
|
||||
flexWrap:'wrap'
|
||||
} as TextStyle,
|
||||
textJustify:{
|
||||
textAlign:'justify',
|
||||
letterSpacing:0
|
||||
} as TextStyle,
|
||||
revealButton: {
|
||||
backgroundColor: '$iconColor',
|
||||
height: 22,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 20,
|
||||
minWidth: 40,
|
||||
maxWidth: 170,
|
||||
},
|
||||
revealText: {
|
||||
color: '$white',
|
||||
fontSize: 14,
|
||||
},
|
||||
videoThumb:{
|
||||
width:'100%',
|
||||
alignItems:'center',
|
||||
justifyContent:'center',
|
||||
},
|
||||
playButton:{
|
||||
alignItems:'center',
|
||||
justifyContent:'center',
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderRadius: 30,
|
||||
backgroundColor:'$primaryBlack'
|
||||
} as ViewStyle
|
||||
});
|
||||
|
||||
|
||||
//legacy style
|
||||
// const customStyle = `
|
||||
// * {
|
||||
// color: ${EStyleSheet.value('$primaryBlack')};
|
||||
// font-family: Roboto, sans-serif;
|
||||
// max-width: 100%;
|
||||
|
||||
// overflow-wrap: break-word;
|
||||
// word-wrap: break-word;
|
||||
|
||||
// -ms-word-break: break-all;
|
||||
// word-break: break-all;
|
||||
// word-break: break-word;
|
||||
|
||||
// -ms-hyphens: auto;
|
||||
// -moz-hyphens: auto;
|
||||
// -webkit-hyphens: auto;
|
||||
// hyphens: auto;
|
||||
|
||||
// }
|
||||
// body {
|
||||
// color: ${EStyleSheet.value('$primaryBlack')};
|
||||
// }
|
||||
// a {
|
||||
// color: ${EStyleSheet.value('$primaryBlue')};
|
||||
// cursor: pointer;
|
||||
// }
|
||||
// img {
|
||||
// align-self: 'center';
|
||||
// max-width: 100%;
|
||||
// }
|
||||
// center {
|
||||
// text-align: 'center';
|
||||
// align-items: 'center';
|
||||
// justify-content: 'center';
|
||||
// }
|
||||
// table {
|
||||
// table-layout: fixed;
|
||||
// width: 100%;
|
||||
// }
|
||||
// th {
|
||||
// flex: 1;
|
||||
// justify-content: 'center';
|
||||
// font-weight: 'bold';
|
||||
// color: ${EStyleSheet.value('$primaryBlack')};
|
||||
// font-size: 14;
|
||||
// padding: 5;
|
||||
// }
|
||||
// tr {
|
||||
// background-color: ${EStyleSheet.value('$darkIconColor')};
|
||||
// flex-direction: 'row';
|
||||
// }
|
||||
// td {
|
||||
// border-width: 0.5;
|
||||
// border-color: ${EStyleSheet.value('$tableBorderColor')};
|
||||
// flex: 1;
|
||||
// padding: 10;
|
||||
// background-color: ${EStyleSheet.value('$tableTrColor')};
|
||||
// }
|
||||
// blockquote {
|
||||
// border-left-width: 5;
|
||||
// border-left-style: solid;
|
||||
// border-color: ${EStyleSheet.value('$darkIconColor')};
|
||||
// margin-left: 5;
|
||||
// padding-left: 5;
|
||||
// }
|
||||
// code {
|
||||
// background-color: ${EStyleSheet.value('$darkIconColor')};
|
||||
// font-family: ${EStyleSheet.value('$editorFont')};
|
||||
// }
|
||||
// center {
|
||||
// text-align: 'center';
|
||||
// align-items: 'center';
|
||||
// justify-content: 'center';
|
||||
// }
|
||||
// .markdown-video-link {
|
||||
// max-width: 100%;
|
||||
// position: relative;
|
||||
// }
|
||||
// .markdown-video-play {
|
||||
// position: absolute;
|
||||
// width: 100px;
|
||||
// height: 100px;
|
||||
// background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAACo1JREFUeAHlm02IHMcVx/trZrEDwsImvggCklYrxRAslhykQLyRFodI2g/ZFjnKsojBxJBbfPAaRJJD4ot1iQI+xArJKcpa3p1VZMPGWiUgQUC2T1ovIZCAwNiRUbDARjPT3fn/aro6vbPz1bOaj0UFPT3dXR/v/96rV69eVbnO/UvuxMSEv7KyUs1WeeTI8T2eF+13XedJ1/XGHCfeof9fj+P4McdxH6rljb9yXfd2HDuf6fst3dd0feQ4wQdLS/P/yNanNgK1EepdnH3f7X+324KZcu74+Hhw48aNin03NXX8KdeNjwvgpOjcVygUPAF0BNqJolj3yPznmcS32uU5nlf7z7dKpRLp66rqWI5j92KpdPGqbUNtFtQmzN4UIzbFgIQIA3xqakoS9U4Ly/O+H+z1PF9gQycMEZaT1QrazF58B0T24h0p8H3f4aKeMKx+rKJvxXH421KpdJsMWRp4zpu6YsCJEyf8CxcuSDpOfPTo0e2eV3xFEn+pWCxuqxEahpJoJCn6ymPB5qWN/IYpqitUXZ4YQXLK5fIXej4XRdXXL126dIc2RJMnmgy38zSUmwHj4y9K9d40Up+enn1Zjf1MwLdLXVFr3gPay0NEjrwwHeaqVxVgxB39f21h4eKvqSNLW6d15mFAauQwbIVCfL5QKB7IAA/UaJ76OqWxUT40o2oZce9e+bqU7SQGM6+R7EhSZ86cMfmw8NPTx08GQbyqfn5AEpDEZdEcp6CrX+BhCG2pzTiChkIhOOB54Sq02VHI0kzmVgl1bZmoSBcgHan8WaneL6MocnVh2PoNvJ5WGOEntASibXZ0dM8ja2sfvytGxNDOvb5Q9rml1OrAzxeLI8+Uy/cAjkZ0pD3Zxnr8HyFFskdBpVKeX1h45znay2Jo1H5TBmQLSvJ/VsU/kLqVVUmxUUVD9K4sWosi9fLi4jtHoCuLpZ7OZgyw72OBl+SLkvyWAG/xGSZkNCHFYzPYe0M1xqVVBsCfran9lgIPNjSgrFHqWWF4AywJJr6tSxuMIGPp9evzxtpj8MRFa+zWFdwCD76csqowHBwdHfvXe++9+yHYPvnkhjHoln6rGuY58fBCxnkNdTf1EgZRoKGmmELD/WNpD6PI34efYDFastcBS9xbBycnCALAW4tv83dyp1HKDUMCXxUs8qZ/B0EWoyUuZQCTCr2k37+Mh1etVnFr8e7ypFC+uhcEBcrhlw8DIwKwjIwUD8zMzPxYNMUJVoPLdgHuZmLj+4V/ysXcLr/eqo/J2OYn9jSPlUPCnP5Hnue8JE/xacqocTt3z8vMNk3m+hwJkydMd8KwsstOoFRDbDRAHDHEeV7wioY8wCP9VDs6aUplyObfvfvfJTkh3y+Xq5MC/z7TN6ngoDUC8BWwCeNPIdRiRvJG+sznXddH+tuUGTRWO8jfLsUq56rYHc3V99i5OoWmp6e/J17OiQ+HlGWQGpHQGGkqHe1KaHS9/4+P3mlxCPBIPw/4dcxRNzBzcvoZFndxcfGKPLLDUr1DA9YIBCQtGNkmQb8A0WBPgU5PzzDD26uxM0/ft+BTDajvYzCBTDZYMWCNiDDSktGquuk3ocswgBheEHgrAo/0NjhHZGyTmjLAlmvECNmlVxU6O9znrsFIJSep8pS086/G+BHArMXwFLKshbEs3fftbjUgw4grqvwKGgEjRFNfGCFmowV4ic+o/RoDpAiTdN1egc9ysRUjFPZ7VT5LTxkBxpqix5PQ5SZur0LPZtjLa/0ttrZdwGasv2c0whhPqxE97BoWo+y1vzdg0UKen6fYHl6b6RL1RPbyuZVG9KhrYPeYJAWKpu0PNDRrxSYdDHqJtWXdzRgxOzs7Ua06c/ezawgvGqvFGOdJMcAbU79oSVw/PzZgxIraX7mfjBBefAJgjUnl4x0sVykNXg2gIkk9ZoTmLTEasIMuoIVKfJ/hYkCXjKBYJ36MNCDS0p3zeCBOPOZ5w6cBlgH23kwjjh2bnZAQ52TTzPApYw6YdtpsuoDKPSoNcB9K+kO7QpaWgd6bMULD5375Eb/QrFyR4FgOnRnWm9FqbcDDuaa8zWobvvedyzKQ9L9SMONruneiOgPHWu84MTqoL8uDDCYZ2pIu0E6w1nH7Uo6Qe1sFh54BjYBr6janqe3hIEjjDAioEyNoGCD797k0wPlMGvANBX+NJRy4iOsIaAW8UEiBQ3seL1YMYDdK9Cl+wC1pwbfFzaFiQI+AW/Yqhulqx4lzCw1Yo+8MS+ox8BRmgnkNBnyUDIPpx0H8qQfOrJDpMX18E6reFAqYwa4uEHwgy4krSB+iG/RVHZoB72GAxNgLMCs08GHAclESD3xCgYK+MaARcKa/PYwDWG2IxVxXy4arYE8sp7ushp8goivVaDeG2oq6ug8QuKFXfd+sXknYy7wwDGATorD/pJfgBw3cSguMtZBY9Dbv0v7+IIXFtVq3WirVwuKBFgfYe6twmPuW+savxB1ic5vuBiw97dy5M7KTF6z6EKwQWfU/j/TBjgZwxQ/s0hjgWcZirUz94zcKFupV98vad7U6SgWapx/WUvtftNr8viYqh9AsLY0ReMVXT4wvOfuWCIQy9p8DK5jVcmxtgNEC9v0+kMvjcAKOsG6uYeK1RAtMnL5D+bA3gKzbFb29KCY+LWEPWuJZ0sOa9OM5MFrpk8FqgM2c2IPZa2w/TVQ2r7rCCetZ2noHeWeLDLtErmmV+jsixGC0BK2z9hqrzbNcxJNIUJkAb0RrC3Rwp468TOug2q6ysDME8NokVX2eGixGW9u64MHNmzfVFV4sXL36h/+Mje37t9RmNlnvX8coW3gL3FF97Q4JT8nwXQHb8vLvMcRpWscA3rKPjvGRfXVsPNamiYMy4GyR3ZA3rWU4/2i36EhB+xzPLi4uvA4m9j/Wk1pvA+x3+z6emZn9Ezsut+JWWZ0jmJfHx6bpFI8FaO/NVJut5qaQdlI8J/CXpQlskkYThj2ZfcICfzkB7yRYmOluSM0YQKFIl/nOrms2HidMQI3yGsYNDffgBTRVpfbFRPJtd4pDQ8t+zWEDmMBdhxD+uHv36CMyKgflMaIdMKIpA6m8j4njMz4GT9p6VpI/TdvQrqulsFoygEoyTHA4icHGY6YOjK0aISoKJ8IM28f0t6/JSF2kFGqxjPAUBk8UuJ2Ah9I8hKeHpo4de3aUvbdsP1VoyZ4WY+zPUx/td5voz+mhKUn9GuP80tJS7kNTuQlmLLXH5th7q97wc9mGAR2bu6eNmc5cqbRwDk5maeuUs227QH1F+AlEd+Q0qUus/X337l1vaoUFiXxLjHhYdxYeOduHJ2kZbO/11bV7pl7UnItYHv1cm5yqX8i5e0NS/+HSUulv+sbBSb/eydH7tqlbwkzFTCrsmeEknvCC6DzFhkvRmhx3NXOqrANCm9mLugCavXhHWnd0VqBXZXPOD/zobI229HfD4WlFf76rAUL78NiK5nZ8eFpLdMkh6tpB61q4PtYONndZSvA2GxttqwnzYSyM6zptSgPqWk2NZPZ9YjDN8Xm9H5MEtSXHeVz3R/VMlyF9qU70ufB/qvstPZvj88TtCV2bHMkPLq1GJtRqU8Btnf8DPtmgstMt+csAAAAASUVORK5CYII=') 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%);
|
||||
// }
|
||||
// b > * {
|
||||
// display: inline-block;
|
||||
// margin: 2 10;
|
||||
// }
|
||||
// iframe {
|
||||
// width: 100%;
|
||||
// height: 240px;
|
||||
// }
|
||||
// .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;
|
||||
// }
|
||||
// `;
|
@ -1,502 +0,0 @@
|
||||
import React, { Fragment, useState, useEffect, useRef } from 'react';
|
||||
import { Dimensions, Linking, Modal, PermissionsAndroid, Platform } from 'react-native';
|
||||
import { useIntl } from 'react-intl';
|
||||
import CameraRoll from '@react-native-community/cameraroll';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import AutoHeightWebView from 'react-native-autoheight-webview';
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
import get from 'lodash/get';
|
||||
import { navigate } from '../../../../navigation/service';
|
||||
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../../constants/routeNames';
|
||||
|
||||
import { CommentPlaceHolder } from '../../../basicUIElements';
|
||||
import { customCommentScript } from './config';
|
||||
|
||||
import { TextButton } from '../../..';
|
||||
|
||||
// Styles
|
||||
import styles from './postBodyStyles';
|
||||
|
||||
// Services and Actions
|
||||
import { writeToClipboard } from '../../../../utils/clipboard';
|
||||
import { toastNotification } from '../../../../redux/actions/uiAction';
|
||||
|
||||
const WIDTH = Dimensions.get('window').width;
|
||||
|
||||
const CommentBody = ({
|
||||
body,
|
||||
textSelectable = true,
|
||||
handleOnUserPress,
|
||||
handleOnPostPress,
|
||||
handleOnLongPress,
|
||||
created,
|
||||
commentDepth,
|
||||
reputation,
|
||||
dispatch,
|
||||
}) => {
|
||||
const [isImageModalOpen, setIsImageModalOpen] = useState(false);
|
||||
const [postImages, setPostImages] = useState([]);
|
||||
const [selectedImage, setSelectedImage] = useState(null);
|
||||
const [selectedLink, setSelectedLink] = useState(null);
|
||||
|
||||
const [revealComment, setRevealComment] = useState(reputation > 0);
|
||||
const intl = useIntl();
|
||||
const actionImage = useRef(null);
|
||||
const actionLink = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedLink) {
|
||||
actionLink.current.show();
|
||||
}
|
||||
}, [selectedLink]);
|
||||
|
||||
useEffect(() => {
|
||||
if (postImages.length > 0 && selectedImage) {
|
||||
actionImage.current.show();
|
||||
}
|
||||
}, [postImages, selectedImage]);
|
||||
|
||||
const _showLowComment = () => {
|
||||
setRevealComment(true);
|
||||
};
|
||||
//new renderer functions
|
||||
const __handleOnLinkPress = (event) => {
|
||||
if ((!event && !get(event, 'nativeEvent.data'), false)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let data = {};
|
||||
try {
|
||||
data = JSON.parse(get(event, 'nativeEvent.data'));
|
||||
} catch (error) {
|
||||
data = {};
|
||||
}
|
||||
|
||||
const {
|
||||
type,
|
||||
href,
|
||||
images,
|
||||
image,
|
||||
author,
|
||||
category,
|
||||
permlink,
|
||||
tag,
|
||||
proposal,
|
||||
videoHref,
|
||||
} = data;
|
||||
|
||||
switch (type) {
|
||||
case '_external':
|
||||
case 'markdown-external-link':
|
||||
setSelectedLink(href);
|
||||
break;
|
||||
case 'longpress':
|
||||
handleOnLongPress();
|
||||
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;
|
||||
case 'image':
|
||||
setPostImages(images);
|
||||
setSelectedImage(image);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const handleImagePress = (ind) => {
|
||||
if (ind === 1) {
|
||||
//open gallery mode
|
||||
setIsImageModalOpen(true);
|
||||
}
|
||||
if (ind === 0) {
|
||||
//copy to clipboard
|
||||
writeToClipboard(selectedImage).then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.copied',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
if (ind === 2) {
|
||||
//save to local
|
||||
_saveImage(selectedImage);
|
||||
}
|
||||
if (ind === 3) {
|
||||
setPostImages([]);
|
||||
setSelectedImage(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLinkPress = (ind) => {
|
||||
if (ind === 1) {
|
||||
//open link
|
||||
if (selectedLink) {
|
||||
Linking.canOpenURL(selectedLink).then((supported) => {
|
||||
if (supported) {
|
||||
Linking.openURL(selectedLink);
|
||||
} else {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.failed_to_open',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (ind === 0) {
|
||||
//copy to clipboard
|
||||
writeToClipboard(selectedLink).then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.copied',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
if (ind === 2) {
|
||||
setSelectedLink(null);
|
||||
}
|
||||
};
|
||||
|
||||
const __handleTagPress = (tag) => {
|
||||
if (tag) {
|
||||
navigate({
|
||||
routeName: ROUTES.SCREENS.TAG_RESULT,
|
||||
params: {
|
||||
tag,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const __handleOnPostPress = (permlink, author) => {
|
||||
if (permlink) {
|
||||
navigate({
|
||||
routeName: ROUTES.SCREENS.POST,
|
||||
params: {
|
||||
author,
|
||||
permlink,
|
||||
},
|
||||
key: `@${author}/${permlink}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const __handleOnUserPress = (username) => {
|
||||
if (username) {
|
||||
navigate({
|
||||
routeName: ROUTES.SCREENS.PROFILE,
|
||||
params: {
|
||||
username,
|
||||
},
|
||||
key: username,
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.wrong_link',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const checkAndroidPermission = async () => {
|
||||
try {
|
||||
const permission = PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;
|
||||
await PermissionsAndroid.request(permission);
|
||||
Promise.resolve();
|
||||
} catch (error) {
|
||||
Promise.reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
const _downloadImage = async (uri) => {
|
||||
return RNFetchBlob.config({
|
||||
fileCache: true,
|
||||
appendExt: 'jpg',
|
||||
})
|
||||
.fetch('GET', uri)
|
||||
.then((res) => {
|
||||
let status = res.info().status;
|
||||
|
||||
if (status == 200) {
|
||||
return res.path();
|
||||
} else {
|
||||
Promise.reject();
|
||||
}
|
||||
})
|
||||
.catch((errorMessage) => {
|
||||
Promise.reject(errorMessage);
|
||||
});
|
||||
};
|
||||
|
||||
const _saveImage = async (uri) => {
|
||||
try {
|
||||
if (Platform.OS === 'android') {
|
||||
await checkAndroidPermission();
|
||||
uri = `file://${await _downloadImage(uri)}`;
|
||||
}
|
||||
CameraRoll.saveToCameraRoll(uri)
|
||||
.then((res) => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.image_saved',
|
||||
}),
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.image_saved_error',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.image_saved_error',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const html = body.replace(/<a/g, '<a target="_blank"');
|
||||
const customStyle = `
|
||||
* {
|
||||
color: ${EStyleSheet.value('$primaryBlack')};
|
||||
font-family: Roboto, sans-serif;
|
||||
max-width: 100%;
|
||||
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
|
||||
-ms-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
|
||||
}
|
||||
body {
|
||||
color: ${EStyleSheet.value('$primaryBlack')};
|
||||
}
|
||||
a {
|
||||
color: ${EStyleSheet.value('$primaryBlue')};
|
||||
cursor: pointer;
|
||||
}
|
||||
img {
|
||||
align-self: 'center';
|
||||
max-width: 100%;
|
||||
}
|
||||
center {
|
||||
text-align: 'center';
|
||||
align-items: 'center';
|
||||
justify-content: 'center';
|
||||
}
|
||||
table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
th {
|
||||
flex: 1;
|
||||
justify-content: 'center';
|
||||
font-weight: 'bold';
|
||||
color: ${EStyleSheet.value('$primaryBlack')};
|
||||
font-size: 14;
|
||||
padding: 5;
|
||||
}
|
||||
tr {
|
||||
background-color: ${EStyleSheet.value('$darkIconColor')};
|
||||
flex-direction: 'row';
|
||||
}
|
||||
td {
|
||||
border-width: 0.5;
|
||||
border-color: ${EStyleSheet.value('$tableBorderColor')};
|
||||
flex: 1;
|
||||
padding: 10;
|
||||
background-color: ${EStyleSheet.value('$tableTrColor')};
|
||||
}
|
||||
blockquote {
|
||||
border-left-width: 5;
|
||||
border-left-style: solid;
|
||||
border-color: ${EStyleSheet.value('$darkIconColor')};
|
||||
margin-left: 5;
|
||||
padding-left: 5;
|
||||
}
|
||||
code {
|
||||
background-color: ${EStyleSheet.value('$darkIconColor')};
|
||||
font-family: ${EStyleSheet.value('$editorFont')};
|
||||
}
|
||||
center {
|
||||
text-align: 'center';
|
||||
align-items: 'center';
|
||||
justify-content: 'center';
|
||||
}
|
||||
.markdown-video-link {
|
||||
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%);
|
||||
}
|
||||
b > * {
|
||||
display: inline-block;
|
||||
margin: 2 10;
|
||||
}
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
}
|
||||
.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>
|
||||
<Modal key={`mkey-${created.toString()}`} visible={isImageModalOpen} transparent={true}>
|
||||
<ImageViewer
|
||||
imageUrls={postImages}
|
||||
enableSwipeDown
|
||||
onCancel={() => setIsImageModalOpen(false)}
|
||||
onClick={() => setIsImageModalOpen(false)}
|
||||
/>
|
||||
</Modal>
|
||||
<ActionSheet
|
||||
ref={actionImage}
|
||||
options={[
|
||||
intl.formatMessage({ id: 'post.copy_link' }),
|
||||
intl.formatMessage({ id: 'post.gallery_mode' }),
|
||||
intl.formatMessage({ id: 'post.save_to_local' }),
|
||||
intl.formatMessage({ id: 'alert.cancel' }),
|
||||
]}
|
||||
title={intl.formatMessage({ id: 'post.image' })}
|
||||
cancelButtonIndex={3}
|
||||
onPress={(index) => {
|
||||
handleImagePress(index);
|
||||
}}
|
||||
/>
|
||||
<ActionSheet
|
||||
ref={actionLink}
|
||||
options={[
|
||||
intl.formatMessage({ id: 'post.copy_link' }),
|
||||
intl.formatMessage({ id: 'alert.external_link' }),
|
||||
intl.formatMessage({ id: 'alert.cancel' }),
|
||||
]}
|
||||
title={intl.formatMessage({ id: 'post.link' })}
|
||||
cancelButtonIndex={2}
|
||||
onPress={(index) => {
|
||||
handleLinkPress(index);
|
||||
}}
|
||||
/>
|
||||
{revealComment ? (
|
||||
<AutoHeightWebView
|
||||
key={`akey-${created.toString()}`}
|
||||
source={{ html }}
|
||||
allowsFullscreenVideo={true}
|
||||
style={{ width: WIDTH - (32 + 34 * (commentDepth % 6)) }}
|
||||
customStyle={customStyle}
|
||||
onMessage={__handleOnLinkPress}
|
||||
customScript={customCommentScript}
|
||||
renderLoading={() => <CommentPlaceHolder />}
|
||||
startInLoadingState={true}
|
||||
onShouldStartLoadWithRequest={false}
|
||||
scrollEnabled={false}
|
||||
scalesPageToFit={false}
|
||||
zoomable={false}
|
||||
/>
|
||||
) : (
|
||||
<TextButton
|
||||
style={styles.revealButton}
|
||||
textStyle={styles.revealText}
|
||||
onPress={() => _showLowComment()}
|
||||
text={intl.formatMessage({ id: 'comments.reveal_comment' })}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const areEqual = (prevProps, nextProps) => prevProps.body !== nextProps.body;
|
||||
|
||||
const mapStateToProps = (state) => ({});
|
||||
|
||||
export default connect(mapStateToProps)(React.memo(CommentBody, areEqual));
|
372
src/components/postElements/body/view/commentBodyView.tsx
Normal file
372
src/components/postElements/body/view/commentBodyView.tsx
Normal file
@ -0,0 +1,372 @@
|
||||
import React, { Fragment, useState, useEffect, useRef } from 'react';
|
||||
import { Alert, Dimensions, Linking, Modal, PermissionsAndroid, Platform, View } from 'react-native';
|
||||
import { useIntl } from 'react-intl';
|
||||
import CameraRoll from '@react-native-community/cameraroll';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
import ActionsSheetView from 'react-native-actions-sheet';
|
||||
|
||||
// import AutoHeightWebView from 'react-native-autoheight-webview';
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
import { navigate } from '../../../../navigation/service';
|
||||
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../../constants/routeNames';
|
||||
|
||||
import { TextButton } from '../../..';
|
||||
|
||||
// Styles
|
||||
import styles from './commentBodyStyles';
|
||||
|
||||
// Services and Actions
|
||||
import { writeToClipboard } from '../../../../utils/clipboard';
|
||||
import { toastNotification } from '../../../../redux/actions/uiAction';
|
||||
import getYoutubeId from '../../../../utils/getYoutubeId';
|
||||
import VideoPlayerSheet from './videoPlayerSheet';
|
||||
import { LongPressGestureHandler, State } from 'react-native-gesture-handler';
|
||||
import { useCallback } from 'react';
|
||||
import HtmlRenderer from './htmlRenderer';
|
||||
|
||||
const WIDTH = Dimensions.get('window').width;
|
||||
|
||||
const CommentBody = ({
|
||||
body,
|
||||
textSelectable = true,
|
||||
handleOnUserPress,
|
||||
handleOnPostPress,
|
||||
handleOnLongPress,
|
||||
created,
|
||||
commentDepth,
|
||||
reputation,
|
||||
dispatch,
|
||||
}) => {
|
||||
|
||||
const _contentWidth = WIDTH - (32 + 34 * (commentDepth % 6))
|
||||
|
||||
const [isImageModalOpen, setIsImageModalOpen] = useState(false);
|
||||
const [postImages, setPostImages] = useState<string[]>([]);
|
||||
const [selectedImage, setSelectedImage] = useState(null);
|
||||
const [selectedLink, setSelectedLink] = useState(null);
|
||||
const [revealComment, setRevealComment] = useState(reputation > 0);
|
||||
const [videoUrl, setVideoUrl] = useState(null);
|
||||
const [youtubeVideoId, setYoutubeVideoId] = useState(null)
|
||||
|
||||
const intl = useIntl();
|
||||
const actionImage = useRef(null);
|
||||
const actionLink = useRef(null);
|
||||
const youtubePlayerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedLink) {
|
||||
actionLink.current.show();
|
||||
}
|
||||
}, [selectedLink]);
|
||||
|
||||
useEffect(() => {
|
||||
if (postImages.length > 0 && selectedImage !== null) {
|
||||
actionImage.current.show();
|
||||
}
|
||||
}, [selectedImage]);
|
||||
|
||||
|
||||
const _onLongPressStateChange = ({nativeEvent}) => {
|
||||
if(nativeEvent.state === State.ACTIVE){
|
||||
handleOnLongPress();
|
||||
}
|
||||
}
|
||||
|
||||
const _showLowComment = () => {
|
||||
setRevealComment(true);
|
||||
};
|
||||
|
||||
|
||||
const handleImagePress = (ind) => {
|
||||
if (ind === 1) {
|
||||
//open gallery mode
|
||||
setIsImageModalOpen(true);
|
||||
}
|
||||
if (ind === 0) {
|
||||
//copy to clipboard
|
||||
writeToClipboard(selectedImage).then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.copied',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
if (ind === 2) {
|
||||
//save to local
|
||||
_saveImage(selectedImage);
|
||||
}
|
||||
if (ind === 3) {
|
||||
setSelectedImage(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLinkPress = (ind) => {
|
||||
if (ind === 1) {
|
||||
//open link
|
||||
if (selectedLink) {
|
||||
Linking.canOpenURL(selectedLink).then((supported) => {
|
||||
if (supported) {
|
||||
Linking.openURL(selectedLink);
|
||||
} else {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.failed_to_open',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (ind === 0) {
|
||||
//copy to clipboard
|
||||
writeToClipboard(selectedLink).then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.copied',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
if (ind === 2) {
|
||||
setSelectedLink(null);
|
||||
}
|
||||
};
|
||||
|
||||
const _handleTagPress = (tag) => {
|
||||
if (tag) {
|
||||
navigate({
|
||||
routeName: ROUTES.SCREENS.TAG_RESULT,
|
||||
params: {
|
||||
tag,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const _handleOnPostPress = (permlink, author) => {
|
||||
if(handleOnPostPress){
|
||||
handleOnUserPress(permlink, author);
|
||||
return;
|
||||
}
|
||||
if (permlink) {
|
||||
navigate({
|
||||
routeName: ROUTES.SCREENS.POST,
|
||||
params: {
|
||||
author,
|
||||
permlink,
|
||||
},
|
||||
key: `@${author}/${permlink}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const _handleOnUserPress = (username) => {
|
||||
if(handleOnUserPress){
|
||||
handleOnUserPress(username);
|
||||
return;
|
||||
}
|
||||
if (username) {
|
||||
navigate({
|
||||
routeName: ROUTES.SCREENS.PROFILE,
|
||||
params: {
|
||||
username,
|
||||
},
|
||||
key: username,
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.wrong_link',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const checkAndroidPermission = async () => {
|
||||
try {
|
||||
const permission = PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;
|
||||
await PermissionsAndroid.request(permission);
|
||||
Promise.resolve();
|
||||
} catch (error) {
|
||||
Promise.reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
const _downloadImage = async (uri) => {
|
||||
return RNFetchBlob.config({
|
||||
fileCache: true,
|
||||
appendExt: 'jpg',
|
||||
})
|
||||
.fetch('GET', uri)
|
||||
.then((res) => {
|
||||
let status = res.info().status;
|
||||
|
||||
if (status == 200) {
|
||||
return res.path();
|
||||
} else {
|
||||
Promise.reject();
|
||||
}
|
||||
})
|
||||
.catch((errorMessage) => {
|
||||
Promise.reject(errorMessage);
|
||||
});
|
||||
};
|
||||
|
||||
const _saveImage = async (uri) => {
|
||||
try {
|
||||
if (Platform.OS === 'android') {
|
||||
await checkAndroidPermission();
|
||||
uri = `file://${await _downloadImage(uri)}`;
|
||||
}
|
||||
CameraRoll.saveToCameraRoll(uri)
|
||||
.then((res) => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.image_saved',
|
||||
}),
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.image_saved_error',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'post.image_saved_error',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const _handleYoutubePress = (embedUrl) => {
|
||||
const videoId = getYoutubeId(embedUrl);
|
||||
if (videoId && youtubePlayerRef.current) {
|
||||
setYoutubeVideoId(videoId);
|
||||
youtubePlayerRef.current.setModalVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
const _handleVideoPress = (embedUrl) => {
|
||||
if (embedUrl && youtubePlayerRef.current) {
|
||||
setVideoUrl(embedUrl);
|
||||
youtubePlayerRef.current.setModalVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const _onElementIsImage = useCallback((imgUrl) =>{
|
||||
if(postImages.indexOf(imgUrl) == -1){
|
||||
postImages.push(imgUrl);
|
||||
setPostImages(postImages);
|
||||
}
|
||||
},[postImages])
|
||||
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Modal key={`mkey-${created.toString()}`} visible={isImageModalOpen} transparent={true}>
|
||||
<ImageViewer
|
||||
imageUrls={postImages.map((url)=>({url}))}
|
||||
enableSwipeDown
|
||||
onCancel={() => setIsImageModalOpen(false)}
|
||||
onClick={() => setIsImageModalOpen(false)}
|
||||
/>
|
||||
</Modal>
|
||||
<ActionSheet
|
||||
ref={actionImage}
|
||||
options={[
|
||||
intl.formatMessage({ id: 'post.copy_link' }),
|
||||
intl.formatMessage({ id: 'post.gallery_mode' }),
|
||||
intl.formatMessage({ id: 'post.save_to_local' }),
|
||||
intl.formatMessage({ id: 'alert.cancel' }),
|
||||
]}
|
||||
title={intl.formatMessage({ id: 'post.image' })}
|
||||
cancelButtonIndex={3}
|
||||
onPress={(index) => {
|
||||
handleImagePress(index);
|
||||
}}
|
||||
/>
|
||||
<ActionSheet
|
||||
ref={actionLink}
|
||||
options={[
|
||||
intl.formatMessage({ id: 'post.copy_link' }),
|
||||
intl.formatMessage({ id: 'alert.external_link' }),
|
||||
intl.formatMessage({ id: 'alert.cancel' }),
|
||||
]}
|
||||
title={intl.formatMessage({ id: 'post.link' })}
|
||||
cancelButtonIndex={2}
|
||||
onPress={(index) => {
|
||||
handleLinkPress(index);
|
||||
}}
|
||||
/>
|
||||
{revealComment ? (
|
||||
<LongPressGestureHandler onHandlersStateChange={_onLongPressStateChange}>
|
||||
<View>
|
||||
<HtmlRenderer
|
||||
contentWidth={_contentWidth}
|
||||
body={body}
|
||||
onElementIsImage={_onElementIsImage}
|
||||
setSelectedImage={setSelectedImage}
|
||||
setSelectedLink={setSelectedLink}
|
||||
handleOnPostPress={_handleOnPostPress}
|
||||
handleOnUserPress={_handleOnUserPress}
|
||||
handleTagPress={_handleTagPress}
|
||||
handleVideoPress={_handleVideoPress}
|
||||
handleYoutubePress={_handleYoutubePress}
|
||||
/>
|
||||
</View>
|
||||
</LongPressGestureHandler>
|
||||
|
||||
) : (
|
||||
<TextButton
|
||||
style={styles.revealButton}
|
||||
textStyle={styles.revealText}
|
||||
onPress={() => _showLowComment()}
|
||||
text={intl.formatMessage({ id: 'comments.reveal_comment' })}
|
||||
/>
|
||||
)}
|
||||
<ActionsSheetView
|
||||
ref={youtubePlayerRef}
|
||||
gestureEnabled={true}
|
||||
hideUnderlay
|
||||
containerStyle={{ backgroundColor: 'black' }}
|
||||
indicatorColor={EStyleSheet.value('$primaryWhiteLightBackground')}
|
||||
onClose={() => {
|
||||
setYoutubeVideoId(null);
|
||||
setVideoUrl(null);
|
||||
}}
|
||||
>
|
||||
<VideoPlayerSheet youtubeVideoId={youtubeVideoId} videoUrl={videoUrl} />
|
||||
</ActionsSheetView>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommentBody;
|
||||
|
209
src/components/postElements/body/view/htmlRenderer.tsx
Normal file
209
src/components/postElements/body/view/htmlRenderer.tsx
Normal file
@ -0,0 +1,209 @@
|
||||
import React from "react";
|
||||
import { View, ImageBackground } from "react-native";
|
||||
import EStyleSheet from "react-native-extended-stylesheet";
|
||||
import RenderHTML, { CustomRendererProps, Element, TNode } from "react-native-render-html";
|
||||
import { IconButton } from "../../..";
|
||||
import styles from "./commentBodyStyles";
|
||||
import { LinkData, parseLinkData } from "./linkDataParser";
|
||||
|
||||
|
||||
interface HtmlRendererProps {
|
||||
contentWidth:number;
|
||||
body:string;
|
||||
setSelectedImage:(imgUrl:string)=>void;
|
||||
setSelectedLink:(url:string)=>void;
|
||||
onElementIsImage:(imgUrl:string)=>void;
|
||||
handleOnPostPress:(permlink:string, authro:string)=>void;
|
||||
handleOnUserPress:(username:string)=>void;
|
||||
handleTagPress:(tag:string)=>void;
|
||||
handleVideoPress:(videoUrl:string)=>void;
|
||||
handleYoutubePress:(videoId:string)=>void;
|
||||
}
|
||||
|
||||
const HtmlRenderer = ({
|
||||
contentWidth,
|
||||
body,
|
||||
setSelectedImage,
|
||||
setSelectedLink,
|
||||
onElementIsImage,
|
||||
handleOnPostPress,
|
||||
handleOnUserPress,
|
||||
handleTagPress,
|
||||
handleVideoPress,
|
||||
handleYoutubePress,
|
||||
}:HtmlRendererProps) => {
|
||||
|
||||
//new renderer functions
|
||||
body = body.replace('<center>', '<div class="text-center">').replace('</center>','</div>');
|
||||
|
||||
const _handleOnLinkPress = (data:LinkData) => {
|
||||
|
||||
if(!data){
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
type,
|
||||
href,
|
||||
author,
|
||||
permlink,
|
||||
tag,
|
||||
videoHref,
|
||||
} = data;
|
||||
|
||||
try {
|
||||
|
||||
switch (type) {
|
||||
case '_external':
|
||||
case 'markdown-external-link':
|
||||
setSelectedLink(href);
|
||||
break;
|
||||
case 'markdown-author-link':
|
||||
if (handleOnUserPress) {
|
||||
handleOnUserPress(author);
|
||||
}
|
||||
break;
|
||||
case 'markdown-post-link':
|
||||
if (handleOnPostPress) {
|
||||
handleOnPostPress(permlink, author);
|
||||
}
|
||||
break;
|
||||
case 'markdown-tag-link':
|
||||
if(handleTagPress){
|
||||
handleTagPress(tag);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'markdown-video-link':
|
||||
if(handleVideoPress){
|
||||
handleVideoPress(videoHref)
|
||||
}
|
||||
break;
|
||||
case 'markdown-video-link-youtube':
|
||||
if(handleYoutubePress){
|
||||
handleYoutubePress(tag)
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//unused cases
|
||||
// case 'markdown-witnesses-link':
|
||||
// break;
|
||||
// case 'markdown-proposal-link':
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
|
||||
const _onElement = (element:Element) => {
|
||||
if(element.tagName === 'img' && element.attribs.src){
|
||||
const imgUrl = element.attribs.src;
|
||||
console.log("img element detected", imgUrl);
|
||||
onElementIsImage(imgUrl)
|
||||
}
|
||||
};
|
||||
|
||||
const _anchorRenderer = ({
|
||||
InternalRenderer,
|
||||
tnode,
|
||||
...props
|
||||
}:CustomRendererProps<TNode>) => {
|
||||
|
||||
const _onPress = () => {
|
||||
console.log("Link Pressed:", tnode)
|
||||
const data = parseLinkData(tnode);
|
||||
_handleOnLinkPress(data);
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<InternalRenderer
|
||||
tnode={tnode}
|
||||
onPress={_onPress}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const _imageRenderer = ({
|
||||
InternalRenderer,
|
||||
tnode,
|
||||
...props
|
||||
}:CustomRendererProps<TNode>) => {
|
||||
|
||||
const _onPress = () => {
|
||||
const imgUrl = tnode.attributes.src;
|
||||
console.log("Image Pressed:", imgUrl)
|
||||
setSelectedImage(imgUrl);
|
||||
};
|
||||
|
||||
const isVideoThumb = tnode.classes?.indexOf('video-thumbnail') >= 0;
|
||||
const isAnchored = !(tnode.parent?.classes?.indexOf('markdown-external-link') >= 0)
|
||||
|
||||
if(isVideoThumb){
|
||||
return (
|
||||
<View pointerEvents={'none'}>
|
||||
<ImageBackground
|
||||
source={{uri:tnode.attributes.src}}
|
||||
style={{...styles.videoThumb, height:contentWidth * 9/16 }}
|
||||
resizeMode={'cover'}>
|
||||
<IconButton
|
||||
style={styles.playButton}
|
||||
size={44}
|
||||
name='play-arrow'
|
||||
color={EStyleSheet.value('$white')}
|
||||
iconType='MaterialIcons'
|
||||
/>
|
||||
</ImageBackground>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<InternalRenderer
|
||||
tnode={tnode}
|
||||
onPress={isAnchored && _onPress}
|
||||
{...props}/>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<RenderHTML
|
||||
contentWidth={contentWidth}
|
||||
source={{ html:body }}
|
||||
baseStyle={styles.baseStyle}
|
||||
classesStyles={{
|
||||
phishy:styles.phishy,
|
||||
'text-justify':styles.textJustify,
|
||||
'text-center':styles.textCenter
|
||||
}}
|
||||
tagsStyles={{
|
||||
body:styles.body,
|
||||
a:styles.a,
|
||||
img:styles.img,
|
||||
th:styles.th,
|
||||
tr:styles.tr,
|
||||
td:styles.td,
|
||||
blockquote:styles.blockquote,
|
||||
code:styles.code,
|
||||
}}
|
||||
domVisitors={{
|
||||
onElement:_onElement
|
||||
}}
|
||||
renderers={{
|
||||
img:_imageRenderer,
|
||||
a:_anchorRenderer,
|
||||
}}
|
||||
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default React.memo(HtmlRenderer, (next, prev)=>next.body === prev.body)
|
103
src/components/postElements/body/view/linkDataParser.ts
Normal file
103
src/components/postElements/body/view/linkDataParser.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { TNode } from "react-native-render-html";
|
||||
|
||||
export interface LinkData {
|
||||
type:string,
|
||||
href?:string,
|
||||
author?:string,
|
||||
permlink?:string,
|
||||
tag?:string,
|
||||
proposal?:string,
|
||||
videoHref?:string,
|
||||
}
|
||||
|
||||
export const parseLinkData = (tnode:TNode):LinkData => {
|
||||
if(!tnode){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(tnode.classes.includes('markdown-external-link')){
|
||||
return {
|
||||
type:'markdown-external-link',
|
||||
href: tnode.attributes['data-href']
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tnode.classes.includes('markdown-author-link')) {
|
||||
var author = tnode.attributes['data-author'];
|
||||
return {
|
||||
type: 'markdown-author-link',
|
||||
author: author
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (tnode.classes.includes('markdown-post-link')) {
|
||||
var author = tnode.attributes['data-author'];
|
||||
var permlink = tnode.attributes['data-permlink'];
|
||||
|
||||
//snippets checks if there is anchored post inside permlink and use that instead
|
||||
const anchoredPostRegex = /(.*?\#\@)(.*)\/(.*)/;
|
||||
const matchedLink = permlink.match(anchoredPostRegex);
|
||||
if(matchedLink){
|
||||
author = matchedLink[2];
|
||||
permlink = matchedLink[3];
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'markdown-post-link',
|
||||
author: author,
|
||||
permlink: permlink
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (tnode.classes.includes('markdown-tag-link')) {
|
||||
var tag = tnode.attributes['data-tag'];
|
||||
return {
|
||||
type: 'markdown-tag-link',
|
||||
tag: tag
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (tnode.classes.includes('markdown-witnesses-link')) {
|
||||
return {
|
||||
type: 'markdown-witnesses-link'
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (tnode.classes.includes('markdown-proposal-link')) {
|
||||
var proposal = tnode.attributes['data-proposal'];
|
||||
return {
|
||||
type: 'markdown-proposal-link',
|
||||
proposal: proposal
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
if (tnode.classes.includes('markdown-video-link-youtube')) {
|
||||
var embedUrl = tnode.attributes['data-embed-src'];
|
||||
|
||||
if (embedUrl) {
|
||||
return {
|
||||
type: 'markdown-video-link-youtube',
|
||||
tag: embedUrl
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tnode.classes.includes('markdown-video-link')) {
|
||||
var videoHref = tnode.attributes['data-embed-src'] || tnode.attributes['data-video-href'];
|
||||
if (videoHref) {
|
||||
return {
|
||||
type: 'markdown-video-link',
|
||||
videoHref: videoHref
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import { toastNotification } from '../../../../redux/actions/uiAction';
|
||||
import { default as ROUTES } from '../../../../constants/routeNames';
|
||||
import getYoutubeId from '../../../../utils/getYoutubeId';
|
||||
import isAndroidOreo from '../../../../utils/isAndroidOreo';
|
||||
import YoutubePlayer from './youtubePlayer';
|
||||
import VideoPlayerSheet from './videoPlayerSheet';
|
||||
|
||||
const WIDTH = Dimensions.get('window').width;
|
||||
|
||||
@ -51,7 +51,6 @@ const PostBody = ({
|
||||
const actionImage = useRef(null);
|
||||
const actionLink = useRef(null);
|
||||
const youtubePlayerRef = useRef(null);
|
||||
// const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedLink) {
|
||||
@ -430,10 +429,12 @@ const PostBody = ({
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.phishy {
|
||||
display: inline;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.text-justify {
|
||||
text-align: justify;
|
||||
}
|
||||
@ -471,7 +472,7 @@ const PostBody = ({
|
||||
setYoutubeVideoId(null);
|
||||
}}
|
||||
>
|
||||
<YoutubePlayer videoId={youtubeVideoId} />
|
||||
<VideoPlayerSheet youtubeVideoId={youtubeVideoId} />
|
||||
</ActionSheetView>
|
||||
|
||||
<ActionSheet
|
||||
|
78
src/components/postElements/body/view/videoPlayerSheet.tsx
Normal file
78
src/components/postElements/body/view/videoPlayerSheet.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React, {useState} from 'react';
|
||||
import { Dimensions } from 'react-native';
|
||||
import { View, StyleSheet, ActivityIndicator } from 'react-native';
|
||||
import AutoHeightWebView from 'react-native-autoheight-webview';
|
||||
import WebView from 'react-native-webview';
|
||||
import YoutubeIframe from 'react-native-youtube-iframe';
|
||||
|
||||
interface VideoPlayerSheetProps {
|
||||
youtubeVideoId?:string;
|
||||
videoUrl?:string;
|
||||
}
|
||||
|
||||
const VideoPlayerSheet = ({youtubeVideoId, videoUrl}: VideoPlayerSheetProps) => {
|
||||
|
||||
const PLAYER_HEIGHT = Dimensions.get('screen').width * (9/16);
|
||||
|
||||
const [shouldPlay, setShouldPlay] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const _onReady = () => {
|
||||
setLoading(false)
|
||||
setShouldPlay(true);
|
||||
}
|
||||
|
||||
const _onChangeState = (event:string) => {
|
||||
setShouldPlay(!(event == 'paused' || event == 'ended'));
|
||||
}
|
||||
|
||||
const _onError = () => {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
|
||||
{youtubeVideoId &&
|
||||
<YoutubeIframe
|
||||
height={PLAYER_HEIGHT}
|
||||
videoId={youtubeVideoId}
|
||||
onReady={_onReady}
|
||||
play={shouldPlay}
|
||||
onChangeState={_onChangeState}
|
||||
onError={_onError}
|
||||
/>
|
||||
|
||||
}{
|
||||
videoUrl &&
|
||||
<View style={{height:PLAYER_HEIGHT}}>
|
||||
<WebView
|
||||
scalesPageToFit={true}
|
||||
bounces={false}
|
||||
javaScriptEnabled={true}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
onLoadEnd={()=>{
|
||||
setLoading(false);
|
||||
}}
|
||||
onLoadStart={()=>{
|
||||
setLoading(true);
|
||||
}}
|
||||
source={{uri:videoUrl}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
}
|
||||
{loading && <ActivityIndicator style={styles.activityIndicator}/>}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoPlayerSheet;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingVertical:16,
|
||||
},
|
||||
activityIndicator: {
|
||||
position:'absolute', alignItems:'center', justifyContent:'center', top:0, bottom:0, left:0, right:0}
|
||||
});
|
@ -1,53 +0,0 @@
|
||||
import React, {useState} from 'react';
|
||||
import { View, StyleSheet, ActivityIndicator } from 'react-native';
|
||||
import YoutubeIframe from 'react-native-youtube-iframe';
|
||||
|
||||
interface YoutubePlayerProps {
|
||||
videoId:string
|
||||
}
|
||||
|
||||
const YoutubePlayer = ({videoId}: YoutubePlayerProps) => {
|
||||
|
||||
const [shouldPlay, setShouldPlay] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const _onReady = () => {
|
||||
setLoading(false)
|
||||
setShouldPlay(true);
|
||||
}
|
||||
|
||||
const _onChangeState = (event:string) => {
|
||||
setShouldPlay(!(event == 'paused' || event == 'ended'));
|
||||
}
|
||||
|
||||
const _onError = () => {
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
|
||||
{videoId &&
|
||||
<YoutubeIframe
|
||||
height={250}
|
||||
videoId={videoId}
|
||||
onReady={_onReady}
|
||||
play={shouldPlay}
|
||||
onChangeState={_onChangeState}
|
||||
onError={_onError}
|
||||
/>
|
||||
}
|
||||
{loading && <ActivityIndicator style={styles.activityIndicator}/>}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default YoutubePlayer;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingVertical:16,
|
||||
},
|
||||
activityIndicator: {
|
||||
position:'absolute', alignItems:'center', justifyContent:'center', top:0, bottom:0, left:0, right:0}
|
||||
});
|
223
yarn.lock
223
yarn.lock
@ -1086,19 +1086,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@esteemapp/react-native-multi-slider/-/react-native-multi-slider-1.1.0.tgz#16ac1df8518147daa4977cec2503caba1fbd96b5"
|
||||
integrity sha512-NSqnLuyrkO23oTpA2WiL9LrxR84eKYKxBp8OogsjLSmThfyaHJvG87J3GLoy+l/9xXA+BeHS4DF360brZ/lrUA==
|
||||
|
||||
"@esteemapp/react-native-render-html@^4.1.5":
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@esteemapp/react-native-render-html/-/react-native-render-html-4.1.5.tgz#91b52ac67d6890cb07fcebc25352e7b228340e41"
|
||||
integrity sha512-C3C/VswCX+59hyenMjfKmbsz5GzX7VLrFUN6Az3W9NXd/iN8I+1P8S18EAmAHbX4hXCRLbDqqOMxxM7CayHcqQ==
|
||||
dependencies:
|
||||
buffer "^4.5.1"
|
||||
events "^1.1.0"
|
||||
html-entities "^1.2.0"
|
||||
htmlparser2 "^3.10.1"
|
||||
react-native-autoheight-webview "^1.3.4"
|
||||
react-native-lightbox "git+https://github.com/oblador/react-native-lightbox.git"
|
||||
stream "0.0.2"
|
||||
|
||||
"@esteemapp/react-native-slider@^0.12.0":
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@esteemapp/react-native-slider/-/react-native-slider-0.12.0.tgz#015d429e22545a176c1c07e7f01ae232302fbab4"
|
||||
@ -1415,6 +1402,37 @@
|
||||
"@types/yargs" "^15.0.0"
|
||||
chalk "^3.0.0"
|
||||
|
||||
"@jsamr/counter-style@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@jsamr/counter-style/-/counter-style-2.0.1.tgz#c555adc97ceeee57a929ae90ef5d99bc4783f404"
|
||||
integrity sha512-ox/fGXtTRWk+si55lcfuM2oIaIxK/vPbugaeR9O++9tI/5Vx31SVkUbtvXIIN27U+thRlR0hz5b/+Geq7zg5NA==
|
||||
|
||||
"@jsamr/react-native-li@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@jsamr/react-native-li/-/react-native-li-2.2.1.tgz#77a737e82899916a25c59fec441595286c7016e5"
|
||||
integrity sha512-24lfABRzLai11PQSWMdOtwfHAr/2pnWM2adO7npE6aNFJ31u3NCp0+zlYKuo4wdOy32QI5t57KvRDKJjlWvefQ==
|
||||
|
||||
"@native-html/css-processor@1.10.2":
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@native-html/css-processor/-/css-processor-1.10.2.tgz#b3a214742dc6fa6ada9aab03f841d09b9acd7b05"
|
||||
integrity sha512-cpcWZ8OcK70UE4TwrIxbaJeSX6hboO7LhAqbalWXp8pkUfEocR72AY+gi1BqQUzAH3sIU0ZUjPmec6brAg2WRQ==
|
||||
dependencies:
|
||||
css-to-react-native "^3.0.0"
|
||||
csstype "^3.0.8"
|
||||
|
||||
"@native-html/transient-render-engine@^9.2.2":
|
||||
version "9.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@native-html/transient-render-engine/-/transient-render-engine-9.2.2.tgz#00691518926ea47709185c3a25a786472c99a1f0"
|
||||
integrity sha512-DhJqrOYhyNmTL9ze/bGG4mbHzoJoMCPnkH/TsQT1p+ZHI5LXL8PBisKF0tiSz3B88GbgTKOO8tp1YMj0fjUNKQ==
|
||||
dependencies:
|
||||
"@native-html/css-processor" "1.10.2"
|
||||
"@types/ramda" "^0.27.40"
|
||||
csstype "^3.0.8"
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
htmlparser2 "^6.1.0"
|
||||
ramda "^0.27.1"
|
||||
|
||||
"@react-native-community/async-storage@1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.5.0.tgz#647ffcd832272068b0be57332e08d73036ed391f"
|
||||
@ -1774,6 +1792,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
|
||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||
|
||||
"@types/ramda@^0.27.40":
|
||||
version "0.27.44"
|
||||
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.27.44.tgz#ba2283d67fcff366f7e68bd5124a0466e467967f"
|
||||
integrity sha512-SlEHKcLG36PlU+rLJwp8p4dpC9Hp/LiH6n0REX2m4iEB15PWe1qKQzgNSZrYKhTHDFvkeEM/F2gcYwfighsEuQ==
|
||||
dependencies:
|
||||
ts-toolbelt "^6.15.1"
|
||||
|
||||
"@types/react-native@>=0.62.0":
|
||||
version "0.64.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.64.12.tgz#1c6a3226c26d7a5949cdf8878e6cfe95fe0951d6"
|
||||
@ -1804,6 +1829,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
||||
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
|
||||
|
||||
"@types/urijs@^1.19.15":
|
||||
version "1.19.16"
|
||||
resolved "https://registry.yarnpkg.com/@types/urijs/-/urijs-1.19.16.tgz#156658c47438fa867db5dce4d2949fe1ca0878e2"
|
||||
integrity sha512-WgxqcUSEYijGnNWHSln/uqay+AywS3mEhLC+d2PwLsru2fLeMblvxP67Y/SCfB2Pxe+dX/zbIoNNzXY+VKOtNA==
|
||||
|
||||
"@types/yargs-parser@*":
|
||||
version "20.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9"
|
||||
@ -2831,7 +2861,7 @@ buffer-xor@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
|
||||
integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
|
||||
|
||||
buffer@^4.5.1, buffer@^4.9.1:
|
||||
buffer@^4.9.1:
|
||||
version "4.9.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
|
||||
integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
|
||||
@ -2920,6 +2950,11 @@ camelcase@^5.0.0, camelcase@^5.3.1:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
camelize@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
|
||||
integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
|
||||
|
||||
caniuse-lite@^1.0.30001219:
|
||||
version "1.0.30001228"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa"
|
||||
@ -2965,6 +3000,16 @@ chalk@^3.0.0:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
character-entities-html4@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125"
|
||||
integrity sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==
|
||||
|
||||
character-entities-legacy@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
|
||||
integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==
|
||||
|
||||
chardet@^0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
|
||||
@ -3458,6 +3503,11 @@ crypto-js@^3.1.9-1:
|
||||
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b"
|
||||
integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==
|
||||
|
||||
css-color-keywords@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
||||
integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
|
||||
|
||||
css-mediaquery@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0"
|
||||
@ -3473,6 +3523,15 @@ css-select@^2.0.2:
|
||||
domutils "^1.7.0"
|
||||
nth-check "^1.0.2"
|
||||
|
||||
css-to-react-native@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
|
||||
integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
|
||||
dependencies:
|
||||
camelize "^1.0.0"
|
||||
css-color-keywords "^1.0.0"
|
||||
postcss-value-parser "^4.0.2"
|
||||
|
||||
css-tree@^1.0.0-alpha.37:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5"
|
||||
@ -3513,6 +3572,11 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b"
|
||||
integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==
|
||||
|
||||
csstype@^3.0.8:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
|
||||
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
|
||||
|
||||
currency-symbol-map@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/currency-symbol-map/-/currency-symbol-map-4.0.4.tgz#3cfba625974dd3f86822d327ecbd10248695e95e"
|
||||
@ -3798,12 +3862,21 @@ dom-serializer@0:
|
||||
domelementtype "^2.0.1"
|
||||
entities "^2.0.0"
|
||||
|
||||
dom-serializer@^1.0.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
|
||||
integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.2.0"
|
||||
entities "^2.0.0"
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
||||
|
||||
domelementtype@1, domelementtype@^1.3.1:
|
||||
domelementtype@1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
|
||||
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
|
||||
@ -3813,6 +3886,11 @@ domelementtype@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e"
|
||||
integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==
|
||||
|
||||
domelementtype@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
||||
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
||||
|
||||
domexception@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
|
||||
@ -3820,14 +3898,14 @@ domexception@^1.0.1:
|
||||
dependencies:
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
domhandler@^2.3.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
|
||||
integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
|
||||
domhandler@^4.0.0, domhandler@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059"
|
||||
integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==
|
||||
dependencies:
|
||||
domelementtype "1"
|
||||
domelementtype "^2.2.0"
|
||||
|
||||
domutils@^1.5.1, domutils@^1.7.0:
|
||||
domutils@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
|
||||
integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
|
||||
@ -3835,6 +3913,15 @@ domutils@^1.5.1, domutils@^1.7.0:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
domutils@^2.5.2:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442"
|
||||
integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==
|
||||
dependencies:
|
||||
dom-serializer "^1.0.1"
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
dooboolab-welcome@1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/dooboolab-welcome/-/dooboolab-welcome-1.3.2.tgz#4928595312f0429b4ea1b485ba8767bae6acdab7"
|
||||
@ -3900,11 +3987,6 @@ elliptic@^6.5.2, elliptic@^6.5.3:
|
||||
minimalistic-assert "^1.0.1"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
emitter-component@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/emitter-component/-/emitter-component-1.1.1.tgz#065e2dbed6959bf470679edabeaf7981d1003ab6"
|
||||
integrity sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=
|
||||
|
||||
emoji-regex@^7.0.1:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||
@ -3939,11 +4021,6 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
entities@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
|
||||
|
||||
entities@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
@ -4403,7 +4480,7 @@ eventemitter3@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
|
||||
integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
|
||||
|
||||
events@^1.0.0, events@^1.0.2, events@^1.1.0:
|
||||
events@^1.0.0, events@^1.0.2:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
|
||||
integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
|
||||
@ -5273,27 +5350,20 @@ html-encoding-sniffer@^1.0.2:
|
||||
dependencies:
|
||||
whatwg-encoding "^1.0.1"
|
||||
|
||||
html-entities@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc"
|
||||
integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==
|
||||
|
||||
html-escaper@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
|
||||
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
|
||||
|
||||
htmlparser2@^3.10.1:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
|
||||
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
|
||||
htmlparser2@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
|
||||
dependencies:
|
||||
domelementtype "^1.3.1"
|
||||
domhandler "^2.3.0"
|
||||
domutils "^1.5.1"
|
||||
entities "^1.1.1"
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^3.1.1"
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.5.2"
|
||||
entities "^2.0.0"
|
||||
|
||||
http-errors@~1.7.2:
|
||||
version "1.7.3"
|
||||
@ -8271,6 +8341,11 @@ posix-character-classes@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
|
||||
|
||||
postcss-value-parser@^4.0.2:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
|
||||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
|
||||
|
||||
prebuild-install@^5.3.3:
|
||||
version "5.3.6"
|
||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.6.tgz#7c225568d864c71d89d07f8796042733a3f54291"
|
||||
@ -8532,6 +8607,11 @@ queue-microtask@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
ramda@^0.27.1:
|
||||
version "0.27.1"
|
||||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9"
|
||||
integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
@ -8622,7 +8702,7 @@ react-native-animatable@1.3.3, react-native-animatable@^1.3.3:
|
||||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-autoheight-webview@^1.3.4, react-native-autoheight-webview@^1.5.8:
|
||||
react-native-autoheight-webview@^1.5.8:
|
||||
version "1.5.8"
|
||||
resolved "https://registry.yarnpkg.com/react-native-autoheight-webview/-/react-native-autoheight-webview-1.5.8.tgz#afcbe65dfefcce4e2088c9aff9fee23dcd18aadf"
|
||||
integrity sha512-6+LY0a47AsnfnGgqMP2JzNVgX0/sGnkgq7UV39OKgUf2Im/glFjUOggYm8EiyzmA93gb9tYVB1mRTORElWAiGQ==
|
||||
@ -8750,12 +8830,6 @@ react-native-level-fs@^3.0.0:
|
||||
level-filesystem "^1.0.1"
|
||||
levelup "^0.18.2"
|
||||
|
||||
"react-native-lightbox@git+https://github.com/oblador/react-native-lightbox.git":
|
||||
version "0.8.1"
|
||||
resolved "git+https://github.com/oblador/react-native-lightbox.git#8db37fda32bfe2f4537b992550bd8d0c27f7ca57"
|
||||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-linear-gradient@^2.4.2:
|
||||
version "2.5.6"
|
||||
resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz#96215cbc5ec7a01247a20890888aa75b834d44a0"
|
||||
@ -8835,6 +8909,21 @@ react-native-receive-sharing-intent@ecency/react-native-receive-sharing-intent:
|
||||
version "1.0.4"
|
||||
resolved "https://codeload.github.com/ecency/react-native-receive-sharing-intent/tar.gz/02d179b5eed6e18bd887248b8d9d2cb2cad0cb18"
|
||||
|
||||
react-native-render-html@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/react-native-render-html/-/react-native-render-html-6.0.5.tgz#b36c020a67760d8aace943e40a4c8b0c61a4759a"
|
||||
integrity sha512-EpLJ7zeshoRAICnlNDDZD+wc109bo47yBSpXahlnFs0txAw45SL9IfB9KiN15vLrXIq+mneV1GDPKhP8S0e4fw==
|
||||
dependencies:
|
||||
"@jsamr/counter-style" "^2.0.1"
|
||||
"@jsamr/react-native-li" "^2.2.1"
|
||||
"@native-html/transient-render-engine" "^9.2.2"
|
||||
"@types/ramda" "^0.27.40"
|
||||
"@types/urijs" "^1.19.15"
|
||||
prop-types "^15.5.7"
|
||||
ramda "^0.27.1"
|
||||
stringify-entities "^3.1.0"
|
||||
urijs "^1.19.6"
|
||||
|
||||
react-native-restart@0.0.17:
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/react-native-restart/-/react-native-restart-0.0.17.tgz#c1f38e019d1a2114248d496698e7951e9435ba91"
|
||||
@ -10112,13 +10201,6 @@ stream-buffers@~2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4"
|
||||
integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=
|
||||
|
||||
stream@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stream/-/stream-0.0.2.tgz#7f5363f057f6592c5595f00bc80a27f5cec1f0ef"
|
||||
integrity sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=
|
||||
dependencies:
|
||||
emitter-component "^1.1.1"
|
||||
|
||||
strict-uri-encode@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
|
||||
@ -10225,6 +10307,15 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
stringify-entities@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-3.1.0.tgz#b8d3feac256d9ffcc9fa1fefdcf3ca70576ee903"
|
||||
integrity sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg==
|
||||
dependencies:
|
||||
character-entities-html4 "^1.0.0"
|
||||
character-entities-legacy "^1.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
stringify-object@^3.2.2:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
|
||||
@ -10545,6 +10636,11 @@ tr46@^1.0.1:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
ts-toolbelt@^6.15.1:
|
||||
version "6.15.5"
|
||||
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83"
|
||||
integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==
|
||||
|
||||
tsconfig-paths@^3.9.0:
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
|
||||
@ -10756,6 +10852,11 @@ uri-js@^4.2.2:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
urijs@^1.19.6:
|
||||
version "1.19.7"
|
||||
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.7.tgz#4f594e59113928fea63c00ce688fb395b1168ab9"
|
||||
integrity sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==
|
||||
|
||||
urix@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
|
||||
|
Loading…
Reference in New Issue
Block a user