import { timestampDate } from "@bufbuild/protobuf/wkt"; import dayjs from "dayjs"; import { useMemo } from "react"; import { type MemoTimeBasis, useView } from "@/contexts/ViewContext"; import { State } from "@/types/proto/api/v1/common_pb"; import type { Memo } from "@/types/proto/api/v1/memo_service_pb"; export interface UseMemoSortingOptions { pinnedFirst?: boolean; state?: State; } export interface UseMemoSortingResult { listSort: (memos: Memo[]) => Memo[]; orderBy: string; } const getMemoSortTime = (memo: Memo, timeBasis: MemoTimeBasis): Date | undefined => { const timestamp = timeBasis === "update_time" ? memo.updateTime : memo.createTime; return timestamp ? timestampDate(timestamp) : undefined; }; export const useMemoSorting = (options: UseMemoSortingOptions = {}): UseMemoSortingResult => { const { pinnedFirst = false, state = State.NORMAL } = options; const { orderByTimeAsc, timeBasis } = useView(); // Generate orderBy string for API const orderBy = useMemo(() => { const timeOrder = orderByTimeAsc ? `${timeBasis} asc` : `${timeBasis} desc`; return pinnedFirst ? `pinned desc, ${timeOrder}` : timeOrder; }, [pinnedFirst, orderByTimeAsc, timeBasis]); // Generate listSort function for client-side sorting const listSort = useMemo(() => { return (memos: Memo[]): Memo[] => { return memos .filter((memo) => memo.state === state) .sort((a, b) => { // First, sort by pinned status if enabled if (pinnedFirst && a.pinned !== b.pinned) { return b.pinned ? 1 : -1; } // Then sort by the selected time field. const aTime = getMemoSortTime(a, timeBasis); const bTime = getMemoSortTime(b, timeBasis); return orderByTimeAsc ? dayjs(aTime).unix() - dayjs(bTime).unix() : dayjs(bTime).unix() - dayjs(aTime).unix(); }); }; }, [pinnedFirst, state, orderByTimeAsc, timeBasis]); return { listSort, orderBy }; };