2017-08-17 03:45:38 +08:00
|
|
|
import NylasStore from 'nylas-store';
|
|
|
|
|
|
|
|
import {
|
|
|
|
FeatureUsageStore,
|
|
|
|
SyncbackMetadataTask,
|
|
|
|
Actions,
|
|
|
|
DatabaseStore,
|
2017-09-14 16:10:46 +08:00
|
|
|
Thread,
|
2017-08-17 03:45:38 +08:00
|
|
|
} from 'nylas-exports';
|
|
|
|
|
2017-09-27 02:33:08 +08:00
|
|
|
import { moveThreads, snoozedUntilMessage } from './snooze-utils';
|
|
|
|
import { PLUGIN_ID } from './snooze-constants';
|
2017-08-17 03:45:38 +08:00
|
|
|
import SnoozeActions from './snooze-actions';
|
|
|
|
|
|
|
|
class SnoozeStore extends NylasStore {
|
|
|
|
activate() {
|
|
|
|
this.unsubscribers = [
|
2017-09-14 16:10:46 +08:00
|
|
|
SnoozeActions.snoozeThreads.listen(this._onSnoozeThreads),
|
2017-09-27 02:33:08 +08:00
|
|
|
DatabaseStore.listen(change => {
|
2017-09-14 16:10:46 +08:00
|
|
|
if (change.type !== 'metadata-expiration' || change.objectClass !== Thread.name) {
|
|
|
|
return;
|
|
|
|
}
|
2017-09-26 06:44:20 +08:00
|
|
|
this._onMetadataExpired(change.objects);
|
2017-09-14 16:10:46 +08:00
|
|
|
}),
|
2017-08-17 03:45:38 +08:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
deactivate() {
|
2017-09-27 02:33:08 +08:00
|
|
|
this.unsubscribers.forEach(unsub => unsub());
|
2017-08-17 03:45:38 +08:00
|
|
|
}
|
|
|
|
|
2017-09-14 16:10:46 +08:00
|
|
|
_recordSnoozeEvent(threads, snoozeDate, label) {
|
2017-08-17 03:45:38 +08:00
|
|
|
try {
|
2017-09-27 02:33:08 +08:00
|
|
|
const timeInSec = Math.round((new Date(snoozeDate).valueOf() - Date.now()) / 1000);
|
|
|
|
Actions.recordUserEvent('Threads Snoozed', {
|
2017-08-17 03:45:38 +08:00
|
|
|
timeInSec: timeInSec,
|
|
|
|
timeInLog10Sec: Math.log10(timeInSec),
|
|
|
|
label: label,
|
|
|
|
numItems: threads.length,
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 16:10:46 +08:00
|
|
|
_onSnoozeThreads = async (threads, snoozeDate, label) => {
|
2017-08-23 12:49:45 +08:00
|
|
|
try {
|
|
|
|
// ensure the user is authorized to use this feature
|
2017-09-26 06:44:20 +08:00
|
|
|
await FeatureUsageStore.asyncUseFeature('snooze', {
|
2017-09-27 02:33:08 +08:00
|
|
|
usedUpHeader: 'All Snoozes Used',
|
|
|
|
usagePhrase: 'snooze',
|
|
|
|
iconUrl: 'mailspring://thread-snooze/assets/ic-snooze-modal@2x.png',
|
2017-09-26 06:44:20 +08:00
|
|
|
});
|
2017-08-23 12:49:45 +08:00
|
|
|
|
|
|
|
// log to analytics
|
2017-09-14 16:10:46 +08:00
|
|
|
this._recordSnoozeEvent(threads, snoozeDate, label);
|
|
|
|
|
|
|
|
// move the threads to the snoozed folder
|
|
|
|
await moveThreads(threads, {
|
|
|
|
snooze: true,
|
|
|
|
description: snoozedUntilMessage(snoozeDate),
|
2017-09-27 02:33:08 +08:00
|
|
|
});
|
2017-09-14 16:10:46 +08:00
|
|
|
|
|
|
|
// attach metadata to the threads to unsnooze them later
|
2017-09-27 02:33:08 +08:00
|
|
|
Actions.queueTasks(
|
|
|
|
threads.map(
|
|
|
|
model =>
|
|
|
|
new SyncbackMetadataTask({
|
|
|
|
model,
|
|
|
|
pluginId: PLUGIN_ID,
|
|
|
|
value: {
|
|
|
|
expiration: snoozeDate,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
)
|
2017-09-14 16:10:46 +08:00
|
|
|
);
|
2017-08-23 12:49:45 +08:00
|
|
|
} catch (error) {
|
|
|
|
if (error instanceof FeatureUsageStore.NoProAccessError) {
|
|
|
|
return;
|
2017-08-17 03:45:38 +08:00
|
|
|
}
|
2017-09-27 02:33:08 +08:00
|
|
|
moveThreads(threads, { snooze: false, description: 'Unsnoozed' });
|
2017-08-17 03:45:38 +08:00
|
|
|
Actions.closePopover();
|
2017-09-27 02:36:58 +08:00
|
|
|
AppEnv.reportError(error);
|
|
|
|
AppEnv.showErrorDialog(
|
2017-09-27 02:33:08 +08:00
|
|
|
`Sorry, we were unable to save your snooze settings. ${error.message}`
|
|
|
|
);
|
2017-08-23 12:49:45 +08:00
|
|
|
}
|
2017-08-17 03:45:38 +08:00
|
|
|
};
|
2017-09-14 16:10:46 +08:00
|
|
|
|
2017-09-27 02:33:08 +08:00
|
|
|
_onUnsnoozeThreads = threads => {
|
2017-09-14 16:10:46 +08:00
|
|
|
// move the threads back to the inbox
|
2017-09-27 02:33:08 +08:00
|
|
|
moveThreads(threads, { snooze: false, description: 'Unsnoozed' });
|
2017-09-14 16:10:46 +08:00
|
|
|
|
|
|
|
// remove the expiration on the metadata. note this is super important,
|
|
|
|
// otherwise we'll receive a notification from the sync worker over and
|
|
|
|
// over again.
|
2017-09-27 02:33:08 +08:00
|
|
|
Actions.queueTasks(
|
|
|
|
threads.map(
|
|
|
|
model =>
|
|
|
|
new SyncbackMetadataTask({
|
|
|
|
model,
|
|
|
|
pluginId: PLUGIN_ID,
|
|
|
|
value: {
|
|
|
|
expiration: null,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
2017-09-26 06:44:20 +08:00
|
|
|
|
2017-09-27 02:33:08 +08:00
|
|
|
_onMetadataExpired = threads => {
|
|
|
|
const unsnooze = threads.filter(thread => {
|
2017-09-26 06:44:20 +08:00
|
|
|
const metadata = thread.metadataForPluginId(PLUGIN_ID);
|
|
|
|
return metadata && metadata.expiration && metadata.expiration < new Date();
|
|
|
|
});
|
|
|
|
if (unsnooze.length > 0) {
|
|
|
|
this._onUnsnoozeThreads(unsnooze);
|
|
|
|
}
|
2017-09-27 02:33:08 +08:00
|
|
|
};
|
2017-08-17 03:45:38 +08:00
|
|
|
}
|
|
|
|
|
2017-08-23 12:49:45 +08:00
|
|
|
export default new SnoozeStore();
|