You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

40 lines
1.8 KiB
TypeScript

// frontend/lib/hooks/useMail.ts — 메일 목록/계정/폴더 SWR 훅
"use client";
import useSWR from "swr";
import type { AccountFolder, EmailRow, MailAccount } from "@/lib/types";
import { mailApi } from "@/lib/mail/api";
export function useMail(account: string | null, folder: string, query = "") {
// 보낸편지함/임시보관함은 전용 엔드포인트(발송/대기 메일)에서 가져온다.
const fetcher =
folder === "sent"
? () => mailApi.sent(account)
: folder === "drafts"
? () => mailApi.drafts(account)
: () => mailApi.list(account, folder, query);
const {
data: emails,
error: emailsError,
mutate,
isLoading,
} = useSWR<EmailRow[]>(["mail", account, folder, query], fetcher, {
// 백엔드 자동 풀링이 새 메일을 적재하므로 주기적으로(10초)·포커스 시 목록을 갱신.
revalidateOnFocus: true,
refreshInterval: 10_000,
// 처음 보는 폴더로 전환할 때 직전 목록을 유지 → emails 가 undefined 로 떨어지지
// 않게 해 전체 화면 스켈레톤(사이드바 언마운트=트리 닫힘)을 막는다.
keepPreviousData: true,
});
// 계정별 안읽음 배지(집중/기타)의 소스. 폰 등 외부에서 읽으면 서버 카운트가 줄지만,
// 자동 재검증이 없으면 배지가 예전 값(예: 1)에 멈춘다 → 포커스·주기(30초) 갱신을 켠다.
const { data: accounts } = useSWR<MailAccount[]>("mail/accounts", () => mailApi.accounts(), {
revalidateOnFocus: true,
refreshInterval: 30_000,
});
const { data: folders } = useSWR<AccountFolder[]>("mail/folders", () => mailApi.folders(), {
revalidateOnFocus: false,
refreshInterval: 30_000, // 폴더 카운트도 주기 갱신
});
return { emails, accounts, folders, error: emailsError, isLoading, mutate };
}