add code-viewer

This commit is contained in:
btzr-io 2018-07-26 18:24:00 -06:00
parent 1c50b71f14
commit c622314eff
8 changed files with 140 additions and 48 deletions

View file

@ -36,6 +36,7 @@
"dependencies": { "dependencies": {
"bluebird": "^3.5.1", "bluebird": "^3.5.1",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"codemirror": "^5.39.2",
"country-data": "^0.0.31", "country-data": "^0.0.31",
"dom-scroll-into-view": "^1.2.1", "dom-scroll-into-view": "^1.2.1",
"electron-dl": "^1.11.0", "electron-dl": "^1.11.0",

View file

@ -0,0 +1,38 @@
// @flow
import React from 'react';
import CodeMirror from 'codemirror';
type Props = {
value: string,
};
class CodeViewer extends React.PureComponent<Props> {
constructor(props) {
super(props);
this.codeMirror = null;
this.textarea = React.createRef();
}
componentDidMount() {
this.codeMirror = CodeMirror.fromTextArea(this.textarea.current, {
mode: 'markdown',
readOnly: true,
dragDrop: false,
lineNumbers: true,
lineWrapping: true,
});
}
render() {
const { value } = this.props;
return (
<div className="document-viewer__content">
<textarea ref={this.textarea} disabled="true" value={value} />
</div>
);
}
}
export default CodeViewer;

View file

@ -3,6 +3,7 @@
import React from 'react'; import React from 'react';
import fs from 'fs'; import fs from 'fs';
import LoadingScreen from 'component/common/loading-screen'; import LoadingScreen from 'component/common/loading-screen';
import CodeViewer from 'component/viewers/codeViewer';
import MarkdownPreview from 'component/common/markdown-preview'; import MarkdownPreview from 'component/common/markdown-preview';
type Props = { type Props = {
@ -34,7 +35,7 @@ class DocumentViewer extends React.PureComponent<Props> {
}); });
stream.on('end', () => { stream.on('end', () => {
this.setState({ content: data }); this.setState({ content: data, loading: false });
}); });
stream.on('error', error => { stream.on('error', error => {
@ -42,36 +43,34 @@ class DocumentViewer extends React.PureComponent<Props> {
}); });
} }
renderDocument(data) { renderDocument() {
let viewer = null;
const { source } = this.props; const { source } = this.props;
const { fileType } = source; const { content, error } = this.state;
const isReady = content && !error;
const markdownType = ['md', 'markdown'];
// Match supported documents if (isReady && markdownType.includes(source.fileType)) {
const docs = { // Render markdown
md: content => <MarkdownPreview content={content} promptLinks />, viewer = <MarkdownPreview content={content} promptLinks />;
}; } else if (isReady) {
// Render plain text
if (docs[fileType]) { viewer = <CodeViewer value={content} />;
// Use custom parser
return docs[fileType](data);
} }
// Render plain text
this.setState({ loading: false }); return viewer;
return <textarea disabled="true" value={data} />;
} }
render() { render() {
const { content, error, loading } = this.state; const { error, loading } = this.state;
const loadingMessage = __('Rendering document.'); const loadingMessage = __('Rendering document.');
const errorMessage = __("Sorry looks like we can't load the document."); const errorMessage = __("Sorry looks like we can't load the document.");
return ( return (
<div className="document-viewer file-render__viewer"> <div className="file-render__viewer document-viewer">
{loading && !error && <LoadingScreen status={loadingMessage} spinner />} {loading && !error && <LoadingScreen status={loadingMessage} spinner />}
{error && <LoadingScreen status={errorMessage} spinner={false} />} {error && <LoadingScreen status={errorMessage} spinner={false} />}
{content && ( {this.renderDocument()}
<div className="document-viewer__content">{content && this.renderDocument(content)}</div>
)}
</div> </div>
); );
} }

View file

@ -96,25 +96,6 @@
} }
} }
.file-render {
width: 100%;
height: 100%;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
overflow: hidden;
.file-render__viewer {
width: 100%;
height: 100%;
background: black;
}
}
img { img {
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;

View file

@ -9,17 +9,80 @@
bottom: 0; bottom: 0;
z-index: 1; z-index: 1;
overflow: hidden; overflow: hidden;
}
.file-render__viewer { .file-render__viewer {
margin: 0; margin: 0;
width: 100%;
height: 100%;
background-color: black;
iframe,
webview {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: black; }
}
iframe,
webview { .document-viewer {
width: 100%; overflow: auto;
height: 100%; background-color: var(--card-bg);
} }
.document-viewer .markdown-preview {
padding: 32px 16px;
}
.document-viewer .CodeMirror {
height: 100%;
width: 100%;
min-height: 100px;
padding: 0;
margin: 0;
.CodeMirror-code {
font-size: calc(var(--font-size-subtext-multiple) * 1em);
font-family: monospace;
}
.CodeMirror-linenumber {
color: var(--card-text-color);
}
.CodeMirror-line {
padding-left: 16px;
}
.CodeMirror-gutters {
border-right: 1px solid var(--color-divider);
background: var(--color-bg-alt);
}
.cm-invalidchar {
display: none;
}
}
.document-viewer__content {
overflow: auto;
width: 100%;
height: 100%;
.markdown-preview {
padding: 32px 16px;
height: 100%;
overflow: auto;
}
textarea {
/*
resize: none;
background: transparent;
color: var(--card-text-color);
border: 0;
outline: none;
font-family: monospace;
*/
display: none;
} }
} }

View file

@ -63,6 +63,11 @@
} }
} }
/* Image */
img {
margin: 16px 0;
}
/* Horizontal Rule */ /* Horizontal Rule */
hr { hr {
border: 1px solid var(--color-divider); border: 1px solid var(--color-divider);

View file

@ -3,7 +3,8 @@ import mime from 'mime';
const formats = [ const formats = [
[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'],
[/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'],
[/\.(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], [/\.(json|csv|txt|log|md|markdown|rtf|xml|yml|yaml)$/i, 'document'],
[/\.(pdf|odf|doc|docx|epub|org)$/i, 'e-book'],
[/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'],
]; ];

View file

@ -1893,6 +1893,10 @@ codemirror@*:
version "5.39.0" version "5.39.0"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.0.tgz#4654f7d2f7e525e04a62e72d9482348ccb37dce5" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.0.tgz#4654f7d2f7e525e04a62e72d9482348ccb37dce5"
codemirror@^5.39.2:
version "5.39.2"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.39.2.tgz#778aa13b55ebf280745c309cb1b148e3fc06f698"
collapse-white-space@^1.0.0, collapse-white-space@^1.0.2: collapse-white-space@^1.0.0, collapse-white-space@^1.0.2:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091"