1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-02 07:27:04 +00:00

[shared file view] code improvement (#3185)

* added component shared-file-view.js & shared-file-view-tip.js
* modified 'text file view'
This commit is contained in:
llj
2019-03-28 10:59:43 +08:00
committed by Daniel Pan
parent 7d5721bb64
commit 61fc8c20dc
8 changed files with 230 additions and 495 deletions

View File

@@ -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 = <p>{gettext('Online view is not applicable to this file format')}</p>;
} else {
errorMsg = <p className="error">{err}</p>;
}
return (
<div className="shared-file-view-body">
<div className="file-view-tip">
{errorMsg}
</div>
</div>
);
}
}
export default SharedFileViewTip;

View File

@@ -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 (
<div className="shared-file-view-md">
<div className="shared-file-view-md-header d-flex">
<React.Fragment>
<a href={siteRoot}>
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
</a>
</React.Fragment>
{ loginUser && <Account /> }
</div>
<div className="shared-file-view-md-main">
<div className="shared-file-view-head">
<div className="float-left">
<h2 className="ellipsis" title={fileName}>{fileName}</h2>
<p className="share-by ellipsis">{gettext('Shared by:')}{' '}{sharedBy}</p>
</div>
{download &&
<div className="float-right">
{(loginUser && loginUser !== sharedBy) &&
<Button color="secondary" id="save" className="shared-file-op-btn"
onClick={this.handleSaveSharedFileDialog}>{gettext('Save as ...')}
</Button>
}{' '}
{(trafficOverLimit === 'False') &&
<Button color="success" className="shared-file-op-btn">
<a href="?dl=1">{gettext('Download')}({Utils.bytesToSize(fileSize)})</a>
</Button>
}
</div>
}
</div>
{this.props.content}
</div>
{this.state.showSaveSharedFileDialog &&
<SaveSharedFileDialog
repoID={repoID}
sharedToken={sharedToken}
toggleCancel={this.toggleCancel}
handleSaveSharedFile={this.handleSaveSharedFile}
/>
}
</div>
);
}
}
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;

View File

@@ -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%;

View File

