feat: add plugin hooks for compose, attachments, search, lifecycle, and routing
This commit is contained in:
@@ -522,6 +522,137 @@ export interface MailtoContext {
|
||||
body?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed to onTransformOutgoingEmail handlers as a transform value.
|
||||
* Handlers receive the email about to be sent and return a (possibly mutated)
|
||||
* copy. Use to inject signatures, rewrite links, strip tracking pixels from
|
||||
* forwards, encrypt the body, etc. Return undefined to pass through unchanged.
|
||||
*/
|
||||
export interface OutgoingEmail {
|
||||
to: string[];
|
||||
cc: string[];
|
||||
bcc: string[];
|
||||
subject: string;
|
||||
htmlBody: string;
|
||||
textBody: string;
|
||||
identityId: string;
|
||||
attachments: { name: string; type: string; size: number }[];
|
||||
/** Original message id when this is a reply or forward */
|
||||
inReplyTo?: string;
|
||||
/** Free-form custom headers added by the composer or earlier handlers */
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed to onBeforeReply / onBeforeReplyAll / onBeforeForward intercept hooks.
|
||||
* Return false to cancel the operation before the composer opens.
|
||||
*/
|
||||
export interface ReplyContext {
|
||||
originalEmailId: string;
|
||||
originalEmail: EmailReadView;
|
||||
mode: 'reply' | 'reply-all' | 'forward';
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes an attachment crossing an attachment hook (upload, download, preview).
|
||||
*/
|
||||
export interface AttachmentInfo {
|
||||
name: string;
|
||||
type: string;
|
||||
size: number;
|
||||
/** JMAP blob id, when known (download / preview / after-upload) */
|
||||
blobId?: string;
|
||||
/** The email this attachment belongs to (download / preview) */
|
||||
emailId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial value passed to the onAttachmentPreview transform hook. A handler
|
||||
* may return a different `previewUrl` (e.g. a proxied/sanitised URL) or a
|
||||
* React component descriptor identified by `customRenderer`. Return undefined
|
||||
* to pass through.
|
||||
*/
|
||||
export interface AttachmentPreview {
|
||||
previewUrl?: string;
|
||||
/** Optional plugin-supplied renderer key. The host resolves the renderer. */
|
||||
customRenderer?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed to onBeforeExternalLink intercept handlers when the user clicks a
|
||||
* link that would navigate away from the app (typically inside an email body).
|
||||
* Return false to cancel the navigation. Mutate `href` to rewrite it.
|
||||
*/
|
||||
export interface ExternalLinkContext {
|
||||
href: string;
|
||||
/** Anchor target ('_blank', '_self', etc.) when set */
|
||||
target?: string;
|
||||
/** Email currently in view, when the click came from an email body */
|
||||
emailId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed to onTextSelectionChange observer when the user selects text inside
|
||||
* the app. Source identifies which surface produced the selection so plugins
|
||||
* can scope themselves (e.g. translate-on-select only inside emails).
|
||||
*/
|
||||
export interface SelectionContext {
|
||||
text: string;
|
||||
source: 'email-body' | 'composer' | 'task-detail' | 'event-detail' | 'other';
|
||||
emailId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned by onCheckEventConflicts transform handlers. The form UI renders
|
||||
* each warning as an inline notice next to the event time fields.
|
||||
*/
|
||||
export interface ConflictWarning {
|
||||
/** Stable unique key per warning, used as React key */
|
||||
key: string;
|
||||
/** Short message — e.g. "Conflicts with: Team Standup" */
|
||||
message: string;
|
||||
severity?: 'info' | 'warning' | 'error';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned by onProvideSearchResults transform handlers. Plugins extend the
|
||||
* initial array with their own results (CRM hits, Slack messages, etc.).
|
||||
* The host renders these in a grouped section below native email results.
|
||||
*/
|
||||
export interface ExternalSearchResult {
|
||||
/** Stable unique key */
|
||||
key: string;
|
||||
title: string;
|
||||
snippet: string;
|
||||
/** Plugin-handled action when the result row is clicked */
|
||||
onClick: () => void;
|
||||
/** Optional source label, e.g. "Slack", "Notion" */
|
||||
source?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned by onProvideRecipientSuggestions transform handlers. Lets plugins
|
||||
* contribute non-contact suggestions (Slack handles, GitHub usernames, etc.)
|
||||
* to the recipient autocomplete in the composer.
|
||||
*/
|
||||
export interface RecipientSuggestion {
|
||||
name: string;
|
||||
email: string;
|
||||
/** Optional source label rendered as a small tag */
|
||||
source?: string;
|
||||
avatarUrl?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passed to router hooks (onNavigate, onRouteEnter, onRouteLeave).
|
||||
* Paths are app-internal, e.g. "/mail/inbox", "/calendar".
|
||||
*/
|
||||
export interface RouteContext {
|
||||
path: string;
|
||||
/** Previous path (only on onNavigate) */
|
||||
from?: string;
|
||||
}
|
||||
|
||||
// ─── Plugin i18n API ─────────────────────────────────────────
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user