@rapidmx/web-client 0.9.0 → 0.11.0
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/README.md +373 -88
- package/apps/admin/_layout.tsx +8 -2
- package/apps/admin/index.tsx +7 -1
- package/apps/admin/ingest-queue/index.tsx +2 -1
- package/apps/admin/mailboxes/[uid].tsx +23 -10
- package/apps/admin/quarantine/index.tsx +2 -1
- package/apps/admin/signing-certificates/index.tsx +343 -0
- package/apps/escrow/_layout.tsx +8 -2
- package/apps/shared/appearance/AppearanceForm.tsx +392 -0
- package/apps/shared/appearance/AppearanceHead.tsx +49 -0
- package/apps/shared/appearance/AppearanceProvider.tsx +470 -0
- package/apps/shared/appearance/ColorField.tsx +107 -0
- package/apps/shared/appearance/appearanceCache.ts +106 -0
- package/apps/shared/appearance/appearanceContext.ts +77 -0
- package/apps/shared/appearance/bootScript.ts +35 -0
- package/apps/shared/appearance/color.ts +169 -0
- package/apps/shared/appearance/photo.ts +88 -0
- package/apps/shared/appearance/resolvedTheme.ts +67 -0
- package/apps/shared/appearance/theme.ts +355 -0
- package/apps/shared/auth/accountUrl.ts +9 -0
- package/apps/shared/auth/adminAccess.ts +99 -0
- package/apps/shared/components/admin/layout/AdminShell.tsx +22 -10
- package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +107 -60
- package/apps/shared/components/admin/settings/BrandingForm.tsx +24 -0
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +2 -1
- package/apps/shared/components/admin/settings/PluginsManager.tsx +228 -25
- package/apps/shared/components/admin/setup/SetupWizard.tsx +2 -1
- package/apps/shared/components/calendar/CalendarListSidebar.tsx +4 -5
- package/apps/shared/components/calendar/layout/CalendarShell.tsx +8 -2
- package/apps/shared/components/contacts/ContactForm.tsx +11 -5
- package/apps/shared/components/contacts/ContactsSidebar.tsx +5 -3
- package/apps/shared/components/contacts/ContactsToolbar.tsx +98 -115
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +25 -8
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +13 -6
- package/apps/shared/components/layout/AppShell.tsx +477 -288
- package/apps/shared/components/layout/BrandingChrome.tsx +200 -13
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -389
- package/apps/shared/components/layout/MailboxProvisioning.tsx +168 -164
- package/apps/shared/components/layout/RailIcon.tsx +100 -0
- package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -0
- package/apps/shared/components/layout/ThemeSwitch.tsx +84 -0
- package/apps/shared/components/layout/UserMenu.tsx +372 -185
- package/apps/shared/components/mail/ConversationList.tsx +271 -262
- package/apps/shared/components/mail/ConversationThreadPane.tsx +147 -94
- package/apps/shared/components/mail/LazyReadingPane.tsx +113 -0
- package/apps/shared/components/mail/MailSelectionBar.tsx +227 -222
- package/apps/shared/components/mail/MessageDetailPane.tsx +1537 -1387
- package/apps/shared/components/mail/OutboxBadge.tsx +44 -0
- package/apps/shared/components/mail/OutboxRowStatus.tsx +31 -0
- package/apps/shared/components/mail/compose/ComposeContext.tsx +312 -160
- package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -418
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +1644 -1736
- package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +111 -0
- package/apps/shared/components/mail/compose/RichTextEditor.tsx +147 -118
- package/apps/shared/components/mail/compose/composePerf.ts +46 -0
- package/apps/shared/components/mail/compose/encryptionRequirement.ts +86 -0
- package/apps/shared/components/mail/compose/quotedBody.ts +161 -100
- package/apps/shared/components/mail/layout/MailShell.tsx +490 -472
- package/apps/shared/components/mail/reading/EncryptedBody.tsx +65 -0
- package/apps/shared/components/mail/reading/EncryptedPreview.tsx +35 -0
- package/apps/shared/components/mail/reading/MessageBody.tsx +240 -0
- package/apps/shared/components/mail/reading/MessageCard.tsx +174 -0
- package/apps/shared/components/mail/reading/bodyContent.ts +100 -0
- package/apps/shared/components/mail/reading/bodyHtml.ts +298 -0
- package/apps/shared/components/mail/reading/color.ts +245 -0
- package/apps/shared/components/mail/reading/frameControl.ts +142 -0
- package/apps/shared/components/mail/reading/frameDocument.ts +123 -0
- package/apps/shared/components/mail/reading/safeDocument.ts +24 -0
- package/apps/shared/components/mail/reading/themeAdaptation.ts +221 -0
- package/apps/shared/components/mail/reading/themeSurface.ts +90 -0
- package/apps/shared/components/mail/reading/viewOriginal.ts +38 -0
- package/apps/shared/components/mail/unreadStyle.tsx +75 -0
- package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -0
- package/apps/shared/components/settings/layout/SettingsShell.tsx +253 -240
- package/apps/shared/components/sharing/PrincipalPicker.tsx +145 -0
- package/apps/shared/components/tasks/TasksSidebar.tsx +5 -3
- package/apps/shared/components/tasks/layout/TasksShell.tsx +24 -8
- package/apps/shared/keyboard/GlobalShortcuts.tsx +51 -0
- package/apps/shared/keyboard/ShortcutProvider.tsx +62 -0
- package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -0
- package/apps/shared/keyboard/dispatch.ts +124 -0
- package/apps/shared/keyboard/format.ts +89 -0
- package/apps/shared/keyboard/keymap.ts +114 -0
- package/apps/shared/keyboard/match.ts +44 -0
- package/apps/shared/keyboard/parse.ts +136 -0
- package/apps/shared/keyboard/platform.ts +34 -0
- package/apps/shared/keyboard/registry.ts +65 -0
- package/apps/shared/keyboard/targets.ts +79 -0
- package/apps/shared/keyboard/useShortcut.ts +50 -0
- package/apps/shared/keyboard/useShortcutProps.ts +17 -0
- package/apps/shared/mail/folderCounts.ts +308 -0
- package/apps/shared/mail/folderTree.ts +143 -0
- package/apps/shared/mail/listSnapshots.ts +87 -0
- package/apps/shared/mail/messageReadState.ts +85 -0
- package/apps/shared/mail/newMailNotifications.ts +183 -0
- package/apps/shared/mail/outbox/UnlockBridge.tsx +23 -0
- package/apps/shared/mail/outbox/composeBridge.ts +69 -0
- package/apps/shared/mail/outbox/outboxState.ts +88 -0
- package/apps/shared/mail/outbox/pendingSends.ts +146 -0
- package/apps/shared/mail/outbox/sendDecision.ts +157 -0
- package/apps/shared/mail/outbox/sendJob.ts +427 -0
- package/apps/shared/mail/outbox/sendOutcomes.ts +146 -0
- package/apps/shared/mail/outbox/sendState.ts +35 -0
- package/apps/shared/mail/outbox/useOutboxStatus.ts +61 -0
- package/apps/shared/mail/useMailConnection.ts +203 -0
- package/apps/shared/mail/useMailLiveUpdates.ts +277 -224
- package/apps/shared/mail/useMarkMessageRead.ts +47 -0
- package/apps/shared/mail/useNewMailNotifications.ts +178 -0
- package/apps/shared/mail/useUnreadTitle.ts +42 -0
- package/apps/shared/navigation/AppRouter.tsx +300 -0
- package/apps/shared/navigation/appHrefs.ts +23 -0
- package/apps/shared/navigation/frameContext.tsx +35 -0
- package/apps/shared/navigation/idle.ts +45 -0
- package/apps/shared/navigation/routerContext.tsx +83 -0
- package/apps/shared/navigation/routes.ts +72 -0
- package/apps/shared/notifications/NotificationCenter.tsx +215 -0
- package/apps/shared/notifications/NotificationHistoryDialog.tsx +90 -0
- package/apps/shared/notifications/apiErrors.ts +98 -0
- package/apps/shared/notifications/headerOffset.ts +35 -0
- package/apps/shared/notifications/pushStatus.ts +56 -0
- package/apps/shared/notifications/store.ts +549 -0
- package/apps/shared/notifications/systemErrors.ts +63 -0
- package/apps/shared/notifications/useNotifications.ts +41 -0
- package/apps/shared/search/LocalIndexLifecycle.tsx +114 -98
- package/apps/shared/signing/enrollmentStorage.ts +33 -0
- package/apps/shared/signing/enrollmentTracker.ts +385 -0
- package/apps/shared/signing/enrollmentView.ts +251 -0
- package/apps/shared/signing/signingInfo.ts +58 -0
- package/apps/shared/signing/useNow.ts +19 -0
- package/apps/shared/signing/useSigningEnrollmentWatcher.ts +90 -0
- package/apps/shared/styles/app.css +108 -10
- package/apps/www/_layout.tsx +8 -2
- package/apps/www/_routedPage.tsx +24 -0
- package/apps/www/_routes.ts +36 -0
- package/apps/www/calendar/index.tsx +64 -33
- package/apps/www/contacts/[uid].tsx +109 -107
- package/apps/www/contacts/index.tsx +62 -42
- package/apps/www/index.tsx +2291 -1917
- package/apps/www/messages/[uid].tsx +108 -101
- package/apps/www/settings/appearance/index.tsx +21 -0
- package/apps/www/settings/auto-reply/index.tsx +7 -8
- package/apps/www/settings/encryption/index.tsx +1287 -1249
- package/apps/www/settings/filters/[uid].tsx +7 -2
- package/apps/www/settings/filters/index.tsx +102 -99
- package/apps/www/settings/filters/new/index.tsx +140 -133
- package/apps/www/settings/labels/index.tsx +204 -201
- package/apps/www/settings/privacy/index.tsx +7 -9
- package/apps/www/settings/read-receipts/index.tsx +7 -8
- package/apps/www/settings/sharing/index.tsx +256 -274
- package/apps/www/settings/signatures/[uid].tsx +172 -167
- package/apps/www/settings/signatures/index.tsx +88 -85
- package/apps/www/settings/signatures/new/index.tsx +135 -129
- package/apps/www/tasks/index.tsx +29 -18
- package/dist/apps/admin/_layout.d.ts +5 -1
- package/dist/apps/admin/_layout.js +3 -2
- package/dist/apps/admin/index.js +3 -2
- package/dist/apps/admin/ingest-queue/index.js +2 -1
- package/dist/apps/admin/mailboxes/[uid].js +9 -6
- package/dist/apps/admin/quarantine/index.js +2 -1
- package/dist/apps/admin/signing-certificates/index.d.ts +3 -0
- package/dist/apps/admin/signing-certificates/index.js +161 -0
- package/dist/apps/escrow/_layout.d.ts +5 -1
- package/dist/apps/escrow/_layout.js +3 -2
- package/dist/apps/shared/appearance/AppearanceForm.d.ts +7 -0
- package/dist/apps/shared/appearance/AppearanceForm.js +131 -0
- package/dist/apps/shared/appearance/AppearanceHead.d.ts +15 -0
- package/dist/apps/shared/appearance/AppearanceHead.js +31 -0
- package/dist/apps/shared/appearance/AppearanceProvider.d.ts +32 -0
- package/dist/apps/shared/appearance/AppearanceProvider.js +390 -0
- package/dist/apps/shared/appearance/ColorField.d.ts +22 -0
- package/dist/apps/shared/appearance/ColorField.js +40 -0
- package/dist/apps/shared/appearance/appearanceCache.d.ts +45 -0
- package/dist/apps/shared/appearance/appearanceCache.js +80 -0
- package/dist/apps/shared/appearance/appearanceContext.d.ts +45 -0
- package/dist/apps/shared/appearance/appearanceContext.js +29 -0
- package/dist/apps/shared/appearance/bootScript.d.ts +16 -0
- package/dist/apps/shared/appearance/bootScript.js +33 -0
- package/dist/apps/shared/appearance/color.d.ts +65 -0
- package/dist/apps/shared/appearance/color.js +132 -0
- package/dist/apps/shared/appearance/photo.d.ts +17 -0
- package/dist/apps/shared/appearance/photo.js +79 -0
- package/dist/apps/shared/appearance/resolvedTheme.d.ts +21 -0
- package/dist/apps/shared/appearance/resolvedTheme.js +55 -0
- package/dist/apps/shared/appearance/theme.d.ts +111 -0
- package/dist/apps/shared/appearance/theme.js +251 -0
- package/dist/apps/shared/auth/accountUrl.d.ts +2 -0
- package/dist/apps/shared/auth/accountUrl.js +8 -0
- package/dist/apps/shared/auth/adminAccess.d.ts +30 -0
- package/dist/apps/shared/auth/adminAccess.js +89 -0
- package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
- package/dist/apps/shared/components/admin/layout/AdminShell.js +16 -6
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +10 -5
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +49 -34
- package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +2 -0
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +7 -1
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +1 -1
- package/dist/apps/shared/components/admin/settings/PluginsManager.js +106 -20
- package/dist/apps/shared/components/admin/setup/SetupWizard.js +2 -1
- package/dist/apps/shared/components/calendar/CalendarListSidebar.js +8 -8
- package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
- package/dist/apps/shared/components/calendar/layout/CalendarShell.js +8 -4
- package/dist/apps/shared/components/contacts/ContactForm.js +1 -1
- package/dist/apps/shared/components/contacts/ContactsSidebar.js +4 -2
- package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +6 -2
- package/dist/apps/shared/components/contacts/ContactsToolbar.js +28 -10
- package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +19 -6
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +7 -4
- package/dist/apps/shared/components/layout/AppShell.d.ts +34 -4
- package/dist/apps/shared/components/layout/AppShell.js +122 -17
- package/dist/apps/shared/components/layout/BrandingChrome.d.ts +69 -10
- package/dist/apps/shared/components/layout/BrandingChrome.js +140 -12
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +10 -9
- package/dist/apps/shared/components/layout/MailboxProvisioning.js +3 -1
- package/dist/apps/shared/components/layout/RailIcon.d.ts +21 -0
- package/dist/apps/shared/components/layout/RailIcon.js +85 -0
- package/dist/apps/shared/components/layout/ResponsiveToolbar.d.ts +55 -0
- package/dist/apps/shared/components/layout/ResponsiveToolbar.js +199 -0
- package/dist/apps/shared/components/layout/ThemeSwitch.d.ts +9 -0
- package/dist/apps/shared/components/layout/ThemeSwitch.js +54 -0
- package/dist/apps/shared/components/layout/UserMenu.d.ts +25 -3
- package/dist/apps/shared/components/layout/UserMenu.js +88 -7
- package/dist/apps/shared/components/mail/ConversationList.js +5 -11
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +6 -2
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +87 -40
- package/dist/apps/shared/components/mail/LazyReadingPane.d.ts +9 -0
- package/dist/apps/shared/components/mail/LazyReadingPane.js +83 -0
- package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +6 -4
- package/dist/apps/shared/components/mail/MailSelectionBar.js +11 -4
- package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +25 -8
- package/dist/apps/shared/components/mail/MessageDetailPane.js +167 -73
- package/dist/apps/shared/components/mail/OutboxBadge.d.ts +17 -0
- package/dist/apps/shared/components/mail/OutboxBadge.js +18 -0
- package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +10 -0
- package/dist/apps/shared/components/mail/OutboxRowStatus.js +19 -0
- package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +38 -0
- package/dist/apps/shared/components/mail/compose/ComposeContext.js +97 -6
- package/dist/apps/shared/components/mail/compose/ComposeToolbar.js +4 -3
- package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +3 -2
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +316 -339
- package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.d.ts +19 -0
- package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +33 -0
- package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +9 -1
- package/dist/apps/shared/components/mail/compose/RichTextEditor.js +20 -2
- package/dist/apps/shared/components/mail/compose/composePerf.d.ts +16 -0
- package/dist/apps/shared/components/mail/compose/composePerf.js +41 -0
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +49 -0
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +35 -0
- package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +13 -0
- package/dist/apps/shared/components/mail/compose/quotedBody.js +67 -11
- package/dist/apps/shared/components/mail/layout/MailShell.d.ts +14 -4
- package/dist/apps/shared/components/mail/layout/MailShell.js +90 -104
- package/dist/apps/shared/components/mail/reading/EncryptedBody.d.ts +21 -0
- package/dist/apps/shared/components/mail/reading/EncryptedBody.js +22 -0
- package/dist/apps/shared/components/mail/reading/EncryptedPreview.d.ts +18 -0
- package/dist/apps/shared/components/mail/reading/EncryptedPreview.js +22 -0
- package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +32 -0
- package/dist/apps/shared/components/mail/reading/MessageBody.js +136 -0
- package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +62 -0
- package/dist/apps/shared/components/mail/reading/MessageCard.js +58 -0
- package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +38 -0
- package/dist/apps/shared/components/mail/reading/bodyContent.js +84 -0
- package/dist/apps/shared/components/mail/reading/bodyHtml.d.ts +47 -0
- package/dist/apps/shared/components/mail/reading/bodyHtml.js +267 -0
- package/dist/apps/shared/components/mail/reading/color.d.ts +63 -0
- package/dist/apps/shared/components/mail/reading/color.js +201 -0
- package/dist/apps/shared/components/mail/reading/frameControl.d.ts +33 -0
- package/dist/apps/shared/components/mail/reading/frameControl.js +120 -0
- package/dist/apps/shared/components/mail/reading/frameDocument.d.ts +52 -0
- package/dist/apps/shared/components/mail/reading/frameDocument.js +98 -0
- package/dist/apps/shared/components/mail/reading/safeDocument.d.ts +3 -0
- package/dist/apps/shared/components/mail/reading/safeDocument.js +12 -0
- package/dist/apps/shared/components/mail/reading/themeAdaptation.d.ts +56 -0
- package/dist/apps/shared/components/mail/reading/themeAdaptation.js +144 -0
- package/dist/apps/shared/components/mail/reading/themeSurface.d.ts +17 -0
- package/dist/apps/shared/components/mail/reading/themeSurface.js +83 -0
- package/dist/apps/shared/components/mail/reading/viewOriginal.d.ts +9 -0
- package/dist/apps/shared/components/mail/reading/viewOriginal.js +32 -0
- package/dist/apps/shared/components/mail/unreadStyle.d.ts +45 -0
- package/dist/apps/shared/components/mail/unreadStyle.js +61 -0
- package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +32 -0
- package/dist/apps/shared/components/settings/SigningCertificateCard.js +98 -0
- package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +16 -5
- package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +26 -0
- package/dist/apps/shared/components/sharing/PrincipalPicker.js +77 -0
- package/dist/apps/shared/components/tasks/TasksSidebar.js +4 -2
- package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
- package/dist/apps/shared/components/tasks/layout/TasksShell.js +18 -6
- package/dist/apps/shared/keyboard/GlobalShortcuts.d.ts +14 -0
- package/dist/apps/shared/keyboard/GlobalShortcuts.js +37 -0
- package/dist/apps/shared/keyboard/ShortcutProvider.d.ts +20 -0
- package/dist/apps/shared/keyboard/ShortcutProvider.js +52 -0
- package/dist/apps/shared/keyboard/ShortcutsDialog.d.ts +14 -0
- package/dist/apps/shared/keyboard/ShortcutsDialog.js +42 -0
- package/dist/apps/shared/keyboard/dispatch.d.ts +16 -0
- package/dist/apps/shared/keyboard/dispatch.js +109 -0
- package/dist/apps/shared/keyboard/format.d.ts +12 -0
- package/dist/apps/shared/keyboard/format.js +74 -0
- package/dist/apps/shared/keyboard/keymap.d.ts +294 -0
- package/dist/apps/shared/keyboard/keymap.js +84 -0
- package/dist/apps/shared/keyboard/match.d.ts +20 -0
- package/dist/apps/shared/keyboard/match.js +31 -0
- package/dist/apps/shared/keyboard/parse.d.ts +31 -0
- package/dist/apps/shared/keyboard/parse.js +107 -0
- package/dist/apps/shared/keyboard/platform.d.ts +15 -0
- package/dist/apps/shared/keyboard/platform.js +22 -0
- package/dist/apps/shared/keyboard/registry.d.ts +39 -0
- package/dist/apps/shared/keyboard/registry.js +33 -0
- package/dist/apps/shared/keyboard/targets.d.ts +14 -0
- package/dist/apps/shared/keyboard/targets.js +67 -0
- package/dist/apps/shared/keyboard/useShortcut.d.ts +19 -0
- package/dist/apps/shared/keyboard/useShortcut.js +35 -0
- package/dist/apps/shared/keyboard/useShortcutProps.d.ts +10 -0
- package/dist/apps/shared/keyboard/useShortcutProps.js +15 -0
- package/dist/apps/shared/mail/folderCounts.d.ts +78 -0
- package/dist/apps/shared/mail/folderCounts.js +218 -0
- package/dist/apps/shared/mail/folderTree.d.ts +55 -0
- package/dist/apps/shared/mail/folderTree.js +116 -0
- package/dist/apps/shared/mail/listSnapshots.d.ts +46 -0
- package/dist/apps/shared/mail/listSnapshots.js +43 -0
- package/dist/apps/shared/mail/messageReadState.d.ts +32 -0
- package/dist/apps/shared/mail/messageReadState.js +63 -0
- package/dist/apps/shared/mail/newMailNotifications.d.ts +62 -0
- package/dist/apps/shared/mail/newMailNotifications.js +138 -0
- package/dist/apps/shared/mail/outbox/UnlockBridge.d.ts +5 -0
- package/dist/apps/shared/mail/outbox/UnlockBridge.js +18 -0
- package/dist/apps/shared/mail/outbox/composeBridge.d.ts +34 -0
- package/dist/apps/shared/mail/outbox/composeBridge.js +32 -0
- package/dist/apps/shared/mail/outbox/outboxState.d.ts +41 -0
- package/dist/apps/shared/mail/outbox/outboxState.js +42 -0
- package/dist/apps/shared/mail/outbox/pendingSends.d.ts +39 -0
- package/dist/apps/shared/mail/outbox/pendingSends.js +109 -0
- package/dist/apps/shared/mail/outbox/sendDecision.d.ts +80 -0
- package/dist/apps/shared/mail/outbox/sendDecision.js +94 -0
- package/dist/apps/shared/mail/outbox/sendJob.d.ts +68 -0
- package/dist/apps/shared/mail/outbox/sendJob.js +319 -0
- package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +3 -0
- package/dist/apps/shared/mail/outbox/sendOutcomes.js +141 -0
- package/dist/apps/shared/mail/outbox/sendState.d.ts +25 -0
- package/dist/apps/shared/mail/outbox/sendState.js +8 -0
- package/dist/apps/shared/mail/outbox/useOutboxStatus.d.ts +11 -0
- package/dist/apps/shared/mail/outbox/useOutboxStatus.js +49 -0
- package/dist/apps/shared/mail/useMailConnection.d.ts +56 -0
- package/dist/apps/shared/mail/useMailConnection.js +138 -0
- package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +29 -9
- package/dist/apps/shared/mail/useMailLiveUpdates.js +60 -32
- package/dist/apps/shared/mail/useMarkMessageRead.d.ts +12 -0
- package/dist/apps/shared/mail/useMarkMessageRead.js +44 -0
- package/dist/apps/shared/mail/useNewMailNotifications.d.ts +35 -0
- package/dist/apps/shared/mail/useNewMailNotifications.js +130 -0
- package/dist/apps/shared/mail/useUnreadTitle.d.ts +18 -0
- package/dist/apps/shared/mail/useUnreadTitle.js +31 -0
- package/dist/apps/shared/navigation/AppRouter.d.ts +52 -0
- package/dist/apps/shared/navigation/AppRouter.js +242 -0
- package/dist/apps/shared/navigation/appHrefs.d.ts +14 -0
- package/dist/apps/shared/navigation/appHrefs.js +20 -0
- package/dist/apps/shared/navigation/frameContext.d.ts +19 -0
- package/dist/apps/shared/navigation/frameContext.js +24 -0
- package/dist/apps/shared/navigation/idle.d.ts +14 -0
- package/dist/apps/shared/navigation/idle.js +43 -0
- package/dist/apps/shared/navigation/routerContext.d.ts +37 -0
- package/dist/apps/shared/navigation/routerContext.js +56 -0
- package/dist/apps/shared/navigation/routes.d.ts +32 -0
- package/dist/apps/shared/navigation/routes.js +37 -0
- package/dist/apps/shared/notifications/NotificationCenter.d.ts +19 -0
- package/dist/apps/shared/notifications/NotificationCenter.js +90 -0
- package/dist/apps/shared/notifications/NotificationHistoryDialog.d.ts +10 -0
- package/dist/apps/shared/notifications/NotificationHistoryDialog.js +36 -0
- package/dist/apps/shared/notifications/apiErrors.d.ts +19 -0
- package/dist/apps/shared/notifications/apiErrors.js +86 -0
- package/dist/apps/shared/notifications/headerOffset.d.ts +8 -0
- package/dist/apps/shared/notifications/headerOffset.js +33 -0
- package/dist/apps/shared/notifications/pushStatus.d.ts +9 -0
- package/dist/apps/shared/notifications/pushStatus.js +54 -0
- package/dist/apps/shared/notifications/store.d.ts +136 -0
- package/dist/apps/shared/notifications/store.js +416 -0
- package/dist/apps/shared/notifications/systemErrors.d.ts +9 -0
- package/dist/apps/shared/notifications/systemErrors.js +58 -0
- package/dist/apps/shared/notifications/useNotifications.d.ts +17 -0
- package/dist/apps/shared/notifications/useNotifications.js +18 -0
- package/dist/apps/shared/search/LocalIndexLifecycle.js +17 -3
- package/dist/apps/shared/signing/enrollmentStorage.d.ts +10 -0
- package/dist/apps/shared/signing/enrollmentStorage.js +33 -0
- package/dist/apps/shared/signing/enrollmentTracker.d.ts +73 -0
- package/dist/apps/shared/signing/enrollmentTracker.js +307 -0
- package/dist/apps/shared/signing/enrollmentView.d.ts +57 -0
- package/dist/apps/shared/signing/enrollmentView.js +214 -0
- package/dist/apps/shared/signing/signingInfo.d.ts +11 -0
- package/dist/apps/shared/signing/signingInfo.js +48 -0
- package/dist/apps/shared/signing/useNow.d.ts +2 -0
- package/dist/apps/shared/signing/useNow.js +18 -0
- package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +16 -0
- package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +87 -0
- package/dist/apps/shared/styles/app.css +108 -10
- package/dist/apps/www/_layout.d.ts +5 -1
- package/dist/apps/www/_layout.js +3 -2
- package/dist/apps/www/_routedPage.d.ts +12 -0
- package/dist/apps/www/_routedPage.js +19 -0
- package/dist/apps/www/_routes.d.ts +11 -0
- package/dist/apps/www/_routes.js +30 -0
- package/dist/apps/www/calendar/index.d.ts +2 -2
- package/dist/apps/www/calendar/index.js +41 -11
- package/dist/apps/www/contacts/[uid].d.ts +3 -9
- package/dist/apps/www/contacts/[uid].js +11 -9
- package/dist/apps/www/contacts/index.d.ts +2 -2
- package/dist/apps/www/contacts/index.js +30 -24
- package/dist/apps/www/index.d.ts +2 -2
- package/dist/apps/www/index.js +332 -48
- package/dist/apps/www/messages/[uid].d.ts +3 -7
- package/dist/apps/www/messages/[uid].js +10 -5
- package/dist/apps/www/settings/appearance/index.d.ts +4 -0
- package/dist/apps/www/settings/appearance/index.js +13 -0
- package/dist/apps/www/settings/auto-reply/index.d.ts +2 -2
- package/dist/apps/www/settings/auto-reply/index.js +6 -7
- package/dist/apps/www/settings/encryption/index.d.ts +2 -2
- package/dist/apps/www/settings/encryption/index.js +106 -96
- package/dist/apps/www/settings/filters/[uid].d.ts +2 -2
- package/dist/apps/www/settings/filters/[uid].js +6 -2
- package/dist/apps/www/settings/filters/index.d.ts +2 -2
- package/dist/apps/www/settings/filters/index.js +3 -1
- package/dist/apps/www/settings/filters/new/index.d.ts +2 -2
- package/dist/apps/www/settings/filters/new/index.js +9 -3
- package/dist/apps/www/settings/labels/index.d.ts +2 -2
- package/dist/apps/www/settings/labels/index.js +3 -1
- package/dist/apps/www/settings/privacy/index.d.ts +2 -2
- package/dist/apps/www/settings/privacy/index.js +8 -9
- package/dist/apps/www/settings/read-receipts/index.d.ts +2 -2
- package/dist/apps/www/settings/read-receipts/index.js +6 -7
- package/dist/apps/www/settings/sharing/index.d.ts +2 -2
- package/dist/apps/www/settings/sharing/index.js +22 -34
- package/dist/apps/www/settings/signatures/[uid].d.ts +2 -2
- package/dist/apps/www/settings/signatures/[uid].js +6 -2
- package/dist/apps/www/settings/signatures/index.d.ts +2 -2
- package/dist/apps/www/settings/signatures/index.js +3 -1
- package/dist/apps/www/settings/signatures/new/index.d.ts +2 -2
- package/dist/apps/www/settings/signatures/new/index.js +9 -4
- package/dist/apps/www/tasks/index.d.ts +2 -2
- package/dist/apps/www/tasks/index.js +22 -16
- package/package.json +2 -2
- package/apps/shared/components/mail/compose/SendFailureAlert.tsx +0 -48
- package/dist/apps/shared/components/mail/compose/SendFailureAlert.d.ts +0 -14
- package/dist/apps/shared/components/mail/compose/SendFailureAlert.js +0 -11
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from "react";
|
|
2
2
|
import { DraftThreading } from "@rapidmx/react-shared/mail/mailApi.js";
|
|
3
|
+
import { ResumeCompose } from "../../../mail/outbox/composeBridge.js";
|
|
4
|
+
/** The CSS variable (on `<html>`) that holds how far down the screen the open compose windows start, in px. */
|
|
5
|
+
export declare const COMPOSE_TOP_VAR = "--rr-compose-top";
|
|
6
|
+
/**
|
|
7
|
+
* Starts downloading the compose window's code without opening one - on hover/focus of a Compose or Reply button and when
|
|
8
|
+
* the browser is idle after the inbox has loaded - so that clicking it finds the chunk already in memory. Safe to call
|
|
9
|
+
* any number of times, and never rejects: a failed download is retried by the click itself.
|
|
10
|
+
*/
|
|
11
|
+
export declare function prefetchComposeWindow(): void;
|
|
12
|
+
/** Test seam: forgets the loaded compose window chunk, as a fresh page load would. */
|
|
13
|
+
export declare function resetComposeWindowLoader(): void;
|
|
3
14
|
export interface ComposeSession {
|
|
4
15
|
id: string;
|
|
5
16
|
/** The initial sending mailbox - absent means "the caller's own mailbox" (see `ComposeWindow`). */
|
|
@@ -20,8 +31,23 @@ export interface ComposeSession {
|
|
|
20
31
|
signatureContext: "new" | "reply_forward";
|
|
21
32
|
/** See `OpenComposeInput.suppressSigning`'s own doc comment. */
|
|
22
33
|
suppressSigning?: boolean;
|
|
34
|
+
/** The window opened before its quoted original was known (see `OpenComposeInput.pending`): the body waits for it. */
|
|
35
|
+
quotePending?: boolean;
|
|
36
|
+
/** What `OpenComposeInput.pending` resolved with, once it has - see `ComposeLateInput`. */
|
|
37
|
+
late?: ComposeLateInput;
|
|
38
|
+
/** See `OpenComposeInput.resume`. */
|
|
39
|
+
resume?: ResumeCompose;
|
|
23
40
|
minimized: boolean;
|
|
24
41
|
}
|
|
42
|
+
/** What a reply or forward could only work out after its window was already open (see `OpenComposeInput.pending`). */
|
|
43
|
+
export interface ComposeLateInput {
|
|
44
|
+
/** The quoted original - see `OpenComposeInput.quotedHtml`. */
|
|
45
|
+
quotedHtml?: string;
|
|
46
|
+
/** A better To than the one the window opened with - applied only if the To field is still exactly what it opened with. */
|
|
47
|
+
to?: string;
|
|
48
|
+
/** A better Cc, under the same rule as `to`. */
|
|
49
|
+
cc?: string;
|
|
50
|
+
}
|
|
25
51
|
export interface OpenComposeInput {
|
|
26
52
|
/** The sending mailbox to start with. Omit for a fresh message (defaults to the caller's own mailbox);
|
|
27
53
|
* a reply/forward passes the original message's mailbox so a shared mailbox's mail replies from it.
|
|
@@ -53,6 +79,18 @@ export interface OpenComposeInput {
|
|
|
53
79
|
* `In-Reply-To`/`References` at all and every mail system - the sender's own Sent Items included - files it
|
|
54
80
|
* as a new conversation rather than part of the thread. Absent for a fresh compose, which starts one. */
|
|
55
81
|
threading?: DraftThreading;
|
|
82
|
+
/**
|
|
83
|
+
* Something the window shouldn't wait for before appearing: a reply or forward opens at once from what is already in
|
|
84
|
+
* memory (the message's own subject and sender), and this settles with what needed the network - the original's body
|
|
85
|
+
* to quote, and for Reply All the recipients its headers name. The compose window shows meanwhile, its body area
|
|
86
|
+
* waiting, and fills the body in when this resolves; `to`/`cc` replace the opened-with values only if the user hasn't
|
|
87
|
+
* touched those fields. Must never reject (resolve `undefined` for "nothing more"); when set, `quotedHtml` is ignored
|
|
88
|
+
* until it resolves.
|
|
89
|
+
*/
|
|
90
|
+
pending?: Promise<ComposeLateInput | undefined>;
|
|
91
|
+
/** Re-opens a message that was already composed - a failed send's "Open draft": the window continues that server draft, with every field
|
|
92
|
+
* exactly as it was typed, instead of starting a new one. */
|
|
93
|
+
resume?: ResumeCompose;
|
|
56
94
|
}
|
|
57
95
|
export interface ComposeContextValue {
|
|
58
96
|
/** Opens a new compose window, stacked alongside any already open (Gmail allows several at once). */
|
|
@@ -3,9 +3,70 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
4
4
|
// SPDX-License-Identifier: MPL-2.0
|
|
5
5
|
///////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
import { createContext, useContext, useMemo, useState } from "react";
|
|
6
|
+
import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import useIsMobile from "@rapidmx/react-shared/util/useIsMobile.js";
|
|
8
|
-
import
|
|
8
|
+
import { registerComposeOpener } from "../../../mail/outbox/composeBridge.js";
|
|
9
|
+
import { markComposePhase } from "./composePerf.js";
|
|
10
|
+
import ComposeWindowPlaceholder from "./ComposeWindowPlaceholder.js";
|
|
11
|
+
/** The CSS variable (on `<html>`) that holds how far down the screen the open compose windows start, in px. */
|
|
12
|
+
export const COMPOSE_TOP_VAR = "--rr-compose-top";
|
|
13
|
+
let loadedComposeWindow;
|
|
14
|
+
let loadingComposeWindow;
|
|
15
|
+
/**
|
|
16
|
+
* The compose window - with the rich-text editor (TipTap/ProseMirror), the recipient inputs and the send pipeline - is
|
|
17
|
+
* the largest piece of the mail app and most page loads never open it, so it is a separate chunk, loaded here once. Not
|
|
18
|
+
* `React.lazy()`: a chunk that failed to download (offline, a deploy that replaced it) must be retryable, and `lazy()` keeps
|
|
19
|
+
* the rejection for good.
|
|
20
|
+
*/
|
|
21
|
+
function loadComposeWindow() {
|
|
22
|
+
loadingComposeWindow ?? (loadingComposeWindow = import("./ComposeWindow.js").then((module) => (loadedComposeWindow = module.default), (err) => {
|
|
23
|
+
loadingComposeWindow = undefined;
|
|
24
|
+
throw err;
|
|
25
|
+
}));
|
|
26
|
+
return loadingComposeWindow;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Starts downloading the compose window's code without opening one - on hover/focus of a Compose or Reply button and when
|
|
30
|
+
* the browser is idle after the inbox has loaded - so that clicking it finds the chunk already in memory. Safe to call
|
|
31
|
+
* any number of times, and never rejects: a failed download is retried by the click itself.
|
|
32
|
+
*/
|
|
33
|
+
export function prefetchComposeWindow() {
|
|
34
|
+
loadComposeWindow().catch(() => undefined);
|
|
35
|
+
}
|
|
36
|
+
/** Test seam: forgets the loaded compose window chunk, as a fresh page load would. */
|
|
37
|
+
export function resetComposeWindowLoader() {
|
|
38
|
+
loadedComposeWindow = undefined;
|
|
39
|
+
loadingComposeWindow = undefined;
|
|
40
|
+
}
|
|
41
|
+
/** The compose window component once its chunk is in, else `undefined` (while loading, or `failed`), and a way to retry. */
|
|
42
|
+
function useComposeWindowComponent(wanted) {
|
|
43
|
+
const [loaded, setComponent] = useState();
|
|
44
|
+
// Also read straight from the module: a prefetch that finished after this provider mounted has no state update to
|
|
45
|
+
// announce it, and the first click must not flash the placeholder for a chunk that is already here.
|
|
46
|
+
const Component = loaded ?? loadedComposeWindow;
|
|
47
|
+
const [failed, setFailed] = useState(false);
|
|
48
|
+
const [attempt, setAttempt] = useState(0);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (!wanted || Component) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
let cancelled = false;
|
|
54
|
+
setFailed(false);
|
|
55
|
+
loadComposeWindow().then((component) => {
|
|
56
|
+
if (!cancelled) {
|
|
57
|
+
setComponent(() => component);
|
|
58
|
+
}
|
|
59
|
+
}, () => {
|
|
60
|
+
if (!cancelled) {
|
|
61
|
+
setFailed(true);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return () => {
|
|
65
|
+
cancelled = true;
|
|
66
|
+
};
|
|
67
|
+
}, [wanted, Component, attempt]);
|
|
68
|
+
return { Component, failed, retry: () => setAttempt((n) => n + 1) };
|
|
69
|
+
}
|
|
9
70
|
const ComposeContext = createContext({ openCompose: () => undefined });
|
|
10
71
|
/** Opens the floating Compose window from anywhere inside `AppShell` (any of the four webmail apps). */
|
|
11
72
|
export function useCompose() {
|
|
@@ -21,11 +82,33 @@ export function useCompose() {
|
|
|
21
82
|
export default function ComposeProvider({ children, userUid, trusted }) {
|
|
22
83
|
const [sessions, setSessions] = useState([]);
|
|
23
84
|
const isMobile = useIsMobile();
|
|
24
|
-
|
|
85
|
+
const { Component: ComposeWindow, failed, retry: retryLoad } = useComposeWindowComponent(sessions.length > 0);
|
|
86
|
+
// The top edge of the compose windows, published as `--rr-compose-top` so the pop-up stack (`NotificationCenter`) can keep clear of them.
|
|
87
|
+
const windowsRef = useRef(null);
|
|
88
|
+
const hasSessions = sessions.length > 0;
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
const element = windowsRef.current;
|
|
91
|
+
if (!element) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const publish = () => document.documentElement.style.setProperty(COMPOSE_TOP_VAR, `${Math.round(element.getBoundingClientRect().top)}px`);
|
|
95
|
+
publish();
|
|
96
|
+
const observer = typeof ResizeObserver === "undefined" ? undefined : new ResizeObserver(publish);
|
|
97
|
+
observer?.observe(element);
|
|
98
|
+
window.addEventListener("resize", publish);
|
|
99
|
+
return () => {
|
|
100
|
+
observer?.disconnect();
|
|
101
|
+
window.removeEventListener("resize", publish);
|
|
102
|
+
document.documentElement.style.removeProperty(COMPOSE_TOP_VAR);
|
|
103
|
+
};
|
|
104
|
+
}, [hasSessions]);
|
|
105
|
+
function openCompose({ mailboxUid, to, cc, subject, quotedHtml, signatureContext = "new", suppressSigning, encrypt, threading, pending, resume, }) {
|
|
106
|
+
const id = crypto.randomUUID();
|
|
107
|
+
markComposePhase(id, "click");
|
|
25
108
|
setSessions((prev) => [
|
|
26
109
|
...prev,
|
|
27
110
|
{
|
|
28
|
-
id
|
|
111
|
+
id,
|
|
29
112
|
mailboxUid,
|
|
30
113
|
initialTo: to,
|
|
31
114
|
initialCc: cc,
|
|
@@ -35,9 +118,15 @@ export default function ComposeProvider({ children, userUid, trusted }) {
|
|
|
35
118
|
threading,
|
|
36
119
|
signatureContext,
|
|
37
120
|
suppressSigning,
|
|
121
|
+
quotePending: !!pending,
|
|
122
|
+
resume,
|
|
38
123
|
minimized: false,
|
|
39
124
|
},
|
|
40
125
|
]);
|
|
126
|
+
// A window closed before this settles is simply not in the list any more - nothing to update.
|
|
127
|
+
void pending
|
|
128
|
+
?.catch(() => undefined)
|
|
129
|
+
.then((late) => setSessions((prev) => prev.map((s) => s.id === id ? { ...s, quotePending: false, late, initialQuotedHtml: late?.quotedHtml ?? s.initialQuotedHtml } : s)));
|
|
41
130
|
}
|
|
42
131
|
function closeCompose(id) {
|
|
43
132
|
setSessions((prev) => prev.filter((s) => s.id !== id));
|
|
@@ -46,6 +135,8 @@ export default function ComposeProvider({ children, userUid, trusted }) {
|
|
|
46
135
|
setSessions((prev) => prev.map((s) => (s.id === id ? { ...s, minimized: !s.minimized } : s)));
|
|
47
136
|
}
|
|
48
137
|
const value = useMemo(() => ({ openCompose }), []);
|
|
138
|
+
// Code with no React context - a failed send's "Open draft" pop-up - opens windows through this.
|
|
139
|
+
useEffect(() => registerComposeOpener((input) => value.openCompose(input)), [value]);
|
|
49
140
|
// On mobile, a non-minimized `ComposeWindow` renders full-screen (see that component's own doc
|
|
50
141
|
// comment) — Gmail-style stacking of several full-screen overlays at once makes no sense there, so
|
|
51
142
|
// at most one non-minimized session is ever shown: the most recently opened one. Minimized
|
|
@@ -54,8 +145,8 @@ export default function ComposeProvider({ children, userUid, trusted }) {
|
|
|
54
145
|
// non-minimized one) once whatever's currently "on top" is closed or minimized. The others stay
|
|
55
146
|
// mounted, just hidden: unmounting them would throw away everything typed into them.
|
|
56
147
|
const lastNonMinimizedId = isMobile ? [...sessions].reverse().find((s) => !s.minimized)?.id : undefined;
|
|
57
|
-
return (_jsxs(ComposeContext.Provider, { value: value, children: [children, sessions.length > 0 && (_jsx("div", { className: "fixed bottom-0 right-6 flex items-end gap-3 z-50", children: sessions.map((session) => {
|
|
148
|
+
return (_jsxs(ComposeContext.Provider, { value: value, children: [children, sessions.length > 0 && (_jsx("div", { ref: windowsRef, className: "fixed bottom-0 right-6 flex items-end gap-3 z-50", children: sessions.map((session) => {
|
|
58
149
|
const hidden = isMobile && !session.minimized && session.id !== lastNonMinimizedId;
|
|
59
|
-
return (_jsx("div", { hidden: hidden, className: hidden ? "hidden" : "contents", children: _jsx(ComposeWindow, { session: session, userUid: userUid, trusted: trusted, onClose: () => closeCompose(session.id), onToggleMinimize: () => toggleMinimize(session.id) }) }, session.id));
|
|
150
|
+
return (_jsx("div", { hidden: hidden, className: hidden ? "hidden" : "contents", children: ComposeWindow ? (_jsx(ComposeWindow, { session: session, userUid: userUid, trusted: trusted, onClose: () => closeCompose(session.id), onToggleMinimize: () => toggleMinimize(session.id) })) : (_jsx(ComposeWindowPlaceholder, { session: session, failed: failed, onRetry: retryLoad, onClose: () => closeCompose(session.id), onToggleMinimize: () => toggleMinimize(session.id) })) }, session.id));
|
|
60
151
|
}) }))] }));
|
|
61
152
|
}
|
|
@@ -3,10 +3,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
4
4
|
// SPDX-License-Identifier: MPL-2.0
|
|
5
5
|
///////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
import { useRef, useState } from "react";
|
|
6
|
+
import { Suspense, lazy, useRef, useState } from "react";
|
|
7
7
|
import { BsArrowClockwise, BsArrowCounterclockwise, BsEraser, BsHighlighter, BsImage, BsIndent, BsJustify, BsLink45Deg, BsListOl, BsListUl, BsPaletteFill, BsTable, BsTextCenter, BsTextLeft, BsTextRight, BsTypeBold, BsTypeItalic, BsTypeStrikethrough, BsTypeUnderline, BsUnindent, } from "react-icons/bs";
|
|
8
|
-
import EmojiPicker from "./EmojiPicker.js";
|
|
9
8
|
import GifPicker from "./GifPicker.js";
|
|
9
|
+
/** Loaded when the picker is first opened: the emoji list is a half-megabyte JSON file that nothing else needs. */
|
|
10
|
+
const EmojiPicker = lazy(() => import("./EmojiPicker.js"));
|
|
10
11
|
const FONT_FAMILIES = [
|
|
11
12
|
{ label: "Default", value: "" },
|
|
12
13
|
{ label: "Sans Serif", value: "Arial, Helvetica, sans-serif" },
|
|
@@ -84,5 +85,5 @@ export default function ComposeToolbar({ editor, onUploadImage }) {
|
|
|
84
85
|
? ed.chain().focus().setFontFamily(e.target.value).run()
|
|
85
86
|
: ed.chain().focus().unsetFontFamily().run()), className: "text-xs py-1 px-1.5 border border-border rounded-sm bg-surface disabled:opacity-40", children: FONT_FAMILIES.map((f) => (_jsx("option", { value: f.value, children: f.label }, f.label))) }), _jsx("select", { "aria-label": "Font size", disabled: disabled, value: editor?.getAttributes("textStyle").fontSize ?? "", onChange: (e) => run((ed) => e.target.value
|
|
86
87
|
? ed.chain().focus().setFontSize(e.target.value).run()
|
|
87
|
-
: ed.chain().focus().unsetFontSize().run()), className: "text-xs py-1 px-1.5 border border-border rounded-sm bg-surface disabled:opacity-40", children: FONT_SIZES.map((f) => (_jsx("option", { value: f.value, children: f.label }, f.label))) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Bold", icon: BsTypeBold, disabled: disabled, active: editor?.isActive("bold"), onClick: () => run((e) => e.chain().focus().toggleBold().run()) }), _jsx(ToolbarButton, { label: "Italic", icon: BsTypeItalic, disabled: disabled, active: editor?.isActive("italic"), onClick: () => run((e) => e.chain().focus().toggleItalic().run()) }), _jsx(ToolbarButton, { label: "Underline", icon: BsTypeUnderline, disabled: disabled, active: editor?.isActive("underline"), onClick: () => run((e) => e.chain().focus().toggleUnderline().run()) }), _jsx(ToolbarButton, { label: "Strikethrough", icon: BsTypeStrikethrough, disabled: disabled, active: editor?.isActive("strike"), onClick: () => run((e) => e.chain().focus().toggleStrike().run()) }), _jsx(Divider, {}), _jsxs("label", { className: "w-8 h-8 flex items-center justify-center rounded-sm text-text-muted hover:bg-surface-alt hover:text-text cursor-pointer has-[:disabled]:opacity-40 has-[:disabled]:cursor-not-allowed", children: [_jsx(BsPaletteFill, { size: 16, "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: "Text color" }), _jsx("input", { type: "color", disabled: disabled, value: editor?.getAttributes("textStyle").color ?? "#000000", onChange: (e) => run((ed) => ed.chain().focus().setColor(e.target.value).run()), className: "sr-only" })] }), _jsx(ToolbarButton, { label: "Highlight", icon: BsHighlighter, disabled: disabled, active: editor?.isActive("highlight"), onClick: () => run((e) => e.chain().focus().toggleHighlight().run()) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Align left", icon: BsTextLeft, disabled: disabled, active: editor?.isActive({ textAlign: "left" }), onClick: () => run((e) => e.chain().focus().setTextAlign("left").run()) }), _jsx(ToolbarButton, { label: "Align center", icon: BsTextCenter, disabled: disabled, active: editor?.isActive({ textAlign: "center" }), onClick: () => run((e) => e.chain().focus().setTextAlign("center").run()) }), _jsx(ToolbarButton, { label: "Align right", icon: BsTextRight, disabled: disabled, active: editor?.isActive({ textAlign: "right" }), onClick: () => run((e) => e.chain().focus().setTextAlign("right").run()) }), _jsx(ToolbarButton, { label: "Justify", icon: BsJustify, disabled: disabled, active: editor?.isActive({ textAlign: "justify" }), onClick: () => run((e) => e.chain().focus().setTextAlign("justify").run()) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Bulleted list", icon: BsListUl, disabled: disabled, active: editor?.isActive("bulletList"), onClick: () => run((e) => e.chain().focus().toggleBulletList().run()) }), _jsx(ToolbarButton, { label: "Numbered list", icon: BsListOl, disabled: disabled, active: editor?.isActive("orderedList"), onClick: () => run((e) => e.chain().focus().toggleOrderedList().run()) }), _jsx(ToolbarButton, { label: "Decrease indent", icon: BsUnindent, disabled: disabled, onClick: () => run((e) => e.chain().focus().liftListItem("listItem").run()) }), _jsx(ToolbarButton, { label: "Increase indent", icon: BsIndent, disabled: disabled, onClick: () => run((e) => e.chain().focus().sinkListItem("listItem").run()) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Insert link", icon: BsLink45Deg, disabled: disabled, active: editor?.isActive("link"), onClick: openLinkPrompt }), _jsx(ToolbarButton, { label: "Insert image", icon: BsImage, disabled: disabled, onClick: () => imageInputRef.current?.click() }), _jsx("input", { ref: imageInputRef, type: "file", accept: "image/*", onChange: handleImageFileSelected, className: "sr-only", "aria-label": "Insert image file" }), _jsx(ToolbarButton, { label: "Insert table", icon: BsTable, disabled: disabled, onClick: () => run((e) => e.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()) }), _jsx("button", { ref: emojiButtonRef, type: "button", "aria-label": "Insert emoji", title: "Insert emoji", disabled: disabled, onClick: () => setOpenPopup((p) => (p === "emoji" ? null : "emoji")), className: "w-8 h-8 flex items-center justify-center text-base rounded-sm disabled:opacity-40 disabled:cursor-not-allowed text-text-muted hover:bg-surface-alt hover:text-text", children: "\uD83D\uDE00" }), openPopup === "emoji" && (_jsx(EmojiPicker, { anchorRef: emojiButtonRef, onSelect: handleInsertEmoji, onClose: () => setOpenPopup(null) })), _jsx("button", { ref: gifButtonRef, type: "button", "aria-label": "Insert GIF", title: "Insert GIF", disabled: disabled, onClick: () => setOpenPopup((p) => (p === "gif" ? null : "gif")), className: "w-8 h-8 flex items-center justify-center text-[10px] font-extrabold tracking-tight rounded-sm disabled:opacity-40 disabled:cursor-not-allowed text-text-muted hover:bg-surface-alt hover:text-text", children: "GIF" }), openPopup === "gif" && _jsx(GifPicker, { anchorRef: gifButtonRef, onSelect: handleInsertGif, onClose: () => setOpenPopup(null) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Clear formatting", icon: BsEraser, disabled: disabled, onClick: () => run((e) => e.chain().focus().unsetAllMarks().clearNodes().run()) }), _jsx(ToolbarButton, { label: "Undo", icon: BsArrowCounterclockwise, disabled: disabled || !editor?.can().undo(), onClick: () => run((e) => e.chain().focus().undo().run()) }), _jsx(ToolbarButton, { label: "Redo", icon: BsArrowClockwise, disabled: disabled || !editor?.can().redo(), onClick: () => run((e) => e.chain().focus().redo().run()) })] }), linkPrompt] }));
|
|
88
|
+
: ed.chain().focus().unsetFontSize().run()), className: "text-xs py-1 px-1.5 border border-border rounded-sm bg-surface disabled:opacity-40", children: FONT_SIZES.map((f) => (_jsx("option", { value: f.value, children: f.label }, f.label))) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Bold", icon: BsTypeBold, disabled: disabled, active: editor?.isActive("bold"), onClick: () => run((e) => e.chain().focus().toggleBold().run()) }), _jsx(ToolbarButton, { label: "Italic", icon: BsTypeItalic, disabled: disabled, active: editor?.isActive("italic"), onClick: () => run((e) => e.chain().focus().toggleItalic().run()) }), _jsx(ToolbarButton, { label: "Underline", icon: BsTypeUnderline, disabled: disabled, active: editor?.isActive("underline"), onClick: () => run((e) => e.chain().focus().toggleUnderline().run()) }), _jsx(ToolbarButton, { label: "Strikethrough", icon: BsTypeStrikethrough, disabled: disabled, active: editor?.isActive("strike"), onClick: () => run((e) => e.chain().focus().toggleStrike().run()) }), _jsx(Divider, {}), _jsxs("label", { className: "w-8 h-8 flex items-center justify-center rounded-sm text-text-muted hover:bg-surface-alt hover:text-text cursor-pointer has-[:disabled]:opacity-40 has-[:disabled]:cursor-not-allowed", children: [_jsx(BsPaletteFill, { size: 16, "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: "Text color" }), _jsx("input", { type: "color", disabled: disabled, value: editor?.getAttributes("textStyle").color ?? "#000000", onChange: (e) => run((ed) => ed.chain().focus().setColor(e.target.value).run()), className: "sr-only" })] }), _jsx(ToolbarButton, { label: "Highlight", icon: BsHighlighter, disabled: disabled, active: editor?.isActive("highlight"), onClick: () => run((e) => e.chain().focus().toggleHighlight().run()) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Align left", icon: BsTextLeft, disabled: disabled, active: editor?.isActive({ textAlign: "left" }), onClick: () => run((e) => e.chain().focus().setTextAlign("left").run()) }), _jsx(ToolbarButton, { label: "Align center", icon: BsTextCenter, disabled: disabled, active: editor?.isActive({ textAlign: "center" }), onClick: () => run((e) => e.chain().focus().setTextAlign("center").run()) }), _jsx(ToolbarButton, { label: "Align right", icon: BsTextRight, disabled: disabled, active: editor?.isActive({ textAlign: "right" }), onClick: () => run((e) => e.chain().focus().setTextAlign("right").run()) }), _jsx(ToolbarButton, { label: "Justify", icon: BsJustify, disabled: disabled, active: editor?.isActive({ textAlign: "justify" }), onClick: () => run((e) => e.chain().focus().setTextAlign("justify").run()) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Bulleted list", icon: BsListUl, disabled: disabled, active: editor?.isActive("bulletList"), onClick: () => run((e) => e.chain().focus().toggleBulletList().run()) }), _jsx(ToolbarButton, { label: "Numbered list", icon: BsListOl, disabled: disabled, active: editor?.isActive("orderedList"), onClick: () => run((e) => e.chain().focus().toggleOrderedList().run()) }), _jsx(ToolbarButton, { label: "Decrease indent", icon: BsUnindent, disabled: disabled, onClick: () => run((e) => e.chain().focus().liftListItem("listItem").run()) }), _jsx(ToolbarButton, { label: "Increase indent", icon: BsIndent, disabled: disabled, onClick: () => run((e) => e.chain().focus().sinkListItem("listItem").run()) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Insert link", icon: BsLink45Deg, disabled: disabled, active: editor?.isActive("link"), onClick: openLinkPrompt }), _jsx(ToolbarButton, { label: "Insert image", icon: BsImage, disabled: disabled, onClick: () => imageInputRef.current?.click() }), _jsx("input", { ref: imageInputRef, type: "file", accept: "image/*", onChange: handleImageFileSelected, className: "sr-only", "aria-label": "Insert image file" }), _jsx(ToolbarButton, { label: "Insert table", icon: BsTable, disabled: disabled, onClick: () => run((e) => e.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()) }), _jsx("button", { ref: emojiButtonRef, type: "button", "aria-label": "Insert emoji", title: "Insert emoji", disabled: disabled, onClick: () => setOpenPopup((p) => (p === "emoji" ? null : "emoji")), className: "w-8 h-8 flex items-center justify-center text-base rounded-sm disabled:opacity-40 disabled:cursor-not-allowed text-text-muted hover:bg-surface-alt hover:text-text", children: "\uD83D\uDE00" }), openPopup === "emoji" && (_jsx(Suspense, { fallback: null, children: _jsx(EmojiPicker, { anchorRef: emojiButtonRef, onSelect: handleInsertEmoji, onClose: () => setOpenPopup(null) }) })), _jsx("button", { ref: gifButtonRef, type: "button", "aria-label": "Insert GIF", title: "Insert GIF", disabled: disabled, onClick: () => setOpenPopup((p) => (p === "gif" ? null : "gif")), className: "w-8 h-8 flex items-center justify-center text-[10px] font-extrabold tracking-tight rounded-sm disabled:opacity-40 disabled:cursor-not-allowed text-text-muted hover:bg-surface-alt hover:text-text", children: "GIF" }), openPopup === "gif" && _jsx(GifPicker, { anchorRef: gifButtonRef, onSelect: handleInsertGif, onClose: () => setOpenPopup(null) }), _jsx(Divider, {}), _jsx(ToolbarButton, { label: "Clear formatting", icon: BsEraser, disabled: disabled, onClick: () => run((e) => e.chain().focus().unsetAllMarks().clearNodes().run()) }), _jsx(ToolbarButton, { label: "Undo", icon: BsArrowCounterclockwise, disabled: disabled || !editor?.can().undo(), onClick: () => run((e) => e.chain().focus().undo().run()) }), _jsx(ToolbarButton, { label: "Redo", icon: BsArrowClockwise, disabled: disabled || !editor?.can().redo(), onClick: () => run((e) => e.chain().focus().redo().run()) })] }), linkPrompt] }));
|
|
88
89
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type
|
|
2
|
+
import { type ComposeSession } from "./ComposeContext.js";
|
|
3
3
|
export interface ComposeWindowProps {
|
|
4
4
|
session: ComposeSession;
|
|
5
5
|
onClose: () => void;
|
|
@@ -18,7 +18,8 @@ export interface ComposeWindowProps {
|
|
|
18
18
|
}
|
|
19
19
|
/** Debounce between the last edit and the draft autosave. */
|
|
20
20
|
export declare const DEFAULT_AUTOSAVE_DELAY_MS = 2000;
|
|
21
|
-
/** Automatic retries of a failed mailbox/encryption-policy
|
|
21
|
+
/** Automatic, silent retries of a failed mailbox/encryption-policy (or recipient key) load, one entry per retry - a flapping gateway is waited out
|
|
22
|
+
* in the background, without a word to the user. */
|
|
22
23
|
export declare const DEFAULT_CRYPTO_RETRY_DELAYS_MS: number[];
|
|
23
24
|
/**
|
|
24
25
|
* A floating, Gmail-style compose window — overlays whatever app is currently showing instead of
|