1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-08 18:30:53 +00:00

scroll-to-changed-nodes (#2564)

This commit is contained in:
Michael An
2018-11-27 10:41:27 +08:00
committed by Daniel Pan
parent 50a04fed0c
commit 1101a8ee6a
2 changed files with 150 additions and 43 deletions

View File

@@ -87,32 +87,34 @@
.review-side-panel-body {
padding: 1rem 2rem;
}
.review-side-panel-reviewers, .review-side-panel-author {
.review-side-panel-item {
border-bottom: 1px solid #e6e6dd;
padding: 1em 0;
}
.reviewer-info {
margin-bottom: 0.8125rem;
}
.reviewers-header, .author-header {
.reviewer-info, .author-info {
display: flex;
justify-content: space-between;
margin-bottom: 0.8125rem;
}
.reviewers-header i {
color: #c8c8c8;
}
.reviewers-header i:hover {
cursor: pointer;
color: #a4a4a4;
align-items: center;
}
.review-side-panel-header {
display: flex;
justify-content: space-between;
margin-bottom: 2px;
font-weight: bold;
color: #666;
font-size: 0.8125rem;
}
.reviewer-avatar, .author-avatar {
.review-side-panel-item i {
color: #c8c8c8;
margin: 5px 5px 0 0;
}
.review-side-panel-item i:hover {
cursor: pointer;
color: #a4a4a4;
}
.review-side-panel-avatar {
margin-right: 10px;
height: 1.5rem;
width: 1.5rem;
}
.reviewer-name, .author-name {
height: 2rem;

View File

@@ -48,16 +48,22 @@ class DraftReview extends React.Component {
reviewers: [],
activeTab: 'reviewInfo',
historyList: [],
totalReversionCount: 0
totalReversionCount: 0,
changedNodes: [],
};
this.selectedText = '';
this.newIndex = null;
this.oldIndex = null;
this.changeIndex = -1;
}
componentDidMount() {
this.initialContent();
document.addEventListener('selectionchange', this.setBtnPosition);
let that = this;
setTimeout(() => {
that.getChangedNodes();
}, 1000);
}
initialContent = () => {
@@ -164,6 +170,12 @@ class DraftReview extends React.Component {
};
onSwitchShowDiff = () => {
if (!this.state.isShowDiff) {
let that = this;
setTimeout(() => {
that.getChangedNodes();
}, 100);
}
this.setState({
isShowDiff: !this.state.isShowDiff,
});
@@ -337,6 +349,50 @@ class DraftReview extends React.Component {
}
}
getChangedNodes = () => {
const nodes = this.refs.diffViewer.value.document.nodes;
let keys = [];
let lastDiffState = '';
nodes.map((node) => {
if (node.data.get("diff_state") === 'diff-added' && lastDiffState !== 'diff-added') {
keys.push(node.key);
}
else if (node.data.get("diff_state") === 'diff-removed' && lastDiffState !== 'diff-removed') {
keys.push(node.key);
}
lastDiffState = node.data.get("diff_state");
});
this.setState({
changedNodes: keys
});
}
scrollToChangedNode = (scroll) => {
if (this.state.changedNodes.length == 0) return;
if (scroll === 'up') {
this.changeIndex++;
}
else {
this.changeIndex--;
}
if (this.changeIndex > this.state.changedNodes.length - 1) {
this.changeIndex = 0;
}
if (this.changeIndex < 0) {
this.changeIndex = this.state.changedNodes.length - 1;
}
const win = window;
let key = this.state.changedNodes[this.changeIndex];
const element = win.document.querySelector(`[data-key="${key}"]`);
const scroller = this.findScrollContainer(element, win);
const isWindow = scroller == win.document.body || scroller == win.document.documentElement;
if (isWindow) {
win.scrollTo(0, element.offsetTop);
} else {
scroller.scrollTop = element.offsetTop;
}
}
componentWillMount() {
this.getCommentsNumber();
this.listReviewers();
@@ -510,34 +566,16 @@ class DraftReview extends React.Component {
<TabContent activeTab={this.state.activeTab}>
<TabPane tabId="reviewInfo">
<div className="review-side-panel-body">
<div className="review-side-panel-reviewers">
<div className="reviewers-header">
<div className="review-side-panel-header">{gettext('Reviewers')}</div>
<i className="fa fa-cog" onClick={this.toggleAddReviewerDialog}></i>
</div>
{ this.state.reviewers.length > 0 ?
this.state.reviewers.map((item, index = 0, arr) => {
return (
<div className="reviewer-info" key={index}>
<img className="avatar reviewer-avatar" src={item.avatar_url} alt=""/>
<span className="reviewer-name">{item.user_name}</span>
</div>
);
})
:
<span>{gettext('No reviewer yet.')}</span>
<SidePanelReviewers
reviewers={this.state.reviewers}
toggleAddReviewerDialog={this.toggleAddReviewerDialog}/>
<SidePanelAuthor/>
{ this.state.isShowDiff &&
<SidePanelChanges
changedNumber={this.state.changedNodes.length}
scrollToChangedNode={this.scrollToChangedNode}/>
}
</div>
<div className="review-side-panel-author">
<div className="author-header">
<div className="review-side-panel-header">{gettext('Author')}</div>
</div>
<div className="author-info">
<img className="avatar author-avatar" src={authorAvatar} alt=""/>
<span className="author-name">{author}</span>
</div>
</div>
</div>
</TabPane>
{ this.state.reviewStatus == "finished"? '':
<TabPane tabId="history" className="history">
@@ -565,6 +603,73 @@ class DraftReview extends React.Component {
}
}
class SidePanelReviewers extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="review-side-panel-item">
<div className="review-side-panel-header">{gettext('Reviewers')}
<i className="fa fa-cog" onClick={this.props.toggleAddReviewerDialog}></i>
</div>
{ this.props.reviewers.length > 0 ?
this.props.reviewers.map((item, index = 0, arr) => {
return (
<div className="reviewer-info" key={index}>
<img className="avatar review-side-panel-avatar" src={item.avatar_url} alt=""/>
<span className="reviewer-name">{item.user_name}</span>
</div>
);
})
:
<span>{gettext('No reviewer yet.')}</span>
}
</div>
);
}
}
class SidePanelAuthor extends React.Component {
render() {
return (
<div className="review-side-panel-item">
<div className="review-side-panel-header">{gettext('Author')}</div>
<div className="author-info">
<img className="avatar review-side-panel-avatar" src={authorAvatar} alt=""/>
<span className="author-name">{author}</span>
</div>
</div>
);
}
}
class SidePanelChanges extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="review-side-panel-item">
<div className="review-side-panel-header">{gettext('Changes')}</div>
<div className="changes-info">
<span>{gettext(`Number of changes: ${this.props.changedNumber}`)}</span>
{ this.props.changedNumber > 0 &&
<div>
<i className="fa fa-arrow-circle-up" onClick={() => { this.props.scrollToChangedNode('down');}}></i>
<i className="fa fa-arrow-circle-down" onClick={() => { this.props.scrollToChangedNode('up');}}></i>
</div>
}
</div>
</div>
);
}
}
ReactDOM.render (
<DraftReview />,
document.getElementById('wrapper')