-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
Copy pathCodeToEditCard.tsx
109 lines (98 loc) · 3.58 KB
/
CodeToEditCard.tsx
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
import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline";
import type { CodeToEdit } from "core";
import { useContext, useState } from "react";
import { useDispatch } from "react-redux";
import { IdeMessengerContext } from "../../context/IdeMessenger";
import { useAppSelector } from "../../redux/hooks";
import {
addCodeToEdit,
removeCodeToEdit,
} from "../../redux/slices/sessionSlice";
import AddFileButton from "./AddFileButton";
import AddFileCombobox from "./AddFileCombobox";
import CodeToEditListItem from "./CodeToEditListItem";
export default function CodeToEditCard() {
const dispatch = useDispatch();
const ideMessenger = useContext(IdeMessengerContext);
const [showAddFileCombobox, setShowAddFileCombobox] = useState(false);
const codeToEdit = useAppSelector((state) => state.session.codeToEdit);
const itemCount =
codeToEdit.length === 0
? ""
: codeToEdit.length === 1
? "(1 item)"
: `(${codeToEdit.length} items)`;
function onDelete(rif: CodeToEdit) {
dispatch(removeCodeToEdit(rif));
}
async function onClickFilename(code: CodeToEdit) {
if ("range" in code) {
await ideMessenger.ide.showLines(
code.filepath,
code.range.start.line,
code.range.end.line,
);
} else {
await ideMessenger.ide.openFile(code.filepath);
}
}
async function onSelectFilesToAdd(uris: string[]) {
const filePromises = uris.map(async (uri) => {
const contents = await ideMessenger.ide.readFile(uri);
return { contents, filepath: uri };
});
const fileResults = await Promise.all(filePromises);
for (const file of fileResults) {
dispatch(addCodeToEdit(file));
}
}
return (
<div className="bg-vsc-editor-background mx-3 flex flex-col rounded-t-lg p-1">
<div className="text-lightgray flex items-center justify-between gap-1.5 py-1.5 pl-3 pr-2 text-xs">
<div className="flex items-center gap-1">
<span>Code to edit</span>
<span className="hidden sm:inline">{itemCount}</span>
</div>
<AddFileButton onClick={() => setShowAddFileCombobox(true)} />
</div>
{codeToEdit.length > 0 ? (
<ul className="no-scrollbar my-0 mb-1.5 max-h-[50vh] list-outside list-none overflow-y-auto pl-0">
{codeToEdit.map((code, i) => (
<CodeToEditListItem
key={code.filepath + i}
code={code}
onDelete={onDelete}
onClickFilename={onClickFilename}
/>
))}
</ul>
) : (
!showAddFileCombobox && (
<div
className="text-lightgray hover:bg-lightgray hover:text-vsc-foreground -mt-0.5 flex cursor-pointer items-center justify-center gap-1 rounded py-1 text-center text-xs transition-colors hover:bg-opacity-20"
onClick={() => setShowAddFileCombobox(true)}
>
<PlusIcon className="h-3.5 w-3.5" />
<span>Add a file to get started</span>
</div>
)
)}
{showAddFileCombobox && (
<div className="mr-2 flex items-center py-1">
<div className="flex-grow">
<AddFileCombobox
onSelect={onSelectFilesToAdd}
onEscape={() => setShowAddFileCombobox(false)}
/>
</div>
<XMarkIcon
onClick={() => {
setShowAddFileCombobox(false);
}}
className="text-lightgray hover:bg-lightgray hover:text-vsc-foreground mb-2 h-3.5 w-3.5 cursor-pointer rounded-sm p-0.5 hover:bg-opacity-20"
/>
</div>
)}
</div>
);
}