@@ -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 = <p>{gettext('Online view is not applicable to this file format')}</p>;
} else {
errorMsg = <p className="error">{err}</p>;
}
return (
<div className="shared-file-view-body">
<div className="file-view-tip">
{errorMsg}
</div>
</div>
);
} else {
return (
<div className="shared-file-view-body d-flex text-center">
<div className="image-file-view flex-1">
<img src={rawPath} alt={fileName} id="image-view" />
</div>
</div>
);
}
}
render() {
return (
<div className="shared-file-view-md">
<div className="shared-file-view-md-header d-flex">
<React.Fragment>
<a href={siteRoot}>
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
</a>
</React.Fragment>
{ loginUser && <Account /> }
</div>
<div className="shared-file-view-md-main">
<div className="shared-file-view-head">
<div className="float-left">
<h2 className="ellipsis" title={fileName}>{fileName}</h2>
<p className="share-by ellipsis">{gettext('Shared by:')}{' '}{sharedBy}</p>
</div>
{download &&
<div className="float-right">
{(loginUser && loginUser !== sharedBy) &&
<Button color="secondary" id="save" className="shared-file-op-btn"
onClick={this.handleSaveSharedFileDialog}>{gettext('Save as ...')}
</Button>
}{' '}
{(trafficOverLimit === 'False') &&
<Button color="success" className="shared-file-op-btn">
<a href="?dl=1">{gettext('Download')}({Utils.bytesToSize(fileSize)})</a>
</Button>
}
</div>
}
</div>
{this.getContent()}
</div>
{this.state.showSaveSharedFileDialog &&
<SaveSharedFileDialog
repoID={repoID}
sharedToken={sharedToken}
toggleCancel={this.toggleCancel}
handleSaveSharedFile={this.handleSaveSharedFile}
/>
}
</div>
);
return <SharedFileView content={<FileContent />} />;
}
}
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 <SharedFileViewTip />;
}
return (
<div className="shared-file-view-body d-flex text-center">
<div className="image-file-view flex-1">
<img src={rawPath} alt={fileName} id="image-view" />
</div>
</div>
);
}
watermark.init({
watermark_txt: watermark_txt,
watermark_alpha: 0.075
});
}
ReactDOM.render(

View File

@@ -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 <SharedFileView content={<FileContent />} />;
}
}
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 <SharedFileViewTip />;
}
if (this.state.loading) {
return <Loading />;
}
return (
<div className="shared-file-view-md">
<div className="shared-file-view-md-header d-flex">
<React.Fragment>
<a href={siteRoot}>
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
</a>
</React.Fragment>
{ loginUser && <Account /> }
</div>
<div className="shared-file-view-md-main">
<div className="shared-file-view-head">
<div className="float-left">
<h2 className="ellipsis" title={fileName}>{fileName}</h2>
<p className="share-by ellipsis">{gettext('Shared by:')}{' '}{sharedBy}</p>
</div>
{download &&
<div className="float-right">
{(loginUser && loginUser !== sharedBy) &&
<Button color="secondary" id="save" className="shared-file-op-btn"
onClick={this.handleSaveSharedFileDialog}>{gettext('Save as ...')}
</Button>
}{' '}
{(trafficOverLimit === 'False') &&
<Button color="success" className="shared-file-op-btn">
<a href="?dl=1">{gettext('Download')}({Utils.bytesToSize(fileSize)})</a>
</Button>
}
</div>
}
</div>
<div className="shared-file-view-body">
<div className="md-view">
<MarkdownViewer
markdownContent={this.state.markdownContent}
showTOC={false}
serviceURL={serviceURL}
sharedToken={sharedToken}
repoID={repoID}
modifyValueBeforeRender={this.modifyValueBeforeRender}
/>
</div>
</div>
</div>
{this.state.showSaveSharedFileDialog &&
<SaveSharedFileDialog
repoID={repoID}
<div className="shared-file-view-body">
<div className="md-view">
<MarkdownViewer
markdownContent={this.state.markdownContent}
showTOC={false}
serviceURL={serviceURL}
sharedToken={sharedToken}
toggleCancel={this.toggleCancel}
handleSaveSharedFile={this.handleSaveSharedFile}
repoID={repoID}
modifyValueBeforeRender={this.modifyValueBeforeRender}
/>
}
</div>
</div>
);
}
}
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 (
<SharedFileViewMarkdown />,
document.getElementById('wrapper')

View File

@@ -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 = <p>{gettext('Online view is not applicable to this file format')}</p>;
} else {
errorMsg = <p className="error">{err}</p>;
}
return (
<div className="shared-file-view-body">
<div className="file-view-tip">
{errorMsg}
</div>
</div>
);
} else {
return (
<div className="shared-file-view-body pdf-file-view">
<PDFViewer />
</div>
);
}
}
const { err } = window.shared.pageOptions;
class SharedFileViewPDF extends React.Component {
render() {
return <SharedFileView content={<FileContent />} />;
}
}
class FileContent extends React.Component {
render() {
if (err) {
return <SharedFileViewTip />;
}
return (
<div className="shared-file-view-md">
<div className="shared-file-view-md-header d-flex">
<React.Fragment>
<a href={siteRoot}>
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
</a>
</React.Fragment>
{ loginUser && <Account /> }
</div>
<div className="shared-file-view-md-main">
<div className="shared-file-view-head">
<div className="float-left">
<h2 className="ellipsis" title={fileName}>{fileName}</h2>
<p className="share-by ellipsis">{gettext('Shared by:')}{' '}{sharedBy}</p>
</div>
{download &&
<div className="float-right">
{(loginUser && loginUser !== sharedBy) &&
<Button color="secondary" id="save" className="shared-file-op-btn"
onClick={this.handleSaveSharedFileDialog}>{gettext('Save as ...')}
</Button>
}{' '}
{(trafficOverLimit === 'False') &&
<Button color="success" className="shared-file-op-btn">
<a href="?dl=1">{gettext('Download')}({Utils.bytesToSize(fileSize)})</a>
</Button>
}
</div>
}
</div>
{this.getContent()}
</div>
{this.state.showSaveSharedFileDialog &&
<SaveSharedFileDialog
repoID={repoID}
sharedToken={sharedToken}
toggleCancel={this.toggleCancel}
handleSaveSharedFile={this.handleSaveSharedFile}
/>
}
<div className="shared-file-view-body pdf-file-view">
<PDFViewer />
</div>
);
}
}
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(
<SharedFileViewImage />,
<SharedFileViewPDF />,
document.getElementById('wrapper')
);

