diff --git a/internal_packages/notifications/lib/sidebar/initial-sync-activity.jsx b/internal_packages/notifications/lib/sidebar/initial-sync-activity.jsx index 1feebb3a5..bef9ea988 100644 --- a/internal_packages/notifications/lib/sidebar/initial-sync-activity.jsx +++ b/internal_packages/notifications/lib/sidebar/initial-sync-activity.jsx @@ -8,7 +8,11 @@ export default class InitialSyncActivity extends React.Component { constructor(props) { super(props); - this.state = this.getStateFromStores(); + this.state = { + isExpanded: false, + syncState: NylasSyncStatusStore.getSyncState(), + syncProgress: NylasSyncStatusStore.getSyncProgress(), + } } componentDidMount() { @@ -22,35 +26,15 @@ export default class InitialSyncActivity extends React.Component { } 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; + const syncState = NylasSyncStatusStore.getSyncState() + const syncProgress = NylasSyncStatusStore.getSyncProgress() + this.setState({syncState, syncProgress}); } hideExpandedState = (event) => { event.stopPropagation(); // So it doesn't reach the parent's onClick event.preventDefault(); - this.setState({expandedSync: false}); + this.setState({isExpanded: false}); } renderExpandedSyncState() { @@ -60,7 +44,8 @@ export default class InitialSyncActivity extends React.Component { return false; } - const folderStates = _.map(accountSyncState.folderSyncProgress, (progress, name) => { + const {folderSyncProgress} = accountSyncState + const folderStates = _.map(folderSyncProgress, ({progress}, name) => { return this.renderFolderProgress(name, progress) }) @@ -104,7 +89,7 @@ export default class InitialSyncActivity extends React.Component { } render() { - const progress = this.calculateProgress(); + const {syncProgress: {progress}} = this.state if (progress === 1) { return false; } @@ -124,14 +109,14 @@ export default class InitialSyncActivity extends React.Component { const classSet = classNames({ 'item': true, - 'expanded-sync': this.state.expandedSync, + 'expanded-sync': this.state.isExpanded, }); return (
(progress ? this.setState({expandedSync: !this.state.expandedSync}) : null)} + onClick={() => (progress ? this.setState({isExpanded: !this.state.isExpanded}) : null)} > {this.renderProgressBar(progress)} {innerContent} diff --git a/internal_packages/worker-ui/lib/developer-bar-store.coffee b/internal_packages/worker-ui/lib/developer-bar-store.coffee index f0ffc1373..68e52cc76 100644 --- a/internal_packages/worker-ui/lib/developer-bar-store.coffee +++ b/internal_packages/worker-ui/lib/developer-bar-store.coffee @@ -91,7 +91,7 @@ class DeveloperBarStore extends NylasStore _onSyncStatusChanged: -> @_longPollStates = {} - _.forEach NylasSyncStatusStore.state(), (state, accountId) => + _.forEach NylasSyncStatusStore.getSyncState(), (state, accountId) => @_longPollStates[accountId] = state.deltaStatus @trigger() diff --git a/src/flux/stores/nylas-sync-status-store.es6 b/src/flux/stores/nylas-sync-status-store.es6 index 317b42863..ea527da45 100644 --- a/src/flux/stores/nylas-sync-status-store.es6 +++ b/src/flux/stores/nylas-sync-status-store.es6 @@ -22,8 +22,14 @@ import CategoryStore from './category-store' * n1Cloud, * }, * folderSyncProgress: { - * inbox: 0.5, - * archive: 0.2, + * inbox: { + * progress: 0.5, + * total: 100, + * } + * archive: { + * progress: 0.2, + * total: 600, + * }, * ... * } * } @@ -85,11 +91,11 @@ class NylasSyncStatusStore extends NylasStore { const {uidnext, fetchedmin, fetchedmax} = folder.syncState || {} if (uidnext) { const progress = (+fetchedmax - +fetchedmin + 1) / uidnext - updates[name] = progress + updates[name] = {progress, total: uidnext} } else { // We don't have a uidnext if the sync hasn't started at all, // but we've found the folder. - updates[name] = 0 + updates[name] = {progress: 0, total: null} } } this._updateState(accountId, {folderSyncProgress: updates}) @@ -107,10 +113,51 @@ class NylasSyncStatusStore extends NylasStore { this._triggerDebounced() } - state() { + getSyncState() { return this._statesByAccount } + /** + * Returns the weighted sync progress for all accounts as a percentage, and + * the total number of messages to sync for a given account + */ + getSyncProgressForAccount(accountId) { + const {folderSyncProgress} = this._statesByAccount[accountId] + const folderNames = Object.keys(folderSyncProgress) + const progressPerFolder = folderNames.map(fname => folderSyncProgress[fname]) + const weightedProgress = progressPerFolder.reduce( + (accum, {progress, total}) => accum + progress * total, 0 + ) + const totalMessageCount = progressPerFolder.reduce( + (accum, {total}) => accum + total, 0 + ) + return { + progress: weightedProgress / totalMessageCount, + total: totalMessageCount, + } + } + + /** + * Returns the weighted sync progress for all accounts as a percentage, and + * the total number of messages to sync + */ + getSyncProgress() { + const accountIds = AccountStore.accountIds() + const progressPerAccount = ( + accountIds.map(accId => this.getSyncProgressForAccount(accId)) + ) + const weightedProgress = progressPerAccount.reduce( + (accum, {progress, total}) => accum + progress * total, 0 + ) + const totalMessageCount = progressPerAccount.reduce( + (accum, {total}) => accum + total, 0 + ) + return { + progress: weightedProgress / totalMessageCount, + total: totalMessageCount, + } + } + /** * Returns true if N1's local cache contains the entire list of available * folders and labels. @@ -123,7 +170,7 @@ class NylasSyncStatusStore extends NylasStore { if (!state) { return false } const folderNames = Object.keys(state.folderSyncProgress || {}) if (folderNames.length === 0) { return false } - return folderNames.some((name) => state.folderSyncProgress[name] !== 0) + return folderNames.some((fname) => state.folderSyncProgress[fname].progress !== 0) } whenCategoryListSynced(accountId) { @@ -149,11 +196,11 @@ class NylasSyncStatusStore extends NylasStore { } if (folderName) { - return state.folderSyncProgress[folderName] >= 1 + return state.folderSyncProgress[folderName].progress >= 1 } const folderNames = Object.keys(state.folderSyncProgress) for (const fname of folderNames) { - const syncProgress = state.folderSyncProgress[fname] + const syncProgress = state.folderSyncProgress[fname].progress if (syncProgress < 1) { return false }