All files / hooks use-search-chat.ts

83.87% Statements 26/31
37.5% Branches 3/8
75% Functions 6/8
88.46% Lines 23/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47    3x 3x   3x       4x 4x 4x 4x   4x 4x     4x       4x 4x     4x 8x         4x 4x 8x 8x 8x 4x   4x     4x   4x    
"use client";
 
import { useDebounce } from "use-debounce";
import { useEffect, useRef, useState } from "react";
import type { ChatThread } from "@/types/thread";
import { getThreadDateGroup, getThreadDateGroupOrder } from "@/utils/date";
 
export type ThreadGroup = { label: string; threads: ChatThread[] };
 
export function useSearchChat(allThreads: ChatThread[], onClose: () => void) {
  const [query, setQuery] = useState("");
  const [debouncedQuery] = useDebounce(query, 500);
  const inputRef = useRef<HTMLInputElement>(null);
 
  useEffect(() => {
    inputRef.current?.focus();
  }, []);
 
  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === "Escape") onClose();
    }
    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [onClose]);
 
  const filtered = allThreads.filter((t) => {
    Eif (!debouncedQuery.trim()) return true;
    const q = debouncedQuery.toLowerCase();
    return t.title.toLowerCase().includes(q) || t.preview.toLowerCase().includes(q);
  });
 
  const groupMap: ThreadGroup[] = [];
  for (const thread of filtered) {
    const label = getThreadDateGroup(thread.updatedAt);
    const existing = groupMap.find((g) => g.label === label);
    if (existing) {
      existing.threads.push(thread);
    } else {
      groupMap.push({ label, threads: [thread] });
    }
  }
  const threadGroups = groupMap.sort((a, b) => getThreadDateGroupOrder(a.label) - getThreadDateGroupOrder(b.label));
 
  return { query, setQuery, threadGroups, inputRef };
}