diff --git a/frontend/src/components/markdown-viewer.js b/frontend/src/components/markdown-viewer.js deleted file mode 100644 index 1ff467b22a..0000000000 --- a/frontend/src/components/markdown-viewer.js +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer'; - -const gettext = window.gettext; - -const viewerPropTypes = { - isFileLoading: PropTypes.bool.isRequired, - lastModified: PropTypes.string, - latestContributor: PropTypes.string, - markdownContent: PropTypes.string, - onContentRendered: PropTypes.func.isRequired, - activeTitleIndex: PropTypes.number, - onLinkClick: PropTypes.func, - reviewStatus: PropTypes.string, - goReviewPage: PropTypes.func, - isDraft: PropTypes.bool, - hasDraft: PropTypes.bool, - goDraftPage: PropTypes.func, -}; - -const contentClass = 'markdown-content'; - -class MarkdownContentViewer extends React.Component { - - constructor(props) { - super(props); - this.state = { - showReviewTip: false, - showDraftTip: false, - }; - } - - componentDidUpdate () { - var links = document.querySelectorAll(`.${contentClass} a`); - links.forEach((li) => {li.addEventListener('click', this.onLinkClick); }); - } - - onLinkClick = (event) => { - event.preventDefault(); - let link = ''; - if (event.target.tagName !== 'A') { - let target = event.target.parentNode; - while (target.tagName !== 'A') { - target = target.parentNode; - } - link = target.href; - } else { - link = event.target.href; - } - this.props.onLinkClick(link); - } - - render() { - if (this.props.isFileLoading) { - return ( - - ); - } - return ( -
- {this.props.reviewStatus === 'open' && -
-
- {gettext('This file is in review stage')} - {gettext('View Review')} -
-
- } - - {(!this.props.isDraft && this.props.hasDraft && this.props.reviewStatus !== 'open') && -
-
- {gettext('This file is in draft stage.')} - {gettext('Edit Draft')} -
-
- } - - -

{gettext('Last modified by')} {this.props.latestContributor}, {this.props.lastModified}

-
- ); - } -} - -MarkdownContentViewer.propTypes = viewerPropTypes; - -export default MarkdownContentViewer; diff --git a/frontend/src/components/wiki-markdown-viewer.js b/frontend/src/components/wiki-markdown-viewer.js new file mode 100644 index 0000000000..847a8794ed --- /dev/null +++ b/frontend/src/components/wiki-markdown-viewer.js @@ -0,0 +1,114 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer'; +import { gettext } from '../utils/constants'; +import Loading from './loading'; + +const propTypes = { + children: PropTypes.object, + isFileLoading: PropTypes.bool.isRequired, + markdownContent: PropTypes.string.isRequired, + latestContributor: PropTypes.string.isRequired, + lastModified: PropTypes.string.isRequired, + onLinkClick: PropTypes.func.isRequired +}; + +const contentClass = 'wiki-page-content'; + +class WikiMarkdownViewer extends React.Component { + + constructor(props) { + super(props); + this.state = { + activeTitleIndex: 0 + }; + this.markdownContainer = React.createRef(); + this.links = []; + this.titlesInfo = []; + } + + componentDidUpdate() { + if (!this.links.length) { + this.links = document.querySelectorAll(`.${contentClass} a`); + this.links.forEach(link => { + link.addEventListener('click', this.onLinkClick); + }); + } + } + + componentWillUnmount() { + if (this.links) { + this.links.forEach(link => { + link.removeEventListener('click', this.onLinkClick); + }); + } + } + + onContentRendered = (markdownViewer) => { + this.titlesInfo = markdownViewer.titlesInfo; + } + + onLinkClick = (event) => { + event.preventDefault(); + let link = ''; + if (event.target.tagName !== 'A') { + let target = event.target.parentNode; + while (target.tagName !== 'A') { + target = target.parentNode; + } + link = target.href; + } else { + link = event.target.href; + } + this.props.onLinkClick(link); + } + + onScrollHandler = () => { + const contentScrollTop = this.markdownContainer.current.scrollTop + 180; + let titlesLength = this.titlesInfo.length; + let activeTitleIndex; + if (contentScrollTop <= this.titlesInfo[0]) { + activeTitleIndex = 0; + this.setState({activeTitleIndex: activeTitleIndex}); + return; + } + if (contentScrollTop > this.titlesInfo[titlesLength - 1]) { + activeTitleIndex = this.titlesInfo.length - 1; + this.setState({activeTitleIndex: activeTitleIndex}); + return; + } + for (let i = 0; i < titlesLength; i++) { + if (contentScrollTop > this.titlesInfo[i]) { + continue; + } else { + activeTitleIndex = i - 1; + break; + } + } + this.setState({activeTitleIndex: activeTitleIndex}); + } + + render() { + if (this.props.isFileLoading) { + return + } + return ( +
+
+ {this.props.children} + +

{gettext('Last modified by')} {this.props.latestContributor}, {this.props.lastModified}

