1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-03 07:55:36 +00:00

[view history/snapshot/trash file] rewrote them with react

This commit is contained in:
llj
2019-06-25 15:47:43 +08:00
parent c958c1c642
commit 0868add020
22 changed files with 451 additions and 14 deletions

View File

@@ -0,0 +1,26 @@
import React from 'react';
import AudioPlayer from '../audio-player';
import '../../css/audio-file-view.css';
const { rawPath } = window.app.pageOptions;
class FileContent extends React.Component {
render() {
const videoJsOptions = {
autoplay: false,
controls: true,
preload: 'auto',
sources: [{
src: rawPath
}]
};
return (
<div className="file-view-content flex-1 audio-file-view">
<AudioPlayer { ...videoJsOptions } />
</div>
);
}
}
export default FileContent;

View File

@@ -0,0 +1,48 @@
import React from 'react';
import { Utils } from '../../utils/utils';
import { gettext, siteRoot } from '../../utils/constants';
import '../../css/image-file-view.css';
const {
repoID,
fileName, previousImage, nextImage, rawPath
} = window.app.pageOptions;
let previousImageUrl, nextImageUrl;
if (previousImage) {
previousImageUrl = `${siteRoot}lib/${repoID}/file${Utils.encodePath(previousImage)}`;
}
if (nextImage) {
nextImageUrl = `${siteRoot}lib/${repoID}/file${Utils.encodePath(nextImage)}`;
}
class FileContent extends React.Component {
componentDidMount() {
document.addEventListener('keydown', (e) => {
if (previousImage && e.keyCode == 37) { // press '<-'
location.href = previousImageUrl;
}
if (nextImage && e.keyCode == 39) { // press '->'
location.href = nextImageUrl;
}
});
}
render() {
return (
<div className="file-view-content flex-1 image-file-view">
{previousImage && (
<a href={previousImageUrl} id="img-prev" title={gettext('you can also press ← ')}><span className="fas fa-chevron-left"></span></a>
)}
{nextImage && (
<a href={nextImageUrl} id="img-next" title={gettext('you can also press →')}><span className="fas fa-chevron-right"></span></a>
)}
<img src={rawPath} alt={fileName} id="image-view" />
</div>
);
}
}
export default FileContent;

View File

@@ -0,0 +1,23 @@
import React from 'react';
import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer';
import '../../css/md-file-view.css';
const { fileContent } = window.app.pageOptions;
class FileContent extends React.Component {
render() {
return (
<div className="file-view-content flex-1 o-auto">
<div className="md-content">
<MarkdownViewer
markdownContent={fileContent}
showTOC={false}
/>
</div>
</div>
);
}
}
export default FileContent;

View File

@@ -0,0 +1,16 @@
import React from 'react';
import PDFViewer from '../pdf-viewer';
import '../../css/pdf-file-view.css';
class FileContent extends React.Component {
render() {
return (
<div className="file-view-content flex-1 pdf-file-view">
<PDFViewer />
</div>
);
}
}
export default FileContent;

View File

@@ -0,0 +1,19 @@
import React from 'react';
import '../../css/svg-file-view.css';
const {
fileName, rawPath
} = window.app.pageOptions;
class FileContent extends React.Component {
render() {
return (
<div className="file-view-content flex-1 svg-file-view">
<img src={rawPath} alt={fileName} id="svg-view" />
</div>
);
}
}
export default FileContent;

View File

@@ -0,0 +1,48 @@
import React from 'react';
import { Utils } from '../../utils/utils';
import CodeMirror from 'react-codemirror';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/clike/clike';
import 'codemirror/mode/php/php';
import 'codemirror/mode/sql/sql';
import 'codemirror/mode/vue/vue';
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';
import '../../css/text-file-view.css';
const {
fileExt, fileContent
} = window.app.pageOptions;
const options = {
lineNumbers: true,
mode: Utils.chooseLanguage(fileExt),
extraKeys: {'Ctrl': 'autocomplete'},
theme: 'default',
textWrapping: true,
lineWrapping: true,
readOnly: true,
cursorBlinkRate: -1 // hide the cursor
};
class FileContent extends React.Component {
render() {
return (
<div className="file-view-content flex-1 text-file-view">
<CodeMirror
ref="code-mirror-editor"
value={fileContent}
options={options}
/>
</div>
);
}
}
export default FileContent;

