-
Notifications
You must be signed in to change notification settings - Fork 74
Add 'All accounts' mode #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
devin-ai-integration[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 retryRemoteSearch is non-functional in All accounts mode The (Refers to line 201) Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,6 @@ | ||||||||||||||||||||||||||||||||||||||||||
| import { useEffect, useState, useCallback, useRef, useMemo } from "react"; | ||||||||||||||||||||||||||||||||||||||||||
| import { useQuery } from "@tanstack/react-query"; | ||||||||||||||||||||||||||||||||||||||||||
| import { useAppStore, useThreadedEmails, type Account, type SyncStatus, type PrefetchProgress, type BackgroundSyncProgress } from "./store"; | ||||||||||||||||||||||||||||||||||||||||||
| import { useAppStore, useThreadedEmails, getAccountColor, type Account, type SyncStatus, type PrefetchProgress, type BackgroundSyncProgress } from "./store"; | ||||||||||||||||||||||||||||||||||||||||||
| import { EmailList } from "./components/EmailList"; | ||||||||||||||||||||||||||||||||||||||||||
| import { EmailDetail } from "./components/EmailDetail"; | ||||||||||||||||||||||||||||||||||||||||||
| import { EmailPreviewSidebar } from "./components/EmailPreviewSidebar"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -170,7 +170,13 @@ function SearchResultsView() { | |||||||||||||||||||||||||||||||||||||||||
| remoteSearchLoadingMore, | ||||||||||||||||||||||||||||||||||||||||||
| } = useAppStore(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const currentUserEmail = accounts.find(a => a.id === currentAccountId)?.email; | ||||||||||||||||||||||||||||||||||||||||||
| const searchUserEmails = useMemo(() => { | ||||||||||||||||||||||||||||||||||||||||||
| if (currentAccountId) { | ||||||||||||||||||||||||||||||||||||||||||
| const email = accounts.find(a => a.id === currentAccountId)?.email; | ||||||||||||||||||||||||||||||||||||||||||
| return email ? new Set([email]) : new Set<string>(); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| return new Set(accounts.map(a => a.email)); | ||||||||||||||||||||||||||||||||||||||||||
| }, [currentAccountId, accounts]); | ||||||||||||||||||||||||||||||||||||||||||
| const scrollContainerRef = useRef<HTMLDivElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
| const sentinelRef = useRef<HTMLDivElement>(null); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -259,11 +265,13 @@ function SearchResultsView() { | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Merge local and remote results, deduplicate, and group into threads | ||||||||||||||||||||||||||||||||||||||||||
| const searchThreads = useMemo( | ||||||||||||||||||||||||||||||||||||||||||
| () => mergeAndThreadSearchResults(activeSearchResults, remoteSearchResults, currentUserEmail), | ||||||||||||||||||||||||||||||||||||||||||
| [activeSearchResults, remoteSearchResults, currentUserEmail], | ||||||||||||||||||||||||||||||||||||||||||
| () => mergeAndThreadSearchResults(activeSearchResults, remoteSearchResults, searchUserEmails), | ||||||||||||||||||||||||||||||||||||||||||
| [activeSearchResults, remoteSearchResults, searchUserEmails], | ||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const hasMoreResults = !!remoteSearchNextPageToken && remoteSearchStatus === "complete"; | ||||||||||||||||||||||||||||||||||||||||||
| // "Load more" only works when a single account is selected — in All accounts | ||||||||||||||||||||||||||||||||||||||||||
| // mode the stored nextPageToken is ambiguous (could be from any account). | ||||||||||||||||||||||||||||||||||||||||||
| const hasMoreResults = !!currentAccountId && !!remoteSearchNextPageToken && remoteSearchStatus === "complete"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||
| <div className="flex-1 min-w-0 flex flex-col bg-white dark:bg-gray-800"> | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -603,11 +611,23 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||
| setAccounts(fullAccounts); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Set current account to primary or first available | ||||||||||||||||||||||||||||||||||||||||||
| // Respect defaultAccountView config for startup account selection | ||||||||||||||||||||||||||||||||||||||||||
| const configResult = await window.api.settings.get(); | ||||||||||||||||||||||||||||||||||||||||||
| const defaultView = configResult.success ? configResult.data.defaultAccountView ?? "all" : "all"; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (fullAccounts.length > 1) { | ||||||||||||||||||||||||||||||||||||||||||
| if (defaultView === "primary") { | ||||||||||||||||||||||||||||||||||||||||||
| const primary = fullAccounts.find(a => a.isPrimary) || fullAccounts[0]; | ||||||||||||||||||||||||||||||||||||||||||
| setCurrentAccountId(primary.id); | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| setCurrentAccountId(null); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } else if (fullAccounts.length === 1) { | ||||||||||||||||||||||||||||||||||||||||||
| setCurrentAccountId(fullAccounts[0].id); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const primaryAccount = fullAccounts.find(a => a.isPrimary) || fullAccounts[0]; | ||||||||||||||||||||||||||||||||||||||||||
| if (primaryAccount) { | ||||||||||||||||||||||||||||||||||||||||||
| setCurrentAccountId(primaryAccount.id); | ||||||||||||||||||||||||||||||||||||||||||
| // Identify user in PostHog using primary email | ||||||||||||||||||||||||||||||||||||||||||
| identifyUser(primaryAccount.email, { | ||||||||||||||||||||||||||||||||||||||||||
| account_count: fullAccounts.length, | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1161,8 +1181,16 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| // Reload sent emails too | ||||||||||||||||||||||||||||||||||||||||||
| await reloadSentEmailsForAccount(currentAccountId); | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| // Fallback to legacy fetch for default account | ||||||||||||||||||||||||||||||||||||||||||
| await fetchEmails(); | ||||||||||||||||||||||||||||||||||||||||||
| // All accounts mode: sync every account and reload emails | ||||||||||||||||||||||||||||||||||||||||||
| await Promise.all(accounts.map(async (account) => { | ||||||||||||||||||||||||||||||||||||||||||
| await window.api.sync.now(account.id); | ||||||||||||||||||||||||||||||||||||||||||
| const result = await window.api.sync.getEmails(account.id); | ||||||||||||||||||||||||||||||||||||||||||
| if (result.success && result.data) { | ||||||||||||||||||||||||||||||||||||||||||
| addEmails(result.data); | ||||||||||||||||||||||||||||||||||||||||||
| prefetchEmailBodies(result.data.map((e: DashboardEmail) => e.id)).catch(console.error); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| await reloadSentEmailsForAccount(account.id); | ||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } catch (err) { | ||||||||||||||||||||||||||||||||||||||||||
| setError(err instanceof Error ? err.message : "Failed to fetch emails"); | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1230,9 +1258,12 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Get current account and its sync status | ||||||||||||||||||||||||||||||||||||||||||
| const currentAccount = accounts.find((a) => a.id === currentAccountId); | ||||||||||||||||||||||||||||||||||||||||||
| const isAllAccountsMode = currentAccountId === null && accounts.length > 0; | ||||||||||||||||||||||||||||||||||||||||||
| const currentSyncStatus = currentAccountId ? getSyncStatus(currentAccountId) : "idle"; | ||||||||||||||||||||||||||||||||||||||||||
| const isSyncing = currentSyncStatus === "syncing"; | ||||||||||||||||||||||||||||||||||||||||||
| const isAnySyncing = isAllAccountsMode && accounts.some((a) => getSyncStatus(a.id) === "syncing"); | ||||||||||||||||||||||||||||||||||||||||||
| const isSyncing = currentSyncStatus === "syncing" || isAnySyncing; | ||||||||||||||||||||||||||||||||||||||||||
| const isCurrentAccountExpired = currentAccountId != null && expiredAccountIds.has(currentAccountId); | ||||||||||||||||||||||||||||||||||||||||||
| const isAnyAccountExpired = isAllAccountsMode && accounts.some((a) => expiredAccountIds.has(a.id)); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Build list of expired accounts with their email addresses for the banner | ||||||||||||||||||||||||||||||||||||||||||
| const expiredAccounts = accounts.filter((a) => expiredAccountIds.has(a.id)); | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1269,6 +1300,32 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| window.api.sync.now(accountId).catch(console.error); | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const handleAllAccountsClick = () => { | ||||||||||||||||||||||||||||||||||||||||||
| setCurrentAccountId(null); | ||||||||||||||||||||||||||||||||||||||||||
| setAccountMenuOpen(false); | ||||||||||||||||||||||||||||||||||||||||||
| trackEvent("account_switched", { account_count: accounts.length, mode: "all" }); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Ensure all accounts have their emails loaded | ||||||||||||||||||||||||||||||||||||||||||
| const storeState = useAppStore.getState(); | ||||||||||||||||||||||||||||||||||||||||||
| for (const account of accounts) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!storeState.emails.some((e) => e.accountId === account.id)) { | ||||||||||||||||||||||||||||||||||||||||||
| window.api.sync.getEmails(account.id).then((result: IpcResponse<DashboardEmail[]>) => { | ||||||||||||||||||||||||||||||||||||||||||
| if (result.success && result.data && result.data.length > 0) { | ||||||||||||||||||||||||||||||||||||||||||
| addEmails(result.data); | ||||||||||||||||||||||||||||||||||||||||||
| prefetchEmailBodies(result.data.map((e: DashboardEmail) => e.id)).catch(console.error); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| }).catch(console.error); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| if (!storeState.sentEmails.some((e) => e.accountId === account.id)) { | ||||||||||||||||||||||||||||||||||||||||||
| window.api.sync.getSentEmails(account.id).then((sentResult: IpcResponse<DashboardEmail[]>) => { | ||||||||||||||||||||||||||||||||||||||||||
| if (sentResult.success && sentResult.data) { | ||||||||||||||||||||||||||||||||||||||||||
| addSentEmails(sentResult.data); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| }).catch(console.error); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const handleCancelScheduled = async (id: string) => { | ||||||||||||||||||||||||||||||||||||||||||
| const result = await window.api.scheduledSend.cancel(id) as { | ||||||||||||||||||||||||||||||||||||||||||
| success: boolean; | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1307,7 +1364,7 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| className="flex items-center space-x-2 px-3 py-1.5 text-sm bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors" | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <span className="text-gray-700 dark:text-gray-300 truncate max-w-[200px]"> | ||||||||||||||||||||||||||||||||||||||||||
| {currentAccount?.email || "Select account"} | ||||||||||||||||||||||||||||||||||||||||||
| {isAllAccountsMode ? "All accounts" : currentAccount?.email || "Select account"} | ||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||
| {/* Sync status indicator */} | ||||||||||||||||||||||||||||||||||||||||||
| {isSyncing && ( | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1316,13 +1373,13 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" /> | ||||||||||||||||||||||||||||||||||||||||||
| </svg> | ||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||
| {!isSyncing && !isCurrentAccountExpired && currentSyncStatus === "idle" && ( | ||||||||||||||||||||||||||||||||||||||||||
| {!isSyncing && !isCurrentAccountExpired && !isAnyAccountExpired && (isAllAccountsMode || currentSyncStatus === "idle") && ( | ||||||||||||||||||||||||||||||||||||||||||
| <span className="w-2 h-2 rounded-full bg-green-500" title="Connected" /> | ||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||
| {isCurrentAccountExpired && ( | ||||||||||||||||||||||||||||||||||||||||||
| {(isCurrentAccountExpired || isAnyAccountExpired) && ( | ||||||||||||||||||||||||||||||||||||||||||
| <span className="w-2 h-2 rounded-full bg-amber-500" title="Session expired" /> | ||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||
| {!isCurrentAccountExpired && currentSyncStatus === "error" && ( | ||||||||||||||||||||||||||||||||||||||||||
| {!isCurrentAccountExpired && !isAnyAccountExpired && !isAllAccountsMode && currentSyncStatus === "error" && ( | ||||||||||||||||||||||||||||||||||||||||||
| <span className="w-2 h-2 rounded-full bg-red-500" title="Sync error" /> | ||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1376
to
1384
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Sync error dot never shown in All accounts mode; green dot shows instead At
Suggested change
Was this helpful? React with 👍 or 👎 to provide feedback. |
||||||||||||||||||||||||||||||||||||||||||
| <svg className="w-4 h-4 text-gray-500 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1334,6 +1391,21 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| {accountMenuOpen && ( | ||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute top-full left-0 mt-1 w-64 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg dark:shadow-black/40 z-50"> | ||||||||||||||||||||||||||||||||||||||||||
| <div className="py-1"> | ||||||||||||||||||||||||||||||||||||||||||
| {accounts.length > 1 && ( | ||||||||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||||||||
| onClick={handleAllAccountsClick} | ||||||||||||||||||||||||||||||||||||||||||
| className={`w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center space-x-2 ${ | ||||||||||||||||||||||||||||||||||||||||||
| isAllAccountsMode ? "bg-blue-50 dark:bg-blue-900/30" : "" | ||||||||||||||||||||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <span className="flex -space-x-1"> | ||||||||||||||||||||||||||||||||||||||||||
| {accounts.slice(0, 3).map((a) => ( | ||||||||||||||||||||||||||||||||||||||||||
| <span key={a.id} className={`w-2 h-2 rounded-full ring-1 ring-white dark:ring-gray-800 ${getAccountColor(accounts, a.id).dot}`} /> | ||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||||||||||||||||||||
| <span>All accounts</span> | ||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||
| {accounts.map((account) => ( | ||||||||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||||||||
| key={account.id} | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1343,11 +1415,11 @@ export default function App() { | |||||||||||||||||||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center space-x-2"> | ||||||||||||||||||||||||||||||||||||||||||
| <span className={`w-2 h-2 rounded-full ${ | ||||||||||||||||||||||||||||||||||||||||||
| expiredAccountIds.has(account.id) ? "bg-amber-500" : | ||||||||||||||||||||||||||||||||||||||||||
| account.isConnected ? "bg-green-500" : "bg-gray-400 dark:bg-gray-500" | ||||||||||||||||||||||||||||||||||||||||||
| }`} /> | ||||||||||||||||||||||||||||||||||||||||||
| <span className={`w-2 h-2 rounded-full ${getAccountColor(accounts, account.id).dot}`} /> | ||||||||||||||||||||||||||||||||||||||||||
| <span className="truncate">{account.email}</span> | ||||||||||||||||||||||||||||||||||||||||||
| {expiredAccountIds.has(account.id) && ( | ||||||||||||||||||||||||||||||||||||||||||
| <span className="w-1.5 h-1.5 rounded-full bg-amber-500 flex-shrink-0" title="Session expired" /> | ||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||
| {account.isPrimary && ( | ||||||||||||||||||||||||||||||||||||||||||
| <span className="text-xs text-gray-500 dark:text-gray-400">Primary</span> | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1715,7 +1787,10 @@ function SnoozeOverlay() { | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const selectedEmail = emails.find((e) => e.id === selectedEmailId); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!showSnoozeMenu || !selectedEmail || !currentAccountId) return null; | ||||||||||||||||||||||||||||||||||||||||||
| // In "All accounts" mode currentAccountId is null — derive from the selected email | ||||||||||||||||||||||||||||||||||||||||||
| const effectiveAccountId = currentAccountId ?? selectedEmail?.accountId ?? null; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!showSnoozeMenu || !selectedEmail || !effectiveAccountId) return null; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Determine if we're in batch mode (any multi-select, even 1 thread via 'x') | ||||||||||||||||||||||||||||||||||||||||||
| const isBatchSnooze = selectedThreadIds.size > 0; | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1735,7 +1810,7 @@ function SnoozeOverlay() { | |||||||||||||||||||||||||||||||||||||||||
| <SnoozeMenu | ||||||||||||||||||||||||||||||||||||||||||
| emailId={selectedEmail.id} | ||||||||||||||||||||||||||||||||||||||||||
| threadId={selectedEmail.threadId} | ||||||||||||||||||||||||||||||||||||||||||
| accountId={currentAccountId} | ||||||||||||||||||||||||||||||||||||||||||
| accountId={effectiveAccountId} | ||||||||||||||||||||||||||||||||||||||||||
| onSnooze={(snoozedEmail: SnoozedEmail) => { | ||||||||||||||||||||||||||||||||||||||||||
| if (isBatchSnooze) { | ||||||||||||||||||||||||||||||||||||||||||
| // Batch snooze: snooze all selected threads using the same snoozeUntil time | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1773,7 +1848,7 @@ function SnoozeOverlay() { | |||||||||||||||||||||||||||||||||||||||||
| id: `snooze-${tid}-${Date.now()}`, | ||||||||||||||||||||||||||||||||||||||||||
| emailId: thread.latestEmail.id, | ||||||||||||||||||||||||||||||||||||||||||
| threadId: tid, | ||||||||||||||||||||||||||||||||||||||||||
| accountId: currentAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| accountId: effectiveAccountId, | ||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Batch snooze uses wrong accountId for cross-account threads in All accounts mode In Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
||||||||||||||||||||||||||||||||||||||||||
| snoozeUntil: snoozedEmail.snoozeUntil, | ||||||||||||||||||||||||||||||||||||||||||
| snoozedAt: snoozedEmail.snoozedAt, | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1788,7 +1863,7 @@ function SnoozeOverlay() { | |||||||||||||||||||||||||||||||||||||||||
| id: `snooze-batch-${Date.now()}`, | ||||||||||||||||||||||||||||||||||||||||||
| type: "snooze", | ||||||||||||||||||||||||||||||||||||||||||
| threadCount: threadIdsToSnooze.length, | ||||||||||||||||||||||||||||||||||||||||||
| accountId: currentAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| accountId: effectiveAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| emails: [], | ||||||||||||||||||||||||||||||||||||||||||
| scheduledAt: Date.now(), | ||||||||||||||||||||||||||||||||||||||||||
| delayMs: 5000, | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1802,7 +1877,7 @@ function SnoozeOverlay() { | |||||||||||||||||||||||||||||||||||||||||
| (window as any).api.snooze.snooze( | ||||||||||||||||||||||||||||||||||||||||||
| thread.latestEmail.id, | ||||||||||||||||||||||||||||||||||||||||||
| tid, | ||||||||||||||||||||||||||||||||||||||||||
| currentAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| effectiveAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| snoozeUntil, | ||||||||||||||||||||||||||||||||||||||||||
| ).catch((err: unknown) => console.error("Batch snooze failed for thread", tid, err)); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1845,7 +1920,7 @@ function SnoozeOverlay() { | |||||||||||||||||||||||||||||||||||||||||
| id: `snooze-${snoozedThreadId}-${Date.now()}`, | ||||||||||||||||||||||||||||||||||||||||||
| type: "snooze", | ||||||||||||||||||||||||||||||||||||||||||
| threadCount: 1, | ||||||||||||||||||||||||||||||||||||||||||
| accountId: currentAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| accountId: effectiveAccountId, | ||||||||||||||||||||||||||||||||||||||||||
| emails: [], | ||||||||||||||||||||||||||||||||||||||||||
| scheduledAt: Date.now(), | ||||||||||||||||||||||||||||||||||||||||||
| delayMs: 5000, | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.