From 2b89469bb9a98a96b35829994e5a6210faa512b5 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sun, 25 Apr 2021 13:14:00 -0500 Subject: [PATCH] Handle mailbox permalinks outside of the thread-sharing plugin --- .../message-autoload-images/package.json | 1 + app/internal_packages/thread-list/lib/main.ts | 3 + .../lib/thread-permalink-handler.ts | 70 +++++++++++++++++++ .../thread-sharing/lib/main.tsx | 68 ------------------ 4 files changed, 74 insertions(+), 68 deletions(-) create mode 100644 app/internal_packages/thread-list/lib/thread-permalink-handler.ts diff --git a/app/internal_packages/message-autoload-images/package.json b/app/internal_packages/message-autoload-images/package.json index bc34b1984..d0f2021e7 100755 --- a/app/internal_packages/message-autoload-images/package.json +++ b/app/internal_packages/message-autoload-images/package.json @@ -8,6 +8,7 @@ "engines": { "mailspring": "*" }, + "syncInit": true, "windowTypes": { "default": true, "thread-popout": true diff --git a/app/internal_packages/thread-list/lib/main.ts b/app/internal_packages/thread-list/lib/main.ts index 2ee94c107..3d559f4aa 100644 --- a/app/internal_packages/thread-list/lib/main.ts +++ b/app/internal_packages/thread-list/lib/main.ts @@ -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, }); diff --git a/app/internal_packages/thread-list/lib/thread-permalink-handler.ts b/app/internal_packages/thread-list/lib/thread-permalink-handler.ts new file mode 100644 index 000000000..b5c31694d --- /dev/null +++ b/app/internal_packages/thread-list/lib/thread-permalink-handler.ts @@ -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).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); +} diff --git a/app/internal_packages/thread-sharing/lib/main.tsx b/app/internal_packages/thread-sharing/lib/main.tsx index 668319a1c..b1f9cd05c 100644 --- a/app/internal_packages/thread-sharing/lib/main.tsx +++ b/app/internal_packages/thread-sharing/lib/main.tsx @@ -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).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) => { 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;