Project creation is workign
This commit is contained in:
@@ -6,172 +6,175 @@ import { usePathCompletion } from "./components/selection/usePathCompletion";
|
||||
import "./App.css";
|
||||
|
||||
function App() {
|
||||
const [projectPath, setProjectPath] = React.useState<string | null>(null);
|
||||
const [errorMsg, setErrorMsg] = React.useState<string | null>(null);
|
||||
const [pathInput, setPathInput] = React.useState("");
|
||||
const [isOpening, setIsOpening] = React.useState(false);
|
||||
const [knownProjects, setKnownProjects] = React.useState<string[]>([]);
|
||||
const [homeDir, setHomeDir] = React.useState<string | null>(null);
|
||||
const [projectPath, setProjectPath] = React.useState<string | null>(null);
|
||||
const [errorMsg, setErrorMsg] = React.useState<string | null>(null);
|
||||
const [pathInput, setPathInput] = React.useState("");
|
||||
const [isOpening, setIsOpening] = React.useState(false);
|
||||
const [knownProjects, setKnownProjects] = React.useState<string[]>([]);
|
||||
const [homeDir, setHomeDir] = React.useState<string | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
api
|
||||
.getKnownProjects()
|
||||
.then((projects) => setKnownProjects(projects))
|
||||
.catch((error) => console.error(error));
|
||||
}, []);
|
||||
React.useEffect(() => {
|
||||
api
|
||||
.getKnownProjects()
|
||||
.then((projects) => setKnownProjects(projects))
|
||||
.catch((error) => console.error(error));
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
let active = true;
|
||||
api
|
||||
.getHomeDirectory()
|
||||
.then((home) => {
|
||||
if (!active) return;
|
||||
setHomeDir(home);
|
||||
setPathInput((current) => {
|
||||
if (current.trim()) {
|
||||
return current;
|
||||
}
|
||||
const initial = home.endsWith("/") ? home : `${home}/`;
|
||||
return initial;
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
React.useEffect(() => {
|
||||
let active = true;
|
||||
api
|
||||
.getHomeDirectory()
|
||||
.then((home) => {
|
||||
if (!active) return;
|
||||
setHomeDir(home);
|
||||
setPathInput((current) => {
|
||||
if (current.trim()) {
|
||||
return current;
|
||||
}
|
||||
const initial = home.endsWith("/") ? home : `${home}/`;
|
||||
return initial;
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, []);
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const {
|
||||
matchList,
|
||||
selectedMatch,
|
||||
suggestionTail,
|
||||
completionError,
|
||||
currentPartial,
|
||||
setSelectedMatch,
|
||||
acceptSelectedMatch,
|
||||
acceptMatch,
|
||||
closeSuggestions,
|
||||
} = usePathCompletion({
|
||||
pathInput,
|
||||
setPathInput,
|
||||
homeDir,
|
||||
listDirectoryAbsolute: api.listDirectoryAbsolute,
|
||||
});
|
||||
const {
|
||||
matchList,
|
||||
selectedMatch,
|
||||
suggestionTail,
|
||||
completionError,
|
||||
currentPartial,
|
||||
setSelectedMatch,
|
||||
acceptSelectedMatch,
|
||||
acceptMatch,
|
||||
closeSuggestions,
|
||||
} = usePathCompletion({
|
||||
pathInput,
|
||||
setPathInput,
|
||||
homeDir,
|
||||
listDirectoryAbsolute: api.listDirectoryAbsolute,
|
||||
});
|
||||
|
||||
async function openProject(path: string) {
|
||||
if (!path.trim()) {
|
||||
setErrorMsg("Please enter a project path.");
|
||||
return;
|
||||
}
|
||||
async function openProject(path: string) {
|
||||
const trimmedPath = path.trim();
|
||||
if (!trimmedPath) {
|
||||
setErrorMsg("Please enter a project path.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setErrorMsg(null);
|
||||
setIsOpening(true);
|
||||
const confirmedPath = await api.openProject(path.trim());
|
||||
setProjectPath(confirmedPath);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const message =
|
||||
e instanceof Error
|
||||
? e.message
|
||||
: typeof e === "string"
|
||||
? e
|
||||
: "An error occurred opening the project.";
|
||||
setErrorMsg(message);
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
}
|
||||
}
|
||||
try {
|
||||
setErrorMsg(null);
|
||||
setIsOpening(true);
|
||||
const confirmedPath = await api.openProject(trimmedPath);
|
||||
setProjectPath(confirmedPath);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
const message =
|
||||
e instanceof Error
|
||||
? e.message
|
||||
: typeof e === "string"
|
||||
? e
|
||||
: "An error occurred opening the project.";
|
||||
|
||||
function handleOpen() {
|
||||
void openProject(pathInput);
|
||||
}
|
||||
setErrorMsg(message);
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleForgetProject(path: string) {
|
||||
try {
|
||||
await api.forgetKnownProject(path);
|
||||
setKnownProjects((prev) => prev.filter((p) => p !== path));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
function handleOpen() {
|
||||
void openProject(pathInput);
|
||||
}
|
||||
|
||||
async function closeProject() {
|
||||
try {
|
||||
await api.closeProject();
|
||||
setProjectPath(null);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
async function handleForgetProject(path: string) {
|
||||
try {
|
||||
await api.forgetKnownProject(path);
|
||||
setKnownProjects((prev) => prev.filter((p) => p !== path));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
function handlePathInputKeyDown(
|
||||
event: React.KeyboardEvent<HTMLInputElement>,
|
||||
) {
|
||||
if (event.key === "ArrowDown") {
|
||||
if (matchList.length > 0) {
|
||||
event.preventDefault();
|
||||
setSelectedMatch((selectedMatch + 1) % matchList.length);
|
||||
}
|
||||
} else if (event.key === "ArrowUp") {
|
||||
if (matchList.length > 0) {
|
||||
event.preventDefault();
|
||||
setSelectedMatch(
|
||||
(selectedMatch - 1 + matchList.length) % matchList.length,
|
||||
);
|
||||
}
|
||||
} else if (event.key === "Tab") {
|
||||
if (matchList.length > 0) {
|
||||
event.preventDefault();
|
||||
acceptSelectedMatch();
|
||||
}
|
||||
} else if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
closeSuggestions();
|
||||
} else if (event.key === "Enter") {
|
||||
handleOpen();
|
||||
}
|
||||
}
|
||||
async function closeProject() {
|
||||
try {
|
||||
await api.closeProject();
|
||||
setProjectPath(null);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<main
|
||||
className="container"
|
||||
style={{ height: "100vh", padding: 0, maxWidth: "100%" }}
|
||||
>
|
||||
{!projectPath ? (
|
||||
<SelectionScreen
|
||||
knownProjects={knownProjects}
|
||||
onOpenProject={openProject}
|
||||
onForgetProject={handleForgetProject}
|
||||
pathInput={pathInput}
|
||||
onPathInputChange={setPathInput}
|
||||
onPathInputKeyDown={handlePathInputKeyDown}
|
||||
isOpening={isOpening}
|
||||
suggestionTail={suggestionTail}
|
||||
matchList={matchList}
|
||||
selectedMatch={selectedMatch}
|
||||
onSelectMatch={setSelectedMatch}
|
||||
onAcceptMatch={acceptMatch}
|
||||
onCloseSuggestions={closeSuggestions}
|
||||
completionError={completionError}
|
||||
currentPartial={currentPartial}
|
||||
/>
|
||||
) : (
|
||||
<div className="workspace" style={{ height: "100%" }}>
|
||||
<Chat projectPath={projectPath} onCloseProject={closeProject} />
|
||||
</div>
|
||||
)}
|
||||
function handlePathInputKeyDown(
|
||||
event: React.KeyboardEvent<HTMLInputElement>,
|
||||
) {
|
||||
if (event.key === "ArrowDown") {
|
||||
if (matchList.length > 0) {
|
||||
event.preventDefault();
|
||||
setSelectedMatch((selectedMatch + 1) % matchList.length);
|
||||
}
|
||||
} else if (event.key === "ArrowUp") {
|
||||
if (matchList.length > 0) {
|
||||
event.preventDefault();
|
||||
setSelectedMatch(
|
||||
(selectedMatch - 1 + matchList.length) % matchList.length,
|
||||
);
|
||||
}
|
||||
} else if (event.key === "Tab") {
|
||||
if (matchList.length > 0) {
|
||||
event.preventDefault();
|
||||
acceptSelectedMatch();
|
||||
}
|
||||
} else if (event.key === "Escape") {
|
||||
event.preventDefault();
|
||||
closeSuggestions();
|
||||
} else if (event.key === "Enter") {
|
||||
handleOpen();
|
||||
}
|
||||
}
|
||||
|
||||
{errorMsg && (
|
||||
<div className="error-message" style={{ marginTop: "20px" }}>
|
||||
<p style={{ color: "red" }}>Error: {errorMsg}</p>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
return (
|
||||
<main
|
||||
className="container"
|
||||
style={{ height: "100vh", padding: 0, maxWidth: "100%" }}
|
||||
>
|
||||
{!projectPath ? (
|
||||
<SelectionScreen
|
||||
knownProjects={knownProjects}
|
||||
onOpenProject={openProject}
|
||||
onForgetProject={handleForgetProject}
|
||||
pathInput={pathInput}
|
||||
homeDir={homeDir}
|
||||
onPathInputChange={setPathInput}
|
||||
onPathInputKeyDown={handlePathInputKeyDown}
|
||||
isOpening={isOpening}
|
||||
suggestionTail={suggestionTail}
|
||||
matchList={matchList}
|
||||
selectedMatch={selectedMatch}
|
||||
onSelectMatch={setSelectedMatch}
|
||||
onAcceptMatch={acceptMatch}
|
||||
onCloseSuggestions={closeSuggestions}
|
||||
completionError={completionError}
|
||||
currentPartial={currentPartial}
|
||||
/>
|
||||
) : (
|
||||
<div className="workspace" style={{ height: "100%" }}>
|
||||
<Chat projectPath={projectPath} onCloseProject={closeProject} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{errorMsg && (
|
||||
<div className="error-message" style={{ marginTop: "20px" }}>
|
||||
<p style={{ color: "red" }}>Error: {errorMsg}</p>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
Reference in New Issue
Block a user