mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-24 01:06:07 +08:00
78d1b85c7f
Summary: Adds a UI component to see the progress of initial sync. (The behavior is sometimes a little strange, but I believe this is just because of weird behavior in the NylasSyncStatusStore itself. For instance, it sometimes never populates the `folderSyncProgress` fields, or it never sets the progress to 1, so the bar stops at 99%) Test Plan: tested locally Reviewers: juan, evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D3536
140 lines
3.7 KiB
JavaScript
140 lines
3.7 KiB
JavaScript
import _ from 'underscore';
|
|
import _str from 'underscore.string';
|
|
import classNames from 'classnames';
|
|
import {AccountStore, NylasSyncStatusStore, React} from 'nylas-exports';
|
|
|
|
export default class InitialSyncActivity extends React.Component {
|
|
static displayName = 'InitialSyncActivity';
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = this.getStateFromStores();
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.unsubscribe = NylasSyncStatusStore.listen(this.onDataChanged);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
if (this.unsubscribe) {
|
|
this.unsubscribe();
|
|
}
|
|
}
|
|
|
|
onDataChanged = () => {
|
|
this.setState(this.getStateFromStores());
|
|
}
|
|
|
|
getStateFromStores() {
|
|
return {
|
|
syncState: NylasSyncStatusStore.state(),
|
|
};
|
|
}
|
|
|
|
/*
|
|
Iterate through the sync progress of each folder of each account and get a
|
|
normalized progress value (0: not started, 1: sync complete) for all syncs.
|
|
*/
|
|
calculateProgress() {
|
|
let count = 0;
|
|
const total = _.values(this.state.syncState).reduce((outerSum, accountSyncState) => {
|
|
return outerSum + _.values(accountSyncState.folderSyncProgress).reduce((innerSum, progress) => {
|
|
count++;
|
|
return innerSum + progress;
|
|
}, 0)
|
|
}, 0);
|
|
|
|
return count ? (total / count) : 0;
|
|
}
|
|
|
|
expandedSyncState() {
|
|
const accounts = _.map(this.state.syncState, (accountSyncState, accountId) => {
|
|
const account = _.findWhere(AccountStore.accounts(), {id: accountId});
|
|
if (!account) {
|
|
return false;
|
|
}
|
|
|
|
const folderStates = _.map(accountSyncState.folderSyncProgress, (progress, name) => {
|
|
return this.renderFolderProgress(name, progress)
|
|
})
|
|
|
|
return (
|
|
<div className="account inner" key={accountId}>
|
|
<h2>{account.emailAddress}</h2>
|
|
{folderStates}
|
|
</div>
|
|
)
|
|
});
|
|
|
|
return (
|
|
<div className="account-detail-area" key="expanded-sync-state">
|
|
{accounts}
|
|
<a className="close-expanded" onClick={this.hideExpandedState}>Hide</a>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
hideExpandedState = (event) => {
|
|
event.stopPropagation(); // So it doesn't reach the parent's onClick
|
|
event.preventDefault();
|
|
this.setState({expandedSync: false});
|
|
}
|
|
|
|
renderFolderProgress(name, progress) {
|
|
let status = 'busy';
|
|
if (progress === 1) {
|
|
status = 'complete';
|
|
}
|
|
|
|
return (
|
|
<div className={`model-progress ${status}`} key={name}>
|
|
<h3>{_str.titleize(name)}:</h3>
|
|
{this.renderProgressBar(progress)}
|
|
<div className="amount">{`${_str.numberFormat(progress * 100, 2) || '0.00'}%`}</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
renderProgressBar(progress) {
|
|
return (
|
|
<div className="progress-track">
|
|
<div className="progress" style={{width: `${(progress || 0) * 100}%`}} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
render() {
|
|
const progress = this.calculateProgress();
|
|
if (progress === 1) {
|
|
return false;
|
|
}
|
|
|
|
const innerContent = []
|
|
if (progress === 0) {
|
|
// On application start, the NylasSyncStatusStore takes awhile to populate
|
|
// the folderSyncProgress fields. Don't let the user expand the details,
|
|
// because they'll be empty.
|
|
innerContent.push(<div className="inner" key="0">Preparing to sync your mailbox…</div>);
|
|
} else {
|
|
innerContent.push(<div className="inner" key="0">Syncing your mailbox…</div>);
|
|
innerContent.push(this.expandedSyncState());
|
|
}
|
|
|
|
const classSet = classNames({
|
|
'item': true,
|
|
'expanded-sync': this.state.expandedSync,
|
|
});
|
|
|
|
return (
|
|
<div
|
|
className={classSet}
|
|
key="initial-sync"
|
|
onClick={() => (progress ? this.setState({expandedSync: !this.state.expandedSync}) : null)}
|
|
>
|
|
{this.renderProgressBar(progress)}
|
|
{innerContent}
|
|
</div>
|
|
)
|
|
}
|
|
}
|