basic markdown rendering
This commit is contained in:
parent
b25f913921
commit
c47c7cd925
4 changed files with 222 additions and 11 deletions
157
package-lock.json
generated
157
package-lock.json
generated
|
@ -10332,9 +10332,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redux-persist": {
|
"redux-persist": {
|
||||||
"version": "5.10.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-5.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz",
|
||||||
"integrity": "sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg=="
|
"integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ=="
|
||||||
},
|
},
|
||||||
"redux-persist-filesystem-storage": {
|
"redux-persist-filesystem-storage": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
|
@ -10887,6 +10887,157 @@
|
||||||
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
|
||||||
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
|
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
|
||||||
},
|
},
|
||||||
|
"showdown": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==",
|
||||||
|
"requires": {
|
||||||
|
"yargs": "^14.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"camelcase": {
|
||||||
|
"version": "5.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||||
|
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||||
|
},
|
||||||
|
"cliui": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||||
|
"requires": {
|
||||||
|
"string-width": "^3.1.0",
|
||||||
|
"strip-ansi": "^5.2.0",
|
||||||
|
"wrap-ansi": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"find-up": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||||
|
"requires": {
|
||||||
|
"locate-path": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get-caller-file": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||||
|
},
|
||||||
|
"is-fullwidth-code-point": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||||
|
},
|
||||||
|
"locate-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||||
|
"requires": {
|
||||||
|
"p-locate": "^3.0.0",
|
||||||
|
"path-exists": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-limit": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
|
||||||
|
"requires": {
|
||||||
|
"p-try": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-locate": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||||
|
"requires": {
|
||||||
|
"p-limit": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-try": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||||
|
},
|
||||||
|
"require-main-filename": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||||
|
},
|
||||||
|
"string-width": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||||
|
"requires": {
|
||||||
|
"emoji-regex": "^7.0.1",
|
||||||
|
"is-fullwidth-code-point": "^2.0.0",
|
||||||
|
"strip-ansi": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "^4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrap-ansi": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^3.2.0",
|
||||||
|
"string-width": "^3.0.0",
|
||||||
|
"strip-ansi": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"y18n": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||||
|
},
|
||||||
|
"yargs": {
|
||||||
|
"version": "14.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz",
|
||||||
|
"integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==",
|
||||||
|
"requires": {
|
||||||
|
"cliui": "^5.0.0",
|
||||||
|
"decamelize": "^1.2.0",
|
||||||
|
"find-up": "^3.0.0",
|
||||||
|
"get-caller-file": "^2.0.1",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"require-main-filename": "^2.0.0",
|
||||||
|
"set-blocking": "^2.0.0",
|
||||||
|
"string-width": "^3.0.0",
|
||||||
|
"which-module": "^2.0.0",
|
||||||
|
"y18n": "^4.0.0",
|
||||||
|
"yargs-parser": "^15.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yargs-parser": {
|
||||||
|
"version": "15.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz",
|
||||||
|
"integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==",
|
||||||
|
"requires": {
|
||||||
|
"camelcase": "^5.0.0",
|
||||||
|
"decamelize": "^1.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||||
|
|
|
@ -50,7 +50,8 @@
|
||||||
"redux-persist-transform-filter": "0.0.18",
|
"redux-persist-transform-filter": "0.0.18",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"rn-fetch-blob": "0.12.0",
|
"rn-fetch-blob": "0.12.0",
|
||||||
"seedrandom": "3.0.3"
|
"seedrandom": "3.0.3",
|
||||||
|
"showdown": "1.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.6.2",
|
"@babel/core": "^7.6.2",
|
||||||
|
|
|
@ -89,7 +89,7 @@ class UriBar extends React.PureComponent {
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
|
|
||||||
if (SEARCH_TYPES.SEARCH === type) {
|
if (SEARCH_TYPES.SEARCH === type) {
|
||||||
this.setState({ currentValue: value }, () => this.setCaretPosition(value));
|
this.setState({ currentValue: value });
|
||||||
updateSearchQuery(value);
|
updateSearchQuery(value);
|
||||||
|
|
||||||
if (onSearchSubmitted) {
|
if (onSearchSubmitted) {
|
||||||
|
|
|
@ -45,6 +45,8 @@ import Video from 'react-native-video';
|
||||||
import FileRewardsDriver from 'component/fileRewardsDriver';
|
import FileRewardsDriver from 'component/fileRewardsDriver';
|
||||||
import filePageStyle from 'styles/filePage';
|
import filePageStyle from 'styles/filePage';
|
||||||
import uriBarStyle from 'styles/uriBar';
|
import uriBarStyle from 'styles/uriBar';
|
||||||
|
import RNFS from 'react-native-fs';
|
||||||
|
import showdown from 'showdown';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
class FilePage extends React.PureComponent {
|
class FilePage extends React.PureComponent {
|
||||||
|
@ -58,6 +60,10 @@ class FilePage extends React.PureComponent {
|
||||||
|
|
||||||
startTime = null;
|
startTime = null;
|
||||||
|
|
||||||
|
webView = null;
|
||||||
|
|
||||||
|
converter = null;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -712,7 +718,7 @@ class FilePage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
openFile = (localFileUri, mediaType) => {
|
openFile = (localFileUri, mediaType, contentType) => {
|
||||||
const { pushDrawerStack } = this.props;
|
const { pushDrawerStack } = this.props;
|
||||||
const isWebViewable = mediaType === 'text';
|
const isWebViewable = mediaType === 'text';
|
||||||
|
|
||||||
|
@ -739,12 +745,55 @@ class FilePage extends React.PureComponent {
|
||||||
{
|
{
|
||||||
showWebView: true,
|
showWebView: true,
|
||||||
},
|
},
|
||||||
() => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW),
|
() => {
|
||||||
|
pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleWebViewLoad = () => {
|
||||||
|
const { contentType, fileInfo } = this.props;
|
||||||
|
const localFileUri = this.localUriForFileInfo(fileInfo);
|
||||||
|
if (this.webView && ['text/markdown', 'text/md'].includes(contentType)) {
|
||||||
|
RNFS.readFile(localFileUri, 'utf8').then(markdown => {
|
||||||
|
if (this.webView) {
|
||||||
|
if (!this.converter) {
|
||||||
|
this.converter = new showdown.Converter();
|
||||||
|
}
|
||||||
|
const html = this.converter.makeHtml(markdown);
|
||||||
|
this.webView.injectJavaScript(
|
||||||
|
'document.getElementById("content").innerHTML = \'' +
|
||||||
|
html.replace(/\n/g, '').replace(/'/g, "\\'") +
|
||||||
|
"'; true;",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
buildWebViewSource = () => {
|
||||||
|
const { contentType, fileInfo } = this.props;
|
||||||
|
const localFileUri = this.localUriForFileInfo(fileInfo);
|
||||||
|
|
||||||
|
if (['text/markdown', 'text/md'].includes(contentType)) {
|
||||||
|
const html =
|
||||||
|
'<!doctype html>' +
|
||||||
|
'<html>' +
|
||||||
|
' <head>' +
|
||||||
|
' <meta charset="utf-8"/>' +
|
||||||
|
' </head>' +
|
||||||
|
' <body>' +
|
||||||
|
' <div id="content"></div>' +
|
||||||
|
' </body>' +
|
||||||
|
'</html>';
|
||||||
|
return { html };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { uri: localFileUri };
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
balance,
|
balance,
|
||||||
|
@ -780,7 +829,7 @@ class FilePage extends React.PureComponent {
|
||||||
<View style={filePageStyle.pageContainer}>
|
<View style={filePageStyle.pageContainer}>
|
||||||
<UriBar value={uri} navigation={navigation} />
|
<UriBar value={uri} navigation={navigation} />
|
||||||
{isResolvingUri && (
|
{isResolvingUri && (
|
||||||
<View style={filePageStyle.busyContainer}>
|
<View stylebuildWeb={filePageStyle.busyContainer}>
|
||||||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} />
|
<ActivityIndicator size="large" color={Colors.NextLbryGreen} />
|
||||||
<Text style={filePageStyle.infoText}>{__('Loading decentralized data...')}</Text>
|
<Text style={filePageStyle.infoText}>{__('Loading decentralized data...')}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
@ -893,7 +942,7 @@ class FilePage extends React.PureComponent {
|
||||||
|
|
||||||
if (this.state.downloadPressed && canOpen && !this.state.autoOpened) {
|
if (this.state.downloadPressed && canOpen && !this.state.autoOpened) {
|
||||||
// automatically open a web viewable or image file after the download button is pressed
|
// automatically open a web viewable or image file after the download button is pressed
|
||||||
this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType));
|
this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType, contentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isChannel) {
|
if (isChannel) {
|
||||||
|
@ -906,7 +955,17 @@ class FilePage extends React.PureComponent {
|
||||||
{innerContent}
|
{innerContent}
|
||||||
|
|
||||||
{this.state.showWebView && isWebViewable && (
|
{this.state.showWebView && isWebViewable && (
|
||||||
<WebView allowFileAccess source={{ uri: localFileUri }} style={filePageStyle.viewer} />
|
<WebView
|
||||||
|
ref={ref => {
|
||||||
|
this.webView = ref;
|
||||||
|
}}
|
||||||
|
allowFileAccess
|
||||||
|
javaScriptEnabled
|
||||||
|
originWhiteList={['*']}
|
||||||
|
source={this.buildWebViewSource()}
|
||||||
|
style={filePageStyle.viewer}
|
||||||
|
onLoad={this.handleWebViewLoad}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{this.state.showImageViewer && (
|
{this.state.showImageViewer && (
|
||||||
<ImageViewer
|
<ImageViewer
|
||||||
|
@ -965,7 +1024,7 @@ class FilePage extends React.PureComponent {
|
||||||
<FileDownloadButton
|
<FileDownloadButton
|
||||||
uri={claim && claim.permanent_url ? claim.permanent_url : uri}
|
uri={claim && claim.permanent_url ? claim.permanent_url : uri}
|
||||||
style={filePageStyle.downloadButton}
|
style={filePageStyle.downloadButton}
|
||||||
openFile={() => this.openFile(localFileUri, mediaType)}
|
openFile={() => this.openFile(localFileUri, mediaType, contentType)}
|
||||||
isPlayable={isPlayable}
|
isPlayable={isPlayable}
|
||||||
isViewable={isViewable}
|
isViewable={isViewable}
|
||||||
onFileActionPress={this.onFileDownloadButtonPressed}
|
onFileActionPress={this.onFileDownloadButtonPressed}
|
||||||
|
|
Loading…
Reference in a new issue