Skip to content

Commit

Permalink
Handle mailbox permalinks outside of the thread-sharing plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
bengotow committed Apr 25, 2021
1 parent dae0085 commit 2b89469
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 68 deletions.
1 change: 1 addition & 0 deletions app/internal_packages/message-autoload-images/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"engines": {
"mailspring": "*"
},
"syncInit": true,
"windowTypes": {
"default": true,
"thread-popout": true
Expand Down
3 changes: 3 additions & 0 deletions app/internal_packages/thread-list/lib/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand Down
70 changes: 70 additions & 0 deletions app/internal_packages/thread-list/lib/thread-permalink-handler.ts
Original file line number Diff line number Diff line change
@@ -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);
}
68 changes: 0 additions & 68 deletions app/internal_packages/thread-sharing/lib/main.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

1 comment on commit 2b89469

@foundry376-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit has been mentioned on Mailspring Community. There might be relevant details there:

https://community.getmailspring.com/t/app-link-stopped-working-when-updating-from-1-8-to-1-9-1/1472/5

Please sign in to comment.