Handle mailbox permalinks outside of the thread-sharing plugin

This commit is contained in:
Ben Gotow 2021-04-25 13:14:00 -05:00
parent dae008534b
commit 2b89469bb9
4 changed files with 74 additions and 68 deletions

View file

@ -8,6 +8,7 @@
"engines": {
"mailspring": "*"
},
"syncInit": true,
"windowTypes": {
"default": true,
"thread-popout": true

View file

@ -6,10 +6,13 @@ import ThreadListVertical from './thread-list-vertical';
import ThreadListEmptyFolderBar from './thread-list-empty-folder-bar';
import MessageListToolbar from './message-list-toolbar';
import SelectedItemsStack from './selected-items-stack';
import * as ThreadPermalinkHandler from './thread-permalink-handler';
import { UpButton, DownButton, MoveButtons, FlagButtons } from './thread-toolbar-buttons';
export function activate() {
ThreadPermalinkHandler.activate();
ComponentRegistry.register(ThreadListEmptyFolderBar, {
location: WorkspaceStore.Location.ThreadList,
});

View file

@ -0,0 +1,70 @@
import url from 'url';
import querystring from 'querystring';
import { ipcRenderer } from 'electron';
import { localized, DatabaseStore, Thread, Matcher, Actions } from 'mailspring-exports';
const DATE_EPSILON = 60; // Seconds
interface MailspringLinkParams {
subject: string;
lastDate?: number;
date?: number;
}
const _parseOpenThreadUrl = (mailspringUrlString: string) => {
const parsedUrl = url.parse(mailspringUrlString);
const params = querystring.parse(parsedUrl.query) as any;
return {
subject: params.subject,
date: params.date ? parseInt(params.date, 10) : undefined,
lastDate: params.lastDate ? parseInt(params.lastDate, 10) : undefined,
} as MailspringLinkParams;
};
const _findCorrespondingThread = (
{ subject, lastDate, date }: MailspringLinkParams,
dateEpsilon = DATE_EPSILON
) => {
const dateClause = date
? new Matcher.And([
Thread.attributes.firstMessageTimestamp.lessThan(date + dateEpsilon),
Thread.attributes.firstMessageTimestamp.greaterThan(date - dateEpsilon),
])
: new Matcher.Or([
new Matcher.And([
Thread.attributes.lastMessageSentTimestamp.lessThan(lastDate + dateEpsilon),
Thread.attributes.lastMessageSentTimestamp.greaterThan(lastDate - dateEpsilon),
]),
new Matcher.And([
Thread.attributes.lastMessageReceivedTimestamp.lessThan(lastDate + dateEpsilon),
Thread.attributes.lastMessageReceivedTimestamp.greaterThan(lastDate - dateEpsilon),
]),
]);
return DatabaseStore.findBy<Thread>(Thread).where([
Thread.attributes.subject.equal(subject),
dateClause,
]);
};
const _onOpenThreadFromWeb = (event, mailspringUrl: string) => {
const params = _parseOpenThreadUrl(mailspringUrl);
_findCorrespondingThread(params)
.then(thread => {
if (!thread) {
throw new Error('Thread not found');
}
Actions.popoutThread(thread);
})
.catch(error => {
AppEnv.reportError(error);
AppEnv.showErrorDialog(
localized(`The thread %@ does not exist in your mailbox!`, params.subject)
);
});
};
export function activate() {
ipcRenderer.on('openThreadFromWeb', _onOpenThreadFromWeb);
}

View file

@ -1,13 +1,8 @@
import url from 'url';
import querystring from 'querystring';
import { ipcRenderer } from 'electron';
import fs from 'fs';
import {
localized,
IdentityStore,
DatabaseStore,
Thread,
Matcher,
Message,
Actions,
AttachmentStore,
@ -24,69 +19,8 @@ import ThreadSharingButton from './thread-sharing-button';
export const PLUGIN_NAME = plugin.title;
export const PLUGIN_ID = plugin.name;
const DATE_EPSILON = 60; // Seconds
const _readFile = Promise.promisify(fs.readFile);
interface MailspringLinkParams {
subject: string;
lastDate?: number;
date?: number;
}
const _parseOpenThreadUrl = (mailspringUrlString: string) => {
const parsedUrl = url.parse(mailspringUrlString);
const params = querystring.parse(parsedUrl.query) as any;
return {
subject: params.subject,
date: params.date ? parseInt(params.date, 10) : undefined,
lastDate: params.lastDate ? parseInt(params.lastDate, 10) : undefined,
} as MailspringLinkParams;
};
const _findCorrespondingThread = (
{ subject, lastDate, date }: MailspringLinkParams,
dateEpsilon = DATE_EPSILON
) => {
const dateClause = date
? new Matcher.And([
Thread.attributes.firstMessageTimestamp.lessThan(date + dateEpsilon),
Thread.attributes.firstMessageTimestamp.greaterThan(date - dateEpsilon),
])
: new Matcher.Or([
new Matcher.And([
Thread.attributes.lastMessageSentTimestamp.lessThan(lastDate + dateEpsilon),
Thread.attributes.lastMessageSentTimestamp.greaterThan(lastDate - dateEpsilon),
]),
new Matcher.And([
Thread.attributes.lastMessageReceivedTimestamp.lessThan(lastDate + dateEpsilon),
Thread.attributes.lastMessageReceivedTimestamp.greaterThan(lastDate - dateEpsilon),
]),
]);
return DatabaseStore.findBy<Thread>(Thread).where([
Thread.attributes.subject.equal(subject),
dateClause,
]);
};
const _onOpenThreadFromWeb = (event, mailspringUrl: string) => {
const params = _parseOpenThreadUrl(mailspringUrl);
_findCorrespondingThread(params)
.then(thread => {
if (!thread) {
throw new Error('Thread not found');
}
Actions.popoutThread(thread);
})
.catch(error => {
AppEnv.reportError(error);
AppEnv.showErrorDialog(
localized(`The thread %@ does not exist in your mailbox!`, params.subject)
);
});
};
const _onDatabaseChange = (change: DatabaseChangeRecord<any>) => {
if (change.type !== 'persist' || change.objectClass !== Thread.name) {
return;
@ -226,12 +160,10 @@ export function activate() {
role: 'ThreadActionsToolbarButton',
});
this._unlisten = DatabaseStore.listen(_onDatabaseChange);
ipcRenderer.on('openThreadFromWeb', _onOpenThreadFromWeb);
}
export function deactivate() {
ComponentRegistry.unregister(ThreadSharingButton);
ipcRenderer.removeListener('openThreadFromWeb', _onOpenThreadFromWeb);
if (this._unlisten) {
this._unlisten();
this._unlisten = null;