fix: add collapse all threads functionality to email selection in thread list
This commit is contained in:
@@ -101,6 +101,7 @@ export function EmailList({
|
|||||||
toggleThreadExpansion,
|
toggleThreadExpansion,
|
||||||
fetchThreadEmails,
|
fetchThreadEmails,
|
||||||
markThreadAsRead,
|
markThreadAsRead,
|
||||||
|
collapseAllThreads,
|
||||||
threadEmailCounts,
|
threadEmailCounts,
|
||||||
searchFilters,
|
searchFilters,
|
||||||
setSearchFilters,
|
setSearchFilters,
|
||||||
@@ -477,7 +478,18 @@ export function EmailList({
|
|||||||
isLoading={isLoadingThread === thread.threadId}
|
isLoading={isLoadingThread === thread.threadId}
|
||||||
expandedEmails={threadEmailsCache.get(thread.threadId)}
|
expandedEmails={threadEmailsCache.get(thread.threadId)}
|
||||||
onToggleExpand={() => handleToggleThreadExpansion(thread.threadId)}
|
onToggleExpand={() => handleToggleThreadExpansion(thread.threadId)}
|
||||||
onEmailSelect={(email) => onEmailSelect?.(email)}
|
onCollapseAllThreads={collapseAllThreads}
|
||||||
|
onEmailSelect={(email) => {
|
||||||
|
// Collapse expanded threads when selecting an email outside the expanded thread
|
||||||
|
const currentExpanded = useEmailStore.getState().expandedThreadIds;
|
||||||
|
if (currentExpanded.size > 0) {
|
||||||
|
// Check if the selected email belongs to any expanded thread via its threadId
|
||||||
|
if (!email.threadId || !currentExpanded.has(email.threadId)) {
|
||||||
|
collapseAllThreads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onEmailSelect?.(email);
|
||||||
|
}}
|
||||||
onEmailDoubleClick={onEmailDoubleClick ? (email) => onEmailDoubleClick(email) : undefined}
|
onEmailDoubleClick={onEmailDoubleClick ? (email) => onEmailDoubleClick(email) : undefined}
|
||||||
onContextMenu={openContextMenu}
|
onContextMenu={openContextMenu}
|
||||||
onOpenConversation={onOpenConversation}
|
onOpenConversation={onOpenConversation}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ interface ThreadListItemProps {
|
|||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
expandedEmails?: Email[];
|
expandedEmails?: Email[];
|
||||||
onToggleExpand: () => void;
|
onToggleExpand: () => void;
|
||||||
|
onCollapseAllThreads?: () => void;
|
||||||
onEmailSelect: (email: Email) => void;
|
onEmailSelect: (email: Email) => void;
|
||||||
onEmailDoubleClick?: (email: Email) => void;
|
onEmailDoubleClick?: (email: Email) => void;
|
||||||
onContextMenu?: (e: React.MouseEvent, email: Email) => void;
|
onContextMenu?: (e: React.MouseEvent, email: Email) => void;
|
||||||
@@ -384,6 +385,7 @@ export const ThreadListItem = React.forwardRef<HTMLDivElement, ThreadListItemPro
|
|||||||
isLoading = false,
|
isLoading = false,
|
||||||
expandedEmails,
|
expandedEmails,
|
||||||
onToggleExpand,
|
onToggleExpand,
|
||||||
|
onCollapseAllThreads,
|
||||||
onEmailSelect,
|
onEmailSelect,
|
||||||
onEmailDoubleClick,
|
onEmailDoubleClick,
|
||||||
onContextMenu,
|
onContextMenu,
|
||||||
@@ -515,6 +517,7 @@ export const ThreadListItem = React.forwardRef<HTMLDivElement, ThreadListItemPro
|
|||||||
} else {
|
} else {
|
||||||
if (selectedEmailIds.size > 0) clearSelection();
|
if (selectedEmailIds.size > 0) clearSelection();
|
||||||
if (!isExpanded) {
|
if (!isExpanded) {
|
||||||
|
onCollapseAllThreads?.();
|
||||||
onToggleExpand();
|
onToggleExpand();
|
||||||
}
|
}
|
||||||
onEmailSelect(latestEmail);
|
onEmailSelect(latestEmail);
|
||||||
@@ -581,32 +584,6 @@ export const ThreadListItem = React.forwardRef<HTMLDivElement, ThreadListItemPro
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isMobile && !isFocusedMailLayout && (
|
|
||||||
<button
|
|
||||||
data-expand-toggle
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onToggleExpand();
|
|
||||||
}}
|
|
||||||
className={cn(
|
|
||||||
"p-1 rounded mt-2 flex-shrink-0 transition-all duration-200",
|
|
||||||
"hover:bg-muted/50 hover:scale-110",
|
|
||||||
"active:scale-95",
|
|
||||||
"text-muted-foreground hover:text-foreground"
|
|
||||||
)}
|
|
||||||
aria-expanded={isExpanded}
|
|
||||||
aria-label={t('toggle_thread')}
|
|
||||||
>
|
|
||||||
{isLoading ? (
|
|
||||||
<Loader2 className="w-4 h-4 animate-spin" />
|
|
||||||
) : isExpanded ? (
|
|
||||||
<ChevronDown className="w-4 h-4" />
|
|
||||||
) : (
|
|
||||||
<ChevronRight className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{hasUnread && (
|
{hasUnread && (
|
||||||
<div className="absolute left-1 top-1/2 -translate-y-1/2">
|
<div className="absolute left-1 top-1/2 -translate-y-1/2">
|
||||||
<Circle className="w-2 h-2 fill-unread text-unread" />
|
<Circle className="w-2 h-2 fill-unread text-unread" />
|
||||||
@@ -614,13 +591,42 @@ export const ThreadListItem = React.forwardRef<HTMLDivElement, ThreadListItemPro
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{density !== 'extra-compact' && (
|
{density !== 'extra-compact' && (
|
||||||
<Avatar
|
<div className="relative flex-shrink-0">
|
||||||
name={avatarPerson?.name}
|
<Avatar
|
||||||
email={avatarPerson?.email}
|
name={avatarPerson?.name}
|
||||||
size={isFocusedMailLayout ? "sm" : "md"}
|
email={avatarPerson?.email}
|
||||||
className="flex-shrink-0 shadow-sm"
|
size={isFocusedMailLayout ? "sm" : "md"}
|
||||||
disableImages={hideJunkAvatarImages}
|
className="shadow-sm"
|
||||||
/>
|
disableImages={hideJunkAvatarImages}
|
||||||
|
/>
|
||||||
|
{!isMobile && !isFocusedMailLayout && (
|
||||||
|
<button
|
||||||
|
data-expand-toggle
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onToggleExpand();
|
||||||
|
}}
|
||||||
|
className={cn(
|
||||||
|
"absolute -bottom-2.5 left-1/2 -translate-x-1/2 p-0.5 rounded-full",
|
||||||
|
"transition-all duration-200",
|
||||||
|
"hover:bg-muted/50 hover:scale-110",
|
||||||
|
"active:scale-95",
|
||||||
|
"text-muted-foreground hover:text-foreground",
|
||||||
|
"bg-background border border-border"
|
||||||
|
)}
|
||||||
|
aria-expanded={isExpanded}
|
||||||
|
aria-label={t('toggle_thread')}
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<Loader2 className="w-3 h-3 animate-spin" />
|
||||||
|
) : isExpanded ? (
|
||||||
|
<ChevronDown className="w-3 h-3" />
|
||||||
|
) : (
|
||||||
|
<ChevronRight className="w-3 h-3" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
|
|||||||
Reference in New Issue
Block a user