Mailspring/app/internal_packages/activity-list/lib/activity-list-store.jsx

218 lines
6.8 KiB
JavaScript

import NylasStore from 'nylas-store';
import {
Actions,
Thread,
DatabaseStore,
NativeNotifications,
FocusedPerspectiveStore,
} from 'nylas-exports';
import ActivityListActions from './activity-list-actions';
import ActivityDataSource from './activity-data-source';
import {pluginFor} from './plugin-helpers';
class ActivityListStore extends NylasStore {
activate() {
this.listenTo(ActivityListActions.resetSeen, this._onResetSeen);
this.listenTo(FocusedPerspectiveStore, this._updateActivity);
const start = () => this._getActivity();
if (NylasEnv.inSpecMode()) {
start();
} else {
setTimeout(start, 2000);
}
}
deactivate() {
// todo
}
actions() {
return this._actions;
}
unreadCount() {
if (this._unreadCount < 1000) {
return this._unreadCount;
} else if (!this._unreadCount) {
return null;
}
return "999+";
}
hasBeenViewed(action) {
if (!NylasEnv.savedState.activityListViewed) return false;
return action.timestamp < NylasEnv.savedState.activityListViewed;
}
focusThread(threadId) {
NylasEnv.displayWindow()
Actions.closePopover()
DatabaseStore.find(Thread, threadId).then((thread) => {
if (!thread) {
NylasEnv.reportError(new Error(`ActivityListStore::focusThread: Can't find thread`, {threadId}))
NylasEnv.showErrorDialog(`Can't find the selected thread in your mailbox`)
return;
}
Actions.ensureCategoryIsFocused('sent', thread.accountId);
Actions.setFocus({collection: 'thread', item: thread});
});
}
getRecipient(recipientEmail, recipients) {
if (recipientEmail) {
for (const recipient of recipients) {
if (recipientEmail === recipient.email) {
return recipient;
}
}
} else if (recipients.length === 1) {
return recipients[0];
}
return null;
}
_dataSource() {
return new ActivityDataSource();
}
_onResetSeen() {
NylasEnv.savedState.activityListViewed = Date.now() / 1000;
this._unreadCount = 0;
this.trigger();
}
_getActivity() {
const dataSource = this._dataSource();
this._subscription = dataSource.buildObservable({
openTrackingId: NylasEnv.packages.pluginIdFor('open-tracking'),
linkTrackingId: NylasEnv.packages.pluginIdFor('link-tracking'),
messageLimit: 500,
}).subscribe((messages) => {
this._messages = messages;
this._updateActivity();
});
}
_updateActivity() {
this._actions = this._messages ? this._getActions(this._messages) : [];
this.trigger();
}
_getActions(messages) {
let actions = [];
this._notifications = [];
this._unreadCount = 0;
const sidebarAccountIds = FocusedPerspectiveStore.sidebarAccountIds();
for (const message of messages) {
if (sidebarAccountIds.length > 1 || message.accountId === sidebarAccountIds[0]) {
const openTrackingId = NylasEnv.packages.pluginIdFor('open-tracking')
const linkTrackingId = NylasEnv.packages.pluginIdFor('link-tracking')
if (message.metadataForPluginId(openTrackingId) ||
message.metadataForPluginId(linkTrackingId)) {
actions = actions.concat(this._openActionsForMessage(message));
actions = actions.concat(this._linkActionsForMessage(message));
}
}
}
if (!this._lastNotified) this._lastNotified = {};
for (const notification of this._notifications) {
const lastNotified = this._lastNotified[notification.threadId];
const {notificationInterval} = pluginFor(notification.pluginId);
if (!lastNotified || lastNotified < Date.now() - notificationInterval) {
NativeNotifications.displayNotification(notification.data);
this._lastNotified[notification.threadId] = Date.now();
}
}
const d = new Date();
this._lastChecked = d.getTime() / 1000;
actions = actions.sort((a, b) => b.timestamp - a.timestamp);
// For performance reasons, only display the last 100 actions
if (actions.length > 100) {
actions.length = 100;
}
return actions;
}
_openActionsForMessage(message) {
const openTrackingId = NylasEnv.packages.pluginIdFor('open-tracking')
const openMetadata = message.metadataForPluginId(openTrackingId);
const recipients = message.to.concat(message.cc, message.bcc);
const actions = [];
if (openMetadata) {
if (openMetadata.open_count > 0) {
for (const open of openMetadata.open_data) {
const recipient = this.getRecipient(open.recipient, recipients);
if (open.timestamp > this._lastChecked) {
this._notifications.push({
pluginId: openTrackingId,
threadId: message.threadId,
data: {
title: "New open",
subtitle: `${recipient ? recipient.displayName() : "Someone"} just opened ${message.subject}`,
canReply: false,
tag: "message-open",
onActivate: () => {
this.focusThread(message.threadId);
},
},
});
}
if (!this.hasBeenViewed(open)) this._unreadCount += 1;
actions.push({
messageId: message.id,
threadId: message.threadId,
title: message.subject,
recipient: recipient,
pluginId: openTrackingId,
timestamp: open.timestamp,
});
}
}
}
return actions;
}
_linkActionsForMessage(message) {
const linkTrackingId = NylasEnv.packages.pluginIdFor('link-tracking')
const linkMetadata = message.metadataForPluginId(linkTrackingId)
const recipients = message.to.concat(message.cc, message.bcc);
const actions = [];
if (linkMetadata && linkMetadata.links) {
for (const link of linkMetadata.links) {
for (const click of link.click_data) {
const recipient = this.getRecipient(click.recipient, recipients);
if (click.timestamp > this._lastChecked) {
this._notifications.push({
pluginId: linkTrackingId,
threadId: message.threadId,
data: {
title: "New click",
subtitle: `${recipient ? recipient.displayName() : "Someone"} just clicked ${link.url}.`,
canReply: false,
tag: "link-open",
onActivate: () => {
this.focusThread(message.threadId);
},
},
});
}
if (!this.hasBeenViewed(click)) this._unreadCount += 1;
actions.push({
messageId: message.id,
threadId: message.threadId,
title: link.url,
recipient: recipient,
pluginId: linkTrackingId,
timestamp: click.timestamp,
});
}
}
}
return actions;
}
}
export default new ActivityListStore();