@remit/web-client 0.0.324 → 0.0.326
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/harness/index.html +50 -0
- package/dist/harness/vite-preset.d.ts +10 -0
- package/dist/harness/vite-preset.js +151 -0
- package/dist/spellcheck/languages.d.ts +33 -0
- package/dist/spellcheck/languages.js +66 -0
- package/dist/spellcheck/vite-plugin.d.ts +43 -0
- package/dist/spellcheck/vite-plugin.js +294 -0
- package/dist/spellcheck/worker-stub.d.ts +15 -0
- package/dist/spellcheck/worker-stub.js +33 -0
- package/dist/src/auth/AccountMenu.d.ts +1 -0
- package/dist/src/auth/AccountMenu.js +4 -0
- package/dist/src/auth/AccountSession.d.ts +14 -0
- package/dist/src/auth/AccountSession.js +12 -0
- package/dist/src/auth/BetterAuthShell.d.ts +18 -0
- package/dist/src/auth/BetterAuthShell.js +88 -0
- package/dist/src/auth/SessionRateLimited.d.ts +12 -0
- package/dist/src/auth/SessionRateLimited.js +10 -0
- package/dist/src/auth/SignInAgain.d.ts +1 -0
- package/dist/src/auth/SignInAgain.js +6 -0
- package/dist/src/auth/account-menu-mode.d.ts +13 -0
- package/dist/src/auth/account-menu-mode.js +15 -0
- package/dist/src/auth/amplify-config.d.ts +9 -0
- package/dist/src/auth/amplify-config.js +43 -0
- package/dist/src/auth/auth-error.d.ts +42 -0
- package/dist/src/auth/auth-error.js +81 -0
- package/dist/src/auth/auth-interceptor.d.ts +12 -0
- package/dist/src/auth/auth-interceptor.js +24 -0
- package/dist/src/auth/better-auth/BetterAuthAccount.d.ts +7 -0
- package/dist/src/auth/better-auth/BetterAuthAccount.js +18 -0
- package/dist/src/auth/better-auth-config.d.ts +43 -0
- package/dist/src/auth/better-auth-config.js +215 -0
- package/dist/src/auth/better-auth-provider.d.ts +7 -0
- package/dist/src/auth/better-auth-provider.js +15 -0
- package/dist/src/auth/cognito/CognitoAccount.d.ts +8 -0
- package/dist/src/auth/cognito/CognitoAccount.js +32 -0
- package/dist/src/auth/cognito/CognitoShell.d.ts +6 -0
- package/dist/src/auth/cognito/CognitoShell.js +204 -0
- package/dist/src/auth/cognito/cognito-token.d.ts +9 -0
- package/dist/src/auth/cognito/cognito-token.js +36 -0
- package/dist/src/auth/cognito-provider.d.ts +8 -0
- package/dist/src/auth/cognito-provider.js +17 -0
- package/dist/src/auth/combined-provider.d.ts +2 -0
- package/dist/src/auth/combined-provider.js +27 -0
- package/dist/src/auth/provider.d.ts +51 -0
- package/dist/src/auth/provider.js +18 -0
- package/dist/src/auth/session-state.d.ts +29 -0
- package/dist/src/auth/session-state.js +16 -0
- package/dist/src/auth/sign-out-visibility.d.ts +5 -0
- package/dist/src/auth/sign-out-visibility.js +1 -0
- package/dist/src/components/calendar/AgendaStrip.d.ts +64 -0
- package/dist/src/components/calendar/AgendaStrip.js +19 -0
- package/dist/src/components/calendar/AgendaView.d.ts +42 -0
- package/dist/src/components/calendar/AgendaView.js +131 -0
- package/dist/src/components/calendar/CalendarComposePane.d.ts +49 -0
- package/dist/src/components/calendar/CalendarComposePane.js +8 -0
- package/dist/src/components/calendar/CalendarComposeSeed.d.ts +7 -0
- package/dist/src/components/calendar/CalendarComposeSeed.js +19 -0
- package/dist/src/components/calendar/CalendarEventPane.d.ts +48 -0
- package/dist/src/components/calendar/CalendarEventPane.js +48 -0
- package/dist/src/components/calendar/CalendarShell.d.ts +43 -0
- package/dist/src/components/calendar/CalendarShell.js +35 -0
- package/dist/src/components/calendar/CalendarUnavailable.d.ts +13 -0
- package/dist/src/components/calendar/CalendarUnavailable.js +24 -0
- package/dist/src/components/calendar/CalendarViewPlaceholder.d.ts +1 -0
- package/dist/src/components/calendar/CalendarViewPlaceholder.js +5 -0
- package/dist/src/components/calendar/CalendarWaiting.d.ts +25 -0
- package/dist/src/components/calendar/CalendarWaiting.js +14 -0
- package/dist/src/components/calendar/CalendarWorkspace.d.ts +49 -0
- package/dist/src/components/calendar/CalendarWorkspace.js +65 -0
- package/dist/src/components/calendar/ChangeCalendarSuggestion.d.ts +5 -0
- package/dist/src/components/calendar/ChangeCalendarSuggestion.js +66 -0
- package/dist/src/components/calendar/OpenCalendarEvent.d.ts +20 -0
- package/dist/src/components/calendar/OpenCalendarEvent.js +169 -0
- package/dist/src/components/calendar/PendingSuggestions.d.ts +9 -0
- package/dist/src/components/calendar/PendingSuggestions.js +50 -0
- package/dist/src/components/calendar/WriteCalendarEvent.d.ts +13 -0
- package/dist/src/components/calendar/WriteCalendarEvent.js +59 -0
- package/dist/src/components/calendar/calendar-story-fixtures.d.ts +21 -0
- package/dist/src/components/calendar/calendar-story-fixtures.js +95 -0
- package/dist/src/components/calendar/calendar-story-server.d.ts +37 -0
- package/dist/src/components/calendar/calendar-story-server.js +108 -0
- package/dist/src/components/compose/AddressField.d.ts +13 -0
- package/dist/src/components/compose/AddressField.js +23 -0
- package/dist/src/components/compose/ComposeForm.d.ts +31 -0
- package/dist/src/components/compose/ComposeForm.js +925 -0
- package/dist/src/components/compose/ComposeProvider.d.ts +38 -0
- package/dist/src/components/compose/ComposeProvider.js +101 -0
- package/dist/src/components/compose/ComposeSmtpMissingBanner.d.ts +8 -0
- package/dist/src/components/compose/ComposeSmtpMissingBanner.js +10 -0
- package/dist/src/components/compose/ConversationCompose.d.ts +17 -0
- package/dist/src/components/compose/ConversationCompose.js +46 -0
- package/dist/src/components/compose/FromSelector.d.ts +7 -0
- package/dist/src/components/compose/FromSelector.js +29 -0
- package/dist/src/components/compose/FullCompose.d.ts +6 -0
- package/dist/src/components/compose/FullCompose.js +38 -0
- package/dist/src/components/compose/MobileComposeSheet.d.ts +1 -0
- package/dist/src/components/compose/MobileComposeSheet.js +65 -0
- package/dist/src/components/compose/compose-spellcheck.d.ts +17 -0
- package/dist/src/components/compose/compose-spellcheck.js +43 -0
- package/dist/src/components/compose/compose-title.d.ts +9 -0
- package/dist/src/components/compose/compose-title.js +9 -0
- package/dist/src/components/compose/mail-sync-off-refusal.d.ts +1 -0
- package/dist/src/components/compose/mail-sync-off-refusal.js +7 -0
- package/dist/src/components/compose/quoted-message.d.ts +59 -0
- package/dist/src/components/compose/quoted-message.js +162 -0
- package/dist/src/components/compose/reply-with-times.d.ts +6 -0
- package/dist/src/components/compose/reply-with-times.js +12 -0
- package/dist/src/components/config-import/ConfigImportWizard.d.ts +24 -0
- package/dist/src/components/config-import/ConfigImportWizard.js +425 -0
- package/dist/src/components/config-import/config-import.fixtures.d.ts +27 -0
- package/dist/src/components/config-import/config-import.fixtures.js +167 -0
- package/dist/src/components/config-import/steps.d.ts +100 -0
- package/dist/src/components/config-import/steps.js +143 -0
- package/dist/src/components/layout/AppShellSkeleton.d.ts +9 -0
- package/dist/src/components/layout/AppShellSkeleton.js +12 -0
- package/dist/src/components/layout/ComposeFab.d.ts +12 -0
- package/dist/src/components/layout/ComposeFab.js +21 -0
- package/dist/src/components/layout/Drawer.d.ts +28 -0
- package/dist/src/components/layout/Drawer.js +37 -0
- package/dist/src/components/layout/MailShell.d.ts +51 -0
- package/dist/src/components/layout/MailShell.js +39 -0
- package/dist/src/components/layout/MailTopBar.d.ts +14 -0
- package/dist/src/components/layout/MailTopBar.js +44 -0
- package/dist/src/components/mail/AuthenticityBanner.d.ts +14 -0
- package/dist/src/components/mail/AuthenticityBanner.js +18 -0
- package/dist/src/components/mail/AutoMovedIndicator.d.ts +20 -0
- package/dist/src/components/mail/AutoMovedIndicator.js +25 -0
- package/dist/src/components/mail/BlockedImagesNotice.d.ts +17 -0
- package/dist/src/components/mail/BlockedImagesNotice.js +8 -0
- package/dist/src/components/mail/BriefPane.d.ts +33 -0
- package/dist/src/components/mail/BriefPane.js +255 -0
- package/dist/src/components/mail/BulkRunProvider.d.ts +90 -0
- package/dist/src/components/mail/BulkRunProvider.js +203 -0
- package/dist/src/components/mail/ConversationView.d.ts +52 -0
- package/dist/src/components/mail/ConversationView.js +279 -0
- package/dist/src/components/mail/DailyBrief.d.ts +46 -0
- package/dist/src/components/mail/DailyBrief.js +584 -0
- package/dist/src/components/mail/DeleteConfirmDialog.d.ts +25 -0
- package/dist/src/components/mail/DeleteConfirmDialog.js +70 -0
- package/dist/src/components/mail/DraftsView.d.ts +15 -0
- package/dist/src/components/mail/DraftsView.js +84 -0
- package/dist/src/components/mail/EmptyTrashBar.d.ts +47 -0
- package/dist/src/components/mail/EmptyTrashBar.js +73 -0
- package/dist/src/components/mail/FlaggedList.d.ts +20 -0
- package/dist/src/components/mail/FlaggedList.js +173 -0
- package/dist/src/components/mail/FlaggedPane.d.ts +29 -0
- package/dist/src/components/mail/FlaggedPane.js +225 -0
- package/dist/src/components/mail/IntelligenceDrawer.d.ts +19 -0
- package/dist/src/components/mail/IntelligenceDrawer.js +16 -0
- package/dist/src/components/mail/IntelligencePane.d.ts +59 -0
- package/dist/src/components/mail/IntelligencePane.js +130 -0
- package/dist/src/components/mail/LabelApplyTrigger.d.ts +15 -0
- package/dist/src/components/mail/LabelApplyTrigger.js +29 -0
- package/dist/src/components/mail/MailListHeader.d.ts +102 -0
- package/dist/src/components/mail/MailListHeader.js +303 -0
- package/dist/src/components/mail/MailNav.d.ts +17 -0
- package/dist/src/components/mail/MailNav.js +20 -0
- package/dist/src/components/mail/MailSidebarAdapter.d.ts +23 -0
- package/dist/src/components/mail/MailSidebarAdapter.js +161 -0
- package/dist/src/components/mail/MailViewChrome.d.ts +54 -0
- package/dist/src/components/mail/MailViewChrome.js +43 -0
- package/dist/src/components/mail/MailboxPane.d.ts +36 -0
- package/dist/src/components/mail/MailboxPane.js +705 -0
- package/dist/src/components/mail/MessageActionMenu.d.ts +36 -0
- package/dist/src/components/mail/MessageActionMenu.js +129 -0
- package/dist/src/components/mail/MessageAttachments.d.ts +21 -0
- package/dist/src/components/mail/MessageAttachments.js +96 -0
- package/dist/src/components/mail/MessageBody.d.ts +72 -0
- package/dist/src/components/mail/MessageBody.js +68 -0
- package/dist/src/components/mail/MessageBodyErrorBanner.d.ts +20 -0
- package/dist/src/components/mail/MessageBodyErrorBanner.js +29 -0
- package/dist/src/components/mail/MessageCard.d.ts +29 -0
- package/dist/src/components/mail/MessageCard.js +77 -0
- package/dist/src/components/mail/MessageList.d.ts +130 -0
- package/dist/src/components/mail/MessageList.js +896 -0
- package/dist/src/components/mail/MessageListItem.d.ts +32 -0
- package/dist/src/components/mail/MessageListItem.js +41 -0
- package/dist/src/components/mail/MessageRow.d.ts +57 -0
- package/dist/src/components/mail/MessageRow.js +137 -0
- package/dist/src/components/mail/MessageSettlementAlert.d.ts +27 -0
- package/dist/src/components/mail/MessageSettlementAlert.js +79 -0
- package/dist/src/components/mail/MessageToolbar.d.ts +58 -0
- package/dist/src/components/mail/MessageToolbar.js +80 -0
- package/dist/src/components/mail/MobileMessageBar.d.ts +25 -0
- package/dist/src/components/mail/MobileMessageBar.js +61 -0
- package/dist/src/components/mail/MoveToTrigger.d.ts +30 -0
- package/dist/src/components/mail/MoveToTrigger.js +114 -0
- package/dist/src/components/mail/NavMenuButton.d.ts +1 -0
- package/dist/src/components/mail/NavMenuButton.js +17 -0
- package/dist/src/components/mail/OutboxPane.d.ts +27 -0
- package/dist/src/components/mail/OutboxPane.js +247 -0
- package/dist/src/components/mail/PullToRefresh.d.ts +12 -0
- package/dist/src/components/mail/PullToRefresh.js +12 -0
- package/dist/src/components/mail/RawMessageView.d.ts +18 -0
- package/dist/src/components/mail/RawMessageView.js +30 -0
- package/dist/src/components/mail/RoleAppointmentPromptProvider.d.ts +39 -0
- package/dist/src/components/mail/RoleAppointmentPromptProvider.js +137 -0
- package/dist/src/components/mail/SelectionWizardHost.d.ts +110 -0
- package/dist/src/components/mail/SelectionWizardHost.js +721 -0
- package/dist/src/components/mail/SpamRescue.d.ts +17 -0
- package/dist/src/components/mail/SpamRescue.js +64 -0
- package/dist/src/components/mail/SwipeableMessageRow.d.ts +31 -0
- package/dist/src/components/mail/SwipeableMessageRow.js +69 -0
- package/dist/src/components/mail/ThreadListInteraction.d.ts +106 -0
- package/dist/src/components/mail/ThreadListInteraction.js +319 -0
- package/dist/src/components/mail/bulk-run-state.d.ts +37 -0
- package/dist/src/components/mail/bulk-run-state.js +64 -0
- package/dist/src/components/mail/intelligence-story-calendar.d.ts +7 -0
- package/dist/src/components/mail/intelligence-story-calendar.js +17 -0
- package/dist/src/components/mail/message-body-error-banner-content.d.ts +31 -0
- package/dist/src/components/mail/message-body-error-banner-content.js +70 -0
- package/dist/src/components/mail/organize-run-state.d.ts +26 -0
- package/dist/src/components/mail/organize-run-state.js +24 -0
- package/dist/src/components/mail/selection-wizard-run-controls.d.ts +66 -0
- package/dist/src/components/mail/selection-wizard-run-controls.js +65 -0
- package/dist/src/components/mail/useModifierSelect.d.ts +35 -0
- package/dist/src/components/mail/useModifierSelect.js +75 -0
- package/dist/src/components/onboarding/OnboardingWizard.d.ts +83 -0
- package/dist/src/components/onboarding/OnboardingWizard.js +661 -0
- package/dist/src/components/onboarding/credential-steps.d.ts +58 -0
- package/dist/src/components/onboarding/credential-steps.js +198 -0
- package/dist/src/components/self-update/SelfUpdateOverlay.d.ts +1 -0
- package/dist/src/components/self-update/SelfUpdateOverlay.js +25 -0
- package/dist/src/components/settings/AccountFormPanel.d.ts +29 -0
- package/dist/src/components/settings/AccountFormPanel.js +337 -0
- package/dist/src/components/settings/AccountServices.d.ts +6 -0
- package/dist/src/components/settings/AccountServices.js +100 -0
- package/dist/src/components/settings/AccountServicesCard.d.ts +16 -0
- package/dist/src/components/settings/AccountServicesCard.js +13 -0
- package/dist/src/components/settings/AdvancedNavIcon.d.ts +1 -0
- package/dist/src/components/settings/AdvancedNavIcon.js +17 -0
- package/dist/src/components/settings/CalendarCreateCard.d.ts +12 -0
- package/dist/src/components/settings/CalendarCreateCard.js +42 -0
- package/dist/src/components/settings/CalendarDetailsForm.d.ts +15 -0
- package/dist/src/components/settings/CalendarDetailsForm.js +34 -0
- package/dist/src/components/settings/CalendarFeedCard.d.ts +18 -0
- package/dist/src/components/settings/CalendarFeedCard.js +58 -0
- package/dist/src/components/settings/CalendarFeedPanel.d.ts +13 -0
- package/dist/src/components/settings/CalendarFeedPanel.js +7 -0
- package/dist/src/components/settings/CalendarSettingsPanel.d.ts +13 -0
- package/dist/src/components/settings/CalendarSettingsPanel.js +21 -0
- package/dist/src/components/settings/CalendarSubscribeCard.d.ts +11 -0
- package/dist/src/components/settings/CalendarSubscribeCard.js +30 -0
- package/dist/src/components/settings/CalendarSubscriptionStatus.d.ts +12 -0
- package/dist/src/components/settings/CalendarSubscriptionStatus.js +20 -0
- package/dist/src/components/settings/ConfigExportCard.d.ts +18 -0
- package/dist/src/components/settings/ConfigExportCard.js +16 -0
- package/dist/src/components/settings/ConfigTransferPanel.d.ts +15 -0
- package/dist/src/components/settings/ConfigTransferPanel.js +55 -0
- package/dist/src/components/settings/DangerZone.d.ts +1 -0
- package/dist/src/components/settings/DangerZone.js +8 -0
- package/dist/src/components/settings/DeleteAccountDialog.d.ts +13 -0
- package/dist/src/components/settings/DeleteAccountDialog.js +62 -0
- package/dist/src/components/settings/DeleteFolderDialog.d.ts +21 -0
- package/dist/src/components/settings/DeleteFolderDialog.js +116 -0
- package/dist/src/components/settings/FilterActionError.d.ts +8 -0
- package/dist/src/components/settings/FilterActionError.js +10 -0
- package/dist/src/components/settings/FilterEditor.d.ts +22 -0
- package/dist/src/components/settings/FilterEditor.js +143 -0
- package/dist/src/components/settings/FilterEditorSurface.d.ts +18 -0
- package/dist/src/components/settings/FilterEditorSurface.js +18 -0
- package/dist/src/components/settings/FiltersList.d.ts +31 -0
- package/dist/src/components/settings/FiltersList.js +58 -0
- package/dist/src/components/settings/LabelsList.d.ts +15 -0
- package/dist/src/components/settings/LabelsList.js +37 -0
- package/dist/src/components/settings/SelfUpdatePanel.d.ts +1 -0
- package/dist/src/components/settings/SelfUpdatePanel.js +19 -0
- package/dist/src/components/settings/TimeZoneSelect.d.ts +12 -0
- package/dist/src/components/settings/TimeZoneSelect.js +10 -0
- package/dist/src/components/settings/TlsRootCaDownload.d.ts +1 -0
- package/dist/src/components/settings/TlsRootCaDownload.js +15 -0
- package/dist/src/components/settings/WarningsNavIcon.d.ts +1 -0
- package/dist/src/components/settings/WarningsNavIcon.js +8 -0
- package/dist/src/components/settings/WarningsPanel.d.ts +21 -0
- package/dist/src/components/settings/WarningsPanel.js +93 -0
- package/dist/src/components/settings/account-form-helpers.d.ts +53 -0
- package/dist/src/components/settings/account-form-helpers.js +78 -0
- package/dist/src/components/ui/AppVersion.d.ts +12 -0
- package/dist/src/components/ui/AppVersion.js +19 -0
- package/dist/src/components/ui/BugReportButton.d.ts +6 -0
- package/dist/src/components/ui/BugReportButton.js +11 -0
- package/dist/src/components/ui/ErrorBannerProvider.d.ts +27 -0
- package/dist/src/components/ui/ErrorBannerProvider.js +82 -0
- package/dist/src/components/ui/FatalErrorOverlay.d.ts +31 -0
- package/dist/src/components/ui/FatalErrorOverlay.js +71 -0
- package/dist/src/components/ui/error-banners.d.ts +43 -0
- package/dist/src/components/ui/error-banners.js +69 -0
- package/dist/src/components/ui/folder-role-refusal.d.ts +29 -0
- package/dist/src/components/ui/folder-role-refusal.js +44 -0
- package/dist/src/components/ui/placement-refusal.d.ts +31 -0
- package/dist/src/components/ui/placement-refusal.js +39 -0
- package/dist/src/hooks/calendar/agenda-window.d.ts +110 -0
- package/dist/src/hooks/calendar/agenda-window.js +159 -0
- package/dist/src/hooks/calendar/draft.d.ts +59 -0
- package/dist/src/hooks/calendar/draft.js +142 -0
- package/dist/src/hooks/calendar/index.d.ts +24 -0
- package/dist/src/hooks/calendar/index.js +24 -0
- package/dist/src/hooks/calendar/instance.d.ts +61 -0
- package/dist/src/hooks/calendar/instance.js +145 -0
- package/dist/src/hooks/calendar/recurrence-rule.d.ts +29 -0
- package/dist/src/hooks/calendar/recurrence-rule.js +159 -0
- package/dist/src/hooks/calendar/resource.d.ts +14 -0
- package/dist/src/hooks/calendar/resource.js +87 -0
- package/dist/src/hooks/calendar/selection.d.ts +38 -0
- package/dist/src/hooks/calendar/selection.js +54 -0
- package/dist/src/hooks/calendar/suggestion-draft.d.ts +11 -0
- package/dist/src/hooks/calendar/suggestion-draft.js +45 -0
- package/dist/src/hooks/calendar/useCalendarCollectionWrites.d.ts +26 -0
- package/dist/src/hooks/calendar/useCalendarCollectionWrites.js +75 -0
- package/dist/src/hooks/calendar/useCalendarEvent.d.ts +8 -0
- package/dist/src/hooks/calendar/useCalendarEvent.js +32 -0
- package/dist/src/hooks/calendar/useCalendarEvents.d.ts +58 -0
- package/dist/src/hooks/calendar/useCalendarEvents.js +128 -0
- package/dist/src/hooks/calendar/useCalendarFeed.d.ts +29 -0
- package/dist/src/hooks/calendar/useCalendarFeed.js +115 -0
- package/dist/src/hooks/calendar/useCalendarFreeBusy.d.ts +15 -0
- package/dist/src/hooks/calendar/useCalendarFreeBusy.js +61 -0
- package/dist/src/hooks/calendar/useCalendarJump.d.ts +24 -0
- package/dist/src/hooks/calendar/useCalendarJump.js +95 -0
- package/dist/src/hooks/calendar/useCalendarSubscriptions.d.ts +17 -0
- package/dist/src/hooks/calendar/useCalendarSubscriptions.js +66 -0
- package/dist/src/hooks/calendar/useCalendarSuggestions.d.ts +45 -0
- package/dist/src/hooks/calendar/useCalendarSuggestions.js +171 -0
- package/dist/src/hooks/calendar/useCalendarWrites.d.ts +44 -0
- package/dist/src/hooks/calendar/useCalendarWrites.js +109 -0
- package/dist/src/hooks/calendar/useCalendars.d.ts +20 -0
- package/dist/src/hooks/calendar/useCalendars.js +30 -0
- package/dist/src/hooks/calendar/useDraftClashes.d.ts +15 -0
- package/dist/src/hooks/calendar/useDraftClashes.js +68 -0
- package/dist/src/hooks/calendar/window.d.ts +57 -0
- package/dist/src/hooks/calendar/window.js +135 -0
- package/dist/src/hooks/queries/keys.d.ts +5 -0
- package/dist/src/hooks/queries/keys.js +5 -0
- package/dist/src/hooks/use-system-update.d.ts +40 -0
- package/dist/src/hooks/use-system-update.js +237 -0
- package/dist/src/hooks/useApplyLabel.d.ts +17 -0
- package/dist/src/hooks/useApplyLabel.js +41 -0
- package/dist/src/hooks/useArchiveMailbox.d.ts +74 -0
- package/dist/src/hooks/useArchiveMailbox.js +120 -0
- package/dist/src/hooks/useAutoMovedBadge.d.ts +56 -0
- package/dist/src/hooks/useAutoMovedBadge.js +86 -0
- package/dist/src/hooks/useBriefSections.d.ts +70 -0
- package/dist/src/hooks/useBriefSections.js +210 -0
- package/dist/src/hooks/useCalendarData.d.ts +37 -0
- package/dist/src/hooks/useCalendarData.js +23 -0
- package/dist/src/hooks/useClauseSuggestions.d.ts +14 -0
- package/dist/src/hooks/useClauseSuggestions.js +39 -0
- package/dist/src/hooks/useComposeAttachments.d.ts +20 -0
- package/dist/src/hooks/useComposeAttachments.js +72 -0
- package/dist/src/hooks/useComposeLanguages.d.ts +11 -0
- package/dist/src/hooks/useComposeLanguages.js +44 -0
- package/dist/src/hooks/useCreateMailbox.d.ts +40 -0
- package/dist/src/hooks/useCreateMailbox.js +123 -0
- package/dist/src/hooks/useCurrentMailboxName.d.ts +39 -0
- package/dist/src/hooks/useCurrentMailboxName.js +109 -0
- package/dist/src/hooks/useDebouncedValue.d.ts +1 -0
- package/dist/src/hooks/useDebouncedValue.js +9 -0
- package/dist/src/hooks/useDeleteFolder.d.ts +36 -0
- package/dist/src/hooks/useDeleteFolder.js +280 -0
- package/dist/src/hooks/useDeleteMessages.d.ts +41 -0
- package/dist/src/hooks/useDeleteMessages.js +171 -0
- package/dist/src/hooks/useDeleteOutcome.d.ts +14 -0
- package/dist/src/hooks/useDeleteOutcome.js +46 -0
- package/dist/src/hooks/useEmptyTrash.d.ts +16 -0
- package/dist/src/hooks/useEmptyTrash.js +130 -0
- package/dist/src/hooks/useEscalatedActions.d.ts +83 -0
- package/dist/src/hooks/useEscalatedActions.js +175 -0
- package/dist/src/hooks/useFilters.d.ts +57 -0
- package/dist/src/hooks/useFilters.js +147 -0
- package/dist/src/hooks/useFolderLabelTranslator.d.ts +6 -0
- package/dist/src/hooks/useFolderLabelTranslator.js +11 -0
- package/dist/src/hooks/useFollowFocusOpen.d.ts +28 -0
- package/dist/src/hooks/useFollowFocusOpen.js +52 -0
- package/dist/src/hooks/useInitialSyncProgress.d.ts +41 -0
- package/dist/src/hooks/useInitialSyncProgress.js +111 -0
- package/dist/src/hooks/useInlineImages.d.ts +16 -0
- package/dist/src/hooks/useInlineImages.js +52 -0
- package/dist/src/hooks/useIntelligenceCalendar.d.ts +20 -0
- package/dist/src/hooks/useIntelligenceCalendar.js +230 -0
- package/dist/src/hooks/useIntelligenceData.d.ts +58 -0
- package/dist/src/hooks/useIntelligenceData.js +242 -0
- package/dist/src/hooks/useIntelligenceDrawer.d.ts +21 -0
- package/dist/src/hooks/useIntelligenceDrawer.js +22 -0
- package/dist/src/hooks/useIntelligenceSurface.d.ts +44 -0
- package/dist/src/hooks/useIntelligenceSurface.js +57 -0
- package/dist/src/hooks/useIsDark.d.ts +8 -0
- package/dist/src/hooks/useIsDark.js +21 -0
- package/dist/src/hooks/useKeyboardNavigation.d.ts +57 -0
- package/dist/src/hooks/useKeyboardNavigation.js +61 -0
- package/dist/src/hooks/useLabels.d.ts +40 -0
- package/dist/src/hooks/useLabels.js +98 -0
- package/dist/src/hooks/useLayoutTier.d.ts +33 -0
- package/dist/src/hooks/useLayoutTier.js +33 -0
- package/dist/src/hooks/useMailboxAccount.d.ts +18 -0
- package/dist/src/hooks/useMailboxAccount.js +48 -0
- package/dist/src/hooks/useMailboxNameIndex.d.ts +2 -0
- package/dist/src/hooks/useMailboxNameIndex.js +21 -0
- package/dist/src/hooks/useMarkAsRead.d.ts +59 -0
- package/dist/src/hooks/useMarkAsRead.js +206 -0
- package/dist/src/hooks/useMatchSample.d.ts +30 -0
- package/dist/src/hooks/useMatchSample.js +74 -0
- package/dist/src/hooks/useMediaQuery.d.ts +11 -0
- package/dist/src/hooks/useMediaQuery.js +12 -0
- package/dist/src/hooks/useMessageBodyContent.d.ts +148 -0
- package/dist/src/hooks/useMessageBodyContent.js +272 -0
- package/dist/src/hooks/useMoveMessages.d.ts +27 -0
- package/dist/src/hooks/useMoveMessages.js +128 -0
- package/dist/src/hooks/useOrganizeJob.d.ts +39 -0
- package/dist/src/hooks/useOrganizeJob.js +95 -0
- package/dist/src/hooks/useRailPanels.d.ts +17 -0
- package/dist/src/hooks/useRailPanels.js +94 -0
- package/dist/src/hooks/useRedirectEnded.d.ts +41 -0
- package/dist/src/hooks/useRedirectEnded.js +106 -0
- package/dist/src/hooks/useRefreshControl.d.ts +97 -0
- package/dist/src/hooks/useRefreshControl.js +234 -0
- package/dist/src/hooks/useReportSpam.d.ts +102 -0
- package/dist/src/hooks/useReportSpam.js +173 -0
- package/dist/src/hooks/useRescueCandidates.d.ts +15 -0
- package/dist/src/hooks/useRescueCandidates.js +41 -0
- package/dist/src/hooks/useResultCount.d.ts +26 -0
- package/dist/src/hooks/useResultCount.js +40 -0
- package/dist/src/hooks/useResultFolderIndex.d.ts +8 -0
- package/dist/src/hooks/useResultFolderIndex.js +45 -0
- package/dist/src/hooks/useReturnFromRedirect.d.ts +19 -0
- package/dist/src/hooks/useReturnFromRedirect.js +38 -0
- package/dist/src/hooks/useRulePreview.d.ts +28 -0
- package/dist/src/hooks/useRulePreview.js +77 -0
- package/dist/src/hooks/useSaveDraft.d.ts +31 -0
- package/dist/src/hooks/useSaveDraft.js +183 -0
- package/dist/src/hooks/useSearchScope.d.ts +15 -0
- package/dist/src/hooks/useSearchScope.js +30 -0
- package/dist/src/hooks/useSearchSuggestions.d.ts +12 -0
- package/dist/src/hooks/useSearchSuggestions.js +77 -0
- package/dist/src/hooks/useSearchTokenContext.d.ts +16 -0
- package/dist/src/hooks/useSearchTokenContext.js +26 -0
- package/dist/src/hooks/useSelectedSubjects.d.ts +6 -0
- package/dist/src/hooks/useSelectedSubjects.js +62 -0
- package/dist/src/hooks/useSignature.d.ts +9 -0
- package/dist/src/hooks/useSignature.js +47 -0
- package/dist/src/hooks/useSpamMatchCounts.d.ts +15 -0
- package/dist/src/hooks/useSpamMatchCounts.js +74 -0
- package/dist/src/hooks/useStaleAccountSync.d.ts +101 -0
- package/dist/src/hooks/useStaleAccountSync.js +252 -0
- package/dist/src/hooks/useStarredThreads.d.ts +42 -0
- package/dist/src/hooks/useStarredThreads.js +100 -0
- package/dist/src/hooks/useThreadActions.d.ts +41 -0
- package/dist/src/hooks/useThreadActions.js +64 -0
- package/dist/src/hooks/useThreadMessageIds.d.ts +10 -0
- package/dist/src/hooks/useThreadMessageIds.js +22 -0
- package/dist/src/hooks/useThreadRow.d.ts +23 -0
- package/dist/src/hooks/useThreadRow.js +40 -0
- package/dist/src/hooks/useToggleStar.d.ts +31 -0
- package/dist/src/hooks/useToggleStar.js +96 -0
- package/dist/src/hooks/useToggleTrusted.d.ts +23 -0
- package/dist/src/hooks/useToggleTrusted.js +100 -0
- package/dist/src/hooks/useTriageLayer.d.ts +80 -0
- package/dist/src/hooks/useTriageLayer.js +99 -0
- package/dist/src/hooks/useTriggerSync.d.ts +30 -0
- package/dist/src/hooks/useTriggerSync.js +42 -0
- package/dist/src/hooks/useUpdateAddressFlags.d.ts +18 -0
- package/dist/src/hooks/useUpdateAddressFlags.js +93 -0
- package/dist/src/hooks/useUpdateFilter.d.ts +16 -0
- package/dist/src/hooks/useUpdateFilter.js +45 -0
- package/dist/src/hooks/useVisualViewport.d.ts +13 -0
- package/dist/src/hooks/useVisualViewport.js +37 -0
- package/dist/src/hooks/useWarningsAttention.d.ts +9 -0
- package/dist/src/hooks/useWarningsAttention.js +31 -0
- package/dist/src/index.css +27 -0
- package/dist/src/lib/account-order.d.ts +3 -0
- package/dist/src/lib/account-order.js +6 -0
- package/dist/src/lib/adjacent-message.d.ts +9 -0
- package/dist/src/lib/adjacent-message.js +19 -0
- package/dist/src/lib/api.d.ts +35 -0
- package/dist/src/lib/api.js +73 -0
- package/dist/src/lib/app-info.d.ts +24 -0
- package/dist/src/lib/app-info.js +26 -0
- package/dist/src/lib/attachment-download.d.ts +63 -0
- package/dist/src/lib/attachment-download.js +130 -0
- package/dist/src/lib/auto-moved.d.ts +46 -0
- package/dist/src/lib/auto-moved.js +82 -0
- package/dist/src/lib/autodiscovery.d.ts +42 -0
- package/dist/src/lib/autodiscovery.js +320 -0
- package/dist/src/lib/brief-criteria.d.ts +69 -0
- package/dist/src/lib/brief-criteria.js +62 -0
- package/dist/src/lib/brief.d.ts +98 -0
- package/dist/src/lib/brief.js +164 -0
- package/dist/src/lib/bug-report.d.ts +67 -0
- package/dist/src/lib/bug-report.js +212 -0
- package/dist/src/lib/bulk-action-copy.d.ts +67 -0
- package/dist/src/lib/bulk-action-copy.js +106 -0
- package/dist/src/lib/bulk-actions.d.ts +228 -0
- package/dist/src/lib/bulk-actions.js +242 -0
- package/dist/src/lib/calendar-collection-copy.d.ts +7 -0
- package/dist/src/lib/calendar-collection-copy.js +12 -0
- package/dist/src/lib/calendar-density.d.ts +26 -0
- package/dist/src/lib/calendar-density.js +31 -0
- package/dist/src/lib/calendar-feed-copy.d.ts +14 -0
- package/dist/src/lib/calendar-feed-copy.js +16 -0
- package/dist/src/lib/calendar-feed-url.d.ts +9 -0
- package/dist/src/lib/calendar-feed-url.js +11 -0
- package/dist/src/lib/calendar-format.d.ts +25 -0
- package/dist/src/lib/calendar-format.js +57 -0
- package/dist/src/lib/calendar-report.d.ts +4 -0
- package/dist/src/lib/calendar-report.js +15 -0
- package/dist/src/lib/calendar-route.d.ts +93 -0
- package/dist/src/lib/calendar-route.js +145 -0
- package/dist/src/lib/calendar-subscription.d.ts +6 -0
- package/dist/src/lib/calendar-subscription.js +8 -0
- package/dist/src/lib/calendar-suggestion.d.ts +56 -0
- package/dist/src/lib/calendar-suggestion.js +165 -0
- package/dist/src/lib/client.d.ts +2 -0
- package/dist/src/lib/client.js +30 -0
- package/dist/src/lib/compose-attachment-controller.d.ts +90 -0
- package/dist/src/lib/compose-attachment-controller.js +359 -0
- package/dist/src/lib/config-import.d.ts +136 -0
- package/dist/src/lib/config-import.js +371 -0
- package/dist/src/lib/console-errors.d.ts +16 -0
- package/dist/src/lib/console-errors.js +80 -0
- package/dist/src/lib/conversation-target.d.ts +16 -0
- package/dist/src/lib/conversation-target.js +1 -0
- package/dist/src/lib/dedupe-thread-messages.d.ts +14 -0
- package/dist/src/lib/dedupe-thread-messages.js +23 -0
- package/dist/src/lib/delete-folder.d.ts +66 -0
- package/dist/src/lib/delete-folder.js +110 -0
- package/dist/src/lib/display-category.d.ts +18 -0
- package/dist/src/lib/display-category.js +20 -0
- package/dist/src/lib/drafts.d.ts +50 -0
- package/dist/src/lib/drafts.js +91 -0
- package/dist/src/lib/error-classifier.d.ts +155 -0
- package/dist/src/lib/error-classifier.js +213 -0
- package/dist/src/lib/escalation-label.d.ts +18 -0
- package/dist/src/lib/escalation-label.js +20 -0
- package/dist/src/lib/fatal-error.d.ts +68 -0
- package/dist/src/lib/fatal-error.js +88 -0
- package/dist/src/lib/filter-report.d.ts +2 -0
- package/dist/src/lib/filter-report.js +13 -0
- package/dist/src/lib/flagged-criteria.d.ts +36 -0
- package/dist/src/lib/flagged-criteria.js +22 -0
- package/dist/src/lib/folder-failure.d.ts +2 -0
- package/dist/src/lib/folder-failure.js +8 -0
- package/dist/src/lib/folder-roles.d.ts +33 -0
- package/dist/src/lib/folder-roles.js +83 -0
- package/dist/src/lib/format.d.ts +156 -0
- package/dist/src/lib/format.js +269 -0
- package/dist/src/lib/fresh-mailbox-count.d.ts +76 -0
- package/dist/src/lib/fresh-mailbox-count.js +37 -0
- package/dist/src/lib/hot-sync-window.d.ts +28 -0
- package/dist/src/lib/hot-sync-window.js +41 -0
- package/dist/src/lib/i18n.d.ts +2 -0
- package/dist/src/lib/i18n.js +29 -0
- package/dist/src/lib/inbox-filters.d.ts +76 -0
- package/dist/src/lib/inbox-filters.js +95 -0
- package/dist/src/lib/intelligence-pref.d.ts +43 -0
- package/dist/src/lib/intelligence-pref.js +41 -0
- package/dist/src/lib/json.d.ts +8 -0
- package/dist/src/lib/json.js +10 -0
- package/dist/src/lib/junk-destination.d.ts +15 -0
- package/dist/src/lib/junk-destination.js +24 -0
- package/dist/src/lib/list-focus.d.ts +14 -0
- package/dist/src/lib/list-focus.js +21 -0
- package/dist/src/lib/list-header-chrome.d.ts +40 -0
- package/dist/src/lib/list-header-chrome.js +12 -0
- package/dist/src/lib/list-narrowing.d.ts +35 -0
- package/dist/src/lib/list-narrowing.js +133 -0
- package/dist/src/lib/list-verb-request.d.ts +43 -0
- package/dist/src/lib/list-verb-request.js +24 -0
- package/dist/src/lib/mail-context.d.ts +61 -0
- package/dist/src/lib/mail-context.js +24 -0
- package/dist/src/lib/mail-freshness.d.ts +57 -0
- package/dist/src/lib/mail-freshness.js +158 -0
- package/dist/src/lib/mail-route.d.ts +103 -0
- package/dist/src/lib/mail-route.js +115 -0
- package/dist/src/lib/mail-search.d.ts +141 -0
- package/dist/src/lib/mail-search.js +55 -0
- package/dist/src/lib/mailbox-sync-wait.d.ts +54 -0
- package/dist/src/lib/mailbox-sync-wait.js +44 -0
- package/dist/src/lib/message-attachments.d.ts +20 -0
- package/dist/src/lib/message-attachments.js +37 -0
- package/dist/src/lib/message-body-source.d.ts +30 -0
- package/dist/src/lib/message-body-source.js +30 -0
- package/dist/src/lib/move-options.d.ts +30 -0
- package/dist/src/lib/move-options.js +33 -0
- package/dist/src/lib/move-targets.d.ts +16 -0
- package/dist/src/lib/move-targets.js +61 -0
- package/dist/src/lib/network-error.d.ts +31 -0
- package/dist/src/lib/network-error.js +68 -0
- package/dist/src/lib/new-folder.d.ts +23 -0
- package/dist/src/lib/new-folder.js +41 -0
- package/dist/src/lib/onboarding-completion.d.ts +15 -0
- package/dist/src/lib/onboarding-completion.js +17 -0
- package/dist/src/lib/organize/clause-suggestions.d.ts +40 -0
- package/dist/src/lib/organize/clause-suggestions.js +61 -0
- package/dist/src/lib/organize/filter-edit-model.d.ts +47 -0
- package/dist/src/lib/organize/filter-edit-model.js +104 -0
- package/dist/src/lib/organize/filter-run.d.ts +27 -0
- package/dist/src/lib/organize/filter-run.js +27 -0
- package/dist/src/lib/organize/filter-status.d.ts +30 -0
- package/dist/src/lib/organize/filter-status.js +84 -0
- package/dist/src/lib/organize/label-delete-copy.d.ts +11 -0
- package/dist/src/lib/organize/label-delete-copy.js +17 -0
- package/dist/src/lib/organize/organize-model.d.ts +110 -0
- package/dist/src/lib/organize/organize-model.js +81 -0
- package/dist/src/lib/organize/organize-poll.d.ts +11 -0
- package/dist/src/lib/organize/organize-poll.js +21 -0
- package/dist/src/lib/organize/rule-model.d.ts +69 -0
- package/dist/src/lib/organize/rule-model.js +98 -0
- package/dist/src/lib/organize/search-to-rule.d.ts +19 -0
- package/dist/src/lib/organize/search-to-rule.js +65 -0
- package/dist/src/lib/outbox-search.d.ts +34 -0
- package/dist/src/lib/outbox-search.js +26 -0
- package/dist/src/lib/outbox-status.d.ts +47 -0
- package/dist/src/lib/outbox-status.js +45 -0
- package/dist/src/lib/provider-presets.d.ts +16 -0
- package/dist/src/lib/provider-presets.js +82 -0
- package/dist/src/lib/quarantine-entries.d.ts +15 -0
- package/dist/src/lib/quarantine-entries.js +40 -0
- package/dist/src/lib/query-error-handler.d.ts +21 -0
- package/dist/src/lib/query-error-handler.js +30 -0
- package/dist/src/lib/recent-searches.d.ts +2 -0
- package/dist/src/lib/recent-searches.js +37 -0
- package/dist/src/lib/recipient-suggestions.d.ts +2 -0
- package/dist/src/lib/recipient-suggestions.js +11 -0
- package/dist/src/lib/request-breadcrumbs.d.ts +59 -0
- package/dist/src/lib/request-breadcrumbs.js +114 -0
- package/dist/src/lib/rescue-candidates.d.ts +17 -0
- package/dist/src/lib/rescue-candidates.js +27 -0
- package/dist/src/lib/rescue-telemetry.d.ts +26 -0
- package/dist/src/lib/rescue-telemetry.js +32 -0
- package/dist/src/lib/result-count.d.ts +43 -0
- package/dist/src/lib/result-count.js +37 -0
- package/dist/src/lib/result-folder.d.ts +57 -0
- package/dist/src/lib/result-folder.js +67 -0
- package/dist/src/lib/route-breadcrumbs.d.ts +27 -0
- package/dist/src/lib/route-breadcrumbs.js +36 -0
- package/dist/src/lib/row-settlement.d.ts +11 -0
- package/dist/src/lib/row-settlement.js +20 -0
- package/dist/src/lib/rum-adapter.d.ts +4 -0
- package/dist/src/lib/rum-adapter.js +84 -0
- package/dist/src/lib/search-conversion.d.ts +17 -0
- package/dist/src/lib/search-conversion.js +17 -0
- package/dist/src/lib/search-params.d.ts +23 -0
- package/dist/src/lib/search-params.js +58 -0
- package/dist/src/lib/search-query.d.ts +1 -0
- package/dist/src/lib/search-query.js +10 -0
- package/dist/src/lib/search-result.d.ts +10 -0
- package/dist/src/lib/search-result.js +34 -0
- package/dist/src/lib/search-scope.d.ts +94 -0
- package/dist/src/lib/search-scope.js +86 -0
- package/dist/src/lib/search-suggestions.d.ts +98 -0
- package/dist/src/lib/search-suggestions.js +202 -0
- package/dist/src/lib/search-surface.d.ts +30 -0
- package/dist/src/lib/search-surface.js +23 -0
- package/dist/src/lib/search-token-index.d.ts +43 -0
- package/dist/src/lib/search-token-index.js +92 -0
- package/dist/src/lib/search-tokens.d.ts +136 -0
- package/dist/src/lib/search-tokens.js +206 -0
- package/dist/src/lib/search-view.d.ts +53 -0
- package/dist/src/lib/search-view.js +71 -0
- package/dist/src/lib/selection-account-scope.d.ts +18 -0
- package/dist/src/lib/selection-account-scope.js +26 -0
- package/dist/src/lib/selection-mode.d.ts +17 -0
- package/dist/src/lib/selection-mode.js +14 -0
- package/dist/src/lib/self-update-state.d.ts +156 -0
- package/dist/src/lib/self-update-state.js +384 -0
- package/dist/src/lib/sender-address.d.ts +24 -0
- package/dist/src/lib/sender-address.js +28 -0
- package/dist/src/lib/session-storage.d.ts +1 -0
- package/dist/src/lib/session-storage.js +8 -0
- package/dist/src/lib/spam-offer.d.ts +69 -0
- package/dist/src/lib/spam-offer.js +90 -0
- package/dist/src/lib/stale-build.d.ts +10 -0
- package/dist/src/lib/stale-build.js +24 -0
- package/dist/src/lib/starred-rows.d.ts +24 -0
- package/dist/src/lib/starred-rows.js +32 -0
- package/dist/src/lib/sync-warning-entries.d.ts +4 -0
- package/dist/src/lib/sync-warning-entries.js +22 -0
- package/dist/src/lib/telemetry-context.d.ts +3 -0
- package/dist/src/lib/telemetry-context.js +6 -0
- package/dist/src/lib/telemetry.d.ts +7 -0
- package/dist/src/lib/telemetry.js +6 -0
- package/dist/src/lib/theme-preference.d.ts +16 -0
- package/dist/src/lib/theme-preference.js +40 -0
- package/dist/src/lib/theme.d.ts +11 -0
- package/dist/src/lib/theme.js +31 -0
- package/dist/src/lib/thread-cache.d.ts +41 -0
- package/dist/src/lib/thread-cache.js +34 -0
- package/dist/src/lib/thread-list-cache.d.ts +51 -0
- package/dist/src/lib/thread-list-cache.js +51 -0
- package/dist/src/lib/thread-search-tokens.d.ts +61 -0
- package/dist/src/lib/thread-search-tokens.js +116 -0
- package/dist/src/lib/wizard-selection.d.ts +27 -0
- package/dist/src/lib/wizard-selection.js +17 -0
- package/dist/src/main.d.ts +1 -0
- package/dist/src/main.js +9 -0
- package/dist/src/routeTree.gen.d.ts +1596 -0
- package/dist/src/routeTree.gen.js +414 -0
- package/dist/src/router.d.ts +12 -0
- package/dist/src/router.js +40 -0
- package/dist/src/routes/__root.d.ts +2 -0
- package/dist/src/routes/__root.js +46 -0
- package/dist/src/routes/calendar/$view.$date/$calendarObjectId/$recurrenceId.d.ts +13 -0
- package/dist/src/routes/calendar/$view.$date/$calendarObjectId/$recurrenceId.js +18 -0
- package/dist/src/routes/calendar/$view.$date/$calendarObjectId/index.d.ts +13 -0
- package/dist/src/routes/calendar/$view.$date/$calendarObjectId/index.js +15 -0
- package/dist/src/routes/calendar/$view.$date/$calendarObjectId.d.ts +13 -0
- package/dist/src/routes/calendar/$view.$date/$calendarObjectId.js +12 -0
- package/dist/src/routes/calendar/$view.$date/index.d.ts +18 -0
- package/dist/src/routes/calendar/$view.$date/index.js +16 -0
- package/dist/src/routes/calendar/$view.$date/new.d.ts +13 -0
- package/dist/src/routes/calendar/$view.$date/new.js +19 -0
- package/dist/src/routes/calendar/$view.$date/suggestion.$suggestionId.d.ts +13 -0
- package/dist/src/routes/calendar/$view.$date/suggestion.$suggestionId.js +15 -0
- package/dist/src/routes/calendar/$view.$date.d.ts +13 -0
- package/dist/src/routes/calendar/$view.$date.js +69 -0
- package/dist/src/routes/calendar/index.d.ts +13 -0
- package/dist/src/routes/calendar/index.js +22 -0
- package/dist/src/routes/calendar.d.ts +14 -0
- package/dist/src/routes/calendar.js +68 -0
- package/dist/src/routes/import.d.ts +1 -0
- package/dist/src/routes/import.js +45 -0
- package/dist/src/routes/index.d.ts +1 -0
- package/dist/src/routes/index.js +6 -0
- package/dist/src/routes/mail/$mailboxId/$threadId/$messageId/$mode.{-$outboxMessageId}.d.ts +29 -0
- package/dist/src/routes/mail/$mailboxId/$threadId/$messageId/$mode.{-$outboxMessageId}.js +12 -0
- package/dist/src/routes/mail/$mailboxId/$threadId/$messageId.d.ts +19 -0
- package/dist/src/routes/mail/$mailboxId/$threadId/$messageId.js +22 -0
- package/dist/src/routes/mail/$mailboxId/$threadId/index.d.ts +19 -0
- package/dist/src/routes/mail/$mailboxId/$threadId/index.js +13 -0
- package/dist/src/routes/mail/$mailboxId/$threadId.d.ts +19 -0
- package/dist/src/routes/mail/$mailboxId/$threadId.js +11 -0
- package/dist/src/routes/mail/$mailboxId/compose.{-$outboxMessageId}.d.ts +19 -0
- package/dist/src/routes/mail/$mailboxId/compose.{-$outboxMessageId}.js +11 -0
- package/dist/src/routes/mail/$mailboxId/index.d.ts +19 -0
- package/dist/src/routes/mail/$mailboxId/index.js +9 -0
- package/dist/src/routes/mail/$mailboxId.d.ts +19 -0
- package/dist/src/routes/mail/$mailboxId.js +26 -0
- package/dist/src/routes/mail/brief/$threadId/$messageId/$mode.{-$outboxMessageId}.d.ts +29 -0
- package/dist/src/routes/mail/brief/$threadId/$messageId/$mode.{-$outboxMessageId}.js +24 -0
- package/dist/src/routes/mail/brief/$threadId/$messageId.d.ts +19 -0
- package/dist/src/routes/mail/brief/$threadId/$messageId.js +22 -0
- package/dist/src/routes/mail/brief/$threadId/index.d.ts +19 -0
- package/dist/src/routes/mail/brief/$threadId/index.js +13 -0
- package/dist/src/routes/mail/brief/$threadId.d.ts +19 -0
- package/dist/src/routes/mail/brief/$threadId.js +15 -0
- package/dist/src/routes/mail/brief/compose.{-$outboxMessageId}.d.ts +19 -0
- package/dist/src/routes/mail/brief/compose.{-$outboxMessageId}.js +19 -0
- package/dist/src/routes/mail/brief/index.d.ts +19 -0
- package/dist/src/routes/mail/brief/index.js +13 -0
- package/dist/src/routes/mail/brief.d.ts +19 -0
- package/dist/src/routes/mail/brief.js +27 -0
- package/dist/src/routes/mail/flagged/$threadId/$messageId/$mode.{-$outboxMessageId}.d.ts +29 -0
- package/dist/src/routes/mail/flagged/$threadId/$messageId/$mode.{-$outboxMessageId}.js +12 -0
- package/dist/src/routes/mail/flagged/$threadId/$messageId.d.ts +19 -0
- package/dist/src/routes/mail/flagged/$threadId/$messageId.js +22 -0
- package/dist/src/routes/mail/flagged/$threadId/index.d.ts +19 -0
- package/dist/src/routes/mail/flagged/$threadId/index.js +13 -0
- package/dist/src/routes/mail/flagged/$threadId.d.ts +19 -0
- package/dist/src/routes/mail/flagged/$threadId.js +15 -0
- package/dist/src/routes/mail/flagged/compose.{-$outboxMessageId}.d.ts +19 -0
- package/dist/src/routes/mail/flagged/compose.{-$outboxMessageId}.js +10 -0
- package/dist/src/routes/mail/flagged/index.d.ts +19 -0
- package/dist/src/routes/mail/flagged/index.js +9 -0
- package/dist/src/routes/mail/flagged.d.ts +19 -0
- package/dist/src/routes/mail/flagged.js +26 -0
- package/dist/src/routes/mail/index.d.ts +37 -0
- package/dist/src/routes/mail/index.js +13 -0
- package/dist/src/routes/mail/outbox/compose.{-$outboxMessageId}.d.ts +19 -0
- package/dist/src/routes/mail/outbox/compose.{-$outboxMessageId}.js +14 -0
- package/dist/src/routes/mail/outbox/draft/$outboxMessageId.d.ts +19 -0
- package/dist/src/routes/mail/outbox/draft/$outboxMessageId.js +18 -0
- package/dist/src/routes/mail/outbox/index.d.ts +19 -0
- package/dist/src/routes/mail/outbox/index.js +9 -0
- package/dist/src/routes/mail/outbox.d.ts +19 -0
- package/dist/src/routes/mail/outbox.js +22 -0
- package/dist/src/routes/mail.d.ts +16 -0
- package/dist/src/routes/mail.js +187 -0
- package/dist/src/routes/onboarding.d.ts +7 -0
- package/dist/src/routes/onboarding.js +35 -0
- package/dist/src/routes/settings/-shared/help-copy.d.ts +5 -0
- package/dist/src/routes/settings/-shared/help-copy.js +7 -0
- package/dist/src/routes/settings/accounts.d.ts +38 -0
- package/dist/src/routes/settings/accounts.js +396 -0
- package/dist/src/routes/settings/advanced.d.ts +1 -0
- package/dist/src/routes/settings/advanced.js +28 -0
- package/dist/src/routes/settings/appearance.d.ts +1 -0
- package/dist/src/routes/settings/appearance.js +61 -0
- package/dist/src/routes/settings/calendars.d.ts +1 -0
- package/dist/src/routes/settings/calendars.js +44 -0
- package/dist/src/routes/settings/filters.d.ts +5 -0
- package/dist/src/routes/settings/filters.js +88 -0
- package/dist/src/routes/settings/folders.d.ts +1 -0
- package/dist/src/routes/settings/folders.js +142 -0
- package/dist/src/routes/settings/index.d.ts +1 -0
- package/dist/src/routes/settings/index.js +5 -0
- package/dist/src/routes/settings/labels.d.ts +1 -0
- package/dist/src/routes/settings/labels.js +71 -0
- package/dist/src/routes/settings/senders.d.ts +6 -0
- package/dist/src/routes/settings/senders.js +202 -0
- package/dist/src/routes/settings/suggested-vips.d.ts +1 -0
- package/dist/src/routes/settings/suggested-vips.js +10 -0
- package/dist/src/routes/settings/warnings.d.ts +1 -0
- package/dist/src/routes/settings/warnings.js +20 -0
- package/dist/src/routes/settings.d.ts +14 -0
- package/dist/src/routes/settings.js +64 -0
- package/dist/src/routing/browsed-list.d.ts +28 -0
- package/dist/src/routing/browsed-list.js +61 -0
- package/dist/src/routing/calendar.d.ts +69 -0
- package/dist/src/routing/calendar.js +152 -0
- package/dist/src/routing/compose.d.ts +52 -0
- package/dist/src/routing/compose.js +139 -0
- package/dist/src/routing/fragment.d.ts +64 -0
- package/dist/src/routing/fragment.js +112 -0
- package/dist/src/routing/index.d.ts +14 -0
- package/dist/src/routing/index.js +14 -0
- package/dist/src/routing/nav-link.d.ts +28 -0
- package/dist/src/routing/nav-link.js +9 -0
- package/dist/src/routing/nav-selection.d.ts +13 -0
- package/dist/src/routing/nav-selection.js +29 -0
- package/dist/src/routing/open-thread.d.ts +65 -0
- package/dist/src/routing/open-thread.js +100 -0
- package/dist/src/routing/outbox-draft.d.ts +13 -0
- package/dist/src/routing/outbox-draft.js +37 -0
- package/dist/src/routing/reply.d.ts +102 -0
- package/dist/src/routing/reply.js +238 -0
- package/dist/src/routing/search-field.d.ts +45 -0
- package/dist/src/routing/search-field.js +67 -0
- package/dist/src/routing/search-mirror.d.ts +63 -0
- package/dist/src/routing/search-mirror.js +120 -0
- package/dist/src/routing/search-navigation.d.ts +16 -0
- package/dist/src/routing/search-navigation.js +32 -0
- package/dist/src/routing/sections.d.ts +16 -0
- package/dist/src/routing/sections.js +33 -0
- package/dist/src/routing/wizard-history.d.ts +83 -0
- package/dist/src/routing/wizard-history.js +153 -0
- package/dist/src/runtime-config.d.ts +59 -0
- package/dist/src/runtime-config.js +42 -0
- package/dist/src/shell/index.d.ts +17 -0
- package/dist/src/shell/index.js +61 -0
- package/package.json +145 -127
- package/harness/build.mjs +0 -121
- package/harness/index.html +0 -52
- package/harness/vite-preset.ts +0 -31
- package/index.html +0 -54
- package/spellcheck/empty-build.test.ts +0 -160
- package/spellcheck/languages.test.ts +0 -80
- package/spellcheck/languages.ts +0 -86
- package/spellcheck/vite-plugin-licence.test.ts +0 -140
- package/spellcheck/vite-plugin.test.ts +0 -230
- package/spellcheck/vite-plugin.ts +0 -385
- package/spellcheck/worker-stub.ts +0 -36
- package/src/auth/AccountMenu.tsx +0 -10
- package/src/auth/AccountSession.tsx +0 -19
- package/src/auth/BetterAuthShell.tsx +0 -233
- package/src/auth/SessionRateLimited.stories.tsx +0 -26
- package/src/auth/SessionRateLimited.tsx +0 -39
- package/src/auth/SignInAgain.tsx +0 -18
- package/src/auth/account-menu-mode.test.ts +0 -64
- package/src/auth/account-menu-mode.ts +0 -28
- package/src/auth/amplify-config.test.ts +0 -50
- package/src/auth/amplify-config.ts +0 -59
- package/src/auth/auth-error.test.ts +0 -129
- package/src/auth/auth-error.ts +0 -120
- package/src/auth/auth-interceptor.test.ts +0 -104
- package/src/auth/auth-interceptor.ts +0 -28
- package/src/auth/better-auth/BetterAuthAccount.tsx +0 -25
- package/src/auth/better-auth-config.ts +0 -253
- package/src/auth/better-auth-provider.tsx +0 -20
- package/src/auth/better-auth-token.test.ts +0 -349
- package/src/auth/cognito/CognitoAccount.tsx +0 -48
- package/src/auth/cognito/CognitoShell.tsx +0 -266
- package/src/auth/cognito/cognito-token.test.ts +0 -106
- package/src/auth/cognito/cognito-token.ts +0 -47
- package/src/auth/cognito-provider.tsx +0 -22
- package/src/auth/cognito-sign-in.stories.tsx +0 -90
- package/src/auth/combined-provider.tsx +0 -42
- package/src/auth/composition.test.ts +0 -59
- package/src/auth/email-sign-in.stories.tsx +0 -128
- package/src/auth/provider.tsx +0 -68
- package/src/auth/session-gate.render.test.ts +0 -77
- package/src/auth/session-state.test.ts +0 -66
- package/src/auth/session-state.ts +0 -41
- package/src/auth/sign-out-visibility.test.ts +0 -40
- package/src/auth/sign-out-visibility.ts +0 -10
- package/src/auth/sign-up-disabled.test.ts +0 -23
- package/src/components/calendar/AgendaStrip.stories.tsx +0 -291
- package/src/components/calendar/AgendaStrip.tsx +0 -162
- package/src/components/calendar/AgendaView.stories.tsx +0 -112
- package/src/components/calendar/AgendaView.tsx +0 -241
- package/src/components/calendar/CalendarComposePane.stories.tsx +0 -151
- package/src/components/calendar/CalendarComposePane.tsx +0 -127
- package/src/components/calendar/CalendarComposeSeed.tsx +0 -35
- package/src/components/calendar/CalendarEventPane.stories.tsx +0 -200
- package/src/components/calendar/CalendarEventPane.tsx +0 -167
- package/src/components/calendar/CalendarShell.stories.tsx +0 -177
- package/src/components/calendar/CalendarShell.tsx +0 -83
- package/src/components/calendar/CalendarUnavailable.tsx +0 -56
- package/src/components/calendar/CalendarViewPlaceholder.stories.tsx +0 -41
- package/src/components/calendar/CalendarViewPlaceholder.tsx +0 -17
- package/src/components/calendar/CalendarWaiting.tsx +0 -102
- package/src/components/calendar/CalendarWorkspace.stories.tsx +0 -374
- package/src/components/calendar/CalendarWorkspace.tsx +0 -258
- package/src/components/calendar/ChangeCalendarSuggestion.stories.tsx +0 -187
- package/src/components/calendar/ChangeCalendarSuggestion.tsx +0 -159
- package/src/components/calendar/OpenCalendarEvent.stories.tsx +0 -273
- package/src/components/calendar/OpenCalendarEvent.tsx +0 -353
- package/src/components/calendar/PendingSuggestions.tsx +0 -100
- package/src/components/calendar/WriteCalendarEvent.stories.tsx +0 -90
- package/src/components/calendar/WriteCalendarEvent.tsx +0 -104
- package/src/components/calendar/agenda-address.render.test.ts +0 -493
- package/src/components/calendar/agenda-strip.render.test.ts +0 -241
- package/src/components/calendar/calendar-app.stories.tsx +0 -122
- package/src/components/calendar/calendar-story-fixtures.ts +0 -118
- package/src/components/calendar/calendar-story-server.tsx +0 -157
- package/src/components/calendar/calendar-workspace.render.test.ts +0 -221
- package/src/components/calendar/calendar-write-flow.render.test.ts +0 -373
- package/src/components/calendar/change-suggestion-first.render.test.ts +0 -304
- package/src/components/calendar/pending-suggestions.render.test.ts +0 -206
- package/src/components/compose/AddressField.tsx +0 -64
- package/src/components/compose/ComposeForm.tsx +0 -1427
- package/src/components/compose/ComposeProvider.tsx +0 -174
- package/src/components/compose/ComposeSmtpMissingBanner.tsx +0 -25
- package/src/components/compose/ConversationCompose.tsx +0 -88
- package/src/components/compose/FromSelector.render.test.ts +0 -99
- package/src/components/compose/FromSelector.stories.tsx +0 -61
- package/src/components/compose/FromSelector.tsx +0 -74
- package/src/components/compose/FullCompose.tsx +0 -93
- package/src/components/compose/MobileComposeSheet.tsx +0 -134
- package/src/components/compose/attachment-only-source.render.test.ts +0 -234
- package/src/components/compose/compose-inline-image.render.test.ts +0 -542
- package/src/components/compose/compose-send-stops-autosave.render.test.ts +0 -328
- package/src/components/compose/compose-spellcheck-failure.render.test.ts +0 -114
- package/src/components/compose/compose-spellcheck.test.ts +0 -157
- package/src/components/compose/compose-spellcheck.ts +0 -56
- package/src/components/compose/compose-starts-a-second-message.render.test.ts +0 -171
- package/src/components/compose/compose-title.ts +0 -10
- package/src/components/compose/compose.stories.tsx +0 -405
- package/src/components/compose/draft-discard-failure.render.test.ts +0 -138
- package/src/components/compose/forward-autosave-is-not-fatal.render.test.ts +0 -358
- package/src/components/compose/mail-sync-off-refusal.ts +0 -7
- package/src/components/compose/mobile-header-stays-expanded.render.test.ts +0 -229
- package/src/components/compose/quote-leaves-with-the-send.render.test.ts +0 -235
- package/src/components/compose/quoted-message.test.ts +0 -158
- package/src/components/compose/quoted-message.ts +0 -216
- package/src/components/compose/reopened-draft-writes-nothing.render.test.ts +0 -148
- package/src/components/compose/reply-all-on-resumed-draft.render.test.ts +0 -250
- package/src/components/compose/reply-with-times.ts +0 -22
- package/src/components/compose/send-from-mail-off-account.render.test.ts +0 -173
- package/src/components/compose/send-poll-server-error.render.test.ts +0 -120
- package/src/components/compose/send-watch-outlives-sent.render.test.ts +0 -121
- package/src/components/config-import/ConfigImportWizard.flow.test.ts +0 -326
- package/src/components/config-import/ConfigImportWizard.tsx +0 -721
- package/src/components/config-import/config-import.fixtures.ts +0 -254
- package/src/components/config-import/config-import.stories.tsx +0 -486
- package/src/components/config-import/steps.import-failure.test.ts +0 -91
- package/src/components/config-import/steps.tsx +0 -784
- package/src/components/config-import/steps.viewport.test.ts +0 -216
- package/src/components/layout/AppShellSkeleton.tsx +0 -53
- package/src/components/layout/ComposeFab.tsx +0 -22
- package/src/components/layout/Drawer.focus.test.ts +0 -253
- package/src/components/layout/Drawer.tsx +0 -108
- package/src/components/layout/MailShell.tsx +0 -106
- package/src/components/layout/MailTopBar.tsx +0 -99
- package/src/components/layout/mail-shell.stories.tsx +0 -142
- package/src/components/mail/AuthenticityBanner.tsx +0 -45
- package/src/components/mail/AutoMovedIndicator.tsx +0 -53
- package/src/components/mail/BlockedImagesNotice.render.test.ts +0 -114
- package/src/components/mail/BlockedImagesNotice.tsx +0 -63
- package/src/components/mail/BriefPane.tsx +0 -477
- package/src/components/mail/BulkRunProvider.tsx +0 -344
- package/src/components/mail/ConversationView.tsx +0 -519
- package/src/components/mail/DailyBrief.scope.test.ts +0 -76
- package/src/components/mail/DailyBrief.tsx +0 -1094
- package/src/components/mail/DeleteConfirmDialog.render.test.ts +0 -412
- package/src/components/mail/DeleteConfirmDialog.tsx +0 -143
- package/src/components/mail/DraftsView.tsx +0 -255
- package/src/components/mail/EmptyTrashBar.render.test.ts +0 -133
- package/src/components/mail/EmptyTrashBar.tsx +0 -181
- package/src/components/mail/FlaggedList.tsx +0 -359
- package/src/components/mail/FlaggedPane.tsx +0 -473
- package/src/components/mail/IntelligenceDrawer.tsx +0 -52
- package/src/components/mail/IntelligencePane.render.test.ts +0 -116
- package/src/components/mail/IntelligencePane.test.ts +0 -16
- package/src/components/mail/IntelligencePane.tsx +0 -391
- package/src/components/mail/LabelApplyTrigger.tsx +0 -67
- package/src/components/mail/MailListHeader.chrome-stability.render.test.ts +0 -323
- package/src/components/mail/MailListHeader.tsx +0 -613
- package/src/components/mail/MailNav.tsx +0 -70
- package/src/components/mail/MailSidebarAdapter.tsx +0 -319
- package/src/components/mail/MailViewChrome.tsx +0 -124
- package/src/components/mail/MailboxPane.tsx +0 -1285
- package/src/components/mail/MessageActionMenu.tsx +0 -296
- package/src/components/mail/MessageAttachments.interaction.test.ts +0 -245
- package/src/components/mail/MessageAttachments.tsx +0 -188
- package/src/components/mail/MessageBody.blocked-sender.test.ts +0 -193
- package/src/components/mail/MessageBody.tsx +0 -226
- package/src/components/mail/MessageBodyErrorBanner.render.test.ts +0 -85
- package/src/components/mail/MessageBodyErrorBanner.test.ts +0 -56
- package/src/components/mail/MessageBodyErrorBanner.tsx +0 -90
- package/src/components/mail/MessageCard.blocked-sender.test.ts +0 -246
- package/src/components/mail/MessageCard.tsx +0 -430
- package/src/components/mail/MessageList.move-guard.test.ts +0 -64
- package/src/components/mail/MessageList.run-reporting.test.ts +0 -87
- package/src/components/mail/MessageList.tsx +0 -1383
- package/src/components/mail/MessageListItem.test.ts +0 -153
- package/src/components/mail/MessageListItem.tsx +0 -106
- package/src/components/mail/MessageRow.render.test.ts +0 -54
- package/src/components/mail/MessageRow.tsx +0 -269
- package/src/components/mail/MessageSettlementAlert.render.test.ts +0 -182
- package/src/components/mail/MessageSettlementAlert.tsx +0 -126
- package/src/components/mail/MessageToolbar.interaction.test.ts +0 -250
- package/src/components/mail/MessageToolbar.render.test.ts +0 -124
- package/src/components/mail/MessageToolbar.tsx +0 -215
- package/src/components/mail/MobileMessageBar.tsx +0 -140
- package/src/components/mail/MoveToTrigger.render.test.ts +0 -310
- package/src/components/mail/MoveToTrigger.tsx +0 -298
- package/src/components/mail/NavMenuButton.tsx +0 -25
- package/src/components/mail/OutboxPane.tsx +0 -584
- package/src/components/mail/PullToRefresh.tsx +0 -24
- package/src/components/mail/RawMessageView.tsx +0 -84
- package/src/components/mail/RoleAppointmentPromptProvider.render.test.ts +0 -294
- package/src/components/mail/RoleAppointmentPromptProvider.tsx +0 -251
- package/src/components/mail/SelectionWizardHost.search-entry.test.ts +0 -81
- package/src/components/mail/SelectionWizardHost.tsx +0 -1078
- package/src/components/mail/SpamRescue.tsx +0 -126
- package/src/components/mail/SwipeableMessageRow.modifier-select.test.ts +0 -243
- package/src/components/mail/SwipeableMessageRow.render.test.ts +0 -110
- package/src/components/mail/SwipeableMessageRow.tsx +0 -160
- package/src/components/mail/ThreadListInteraction.test.ts +0 -546
- package/src/components/mail/ThreadListInteraction.tsx +0 -538
- package/src/components/mail/authenticity-warning.stories.tsx +0 -116
- package/src/components/mail/blocked-images-notice.stories.tsx +0 -90
- package/src/components/mail/brief-server-sections.render.test.ts +0 -656
- package/src/components/mail/bulk-run-state.test.ts +0 -101
- package/src/components/mail/bulk-run-state.ts +0 -99
- package/src/components/mail/conversation-reply-identity.render.test.ts +0 -307
- package/src/components/mail/conversation-reply-reach.render.test.ts +0 -414
- package/src/components/mail/daily-brief.stories.tsx +0 -264
- package/src/components/mail/delete-open-message-keeps-the-list.render.test.ts +0 -154
- package/src/components/mail/detail-surface.stories.tsx +0 -171
- package/src/components/mail/drafts.stories.tsx +0 -61
- package/src/components/mail/empty-trash-bar.stories.tsx +0 -121
- package/src/components/mail/enter-cursor-late-open.render.test.ts +0 -197
- package/src/components/mail/filtered-empty-state.render.test.ts +0 -240
- package/src/components/mail/flagged-search-reach.render.test.ts +0 -272
- package/src/components/mail/flagged.stories.tsx +0 -159
- package/src/components/mail/intelligence-auto-open-pref.render.test.ts +0 -412
- package/src/components/mail/intelligence-drawer.stories.tsx +0 -353
- package/src/components/mail/intelligence-shortcut-surface.render.test.ts +0 -373
- package/src/components/mail/intelligence-story-calendar.ts +0 -19
- package/src/components/mail/intelligence-surface-reach.render.test.ts +0 -220
- package/src/components/mail/mail-pickers.stories.tsx +0 -82
- package/src/components/mail/message-body-error-banner-content.ts +0 -87
- package/src/components/mail/message-gone.stories.tsx +0 -44
- package/src/components/mail/offer-times-reply.render.test.ts +0 -557
- package/src/components/mail/organize-run-state.test.ts +0 -115
- package/src/components/mail/organize-run-state.ts +0 -44
- package/src/components/mail/outbox.stories.tsx +0 -59
- package/src/components/mail/reclassify-remove-override.render.test.ts +0 -138
- package/src/components/mail/reply-verbs-reach.render.test.ts +0 -235
- package/src/components/mail/search.stories.tsx +0 -280
- package/src/components/mail/selection-wizard-run-controls.test.ts +0 -231
- package/src/components/mail/selection-wizard-run-controls.ts +0 -101
- package/src/components/mail/selection-wizard.stories.tsx +0 -160
- package/src/components/mail/spam-offer-server-count.render.test.ts +0 -349
- package/src/components/mail/two-window-listeners-one-key.render.test.ts +0 -593
- package/src/components/mail/useModifierSelect.render.test.ts +0 -223
- package/src/components/mail/useModifierSelect.ts +0 -100
- package/src/components/onboarding/OnboardingWizard.flow.test.ts +0 -709
- package/src/components/onboarding/OnboardingWizard.tsx +0 -1599
- package/src/components/onboarding/credential-steps.tsx +0 -441
- package/src/components/onboarding/onboarding-servers.stories.tsx +0 -49
- package/src/components/onboarding/onboarding.stories.tsx +0 -550
- package/src/components/overlay-escape.render.test.ts +0 -155
- package/src/components/self-update/SelfUpdateOverlay.tsx +0 -45
- package/src/components/settings/AccountFormPanel.render.test.ts +0 -269
- package/src/components/settings/AccountFormPanel.test.ts +0 -37
- package/src/components/settings/AccountFormPanel.tsx +0 -949
- package/src/components/settings/AccountServices.render.test.ts +0 -257
- package/src/components/settings/AccountServices.tsx +0 -181
- package/src/components/settings/AccountServicesCard.stories.tsx +0 -71
- package/src/components/settings/AccountServicesCard.tsx +0 -76
- package/src/components/settings/AdvancedNavIcon.tsx +0 -23
- package/src/components/settings/CalendarCreateCard.stories.tsx +0 -33
- package/src/components/settings/CalendarCreateCard.tsx +0 -149
- package/src/components/settings/CalendarDetailsForm.stories.tsx +0 -57
- package/src/components/settings/CalendarDetailsForm.tsx +0 -136
- package/src/components/settings/CalendarFeedCard.render.test.ts +0 -154
- package/src/components/settings/CalendarFeedCard.stories.tsx +0 -152
- package/src/components/settings/CalendarFeedCard.tsx +0 -289
- package/src/components/settings/CalendarFeedPanel.tsx +0 -38
- package/src/components/settings/CalendarSettingsPanel.tsx +0 -60
- package/src/components/settings/CalendarSubscribeCard.stories.tsx +0 -89
- package/src/components/settings/CalendarSubscribeCard.tsx +0 -115
- package/src/components/settings/CalendarSubscriptionStatus.stories.tsx +0 -77
- package/src/components/settings/CalendarSubscriptionStatus.tsx +0 -87
- package/src/components/settings/ConfigExportCard.tsx +0 -114
- package/src/components/settings/ConfigTransferPanel.tsx +0 -72
- package/src/components/settings/DangerZone.tsx +0 -30
- package/src/components/settings/DeleteAccountDialog.render.test.ts +0 -47
- package/src/components/settings/DeleteAccountDialog.tsx +0 -224
- package/src/components/settings/DeleteFolderDialog.render.test.ts +0 -836
- package/src/components/settings/DeleteFolderDialog.tsx +0 -406
- package/src/components/settings/FilterActionError.render.test.ts +0 -46
- package/src/components/settings/FilterActionError.stories.tsx +0 -50
- package/src/components/settings/FilterActionError.tsx +0 -40
- package/src/components/settings/FilterEditor.render.test.ts +0 -307
- package/src/components/settings/FilterEditor.tsx +0 -364
- package/src/components/settings/FilterEditorSurface.tsx +0 -65
- package/src/components/settings/FiltersList.render.test.ts +0 -202
- package/src/components/settings/FiltersList.stories.tsx +0 -113
- package/src/components/settings/FiltersList.tsx +0 -191
- package/src/components/settings/LabelsList.stories.tsx +0 -134
- package/src/components/settings/LabelsList.tsx +0 -112
- package/src/components/settings/SelfUpdatePanel.tsx +0 -47
- package/src/components/settings/TimeZoneSelect.tsx +0 -43
- package/src/components/settings/TlsRootCaDownload.render.test.ts +0 -37
- package/src/components/settings/TlsRootCaDownload.tsx +0 -33
- package/src/components/settings/WarningsNavIcon.tsx +0 -12
- package/src/components/settings/WarningsPanel.dom.test.ts +0 -201
- package/src/components/settings/WarningsPanel.render.test.ts +0 -56
- package/src/components/settings/WarningsPanel.tsx +0 -244
- package/src/components/settings/account-form-helpers.test.ts +0 -172
- package/src/components/settings/account-form-helpers.ts +0 -105
- package/src/components/settings/accounts.stories.tsx +0 -386
- package/src/components/settings/advanced.stories.tsx +0 -40
- package/src/components/settings/appearance.stories.tsx +0 -33
- package/src/components/settings/calendar-collection-cards.render.test.ts +0 -149
- package/src/components/settings/calendar-feed-flow.render.test.ts +0 -449
- package/src/components/settings/folders.stories.tsx +0 -89
- package/src/components/settings/label-delete-confirm.stories.tsx +0 -83
- package/src/components/settings/self-update.stories.tsx +0 -288
- package/src/components/settings/senders.stories.tsx +0 -155
- package/src/components/settings/settings-filter.stories.tsx +0 -145
- package/src/components/settings/warnings.stories.tsx +0 -290
- package/src/components/ui/AppVersion.stories.tsx +0 -31
- package/src/components/ui/AppVersion.tsx +0 -57
- package/src/components/ui/BugReportButton.stories.tsx +0 -19
- package/src/components/ui/BugReportButton.tsx +0 -20
- package/src/components/ui/ErrorBannerProvider.render.test.ts +0 -85
- package/src/components/ui/ErrorBannerProvider.tsx +0 -134
- package/src/components/ui/FatalErrorOverlay.render.test.ts +0 -66
- package/src/components/ui/FatalErrorOverlay.stories.tsx +0 -55
- package/src/components/ui/FatalErrorOverlay.tsx +0 -158
- package/src/components/ui/banner-way-out.test.ts +0 -71
- package/src/components/ui/error-banners.test.ts +0 -186
- package/src/components/ui/error-banners.ts +0 -121
- package/src/components/ui/folder-role-refusal.test.ts +0 -124
- package/src/components/ui/folder-role-refusal.ts +0 -69
- package/src/components/ui/placement-refusal.test.ts +0 -98
- package/src/components/ui/placement-refusal.ts +0 -71
- package/src/hooks/bulk-chunking.render.test.ts +0 -157
- package/src/hooks/calendar/agenda-window.test.ts +0 -392
- package/src/hooks/calendar/agenda-window.ts +0 -210
- package/src/hooks/calendar/calendar-collections.render.test.ts +0 -281
- package/src/hooks/calendar/calendar-reads.render.test.ts +0 -265
- package/src/hooks/calendar/calendar-writes.render.test.ts +0 -326
- package/src/hooks/calendar/draft.test.ts +0 -537
- package/src/hooks/calendar/draft.ts +0 -204
- package/src/hooks/calendar/index.ts +0 -122
- package/src/hooks/calendar/instance.test.ts +0 -206
- package/src/hooks/calendar/instance.ts +0 -224
- package/src/hooks/calendar/recurrence-rule.test.ts +0 -134
- package/src/hooks/calendar/recurrence-rule.ts +0 -177
- package/src/hooks/calendar/resource.test.ts +0 -141
- package/src/hooks/calendar/resource.ts +0 -104
- package/src/hooks/calendar/selection.ts +0 -110
- package/src/hooks/calendar/suggestion-draft.ts +0 -77
- package/src/hooks/calendar/useCalendarCollectionWrites.ts +0 -131
- package/src/hooks/calendar/useCalendarEvent.ts +0 -46
- package/src/hooks/calendar/useCalendarEvents.ts +0 -195
- package/src/hooks/calendar/useCalendarFeed.ts +0 -163
- package/src/hooks/calendar/useCalendarFreeBusy.ts +0 -80
- package/src/hooks/calendar/useCalendarJump.ts +0 -117
- package/src/hooks/calendar/useCalendarSubscriptions.ts +0 -103
- package/src/hooks/calendar/useCalendarSuggestions.ts +0 -279
- package/src/hooks/calendar/useCalendarWrites.ts +0 -177
- package/src/hooks/calendar/useCalendars.ts +0 -59
- package/src/hooks/calendar/useDraftClashes.ts +0 -93
- package/src/hooks/calendar/window.test.ts +0 -189
- package/src/hooks/calendar/window.ts +0 -188
- package/src/hooks/cross-account-bulk.render.test.ts +0 -164
- package/src/hooks/escalated-run-lifetime.render.test.ts +0 -349
- package/src/hooks/escalated-run-refusal.render.test.ts +0 -373
- package/src/hooks/escalated-run-survives-navigation.render.test.ts +0 -524
- package/src/hooks/intelligence-calendar.render.test.ts +0 -497
- package/src/hooks/intelligence-drawer.render.test.ts +0 -99
- package/src/hooks/mutation-optimism.test.ts +0 -278
- package/src/hooks/queries/keys.ts +0 -9
- package/src/hooks/refusal-escalation.render.test.ts +0 -243
- package/src/hooks/signed-out-poll-is-not-fatal.render.test.ts +0 -126
- package/src/hooks/stale-account-sync-visibility.test.ts +0 -166
- package/src/hooks/update-restart-escalation.render.test.ts +0 -340
- package/src/hooks/use-system-update.test.ts +0 -686
- package/src/hooks/use-system-update.ts +0 -341
- package/src/hooks/useApplyLabel.ts +0 -71
- package/src/hooks/useArchiveMailbox.ts +0 -162
- package/src/hooks/useAutoMovedBadge.ts +0 -145
- package/src/hooks/useBriefSections.ts +0 -320
- package/src/hooks/useCalendarData.ts +0 -94
- package/src/hooks/useClauseSuggestions.ts +0 -57
- package/src/hooks/useComposeAttachments.ts +0 -108
- package/src/hooks/useComposeLanguages.ts +0 -69
- package/src/hooks/useCreateMailbox.render.test.ts +0 -233
- package/src/hooks/useCreateMailbox.ts +0 -153
- package/src/hooks/useCurrentMailboxName.ts +0 -128
- package/src/hooks/useDebouncedValue.ts +0 -12
- package/src/hooks/useDeleteFolder.ts +0 -380
- package/src/hooks/useDeleteMessages.test.ts +0 -62
- package/src/hooks/useDeleteMessages.ts +0 -260
- package/src/hooks/useDeleteOutcome.ts +0 -70
- package/src/hooks/useEmptyTrash.render.test.ts +0 -194
- package/src/hooks/useEmptyTrash.ts +0 -191
- package/src/hooks/useEscalatedActions.test.ts +0 -36
- package/src/hooks/useEscalatedActions.ts +0 -334
- package/src/hooks/useFilters.test.ts +0 -106
- package/src/hooks/useFilters.ts +0 -188
- package/src/hooks/useFolderLabelTranslator.ts +0 -19
- package/src/hooks/useFollowFocusOpen.render.test.ts +0 -145
- package/src/hooks/useFollowFocusOpen.ts +0 -81
- package/src/hooks/useInitialSyncProgress.render.test.ts +0 -314
- package/src/hooks/useInitialSyncProgress.ts +0 -134
- package/src/hooks/useInlineImages.ts +0 -93
- package/src/hooks/useIntelligenceCalendar.ts +0 -394
- package/src/hooks/useIntelligenceData.test.ts +0 -403
- package/src/hooks/useIntelligenceData.ts +0 -325
- package/src/hooks/useIntelligenceDrawer.ts +0 -54
- package/src/hooks/useIntelligenceSurface.ts +0 -103
- package/src/hooks/useIsDark.ts +0 -27
- package/src/hooks/useKeyboardNavigation.ts +0 -130
- package/src/hooks/useLabels.ts +0 -124
- package/src/hooks/useLayoutTier.test.ts +0 -96
- package/src/hooks/useLayoutTier.ts +0 -60
- package/src/hooks/useMailboxAccount.ts +0 -67
- package/src/hooks/useMailboxNameIndex.ts +0 -32
- package/src/hooks/useMarkAsRead.test.ts +0 -307
- package/src/hooks/useMarkAsRead.ts +0 -333
- package/src/hooks/useMatchSample.ts +0 -104
- package/src/hooks/useMediaQuery.ts +0 -13
- package/src/hooks/useMessageBodyContent.test.ts +0 -370
- package/src/hooks/useMessageBodyContent.ts +0 -388
- package/src/hooks/useMoveMessages.ts +0 -193
- package/src/hooks/useOrganizeJob.render.test.ts +0 -190
- package/src/hooks/useOrganizeJob.ts +0 -146
- package/src/hooks/useRailPanels.ts +0 -128
- package/src/hooks/useRedirectEnded.ts +0 -116
- package/src/hooks/useRefreshControl.test.ts +0 -287
- package/src/hooks/useRefreshControl.ts +0 -347
- package/src/hooks/useReportSpam.escalation.test.ts +0 -135
- package/src/hooks/useReportSpam.render.test.ts +0 -113
- package/src/hooks/useReportSpam.test.ts +0 -115
- package/src/hooks/useReportSpam.ts +0 -244
- package/src/hooks/useRescueCandidates.test.ts +0 -194
- package/src/hooks/useRescueCandidates.ts +0 -48
- package/src/hooks/useResultCount.render.test.ts +0 -161
- package/src/hooks/useResultCount.ts +0 -68
- package/src/hooks/useResultFolderIndex.ts +0 -88
- package/src/hooks/useReturnFromRedirect.ts +0 -41
- package/src/hooks/useRulePreview.ts +0 -122
- package/src/hooks/useSaveDraft.ts +0 -244
- package/src/hooks/useSearchScope.ts +0 -46
- package/src/hooks/useSearchSuggestions.ts +0 -126
- package/src/hooks/useSearchTokenContext.ts +0 -28
- package/src/hooks/useSelectedSubjects.ts +0 -79
- package/src/hooks/useSignature.ts +0 -69
- package/src/hooks/useSpamMatchCounts.ts +0 -102
- package/src/hooks/useStaleAccountSync.test.ts +0 -300
- package/src/hooks/useStaleAccountSync.ts +0 -325
- package/src/hooks/useStarredThreads.test.ts +0 -209
- package/src/hooks/useStarredThreads.ts +0 -146
- package/src/hooks/useThreadActions.star.test.ts +0 -200
- package/src/hooks/useThreadActions.ts +0 -127
- package/src/hooks/useThreadMessageIds.ts +0 -33
- package/src/hooks/useThreadRow.ts +0 -49
- package/src/hooks/useToggleStar.test.ts +0 -131
- package/src/hooks/useToggleStar.ts +0 -164
- package/src/hooks/useToggleTrusted.test.ts +0 -106
- package/src/hooks/useToggleTrusted.ts +0 -157
- package/src/hooks/useTriageLayer.ts +0 -167
- package/src/hooks/useTriggerSync.test.ts +0 -18
- package/src/hooks/useTriggerSync.ts +0 -64
- package/src/hooks/useUpdateAddressFlags.ts +0 -152
- package/src/hooks/useUpdateFilter.ts +0 -56
- package/src/hooks/useVisualViewport.render.test.ts +0 -63
- package/src/hooks/useVisualViewport.ts +0 -51
- package/src/hooks/useWarningsAttention.ts +0 -37
- package/src/index.css +0 -28
- package/src/index.css.test.ts +0 -97
- package/src/kit-stylesheets.test.ts +0 -64
- package/src/lib/account-order.test.ts +0 -74
- package/src/lib/account-order.ts +0 -13
- package/src/lib/adjacent-message.test.ts +0 -34
- package/src/lib/adjacent-message.ts +0 -20
- package/src/lib/api.ts +0 -121
- package/src/lib/app-info.ts +0 -32
- package/src/lib/attachment-download.test.ts +0 -207
- package/src/lib/attachment-download.ts +0 -195
- package/src/lib/auto-moved.test.ts +0 -234
- package/src/lib/auto-moved.ts +0 -103
- package/src/lib/autodiscovery.test.ts +0 -47
- package/src/lib/autodiscovery.ts +0 -354
- package/src/lib/brief-chip-query.test.ts +0 -85
- package/src/lib/brief-criteria.test.ts +0 -168
- package/src/lib/brief-criteria.ts +0 -129
- package/src/lib/brief.test.ts +0 -493
- package/src/lib/brief.ts +0 -205
- package/src/lib/bug-report.test.ts +0 -487
- package/src/lib/bug-report.ts +0 -320
- package/src/lib/bulk-action-copy.test.ts +0 -123
- package/src/lib/bulk-action-copy.ts +0 -182
- package/src/lib/bulk-actions.test.ts +0 -612
- package/src/lib/bulk-actions.ts +0 -400
- package/src/lib/calendar-collection-copy.test.ts +0 -23
- package/src/lib/calendar-collection-copy.ts +0 -21
- package/src/lib/calendar-density.ts +0 -46
- package/src/lib/calendar-feed-copy.ts +0 -29
- package/src/lib/calendar-feed-url.ts +0 -14
- package/src/lib/calendar-format.ts +0 -74
- package/src/lib/calendar-report.ts +0 -21
- package/src/lib/calendar-route.test.ts +0 -224
- package/src/lib/calendar-route.ts +0 -197
- package/src/lib/calendar-subscription.ts +0 -11
- package/src/lib/calendar-suggestion.test.ts +0 -189
- package/src/lib/calendar-suggestion.ts +0 -263
- package/src/lib/calendar-suggestion.west.test.ts +0 -61
- package/src/lib/client.test.ts +0 -114
- package/src/lib/client.ts +0 -33
- package/src/lib/compose-attachment-controller.test.ts +0 -352
- package/src/lib/compose-attachment-controller.ts +0 -519
- package/src/lib/config-import.test.ts +0 -339
- package/src/lib/config-import.ts +0 -512
- package/src/lib/console-errors.test.ts +0 -64
- package/src/lib/console-errors.ts +0 -92
- package/src/lib/conversation-target.ts +0 -17
- package/src/lib/dedupe-thread-messages.test.ts +0 -79
- package/src/lib/dedupe-thread-messages.ts +0 -26
- package/src/lib/delete-folder.test.ts +0 -304
- package/src/lib/delete-folder.ts +0 -188
- package/src/lib/desktop-breakpoint.test.ts +0 -76
- package/src/lib/display-category.test.ts +0 -32
- package/src/lib/display-category.ts +0 -24
- package/src/lib/drafts.test.ts +0 -218
- package/src/lib/drafts.ts +0 -122
- package/src/lib/error-classifier.test.ts +0 -434
- package/src/lib/error-classifier.ts +0 -260
- package/src/lib/escalation-label.test.ts +0 -49
- package/src/lib/escalation-label.ts +0 -32
- package/src/lib/fatal-error.test.ts +0 -78
- package/src/lib/fatal-error.ts +0 -165
- package/src/lib/filter-report.ts +0 -19
- package/src/lib/flagged-criteria.test.ts +0 -114
- package/src/lib/flagged-criteria.ts +0 -62
- package/src/lib/folder-failure.test.ts +0 -29
- package/src/lib/folder-failure.ts +0 -10
- package/src/lib/folder-roles.test.ts +0 -152
- package/src/lib/folder-roles.ts +0 -110
- package/src/lib/format.test.ts +0 -470
- package/src/lib/format.ts +0 -397
- package/src/lib/fresh-mailbox-count.test.ts +0 -145
- package/src/lib/fresh-mailbox-count.ts +0 -114
- package/src/lib/hot-sync-window.test.ts +0 -59
- package/src/lib/hot-sync-window.ts +0 -48
- package/src/lib/i18n.ts +0 -36
- package/src/lib/inbox-filters.test.ts +0 -134
- package/src/lib/inbox-filters.ts +0 -154
- package/src/lib/intelligence-pref.test.ts +0 -201
- package/src/lib/intelligence-pref.ts +0 -71
- package/src/lib/json.ts +0 -11
- package/src/lib/junk-destination.test.ts +0 -40
- package/src/lib/junk-destination.ts +0 -37
- package/src/lib/list-focus.test.ts +0 -25
- package/src/lib/list-focus.ts +0 -24
- package/src/lib/list-header-chrome.ts +0 -55
- package/src/lib/list-narrowing.test.ts +0 -88
- package/src/lib/list-narrowing.ts +0 -172
- package/src/lib/list-verb-request.test.ts +0 -124
- package/src/lib/list-verb-request.ts +0 -62
- package/src/lib/mail-context.ts +0 -91
- package/src/lib/mail-freshness.test.ts +0 -165
- package/src/lib/mail-freshness.tsx +0 -244
- package/src/lib/mail-route.test.ts +0 -261
- package/src/lib/mail-route.ts +0 -140
- package/src/lib/mail-search.ts +0 -69
- package/src/lib/mailbox-sync-wait.test.ts +0 -186
- package/src/lib/mailbox-sync-wait.ts +0 -102
- package/src/lib/message-attachments.test.ts +0 -163
- package/src/lib/message-attachments.ts +0 -70
- package/src/lib/message-body-source.test.ts +0 -115
- package/src/lib/message-body-source.ts +0 -51
- package/src/lib/move-options.test.ts +0 -154
- package/src/lib/move-options.ts +0 -60
- package/src/lib/move-targets.test.ts +0 -235
- package/src/lib/move-targets.ts +0 -70
- package/src/lib/network-error.ts +0 -74
- package/src/lib/new-folder.test.ts +0 -127
- package/src/lib/new-folder.ts +0 -59
- package/src/lib/onboarding-completion.test.ts +0 -48
- package/src/lib/onboarding-completion.ts +0 -23
- package/src/lib/organize/clause-suggestions.test.ts +0 -114
- package/src/lib/organize/clause-suggestions.ts +0 -89
- package/src/lib/organize/filter-edit-model.test.ts +0 -271
- package/src/lib/organize/filter-edit-model.ts +0 -129
- package/src/lib/organize/filter-run.test.ts +0 -79
- package/src/lib/organize/filter-run.ts +0 -48
- package/src/lib/organize/filter-status.test.ts +0 -120
- package/src/lib/organize/filter-status.ts +0 -115
- package/src/lib/organize/label-delete-copy.test.ts +0 -21
- package/src/lib/organize/label-delete-copy.ts +0 -22
- package/src/lib/organize/organize-model.test.ts +0 -209
- package/src/lib/organize/organize-model.ts +0 -198
- package/src/lib/organize/organize-poll.test.ts +0 -37
- package/src/lib/organize/organize-poll.ts +0 -28
- package/src/lib/organize/rule-model.test.ts +0 -211
- package/src/lib/organize/rule-model.ts +0 -140
- package/src/lib/organize/search-to-rule.test.ts +0 -142
- package/src/lib/organize/search-to-rule.ts +0 -105
- package/src/lib/outbox-search.test.ts +0 -75
- package/src/lib/outbox-search.ts +0 -58
- package/src/lib/outbox-status.test.ts +0 -79
- package/src/lib/outbox-status.ts +0 -79
- package/src/lib/provider-presets.test.ts +0 -51
- package/src/lib/provider-presets.ts +0 -94
- package/src/lib/quarantine-entries.test.ts +0 -77
- package/src/lib/quarantine-entries.ts +0 -46
- package/src/lib/query-error-handler.test.ts +0 -87
- package/src/lib/query-error-handler.ts +0 -41
- package/src/lib/query-escalation.integration.test.ts +0 -139
- package/src/lib/recent-searches.test.ts +0 -53
- package/src/lib/recent-searches.ts +0 -34
- package/src/lib/recipient-suggestions.test.ts +0 -109
- package/src/lib/recipient-suggestions.ts +0 -15
- package/src/lib/request-breadcrumbs.test.ts +0 -162
- package/src/lib/request-breadcrumbs.ts +0 -138
- package/src/lib/rescue-candidates.test.ts +0 -94
- package/src/lib/rescue-candidates.ts +0 -35
- package/src/lib/rescue-telemetry.ts +0 -55
- package/src/lib/result-count.test.ts +0 -97
- package/src/lib/result-count.ts +0 -57
- package/src/lib/result-folder.test.ts +0 -133
- package/src/lib/result-folder.ts +0 -111
- package/src/lib/route-breadcrumbs.test.ts +0 -41
- package/src/lib/route-breadcrumbs.ts +0 -45
- package/src/lib/route-search-query.test.ts +0 -70
- package/src/lib/row-settlement.ts +0 -28
- package/src/lib/rum-adapter.test.ts +0 -195
- package/src/lib/rum-adapter.ts +0 -107
- package/src/lib/search-conversion.ts +0 -23
- package/src/lib/search-params.test.ts +0 -77
- package/src/lib/search-params.ts +0 -59
- package/src/lib/search-query.test.ts +0 -24
- package/src/lib/search-query.ts +0 -11
- package/src/lib/search-result.test.ts +0 -20
- package/src/lib/search-result.ts +0 -55
- package/src/lib/search-scope.test.ts +0 -174
- package/src/lib/search-scope.ts +0 -140
- package/src/lib/search-suggestions.test.ts +0 -249
- package/src/lib/search-suggestions.ts +0 -296
- package/src/lib/search-surface.test.ts +0 -74
- package/src/lib/search-surface.ts +0 -34
- package/src/lib/search-token-index.test.ts +0 -232
- package/src/lib/search-token-index.ts +0 -120
- package/src/lib/search-tokens.test.ts +0 -454
- package/src/lib/search-tokens.ts +0 -319
- package/src/lib/search-view.test.ts +0 -320
- package/src/lib/search-view.ts +0 -97
- package/src/lib/selection-account-scope.ts +0 -40
- package/src/lib/selection-mode.test.ts +0 -34
- package/src/lib/selection-mode.ts +0 -24
- package/src/lib/self-update-state.test.ts +0 -552
- package/src/lib/self-update-state.ts +0 -658
- package/src/lib/sender-address.test.ts +0 -60
- package/src/lib/sender-address.ts +0 -36
- package/src/lib/session-storage.ts +0 -7
- package/src/lib/spam-offer.test.ts +0 -192
- package/src/lib/spam-offer.ts +0 -163
- package/src/lib/stale-build.test.ts +0 -52
- package/src/lib/stale-build.ts +0 -36
- package/src/lib/starred-rows.test.ts +0 -67
- package/src/lib/starred-rows.ts +0 -32
- package/src/lib/sync-warning-entries.ts +0 -33
- package/src/lib/telemetry-context.tsx +0 -9
- package/src/lib/telemetry.ts +0 -17
- package/src/lib/theme-preference.ts +0 -46
- package/src/lib/theme.ts +0 -33
- package/src/lib/thread-cache.test.ts +0 -65
- package/src/lib/thread-cache.ts +0 -76
- package/src/lib/thread-list-cache.test.ts +0 -147
- package/src/lib/thread-list-cache.ts +0 -119
- package/src/lib/thread-search-tokens.test.ts +0 -196
- package/src/lib/thread-search-tokens.ts +0 -177
- package/src/lib/wizard-selection.test.ts +0 -50
- package/src/lib/wizard-selection.ts +0 -43
- package/src/main.tsx +0 -10
- package/src/mocks/story-frame/AppStory.tsx +0 -62
- package/src/mocks/story-frame/calendar-window.ts +0 -21
- package/src/mocks/story-frame/compose-world.ts +0 -191
- package/src/mocks/story-frame/mail-handlers.ts +0 -556
- package/src/mocks/story-frame/mail-world.ts +0 -447
- package/src/mocks/story-frame/onboarding-handlers.ts +0 -97
- package/src/mocks/story-frame/session.tsx +0 -19
- package/src/mocks/story-frame/touch.ts +0 -22
- package/src/routeTree.gen.ts +0 -1279
- package/src/router.tsx +0 -59
- package/src/routes/__root.tsx +0 -92
- package/src/routes/calendar/$view.$date/$calendarObjectId/$recurrenceId.tsx +0 -26
- package/src/routes/calendar/$view.$date/$calendarObjectId/index.tsx +0 -18
- package/src/routes/calendar/$view.$date/$calendarObjectId.tsx +0 -15
- package/src/routes/calendar/$view.$date/index.tsx +0 -25
- package/src/routes/calendar/$view.$date/new.tsx +0 -20
- package/src/routes/calendar/$view.$date/suggestion.$suggestionId.tsx +0 -22
- package/src/routes/calendar/$view.$date.tsx +0 -170
- package/src/routes/calendar/-calendar-tree.test.ts +0 -285
- package/src/routes/calendar/index.tsx +0 -27
- package/src/routes/calendar.tsx +0 -99
- package/src/routes/import.tsx +0 -51
- package/src/routes/index.tsx +0 -7
- package/src/routes/mail/$mailboxId/$threadId/$messageId/$mode.{-$outboxMessageId}.tsx +0 -15
- package/src/routes/mail/$mailboxId/$threadId/$messageId.tsx +0 -23
- package/src/routes/mail/$mailboxId/$threadId/index.tsx +0 -14
- package/src/routes/mail/$mailboxId/$threadId.tsx +0 -12
- package/src/routes/mail/$mailboxId/compose.{-$outboxMessageId}.tsx +0 -14
- package/src/routes/mail/$mailboxId/index.tsx +0 -10
- package/src/routes/mail/$mailboxId.tsx +0 -38
- package/src/routes/mail/brief/$threadId/$messageId/$mode.{-$outboxMessageId}.tsx +0 -27
- package/src/routes/mail/brief/$threadId/$messageId.tsx +0 -23
- package/src/routes/mail/brief/$threadId/index.tsx +0 -14
- package/src/routes/mail/brief/$threadId.tsx +0 -16
- package/src/routes/mail/brief/compose.{-$outboxMessageId}.tsx +0 -22
- package/src/routes/mail/brief/index.tsx +0 -14
- package/src/routes/mail/brief.tsx +0 -52
- package/src/routes/mail/flagged/$threadId/$messageId/$mode.{-$outboxMessageId}.tsx +0 -15
- package/src/routes/mail/flagged/$threadId/$messageId.tsx +0 -23
- package/src/routes/mail/flagged/$threadId/index.tsx +0 -14
- package/src/routes/mail/flagged/$threadId.tsx +0 -16
- package/src/routes/mail/flagged/compose.{-$outboxMessageId}.tsx +0 -13
- package/src/routes/mail/flagged/index.tsx +0 -10
- package/src/routes/mail/flagged.tsx +0 -51
- package/src/routes/mail/index.tsx +0 -14
- package/src/routes/mail/outbox/compose.{-$outboxMessageId}.tsx +0 -17
- package/src/routes/mail/outbox/draft/$outboxMessageId.tsx +0 -19
- package/src/routes/mail/outbox/index.tsx +0 -10
- package/src/routes/mail/outbox.tsx +0 -32
- package/src/routes/mail.tsx +0 -262
- package/src/routes/onboarding.tsx +0 -47
- package/src/routes/settings/-accounts.test.ts +0 -340
- package/src/routes/settings/-filters.test.ts +0 -209
- package/src/routes/settings/-senders-remove-flag.render.test.ts +0 -105
- package/src/routes/settings/-shared/help-copy.tsx +0 -91
- package/src/routes/settings/accounts.tsx +0 -692
- package/src/routes/settings/advanced.tsx +0 -57
- package/src/routes/settings/appearance.tsx +0 -118
- package/src/routes/settings/calendars.tsx +0 -134
- package/src/routes/settings/filters.tsx +0 -259
- package/src/routes/settings/folders.tsx +0 -330
- package/src/routes/settings/index.tsx +0 -5
- package/src/routes/settings/labels.tsx +0 -242
- package/src/routes/settings/senders.tsx +0 -444
- package/src/routes/settings/suggested-vips.tsx +0 -10
- package/src/routes/settings/warnings.tsx +0 -36
- package/src/routes/settings.tsx +0 -87
- package/src/routing/browsed-list.ts +0 -76
- package/src/routing/calendar-fragment.test.ts +0 -66
- package/src/routing/calendar.ts +0 -250
- package/src/routing/compose-press-opens.render.test.ts +0 -179
- package/src/routing/compose.ts +0 -181
- package/src/routing/fragment.render.test.ts +0 -98
- package/src/routing/fragment.test.ts +0 -113
- package/src/routing/fragment.ts +0 -145
- package/src/routing/index.ts +0 -93
- package/src/routing/nav-link.tsx +0 -64
- package/src/routing/nav-selection.ts +0 -26
- package/src/routing/open-thread.ts +0 -157
- package/src/routing/outbox-draft.ts +0 -44
- package/src/routing/reply.ts +0 -335
- package/src/routing/search-field.render.test.ts +0 -216
- package/src/routing/search-field.ts +0 -85
- package/src/routing/search-mirror-convergence.render.test.ts +0 -198
- package/src/routing/search-mirror-detail.render.test.ts +0 -226
- package/src/routing/search-mirror.ts +0 -130
- package/src/routing/search-navigation.ts +0 -43
- package/src/routing/sections.ts +0 -55
- package/src/routing/wizard-history.test.ts +0 -163
- package/src/routing/wizard-history.ts +0 -219
- package/src/runtime-config.test.ts +0 -43
- package/src/runtime-config.ts +0 -104
- package/src/shell/index.tsx +0 -101
- package/src/test-support/bulk-run.ts +0 -13
- package/src/test-support/dom.ts +0 -232
- package/src/test-support/fixtures.ts +0 -109
- package/src/test-support/http.ts +0 -82
- package/src/test-support/intelligence-surface.ts +0 -42
- package/src/test-support/list-search-binding.ts +0 -34
- package/src/test-support/test-bundle-app.ts +0 -102
- package/src/test-support/thread-router.ts +0 -54
- package/vite.base.ts +0 -61
- /package/{src → dist/src}/auth/auth.css +0 -0
- /package/{src → dist/src}/auth/cognito/cognito.css +0 -0
- /package/{src → dist/src}/vite-env.d.ts +0 -0
|
@@ -1,1427 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
configOperationsGetConfigOptions,
|
|
3
|
-
outboxDetailOperationsDeleteOutboxMessageMutation,
|
|
4
|
-
outboxDetailOperationsGetOutboxMessageOptions,
|
|
5
|
-
outboxDetailOperationsSendOutboxMessageMutation,
|
|
6
|
-
} from "@remit/api-http-client/@tanstack/react-query.gen.ts";
|
|
7
|
-
import type {
|
|
8
|
-
RemitImapAccountResponse,
|
|
9
|
-
RemitImapDescribeMessageResponse,
|
|
10
|
-
} from "@remit/api-http-client/types.gen.ts";
|
|
11
|
-
import {
|
|
12
|
-
Banner,
|
|
13
|
-
ComposeActionBar,
|
|
14
|
-
ComposeAttachments,
|
|
15
|
-
ComposeBodySkeleton,
|
|
16
|
-
ComposeFormShell,
|
|
17
|
-
ComposeHeader,
|
|
18
|
-
ComposeQuoteMissingBanner,
|
|
19
|
-
type ComposeQuoteMode,
|
|
20
|
-
type ComposeSendState,
|
|
21
|
-
type ComposeShellLayout,
|
|
22
|
-
ComposeSubjectField,
|
|
23
|
-
composeHeaderSummary,
|
|
24
|
-
defaultComposeLanguages,
|
|
25
|
-
modeOfDraft,
|
|
26
|
-
NO_QUOTABLE_BODY_FORWARD_MESSAGE,
|
|
27
|
-
QuotedText,
|
|
28
|
-
type RichTextValue,
|
|
29
|
-
SMTP_MISSING_MESSAGE,
|
|
30
|
-
sanitizeQuotedHtml,
|
|
31
|
-
unwrapLanguage,
|
|
32
|
-
} from "@remit/ui";
|
|
33
|
-
import type { ComposeBodyMode, ComposeInsertion } from "@remit/ui/rich-text";
|
|
34
|
-
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
35
|
-
import type { RefObject } from "react";
|
|
36
|
-
import {
|
|
37
|
-
lazy,
|
|
38
|
-
Suspense,
|
|
39
|
-
useCallback,
|
|
40
|
-
useEffect,
|
|
41
|
-
useMemo,
|
|
42
|
-
useRef,
|
|
43
|
-
useState,
|
|
44
|
-
} from "react";
|
|
45
|
-
import {
|
|
46
|
-
type DraftForAttachment,
|
|
47
|
-
useComposeAttachments,
|
|
48
|
-
} from "../../hooks/useComposeAttachments";
|
|
49
|
-
import { useInlineImages } from "../../hooks/useInlineImages";
|
|
50
|
-
import { useMessageBodyContent } from "../../hooks/useMessageBodyContent";
|
|
51
|
-
import { useSaveDraft } from "../../hooks/useSaveDraft";
|
|
52
|
-
import { useSignature } from "../../hooks/useSignature.js";
|
|
53
|
-
import { isNotFound, softErrorMeta } from "../../lib/error-classifier";
|
|
54
|
-
import type { ComposeSeed } from "../../lib/mail-search";
|
|
55
|
-
import { accountIsMissingSmtp } from "../settings/account-form-helpers.js";
|
|
56
|
-
import { useErrorBanners } from "../ui/ErrorBannerProvider.js";
|
|
57
|
-
import {
|
|
58
|
-
buildMutationErrorBanner,
|
|
59
|
-
formatErrorDetail,
|
|
60
|
-
} from "../ui/error-banners.js";
|
|
61
|
-
import type {
|
|
62
|
-
AddressEntry,
|
|
63
|
-
ComposeAddressFieldHandle,
|
|
64
|
-
ParsedAddressInput,
|
|
65
|
-
} from "./AddressField";
|
|
66
|
-
import { AddressField } from "./AddressField";
|
|
67
|
-
import { ComposeSmtpMissingBanner } from "./ComposeSmtpMissingBanner";
|
|
68
|
-
import { composeSpellcheck } from "./compose-spellcheck.js";
|
|
69
|
-
import { mailSyncOffReason } from "./mail-sync-off-refusal.js";
|
|
70
|
-
import {
|
|
71
|
-
buildQuotedBlock,
|
|
72
|
-
outgoingBody,
|
|
73
|
-
type QuotedBlock,
|
|
74
|
-
type QuotedSourceBody,
|
|
75
|
-
textToHtml,
|
|
76
|
-
} from "./quoted-message.js";
|
|
77
|
-
|
|
78
|
-
const LazyComposeBody = lazy(() =>
|
|
79
|
-
import("@remit/ui/rich-text").then((m) => ({ default: m.ComposeBody })),
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
import { useIsDesktop } from "../../hooks/useMediaQuery.js";
|
|
83
|
-
import { useVisualViewport } from "../../hooks/useVisualViewport.js";
|
|
84
|
-
import type { ComposeMode } from "./ComposeProvider";
|
|
85
|
-
import { OUTBOX_ROW_META, useCompose } from "./ComposeProvider";
|
|
86
|
-
import { FromSelector } from "./FromSelector";
|
|
87
|
-
|
|
88
|
-
interface ComposeFormProps {
|
|
89
|
-
mode: ComposeMode;
|
|
90
|
-
account?: RemitImapAccountResponse;
|
|
91
|
-
sourceMessage?: RemitImapDescribeMessageResponse;
|
|
92
|
-
/**
|
|
93
|
-
* The draft this composer writes to. Absent until there is one, and owned by
|
|
94
|
-
* whoever mounted the form — the address for the compose route, the inline
|
|
95
|
-
* composer's own state for a reply. A composer that read it from somewhere
|
|
96
|
-
* shared would open on the last draft any other composer touched.
|
|
97
|
-
*/
|
|
98
|
-
outboxMessageId?: string;
|
|
99
|
-
seed?: ComposeSeed;
|
|
100
|
-
insertion?: ComposeInsertion;
|
|
101
|
-
/** The draft the first autosave created, for the owner to record. */
|
|
102
|
-
onDraftCreated: (outboxMessageId: string) => void;
|
|
103
|
-
onClose: () => void;
|
|
104
|
-
onAccountChange?: (account: RemitImapAccountResponse) => void;
|
|
105
|
-
/**
|
|
106
|
-
* How the surface takes its height. A window in its own pane fills that
|
|
107
|
-
* pane; one opened as a block of the conversation grows with what is written
|
|
108
|
-
* in it and leaves the pane the only scroller.
|
|
109
|
-
*/
|
|
110
|
-
layout?: ComposeShellLayout;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const buildInitialHtml = (signaturePlainText: string): string => {
|
|
114
|
-
if (!signaturePlainText) return "";
|
|
115
|
-
return `<p></p><p>-- </p>${textToHtml(signaturePlainText)}`;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* The document a new message opens on. One definition, because a form that
|
|
120
|
-
* starts a second message without remounting has to open on the same thing the
|
|
121
|
-
* first one did.
|
|
122
|
-
*/
|
|
123
|
-
const freshDocument = (
|
|
124
|
-
signaturePlainText: string,
|
|
125
|
-
seed?: ComposeSeed,
|
|
126
|
-
): { html: string; text: string } => {
|
|
127
|
-
if (!seed) {
|
|
128
|
-
return {
|
|
129
|
-
html: buildInitialHtml(signaturePlainText),
|
|
130
|
-
text: signaturePlainText,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
html: `${textToHtml(seed.body)}${buildInitialHtml(signaturePlainText)}`,
|
|
135
|
-
text: [seed.body, signaturePlainText].filter(Boolean).join("\n\n"),
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
const buildReplySubject = (subject?: string): string => {
|
|
140
|
-
if (!subject) return "Re: ";
|
|
141
|
-
if (/^re:\s/i.test(subject)) return subject;
|
|
142
|
-
return `Re: ${subject}`;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const buildForwardSubject = (subject?: string): string => {
|
|
146
|
-
if (!subject) return "Fwd: ";
|
|
147
|
-
if (/^fwd?:\s/i.test(subject)) return subject;
|
|
148
|
-
return `Fwd: ${subject}`;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const getReplyAddresses = (
|
|
152
|
-
msg: RemitImapDescribeMessageResponse,
|
|
153
|
-
mode: ComposeMode,
|
|
154
|
-
myEmail?: string,
|
|
155
|
-
): { to: AddressEntry[]; cc: AddressEntry[] } => {
|
|
156
|
-
const { envelope } = msg;
|
|
157
|
-
const replyTo =
|
|
158
|
-
envelope.replyTo.length > 0 ? envelope.replyTo : envelope.from;
|
|
159
|
-
|
|
160
|
-
const to: AddressEntry[] = replyTo.map((a) => ({
|
|
161
|
-
email: a.normalizedEmail,
|
|
162
|
-
displayName: a.displayName,
|
|
163
|
-
}));
|
|
164
|
-
|
|
165
|
-
if (mode !== "reply-all") return { to, cc: [] };
|
|
166
|
-
|
|
167
|
-
const myEmailLower = myEmail?.toLowerCase();
|
|
168
|
-
const toEmails = new Set(to.map((a) => a.email.toLowerCase()));
|
|
169
|
-
|
|
170
|
-
const cc: AddressEntry[] = [...envelope.to, ...envelope.cc]
|
|
171
|
-
.filter(
|
|
172
|
-
(a) =>
|
|
173
|
-
a.normalizedEmail.toLowerCase() !== myEmailLower &&
|
|
174
|
-
!toEmails.has(a.normalizedEmail.toLowerCase()),
|
|
175
|
-
)
|
|
176
|
-
.map((a) => ({
|
|
177
|
-
email: a.normalizedEmail,
|
|
178
|
-
displayName: a.displayName,
|
|
179
|
-
}));
|
|
180
|
-
|
|
181
|
-
return { to, cc };
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const getReferences = (
|
|
185
|
-
msg: RemitImapDescribeMessageResponse,
|
|
186
|
-
): { inReplyTo?: string; references: string[] } => {
|
|
187
|
-
const messageIdValue = msg.envelope.messageIdValue;
|
|
188
|
-
const ofType = (
|
|
189
|
-
type: RemitImapDescribeMessageResponse["references"][number]["referenceType"],
|
|
190
|
-
): string[] =>
|
|
191
|
-
msg.references
|
|
192
|
-
.filter((r) => r.referenceType === type)
|
|
193
|
-
.sort((a, b) => a.referenceOrder - b.referenceOrder)
|
|
194
|
-
.map((r) => r.messageIdValue);
|
|
195
|
-
const existingRefs = ofType("references");
|
|
196
|
-
|
|
197
|
-
const references =
|
|
198
|
-
existingRefs.length > 0 ? [...existingRefs] : ofType("in_reply_to");
|
|
199
|
-
if (messageIdValue && !references.includes(messageIdValue)) {
|
|
200
|
-
references.push(messageIdValue);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return {
|
|
204
|
-
inReplyTo: messageIdValue,
|
|
205
|
-
references,
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
type SendReadiness =
|
|
210
|
-
| { status: "sending" }
|
|
211
|
-
| { status: "blocked"; reason: string }
|
|
212
|
-
| { status: "ready"; accountId: string };
|
|
213
|
-
|
|
214
|
-
/** The three recipient lists a send goes out with. */
|
|
215
|
-
interface Recipients {
|
|
216
|
-
to: AddressEntry[];
|
|
217
|
-
cc: AddressEntry[];
|
|
218
|
-
bcc: AddressEntry[];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/** The fields a send takes its recipients from, in the order they are read. */
|
|
222
|
-
interface AddressFieldHandles {
|
|
223
|
-
to: RefObject<ComposeAddressFieldHandle | null>;
|
|
224
|
-
cc: RefObject<ComposeAddressFieldHandle | null>;
|
|
225
|
-
bcc: RefObject<ComposeAddressFieldHandle | null>;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Naming To, not "a recipient". Sending goes through the draft, and a draft is
|
|
230
|
-
* created against `CreateOutboxMessageInput`, whose `@minItems(1)` is on
|
|
231
|
-
* `toAddresses` alone — so a message addressed only in Cc has a recipient and
|
|
232
|
-
* still cannot be sent from here, and being told to add one it can already see
|
|
233
|
-
* leaves it with nothing to do. The server's own send guard counts Cc and Bcc,
|
|
234
|
-
* because a Bcc-only envelope is real mail; it is answering whether the message
|
|
235
|
-
* has anywhere to go, which is not the question this one asks.
|
|
236
|
-
*/
|
|
237
|
-
const NO_TO_ADDRESS_MESSAGE = "Add a To address before sending.";
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Send waits for the message being quoted. Pressed before it lands, the send
|
|
241
|
-
* would go out carrying the answer and nothing of what it answers — the defect
|
|
242
|
-
* this refusal exists to make impossible rather than merely unlikely (#845.5).
|
|
243
|
-
*/
|
|
244
|
-
const QUOTE_LOADING_MESSAGE = "Loading the message you're quoting.";
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* The quoted original could not be fetched. A forward without it is an empty
|
|
248
|
-
* message and a reply without it drops the thread, so the composer says so
|
|
249
|
-
* where the message is being written instead of sending a message the user
|
|
250
|
-
* believes carries the original.
|
|
251
|
-
*/
|
|
252
|
-
const QUOTE_FAILED_MESSAGE =
|
|
253
|
-
"The message you're quoting couldn't be loaded, so it won't be included.";
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* A file needs a draft to hang from, and a draft is created against its To
|
|
257
|
-
* address, so a message with none cannot take a file yet.
|
|
258
|
-
*/
|
|
259
|
-
const ATTACH_NEEDS_TO_ADDRESS =
|
|
260
|
-
"Add a To address before attaching a file — the draft the file is kept with is saved against it.";
|
|
261
|
-
|
|
262
|
-
/** A field holding text that is not an address, and which field it is. */
|
|
263
|
-
interface UnparsedField {
|
|
264
|
-
label: string;
|
|
265
|
-
text: string;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Text a recipient field could not read as an address stops the send and is
|
|
270
|
-
* quoted back. It is on screen and it was meant for somebody, so sending
|
|
271
|
-
* without it would deliver a message to fewer people than it was addressed to,
|
|
272
|
-
* and the composer closing on the send would take the text with it.
|
|
273
|
-
*/
|
|
274
|
-
const unparsedRefusal = ({ label, text }: UnparsedField): string =>
|
|
275
|
-
`${label} holds "${text}", which is not an address.`;
|
|
276
|
-
|
|
277
|
-
const firstUnparsed = (
|
|
278
|
-
fields: readonly UnparsedField[],
|
|
279
|
-
): UnparsedField | undefined =>
|
|
280
|
-
fields.find((field) => field.text.trim() !== "");
|
|
281
|
-
|
|
282
|
-
const EMPTY_PENDING: ParsedAddressInput = { entries: [], unparsed: "" };
|
|
283
|
-
|
|
284
|
-
const isFormEmpty = (
|
|
285
|
-
toAddresses: AddressEntry[],
|
|
286
|
-
ccAddresses: AddressEntry[],
|
|
287
|
-
bccAddresses: AddressEntry[],
|
|
288
|
-
subject: string,
|
|
289
|
-
body: RichTextValue,
|
|
290
|
-
): boolean =>
|
|
291
|
-
toAddresses.length === 0 &&
|
|
292
|
-
ccAddresses.length === 0 &&
|
|
293
|
-
bccAddresses.length === 0 &&
|
|
294
|
-
subject.trim() === "" &&
|
|
295
|
-
body.text.trim() === "";
|
|
296
|
-
|
|
297
|
-
// ---------------------------------------------------------------------------
|
|
298
|
-
// WiredComposeHeader — the shared header, with the app's fields in its slots
|
|
299
|
-
// ---------------------------------------------------------------------------
|
|
300
|
-
|
|
301
|
-
interface WiredComposeHeaderProps {
|
|
302
|
-
documentGeneration: number;
|
|
303
|
-
selectedAccountId?: string;
|
|
304
|
-
onAccountChange: (account: RemitImapAccountResponse) => void;
|
|
305
|
-
toAddresses: AddressEntry[];
|
|
306
|
-
setToAddresses: (v: AddressEntry[]) => void;
|
|
307
|
-
ccAddresses: AddressEntry[];
|
|
308
|
-
setCcAddresses: (v: AddressEntry[]) => void;
|
|
309
|
-
bccAddresses: AddressEntry[];
|
|
310
|
-
setBccAddresses: (v: AddressEntry[]) => void;
|
|
311
|
-
showCc: boolean;
|
|
312
|
-
setShowCc: (v: boolean) => void;
|
|
313
|
-
showBcc: boolean;
|
|
314
|
-
setShowBcc: (v: boolean) => void;
|
|
315
|
-
subject: string;
|
|
316
|
-
setSubject: (v: string) => void;
|
|
317
|
-
fieldHandles: AddressFieldHandles;
|
|
318
|
-
onToPendingChange: (pending: ParsedAddressInput) => void;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const WiredComposeHeader = ({
|
|
322
|
-
documentGeneration,
|
|
323
|
-
selectedAccountId,
|
|
324
|
-
onAccountChange,
|
|
325
|
-
toAddresses,
|
|
326
|
-
setToAddresses,
|
|
327
|
-
ccAddresses,
|
|
328
|
-
setCcAddresses,
|
|
329
|
-
bccAddresses,
|
|
330
|
-
setBccAddresses,
|
|
331
|
-
showCc,
|
|
332
|
-
setShowCc,
|
|
333
|
-
showBcc,
|
|
334
|
-
setShowBcc,
|
|
335
|
-
subject,
|
|
336
|
-
setSubject,
|
|
337
|
-
fieldHandles,
|
|
338
|
-
onToPendingChange,
|
|
339
|
-
}: WiredComposeHeaderProps) => {
|
|
340
|
-
const isDesktop = useIsDesktop();
|
|
341
|
-
const { isKeyboardOpen } = useVisualViewport();
|
|
342
|
-
// What the user asked to see belongs to the document being written, not to
|
|
343
|
-
// the keyboard. Tying it to the keyboard collapsed the rows again the moment
|
|
344
|
-
// one came back up — over the recipient field being typed into, which took
|
|
345
|
-
// the keyboard down with it and started the cycle over.
|
|
346
|
-
const [expandedFor, setExpandedFor] = useState<number | undefined>(undefined);
|
|
347
|
-
const expanded = expandedFor === documentGeneration;
|
|
348
|
-
const [focusWithin, setFocusWithin] = useState(false);
|
|
349
|
-
|
|
350
|
-
return (
|
|
351
|
-
<div
|
|
352
|
-
className="contents"
|
|
353
|
-
onFocusCapture={() => setFocusWithin(true)}
|
|
354
|
-
onBlurCapture={(event) => {
|
|
355
|
-
if (event.currentTarget.contains(event.relatedTarget)) return;
|
|
356
|
-
setFocusWithin(false);
|
|
357
|
-
}}
|
|
358
|
-
>
|
|
359
|
-
<ComposeHeader
|
|
360
|
-
collapsed={!isDesktop && isKeyboardOpen && !expanded && !focusWithin}
|
|
361
|
-
onExpand={() => setExpandedFor(documentGeneration)}
|
|
362
|
-
summary={composeHeaderSummary({
|
|
363
|
-
to: toAddresses,
|
|
364
|
-
cc: ccAddresses,
|
|
365
|
-
bcc: bccAddresses,
|
|
366
|
-
subject,
|
|
367
|
-
})}
|
|
368
|
-
from={
|
|
369
|
-
<FromSelector
|
|
370
|
-
selectedAccountId={selectedAccountId}
|
|
371
|
-
onSelect={onAccountChange}
|
|
372
|
-
/>
|
|
373
|
-
}
|
|
374
|
-
to={
|
|
375
|
-
<AddressField
|
|
376
|
-
label="To"
|
|
377
|
-
addresses={toAddresses}
|
|
378
|
-
onChange={setToAddresses}
|
|
379
|
-
placeholder="Recipients"
|
|
380
|
-
onPendingChange={onToPendingChange}
|
|
381
|
-
ref={fieldHandles.to}
|
|
382
|
-
/>
|
|
383
|
-
}
|
|
384
|
-
cc={
|
|
385
|
-
showCc ? (
|
|
386
|
-
<AddressField
|
|
387
|
-
label="Cc"
|
|
388
|
-
addresses={ccAddresses}
|
|
389
|
-
onChange={setCcAddresses}
|
|
390
|
-
ref={fieldHandles.cc}
|
|
391
|
-
/>
|
|
392
|
-
) : undefined
|
|
393
|
-
}
|
|
394
|
-
bcc={
|
|
395
|
-
showBcc ? (
|
|
396
|
-
<AddressField
|
|
397
|
-
label="Bcc"
|
|
398
|
-
addresses={bccAddresses}
|
|
399
|
-
onChange={setBccAddresses}
|
|
400
|
-
ref={fieldHandles.bcc}
|
|
401
|
-
/>
|
|
402
|
-
) : undefined
|
|
403
|
-
}
|
|
404
|
-
subject={<ComposeSubjectField value={subject} onChange={setSubject} />}
|
|
405
|
-
onShowCc={() => setShowCc(true)}
|
|
406
|
-
onShowBcc={() => setShowBcc(true)}
|
|
407
|
-
/>
|
|
408
|
-
</div>
|
|
409
|
-
);
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
export const ComposeForm = ({
|
|
413
|
-
mode,
|
|
414
|
-
account,
|
|
415
|
-
sourceMessage,
|
|
416
|
-
outboxMessageId,
|
|
417
|
-
seed,
|
|
418
|
-
insertion,
|
|
419
|
-
onDraftCreated,
|
|
420
|
-
onClose,
|
|
421
|
-
onAccountChange,
|
|
422
|
-
layout = "fill",
|
|
423
|
-
}: ComposeFormProps) => {
|
|
424
|
-
const { startSendPolling } = useCompose();
|
|
425
|
-
const { pushError } = useErrorBanners();
|
|
426
|
-
|
|
427
|
-
const [toAddresses, setToAddresses] = useState<AddressEntry[]>([]);
|
|
428
|
-
const [ccAddresses, setCcAddresses] = useState<AddressEntry[]>([]);
|
|
429
|
-
const [bccAddresses, setBccAddresses] = useState<AddressEntry[]>([]);
|
|
430
|
-
/**
|
|
431
|
-
* What To is holding but has not committed. A press on Send takes it, so the
|
|
432
|
-
* refusal for having no recipient must not stand while an address is on
|
|
433
|
-
* screen — the button's own reason comes from this state, before the press.
|
|
434
|
-
*/
|
|
435
|
-
const [pendingTo, setPendingTo] = useState<ParsedAddressInput>(EMPTY_PENDING);
|
|
436
|
-
const toFieldRef = useRef<ComposeAddressFieldHandle>(null);
|
|
437
|
-
const ccFieldRef = useRef<ComposeAddressFieldHandle>(null);
|
|
438
|
-
const bccFieldRef = useRef<ComposeAddressFieldHandle>(null);
|
|
439
|
-
const fieldHandles = useMemo<AddressFieldHandles>(
|
|
440
|
-
() => ({ to: toFieldRef, cc: ccFieldRef, bcc: bccFieldRef }),
|
|
441
|
-
[],
|
|
442
|
-
);
|
|
443
|
-
/** A new document leaves nothing typed behind in a field that did not remount. */
|
|
444
|
-
const clearPendingFields = useCallback(() => {
|
|
445
|
-
toFieldRef.current?.clearPending();
|
|
446
|
-
ccFieldRef.current?.clearPending();
|
|
447
|
-
bccFieldRef.current?.clearPending();
|
|
448
|
-
}, []);
|
|
449
|
-
const [subject, setSubject] = useState("");
|
|
450
|
-
const [showCc, setShowCc] = useState(false);
|
|
451
|
-
const [showBcc, setShowBcc] = useState(false);
|
|
452
|
-
const [selectedAccountId, setSelectedAccountId] = useState(
|
|
453
|
-
account?.accountId,
|
|
454
|
-
);
|
|
455
|
-
const [draftLoaded, setDraftLoaded] = useState(false);
|
|
456
|
-
/**
|
|
457
|
-
* The document the fields on screen belong to. It trails `outboxMessageId`
|
|
458
|
-
* for one commit whenever the document changes, and autosave has to sit that
|
|
459
|
-
* commit out — the fields still hold the message that has just been left.
|
|
460
|
-
*/
|
|
461
|
-
const [openDocumentId, setOpenDocumentId] = useState(outboxMessageId);
|
|
462
|
-
/**
|
|
463
|
-
* What the server's copy of this document would autosave as, so a draft that
|
|
464
|
-
* is only being looked at writes nothing.
|
|
465
|
-
*
|
|
466
|
-
* Opening one runs the autosave effect on the render that fills the fields
|
|
467
|
-
* from the read, and that write is no longer free: an edit returns a settled
|
|
468
|
-
* failure to `draft` (#933), so opening a Failed message and pressing Escape
|
|
469
|
-
* would take it out of the Outbox with the reader having changed nothing. The
|
|
470
|
-
* first run after a load records what was loaded; only a payload that differs
|
|
471
|
-
* from it is an edit.
|
|
472
|
-
*/
|
|
473
|
-
const loadedPayloadRef = useRef<string | undefined>(undefined);
|
|
474
|
-
const captureLoadedPayloadRef = useRef(false);
|
|
475
|
-
const smtpConfigureRef = useRef<HTMLButtonElement>(null);
|
|
476
|
-
const prevOutboxMessageIdRef = useRef<string | undefined>(outboxMessageId);
|
|
477
|
-
/**
|
|
478
|
-
* Whether the document on screen came from a draft the server already held.
|
|
479
|
-
* A reply carries the message it answers whether it is being started or being
|
|
480
|
-
* resumed, so this is what separates the two: the source seeds a reply that
|
|
481
|
-
* has nothing behind it, and leaves a saved one holding the recipients and
|
|
482
|
-
* the subject the reader edited.
|
|
483
|
-
*/
|
|
484
|
-
const resumedDraftRef = useRef(outboxMessageId !== undefined);
|
|
485
|
-
/**
|
|
486
|
-
* Whether the document on screen already carries the quoted original. True of
|
|
487
|
-
* exactly one thing: a draft read back from the server, which was saved with
|
|
488
|
-
* the quote in its body. Held as state rather than read off `resumedDraftRef`
|
|
489
|
-
* because the quote is assembled during render.
|
|
490
|
-
*/
|
|
491
|
-
const [documentHoldsQuote, setDocumentHoldsQuote] = useState(
|
|
492
|
-
outboxMessageId !== undefined,
|
|
493
|
-
);
|
|
494
|
-
/**
|
|
495
|
-
* The mode the fields on screen were last written for. A draft that is
|
|
496
|
-
* resumed holds what its reader saved and must not be overwritten when it
|
|
497
|
-
* mounts — but a switch of mode over the same message asks for different
|
|
498
|
-
* recipients, which is how Reply All reaches the Cc field (#796).
|
|
499
|
-
*
|
|
500
|
-
* Taken at mount rather than on the first run that has a source: the source
|
|
501
|
-
* is fetched fresh after a reload, so a reader who presses Reply All before
|
|
502
|
-
* it lands would otherwise have that press recorded as the mode the draft
|
|
503
|
-
* opened under, and Reply All would stay dead.
|
|
504
|
-
*/
|
|
505
|
-
const seededModeRef = useRef<ComposeMode | undefined>(
|
|
506
|
-
outboxMessageId !== undefined ? mode : undefined,
|
|
507
|
-
);
|
|
508
|
-
/**
|
|
509
|
-
* The reader's own address the recipients were last written against, absent
|
|
510
|
-
* until something has been written. The account resolves from the source's
|
|
511
|
-
* mailbox, so it lands after the source: a seed made before it arrived kept
|
|
512
|
-
* the reader in their own Cc (#819), and is redone once it does.
|
|
513
|
-
*/
|
|
514
|
-
const seededMyEmailRef = useRef<{ myEmail: string | undefined } | undefined>(
|
|
515
|
-
undefined,
|
|
516
|
-
);
|
|
517
|
-
// Read where a mode change must not itself be the trigger.
|
|
518
|
-
const modeRef = useRef(mode);
|
|
519
|
-
modeRef.current = mode;
|
|
520
|
-
/**
|
|
521
|
-
* The identity this form has already taken from the surface that mounted it.
|
|
522
|
-
* A reply learns which account the message reached only once the mailbox it
|
|
523
|
-
* was delivered to resolves, which lands after the first render — so From
|
|
524
|
-
* follows the prop instead of only its initial value. Applied once per
|
|
525
|
-
* identity, so a reader who then picks another one keeps it.
|
|
526
|
-
*/
|
|
527
|
-
const appliedAccountIdRef = useRef(account?.accountId);
|
|
528
|
-
|
|
529
|
-
useEffect(() => {
|
|
530
|
-
const accountId = account?.accountId;
|
|
531
|
-
if (!accountId || appliedAccountIdRef.current === accountId) return;
|
|
532
|
-
appliedAccountIdRef.current = accountId;
|
|
533
|
-
// A saved draft carries the account it was written from; that is the one
|
|
534
|
-
// it reopens on.
|
|
535
|
-
if (resumedDraftRef.current) return;
|
|
536
|
-
setSelectedAccountId(accountId);
|
|
537
|
-
}, [account?.accountId]);
|
|
538
|
-
|
|
539
|
-
// The document this form is on changed under it, so it starts again: another
|
|
540
|
-
// draft, or no draft at all. Without this the previous one's fields stay on
|
|
541
|
-
// screen and the new one never loads, because `draftLoaded` is still true
|
|
542
|
-
// from the session before (#536).
|
|
543
|
-
//
|
|
544
|
-
// "No draft at all" is Compose pressed while already composing — the address
|
|
545
|
-
// drops the draft segment and the same route stays matched, so nothing
|
|
546
|
-
// remounts the form. Leaving it alone there showed the old message under an
|
|
547
|
-
// address that said new one, and the next autosave took the create branch
|
|
548
|
-
// and wrote a second draft holding the first one's content.
|
|
549
|
-
//
|
|
550
|
-
// The one change that is not a different document is the first autosave
|
|
551
|
-
// adopting the id it just created. That is this session's own content coming
|
|
552
|
-
// back, and blanking the form there would throw away what is being typed.
|
|
553
|
-
useEffect(() => {
|
|
554
|
-
const previous = prevOutboxMessageIdRef.current;
|
|
555
|
-
if (previous === outboxMessageId) return;
|
|
556
|
-
prevOutboxMessageIdRef.current = outboxMessageId;
|
|
557
|
-
if (previous === undefined) return;
|
|
558
|
-
resumedDraftRef.current = outboxMessageId !== undefined;
|
|
559
|
-
setDocumentHoldsQuote(outboxMessageId !== undefined);
|
|
560
|
-
seededModeRef.current =
|
|
561
|
-
outboxMessageId !== undefined ? modeRef.current : undefined;
|
|
562
|
-
seededMyEmailRef.current = undefined;
|
|
563
|
-
// A draft brings its own body along in a moment; a new message opens on
|
|
564
|
-
// the signature, the same document a fresh mount would have started on.
|
|
565
|
-
const opening = outboxMessageId
|
|
566
|
-
? { html: "", text: "" }
|
|
567
|
-
: freshDocument(signatureRef.current, seedRef.current);
|
|
568
|
-
setToAddresses([]);
|
|
569
|
-
setCcAddresses([]);
|
|
570
|
-
setBccAddresses([]);
|
|
571
|
-
clearPendingFields();
|
|
572
|
-
setSubject("");
|
|
573
|
-
setShowCc(false);
|
|
574
|
-
setShowBcc(false);
|
|
575
|
-
setInitialHtml(opening.html);
|
|
576
|
-
setInitialText(opening.text);
|
|
577
|
-
setBodyMode("rich");
|
|
578
|
-
setDraftLanguage(undefined);
|
|
579
|
-
setBody({ ...opening, formatting: [] });
|
|
580
|
-
setDocumentGeneration((generation) => generation + 1);
|
|
581
|
-
setDraftLoaded(false);
|
|
582
|
-
loadedPayloadRef.current = undefined;
|
|
583
|
-
captureLoadedPayloadRef.current = false;
|
|
584
|
-
setOpenDocumentId(outboxMessageId);
|
|
585
|
-
}, [outboxMessageId, clearPendingFields]);
|
|
586
|
-
|
|
587
|
-
const { signature } = useSignature(selectedAccountId);
|
|
588
|
-
// Read when a new message starts, never depended on: a signature arriving is
|
|
589
|
-
// not a reason to reopen the document somebody is typing in.
|
|
590
|
-
const signatureRef = useRef(signature.plainText);
|
|
591
|
-
signatureRef.current = signature.plainText;
|
|
592
|
-
const seedRef = useRef(seed);
|
|
593
|
-
seedRef.current = seed;
|
|
594
|
-
// The editor reads its document once, so this is the document it opens on,
|
|
595
|
-
// not the live value, and it is remounted when the generation changes. Only
|
|
596
|
-
// loading a different document bumps that — remounting mid-compose would take
|
|
597
|
-
// the caret, the focus and the undo history with it.
|
|
598
|
-
const [documentGeneration, setDocumentGeneration] = useState(0);
|
|
599
|
-
const [initialHtml, setInitialHtml] = useState(
|
|
600
|
-
() => freshDocument(signature.plainText, seed).html,
|
|
601
|
-
);
|
|
602
|
-
const [initialText, setInitialText] = useState(
|
|
603
|
-
() => freshDocument(signature.plainText, seed).text,
|
|
604
|
-
);
|
|
605
|
-
const [bodyMode, setBodyMode] = useState<ComposeBodyMode>("rich");
|
|
606
|
-
// What the body is tagged with on the way out. The composer owns the value —
|
|
607
|
-
// it is the surface that has the text detection reads — and reports it here,
|
|
608
|
-
// because this is where a draft is written and where a send is assembled.
|
|
609
|
-
const [composeLanguage, setComposeLanguage] = useState("en");
|
|
610
|
-
const [draftLanguage, setDraftLanguage] = useState<string | undefined>();
|
|
611
|
-
const [body, setBody] = useState<RichTextValue>(() => ({
|
|
612
|
-
...freshDocument(signature.plainText, seed),
|
|
613
|
-
formatting: [],
|
|
614
|
-
}));
|
|
615
|
-
const [insertedVersion, setInsertedVersion] = useState(
|
|
616
|
-
() => insertion?.version ?? 0,
|
|
617
|
-
);
|
|
618
|
-
const pendingInsertion =
|
|
619
|
-
insertion &&
|
|
620
|
-
insertion.version > insertedVersion &&
|
|
621
|
-
(outboxMessageId === undefined || draftLoaded)
|
|
622
|
-
? insertion
|
|
623
|
-
: undefined;
|
|
624
|
-
|
|
625
|
-
const { data: draftData, error: draftError } = useQuery({
|
|
626
|
-
...outboxDetailOperationsGetOutboxMessageOptions({
|
|
627
|
-
path: { outboxMessageId: outboxMessageId ?? "" },
|
|
628
|
-
}),
|
|
629
|
-
enabled: !!outboxMessageId && !draftLoaded,
|
|
630
|
-
meta: OUTBOX_ROW_META,
|
|
631
|
-
retry: (failureCount, error) => !isNotFound(error) && failureCount < 1,
|
|
632
|
-
});
|
|
633
|
-
|
|
634
|
-
// The draft id is a path segment, so Back after a send — or a restored tab —
|
|
635
|
-
// reopens the composer on a row the send already filed and deleted. There is
|
|
636
|
-
// no document left to reopen and nothing failed, so the surface closes the way
|
|
637
|
-
// it closes on Send. Only the 404 is read this way; a lapsed session still
|
|
638
|
-
// escalates.
|
|
639
|
-
useEffect(() => {
|
|
640
|
-
if (!isNotFound(draftError)) return;
|
|
641
|
-
onClose();
|
|
642
|
-
}, [draftError, onClose]);
|
|
643
|
-
|
|
644
|
-
useEffect(() => {
|
|
645
|
-
if (!draftData || draftLoaded) return;
|
|
646
|
-
|
|
647
|
-
setToAddresses(
|
|
648
|
-
draftData.toAddresses.map((email) => ({ email, displayName: undefined })),
|
|
649
|
-
);
|
|
650
|
-
if (draftData.ccAddresses && draftData.ccAddresses.length > 0) {
|
|
651
|
-
setCcAddresses(
|
|
652
|
-
draftData.ccAddresses.map((email) => ({
|
|
653
|
-
email,
|
|
654
|
-
displayName: undefined,
|
|
655
|
-
})),
|
|
656
|
-
);
|
|
657
|
-
setShowCc(true);
|
|
658
|
-
}
|
|
659
|
-
if (draftData.bccAddresses && draftData.bccAddresses.length > 0) {
|
|
660
|
-
setBccAddresses(
|
|
661
|
-
draftData.bccAddresses.map((email) => ({
|
|
662
|
-
email,
|
|
663
|
-
displayName: undefined,
|
|
664
|
-
})),
|
|
665
|
-
);
|
|
666
|
-
setShowBcc(true);
|
|
667
|
-
}
|
|
668
|
-
if (draftData.subject) setSubject(draftData.subject);
|
|
669
|
-
// A draft stores what would have been sent, so which surface it reopens in
|
|
670
|
-
// is read off that rather than a field of its own. A rich draft comes back
|
|
671
|
-
// from its HTML — reading its text into one paragraph, as this did, brought
|
|
672
|
-
// a formatted message back flattened.
|
|
673
|
-
// A rich draft carries its language in the `<div lang>` it was stored
|
|
674
|
-
// under; the editor reopens on what is inside that, so a reopened draft
|
|
675
|
-
// does not gain a second wrapper on its next autosave. A plain draft has
|
|
676
|
-
// no HTML to have carried one, and comes back on the account default.
|
|
677
|
-
const stored = unwrapLanguage(draftData.htmlBody ?? "");
|
|
678
|
-
const loadedHtml = stored.html;
|
|
679
|
-
const loadedText = draftData.textBody ?? "";
|
|
680
|
-
setBodyMode(modeOfDraft(draftData.htmlBody));
|
|
681
|
-
setDraftLanguage(stored.language ?? undefined);
|
|
682
|
-
setInitialHtml(loadedHtml);
|
|
683
|
-
setInitialText(loadedText);
|
|
684
|
-
setBody({ html: loadedHtml, text: loadedText, formatting: [] });
|
|
685
|
-
setDocumentGeneration((generation) => generation + 1);
|
|
686
|
-
setSelectedAccountId(draftData.accountId);
|
|
687
|
-
setDraftLoaded(true);
|
|
688
|
-
captureLoadedPayloadRef.current = true;
|
|
689
|
-
}, [draftData, draftLoaded]);
|
|
690
|
-
|
|
691
|
-
useEffect(() => {
|
|
692
|
-
if (!sourceMessage) return;
|
|
693
|
-
// A draft the reader came back to holds what they saved, so mounting over
|
|
694
|
-
// it seeds nothing — but a switch of mode over the same message asks for
|
|
695
|
-
// a different answer, and rewrites the fields for it (#796). A rewrite
|
|
696
|
-
// made before the account resolved is redone when its address arrives,
|
|
697
|
-
// which is what takes the reader back out of their own Cc (#819).
|
|
698
|
-
if (resumedDraftRef.current && seededModeRef.current === mode) {
|
|
699
|
-
const seeded = seededMyEmailRef.current;
|
|
700
|
-
if (!seeded || seeded.myEmail === account?.email) return;
|
|
701
|
-
}
|
|
702
|
-
seededModeRef.current = mode;
|
|
703
|
-
seededMyEmailRef.current = { myEmail: account?.email };
|
|
704
|
-
|
|
705
|
-
// The fields are being rewritten for a different answer, so what was typed
|
|
706
|
-
// into one and left there belongs to the answer being left behind. Without
|
|
707
|
-
// this the blur timer commits it into the new one 150 ms later.
|
|
708
|
-
clearPendingFields();
|
|
709
|
-
|
|
710
|
-
if (mode === "reply" || mode === "reply-all") {
|
|
711
|
-
const { to, cc } = getReplyAddresses(sourceMessage, mode, account?.email);
|
|
712
|
-
setToAddresses(to);
|
|
713
|
-
setCcAddresses(cc);
|
|
714
|
-
if (cc.length > 0) setShowCc(true);
|
|
715
|
-
setSubject(buildReplySubject(sourceMessage.envelope.subject));
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
// A forward is addressed to nobody, so it writes the address fields the
|
|
719
|
-
// way a reply writes them. Setting only the subject read as "keep what is
|
|
720
|
-
// already there", which sent the forward to the person being answered
|
|
721
|
-
// (#797).
|
|
722
|
-
if (mode === "forward") {
|
|
723
|
-
setToAddresses([]);
|
|
724
|
-
setCcAddresses([]);
|
|
725
|
-
setBccAddresses([]);
|
|
726
|
-
setSubject(buildForwardSubject(sourceMessage.envelope.subject));
|
|
727
|
-
}
|
|
728
|
-
}, [mode, sourceMessage, account?.email, clearPendingFields]);
|
|
729
|
-
|
|
730
|
-
// Quoted reply/forward content lives at the per-part `contentUrl` since
|
|
731
|
-
// #224 PR 3 — fetch it via the same hook MessageBody uses.
|
|
732
|
-
const isQuoting =
|
|
733
|
-
mode === "reply" || mode === "reply-all" || mode === "forward";
|
|
734
|
-
const {
|
|
735
|
-
data: sourceBody,
|
|
736
|
-
isLoading: quoteIsLoading,
|
|
737
|
-
isError: quoteFailed,
|
|
738
|
-
hasNoRenderablePart: sourceHasNoQuotableBody,
|
|
739
|
-
refetch: refetchQuote,
|
|
740
|
-
} = useMessageBodyContent({
|
|
741
|
-
messageId: sourceMessage?.message.messageId,
|
|
742
|
-
bodyParts: sourceMessage?.bodyParts,
|
|
743
|
-
enabled: isQuoting && !!sourceMessage,
|
|
744
|
-
});
|
|
745
|
-
|
|
746
|
-
const quoteMode: ComposeQuoteMode = mode === "forward" ? "forward" : "reply";
|
|
747
|
-
|
|
748
|
-
/**
|
|
749
|
-
* The message being answered has not arrived yet, so the quote's own fetch
|
|
750
|
-
* cannot have started — it picks its part out of what has not landed. A send
|
|
751
|
-
* pressed in this window went out carrying none of the original and was
|
|
752
|
-
* refused by nothing, because "no part picked" reads the same here as "this
|
|
753
|
-
* message has no part to pick" (#1030).
|
|
754
|
-
*/
|
|
755
|
-
const quoteSourceIsLoading = isQuoting && !sourceMessage;
|
|
756
|
-
|
|
757
|
-
/**
|
|
758
|
-
* The message being answered arrived carrying attachments and no text. A
|
|
759
|
-
* forward of it is refused: the composer sends a text body and an html body
|
|
760
|
-
* and no attachments, so the forward would arrive holding nothing of the
|
|
761
|
-
* original at all. A reply goes out — it carries the answer and the thread's
|
|
762
|
-
* references either way — and says the original is not quoted in it.
|
|
763
|
-
*
|
|
764
|
-
* Not stated for a resumed draft, whose body already holds whatever quote it
|
|
765
|
-
* was saved with; this composer is not the one that assembles it.
|
|
766
|
-
*/
|
|
767
|
-
const quoteHasNoBody =
|
|
768
|
-
isQuoting && !documentHoldsQuote && sourceHasNoQuotableBody;
|
|
769
|
-
const nothingToForward = quoteHasNoBody && quoteMode === "forward";
|
|
770
|
-
|
|
771
|
-
/**
|
|
772
|
-
* The original as it will be sent, and as it is shown while the answer is
|
|
773
|
-
* written — one value for both, because the two disagreeing is the whole of
|
|
774
|
-
* #845.5.
|
|
775
|
-
*
|
|
776
|
-
* Absent for a draft read back from the server: that document was saved with
|
|
777
|
-
* the quote already in it, so the editor holds it and appending a second copy
|
|
778
|
-
* would send the original twice.
|
|
779
|
-
*/
|
|
780
|
-
const quotedBlock = useMemo<QuotedBlock | undefined>(() => {
|
|
781
|
-
if (!isQuoting || !sourceMessage || documentHoldsQuote) return undefined;
|
|
782
|
-
if (!sourceBody) return undefined;
|
|
783
|
-
const body: QuotedSourceBody =
|
|
784
|
-
sourceBody.kind === "html"
|
|
785
|
-
? { kind: "html", content: sanitizeQuotedHtml(sourceBody.body) }
|
|
786
|
-
: { kind: "text", content: sourceBody.body };
|
|
787
|
-
return buildQuotedBlock(
|
|
788
|
-
mode === "forward" ? "forward" : "reply",
|
|
789
|
-
sourceMessage.envelope,
|
|
790
|
-
body,
|
|
791
|
-
);
|
|
792
|
-
}, [isQuoting, sourceMessage, documentHoldsQuote, sourceBody, mode]);
|
|
793
|
-
|
|
794
|
-
const senderName =
|
|
795
|
-
sourceMessage?.envelope.from[0]?.displayName ??
|
|
796
|
-
sourceMessage?.envelope.from[0]?.normalizedEmail;
|
|
797
|
-
|
|
798
|
-
// The draft this session just created holds what is already on screen, so
|
|
799
|
-
// there is nothing to read back — and reading it back would replace the
|
|
800
|
-
// document under the caret with the server's copy of it.
|
|
801
|
-
const adoptCreatedDraft = useCallback(
|
|
802
|
-
(createdId: string) => {
|
|
803
|
-
setDraftLoaded(true);
|
|
804
|
-
// What is on screen is what was just written, so the fields belong to
|
|
805
|
-
// the new draft the moment it exists — before the id has travelled out
|
|
806
|
-
// through the address and back. Waiting for that would hold the next
|
|
807
|
-
// autosave, and the last thing typed before a pause would not be saved.
|
|
808
|
-
setOpenDocumentId(createdId);
|
|
809
|
-
onDraftCreated(createdId);
|
|
810
|
-
},
|
|
811
|
-
[onDraftCreated],
|
|
812
|
-
);
|
|
813
|
-
|
|
814
|
-
const { saveState, saveError, saveDraft, saveImmediately, stopAutoSave } =
|
|
815
|
-
useSaveDraft({
|
|
816
|
-
outboxMessageId,
|
|
817
|
-
onDraftCreated: adoptCreatedDraft,
|
|
818
|
-
});
|
|
819
|
-
|
|
820
|
-
const ensureDraftForAttachment =
|
|
821
|
-
useCallback(async (): Promise<DraftForAttachment> => {
|
|
822
|
-
if (outboxMessageId) return { outcome: "ready", outboxMessageId };
|
|
823
|
-
if (!selectedAccountId) {
|
|
824
|
-
return {
|
|
825
|
-
outcome: "refused",
|
|
826
|
-
reason: "Choose an account to send from before attaching a file.",
|
|
827
|
-
};
|
|
828
|
-
}
|
|
829
|
-
if (toAddresses.length === 0) {
|
|
830
|
-
return { outcome: "refused", reason: ATTACH_NEEDS_TO_ADDRESS };
|
|
831
|
-
}
|
|
832
|
-
const { htmlBody, textBody } = outgoingBody(
|
|
833
|
-
bodyMode,
|
|
834
|
-
body,
|
|
835
|
-
composeLanguage,
|
|
836
|
-
quotedBlock,
|
|
837
|
-
);
|
|
838
|
-
const saved = await saveImmediately({
|
|
839
|
-
accountId: selectedAccountId,
|
|
840
|
-
toAddresses: toAddresses.map((a) => a.email),
|
|
841
|
-
ccAddresses:
|
|
842
|
-
ccAddresses.length > 0 ? ccAddresses.map((a) => a.email) : undefined,
|
|
843
|
-
bccAddresses:
|
|
844
|
-
bccAddresses.length > 0
|
|
845
|
-
? bccAddresses.map((a) => a.email)
|
|
846
|
-
: undefined,
|
|
847
|
-
subject: subject || undefined,
|
|
848
|
-
textBody,
|
|
849
|
-
htmlBody,
|
|
850
|
-
...(sourceMessage && (mode === "reply" || mode === "reply-all")
|
|
851
|
-
? getReferences(sourceMessage)
|
|
852
|
-
: {}),
|
|
853
|
-
});
|
|
854
|
-
if (saved.outcome === "failed") {
|
|
855
|
-
return {
|
|
856
|
-
outcome: "refused",
|
|
857
|
-
reason: `The draft could not be saved, so the file was not attached: ${formatErrorDetail(saved.error) ?? "the request failed"}.`,
|
|
858
|
-
};
|
|
859
|
-
}
|
|
860
|
-
return { outcome: "ready", outboxMessageId: saved.outboxMessageId };
|
|
861
|
-
}, [
|
|
862
|
-
outboxMessageId,
|
|
863
|
-
selectedAccountId,
|
|
864
|
-
toAddresses,
|
|
865
|
-
ccAddresses,
|
|
866
|
-
bccAddresses,
|
|
867
|
-
subject,
|
|
868
|
-
body,
|
|
869
|
-
bodyMode,
|
|
870
|
-
composeLanguage,
|
|
871
|
-
quotedBlock,
|
|
872
|
-
sourceMessage,
|
|
873
|
-
mode,
|
|
874
|
-
saveImmediately,
|
|
875
|
-
]);
|
|
876
|
-
|
|
877
|
-
const {
|
|
878
|
-
items: attachmentItems,
|
|
879
|
-
attach,
|
|
880
|
-
retry: retryAttachment,
|
|
881
|
-
remove: removeAttachment,
|
|
882
|
-
load: loadAttachments,
|
|
883
|
-
reset: resetAttachments,
|
|
884
|
-
owns: ownsAttachment,
|
|
885
|
-
isLoaded: attachmentsLoaded,
|
|
886
|
-
refreshLinks: refreshAttachmentLinks,
|
|
887
|
-
storedContent,
|
|
888
|
-
onRemoved: onAttachmentRemoved,
|
|
889
|
-
blockingReason: attachmentBlockingReason,
|
|
890
|
-
} = useComposeAttachments({
|
|
891
|
-
ensureDraft: ensureDraftForAttachment,
|
|
892
|
-
});
|
|
893
|
-
|
|
894
|
-
const queryClient = useQueryClient();
|
|
895
|
-
const inlineImages = useInlineImages({
|
|
896
|
-
attach,
|
|
897
|
-
owns: ownsAttachment,
|
|
898
|
-
isLoaded: attachmentsLoaded,
|
|
899
|
-
storedContent,
|
|
900
|
-
refreshLinks: () => {
|
|
901
|
-
if (!outboxMessageId) return Promise.resolve();
|
|
902
|
-
return queryClient
|
|
903
|
-
.fetchQuery({
|
|
904
|
-
...outboxDetailOperationsGetOutboxMessageOptions({
|
|
905
|
-
path: { outboxMessageId },
|
|
906
|
-
}),
|
|
907
|
-
staleTime: 0,
|
|
908
|
-
})
|
|
909
|
-
.then((draft) => refreshAttachmentLinks(draft.attachments));
|
|
910
|
-
},
|
|
911
|
-
onRemoved: onAttachmentRemoved,
|
|
912
|
-
draftAttachments:
|
|
913
|
-
draftData && draftData.outboxMessageId === outboxMessageId
|
|
914
|
-
? draftData.attachments
|
|
915
|
-
: [],
|
|
916
|
-
pushError,
|
|
917
|
-
});
|
|
918
|
-
|
|
919
|
-
const attachmentDocumentRef = useRef(outboxMessageId);
|
|
920
|
-
useEffect(() => {
|
|
921
|
-
const previous = attachmentDocumentRef.current;
|
|
922
|
-
if (previous === outboxMessageId) return;
|
|
923
|
-
attachmentDocumentRef.current = outboxMessageId;
|
|
924
|
-
if (previous === undefined) return;
|
|
925
|
-
resetAttachments(outboxMessageId);
|
|
926
|
-
}, [outboxMessageId, resetAttachments]);
|
|
927
|
-
|
|
928
|
-
const attachmentsLoadedForRef = useRef<string | undefined>(undefined);
|
|
929
|
-
useEffect(() => {
|
|
930
|
-
if (!draftData || draftData.outboxMessageId !== outboxMessageId) return;
|
|
931
|
-
if (attachmentsLoadedForRef.current === draftData.outboxMessageId) return;
|
|
932
|
-
attachmentsLoadedForRef.current = draftData.outboxMessageId;
|
|
933
|
-
loadAttachments(draftData.outboxMessageId, draftData.attachments);
|
|
934
|
-
}, [draftData, outboxMessageId, loadAttachments]);
|
|
935
|
-
|
|
936
|
-
// Auto-save runs on a debounce, so a failure has no inline call site to
|
|
937
|
-
// surface it. Push the real error detail to a banner instead of leaving only
|
|
938
|
-
// the muted "Save failed" status dot. A fatal 5xx also hits the global
|
|
939
|
-
// escalation overlay via MutationCache.onError.
|
|
940
|
-
useEffect(() => {
|
|
941
|
-
if (!saveError) return;
|
|
942
|
-
pushError({
|
|
943
|
-
title: "Couldn't save draft",
|
|
944
|
-
detail: formatErrorDetail(saveError) ?? "Saving the draft failed.",
|
|
945
|
-
error: saveError,
|
|
946
|
-
});
|
|
947
|
-
}, [saveError, pushError]);
|
|
948
|
-
|
|
949
|
-
// A refused send is reported below, next to the message it did not send, and
|
|
950
|
-
// the composer stays up so the user can fix the address and press it again.
|
|
951
|
-
// A 5xx still escalates.
|
|
952
|
-
const sendMutation = useMutation({
|
|
953
|
-
...outboxDetailOperationsSendOutboxMessageMutation(),
|
|
954
|
-
meta: softErrorMeta,
|
|
955
|
-
});
|
|
956
|
-
|
|
957
|
-
const deleteMutation = useMutation({
|
|
958
|
-
...outboxDetailOperationsDeleteOutboxMessageMutation(),
|
|
959
|
-
meta: softErrorMeta,
|
|
960
|
-
onError: (error) => {
|
|
961
|
-
// Discard closes the dialog optimistically. A soft 4xx (409/404 the
|
|
962
|
-
// draft is already gone) must not pass silently as success — surface a
|
|
963
|
-
// banner. A fatal 5xx still escalates through MutationCache.onError.
|
|
964
|
-
pushError(
|
|
965
|
-
buildMutationErrorBanner(
|
|
966
|
-
"Couldn't discard draft",
|
|
967
|
-
"The draft wasn't discarded.",
|
|
968
|
-
error,
|
|
969
|
-
),
|
|
970
|
-
);
|
|
971
|
-
},
|
|
972
|
-
});
|
|
973
|
-
|
|
974
|
-
const { data: config } = useQuery({
|
|
975
|
-
...configOperationsGetConfigOptions(),
|
|
976
|
-
staleTime: Infinity,
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
const selectedAccount = config?.accounts.find(
|
|
980
|
-
(a) => a.accountId === selectedAccountId,
|
|
981
|
-
);
|
|
982
|
-
const selectedAccountMissingSmtp = selectedAccount
|
|
983
|
-
? accountIsMissingSmtp(selectedAccount)
|
|
984
|
-
: false;
|
|
985
|
-
const [mailOffRefusal, setMailOffRefusal] = useState<
|
|
986
|
-
{ accountId: string; reason: string } | undefined
|
|
987
|
-
>();
|
|
988
|
-
const selectedAccountMailOffReason =
|
|
989
|
-
mailOffRefusal && mailOffRefusal.accountId === selectedAccountId
|
|
990
|
-
? mailOffRefusal.reason
|
|
991
|
-
: undefined;
|
|
992
|
-
|
|
993
|
-
// An account that has never been to the language setting falls back to what
|
|
994
|
-
// the browser already knows the user reads, which is an ordered answer.
|
|
995
|
-
const configured = selectedAccount?.composeLanguages;
|
|
996
|
-
const accountLanguages = useMemo(
|
|
997
|
-
() =>
|
|
998
|
-
configured && configured.length > 0
|
|
999
|
-
? configured
|
|
1000
|
-
: defaultComposeLanguages(navigator.languages),
|
|
1001
|
-
[configured],
|
|
1002
|
-
);
|
|
1003
|
-
|
|
1004
|
-
// The editor reopens the checker whenever the composer's language changes,
|
|
1005
|
-
// so the tag the chip and detection settle on is the only one it is ever
|
|
1006
|
-
// asked for.
|
|
1007
|
-
const spellcheck = useMemo(() => composeSpellcheck(pushError), [pushError]);
|
|
1008
|
-
|
|
1009
|
-
// The action bar refuses a second press while one is in flight, but the
|
|
1010
|
-
// editor's own Cmd+Enter goes straight to `attemptSend`, and the write that
|
|
1011
|
-
// now precedes the request widens the window a second press lands in.
|
|
1012
|
-
const sendInFlightRef = useRef(false);
|
|
1013
|
-
const [isSending, setIsSending] = useState(false);
|
|
1014
|
-
// Every refusal carries the sentence that explains it. Send is never a
|
|
1015
|
-
// no-op: the state it reads has no way to be blocked without a reason. A
|
|
1016
|
-
// ready state carries the account the message goes out from, so the send
|
|
1017
|
-
// path has no condition of its own left to refuse on in silence.
|
|
1018
|
-
const readinessFor = useCallback(
|
|
1019
|
-
(toCount: number, unparsed: UnparsedField | undefined): SendReadiness => {
|
|
1020
|
-
if (isSending) return { status: "sending" };
|
|
1021
|
-
if (!selectedAccountId) {
|
|
1022
|
-
return { status: "blocked", reason: "Choose an account to send from." };
|
|
1023
|
-
}
|
|
1024
|
-
if (selectedAccountMailOffReason) {
|
|
1025
|
-
return { status: "blocked", reason: selectedAccountMailOffReason };
|
|
1026
|
-
}
|
|
1027
|
-
if (selectedAccountMissingSmtp) {
|
|
1028
|
-
return { status: "blocked", reason: SMTP_MISSING_MESSAGE };
|
|
1029
|
-
}
|
|
1030
|
-
if (quoteIsLoading || quoteSourceIsLoading) {
|
|
1031
|
-
return { status: "blocked", reason: QUOTE_LOADING_MESSAGE };
|
|
1032
|
-
}
|
|
1033
|
-
if (attachmentBlockingReason) {
|
|
1034
|
-
return { status: "blocked", reason: attachmentBlockingReason };
|
|
1035
|
-
}
|
|
1036
|
-
if (unparsed) {
|
|
1037
|
-
return { status: "blocked", reason: unparsedRefusal(unparsed) };
|
|
1038
|
-
}
|
|
1039
|
-
if (toCount === 0) {
|
|
1040
|
-
return { status: "blocked", reason: NO_TO_ADDRESS_MESSAGE };
|
|
1041
|
-
}
|
|
1042
|
-
// Last of the refusals: the others name something the writer can go and
|
|
1043
|
-
// fix, and this one names something about the message being forwarded
|
|
1044
|
-
// that they cannot. The banner above states it the whole time either
|
|
1045
|
-
// way, so the press is better spent on the fixable thing.
|
|
1046
|
-
if (nothingToForward) {
|
|
1047
|
-
return {
|
|
1048
|
-
status: "blocked",
|
|
1049
|
-
reason: NO_QUOTABLE_BODY_FORWARD_MESSAGE,
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
return { status: "ready", accountId: selectedAccountId };
|
|
1053
|
-
},
|
|
1054
|
-
[
|
|
1055
|
-
isSending,
|
|
1056
|
-
selectedAccountId,
|
|
1057
|
-
selectedAccountMailOffReason,
|
|
1058
|
-
selectedAccountMissingSmtp,
|
|
1059
|
-
quoteIsLoading,
|
|
1060
|
-
quoteSourceIsLoading,
|
|
1061
|
-
attachmentBlockingReason,
|
|
1062
|
-
nothingToForward,
|
|
1063
|
-
],
|
|
1064
|
-
);
|
|
1065
|
-
const sendReadiness = useMemo<SendReadiness>(
|
|
1066
|
-
() =>
|
|
1067
|
-
readinessFor(
|
|
1068
|
-
toAddresses.length + pendingTo.entries.length,
|
|
1069
|
-
firstUnparsed([{ label: "To", text: pendingTo.unparsed }]),
|
|
1070
|
-
),
|
|
1071
|
-
[readinessFor, toAddresses.length, pendingTo],
|
|
1072
|
-
);
|
|
1073
|
-
const sendState: ComposeSendState = sendReadiness;
|
|
1074
|
-
|
|
1075
|
-
useEffect(() => {
|
|
1076
|
-
if (!selectedAccountId) return;
|
|
1077
|
-
// Nor one that is on its way out. Send commits the address fields as it
|
|
1078
|
-
// goes, which lands here as a recipient change and would re-arm the timer
|
|
1079
|
-
// `stopAutoSave` has just dropped — a draft write arriving after the send
|
|
1080
|
-
// took the row out of draft (#845.6).
|
|
1081
|
-
if (sendInFlightRef.current) return;
|
|
1082
|
-
// Don't autosave a document the fields are no longer on. They trail the
|
|
1083
|
-
// address by a commit whenever it changes, so writing here sends the
|
|
1084
|
-
// message just left to whatever the address now names — the previous
|
|
1085
|
-
// draft's content onto the next draft, or, with no draft named at all, a
|
|
1086
|
-
// spurious second one holding it (#535/#536).
|
|
1087
|
-
if (openDocumentId !== undefined && openDocumentId !== outboxMessageId)
|
|
1088
|
-
return;
|
|
1089
|
-
// Nor one still arriving: opening an existing draft leaves the fields
|
|
1090
|
-
// mid-population until the read lands.
|
|
1091
|
-
if (outboxMessageId && !draftLoaded) return;
|
|
1092
|
-
if (isFormEmpty(toAddresses, ccAddresses, bccAddresses, subject, body))
|
|
1093
|
-
return;
|
|
1094
|
-
|
|
1095
|
-
const { htmlBody, textBody } = outgoingBody(
|
|
1096
|
-
bodyMode,
|
|
1097
|
-
body,
|
|
1098
|
-
composeLanguage,
|
|
1099
|
-
quotedBlock,
|
|
1100
|
-
);
|
|
1101
|
-
|
|
1102
|
-
const payload = {
|
|
1103
|
-
accountId: selectedAccountId,
|
|
1104
|
-
toAddresses: toAddresses.map((a) => a.email),
|
|
1105
|
-
ccAddresses:
|
|
1106
|
-
ccAddresses.length > 0 ? ccAddresses.map((a) => a.email) : undefined,
|
|
1107
|
-
bccAddresses:
|
|
1108
|
-
bccAddresses.length > 0 ? bccAddresses.map((a) => a.email) : undefined,
|
|
1109
|
-
subject: subject || undefined,
|
|
1110
|
-
textBody,
|
|
1111
|
-
htmlBody,
|
|
1112
|
-
};
|
|
1113
|
-
|
|
1114
|
-
// Nor a document nobody has touched. Reopening one is not editing it, and
|
|
1115
|
-
// a PATCH is now a status change as well as a content one (#933).
|
|
1116
|
-
const fingerprint = JSON.stringify(payload);
|
|
1117
|
-
if (captureLoadedPayloadRef.current) {
|
|
1118
|
-
captureLoadedPayloadRef.current = false;
|
|
1119
|
-
loadedPayloadRef.current = fingerprint;
|
|
1120
|
-
return;
|
|
1121
|
-
}
|
|
1122
|
-
if (loadedPayloadRef.current === fingerprint) return;
|
|
1123
|
-
loadedPayloadRef.current = undefined;
|
|
1124
|
-
|
|
1125
|
-
saveDraft(payload);
|
|
1126
|
-
}, [
|
|
1127
|
-
selectedAccountId,
|
|
1128
|
-
outboxMessageId,
|
|
1129
|
-
openDocumentId,
|
|
1130
|
-
draftLoaded,
|
|
1131
|
-
toAddresses,
|
|
1132
|
-
ccAddresses,
|
|
1133
|
-
bccAddresses,
|
|
1134
|
-
subject,
|
|
1135
|
-
body,
|
|
1136
|
-
bodyMode,
|
|
1137
|
-
composeLanguage,
|
|
1138
|
-
quotedBlock,
|
|
1139
|
-
saveDraft,
|
|
1140
|
-
]);
|
|
1141
|
-
|
|
1142
|
-
const handleSend = useCallback(
|
|
1143
|
-
async (accountId: string, recipients: Recipients) => {
|
|
1144
|
-
if (sendInFlightRef.current) return;
|
|
1145
|
-
|
|
1146
|
-
sendInFlightRef.current = true;
|
|
1147
|
-
setIsSending(true);
|
|
1148
|
-
try {
|
|
1149
|
-
stopAutoSave();
|
|
1150
|
-
|
|
1151
|
-
const replyData =
|
|
1152
|
-
sourceMessage && (mode === "reply" || mode === "reply-all")
|
|
1153
|
-
? getReferences(sourceMessage)
|
|
1154
|
-
: {};
|
|
1155
|
-
|
|
1156
|
-
const { htmlBody, textBody } = outgoingBody(
|
|
1157
|
-
bodyMode,
|
|
1158
|
-
body,
|
|
1159
|
-
composeLanguage,
|
|
1160
|
-
quotedBlock,
|
|
1161
|
-
);
|
|
1162
|
-
const createdThisAttempt = !outboxMessageId;
|
|
1163
|
-
|
|
1164
|
-
// The debounce dropped above may have been holding the last two seconds
|
|
1165
|
-
// of typing, and an existing entry would otherwise go out as the server
|
|
1166
|
-
// last saw it (#674). What is on screen is written first, and a write
|
|
1167
|
-
// that fails stops the send rather than transmitting the older copy.
|
|
1168
|
-
const flushed = await saveImmediately({
|
|
1169
|
-
accountId,
|
|
1170
|
-
toAddresses: recipients.to.map((a) => a.email),
|
|
1171
|
-
ccAddresses:
|
|
1172
|
-
recipients.cc.length > 0
|
|
1173
|
-
? recipients.cc.map((a) => a.email)
|
|
1174
|
-
: undefined,
|
|
1175
|
-
bccAddresses:
|
|
1176
|
-
recipients.bcc.length > 0
|
|
1177
|
-
? recipients.bcc.map((a) => a.email)
|
|
1178
|
-
: undefined,
|
|
1179
|
-
subject: subject || undefined,
|
|
1180
|
-
textBody,
|
|
1181
|
-
htmlBody,
|
|
1182
|
-
...replyData,
|
|
1183
|
-
});
|
|
1184
|
-
|
|
1185
|
-
if (flushed.outcome === "failed") {
|
|
1186
|
-
pushError({
|
|
1187
|
-
title: "Couldn't send message",
|
|
1188
|
-
detail:
|
|
1189
|
-
formatErrorDetail(flushed.error) ??
|
|
1190
|
-
"Saving the message failed, so nothing was sent. Try again.",
|
|
1191
|
-
error: flushed.error,
|
|
1192
|
-
});
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
const messageId = flushed.outboxMessageId;
|
|
1197
|
-
|
|
1198
|
-
const sent = await sendMutation
|
|
1199
|
-
.mutateAsync({
|
|
1200
|
-
path: { outboxMessageId: messageId },
|
|
1201
|
-
})
|
|
1202
|
-
.catch((error: unknown) => {
|
|
1203
|
-
const reason = mailSyncOffReason(error);
|
|
1204
|
-
if (reason) setMailOffRefusal({ accountId, reason });
|
|
1205
|
-
pushError({
|
|
1206
|
-
title: "Couldn't send message",
|
|
1207
|
-
detail:
|
|
1208
|
-
formatErrorDetail(error) ??
|
|
1209
|
-
(createdThisAttempt
|
|
1210
|
-
? "The draft was saved but the send request failed. Try again from the Outbox."
|
|
1211
|
-
: "The send request failed. Try again."),
|
|
1212
|
-
error,
|
|
1213
|
-
});
|
|
1214
|
-
return null;
|
|
1215
|
-
});
|
|
1216
|
-
if (sent === null) return;
|
|
1217
|
-
|
|
1218
|
-
stopAutoSave(messageId);
|
|
1219
|
-
startSendPolling(messageId);
|
|
1220
|
-
onClose();
|
|
1221
|
-
} finally {
|
|
1222
|
-
sendInFlightRef.current = false;
|
|
1223
|
-
setIsSending(false);
|
|
1224
|
-
}
|
|
1225
|
-
},
|
|
1226
|
-
[
|
|
1227
|
-
subject,
|
|
1228
|
-
body,
|
|
1229
|
-
bodyMode,
|
|
1230
|
-
composeLanguage,
|
|
1231
|
-
quotedBlock,
|
|
1232
|
-
mode,
|
|
1233
|
-
sourceMessage,
|
|
1234
|
-
outboxMessageId,
|
|
1235
|
-
saveImmediately,
|
|
1236
|
-
sendMutation,
|
|
1237
|
-
stopAutoSave,
|
|
1238
|
-
startSendPolling,
|
|
1239
|
-
pushError,
|
|
1240
|
-
onClose,
|
|
1241
|
-
],
|
|
1242
|
-
);
|
|
1243
|
-
|
|
1244
|
-
const handleDiscard = useCallback(() => {
|
|
1245
|
-
stopAutoSave(outboxMessageId);
|
|
1246
|
-
if (outboxMessageId) {
|
|
1247
|
-
deleteMutation.mutate({
|
|
1248
|
-
path: { outboxMessageId },
|
|
1249
|
-
});
|
|
1250
|
-
}
|
|
1251
|
-
onClose();
|
|
1252
|
-
}, [stopAutoSave, outboxMessageId, deleteMutation, onClose]);
|
|
1253
|
-
|
|
1254
|
-
// The refusal is announced first and moved to second. Focus alone carried
|
|
1255
|
-
// nothing to a screen reader — the banner above was already on screen, so
|
|
1256
|
-
// the press read as the button doing nothing.
|
|
1257
|
-
const reportBlocked = useCallback(
|
|
1258
|
-
(reason: string) => {
|
|
1259
|
-
pushError({ title: "Can't send yet", detail: reason });
|
|
1260
|
-
if (reason !== SMTP_MISSING_MESSAGE) return;
|
|
1261
|
-
smtpConfigureRef.current?.focus();
|
|
1262
|
-
},
|
|
1263
|
-
[pushError],
|
|
1264
|
-
);
|
|
1265
|
-
|
|
1266
|
-
/**
|
|
1267
|
-
* Send goes out to the addresses on screen, not to the ones the fields have
|
|
1268
|
-
* got round to committing. Each field commits on blur behind a timer, and the
|
|
1269
|
-
* press that sends is the press that blurs — so a recipient typed and left in
|
|
1270
|
-
* the field is taken here, in the same tick, before the message is judged to
|
|
1271
|
-
* have anywhere to go (#845.6).
|
|
1272
|
-
*/
|
|
1273
|
-
const attemptSend = useCallback(() => {
|
|
1274
|
-
if (sendReadiness.status === "sending") return;
|
|
1275
|
-
|
|
1276
|
-
const to = fieldHandles.to.current?.commitPending();
|
|
1277
|
-
const cc = fieldHandles.cc.current?.commitPending();
|
|
1278
|
-
const bcc = fieldHandles.bcc.current?.commitPending();
|
|
1279
|
-
const recipients: Recipients = {
|
|
1280
|
-
to: to?.addresses ?? toAddresses,
|
|
1281
|
-
cc: cc?.addresses ?? ccAddresses,
|
|
1282
|
-
bcc: bcc?.addresses ?? bccAddresses,
|
|
1283
|
-
};
|
|
1284
|
-
|
|
1285
|
-
const readiness = readinessFor(
|
|
1286
|
-
recipients.to.length,
|
|
1287
|
-
firstUnparsed([
|
|
1288
|
-
{ label: "To", text: to?.unparsed ?? "" },
|
|
1289
|
-
{ label: "Cc", text: cc?.unparsed ?? "" },
|
|
1290
|
-
{ label: "Bcc", text: bcc?.unparsed ?? "" },
|
|
1291
|
-
]),
|
|
1292
|
-
);
|
|
1293
|
-
if (readiness.status === "sending") return;
|
|
1294
|
-
if (readiness.status === "blocked") {
|
|
1295
|
-
reportBlocked(readiness.reason);
|
|
1296
|
-
return;
|
|
1297
|
-
}
|
|
1298
|
-
void handleSend(readiness.accountId, recipients);
|
|
1299
|
-
}, [
|
|
1300
|
-
sendReadiness.status,
|
|
1301
|
-
fieldHandles,
|
|
1302
|
-
toAddresses,
|
|
1303
|
-
ccAddresses,
|
|
1304
|
-
bccAddresses,
|
|
1305
|
-
readinessFor,
|
|
1306
|
-
reportBlocked,
|
|
1307
|
-
handleSend,
|
|
1308
|
-
]);
|
|
1309
|
-
|
|
1310
|
-
const handleAccountChange = useCallback(
|
|
1311
|
-
(acct: RemitImapAccountResponse) => {
|
|
1312
|
-
setSelectedAccountId(acct.accountId);
|
|
1313
|
-
onAccountChange?.(acct);
|
|
1314
|
-
},
|
|
1315
|
-
[onAccountChange],
|
|
1316
|
-
);
|
|
1317
|
-
|
|
1318
|
-
return (
|
|
1319
|
-
<ComposeFormShell
|
|
1320
|
-
layout={layout}
|
|
1321
|
-
onDropFiles={(files) => {
|
|
1322
|
-
void attach(files);
|
|
1323
|
-
}}
|
|
1324
|
-
banner={
|
|
1325
|
-
<>
|
|
1326
|
-
{selectedAccount && selectedAccountMissingSmtp ? (
|
|
1327
|
-
<ComposeSmtpMissingBanner
|
|
1328
|
-
accountId={selectedAccount.accountId}
|
|
1329
|
-
configureRef={smtpConfigureRef}
|
|
1330
|
-
/>
|
|
1331
|
-
) : null}
|
|
1332
|
-
{quoteHasNoBody ? (
|
|
1333
|
-
<ComposeQuoteMissingBanner mode={quoteMode} />
|
|
1334
|
-
) : null}
|
|
1335
|
-
{quoteFailed ? (
|
|
1336
|
-
<Banner tone="warning" data-testid="compose-quote-failed">
|
|
1337
|
-
<span>{QUOTE_FAILED_MESSAGE}</span>{" "}
|
|
1338
|
-
<button
|
|
1339
|
-
type="button"
|
|
1340
|
-
className="underline"
|
|
1341
|
-
onClick={() => {
|
|
1342
|
-
void refetchQuote();
|
|
1343
|
-
}}
|
|
1344
|
-
>
|
|
1345
|
-
Try again
|
|
1346
|
-
</button>
|
|
1347
|
-
</Banner>
|
|
1348
|
-
) : null}
|
|
1349
|
-
</>
|
|
1350
|
-
}
|
|
1351
|
-
header={
|
|
1352
|
-
<WiredComposeHeader
|
|
1353
|
-
documentGeneration={documentGeneration}
|
|
1354
|
-
selectedAccountId={selectedAccountId}
|
|
1355
|
-
onAccountChange={handleAccountChange}
|
|
1356
|
-
toAddresses={toAddresses}
|
|
1357
|
-
setToAddresses={setToAddresses}
|
|
1358
|
-
ccAddresses={ccAddresses}
|
|
1359
|
-
setCcAddresses={setCcAddresses}
|
|
1360
|
-
bccAddresses={bccAddresses}
|
|
1361
|
-
setBccAddresses={setBccAddresses}
|
|
1362
|
-
showCc={showCc}
|
|
1363
|
-
setShowCc={setShowCc}
|
|
1364
|
-
showBcc={showBcc}
|
|
1365
|
-
setShowBcc={setShowBcc}
|
|
1366
|
-
subject={subject}
|
|
1367
|
-
setSubject={setSubject}
|
|
1368
|
-
fieldHandles={fieldHandles}
|
|
1369
|
-
onToPendingChange={setPendingTo}
|
|
1370
|
-
/>
|
|
1371
|
-
}
|
|
1372
|
-
quoted={
|
|
1373
|
-
quotedBlock ? (
|
|
1374
|
-
<QuotedText
|
|
1375
|
-
text={quotedBlock.text}
|
|
1376
|
-
html={quotedBlock.html}
|
|
1377
|
-
senderName={senderName}
|
|
1378
|
-
/>
|
|
1379
|
-
) : undefined
|
|
1380
|
-
}
|
|
1381
|
-
attachments={
|
|
1382
|
-
<ComposeAttachments
|
|
1383
|
-
items={attachmentItems}
|
|
1384
|
-
onRemove={(key) => {
|
|
1385
|
-
void removeAttachment(key);
|
|
1386
|
-
}}
|
|
1387
|
-
onRetry={(key) => {
|
|
1388
|
-
void retryAttachment(key);
|
|
1389
|
-
}}
|
|
1390
|
-
/>
|
|
1391
|
-
}
|
|
1392
|
-
actionBar={
|
|
1393
|
-
<ComposeActionBar
|
|
1394
|
-
send={sendState}
|
|
1395
|
-
onSend={attemptSend}
|
|
1396
|
-
onBlocked={reportBlocked}
|
|
1397
|
-
onDiscard={handleDiscard}
|
|
1398
|
-
save={saveState}
|
|
1399
|
-
onAttach={(files) => {
|
|
1400
|
-
void attach(files);
|
|
1401
|
-
}}
|
|
1402
|
-
/>
|
|
1403
|
-
}
|
|
1404
|
-
>
|
|
1405
|
-
<Suspense fallback={<ComposeBodySkeleton />}>
|
|
1406
|
-
<LazyComposeBody
|
|
1407
|
-
key={documentGeneration}
|
|
1408
|
-
mode={bodyMode}
|
|
1409
|
-
onModeChange={setBodyMode}
|
|
1410
|
-
initialHtml={initialHtml}
|
|
1411
|
-
initialText={initialText}
|
|
1412
|
-
onChange={setBody}
|
|
1413
|
-
onSubmit={attemptSend}
|
|
1414
|
-
initialCaret={mode === "new" ? "start" : undefined}
|
|
1415
|
-
onConversionError={pushError}
|
|
1416
|
-
languages={accountLanguages}
|
|
1417
|
-
initialLanguage={draftLanguage}
|
|
1418
|
-
onLanguageChange={setComposeLanguage}
|
|
1419
|
-
spellcheck={spellcheck}
|
|
1420
|
-
insertion={pendingInsertion}
|
|
1421
|
-
onInserted={setInsertedVersion}
|
|
1422
|
-
inlineImages={inlineImages}
|
|
1423
|
-
/>
|
|
1424
|
-
</Suspense>
|
|
1425
|
-
</ComposeFormShell>
|
|
1426
|
-
);
|
|
1427
|
-
};
|