+
+
+ ); + } +} + +WikiMarkdownViewer.propTypes = propTypes; + +export default WikiMarkdownViewer; diff --git a/frontend/src/css/wiki.css b/frontend/src/css/wiki.css index bb610d688c..1a6d315d86 100644 --- a/frontend/src/css/wiki.css +++ b/frontend/src/css/wiki.css @@ -60,14 +60,21 @@ img[src=""] { min-height: 0; } -.cur-view-content .markdown-container{ - padding: 0 1.5rem; +.cur-view-content { + display: flex; + flex-direction: column; + overflow: hidden; +} + +.cur-view-content .wiki-page-container{ + margin: -0.625rem -1rem -1.25rem; + padding: 0.625rem 1rem 1.25rem; display: flex; flex: 1; overflow: auto; } -.cur-view-content .markdown-content { +.cur-view-content .wiki-page-content { width: calc(100% - 160px); padding-right: 40px; } @@ -86,10 +93,10 @@ img[src=""] { } @media (max-width: 991.98px) { - .cur-view-content .markdown-container { + .cur-view-content .wiki-page-container { padding-right: 1.5rem; } - .cur-view-content .markdown-content { + .cur-view-content .wiki-page-content { width: 100%; padding-right: 0; } @@ -176,11 +183,11 @@ img[src=""] { margin-top: 0; } -.markdown-content a { +.wiki-page-content a { cursor: pointer; } -.wiki-side-nav .markdown-content a { +.wiki-side-nav .wiki-page-content a { color: #212529; cursor: pointer; } @@ -191,11 +198,11 @@ img[src=""] { top: 0.25rem; } -.wiki-main-panel .markdown-content .ml-2 { +.wiki-main-panel .wiki-page-content .ml-2 { text-decoration: underline; } -.wiki-main-panel .markdown-content .ml-2:hover { +.wiki-main-panel .wiki-page-content .ml-2:hover { text-decoration: underline; color:#eb8205; } diff --git a/frontend/src/pages/repo-wiki-mode/main-panel.js b/frontend/src/pages/repo-wiki-mode/main-panel.js index 30af465137..020a154a9a 100644 --- a/frontend/src/pages/repo-wiki-mode/main-panel.js +++ b/frontend/src/pages/repo-wiki-mode/main-panel.js @@ -10,7 +10,7 @@ import ViewModeToolbar from '../../components/toolbar/view-mode-toolbar'; import DirOperationToolBar from '../../components/toolbar/dir-operation-toolbar'; import MutipleDirOperationToolbar from '../../components/toolbar/mutilple-dir-operation-toolbar'; import CurDirPath from '../../components/cur-dir-path'; -import MarkdownContentViewer from '../../components/markdown-viewer'; +import WikiMarkdownViewer from '../../components/wiki-markdown-viewer'; import DirentListView from '../../components/dirent-list-view/dirent-list-view'; import DirentDetail from '../../components/dirent-detail/dirent-details'; import FileUploader from '../../components/file-uploader/file-uploader'; @@ -75,10 +75,7 @@ class MainPanel extends Component { direntPath: '', currentRepoInfo: null, isRepoOwner: false, - activeTitleIndex: -1, }; - this.titlesInfo = null; - this.pageScroll = false; } componentDidMount() { @@ -152,40 +149,6 @@ class MainPanel extends Component { this.props.onFileUploadSuccess(direntObject); } - handlePageScroll = () => { - if (this.props.pathExist && this.props.isViewFile && !this.pageScroll && this.titlesInfo && this.titlesInfo.length > 0) { - this.pageScroll = true; - let that = this; - setTimeout(function() { - that.pageScroll = false; - }, 100); - const contentScrollTop = this.refs.curViewContent.scrollTop + 180; - let activeTitleIndex; - if (contentScrollTop <= this.titlesInfo[0]) { - activeTitleIndex = 0; - } - else if (contentScrollTop > this.titlesInfo[this.titlesInfo.length - 1]) { - activeTitleIndex = this.titlesInfo.length - 1; - } - else { - for (let i = 0; i < this.titlesInfo.length - 1; i++) { - if (contentScrollTop > this.titlesInfo[i] && this.titlesInfo[i + 1] && - contentScrollTop < this.titlesInfo[i + 1]) { - activeTitleIndex = i; - break; - } - } - } - this.setState({ - activeTitleIndex: activeTitleIndex - }); - } - } - - onContentRendered = (markdownViewer) => { - this.titlesInfo = markdownViewer.titlesInfo; - } - render() { const ErrMessage = (

{gettext('Folder does not exist.')}

); @@ -241,21 +204,32 @@ class MainPanel extends Component { ErrMessage : { this.props.isViewFile ? - : + > + + {this.props.reviewStatus === 'open' && +
+
+ {gettext('This file is in review stage')} + {gettext('View Review')} +
+
+ } + {(!this.props.isDraft && this.props.hasDraft && this.props.reviewStatus !== 'open') && +
+
+ {gettext('This file is in draft stage.')} + {gettext('Edit Draft')} +
+
+ } +
+ : {this.props.path === '/' && !(this.props.usedRepoTags.length === 0 && this.props.readmeMarkdown === null) && ( { - // - } render() { @@ -113,17 +110,16 @@ class MainPanel extends Component {
- { this.props.isViewFileState && - } - { !this.props.isViewFileState && + {!this.props.isViewFileState && }