feat: add unread filter functionality in mailbox sidebar

This commit is contained in:
Linus Rath
2026-03-15 15:32:34 +01:00
parent 1f1db8fac8
commit c24fabe977
2 changed files with 57 additions and 7 deletions
+37
View File
@@ -657,6 +657,42 @@ export default function Home() {
} }
}; };
const handleUnreadFilterClick = async (mailboxId: string) => {
const isTogglingOff = selectedMailbox === mailboxId && searchFilters.isUnread === true;
// Select the mailbox if not already selected
if (selectedMailbox !== mailboxId) {
selectMailbox(mailboxId);
selectEmail(null);
}
// On mobile, close sidebar and go to list view
if (isMobile) {
setSidebarOpen(false);
setActiveView("list");
}
// On tablet, show the list again
if (isTablet) {
setTabletListVisible(true);
}
if (isTogglingOff) {
// Disable the unread filter and show all emails
clearSearchFilters();
if (client) {
await fetchEmails(client, mailboxId);
}
} else {
// Enable unread filter
clearSearchFilters();
setSearchFilters({ isUnread: true });
if (client) {
await advancedSearch(client);
}
}
};
const handleLogout = () => { const handleLogout = () => {
logout(); logout();
router.push('/login'); router.push('/login');
@@ -929,6 +965,7 @@ export default function Home() {
selectedKeyword={selectedKeyword} selectedKeyword={selectedKeyword}
onMailboxSelect={handleMailboxSelect} onMailboxSelect={handleMailboxSelect}
onTagSelect={handleTagSelect} onTagSelect={handleTagSelect}
onUnreadFilterClick={handleUnreadFilterClick}
onCompose={() => { onCompose={() => {
setComposerMode('compose'); setComposerMode('compose');
setShowComposer(true); setShowComposer(true);
+20 -7
View File
@@ -46,6 +46,7 @@ interface SidebarProps {
onTagSelect?: (keywordId: string | null) => void; onTagSelect?: (keywordId: string | null) => void;
onCompose?: () => void; onCompose?: () => void;
onSidebarClose?: () => void; onSidebarClose?: () => void;
onUnreadFilterClick?: (mailboxId: string) => void;
className?: string; className?: string;
} }
@@ -84,6 +85,7 @@ function MailboxTreeItem({
onMailboxSelect, onMailboxSelect,
onToggleExpand, onToggleExpand,
isCollapsed, isCollapsed,
onUnreadFilterClick,
}: { }: {
node: MailboxNode; node: MailboxNode;
selectedMailbox: string; selectedMailbox: string;
@@ -91,6 +93,7 @@ function MailboxTreeItem({
onMailboxSelect?: (id: string) => void; onMailboxSelect?: (id: string) => void;
onToggleExpand: (id: string) => void; onToggleExpand: (id: string) => void;
isCollapsed: boolean; isCollapsed: boolean;
onUnreadFilterClick?: (mailboxId: string) => void;
}) { }) {
const t = useTranslations('sidebar'); const t = useTranslations('sidebar');
const tNotifications = useTranslations('notifications'); const tNotifications = useTranslations('notifications');
@@ -188,14 +191,21 @@ function MailboxTreeItem({
<span className="flex-1 truncate">{node.name}</span> <span className="flex-1 truncate">{node.name}</span>
<span className="flex items-center gap-1.5 ml-2 flex-shrink-0"> <span className="flex items-center gap-1.5 ml-2 flex-shrink-0">
{node.unreadEmails > 0 && ( {node.unreadEmails > 0 && (
<span className={cn( <button
"text-xs rounded-full px-2 py-0.5 font-medium", onClick={(e) => {
selectedMailbox === node.id e.stopPropagation();
? "bg-primary text-primary-foreground" onUnreadFilterClick?.(node.id);
: "bg-foreground text-background" }}
)}> className={cn(
"text-xs rounded-full px-2 py-0.5 font-medium cursor-pointer hover:ring-2 hover:ring-primary/50 transition-all",
selectedMailbox === node.id
? "bg-primary text-primary-foreground"
: "bg-foreground text-background"
)}
title={node.unreadEmails + " unread"}
>
{node.unreadEmails} {node.unreadEmails}
</span> </button>
)} )}
<span className="text-xs text-muted-foreground tabular-nums"> <span className="text-xs text-muted-foreground tabular-nums">
{node.totalEmails} {node.totalEmails}
@@ -217,6 +227,7 @@ function MailboxTreeItem({
onMailboxSelect={onMailboxSelect} onMailboxSelect={onMailboxSelect}
onToggleExpand={onToggleExpand} onToggleExpand={onToggleExpand}
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onUnreadFilterClick={onUnreadFilterClick}
/> />
))} ))}
</div> </div>
@@ -336,6 +347,7 @@ export function Sidebar({
onTagSelect, onTagSelect,
onCompose, onCompose,
onSidebarClose, onSidebarClose,
onUnreadFilterClick,
className, className,
}: SidebarProps) { }: SidebarProps) {
const { sidebarCollapsed: isCollapsed, toggleSidebarCollapsed } = useUIStore(); const { sidebarCollapsed: isCollapsed, toggleSidebarCollapsed } = useUIStore();
@@ -482,6 +494,7 @@ export function Sidebar({
onMailboxSelect={onMailboxSelect} onMailboxSelect={onMailboxSelect}
onToggleExpand={handleToggleExpand} onToggleExpand={handleToggleExpand}
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onUnreadFilterClick={onUnreadFilterClick}
/> />
))} ))}
</> </>