View File

@@ -0,0 +1,28 @@
import React from 'react';
import VideoPlayer from '../video-player';
import '../../css/video-file-view.css';
const {
rawPath
} = window.app.pageOptions;
class FileContent extends React.Component {
render() {
const videoJsOptions = {
autoplay: false,
controls: true,
preload: 'auto',
sources: [{
src: rawPath
}]
};
return (
<div className="file-view-content flex-1 video-file-view">
<VideoPlayer { ...videoJsOptions } />
</div>
);
}
}
export default FileContent;

View File

@@ -49,9 +49,9 @@ class FileInfo extends React.PureComponent {
/>
}
</h2>
<div className="last-modification">
<div className="meta-info">
<a href={`${siteRoot}profile/${encodeURIComponent(latestContributor)}/`}>{latestContributorName}</a>
<span className="last-modification-time">{moment(lastModificationTime * 1000).format('YYYY-MM-DD HH:mm')}</span>
<span className="ml-2">{moment(lastModificationTime * 1000).format('YYYY-MM-DD HH:mm')}</span>
</div>
</div>
);

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { gettext, siteRoot } from '../../utils/constants';
const {
fileName, repoID, objID, path
} = window.app.pageOptions;
function Download() {
return (
<a href={`${siteRoot}repo/${repoID}/${objID}/download/?file_name=${encodeURIComponent(fileName)}&p=${encodeURIComponent(path)}`} className="btn btn-secondary">{gettext('Download')}</a>
);
}
export default Download;

View File

@@ -0,0 +1,34 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import Download from './download';
const propTypes = {
err: PropTypes.string
};
const { canDownloadFile, err } = window.app.pageOptions;
const UNSUPPORTED = 'File preview unsupported';
class FileViewTip extends React.Component {
render() {
let errorMsg;
if (err == UNSUPPORTED || this.props.err == UNSUPPORTED) {
errorMsg = <p>{gettext('Online view is not applicable to this file format')}</p>;
} else {
errorMsg = <p className="error">{err}</p>;
}
return (
<div className="file-view-content flex-1 o-auto">
<div className="file-view-tip">
{errorMsg}
{canDownloadFile && <Download />}
</div>
</div>
);
}
}
FileViewTip.propTypes = propTypes;
export default FileViewTip;

View File

@@ -0,0 +1,54 @@
import React from 'react';
import PropTypes from 'prop-types';
import watermark from 'watermark-dom';
import { gettext, siteName } from '../../utils/constants';
import Download from './download';
import '../../css/file-view.css';
const propTypes = {
content: PropTypes.object.isRequired
};
const {
fromTrash,
fileName, commitTime,
canDownloadFile,
enableWatermark, userNickName
} = window.app.pageOptions;
class FileView extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="h-100 d-flex flex-column">
<div className="file-view-header d-flex justify-content-between align-items-center">
<div>
<h2 className="file-title">{fileName}</h2>
<p className="meta-info m-0">{fromTrash ? `${gettext('Current Path: ')}${gettext('Trash')}`: commitTime}</p>
</div>
{canDownloadFile && <Download />}
</div>
<div className="file-view-body flex-auto d-flex o-hidden">
{this.props.content}
</div>
</div>
);
}
}
if (enableWatermark) {
watermark.init({
watermark_txt: `${siteName} ${userNickName}`,
watermark_alpha: 0.075
});
}
FileView.propTypes = propTypes;
export default FileView;