From 61fc8c20dc4ba4821f1c829946271b1d68145a39 Mon Sep 17 00:00:00 2001 From: llj Date: Thu, 28 Mar 2019 10:59:43 +0800 Subject: [PATCH] [shared file view] code improvement (#3185) * added component shared-file-view.js & shared-file-view-tip.js * modified 'text file view' --- .../shared-file-view/shared-file-view-tip.js | 24 +++ .../shared-file-view/shared-file-view.js | 117 ++++++++++++++ frontend/src/css/shared-file-view.css | 28 ---- frontend/src/shared-file-view-image.js | 140 ++-------------- frontend/src/shared-file-view-markdown.js | 125 +++------------ frontend/src/shared-file-view-pdf.js | 140 ++-------------- frontend/src/shared-file-view-text.js | 149 ++++-------------- seahub/templates/shared_file_view_react.html | 2 +- 8 files changed, 230 insertions(+), 495 deletions(-) create mode 100644 frontend/src/components/shared-file-view/shared-file-view-tip.js create mode 100644 frontend/src/components/shared-file-view/shared-file-view.js diff --git a/frontend/src/components/shared-file-view/shared-file-view-tip.js b/frontend/src/components/shared-file-view/shared-file-view-tip.js new file mode 100644 index 0000000000..e5d31c998b --- /dev/null +++ b/frontend/src/components/shared-file-view/shared-file-view-tip.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { gettext } from '../../utils/constants'; + +const { err } = window.shared.pageOptions; + +class SharedFileViewTip extends React.Component { + render() { + let errorMsg; + if (err == 'File preview unsupported') { + errorMsg =

{gettext('Online view is not applicable to this file format')}

; + } else { + errorMsg =

{err}

; + } + return ( +
+
+ {errorMsg} +
+
+ ); + } +} + +export default SharedFileViewTip; diff --git a/frontend/src/components/shared-file-view/shared-file-view.js b/frontend/src/components/shared-file-view/shared-file-view.js new file mode 100644 index 0000000000..e644f21864 --- /dev/null +++ b/frontend/src/components/shared-file-view/shared-file-view.js @@ -0,0 +1,117 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Account from '../common/account'; +import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from '../../utils/constants'; +import { Button } from 'reactstrap'; +import { Utils } from '../../utils/utils'; +import SaveSharedFileDialog from '../dialog/save-shared-file-dialog'; +import toaster from '../toast'; +import watermark from 'watermark-dom'; + +import '../../css/shared-file-view.css'; + +const propTypes = { + content: PropTypes.object.isRequired +}; + +let loginUser = window.app.pageOptions.name; +const { repoID, sharedToken, trafficOverLimit, fileName, fileSize, sharedBy, siteName, enableWatermark, download } = window.shared.pageOptions; + +class SharedFileView extends React.Component { + + constructor(props) { + super(props); + this.state = { + showSaveSharedFileDialog: false + }; + } + + handleSaveSharedFileDialog = () => { + this.setState({ + showSaveSharedFileDialog: true + }); + } + + toggleCancel = () => { + this.setState({ + showSaveSharedFileDialog: false + }); + } + + handleSaveSharedFile = () => { + toaster.success(gettext('Successfully saved'), { + duration: 3 + }); + } + + componentDidMount() { + if (trafficOverLimit == 'True') { + toaster.danger(gettext('File download is disabled: the share link traffic of owner is used up.'), { + duration: 3 + }); + } + } + + render() { + return ( +
+
+ + + logo + + + { loginUser && } +
+
+
+
+

{fileName}

+

{gettext('Shared by:')}{' '}{sharedBy}

+
+ {download && +
+ {(loginUser && loginUser !== sharedBy) && + + }{' '} + {(trafficOverLimit === 'False') && + + } +
+ } +
+ {this.props.content} +
+ {this.state.showSaveSharedFileDialog && + + } +
+ ); + } +} + +if (enableWatermark) { + let watermark_txt; + if (loginUser) { + watermark_txt = siteName + ' ' + loginUser; + } else { + watermark_txt = gettext('Anonymous User'); + } + watermark.init({ + watermark_txt: watermark_txt, + watermark_alpha: 0.075 + }); +} + +SharedFileView.propTypes = propTypes; + +export default SharedFileView; diff --git a/frontend/src/css/shared-file-view.css b/frontend/src/css/shared-file-view.css index d64a392d89..f5a25c17ba 100644 --- a/frontend/src/css/shared-file-view.css +++ b/frontend/src/css/shared-file-view.css @@ -67,34 +67,6 @@ overflow: auto; } -.shared-file-view-body .txt-view .CodeMirror, -.shared-file-view-body .txt-view .file-view-tip { - height: auto; - min-height: 400px; - border: 1px solid #ccc; - margin: 0 auto; - box-shadow: 0 0 6px #ccc; - width: 816px; - padding: 40px 96px; - line-height: 1.5em; - background-color: #fff; -} - -.shared-file-view-body .txt-view .file-view-tip { - min-height: 100px; - text-align: center; -} - -.shared-file-view-body .txt-view .CodeMirror-scroll { - min-height: 400px; -} - -.file-enc-cont { - width: 950px; - margin: -20px auto 6px; - text-align: right; -} - @media (max-width: 991.98px) { .shared-file-view-head { width: 100%; diff --git a/frontend/src/shared-file-view-image.js b/frontend/src/shared-file-view-image.js index 6604d2b688..a21f6f0ffc 100644 --- a/frontend/src/shared-file-view-image.js +++ b/frontend/src/shared-file-view-image.js @@ -1,138 +1,32 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Account from './components/common/account'; -import { serviceURL, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; -import { Button } from 'reactstrap'; -import { Utils } from './utils/utils'; -import SaveSharedFileDialog from './components/dialog/save-shared-file-dialog'; -import toaster from './components/toast'; -import watermark from 'watermark-dom'; +import SharedFileView from './components/shared-file-view/shared-file-view'; +import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip'; -import './css/shared-file-view.css'; import './css/image-file-view.css'; -let loginUser = window.app.pageOptions.name; -const { repoID, sharedToken, trafficOverLimit, fileName, fileSize, rawPath, sharedBy, siteName, enableWatermark, download, err } = window.shared.pageOptions; +const { fileName, rawPath, err } = window.shared.pageOptions; class SharedFileViewImage extends React.Component { - - constructor(props) { - super(props); - this.state = { - showSaveSharedFileDialog: false - }; - } - - handleSaveSharedFileDialog = () => { - this.setState({ - showSaveSharedFileDialog: true - }); - } - - toggleCancel = () => { - this.setState({ - showSaveSharedFileDialog: false - }); - } - - handleSaveSharedFile = () => { - toaster.success(gettext('Successfully saved'), { - duration: 3 - }); - } - - componentDidMount() { - if (trafficOverLimit == 'True') { - toaster.danger(gettext('File download is disabled: the share link traffic of owner is used up.'), { - duration: 3 - }); - } - } - - getContent() { - if (err) { - let errorMsg; - if (err == 'File preview unsupported') { - errorMsg =

{gettext('Online view is not applicable to this file format')}

; - } else { - errorMsg =

{err}

; - } - return ( -
-
- {errorMsg} -
-
- ); - } else { - return ( -
-
- {fileName} -
-
- ); - } - } - render() { - return ( -
-
- - - logo - - - { loginUser && } -
-
-
-
-

{fileName}

-

{gettext('Shared by:')}{' '}{sharedBy}

-
- {download && -
- {(loginUser && loginUser !== sharedBy) && - - }{' '} - {(trafficOverLimit === 'False') && - - } -
- } -
- {this.getContent()} -
- {this.state.showSaveSharedFileDialog && - - } -
- ); + return } />; } } -if (enableWatermark) { - let watermark_txt; - if (loginUser) { - watermark_txt = siteName + ' ' + loginUser; - } else { - watermark_txt = gettext('Anonymous User'); +class FileContent extends React.Component { + render() { + if (err) { + return ; + } + + return ( +
+
+ {fileName} +
+
+ ); } - watermark.init({ - watermark_txt: watermark_txt, - watermark_alpha: 0.075 - }); } ReactDOM.render( diff --git a/frontend/src/shared-file-view-markdown.js b/frontend/src/shared-file-view-markdown.js index 96b798b29f..3e0542f4c4 100644 --- a/frontend/src/shared-file-view-markdown.js +++ b/frontend/src/shared-file-view-markdown.js @@ -1,53 +1,31 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Account from './components/common/account'; -import { serviceURL, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; -import { Button } from 'reactstrap'; import { seafileAPI } from './utils/seafile-api'; import { Utils } from './utils/utils'; +import { serviceURL } from './utils/constants'; +import SharedFileView from './components/shared-file-view/shared-file-view'; +import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip'; import Loading from './components/loading'; -import SaveSharedFileDialog from './components/dialog/save-shared-file-dialog'; -import toaster from './components/toast'; -import watermark from 'watermark-dom'; import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer'; -import './css/shared-file-view.css'; -import './assets/css/fa-solid.css'; -import './assets/css/fa-regular.css'; -import './assets/css/fontawesome.css'; - -let loginUser = window.app.pageOptions.name; -const { repoID, sharedToken, trafficOverLimit, fileName, fileSize, rawPath, sharedBy, siteName, enableWatermark, download } = window.shared.pageOptions; +const { repoID, sharedToken, rawPath, err } = window.shared.pageOptions; class SharedFileViewMarkdown extends React.Component { + render() { + return } />; + } +} + +class FileContent extends React.Component { constructor(props) { super(props); this.state = { markdownContent: '', - loading: true, - showSaveSharedFileDialog: false, + loading: !err }; } - handleSaveSharedFileDialog = () => { - this.setState({ - showSaveSharedFileDialog: true - }); - } - - toggleCancel = () => { - this.setState({ - showSaveSharedFileDialog: false - }); - } - - handleSaveSharedFile = () => { - toaster.success(gettext('Successfully saved'), { - duration: 3 - }); - } - componentDidMount() { seafileAPI.getFileContent(rawPath).then((res) => { this.setState({ @@ -55,11 +33,6 @@ class SharedFileViewMarkdown extends React.Component { loading: false }); }); - if (trafficOverLimit == 'True') { - toaster.danger(gettext('File download is disabled: the share link traffic of owner is used up.'), { - duration: 3 - }); - } } changeImageURL = (innerNode) => { @@ -90,79 +63,31 @@ class SharedFileViewMarkdown extends React.Component { } render() { + if (err) { + return ; + } + if (this.state.loading) { return ; } + return ( -
-
- - - logo - - - { loginUser && } -
-
-
-
-

{fileName}

-

{gettext('Shared by:')}{' '}{sharedBy}

-
- {download && -
- {(loginUser && loginUser !== sharedBy) && - - }{' '} - {(trafficOverLimit === 'False') && - - } -
- } -
-
-
- -
-
-
- {this.state.showSaveSharedFileDialog && - +
+ - } +
); } } -if (enableWatermark) { - let watermark_txt; - if (loginUser) { - watermark_txt = siteName + ' ' + loginUser; - } else { - watermark_txt = gettext('Anonymous User'); - } - watermark.init({ - watermark_txt: watermark_txt, - watermark_alpha: 0.075 - }); -} - ReactDOM.render ( , document.getElementById('wrapper') diff --git a/frontend/src/shared-file-view-pdf.js b/frontend/src/shared-file-view-pdf.js index df556057af..11eedc0e89 100644 --- a/frontend/src/shared-file-view-pdf.js +++ b/frontend/src/shared-file-view-pdf.js @@ -1,140 +1,34 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Account from './components/common/account'; -import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; -import { Button } from 'reactstrap'; -import { Utils } from './utils/utils'; -import SaveSharedFileDialog from './components/dialog/save-shared-file-dialog'; +import SharedFileView from './components/shared-file-view/shared-file-view'; +import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip'; import PDFViewer from './components/pdf-viewer'; -import toaster from './components/toast'; -import watermark from 'watermark-dom'; -import './css/shared-file-view.css'; import './css/pdf-file-view.css'; -let loginUser = window.app.pageOptions.name; -const { repoID, sharedToken, trafficOverLimit, fileName, fileSize, rawPath, sharedBy, siteName, enableWatermark, download, err } = window.shared.pageOptions; - -class SharedFileViewImage extends React.Component { - - constructor(props) { - super(props); - this.state = { - showSaveSharedFileDialog: false - }; - } - - handleSaveSharedFileDialog = () => { - this.setState({ - showSaveSharedFileDialog: true - }); - } - - toggleCancel = () => { - this.setState({ - showSaveSharedFileDialog: false - }); - } - - handleSaveSharedFile = () => { - toaster.success(gettext('Successfully saved'), { - duration: 3 - }); - } - - componentDidMount() { - if (trafficOverLimit == 'True') { - toaster.danger(gettext('File download is disabled: the share link traffic of owner is used up.'), { - duration: 3 - }); - } - } - - getContent() { - if (err) { - let errorMsg; - if (err == 'File preview unsupported') { - errorMsg =

{gettext('Online view is not applicable to this file format')}

; - } else { - errorMsg =

{err}

; - } - return ( -
-
- {errorMsg} -
-
- ); - } else { - return ( -
- -
- ); - } - } +const { err } = window.shared.pageOptions; +class SharedFileViewPDF extends React.Component { render() { + return } />; + } +} + +class FileContent extends React.Component { + render() { + if (err) { + return ; + } + return ( -
-
- - - logo - - - { loginUser && } -
-
-
-
-

{fileName}

-

{gettext('Shared by:')}{' '}{sharedBy}

-
- {download && -
- {(loginUser && loginUser !== sharedBy) && - - }{' '} - {(trafficOverLimit === 'False') && - - } -
- } -
- {this.getContent()} -
- {this.state.showSaveSharedFileDialog && - - } +
+
); } } -if (enableWatermark) { - let watermark_txt; - if (loginUser) { - watermark_txt = siteName + ' ' + loginUser; - } else { - watermark_txt = gettext('Anonymous User'); - } - watermark.init({ - watermark_txt: watermark_txt, - watermark_alpha: 0.075 - }); -} - ReactDOM.render( - , + , document.getElementById('wrapper') ); diff --git a/frontend/src/shared-file-view-text.js b/frontend/src/shared-file-view-text.js index 7ef2a54b56..ff3f84d40b 100644 --- a/frontend/src/shared-file-view-text.js +++ b/frontend/src/shared-file-view-text.js @@ -1,16 +1,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Account from './components/common/account'; -import CodeMirror from 'react-codemirror'; -import { Button } from 'reactstrap'; import { Utils } from './utils/utils'; -import watermark from 'watermark-dom'; -import SaveSharedFileDialog from './components/dialog/save-shared-file-dialog'; -import toaster from './components/toast'; -import { serviceURL, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants'; +import SharedFileView from './components/shared-file-view/shared-file-view'; +import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip'; -import 'codemirror/lib/codemirror.css'; -import './css/shared-file-view.css'; +import CodeMirror from 'react-codemirror'; import 'codemirror/mode/javascript/javascript'; import 'codemirror/mode/css/css'; import 'codemirror/mode/clike/clike'; @@ -21,133 +15,48 @@ import 'codemirror/mode/xml/xml'; import 'codemirror/mode/go/go'; import 'codemirror/mode/python/python'; import 'codemirror/mode/htmlmixed/htmlmixed'; +import 'codemirror/lib/codemirror.css'; -const loginUser = window.app.pageOptions.name; -const { trafficOverLimit, fileName, fileSize, sharedBy, siteName, enableWatermark, download, encoding, fileContent, sharedToken, fileEncodingList, err, fileext } = window.shared.pageOptions; -const URL = require('url-parse'); +import './css/text-file-view.css'; -const options={ - lineNumbers: false, - mode: Utils.chooseLanguage(fileext), +const { err, fileExt, fileContent } = window.shared.pageOptions; + +const options = { + lineNumbers: true, + mode: Utils.chooseLanguage(fileExt), extraKeys: {'Ctrl': 'autocomplete'}, theme: 'default', - autoMatchParens: true, textWrapping: true, lineWrapping: true, - readOnly: 'nocursor', + readOnly: true, + cursorBlinkRate: -1 // hide the cursor }; class SharedFileViewText extends React.Component { - - constructor(props) { - super(props); - this.state = { - showSaveSharedFileDialog: false, - }; - } - - changeEncode = (e) => { - let url = new URL(serviceURL) + '/f/' + sharedToken + '/?file_enc=' + e.target.value; - window.location.href = url.toString(); - } - - fileEncode = () => { - const list = fileEncodingList.substring(1, fileEncodingList.length - 1).replace(/\'*/g,'').replace(/\s*/g,'').split(','); - return ( -
- - -
- ); - } - - handleSaveSharedFileDialog = () => { - this.setState({ - showSaveSharedFileDialog: !this.state.showSaveSharedFileDialog - }); - } - - saveFileSuccess = () => { - let msg = gettext('Successfully saved {fileName}.'); - msg = msg.replace('{fileName}', fileName); - toaster.success(msg); - } - render() { + return } />; + } +} + +class FileContent extends React.Component { + render() { + if (err) { + return ; + } + return ( -
-
- - - logo - - - { loginUser && } -
-
-
-
-

{fileName}

-

{gettext('Shared by:')}{' '}{sharedBy}

-
- {download && -
- {(loginUser && loginUser !== sharedBy) && - - }{' '} - {(trafficOverLimit === 'False') && - - } -
- } -
-
- {this.fileEncode()} -
- { err ?
{err}
: - } - { this.state.showSaveSharedFileDialog && - - } -
-
-
+
+
); } } -if (enableWatermark) { - let watermark_txt; - if (loginUser) { - watermark_txt = siteName + ' ' + loginUser; - } else { - watermark_txt = gettext('Anonymous User'); - } - watermark.init({ - watermark_txt: watermark_txt, - watermark_alpha: 0.075 - }); -} - -ReactDOM.render ( +ReactDOM.render( , document.getElementById('wrapper') ); diff --git a/seahub/templates/shared_file_view_react.html b/seahub/templates/shared_file_view_react.html index e4c93ad27b..98db73858c 100644 --- a/seahub/templates/shared_file_view_react.html +++ b/seahub/templates/shared_file_view_react.html @@ -36,7 +36,7 @@ encoding: '{{ encoding }}', fileContent: '{{ file_content|escapejs }}', err: '{{ err }}', - fileext: '{{ fileext }}', + fileExt: '{{ fileext }}', } };