Skip to content

Commit

Permalink
fix(#2): bug: on open existing project, was used code from not last msg
Browse files Browse the repository at this point in the history
  • Loading branch information
k2589 committed Oct 16, 2024
1 parent 85a7523 commit baf54b8
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 50 deletions.
77 changes: 43 additions & 34 deletions app/lib/persistence/fileSystem.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { atom } from "nanostores";
import { createScopedLogger } from "~/utils/logger";
import * as path from "path-browserify";
import { useNavigate } from "@remix-run/react";

const logger = createScopedLogger("FileSystem");

export const selectedDirectoryHandle = atom<FileSystemDirectoryHandle | null>(
null,
);
export const selectedDirectoryHandle = atom<FileSystemDirectoryHandle | null>(null);
export const fileChanges = atom<Map<string, string>>(new Map());

interface FileContent {
Expand All @@ -15,7 +14,7 @@ interface FileContent {
}

export async function createProjectFiles(
chatItem: ChatHistoryItem,
chatItem: ChatHistoryItem
): Promise<void> {
const directoryHandle = await getDirectoryHandle();

Expand All @@ -30,7 +29,7 @@ export async function createProjectFiles(
for (const message of chatItem.messages) {
if (message.role === "assistant") {
const matches = message.content.matchAll(
/<boltAction type="file" filePath="([^"]+)">([\s\S]*?)<\/boltAction>/g,
/<boltAction type="file" filePath="([^"]+)">([\s\S]*?)<\/boltAction>/g
);

for (const match of matches) {
Expand All @@ -53,45 +52,62 @@ export async function createProjectFiles(
}
}

export async function selectDirectory(): Promise<void> {
export async function selectDirectory(): Promise<string | null> {
try {
const directoryHandle = await window.showDirectoryPicker();
selectedDirectoryHandle.set(directoryHandle);
localStorage.setItem("selectedDirectoryPath", directoryHandle.name);
logger.info(`Directory selected: ${directoryHandle.name}`);

// Check for existing .boltnew file
try {
const boltNewContent = await readFile(".boltnew");
const { chatId } = JSON.parse(boltNewContent);

// Check for corresponding .boltnew.json file
try {
await readBoltNewJson(chatId);
return chatId; // Return the chatId if both files exist
} catch (error) {
logger.warn(`No ${chatId}.boltnew.json file found`);
}
} catch (error) {
logger.info("No existing .boltnew file found");
}

return null; // Return null if no existing chat was found
} catch (error) {
logger.error("Error selecting directory:", error);
return null;
}
}

export async function getDirectoryHandle(): Promise<
FileSystemDirectoryHandle | null
> {
export async function getDirectoryHandle(): Promise<FileSystemDirectoryHandle | null> {
const currentHandle = selectedDirectoryHandle.get();

if (currentHandle) {
return currentHandle;
}
if (currentHandle) {
return currentHandle;
}

const savedPath = localStorage.getItem("selectedDirectoryPath");
const savedPath = localStorage.getItem("selectedDirectoryPath");

if (savedPath) {
try {
const handle = await window.showDirectoryPicker({ startIn: savedPath });
selectedDirectoryHandle.set(handle);
if (savedPath) {
try {
const handle = await window.showDirectoryPicker({ startIn: savedPath });
selectedDirectoryHandle.set(handle);

return handle;
} catch (error) {
console.error("Error retrieving saved directory:", error);
}
return handle;
} catch (error) {
console.error("Error retrieving saved directory:", error);
}
}

return null;
return null;
}

export async function writeFile(
filePath: string,
content: string,
content: string
): Promise<void> {
const directoryHandle = await getDirectoryHandle();

Expand Down Expand Up @@ -131,7 +147,7 @@ export async function writeFile(

export async function updateFile(
filePath: string,
content: string,
content: string
): Promise<void> {
try {
await writeFile(filePath, content);
Expand Down Expand Up @@ -160,13 +176,6 @@ export async function readFile(name: string): Promise<string> {
}
}

/*
* export async function createBoltNewFile(chatId: string): Promise<void> {
* const content = JSON.stringify({ chatId });
* await writeFile('.boltnew', content);
* }
*/

export async function checkForFileChanges(): Promise<void> {
const directoryHandle = await getDirectoryHandle();

Expand All @@ -179,7 +188,7 @@ export async function checkForFileChanges(): Promise<void> {

async function traverseDirectory(
dirHandle: FileSystemDirectoryHandle,
currentPath: string = "",
currentPath: string = ""
) {
for await (const entry of dirHandle.values()) {
const entryPath = currentPath
Expand Down Expand Up @@ -227,15 +236,15 @@ export async function readBoltNewFile(): Promise<string | null> {

export async function writeBoltNewJson(
chatId: string,
chatItem: ChatHistoryItem,
chatItem: ChatHistoryItem
): Promise<void> {
const fileName = `${chatId}.boltnew.json`;
const content = JSON.stringify(chatItem, null, 2);
await writeFile(fileName, content);
}

export async function readBoltNewJson(
chatId: string,
chatId: string
): Promise<ChatHistoryItem | null> {
try {
const fileName = `${chatId}.boltnew.json`;
Expand Down
50 changes: 37 additions & 13 deletions app/lib/persistence/useChatHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,31 @@ export function useChatHistory() {

if (chatIdToUse) {
try {
const storedMessages = await getMessages(db, chatIdToUse);
if (storedMessages && storedMessages.messages.length > 0) {
setInitialMessages(storedMessages.messages);
setUrlId(storedMessages.urlId);
description.set(storedMessages.description);
chatId.set(storedMessages.id);
// First, try to get the chat history from the local folder
const localChatItem = await FileSystem.readBoltNewJson(chatIdToUse);

if (localChatItem && localChatItem.messages.length > 0) {
setInitialMessages(localChatItem.messages);
setUrlId(localChatItem.urlId);
description.set(localChatItem.description);
chatId.set(localChatItem.id);

// Update the files in the workbench with the latest content from the local folder
await FileSystem.createProjectFiles(localChatItem);
} else {
navigate(`/`, { replace: true });
// If not found in the local folder, fallback to IndexedDB
const storedMessages = await getMessages(db, chatIdToUse);
if (storedMessages && storedMessages.messages.length > 0) {
setInitialMessages(storedMessages.messages);
setUrlId(storedMessages.urlId);
description.set(storedMessages.description);
chatId.set(storedMessages.id);

// Update the local folder with the content from IndexedDB
await FileSystem.createProjectFiles(storedMessages);
} else {
navigate(`/`, { replace: true });
}
}
} catch (error) {
toast.error((error as Error).message);
Expand Down Expand Up @@ -107,17 +124,24 @@ export function useChatHistory() {
}
}

await setMessages(db, chatId.get() as string, messages, urlId, description.get());
const chatItem: ChatHistoryItem = {
id: chatId.get() as string,
urlId,
description: description.get(),
messages,
timestamp: new Date().toISOString(),
};

await setMessages(db, chatItem.id, messages, urlId, description.get());

// Update the local folder with the latest chat history
await FileSystem.writeBoltNewJson(chatItem.id, chatItem);
await FileSystem.createProjectFiles(chatItem);
},
};
}

function navigateChat(nextId: string) {
/**
* FIXME: Using the intended navigate function causes a rerender for <Chat /> that breaks the app.
*
* `navigate(`/chat/${nextId}`, { replace: true });`
*/
const url = new URL(window.location.href);
url.pathname = `/chat/${nextId}`;

Expand Down
16 changes: 13 additions & 3 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Header } from '~/components/header/Header';
import { useEffect } from 'react';
import { selectDirectory, selectedDirectoryHandle } from '~/lib/persistence/fileSystem';
import { useStore } from '@nanostores/react';
import { useNavigate } from '@remix-run/react';

export const meta: MetaFunction = () => {
return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];
Expand All @@ -15,12 +16,17 @@ export const loader = () => json({});

export default function Index() {
const directoryHandle = useStore(selectedDirectoryHandle);
const navigate = useNavigate();

useEffect(() => {
if (!directoryHandle) {
selectDirectory().catch(console.error);
selectDirectory().then((existingChatId) => {
if (existingChatId) {
navigate(`/chat/${existingChatId}`);
}
}).catch(console.error);
}
}, [directoryHandle]);
}, [directoryHandle, navigate]);

return (
<div className="flex flex-col h-full w-full">
Expand All @@ -30,7 +36,11 @@ export default function Index() {
) : (
<div className="flex items-center justify-center h-full">
<button
onClick={selectDirectory}
onClick={() => selectDirectory().then((existingChatId) => {
if (existingChatId) {
navigate(`/chat/${existingChatId}`);
}
})}
className="px-4 py-2 bg-bolt-elements-button-primary-background text-bolt-elements-button-primary-text rounded-md hover:bg-bolt-elements-button-primary-backgroundHover"
>
Select Directory to Start
Expand Down

0 comments on commit baf54b8

Please sign in to comment.