mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 15:38:15 +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:
@@ -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;
|
117
frontend/src/components/shared-file-view/shared-file-view.js
Normal file
117
frontend/src/components/shared-file-view/shared-file-view.js
Normal 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;
|
@@ -67,34 +67,6 @@
|
|||||||
overflow: auto;
|
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) {
|
@media (max-width: 991.98px) {
|
||||||
.shared-file-view-head {
|
.shared-file-view-head {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@@ -1,138 +1,32 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Account from './components/common/account';
|
import SharedFileView from './components/shared-file-view/shared-file-view';
|
||||||
import { serviceURL, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants';
|
import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip';
|
||||||
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 './css/shared-file-view.css';
|
|
||||||
import './css/image-file-view.css';
|
import './css/image-file-view.css';
|
||||||
|
|
||||||
let loginUser = window.app.pageOptions.name;
|
const { fileName, rawPath, err } = window.shared.pageOptions;
|
||||||
const { repoID, sharedToken, trafficOverLimit, fileName, fileSize, rawPath, sharedBy, siteName, enableWatermark, download, err } = window.shared.pageOptions;
|
|
||||||
|
|
||||||
class SharedFileViewImage extends React.Component {
|
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() {
|
render() {
|
||||||
return (
|
return <SharedFileView content={<FileContent />} />;
|
||||||
<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>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableWatermark) {
|
class FileContent extends React.Component {
|
||||||
let watermark_txt;
|
render() {
|
||||||
if (loginUser) {
|
if (err) {
|
||||||
watermark_txt = siteName + ' ' + loginUser;
|
return <SharedFileViewTip />;
|
||||||
} else {
|
}
|
||||||
watermark_txt = gettext('Anonymous User');
|
|
||||||
|
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(
|
ReactDOM.render(
|
||||||
|
@@ -1,53 +1,31 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
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 { seafileAPI } from './utils/seafile-api';
|
||||||
import { Utils } from './utils/utils';
|
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 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 MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer';
|
||||||
|
|
||||||
import './css/shared-file-view.css';
|
const { repoID, sharedToken, rawPath, err } = window.shared.pageOptions;
|
||||||
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;
|
|
||||||
|
|
||||||
class SharedFileViewMarkdown extends React.Component {
|
class SharedFileViewMarkdown extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <SharedFileView content={<FileContent />} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileContent extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
markdownContent: '',
|
markdownContent: '',
|
||||||
loading: true,
|
loading: !err
|
||||||
showSaveSharedFileDialog: false,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSaveSharedFileDialog = () => {
|
|
||||||
this.setState({
|
|
||||||
showSaveSharedFileDialog: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCancel = () => {
|
|
||||||
this.setState({
|
|
||||||
showSaveSharedFileDialog: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSaveSharedFile = () => {
|
|
||||||
toaster.success(gettext('Successfully saved'), {
|
|
||||||
duration: 3
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
seafileAPI.getFileContent(rawPath).then((res) => {
|
seafileAPI.getFileContent(rawPath).then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -55,11 +33,6 @@ class SharedFileViewMarkdown extends React.Component {
|
|||||||
loading: false
|
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) => {
|
changeImageURL = (innerNode) => {
|
||||||
@@ -90,79 +63,31 @@ class SharedFileViewMarkdown extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (err) {
|
||||||
|
return <SharedFileViewTip />;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shared-file-view-md">
|
<div className="shared-file-view-body">
|
||||||
<div className="shared-file-view-md-header d-flex">
|
<div className="md-view">
|
||||||
<React.Fragment>
|
<MarkdownViewer
|
||||||
<a href={siteRoot}>
|
markdownContent={this.state.markdownContent}
|
||||||
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
|
showTOC={false}
|
||||||
</a>
|
serviceURL={serviceURL}
|
||||||
</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}
|
|
||||||
sharedToken={sharedToken}
|
sharedToken={sharedToken}
|
||||||
toggleCancel={this.toggleCancel}
|
repoID={repoID}
|
||||||
handleSaveSharedFile={this.handleSaveSharedFile}
|
modifyValueBeforeRender={this.modifyValueBeforeRender}
|
||||||
/>
|
/>
|
||||||
}
|
</div>
|
||||||
</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 (
|
ReactDOM.render (
|
||||||
<SharedFileViewMarkdown />,
|
<SharedFileViewMarkdown />,
|
||||||
document.getElementById('wrapper')
|
document.getElementById('wrapper')
|
||||||
|
@@ -1,140 +1,34 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Account from './components/common/account';
|
import SharedFileView from './components/shared-file-view/shared-file-view';
|
||||||
import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants';
|
import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip';
|
||||||
import { Button } from 'reactstrap';
|
|
||||||
import { Utils } from './utils/utils';
|
|
||||||
import SaveSharedFileDialog from './components/dialog/save-shared-file-dialog';
|
|
||||||
import PDFViewer from './components/pdf-viewer';
|
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';
|
import './css/pdf-file-view.css';
|
||||||
|
|
||||||
let loginUser = window.app.pageOptions.name;
|
const { err } = window.shared.pageOptions;
|
||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
class SharedFileViewPDF extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
|
return <SharedFileView content={<FileContent />} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileContent extends React.Component {
|
||||||
|
render() {
|
||||||
|
if (err) {
|
||||||
|
return <SharedFileViewTip />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shared-file-view-md">
|
<div className="shared-file-view-body pdf-file-view">
|
||||||
<div className="shared-file-view-md-header d-flex">
|
<PDFViewer />
|
||||||
<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>
|
</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(
|
||||||
<SharedFileViewImage />,
|
<SharedFileViewPDF />,
|
||||||
document.getElementById('wrapper')
|
document.getElementById('wrapper')
|
||||||
);
|
);
|
||||||
|
@@ -1,16 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
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 { Utils } from './utils/utils';
|
||||||
import watermark from 'watermark-dom';
|
import SharedFileView from './components/shared-file-view/shared-file-view';
|
||||||
import SaveSharedFileDialog from './components/dialog/save-shared-file-dialog';
|
import SharedFileViewTip from './components/shared-file-view/shared-file-view-tip';
|
||||||
import toaster from './components/toast';
|
|
||||||
import { serviceURL, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants';
|
|
||||||
|
|
||||||
import 'codemirror/lib/codemirror.css';
|
import CodeMirror from 'react-codemirror';
|
||||||
import './css/shared-file-view.css';
|
|
||||||
import 'codemirror/mode/javascript/javascript';
|
import 'codemirror/mode/javascript/javascript';
|
||||||
import 'codemirror/mode/css/css';
|
import 'codemirror/mode/css/css';
|
||||||
import 'codemirror/mode/clike/clike';
|
import 'codemirror/mode/clike/clike';
|
||||||
@@ -21,133 +15,48 @@ import 'codemirror/mode/xml/xml';
|
|||||||
import 'codemirror/mode/go/go';
|
import 'codemirror/mode/go/go';
|
||||||
import 'codemirror/mode/python/python';
|
import 'codemirror/mode/python/python';
|
||||||
import 'codemirror/mode/htmlmixed/htmlmixed';
|
import 'codemirror/mode/htmlmixed/htmlmixed';
|
||||||
|
import 'codemirror/lib/codemirror.css';
|
||||||
|
|
||||||
const loginUser = window.app.pageOptions.name;
|
import './css/text-file-view.css';
|
||||||
const { trafficOverLimit, fileName, fileSize, sharedBy, siteName, enableWatermark, download, encoding, fileContent, sharedToken, fileEncodingList, err, fileext } = window.shared.pageOptions;
|
|
||||||
const URL = require('url-parse');
|
|
||||||
|
|
||||||
const options={
|
const { err, fileExt, fileContent } = window.shared.pageOptions;
|
||||||
lineNumbers: false,
|
|
||||||
mode: Utils.chooseLanguage(fileext),
|
const options = {
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: Utils.chooseLanguage(fileExt),
|
||||||
extraKeys: {'Ctrl': 'autocomplete'},
|
extraKeys: {'Ctrl': 'autocomplete'},
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
autoMatchParens: true,
|
|
||||||
textWrapping: true,
|
textWrapping: true,
|
||||||
lineWrapping: true,
|
lineWrapping: true,
|
||||||
readOnly: 'nocursor',
|
readOnly: true,
|
||||||
|
cursorBlinkRate: -1 // hide the cursor
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedFileViewText extends React.Component {
|
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() {
|
render() {
|
||||||
|
return <SharedFileView content={<FileContent />} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileContent extends React.Component {
|
||||||
|
render() {
|
||||||
|
if (err) {
|
||||||
|
return <SharedFileViewTip />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shared-file-view-md">
|
<div className="shared-file-view-body text-file-view">
|
||||||
<div className="shared-file-view-md-header d-flex">
|
<CodeMirror
|
||||||
<React.Fragment>
|
ref="code-mirror-editor"
|
||||||
<a href={siteRoot}>
|
value={fileContent}
|
||||||
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo"/>
|
options={options}
|
||||||
</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableWatermark) {
|
ReactDOM.render(
|
||||||
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 (
|
|
||||||
<SharedFileViewText />,
|
<SharedFileViewText />,
|
||||||
document.getElementById('wrapper')
|
document.getElementById('wrapper')
|
||||||
);
|
);
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
encoding: '{{ encoding }}',
|
encoding: '{{ encoding }}',
|
||||||
fileContent: '{{ file_content|escapejs }}',
|
fileContent: '{{ file_content|escapejs }}',
|
||||||
err: '{{ err }}',
|
err: '{{ err }}',
|
||||||
fileext: '{{ fileext }}',
|
fileExt: '{{ fileext }}',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
Reference in New Issue
Block a user