mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 16:13:15 +00:00
fix: keep a quick reply as a draft when an automatic sign-out comes while the external recipient question is open
This commit is contained in:
@@ -62,3 +62,31 @@ describe('quick reply', () => {
|
||||
expect(box.value).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('automatic sign-out while the external recipient question is open', () => {
|
||||
it('answers Back and keeps the typed reply as a draft, without asking again', async () => {
|
||||
const { useExternalRecipientConfirmStore } = await import('@/stores/external-recipient-confirm-store');
|
||||
const { flushComposers, resetComposeFlushRegistry } = await import('@/lib/compose-flush-registry');
|
||||
resetComposeFlushRegistry();
|
||||
useExternalRecipientConfirmStore.setState({ pending: null, queue: [] });
|
||||
const onQuickReply = vi.fn((body: string) => {
|
||||
void body;
|
||||
return useExternalRecipientConfirmStore.getState().ask([{ address: 'org-dave@org-two.test', domain: 'org-two.test', field: 'to' }]);
|
||||
});
|
||||
const onSaveQuickReplyDraft = vi.fn(async () => {});
|
||||
render(<EmailViewer email={message} isLoading={false} mailboxes={mailboxes} selectedMailbox="inbox" currentMailboxRole="inbox"
|
||||
onQuickReply={onQuickReply} onSaveQuickReplyDraft={onSaveQuickReplyDraft} />);
|
||||
await act(async () => { await new Promise((r) => setTimeout(r, 10)); });
|
||||
const box = screen.getByPlaceholderText('quick_reply_placeholder') as HTMLTextAreaElement;
|
||||
fireEvent.focus(box);
|
||||
fireEvent.change(box, { target: { value: 'My answer' } });
|
||||
fireEvent.click(screen.getByRole('button', { name: 'send' }));
|
||||
await waitFor(() => expect(useExternalRecipientConfirmStore.getState().pending).not.toBeNull());
|
||||
|
||||
await act(async () => { await flushComposers(2000); });
|
||||
expect(onSaveQuickReplyDraft).toHaveBeenCalledWith('My answer');
|
||||
expect(useExternalRecipientConfirmStore.getState().pending).toBeNull();
|
||||
expect(box.value).toBe('My answer');
|
||||
expect(onQuickReply).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -103,6 +103,7 @@ import { useSettingsStore } from "@/stores/settings-store";
|
||||
import { useShallow } from "zustand/react/shallow";
|
||||
import { useEffectiveMailLayout } from "@/hooks/use-effective-mail-layout";
|
||||
import { registerComposeFlush } from "@/lib/compose-flush-registry";
|
||||
import { useExternalRecipientConfirmStore } from "@/stores/external-recipient-confirm-store";
|
||||
import { useUIStore } from "@/stores/ui-store";
|
||||
import { useContactStore, getContactDisplayName, getContactPrimaryEmail } from "@/stores/contact-store";
|
||||
import { toast } from "@/stores/toast-store";
|
||||
@@ -1377,7 +1378,9 @@ export function EmailViewer({
|
||||
const [isQuickReplyFocused, setIsQuickReplyFocused] = useState(false);
|
||||
const [isSendingQuickReply, setIsSendingQuickReply] = useState(false);
|
||||
// An automatic sign-out keeps typed quick-reply text as a draft; text on
|
||||
// its way out as a reply needs none.
|
||||
// its way out as a reply needs none. A reply still waiting on the
|
||||
// "Send outside your organisation?" question hasn't gone out: the question
|
||||
// is answered with Back and the text kept as a draft.
|
||||
const quickReplyDraftRef = useRef({ text: quickReplyText, sending: isSendingQuickReply, save: onSaveQuickReplyDraft });
|
||||
quickReplyDraftRef.current = { text: quickReplyText, sending: isSendingQuickReply, save: onSaveQuickReplyDraft };
|
||||
const hasQuickReplyDraft = quickReplyText.trim().length > 0 && !!onSaveQuickReplyDraft;
|
||||
@@ -1385,7 +1388,12 @@ export function EmailViewer({
|
||||
if (!hasQuickReplyDraft) return;
|
||||
return registerComposeFlush(async () => {
|
||||
const { text, sending, save } = quickReplyDraftRef.current;
|
||||
if (sending || !text.trim() || !save) return;
|
||||
if (!text.trim() || !save) return;
|
||||
if (sending) {
|
||||
const confirm = useExternalRecipientConfirmStore.getState();
|
||||
if (!confirm.pending) return;
|
||||
confirm.cancelAll();
|
||||
}
|
||||
await save(text);
|
||||
});
|
||||
}, [hasQuickReplyDraft]);
|
||||
|
||||
Reference in New Issue
Block a user