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
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 };
|
|
}
|