diff --git a/frontend/config/webpack.config.dev.js b/frontend/config/webpack.config.dev.js index c47821f64c..f09b149e95 100644 --- a/frontend/config/webpack.config.dev.js +++ b/frontend/config/webpack.config.dev.js @@ -139,6 +139,11 @@ module.exports = { require.resolve('react-dev-utils/webpackHotDevClient'), paths.appSrc + "/view-file-svg.js", ], + viewFileAudio: [ + require.resolve('./polyfills'), + require.resolve('react-dev-utils/webpackHotDevClient'), + paths.appSrc + "/view-file-audio.js", + ], orgAdmin: [ require.resolve('./polyfills'), require.resolve('react-dev-utils/webpackHotDevClient'), diff --git a/frontend/config/webpack.config.prod.js b/frontend/config/webpack.config.prod.js index b5e7dbc37f..65be6a4430 100644 --- a/frontend/config/webpack.config.prod.js +++ b/frontend/config/webpack.config.prod.js @@ -76,6 +76,7 @@ module.exports = { viewFileVideo: [require.resolve('./polyfills'), paths.appSrc + "/view-file-video.js"], viewFilePDF: [require.resolve('./polyfills'), paths.appSrc + "/view-file-pdf.js"], viewFileSVG: [require.resolve('./polyfills'), paths.appSrc + "/view-file-svg.js"], + viewFileAudio: [require.resolve('./polyfills'), paths.appSrc + "/view-file-audio.js"], orgAdmin: [require.resolve('./polyfills'), paths.appSrc + "/pages/org-admin"], viewFileUMind: [require.resolve('./polyfills'), paths.appSrc + "/view-file-umind.js"], sysAdmin: [require.resolve('./polyfills'), paths.appSrc + "/pages/sys-admin"], diff --git a/frontend/src/components/audio-player.js b/frontend/src/components/audio-player.js new file mode 100644 index 0000000000..0ae8221f22 --- /dev/null +++ b/frontend/src/components/audio-player.js @@ -0,0 +1,32 @@ +import React from 'react'; + +import videojs from 'video.js'; +import 'video.js/dist/video-js.css'; + +class AudioPlayer extends React.Component { + componentDidMount() { + // instantiate Video.js + this.player = videojs(this.videoNode, this.props, function onPlayerReady() { + }); + } + + // destroy player on unmount + componentWillUnmount() { + if (this.player) { + this.player.dispose(); + } + } + + // wrap the player in a div with a `data-vjs-player` attribute + // so videojs won't create additional wrapper in the DOM + // see https://github.com/videojs/video.js/pull/3856 + render() { + return ( +
+ +
+ ); + } +} + +export default AudioPlayer; diff --git a/frontend/src/css/audio-file-view.css b/frontend/src/css/audio-file-view.css new file mode 100644 index 0000000000..d19f016367 --- /dev/null +++ b/frontend/src/css/audio-file-view.css @@ -0,0 +1,9 @@ +.video-js { + width: calc(100% - 40px); + max-width: 500px; + height: 30px; + margin: 0 auto; +} +.video-js .vjs-fullscreen-control { + display: none; +} diff --git a/frontend/src/view-file-audio.js b/frontend/src/view-file-audio.js new file mode 100644 index 0000000000..dbc5dabada --- /dev/null +++ b/frontend/src/view-file-audio.js @@ -0,0 +1,133 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import watermark from 'watermark-dom'; +import { seafileAPI } from './utils/seafile-api'; +import { siteName } from './utils/constants'; +import FileInfo from './components/file-view/file-info'; +import FileToolbar from './components/file-view/file-toolbar'; +import FileViewTip from './components/file-view/file-view-tip'; +import CommentPanel from './components/file-view/comment-panel'; +import AudioPlayer from './components/audio-player'; + +import './css/file-view.css'; +import './css/audio-file-view.css'; + +const { isStarred, isLocked, lockedByMe, + repoID, filePath, err, enableWatermark, userNickName, + // the following are only for this type of file view + rawPath +} = window.app.pageOptions; + +class ViewFileAudio extends React.Component { + + constructor(props) { + super(props); + this.state = { + isStarred: isStarred, + isLocked: isLocked, + lockedByMe: lockedByMe, + isCommentPanelOpen: false + }; + } + + toggleCommentPanel = () => { + this.setState({ + isCommentPanelOpen: !this.state.isCommentPanelOpen + }); + } + + toggleStar = () => { + if (this.state.isStarred) { + seafileAPI.unStarItem(repoID, filePath).then((res) => { + this.setState({ + isStarred: false + }); + }); + } else { + seafileAPI.starItem(repoID, filePath).then((res) => { + this.setState({ + isStarred: true + }); + }); + } + } + + toggleLockFile = () => { + if (this.state.isLocked) { + seafileAPI.unlockfile(repoID, filePath).then((res) => { + this.setState({ + isLocked: false, + lockedByMe: false + }); + }); + } else { + seafileAPI.lockfile(repoID, filePath).then((res) => { + this.setState({ + isLocked: true, + lockedByMe: true + }); + }); + } + } + + render() { + return ( +
+
+ + +
+
+ + {this.state.isCommentPanelOpen && + + } +
+
+ ); + } +} + +class FileContent extends React.Component { + + render() { + if (err) { + return ; + } + + const videoJsOptions = { + autoplay: false, + controls: true, + preload: 'auto', + sources: [{ + src: rawPath + }] + }; + return ( +
+ +
+ ); + } +} + +if (enableWatermark) { + watermark.init({ + watermark_txt: `${siteName} ${userNickName}`, + watermark_alpha: 0.075 + }); +} + +ReactDOM.render ( + , + document.getElementById('wrapper') +); diff --git a/frontend/src/view-file-video.js b/frontend/src/view-file-video.js index e485327ede..84e16cc519 100644 --- a/frontend/src/view-file-video.js +++ b/frontend/src/view-file-video.js @@ -113,7 +113,7 @@ class FileContent extends React.Component { }] }; return ( -
+
); diff --git a/seahub/templates/audio_file_view_react.html b/seahub/templates/audio_file_view_react.html new file mode 100644 index 0000000000..a919bd01d0 --- /dev/null +++ b/seahub/templates/audio_file_view_react.html @@ -0,0 +1,15 @@ +{% extends 'file_view_react.html' %} +{% load render_bundle from webpack_loader %} +{% load seahub_tags %} + +{% block extra_style %} +{% render_bundle 'viewFileAudio' 'css' %} +{% endblock %} + +{% block extra_data %} + rawPath: '{{ raw_path|escapejs }}' +{% endblock %} + +{% block render_bundle %} +{% render_bundle 'viewFileAudio' 'js' %} +{% endblock %} diff --git a/seahub/views/file.py b/seahub/views/file.py index 4b45b1226c..3a42101174 100644 --- a/seahub/views/file.py +++ b/seahub/views/file.py @@ -697,8 +697,7 @@ def view_lib_file(request, repo_id, path): return_dict['raw_path'] = raw_path send_file_access_msg(request, repo, path, 'web') - if filetype in (VIDEO, PDF, SVG): - template = '%s_file_view_react.html' % filetype.lower() + template = '%s_file_view_react.html' % filetype.lower() return render(request, template, return_dict) elif filetype == DRAW: