mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-12 04:25:31 +08:00
d1b81b6afe
Summary: Sometimes, when logging out of your NylasID and restarting the app, we would continue making some requests from the worker window that required a NylasID. This would make the app enter a restart loop and become completely unresponsive because when we made a request without a NylasID, we would force the user to log out and restart the app, and then we would again make the requests without the id, ad infinitum. To fix this, we make sure we have a NylasID before making any requests that require it Test Plan: manual Reviewers: halla, evan Reviewed By: halla, evan Differential Revision: https://phab.nylas.com/D4344
112 lines
3.2 KiB
JavaScript
112 lines
3.2 KiB
JavaScript
import _ from 'underscore'
|
|
import moment from 'moment-timezone'
|
|
import {
|
|
IdentityStore,
|
|
AccountStore,
|
|
NylasAPI,
|
|
NylasAPIRequest,
|
|
FolderSyncProgressStore,
|
|
} from 'nylas-exports'
|
|
import RefreshingJSONCache from './refreshing-json-cache'
|
|
|
|
// Stores contact rankings
|
|
class ContactRankingsCache extends RefreshingJSONCache {
|
|
constructor(accountId) {
|
|
super({
|
|
key: `ContactRankingsFor${accountId}`,
|
|
version: 1,
|
|
refreshInterval: moment.duration(60, 'seconds').asMilliseconds(),
|
|
maxRefreshInterval: moment.duration(24, 'hours').asMilliseconds(),
|
|
})
|
|
this._accountId = accountId
|
|
}
|
|
|
|
_nextRefreshInterval() {
|
|
// For the first 15 minutes, refresh roughly once every minute so that the
|
|
// experience of composing drafts during initial is less annoying.
|
|
const initialLimit = (60 * 1000) + 15;
|
|
if (this.refreshInterval < initialLimit) {
|
|
return this.refreshInterval + 1;
|
|
}
|
|
// After the first 15 minutes, refresh twice as long each time up to the max.
|
|
return Math.min(this.refreshInterval * 2, this.maxRefreshInterval);
|
|
}
|
|
|
|
fetchData = (callback) => {
|
|
if (NylasEnv.inSpecMode()) { return }
|
|
if (!IdentityStore.identity()) { return }
|
|
|
|
const request = new NylasAPIRequest({
|
|
api: NylasAPI,
|
|
options: {
|
|
accountId: this._accountId,
|
|
path: "/contacts/rankings",
|
|
},
|
|
})
|
|
|
|
request.run()
|
|
.then((json) => {
|
|
if (!json || !(json instanceof Array)) return
|
|
|
|
// Convert rankings into the format needed for quick lookup
|
|
const rankings = {}
|
|
for (const [email, rank] of json) {
|
|
rankings[email.toLowerCase()] = rank
|
|
}
|
|
callback(rankings)
|
|
|
|
this.refreshInterval = this._nextRefreshInterval();
|
|
})
|
|
.catch((err) => {
|
|
console.warn(`Request for Contact Rankings failed for
|
|
account ${this._accountId}. ${err}`)
|
|
})
|
|
}
|
|
}
|
|
|
|
class ContactRankingsCacheManager {
|
|
constructor() {
|
|
this.accountCaches = {};
|
|
this.unsubscribers = [];
|
|
this.onAccountsChanged = _.debounce(this.onAccountsChanged, 100);
|
|
}
|
|
|
|
activate() {
|
|
this.onAccountsChanged();
|
|
this.unsubscribers = [AccountStore.listen(this.onAccountsChanged)];
|
|
}
|
|
|
|
deactivate() {
|
|
this.unsubscribers.forEach(unsub => unsub());
|
|
}
|
|
|
|
onAccountsChanged = async () => {
|
|
const previousIDs = Object.keys(this.accountCaches);
|
|
const latestIDs = AccountStore.accounts().map(a => a.id);
|
|
if (_.isEqual(previousIDs, latestIDs)) {
|
|
return;
|
|
}
|
|
|
|
const newIDs = _.difference(latestIDs, previousIDs);
|
|
const removedIDs = _.difference(previousIDs, latestIDs);
|
|
|
|
console.log(`ContactRankingsCache: Updating contact rankings; added = ${latestIDs}, removed = ${removedIDs}`);
|
|
|
|
for (const newID of newIDs) {
|
|
// Wait until the account has started syncing before trying to fetch
|
|
// contact rankings
|
|
await FolderSyncProgressStore.whenCategoryListSynced(newID)
|
|
this.accountCaches[newID] = new ContactRankingsCache(newID);
|
|
this.accountCaches[newID].start();
|
|
}
|
|
|
|
for (const removedID of removedIDs) {
|
|
if (this.accountCaches[removedID]) {
|
|
this.accountCaches[removedID].end();
|
|
this.accountCaches[removedID] = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default new ContactRankingsCacheManager();
|