import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import { Link } from '@gatsbyjs/reach-router'; import { seafileAPI } from '../../utils/seafile-api'; import { gettext, siteRoot, username } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import Loading from '../../components/loading'; import Activity from '../../models/activity'; import FileActivitiesContent from './content'; import UserSelector from './user-selector'; import '../../css/files-activities.css'; moment.locale(window.app.config.lang); const propTypes = { onlyMine: PropTypes.bool }; class FilesActivities extends Component { constructor(props) { super(props); this.state = { errorMsg: '', isFirstLoading: true, isLoadingMore: false, currentPage: 1, hasMore: true, allItems: [], items: [], availableUsers: [], targetUsers: [] }; this.avatarSize = 72; this.curPathList = []; this.oldPathList = []; this.availableUserEmails = new Set(); } componentDidMount() { let { currentPage, availableUsers } = this.state; seafileAPI.listActivities(currentPage, this.avatarSize).then(res => { // {"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 }); } }); this.setState({ allItems: events, items: this.filterEvents(events), availableUsers: availableUsers, currentPage: currentPage + 1, isFirstLoading: false, hasMore: true, }); if (this.state.items.length < 25) { this.getMore(); } }).catch(error => { this.setState({ isFirstLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } 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++; multiFilesActivity.createdFilesList.push(events[i]); } else { actuallyEvents.push(events[i]); } } } return actuallyEvents; }; getMore() { const { currentPage, availableUsers, targetUsers } = this.state; seafileAPI.listActivities(currentPage, this.avatarSize).then(res => { // {"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); this.setState({ allItems: [...this.state.allItems, ...events], items: [...this.state.items, ...filteredEvents], availableUsers: availableUsers, currentPage: currentPage + 1, isLoadingMore: false, hasMore: res.data.events.length === 0 ? false : true }); if (this.state.items.length < 25 && this.state.hasMore) { if (!(targetUsers.length && currentPage == 100)) { this.getMore(); } } }).catch(error => { this.setState({ isLoadingMore: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } 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(); } }); }); }; handleScroll = (event) => { 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(); }); } } }; render() { const { onlyMine } = this.props; const { targetUsers, availableUsers } = this.state; return (
  • {gettext('All Activities')}
  • {gettext('My Activities')}
{this.state.isFirstLoading && } {(!this.state.isFirstLoading && this.state.errorMsg) &&

{this.state.errorMsg}

} {!this.state.isFirstLoading && ( {!onlyMine && ( )} ) }
); } } FilesActivities.propTypes = propTypes; export default FilesActivities;