Mailspring/internal_packages/thread-snooze/lib/snooze-store.jsx
Evan Morikawa 7aefb73ef8 feat(usage): add new feature usage modal
Summary:
This adds the "You've reached max features" modal in N1.

http://g.recordit.co/9O7R0mLlXE.gif

Test Plan:
1. Pull latest nylas/cloud-core and start Billing site:
```
  cd cloud-core
  vagrant up
  vagrant ssh
  cd /vagrant
  bin/setup-up-feature-usage
  bin/launch
```
2. Blow away ~/.nylas-mail (err backup your old one first)
3. Restart N1
4. Before logging in, edit `~/.nylas-mail/config.json`
   - set env to "local"
   - remove `thread-snooze` from the list of `disabledPlugins`
5. `cd /nylas-mail/src/k2` and run `npm start`
6. Restart N1 and create accounts & log in

Reviewers: khamidou, juan, halla

Reviewed By: halla

Differential Revision: https://phab.nylas.com/D3846
2017-02-07 15:46:57 -05:00

160 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import _ from 'underscore';
import {React, FeatureUsageStore, Actions, NylasAPIHelpers, AccountStore,
DatabaseStore, Message, CategoryStore} from 'nylas-exports';
import {FeatureUsedUpModal} from 'nylas-component-kit'
import SnoozeUtils from './snooze-utils'
import {PLUGIN_ID, PLUGIN_NAME} from './snooze-constants';
import SnoozeActions from './snooze-actions';
class SnoozeStore {
constructor(pluginId = PLUGIN_ID, pluginName = PLUGIN_NAME) {
this.pluginId = pluginId
this.pluginName = pluginName
this.accountIds = _.pluck(AccountStore.accounts(), 'id')
this.snoozeCategoriesPromise = SnoozeUtils.getSnoozeCategoriesByAccount(AccountStore.accounts())
}
activate() {
this.unsubscribers = [
AccountStore.listen(this.onAccountsChanged),
SnoozeActions.snoozeThreads.listen(this.onSnoozeThreads),
]
}
recordSnoozeEvent(threads, snoozeDate, label) {
try {
const timeInSec = Math.round(((new Date(snoozeDate)).valueOf() - Date.now()) / 1000);
Actions.recordUserEvent("Threads Snoozed", {
timeInSec: timeInSec,
timeInLog10Sec: Math.log10(timeInSec),
label: label,
numItems: threads.length,
});
} catch (e) {
// Do nothing
}
}
groupUpdatedThreads = (threads, snoozeCategoriesByAccount) => {
const getSnoozeCategory = (accId) => snoozeCategoriesByAccount[accId]
const {getInboxCategory} = CategoryStore
const threadsByAccountId = {}
threads.forEach((thread) => {
const accId = thread.accountId
if (!threadsByAccountId[accId]) {
threadsByAccountId[accId] = {
threads: [thread],
snoozeCategoryId: getSnoozeCategory(accId).serverId,
returnCategoryId: getInboxCategory(accId).serverId,
}
} else {
threadsByAccountId[accId].threads.push(thread);
}
});
return Promise.resolve(threadsByAccountId);
};
onAccountsChanged = () => {
const nextIds = _.pluck(AccountStore.accounts(), 'id')
const isSameAccountIds = (
this.accountIds.length === nextIds.length &&
this.accountIds.length === _.intersection(this.accountIds, nextIds).length
)
if (!isSameAccountIds) {
this.accountIds = nextIds
this.snoozeCategoriesPromise = SnoozeUtils.getSnoozeCategoriesByAccount(AccountStore.accounts())
}
};
onSnoozeThreads = (threads, snoozeDate, label) => {
if (!FeatureUsageStore.isUsable("snooze")) {
const featureData = FeatureUsageStore.featureData("snooze");
let headerText = "";
let rechargeText = ""
if (!featureData.quota) {
headerText = "Snooze not yet enabled";
rechargeText = "Upgrade to Pro to start Snoozing"
} else {
headerText = "All Snoozes used";
let time = "later";
if (featureData.period === "hourly") {
time = "next hour"
} else if (featureData.period === "daily") {
time = "tomorrow"
} else if (featureData.period === "weekly") {
time = "next week"
} else if (featureData.period === "monthly") {
time = "next month"
} else if (featureData.period === "yearly") {
time = "next year"
} else if (featureData.period === "unlimited") {
time = "if you upgrade to Pro"
}
rechargeText = `Youll have ${featureData.quota} more snoozes ${time}`
}
Actions.openModal({
component: (
<FeatureUsedUpModal
modalClass="snooze"
featureName="Snooze"
headerText={headerText}
iconUrl="nylas://thread-snooze/assets/ic-snooze-modal@2x.png"
rechargeText={rechargeText}
/>
),
height: 575,
width: 412,
})
return Promise.resolve()
}
this.recordSnoozeEvent(threads, snoozeDate, label)
const accounts = AccountStore.accountsForItems(threads)
const promises = accounts.map((acc) => {
return NylasAPIHelpers.authPlugin(this.pluginId, this.pluginName, acc)
})
return Promise.all(promises)
.then(() => {
return SnoozeUtils.moveThreadsToSnooze(threads, this.snoozeCategoriesPromise, snoozeDate)
})
.then((updatedThreads) => {
return this.snoozeCategoriesPromise
.then(snoozeCategories => this.groupUpdatedThreads(updatedThreads, snoozeCategories))
})
.then((updatedThreadsByAccountId) => {
_.each(updatedThreadsByAccountId, (update) => {
const {snoozeCategoryId, returnCategoryId} = update;
// Get messages for those threads and metadata for those.
DatabaseStore.findAll(Message, {threadId: update.threads.map(t => t.id)}).then((messages) => {
for (const message of messages) {
const header = message.messageIdHeader;
const stableId = message.id;
Actions.setMetadata(message, this.pluginId,
{expiration: snoozeDate, header, stableId, snoozeCategoryId, returnCategoryId})
}
});
});
}).then(() => {
return FeatureUsageStore.useFeature('snooze')
})
.catch((error) => {
SnoozeUtils.moveThreadsFromSnooze(threads, this.snoozeCategoriesPromise)
Actions.closePopover();
NylasEnv.reportError(error);
NylasEnv.showErrorDialog(`Sorry, we were unable to save your snooze settings. ${error.message}`);
});
};
deactivate() {
this.unsubscribers.forEach(unsub => unsub())
}
}
export default SnoozeStore;