mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-09 17:55:35 +08:00
fix(sync-status):Use weighted percentage avg for sync status progress bar
Summary: Also move calculation to sync store, rename stuff a little bit Test Plan: Manual :( Reviewers: evan, jackie, halla Reviewed By: jackie Differential Revision: https://phab.nylas.com/D3547
This commit is contained in:
parent
b5970e1e46
commit
a0050a22d5
3 changed files with 70 additions and 38 deletions
|
@ -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 (
|
||||
<div
|
||||
className={classSet}
|
||||
key="initial-sync"
|
||||
onClick={() => (progress ? this.setState({expandedSync: !this.state.expandedSync}) : null)}
|
||||
onClick={() => (progress ? this.setState({isExpanded: !this.state.isExpanded}) : null)}
|
||||
>
|
||||
{this.renderProgressBar(progress)}
|
||||
{innerContent}
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue