mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-05 16:16:49 +00:00
fix: show the selection in the reading pane once rows beyond the open message are ticked
This commit is contained in:
@@ -37,8 +37,8 @@ vi.mock('@/components/ui/welcome-banner', () => ({
|
||||
useWelcomeBannerDue: () => false,
|
||||
}));
|
||||
vi.mock('@/components/email/email-viewer', () => ({
|
||||
EmailViewer: ({ emptyPaneContent, emptyPaneFooter }: { emptyPaneContent?: React.ReactNode; emptyPaneFooter?: React.ReactNode }) => (
|
||||
<div data-testid="viewer">{emptyPaneContent ?? <p>no conversation selected</p>}{emptyPaneFooter}</div>
|
||||
EmailViewer: ({ email, emptyPaneContent, emptyPaneFooter }: { email?: { id: string } | null; emptyPaneContent?: React.ReactNode; emptyPaneFooter?: React.ReactNode }) => (
|
||||
<div data-testid="viewer">{email ? <p>reading {email.id}</p> : <>{emptyPaneContent ?? <p>no conversation selected</p>}{emptyPaneFooter}</>}</div>
|
||||
),
|
||||
}));
|
||||
vi.mock('@/components/email/email-list', () => ({
|
||||
@@ -94,7 +94,7 @@ beforeEach(() => {
|
||||
viewingAccountId: null, accountMailboxes: {}, isUnifiedView: false, unifiedRole: null,
|
||||
isScheduledView: false, isLoadingEmail: false, isLoading: false, searchQuery: '',
|
||||
searchFilters: { ...DEFAULT_SEARCH_FILTERS }, searchMailboxId: '', isAdvancedSearchOpen: false,
|
||||
selectedEmailKeys: new Set(), unreadSection: null,
|
||||
selectedEmailKeys: new Set(), unreadSection: null, listRows: null,
|
||||
fetchMailboxes: vi.fn().mockResolvedValue(undefined), fetchEmails: vi.fn().mockResolvedValue(undefined),
|
||||
fetchQuota: vi.fn().mockResolvedValue(undefined), fetchTagCounts: vi.fn().mockResolvedValue(undefined),
|
||||
refreshScheduledMetadata: vi.fn().mockResolvedValue(undefined),
|
||||
@@ -138,6 +138,35 @@ describe('the reading pane for a selection', () => {
|
||||
expect(screen.getByTestId('viewer').contains(listProps.host!)).toBe(true);
|
||||
});
|
||||
|
||||
it('replaces the open message once other rows are ticked too (mail-p2-3)', () => {
|
||||
useEmailStore.setState({ selectedEmail: message, selectedEmailKeys: new Set(['m1', 'm2']) } as never);
|
||||
render(<MailApp />);
|
||||
expect(screen.queryByText('reading m1')).toBeNull();
|
||||
expect(listProps.host).toBeInstanceOf(HTMLElement);
|
||||
expect(screen.getByTestId('viewer').contains(listProps.host!)).toBe(true);
|
||||
});
|
||||
|
||||
it('replaces the open message when another single row is ticked', () => {
|
||||
useEmailStore.setState({ selectedEmail: message, selectedEmailKeys: new Set(['m2']) } as never);
|
||||
render(<MailApp />);
|
||||
expect(screen.queryByText('reading m1')).toBeNull();
|
||||
});
|
||||
|
||||
it('keeps the open message when only its own row is ticked', () => {
|
||||
useEmailStore.setState({ selectedEmail: message, selectedEmailKeys: new Set(['m1']) } as never);
|
||||
render(<MailApp />);
|
||||
expect(screen.getByText('reading m1')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('keeps the open message when its conversation row is ticked', () => {
|
||||
useEmailStore.setState({
|
||||
selectedEmail: message, selectedEmailKeys: new Set(['m1', 'm1-reply']),
|
||||
listRows: [{ key: 'm1', members: ['m1', 'm1-reply'] }, { key: 'm2', members: ['m2'] }],
|
||||
} as never);
|
||||
render(<MailApp />);
|
||||
expect(screen.getByText('reading m1')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('says nothing is selected without a selection', () => {
|
||||
render(<MailApp />);
|
||||
expect(screen.getByText('no conversation selected')).toBeTruthy();
|
||||
|
||||
@@ -4927,8 +4927,23 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
const dockedReply = dockCandidate && dockedSessionRef.current === composerSessionId;
|
||||
const composerHost = floatingComposer ? 'window' : mvInlineReply ? 'inline' : dockedReply ? 'dock' : 'pane';
|
||||
composerHostRef.current = composerHost;
|
||||
// Rows ticked beyond the open message take the reading pane (mail-p2-3):
|
||||
// the selection bar and the keys act on the ticked rows, so a reader
|
||||
// toolbar acting on the one open message would be a second, different set.
|
||||
// Unticking brings the message back. Mountain View keeps the message while
|
||||
// rows are ticked (#1231); the focus layout can't tick rows while reading.
|
||||
const openRowKeys = (() => {
|
||||
if (!selectedEmail) return null;
|
||||
const key = emailKeyFor(selectedEmail);
|
||||
// A conversation row ticks all its messages: the open one's whole row.
|
||||
const row = useEmailStore.getState().listRows?.find((r) => r.key === key || r.members.includes(key));
|
||||
return new Set(row ? [key, ...row.members] : [key]);
|
||||
})();
|
||||
const selectionTakesReader = !isMobile && !isFocusedMailLayout && !mvShell && !isScheduledView
|
||||
&& selectedEmailKeys.size > 0
|
||||
&& !(openRowKeys && [...selectedEmailKeys].every((key) => openRowKeys.has(key)));
|
||||
const hasViewerContent = (showComposer && !floatingComposer) || Boolean(conversationThread)
|
||||
|| Boolean(selectedEmail && !(mvShell && cursorOnly)) || deepLinkPane !== null;
|
||||
|| Boolean(selectedEmail && !(mvShell && cursorOnly) && !selectionTakesReader) || deepLinkPane !== null;
|
||||
// A linked message on a phone opens over the list, as one picked there does.
|
||||
const mobileView = deepLinkPane !== null && isMobile ? 'viewer' : activeView;
|
||||
const shouldCollapseListPane = !isMobile && isFocusedMailLayout && hasViewerContent;
|
||||
@@ -6106,9 +6121,9 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
<>
|
||||
<ErrorBoundary fallback={EmailViewerErrorFallback}>
|
||||
<EmailViewer
|
||||
email={selectedEmail}
|
||||
email={selectionTakesReader ? null : selectedEmail}
|
||||
blobSource={resolveEmailBlobContext(selectedEmail, client)}
|
||||
isLoading={isLoadingEmail || deepLinkPane !== null}
|
||||
isLoading={!selectionTakesReader && (isLoadingEmail || deepLinkPane !== null)}
|
||||
onReply={handleReply}
|
||||
onReplyAll={handleReplyAll}
|
||||
onForward={handleForward}
|
||||
|
||||
Reference in New Issue
Block a user