From 9fe7d78aca512a901b216bcb0666c7021e7ec441 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:50:56 +0000 Subject: [PATCH 1/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/hooks/poll-imap.ts | 51 ++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/routes/hooks/poll-imap.ts b/src/routes/hooks/poll-imap.ts index ce15c03..664a95d 100644 --- a/src/routes/hooks/poll-imap.ts +++ b/src/routes/hooks/poll-imap.ts @@ -55,29 +55,44 @@ export const Route = createFileRoute("/hooks/poll-imap")({ const sinceUid = (settings.last_uid ?? 0) + 1; const range = `${sinceUid}:*`; - // First pass: fetch lightweight envelopes only to learn the - // size of each message. Then fetch full source one-by-one, - // skipping anything over the size cap. - const candidates: Array<{ uid: number; size: number }> = []; - for await (const meta of client.fetch( - range, - { uid: true, size: true }, + // First pass: collect just UIDs via search (no FETCH stream). + // This avoids any large per-message data crossing the socket + // before we know which messages to skip. + const uidList = await client.search( + { uid: range }, { uid: true }, - )) { - if (meta.uid <= (settings.last_uid ?? 0)) continue; - candidates.push({ uid: meta.uid, size: meta.size ?? 0 }); - if (candidates.length >= MAX_MESSAGES_PER_RUN * 4) break; - } + ); + const candidateUids = (uidList ?? []) + .filter((u) => u > (settings.last_uid ?? 0)) + .sort((a, b) => a - b) + .slice(0, MAX_MESSAGES_PER_RUN * 4); - for (const cand of candidates) { + for (const uid of candidateUids) { if (imported >= MAX_MESSAGES_PER_RUN) break; // Always advance highestUid so we don't re-attempt skipped messages. - if (cand.uid > highestUid) highestUid = cand.uid; + if (uid > highestUid) highestUid = uid; - if (cand.size > MAX_MESSAGE_SIZE_BYTES) { + // Per-message size probe so we can skip oversize messages + // before downloading the full source. + let probedSize = 0; + try { + for await (const meta of client.fetch( + String(uid), + { uid: true, size: true }, + { uid: true }, + )) { + probedSize = meta.size ?? 0; + break; + } + } catch (e) { + console.error("Size probe failed uid", uid, e); + continue; + } + + if (probedSize > MAX_MESSAGE_SIZE_BYTES) { console.warn( - `Skipping IMAP uid ${cand.uid} (${cand.size} bytes > ${MAX_MESSAGE_SIZE_BYTES})`, + `Skipping IMAP uid ${uid} (${probedSize} bytes > ${MAX_MESSAGE_SIZE_BYTES})`, ); continue; } @@ -85,7 +100,7 @@ export const Route = createFileRoute("/hooks/poll-imap")({ let msg: { uid: number; source: Buffer; size?: number } | null = null; try { for await (const m of client.fetch( - String(cand.uid), + String(uid), { uid: true, source: true, size: true }, { uid: true }, )) { @@ -93,7 +108,7 @@ export const Route = createFileRoute("/hooks/poll-imap")({ break; } } catch (e) { - console.error("Per-message fetch failed uid", cand.uid, e); + console.error("Per-message fetch failed uid", uid, e); continue; } if (!msg) continue; From 7b934cd82803a06603f7d06a4f98ae49dbcdd442 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:51:08 +0000 Subject: [PATCH 2/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/hooks/poll-imap.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/hooks/poll-imap.ts b/src/routes/hooks/poll-imap.ts index 664a95d..e68788f 100644 --- a/src/routes/hooks/poll-imap.ts +++ b/src/routes/hooks/poll-imap.ts @@ -58,13 +58,13 @@ export const Route = createFileRoute("/hooks/poll-imap")({ // First pass: collect just UIDs via search (no FETCH stream). // This avoids any large per-message data crossing the socket // before we know which messages to skip. - const uidList = await client.search( + const uidList = (await (client as any).search( { uid: range }, { uid: true }, - ); + )) as number[] | undefined; const candidateUids = (uidList ?? []) - .filter((u) => u > (settings.last_uid ?? 0)) - .sort((a, b) => a - b) + .filter((u: number) => u > (settings.last_uid ?? 0)) + .sort((a: number, b: number) => a - b) .slice(0, MAX_MESSAGES_PER_RUN * 4); for (const uid of candidateUids) { From 6dad2d87b1bf6a5c8daa9feba3cb57b0c8ab4506 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:51:28 +0000 Subject: [PATCH 3/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/index.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 8d4fee9..40bf039 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -13,6 +13,8 @@ import { } from "lucide-react"; import { formatCurrency, formatDate, statusBadgeClass } from "@/lib/format"; import { format, startOfDay, startOfMonth, endOfMonth, subDays } from "date-fns"; +import { QuickAddTime, QuickAddExpense } from "@/components/quick-add/quick-add"; +import { NewTaskDialog } from "@/components/tasks/new-task-dialog"; export const Route = createFileRoute("/")({ component: () => ( @@ -150,12 +152,9 @@ function Dashboard() { }, [user?.id]); const quickActions = useMemo(() => [ - { label: "Add task", icon: CheckSquare, to: "/tasks" }, { label: "Add case", icon: Briefcase, to: "/cases/new" }, { label: "Add contact", icon: UserPlus, to: "/contacts" }, { label: "Create invoice", icon: Receipt, to: "/invoices" }, - { label: "Add time", icon: Clock, to: "/tasks" }, - { label: "Add expense", icon: DollarSign, to: "/cases" }, ], []); const financialCards = [ @@ -174,11 +173,20 @@ function Dashboard() {
Quick actions
+ + Add task + + } + /> {quickActions.map((a) => ( ))} + +
From 0fb0b108137b6929eb8f49f91bbc1a332123204a Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:51:36 +0000 Subject: [PATCH 4/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/index.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 40bf039..41fd962 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -50,6 +50,7 @@ function Dashboard() { const [recentCases, setRecentCases] = useState([]); const [recentInvoices, setRecentInvoices] = useState([]); const [recentPayments, setRecentPayments] = useState([]); + const [taskDialogOpen, setTaskDialogOpen] = useState(false); const [upcomingReminders, setUpcomingReminders] = useState([]); const [loading, setLoading] = useState(true); @@ -173,13 +174,10 @@ function Dashboard() {
Quick actions
- - Add task - - } - /> + + {quickActions.map((a) => (