1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-05 09:10:05 +00:00
seahub/frontend/src/pages/dashboard/files-activities.js

261 lines
8.6 KiB
JavaScript
Raw Normal View History

2018-11-29 09:55:14 +00:00
import React, { Component, Fragment } from 'react';
2018-10-16 10:19:51 +00:00
import PropTypes from 'prop-types';
import moment from 'moment';
import { Link } from '@gatsbyjs/reach-router';
2018-09-21 06:16:15 +00:00
import { seafileAPI } from '../../utils/seafile-api';
import { gettext, siteRoot, username } from '../../utils/constants';
2018-12-24 04:24:16 +00:00
import { Utils } from '../../utils/utils';
2018-12-28 03:12:24 +00:00
import Loading from '../../components/loading';
import Activity from '../../models/activity';
import FileActivitiesContent from './content';
import UserSelector from './user-selector';
import '../../css/files-activities.css';
2018-08-30 07:10:52 +00:00
moment.locale(window.app.config.lang);
const propTypes = {
onlyMine: PropTypes.bool
2018-10-16 10:19:51 +00:00
};
2018-08-30 07:10:52 +00:00
class FilesActivities extends Component {
2018-08-30 07:10:52 +00:00
constructor(props) {
super(props);
this.state = {
2018-12-28 03:12:24 +00:00
errorMsg: '',
isFirstLoading: true,
isLoadingMore: false,
currentPage: 1,
hasMore: true,
allItems: [],
items: [],
availableUsers: [],
targetUsers: []
2018-08-30 07:10:52 +00:00
};
2019-01-08 06:51:13 +00:00
this.avatarSize = 72;
this.curPathList = [];
this.oldPathList = [];
this.availableUserEmails = new Set();
2018-08-30 07:10:52 +00:00
}
componentDidMount() {
let { currentPage, availableUsers } = this.state;
2019-01-08 06:51:13 +00:00
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
2018-12-28 03:12:24 +00:00
// {"events":[...]}
let events = this.mergePublishEvents(res.data.events);
events = this.mergeFileCreateEvents(events);
events.forEach(item => {
if (!this.availableUserEmails.has(item.author_email)) {
this.availableUserEmails.add(item.author_email);
availableUsers.push({
email: item.author_email,
name: item.author_name,
avatar_url: item.avatar_url
});
}
});
2018-12-28 03:12:24 +00:00
this.setState({
allItems: events,
items: this.filterEvents(events),
availableUsers: availableUsers,
2018-12-28 03:12:24 +00:00
currentPage: currentPage + 1,
isFirstLoading: false,
hasMore: true,
});
if (this.state.items.length < 25) {
this.getMore();
}
2018-12-28 03:12:24 +00:00
}).catch(error => {
this.setState({
isFirstLoading: false,
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
});
2018-08-30 07:10:52 +00:00
});
}
mergePublishEvents = (events) => {
events.forEach((item) => {
if (item.op_type === 'publish') {
this.curPathList.push(item.path);
this.oldPathList.push(item.old_path);
}
});
let actuallyEvents = [];
for (var i = 0; i < events.length; i++) {
if (events[i].obj_type === 'file') {
if (events[i].op_type === 'delete' && this.oldPathList.includes(events[i].path)) {
this.oldPathList.splice(this.oldPathList.indexOf(events[i].path), 1);
} else if (events[i].op_type === 'edit' && this.curPathList.includes(events[i].path)) {
this.curPathList.splice(this.curPathList.indexOf(events[i].path), 1);
} else if (events[i].op_type === 'rename' && this.oldPathList.includes(events[i].old_path)) {
this.oldPathList.splice(this.oldPathList.indexOf(events[i].old_path), 1);
} else {
actuallyEvents.push(events[i]);
}
} else {
actuallyEvents.push(events[i]);
}
}
return actuallyEvents;
};
mergeFileCreateEvents = (events) => {
let actuallyEvents = [];
let multiFilesActivity = null;
for (var i = 0; i < events.length; i++) {
let isFulfilCondition = events[i].obj_type === 'file' &&
events[i].op_type === 'create' &&
events[i + 1] &&
events[i + 1].obj_type === 'file' &&
events[i + 1].op_type === 'create' &&
events[i + 1].repo_name === events[i].repo_name &&
events[i + 1].author_email === events[i].author_email;
if (multiFilesActivity != null) {
multiFilesActivity.createdFilesCount++;
multiFilesActivity.createdFilesList.push(events[i]);
if (isFulfilCondition) {
continue;
} else {
actuallyEvents.push(multiFilesActivity);
multiFilesActivity = null;
}
} else {
if (isFulfilCondition) {
multiFilesActivity = new Activity(events[i]);
multiFilesActivity.obj_type = 'files';
multiFilesActivity.createdFilesCount++;
2019-02-28 06:34:54 +00:00
multiFilesActivity.createdFilesList.push(events[i]);
} else {
actuallyEvents.push(events[i]);
}
}
}
return actuallyEvents;
};
2018-08-30 07:10:52 +00:00
getMore() {
const { currentPage, availableUsers, targetUsers } = this.state;
2019-01-08 06:51:13 +00:00
seafileAPI.listActivities(currentPage, this.avatarSize).then(res => {
2018-12-28 03:12:24 +00:00
// {"events":[...]}
let events = this.mergePublishEvents(res.data.events);
events = this.mergeFileCreateEvents(events);
events.forEach(item => {
if (!this.availableUserEmails.has(item.author_email)) {
this.availableUserEmails.add(item.author_email);
availableUsers.push({
email: item.author_email,
name: item.author_name,
avatar_url: item.avatar_url
});
}
});
const filteredEvents = this.filterEvents(events);
2018-12-28 03:12:24 +00:00
this.setState({
allItems: [...this.state.allItems, ...events],
items: [...this.state.items, ...filteredEvents],
availableUsers: availableUsers,
2018-12-28 03:12:24 +00:00
currentPage: currentPage + 1,
isLoadingMore: false,
hasMore: res.data.events.length === 0 ? false : true
2018-12-28 03:12:24 +00:00
});
if (this.state.items.length < 25 && this.state.hasMore) {
if (!(targetUsers.length && currentPage == 100)) {
this.getMore();
}
}
2018-12-28 03:12:24 +00:00
}).catch(error => {
this.setState({
isLoadingMore: false,
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
});
});
2018-08-30 07:10:52 +00:00
}
filterEvents = (events) => {
const { onlyMine } = this.props;
const { targetUsers } = this.state;
if (onlyMine) {
return events.filter(item => item.author_email == username);
} else if (targetUsers.length) {
return events.filter(item => targetUsers.map(item => item.email).indexOf(item.author_email) != -1);
} else {
return events;
}
};
setTargetUsers = (selectedUsers) => {
this.setState({
targetUsers: selectedUsers
}, () => {
const items = this.filterEvents(this.state.allItems);
this.setState({
items: items
}, () => {
if (items.length < 25 && this.state.hasMore) {
this.getMore();
}
});
});
};
2018-12-28 03:12:24 +00:00
handleScroll = (event) => {
2019-01-08 06:51:13 +00:00
if (!this.state.isLoadingMore && this.state.hasMore) {
const clientHeight = event.target.clientHeight;
const scrollHeight = event.target.scrollHeight;
const scrollTop = event.target.scrollTop;
const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight);
if (isBottom) { // scroll to the bottom
this.setState({isLoadingMore: true}, () => {
this.getMore();
});
}
2018-08-30 07:10:52 +00:00
}
};
2018-08-30 07:10:52 +00:00
render() {
const { onlyMine } = this.props;
const { targetUsers, availableUsers } = this.state;
2018-08-30 07:10:52 +00:00
return (
2018-11-26 09:53:18 +00:00
<div className="main-panel-center">
<div className="cur-view-container" id="activities">
<div className="cur-view-path">
<ul className="nav">
<li className="nav-item">
<Link to={`${siteRoot}dashboard/`} className={`nav-link${onlyMine ? '' : ' active'}`}>{gettext('All Activities')}</Link>
</li>
<li className="nav-item">
<Link to={`${siteRoot}my-activities/`} className={`nav-link${onlyMine ? ' active': ''}`}>{gettext('My Activities')}</Link>
</li>
</ul>
2018-11-26 09:53:18 +00:00
</div>
<div className="cur-view-content d-block" onScroll={this.handleScroll}>
2018-12-28 03:12:24 +00:00
{this.state.isFirstLoading && <Loading />}
{(!this.state.isFirstLoading && this.state.errorMsg) &&
2018-12-28 03:12:24 +00:00
<p className="error text-center">{this.state.errorMsg}</p>
}
{!this.state.isFirstLoading && (
<Fragment>
{!onlyMine && (
<UserSelector
availableUsers={availableUsers}
currentSelectedUsers={targetUsers}
setTargetUsers={this.setTargetUsers}
/>
)}
<FileActivitiesContent items={this.state.items} isLoadingMore={this.state.isLoadingMore} />
</Fragment>
)
2018-12-28 03:12:24 +00:00
}
2018-11-26 06:00:32 +00:00
</div>
2018-08-30 07:10:52 +00:00
</div>
2018-11-26 09:53:18 +00:00
</div>
2018-08-30 07:10:52 +00:00
);
}
}
FilesActivities.propTypes = propTypes;
2018-08-30 07:10:52 +00:00
export default FilesActivities;