1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-26 15:26:19 +00:00

feat(comment): add comment in wiki (#8123)

* feat(comment): add comment in wiki

* feat(comment): update layout

* fix(css): optimize code

* fix(css): optimize code
This commit is contained in:
Guodong SU
2025-08-14 16:57:04 +08:00
committed by GitHub
parent 5a2c32d3e4
commit b474e6b2a4
5 changed files with 147 additions and 3 deletions

View File

@@ -78,6 +78,10 @@
position: relative;
}
.main-panel-center {
flex-direction: row;
}
.side-panel-center,
.side-panel-footer {
min-height: 0;

View File

@@ -1,7 +1,8 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap';
import { SdocWikiEditor, DocInfo } from '@seafile/seafile-sdoc-editor';
import { SdocWikiEditor, DocInfo, ErrorBoundary, EXTERNAL_EVENT } from '@seafile/seafile-sdoc-editor';
import { CollaboratorsProvider, CommentContextProvider, EventBus, PluginsProvider, RightPanel } from '@seafile/sdoc-editor';
import { gettext, username, wikiPermission, wikiId, siteRoot, isPro } from '../../utils/constants';
import TextTranslation from '../../utils/text-translation';
import Switch from '../../components/switch';
@@ -11,7 +12,10 @@ import Account from '../../components/common/account';
import WikiTopNav from './top-nav';
import { getCurrentPageConfig } from './utils';
import RightHeader from './wiki-right-header';
import CommentPlugin from './wiki-comment/plugin-item';
import User from '../../metadata/model/user';
import { metadataAPI } from '../../metadata';
import classnames from 'classnames';
const propTypes = {
path: PropTypes.string.isRequired,
@@ -42,6 +46,10 @@ class MainPanel extends Component {
currentPageConfig: {},
isDropdownMenuOpen: false,
showExportSubmenu: false,
isShowRightPanel: false,
collaborators: [],
editor: {},
unseenNotificationsCount: 0,
};
this.scrollRef = React.createRef();
this.exportDropdownRef = React.createRef();
@@ -69,6 +77,36 @@ class MainPanel extends Component {
return { ...props, docUuid: window.seafile.docUuid, currentPageConfig };
}
componentDidMount() {
if (!wikiId) return;
this.fetchCollaborators(wikiId);
const eventBus = EventBus.getInstance();
this.unsubscribeUnseenNotificationsCount = eventBus.subscribe(EXTERNAL_EVENT.UNSEEN_NOTIFICATIONS_COUNT, this.updateUnseenNotificationsCount);
}
componentWillUnmount() {
this.unsubscribeUnseenNotificationsCount();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.docUuid !== this.state.docUuid) {
this.setState({ isShowRightPanel: false });
}
}
fetchCollaborators(wikiId) {
metadataAPI.getCollaborators(wikiId).then(res => {
const collaborators = Array.isArray(res?.data?.user_list)
? res.data.user_list.map(user => new User(user))
: [];
this.setState({ collaborators });
});
}
updateUnseenNotificationsCount = (count) => {
this.setState({ unseenNotificationsCount: count });
};
handleEditorStateChange = ({ pageId, locked }) => {
this.forceUpdate();
};
@@ -145,6 +183,16 @@ class MainPanel extends Component {
this.setState({ showExportSubmenu: false });
};
setIsShowRightPanel = () => {
this.setState(prevState => ({
isShowRightPanel: !prevState.isShowRightPanel
}));
};
setEditor = (editor) => {
this.setState({ editor: editor });
};
render() {
const menuItems = this.getMenu();
const { permission, pathExist, isDataLoading, config, onUpdatePage, isUpdateBySide, style, currentPageLocked } = this.props;
@@ -152,7 +200,7 @@ class MainPanel extends Component {
const isViewingFile = pathExist && !isDataLoading;
const isReadOnly = currentPageLocked || !(permission === 'rw');
return (
<div className="wiki2-main-panel" style={style}>
<div className={classnames('wiki2-main-panel', { 'show-comment-panel': this.state.isShowRightPanel })} style={style}>
<div className='wiki2-main-panel-north'>
<div className="d-flex align-items-center flex-fill o-hidden">
<div className='wiki2-main-panel-north-content'>
@@ -176,6 +224,7 @@ class MainPanel extends Component {
</div>
</div>
<div className='d-flex align-items-center'>
<CommentPlugin unseenNotificationsCount={this.state.unseenNotificationsCount} setIsShowRightPanel={this.setIsShowRightPanel} />
{menuItems.length > 0 &&
<Dropdown isOpen={isDropdownMenuOpen} toggle={this.toggleDropdownMenu} className='wiki2-file-history-button'>
<DropdownToggle
@@ -268,11 +317,26 @@ class MainPanel extends Component {
docUuid={this.state.docUuid}
isWikiReadOnly={isReadOnly}
scrollRef={this.scrollRef}
collaborators={this.state.collaborators}
showComment={true}
isShowRightPanel={this.state.isShowRightPanel}
setEditor={this.setEditor}
/>
</div>
</div>
)}
</div>
{this.state.isShowRightPanel && (
<ErrorBoundary>
<CollaboratorsProvider collaborators={this.state.collaborators}>
<PluginsProvider plugins={[]} showComment={true} setIsShowRightPanel={this.setIsShowRightPanel}>
<CommentContextProvider {... { editor: this.state.editor }}>
<RightPanel classname='in-wiki-editor' editor={this.state.editor} />
</CommentContextProvider>
</PluginsProvider>
</CollaboratorsProvider>
</ErrorBoundary>
)}
</div>
</div>
);

View File

@@ -0,0 +1,33 @@
.wiki-plugin-operation-btn-container {
border-radius: 3px;
cursor: pointer;
height: 24px;
justify-content: center;
margin-left: 10px;
position: relative;
width: 24px;
align-items: center;
display: flex;
margin-right: 16px;
}
.wiki-plugin-operation-btn-container:hover {
background-color: #efefef;
cursor: pointer
}
.wiki-plugin-operation-btn-container .sdocfont {
color: #666666;
cursor: pointer;
}
.wiki-plugin-operation-btn-container .sdoc-unread-message-tip {
display: inline-block;
height: 6px;
width: 6px;
border-radius: 50%;
background-color: #fc6440;
position: absolute;
right: 2px;
top: 2px;
}

View File

@@ -0,0 +1,23 @@
import React, { useCallback } from 'react';
import './plugin-item.css';
const CommentPlugin = ({ setIsShowRightPanel, unseenNotificationsCount }) => {
const handleOnClick = useCallback((event) => {
event.stopPropagation();
setIsShowRightPanel(prev => !prev);
}, []);
return (
<span className="op-item wiki-plugin-operation-btn-container" onClick={handleOnClick}>
<i className='sdocfont sdoc-comments'></i>
{unseenNotificationsCount > 0 && (
<span className="sdoc-unread-message-tip"></span>
)}
</span>
);
};
export default CommentPlugin;

View File

@@ -10,6 +10,15 @@ body {
overflow: hidden;
}
.wiki2-main-panel.show-comment-panel .wiki-page-title-wrapper,
.wiki2-main-panel.show-comment-panel .sdoc-editor-container .sdoc-article-container .article.sdoc-editor__article {
padding-left: 50px;
}
.wiki2-main-panel .sdoc-comment-container .comment-container-right .element-comments-count {
left: -100px;
}
.wiki2-main-panel .wiki2-main-panel-north {
height: 44px;
position: relative;
@@ -58,6 +67,17 @@ body {
.main-panel-center .cur-view-content {
padding: 0;
min-width: 500px;
}
.main-panel-center .sdoc-content-right-panel-wrapper {
margin-top: -44px;
height: calc(100vh + 44px);
z-index: 103 !important;
}
.main-panel-center .sdoc-content-right-panel-wrapper .comments-panel-wrapper {
height: 100vh;
}
/* scroll container */