View File

@@ -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 (
<div className="file-enc-cont">
<label htmlFor="file-enc">{gettext('Encoding:')}</label>
<select id="file-enc" onChange={this.changeEncode} defaultValue={encoding}>
{ list && list.map((value, index) => {
if (value === 'auto') {
return (<option value={value} key={index}>{gettext('auto detect')}</option>);
} else {
return (<option value={value} key={index}>{value}</option>);
}
})
}
</select>
</div>
);
}
handleSaveSharedFileDialog = () => {
this.setState({
showSaveSharedFileDialog: !this.state.showSaveSharedFileDialog
});
}
saveFileSuccess = () => {
let msg = gettext('Successfully saved {fileName}.');
msg = msg.replace('{fileName}', fileName);
toaster.success(msg);
}
render() {
return <SharedFileView content={<FileContent />} />;
}
}
class FileContent extends React.Component {
render() {
if (err) {
return <SharedFileViewTip />;
}
return (
<div className="shared-file-view-md">
<div className="shared-file-view-md-header d-flex">
<React.Fragment>
<a href={siteRoot}>
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo"/>
</a>
</React.Fragment>
{ loginUser && <Account /> }
</div>
<div className="shared-file-view-md-main">
<div className="shared-file-view-head">
<div className="float-left">
<h2 className="ellipsis" title={fileName}>{fileName}</h2>
<p className="share-by ellipsis">{gettext('Shared by:')}{' '}{sharedBy}</p>
</div>
{download &&
<div className="float-right">
{(loginUser && loginUser !== sharedBy) &&
<Button color="secondary" id="save" className="shared-file-op-btn"
onClick={this.handleSaveSharedFileDialog}>{gettext('Save as ...')}
</Button>
}{' '}
{(trafficOverLimit === 'False') &&
<Button color="success" className="shared-file-op-btn">
<a href="?dl=1">{gettext('Download')}{' '}({Utils.bytesToSize(parseInt(fileSize))})</a>
</Button>
}
</div>
}
</div>
<div className="shared-file-view-body">
{this.fileEncode()}
<div className="txt-view">
{ err ? <div className="file-view-tip error">{err}</div> :
<CodeMirror ref="editor-sql" value={fileContent} options={options}/>}
{ this.state.showSaveSharedFileDialog &&
<SaveSharedFileDialog
sharedToken={sharedToken}
toggleCancel={this.handleSaveSharedFileDialog}
handleSaveSharedFile={this.saveFileSuccess}
/>
}
</div>
</div>
</div>
<div className="shared-file-view-body text-file-view">
<CodeMirror
ref="code-mirror-editor"
value={fileContent}
options={options}
/>
</div>
);
}
}
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(
<SharedFileViewText />,
document.getElementById('wrapper')
);

View File

@@ -36,7 +36,7 @@
encoding: '{{ encoding }}',
fileContent: '{{ file_content|escapejs }}',
err: '{{ err }}',
fileext: '{{ fileext }}',
fileExt: '{{ fileext }}',
}
};
</script>