File size: 4,719 Bytes
35ef307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dbf8f03
 
35ef307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dbf8f03
 
35ef307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { useState, useMemo } from "react";
import { FileCode, FileText, Braces, AtSign } from "lucide-react";

import { Button } from "@/components/ui/button";
import { useEditor } from "@/hooks/useEditor";
import { useAi } from "@/hooks/useAi";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import classNames from "classnames";

export const Context = () => {
  const { pages, currentPage, globalEditorLoading } = useEditor();
  const { contextFile, setContextFile, globalAiLoading } = useAi();
  const [open, setOpen] = useState(false);

  const selectedFile = contextFile || null;

  const getFileIcon = (filePath: string, size = "size-3.5") => {
    if (filePath.endsWith(".css")) {
      return <Braces className={size} />;
    } else if (filePath.endsWith(".js")) {
      return <FileCode className={size} />;
    } else if (filePath.endsWith(".json")) {
      return <Braces className={size} />;
    } else {
      return <FileText className={size} />;
    }
  };

  const buttonContent = useMemo(() => {
    if (selectedFile) {
      return (
        <>
          <span className="truncate max-w-[120px]">{selectedFile}</span>
        </>
      );
    }
    return <>Add Context</>;
  }, [selectedFile]);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          size="xs"
          variant={open ? "default" : "outline"}
          className={classNames("!rounded-md", {
            "!bg-blue-500/10 !border-blue-500/30 !text-blue-400":
              selectedFile && selectedFile.endsWith(".css"),
            "!bg-orange-500/10 !border-orange-500/30 !text-orange-400":
              selectedFile && selectedFile.endsWith(".html"),
            "!bg-amber-500/10 !border-amber-500/30 !text-amber-400":
              selectedFile && selectedFile.endsWith(".js"),
            "!bg-yellow-500/10 !border-yellow-500/30 !text-yellow-400":
              selectedFile && selectedFile.endsWith(".json"),
          })}
          disabled={
            globalAiLoading || globalEditorLoading || pages.length === 0
          }
        >
          <AtSign className="size-3.5" />

          {buttonContent}
        </Button>
      </PopoverTrigger>
      <PopoverContent
        align="start"
        className="w-64 !bg-neutral-900 !border-neutral-800 !p-0 !rounded-2xl overflow-hidden"
      >
        <header className="flex items-center justify-center text-xs px-2 py-2.5 border-b gap-2 bg-neutral-950 border-neutral-800 font-semibold text-neutral-200">
          Select a file to send as context
        </header>
        <main className="space-y-1 p-2">
          <div className="max-h-[200px] overflow-y-auto space-y-0.5">
            {pages.length === 0 ? (
              <div className="px-2 py-2 text-xs text-neutral-500">
                No files available
              </div>
            ) : (
              <>
                <button
                  onClick={() => {
                    setContextFile(null);
                    setOpen(false);
                  }}
                  className={`cursor-pointer w-full px-2 py-1.5 text-xs text-left rounded-md hover:bg-neutral-800 transition-colors ${
                    !selectedFile
                      ? "bg-neutral-800 text-neutral-200 font-medium"
                      : "text-neutral-400 hover:text-neutral-200"
                  }`}
                >
                  All files (default)
                </button>
                {pages.map((page) => (
                  <button
                    key={page.path}
                    onClick={() => {
                      setContextFile(page.path);
                      setOpen(false);
                    }}
                    className={`cursor-pointer w-full px-2 py-1.5 text-xs text-left rounded-md hover:bg-neutral-800 transition-colors flex items-center gap-1.5 ${
                      selectedFile === page.path
                        ? "bg-neutral-800 text-neutral-200 font-medium"
                        : "text-neutral-400 hover:text-neutral-200"
                    }`}
                  >
                    <span className="shrink-0">
                      {getFileIcon(page.path, "size-3")}
                    </span>
                    <span className="truncate flex-1">{page.path}</span>
                    {page.path === currentPage && (
                      <span className="text-[10px] text-neutral-500 shrink-0">
                        (current)
                      </span>
                    )}
                  </button>
                ))}
              </>
            )}
          </div>
        </main>
      </PopoverContent>
    </Popover>
  );
};