From 80c0f9a8f6779b76e090456b8ea29d486179b35c Mon Sep 17 00:00:00 2001 From: btzr-io <btzr.io@gmail.com> Date: Wed, 1 Aug 2018 22:56:17 -0600 Subject: [PATCH] extend support for human-readable files --- src/renderer/component/fileRender/view.jsx | 16 +++++++++++++-- .../component/fileViewer/internal/player.jsx | 2 +- src/renderer/component/viewers/codeViewer.jsx | 12 +++++++++-- src/renderer/component/viewers/htmlViewer.jsx | 20 +++++++++++++++++++ src/renderer/page/file/view.jsx | 3 ++- src/renderer/util/getMediaType.js | 1 + 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 src/renderer/component/viewers/htmlViewer.jsx diff --git a/src/renderer/component/fileRender/view.jsx b/src/renderer/component/fileRender/view.jsx index 34194b213..ce0494f6a 100644 --- a/src/renderer/component/fileRender/view.jsx +++ b/src/renderer/component/fileRender/view.jsx @@ -5,6 +5,7 @@ import PdfViewer from 'component/viewers/pdfViewer'; import ThreeViewer from 'component/viewers/threeViewer'; import DocumentViewer from 'component/viewers/documentViewer'; import DocxViewer from 'component/viewers/docxViewer'; +import HtmlViewer from 'component/viewers/htmlViewer'; type Props = { mediaType: string, @@ -25,10 +26,12 @@ class FileRender extends React.PureComponent<Props> { // Extract relevant data to render file const { blob, stream, fileName, fileType, contentType, downloadPath } = source; + // Human-readable files (scripts and plain-text files) + const readableFiles = ['text', 'document', 'script']; + // Supported mediaTypes const mediaTypes = { '3D-file': <ThreeViewer source={{ fileType, downloadPath }} theme={currentTheme} />, - document: <DocumentViewer source={{ stream, fileType, contentType }} theme={currentTheme} />, // Add routes to viewer... }; @@ -36,10 +39,19 @@ class FileRender extends React.PureComponent<Props> { const fileTypes = { pdf: <PdfViewer source={downloadPath} />, docx: <DocxViewer source={downloadPath} />, + html: <HtmlViewer source={downloadPath} />, // Add routes to viewer... }; - const viewer = mediaType && source && (fileTypes[fileType] || mediaTypes[mediaType]); + // Check for a valid fileType or mediaType + let viewer = fileTypes[fileType] || mediaTypes[mediaType]; + + // Check for Human-readable files + if (!viewer && readableFiles.includes(mediaType)) { + viewer = <DocumentViewer source={{ stream, fileType, contentType }} theme={currentTheme} />; + } + + // Message Error const unsupportedMessage = __("Sorry, looks like we can't preview this file."); const unsupported = <LoadingScreen status={unsupportedMessage} spinner={false} />; diff --git a/src/renderer/component/fileViewer/internal/player.jsx b/src/renderer/component/fileViewer/internal/player.jsx index 1482146bf..375f8d152 100644 --- a/src/renderer/component/fileViewer/internal/player.jsx +++ b/src/renderer/component/fileViewer/internal/player.jsx @@ -11,7 +11,7 @@ import LoadingScreen from 'component/common/loading-screen'; class MediaPlayer extends React.PureComponent { static MP3_CONTENT_TYPES = ['audio/mpeg3', 'audio/mpeg']; - static FILE_MEDIA_TYPES = ['e-book', 'comic-book', 'document', '3D-file']; + static FILE_MEDIA_TYPES = ['text', 'script', 'e-book', 'comic-book', 'document', '3D-file']; constructor(props) { super(props); diff --git a/src/renderer/component/viewers/codeViewer.jsx b/src/renderer/component/viewers/codeViewer.jsx index c076ddac2..1d5164468 100644 --- a/src/renderer/component/viewers/codeViewer.jsx +++ b/src/renderer/component/viewers/codeViewer.jsx @@ -8,9 +8,17 @@ import { openSnippetMenu, stopContextMenu } from 'util/contextMenu'; import 'codemirror/addon/selection/mark-selection'; // Syntax mode -import 'codemirror/mode/javascript/javascript'; -import 'codemirror/mode/markdown/markdown'; +import 'codemirror/mode/go/go'; +import 'codemirror/mode/jsx/jsx'; +import 'codemirror/mode/css/css'; import 'codemirror/mode/xml/xml'; +import 'codemirror/mode/php/php'; +import 'codemirror/mode/ruby/ruby'; +import 'codemirror/mode/clike/clike'; +import 'codemirror/mode/shell/shell'; +import 'codemirror/mode/python/python'; +import 'codemirror/mode/markdown/markdown'; +import 'codemirror/mode/javascript/javascript'; type Props = { theme: string, diff --git a/src/renderer/component/viewers/htmlViewer.jsx b/src/renderer/component/viewers/htmlViewer.jsx new file mode 100644 index 000000000..029d7e15d --- /dev/null +++ b/src/renderer/component/viewers/htmlViewer.jsx @@ -0,0 +1,20 @@ +// @flow +import React from 'react'; +import { stopContextMenu } from 'util/contextMenu'; + +type Props = { + source: string, +}; + +class HtmlViewer extends React.PureComponent<Props> { + render() { + const { source } = this.props; + return ( + <div className="file-render__viewer" onContextMenu={stopContextMenu}> + <iframe sandbox="" title={__('File preview')} src={`file://${source}`} /> + </div> + ); + } +} + +export default HtmlViewer; diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index 1c29794ac..8c8833dd4 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -55,8 +55,9 @@ class FilePage extends React.Component<Props> { 'text', 'model', 'image', - '3D-file', + 'script', 'document', + '3D-file', // Bypass unplayable files // TODO: Find a better way to detect supported types 'application', diff --git a/src/renderer/util/getMediaType.js b/src/renderer/util/getMediaType.js index 49ca3e735..a028f6655 100644 --- a/src/renderer/util/getMediaType.js +++ b/src/renderer/util/getMediaType.js @@ -3,6 +3,7 @@ import mime from 'mime'; const formats = [ [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], + [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'],