@rapidmx/web-client 0.10.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 +183 -2
- 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/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/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/contacts/ContactForm.tsx +11 -5
- package/apps/shared/components/contacts/ContactsSidebar.tsx +5 -3
- package/apps/shared/components/contacts/ContactsToolbar.tsx +25 -52
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +10 -5
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +13 -6
- package/apps/shared/components/layout/AppShell.tsx +98 -32
- package/apps/shared/components/layout/BrandingChrome.tsx +200 -13
- 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 +75 -6
- package/apps/shared/components/mail/ConversationList.tsx +4 -2
- package/apps/shared/components/mail/ConversationThreadPane.tsx +487 -475
- package/apps/shared/components/mail/LazyReadingPane.tsx +14 -16
- package/apps/shared/components/mail/MailSelectionBar.tsx +2 -10
- package/apps/shared/components/mail/MessageDetailPane.tsx +366 -287
- 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 +35 -2
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +239 -437
- package/apps/shared/components/mail/compose/encryptionRequirement.ts +86 -0
- package/apps/shared/components/mail/layout/MailShell.tsx +39 -25
- 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/settings/SigningCertificateCard.tsx +344 -0
- package/apps/shared/components/settings/layout/SettingsShell.tsx +1 -0
- 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 +9 -5
- package/apps/shared/mail/folderCounts.ts +9 -3
- package/apps/shared/mail/folderTree.ts +143 -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 +81 -28
- package/apps/shared/mail/useMailLiveUpdates.ts +55 -10
- package/apps/shared/mail/useNewMailNotifications.ts +47 -32
- package/apps/shared/navigation/AppRouter.tsx +2 -2
- 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/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 +80 -0
- package/apps/www/_layout.tsx +8 -2
- package/apps/www/_routes.ts +1 -0
- package/apps/www/calendar/index.tsx +9 -14
- package/apps/www/contacts/[uid].tsx +5 -8
- package/apps/www/contacts/index.tsx +587 -584
- package/apps/www/index.tsx +38 -27
- package/apps/www/messages/[uid].tsx +3 -1
- package/apps/www/settings/appearance/index.tsx +21 -0
- package/apps/www/settings/auto-reply/index.tsx +3 -7
- package/apps/www/settings/encryption/index.tsx +151 -116
- package/apps/www/settings/filters/[uid].tsx +3 -1
- package/apps/www/settings/filters/new/index.tsx +3 -1
- package/apps/www/settings/privacy/index.tsx +3 -8
- package/apps/www/settings/read-receipts/index.tsx +3 -7
- package/apps/www/settings/sharing/index.tsx +44 -65
- package/apps/www/settings/signatures/[uid].tsx +3 -1
- package/apps/www/settings/signatures/new/index.tsx +3 -2
- package/apps/www/tasks/index.tsx +11 -16
- 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/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/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/contacts/ContactForm.js +1 -1
- package/dist/apps/shared/components/contacts/ContactsSidebar.js +4 -2
- package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +3 -1
- package/dist/apps/shared/components/contacts/ContactsToolbar.js +24 -9
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +4 -1
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +7 -4
- package/dist/apps/shared/components/layout/AppShell.d.ts +6 -1
- package/dist/apps/shared/components/layout/AppShell.js +59 -13
- 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/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 +7 -1
- package/dist/apps/shared/components/layout/UserMenu.js +41 -7
- package/dist/apps/shared/components/mail/ConversationList.js +3 -2
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +2 -1
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +42 -20
- package/dist/apps/shared/components/mail/LazyReadingPane.js +9 -8
- package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +3 -4
- package/dist/apps/shared/components/mail/MailSelectionBar.js +2 -3
- package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +18 -7
- package/dist/apps/shared/components/mail/MessageDetailPane.js +86 -41
- 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 +8 -0
- package/dist/apps/shared/components/mail/compose/ComposeContext.js +28 -3
- package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +2 -1
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +229 -328
- 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/layout/MailShell.d.ts +2 -0
- package/dist/apps/shared/components/mail/layout/MailShell.js +20 -14
- 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/settings/SigningCertificateCard.d.ts +32 -0
- package/dist/apps/shared/components/settings/SigningCertificateCard.js +98 -0
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +1 -0
- 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.js +3 -1
- package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
- package/dist/apps/shared/mail/folderCounts.js +9 -3
- package/dist/apps/shared/mail/folderTree.d.ts +55 -0
- package/dist/apps/shared/mail/folderTree.js +116 -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 +9 -8
- package/dist/apps/shared/mail/useMailConnection.js +64 -22
- package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +17 -4
- package/dist/apps/shared/mail/useMailLiveUpdates.js +36 -10
- package/dist/apps/shared/mail/useNewMailNotifications.d.ts +4 -10
- package/dist/apps/shared/mail/useNewMailNotifications.js +43 -23
- package/dist/apps/shared/navigation/AppRouter.js +2 -2
- 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/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 +80 -0
- package/dist/apps/www/_layout.d.ts +5 -1
- package/dist/apps/www/_layout.js +3 -2
- package/dist/apps/www/_routes.js +1 -0
- package/dist/apps/www/calendar/index.js +3 -4
- package/dist/apps/www/contacts/[uid].js +5 -7
- package/dist/apps/www/contacts/index.js +14 -21
- package/dist/apps/www/index.js +37 -19
- package/dist/apps/www/messages/[uid].js +3 -1
- 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.js +3 -6
- package/dist/apps/www/settings/encryption/index.js +103 -95
- package/dist/apps/www/settings/filters/[uid].js +3 -1
- package/dist/apps/www/settings/filters/new/index.js +3 -1
- package/dist/apps/www/settings/privacy/index.js +5 -8
- package/dist/apps/www/settings/read-receipts/index.js +3 -6
- package/dist/apps/www/settings/sharing/index.js +19 -33
- package/dist/apps/www/settings/signatures/[uid].js +3 -1
- package/dist/apps/www/settings/signatures/new/index.js +3 -2
- package/dist/apps/www/tasks/index.js +8 -14
- package/package.json +2 -2
- package/apps/shared/components/mail/NewMailToasts.tsx +0 -141
- package/apps/shared/components/mail/compose/SendFailureAlert.tsx +0 -48
- package/dist/apps/shared/components/mail/NewMailToasts.d.ts +0 -19
- package/dist/apps/shared/components/mail/NewMailToasts.js +0 -55
- package/dist/apps/shared/components/mail/compose/SendFailureAlert.d.ts +0 -14
- package/dist/apps/shared/components/mail/compose/SendFailureAlert.js +0 -11
package/apps/www/index.tsx
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
createFolder,
|
|
21
21
|
getMessage,
|
|
22
22
|
getMessageRawContent,
|
|
23
|
+
listFolders,
|
|
23
24
|
listMessages,
|
|
24
25
|
moveMessages,
|
|
25
26
|
setMessagesFlagged,
|
|
@@ -46,6 +47,7 @@ import MailShell, {
|
|
|
46
47
|
useMailShell,
|
|
47
48
|
} from "../shared/components/mail/layout/MailShell.js";
|
|
48
49
|
import MailAddress from "../shared/components/mail/MailAddress.js";
|
|
50
|
+
import OutboxRowStatus from "../shared/components/mail/OutboxRowStatus.js";
|
|
49
51
|
import { mergeFirstPage } from "../shared/mail/mergeFirstPage.js";
|
|
50
52
|
import { listSnapshotKey, readListSnapshot, saveListScroll, writeListSnapshot } from "../shared/mail/listSnapshots.js";
|
|
51
53
|
import { setReadStateMany } from "../shared/mail/messageReadState.js";
|
|
@@ -53,6 +55,7 @@ import { useMarkMessageRead } from "../shared/mail/useMarkMessageRead.js";
|
|
|
53
55
|
import { ROW_FOCUS_CLASS, UnreadBar, UnreadLabel, dateClass, isUnread, rowClass, senderClass, subjectClass } from "../shared/components/mail/unreadStyle.js";
|
|
54
56
|
import { LazyConversationThreadPane, LazyMessageDetailPane, prefetchReadingPane } from "../shared/components/mail/LazyReadingPane.js";
|
|
55
57
|
import ConversationList from "../shared/components/mail/ConversationList.js";
|
|
58
|
+
import { EncryptedPreview } from "../shared/components/mail/reading/EncryptedPreview.js";
|
|
56
59
|
import MailListToolbar from "../shared/components/mail/MailListToolbar.js";
|
|
57
60
|
import MailSelectionBar from "../shared/components/mail/MailSelectionBar.js";
|
|
58
61
|
import {
|
|
@@ -70,6 +73,7 @@ import { useUnlockPrompt } from "../shared/components/layout/UnlockPromptProvide
|
|
|
70
73
|
import { SHORTCUTS } from "../shared/keyboard/keymap.js";
|
|
71
74
|
import { isActivatable } from "../shared/keyboard/targets.js";
|
|
72
75
|
import { useShortcut } from "../shared/keyboard/useShortcut.js";
|
|
76
|
+
import { notifyApiError } from "../shared/notifications/apiErrors.js";
|
|
73
77
|
|
|
74
78
|
const MESSAGE_PAGE_SIZE = 50;
|
|
75
79
|
const SEARCH_DEBOUNCE_MS = 300;
|
|
@@ -461,7 +465,7 @@ function InboxPage(props: MailShellProps) {
|
|
|
461
465
|
}
|
|
462
466
|
|
|
463
467
|
function InboxContent({ userUid }: { userUid?: string }) {
|
|
464
|
-
const { folderUid, mailboxUid, mailboxes, mailboxFolders, aggregateFolderType, onFolderCreated, live, trackMessageChange } = useMailShell();
|
|
468
|
+
const { folderUid, mailboxUid, mailboxes, mailboxFolders, aggregateFolderType, onFolderCreated, noteFolderUids, live, trackMessageChange } = useMailShell();
|
|
465
469
|
const isMobile = useIsMobile();
|
|
466
470
|
const navigate = useNavigate();
|
|
467
471
|
const { requestUnlock } = useUnlockPrompt();
|
|
@@ -503,7 +507,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
503
507
|
// or it would act on a selection that is still arriving.
|
|
504
508
|
const [resolvingSelection, setResolvingSelection] = useState(0);
|
|
505
509
|
const [bulkBusy, setBulkBusy] = useState(false);
|
|
506
|
-
const [bulkError, setBulkError] = useState<string | null>(null);
|
|
507
510
|
// Bumped to force the list effect below to re-run - a bulk update is deliberately neither atomic nor
|
|
508
511
|
// all-or-nothing (see `bulkUpdateMessages()`), so a rejection means refetching rather than guessing
|
|
509
512
|
// which half of the selection actually landed.
|
|
@@ -1120,10 +1123,18 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1120
1123
|
unlockRefresh,
|
|
1121
1124
|
searchAllMail,
|
|
1122
1125
|
aggregateFolderType,
|
|
1123
|
-
|
|
1126
|
+
// Only a merged view is built from the folder tree; for a single folder a folder appearing in the sidebar (the Outbox, Sent Items) must not reload
|
|
1127
|
+
// the list on screen and forget its selection.
|
|
1128
|
+
aggregateFolderType ? mailboxFolders : null,
|
|
1124
1129
|
activeMailboxUid,
|
|
1125
1130
|
]);
|
|
1126
1131
|
|
|
1132
|
+
// Which folders the messages on screen live in: one the sidebar does not know (the Outbox and Sent Items are made by the server on first use) is looked for -
|
|
1133
|
+
// its mailbox's folders are listed again, once - so it appears without a reload. A conversation names every folder it has a message in.
|
|
1134
|
+
useEffect(() => {
|
|
1135
|
+
noteFolderUids([...messages.map((message) => message.folderUid), ...conversations.flatMap((conversation) => conversation.folderUids)]);
|
|
1136
|
+
}, [messages, conversations, noteFolderUids]);
|
|
1137
|
+
|
|
1127
1138
|
// New mail without a reload. `live` is bumped by a push event, a reconnect, the safety-net poll or the tab coming back (see
|
|
1128
1139
|
// `useMailLiveUpdates()`); this then quietly refetches the first page of whatever is listed and folds it in - unlike the
|
|
1129
1140
|
// effect above it resets nothing: not the selection, the open thread, select mode, the scroll position or the rows
|
|
@@ -1454,7 +1465,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1454
1465
|
setSelectMode(false);
|
|
1455
1466
|
setSelectedUids(new Set());
|
|
1456
1467
|
setSelectedConversationIds(new Set());
|
|
1457
|
-
setBulkError(null);
|
|
1458
1468
|
}
|
|
1459
1469
|
|
|
1460
1470
|
function toggleSelected(uid: string) {
|
|
@@ -1471,7 +1481,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1471
1481
|
|
|
1472
1482
|
/** Loads (once) the messages behind each of `ids`, so a ticked conversation resolves to the messages
|
|
1473
1483
|
* every bulk action below acts on. If any of them fails to load, none of that batch stays ticked and
|
|
1474
|
-
*
|
|
1484
|
+
* a pop-up says why - better than acting on the part of a selection that happened to arrive. */
|
|
1475
1485
|
async function resolveConversations(ids: string[]) {
|
|
1476
1486
|
const missing = ids.filter((id) => !conversationMessagesById[id]);
|
|
1477
1487
|
if (missing.length === 0) {
|
|
@@ -1484,9 +1494,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1484
1494
|
);
|
|
1485
1495
|
setConversationMessagesById((prev) => ({ ...prev, ...Object.fromEntries(loaded) }));
|
|
1486
1496
|
} catch (err) {
|
|
1487
|
-
|
|
1488
|
-
err instanceof ApiRequestError ? err.message : "Could not load the messages in one of those conversations.",
|
|
1489
|
-
);
|
|
1497
|
+
notifyApiError(err, "Couldn't load the messages in one of those conversations");
|
|
1490
1498
|
setSelectedConversationIds((prev) => {
|
|
1491
1499
|
const next = new Set(prev);
|
|
1492
1500
|
for (const id of missing) {
|
|
@@ -1528,7 +1536,8 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1528
1536
|
*
|
|
1529
1537
|
* A bulk update is applied element by element server-side and stops at its first rejection, so a
|
|
1530
1538
|
* failure leaves an unknown prefix of the selection already changed (see `bulkUpdateMessages()`) -
|
|
1531
|
-
* which is why a failure reloads the list rather than trying to reconcile it, and says so
|
|
1539
|
+
* which is why a failure reloads the list rather than trying to reconcile it, and says so ("all of those messages" in the pop-up's
|
|
1540
|
+
* title: some may have changed).
|
|
1532
1541
|
*
|
|
1533
1542
|
* `chosen` is the selection bar's ticked messages unless the caller (a keyboard shortcut acting on the one open message or conversation)
|
|
1534
1543
|
* names its own. Resolves whether it succeeded.
|
|
@@ -1539,7 +1548,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1539
1548
|
chosen: Message[] = selectedMessages,
|
|
1540
1549
|
): Promise<boolean> {
|
|
1541
1550
|
setBulkBusy(true);
|
|
1542
|
-
setBulkError(null);
|
|
1543
1551
|
try {
|
|
1544
1552
|
const updated = await action(chosen);
|
|
1545
1553
|
if (removesRows) {
|
|
@@ -1569,9 +1577,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1569
1577
|
setSelectedUids(new Set());
|
|
1570
1578
|
return true;
|
|
1571
1579
|
} catch (err) {
|
|
1572
|
-
|
|
1573
|
-
`${err instanceof ApiRequestError ? err.message : "Those messages couldn't all be updated."} Some of them may already have changed, so the list has been reloaded.`,
|
|
1574
|
-
);
|
|
1580
|
+
notifyApiError(err, chosen.length === 1 ? "Couldn't update the message" : "Couldn't update all of those messages");
|
|
1575
1581
|
setSelectedUids(new Set());
|
|
1576
1582
|
setSelectedConversationIds(new Set());
|
|
1577
1583
|
setConversationMessagesById({});
|
|
@@ -1596,12 +1602,13 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1596
1602
|
}
|
|
1597
1603
|
|
|
1598
1604
|
/**
|
|
1599
|
-
* This mailbox's folder of `type
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1605
|
+
* This mailbox's folder of `type`. The server makes every well-known folder itself (when the mailbox is made, and again when the folders are listed
|
|
1606
|
+
* if one is missing), so a folder the page's tree lacks is asked for - the tree may simply be out of date - and used, never created a second time: a
|
|
1607
|
+
* duplicate of a well-known type is invisible to the server (it answers with the oldest) but would be a second row in the sidebar. Only a server that
|
|
1608
|
+
* really has none (an older one, which makes Deleted Items and Junk on first use) is asked to create it.
|
|
1602
1609
|
*
|
|
1603
|
-
* A folder created here
|
|
1604
|
-
*
|
|
1610
|
+
* A folder found or created here may not be in `mailboxFolders` yet, so it is filed there and remembered per mailbox and type until the page
|
|
1611
|
+
* reloads; otherwise a second Delete would ask again.
|
|
1605
1612
|
*/
|
|
1606
1613
|
async function resolveFolderOfType(type: Folder["type"], name: string): Promise<string> {
|
|
1607
1614
|
const key = `${activeMailboxUid}:${type}`;
|
|
@@ -1609,6 +1616,12 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1609
1616
|
if (known) {
|
|
1610
1617
|
return known;
|
|
1611
1618
|
}
|
|
1619
|
+
const listed = (await listFolders(activeMailboxUid)).find((f) => f.type === type);
|
|
1620
|
+
if (listed) {
|
|
1621
|
+
onFolderCreated(listed);
|
|
1622
|
+
lazyFoldersRef.current.set(key, listed.uid);
|
|
1623
|
+
return listed.uid;
|
|
1624
|
+
}
|
|
1612
1625
|
const created = await createFolder({ mailboxUid: activeMailboxUid, name, type });
|
|
1613
1626
|
lazyFoldersRef.current.set(key, created.uid);
|
|
1614
1627
|
return created.uid;
|
|
@@ -1784,7 +1797,7 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1784
1797
|
try {
|
|
1785
1798
|
chosen = selectMode ? selectedMessages : inConversations ? await loadOpenConversation(openThread!.conversation) : [selected!];
|
|
1786
1799
|
} catch (err) {
|
|
1787
|
-
|
|
1800
|
+
notifyApiError(err, "Couldn't load the messages in that conversation");
|
|
1788
1801
|
return;
|
|
1789
1802
|
}
|
|
1790
1803
|
chosen = chosen.filter(applies);
|
|
@@ -1934,7 +1947,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
1934
1947
|
onReportJunk={() => void moveSelectionToType("junk", "Junk Email")}
|
|
1935
1948
|
onDelete={() => void moveSelectionToType("deleted_items", "Deleted Items")}
|
|
1936
1949
|
busy={bulkBusy || resolvingSelection > 0}
|
|
1937
|
-
error={bulkError}
|
|
1938
1950
|
/>
|
|
1939
1951
|
) : (
|
|
1940
1952
|
<MailListToolbar
|
|
@@ -2079,12 +2091,6 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
2079
2091
|
<Alert>{error}</Alert>
|
|
2080
2092
|
</div>
|
|
2081
2093
|
)}
|
|
2082
|
-
{/* Select mode shows a bulk action's failure in its own bar; the keyboard's actions on the one open message need somewhere too. */}
|
|
2083
|
-
{!selectMode && bulkError && (
|
|
2084
|
-
<div className="p-4">
|
|
2085
|
-
<Alert>{bulkError}</Alert>
|
|
2086
|
-
</div>
|
|
2087
|
-
)}
|
|
2088
2094
|
|
|
2089
2095
|
{loading ? (
|
|
2090
2096
|
// A skeleton of rows rather than a line of text: the list keeps its shape while a folder that was not shown a
|
|
@@ -2189,13 +2195,18 @@ function InboxContent({ userUid }: { userUid?: string }) {
|
|
|
2189
2195
|
</div>
|
|
2190
2196
|
<div className="flex items-center gap-2 text-xs text-text-muted font-normal">
|
|
2191
2197
|
<span className="truncate">
|
|
2192
|
-
{snippets[message.uid] ||
|
|
2198
|
+
{snippets[message.uid] ||
|
|
2199
|
+
decryptedRows[message.uid]?.preview ||
|
|
2200
|
+
message.bodyPreview ||
|
|
2201
|
+
(message.encrypted ? <EncryptedPreview /> : null)}
|
|
2193
2202
|
</span>
|
|
2194
2203
|
{message.hasAttachments && <HiOutlinePaperClip size={12} aria-label="Has attachments" />}
|
|
2195
2204
|
{message.flags.flagged && (
|
|
2196
2205
|
<HiOutlineFlag size={12} aria-label="Flagged" className="text-danger" />
|
|
2197
2206
|
)}
|
|
2198
2207
|
</div>
|
|
2208
|
+
{/* What the server is doing with a message in Outbox: sending, retrying, or why it wasn't sent. */}
|
|
2209
|
+
{isOutbox && <OutboxRowStatus message={message} />}
|
|
2199
2210
|
</>
|
|
2200
2211
|
)}
|
|
2201
2212
|
</button>
|
|
@@ -11,6 +11,7 @@ import { useMessageAttachments } from "@rapidmx/react-shared/mail/mailDetailHook
|
|
|
11
11
|
import { useMarkMessageRead } from "../../shared/mail/useMarkMessageRead.js";
|
|
12
12
|
import MailShell, { MailShellProps, useMailShell } from "../../shared/components/mail/layout/MailShell.js";
|
|
13
13
|
import { LazyMessageDetailPane } from "../../shared/components/mail/LazyReadingPane.js";
|
|
14
|
+
import { ReadingPaneSkeleton } from "../../shared/components/mail/reading/MessageCard.js";
|
|
14
15
|
import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -66,7 +67,8 @@ function MessageDetailContent({ uid }: { uid: string }) {
|
|
|
66
67
|
useMarkMessageRead(message, setMessage);
|
|
67
68
|
|
|
68
69
|
if (loading) {
|
|
69
|
-
|
|
70
|
+
// The pane's own frame - a header card and a message card - rather than a line of text: what is coming is known, only not yet its contents.
|
|
71
|
+
return <ReadingPaneSkeleton />;
|
|
70
72
|
}
|
|
71
73
|
if (error || !message) {
|
|
72
74
|
return <Alert>{error ?? "Message not found."}</Alert>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
import { routedPage } from "../../_routedPage.js";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import SettingsShell, { SettingsShellProps } from "../../../shared/components/settings/layout/SettingsShell.js";
|
|
8
|
+
import AppearanceForm from "../../../shared/appearance/AppearanceForm.js";
|
|
9
|
+
|
|
10
|
+
export type SettingsAppearancePageProps = Omit<SettingsShellProps, "active">;
|
|
11
|
+
|
|
12
|
+
/** Settings > Appearance: the colour scheme, theme colours and background. Not mailbox-scoped - it is the signed-in user's own. */
|
|
13
|
+
function SettingsAppearancePage(props: SettingsAppearancePageProps) {
|
|
14
|
+
return (
|
|
15
|
+
<SettingsShell {...props} active="appearance">
|
|
16
|
+
<AppearanceForm />
|
|
17
|
+
</SettingsShell>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default routedPage("/settings/appearance", SettingsAppearancePage);
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
///////////////////////////////////////////////////////////////////////////////
|
|
5
5
|
import { routedPage } from "../../_routedPage.js";
|
|
6
6
|
import React, { FormEvent, useState } from "react";
|
|
7
|
-
import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
|
|
8
7
|
import { toDatetimeLocal } from "@rapidmx/react-shared/util/dateInput.js";
|
|
9
8
|
import { updateMailbox } from "@rapidmx/react-shared/mail/mailApi.js";
|
|
10
9
|
import SettingsShell, { SettingsShellProps, useSettingsShell } from "../../../shared/components/settings/layout/SettingsShell.js";
|
|
11
|
-
import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
|
|
12
10
|
import Button from "@rapidmx/react-shared/components/buttons/Button.js";
|
|
11
|
+
import { notifyApiError } from "../../../shared/notifications/apiErrors.js";
|
|
13
12
|
|
|
14
13
|
const INPUT_CLASS =
|
|
15
14
|
"w-full text-sm py-2 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
|
|
@@ -38,13 +37,11 @@ function AutoReplyContent() {
|
|
|
38
37
|
// `SettingsShell`'s `mailboxes` is fetched once - every save bumps the server's version, so a second
|
|
39
38
|
// save without a reload must send the version the previous save returned, not the stale original.
|
|
40
39
|
const [version, setVersion] = useState(mailbox.version);
|
|
41
|
-
const [error, setError] = useState<string | null>(null);
|
|
42
40
|
const [saving, setSaving] = useState(false);
|
|
43
41
|
const [saved, setSaved] = useState(false);
|
|
44
42
|
|
|
45
43
|
async function handleSubmit(e: FormEvent) {
|
|
46
44
|
e.preventDefault();
|
|
47
|
-
setError(null);
|
|
48
45
|
setSaved(false);
|
|
49
46
|
setSaving(true);
|
|
50
47
|
try {
|
|
@@ -60,7 +57,7 @@ function AutoReplyContent() {
|
|
|
60
57
|
setVersion(updated.version);
|
|
61
58
|
setSaved(true);
|
|
62
59
|
} catch (err) {
|
|
63
|
-
|
|
60
|
+
notifyApiError(err, "Couldn't save the automatic reply settings");
|
|
64
61
|
} finally {
|
|
65
62
|
setSaving(false);
|
|
66
63
|
}
|
|
@@ -75,8 +72,7 @@ function AutoReplyContent() {
|
|
|
75
72
|
calendar event with its own automatic reply enabled takes over for its own start/end window.
|
|
76
73
|
</p>
|
|
77
74
|
|
|
78
|
-
{
|
|
79
|
-
{saved && !error && <div className="mb-4 text-sm text-success font-medium">Saved.</div>}
|
|
75
|
+
{saved && <div className="mb-4 text-sm text-success font-medium">Saved.</div>}
|
|
80
76
|
|
|
81
77
|
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
|
82
78
|
<label className="flex items-center gap-2 text-sm font-medium">
|