Skip to content

Commit

Permalink
feat: upload files or folders to chat from local
Browse files Browse the repository at this point in the history
  • Loading branch information
muzafferkadir committed Nov 3, 2024
1 parent 64e95a0 commit 21b4021
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 14 deletions.
59 changes: 59 additions & 0 deletions app/components/chat/Chat.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,65 @@ export const ChatImpl = memo(({ initialMessages, storeMessageHistory }: ChatProp

const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;

const addCustomFile = async () => {
const input = document.createElement('input');
input.type = 'file';

input.onchange = async (e) => {
const file = e.target.files[0];
const randomID = Math.random().toString(36).substring(2, 15);
const fileName = file.name;

const content = await file.text();

const newMessage = {
id: randomID,
role: 'assistant',
content: `File Added: ${fileName} <boltArtifact id="${randomID}" title="${fileName}">\n <boltAction type="file" filePath="${fileName}">\n ${content}\n </boltAction>\n</boltArtifact>`,
createdAt: Date.now(),
};

messages.push(newMessage);
await storeMessageHistory(messages);
parseMessages(messages, false);
};

input.click();
};
workbenchStore.addCustomFile = addCustomFile;

const addCustomFolder = async () => {
const input = document.createElement('input');
input.type = 'file';
input.webkitdirectory = true;
input.multiple = true;

input.onchange = async (e) => {
const files = Array.from(e.target.files);

for (const file of files) {
const randomID = Math.random().toString(36).substring(2, 15);
const fileName = file.name;

const content = await file.text();

const newMessage = {
id: randomID,
role: 'assistant',
content: `File Added: ${fileName} <boltArtifact id="${randomID}" title="${fileName}">\n <boltAction type="file" filePath="${fileName}">\n ${content}\n </boltAction>\n</boltArtifact>`,
createdAt: Date.now(),
};

messages.push(newMessage);
await storeMessageHistory(messages);
parseMessages(messages, false);
}
};

input.click();
};
workbenchStore.addCustomFolder = addCustomFolder;

useEffect(() => {
chatStore.setKey('started', initialMessages.length > 0);
}, []);
Expand Down
18 changes: 18 additions & 0 deletions app/components/workbench/EditorPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,24 @@ export const EditorPanel = memo(
<div className="i-ph:tree-structure-duotone shrink-0" />
Files
</PanelHeader>
<PanelHeader>
<button
className="bg-transparent flex gap-2 items-center text-nowrap"
onClick={workbenchStore.addCustomFile}
>
<div className="i-ph:file-arrow-up-duotone shrink-0" />
<span>Upload File</span>
</button>
</PanelHeader>
<PanelHeader>
<button
className="bg-transparent flex gap-2 items-center text-nowrap"
onClick={workbenchStore.addCustomFolder}
>
<div className="i-ph:folder-plus-duotone shrink-0" />
<span>Upload Folder</span>
</button>
</PanelHeader>
<FileTree
className="h-full"
files={files}
Expand Down
36 changes: 22 additions & 14 deletions app/lib/stores/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,20 +336,20 @@ export class WorkbenchStore {
}

async pushToGitHub(repoName: string, githubUsername: string, ghToken: string) {

try {
// Get the GitHub auth token from environment variables
const githubToken = ghToken;

const owner = githubUsername;

if (!githubToken) {
throw new Error('GitHub token is not set in environment variables');
}

// Initialize Octokit with the auth token
const octokit = new Octokit({ auth: githubToken });

// Check if the repository already exists before creating it
let repo
try {
Expand All @@ -368,13 +368,13 @@ export class WorkbenchStore {
throw error; // Some other error occurred
}
}

// Get all files
const files = this.files.get();
if (!files || Object.keys(files).length === 0) {
throw new Error('No files found to push');
}

// Create blobs for each file
const blobs = await Promise.all(
Object.entries(files).map(async ([filePath, dirent]) => {
Expand All @@ -389,21 +389,21 @@ export class WorkbenchStore {
}
})
);

const validBlobs = blobs.filter(Boolean); // Filter out any undefined blobs

if (validBlobs.length === 0) {
throw new Error('No valid files to push');
}

// Get the latest commit SHA (assuming main branch, update dynamically if needed)
const { data: ref } = await octokit.git.getRef({
owner: repo.owner.login,
repo: repo.name,
ref: `heads/${repo.default_branch || 'main'}`, // Handle dynamic branch
});
const latestCommitSha = ref.object.sha;

// Create a new tree
const { data: newTree } = await octokit.git.createTree({
owner: repo.owner.login,
Expand All @@ -416,7 +416,7 @@ export class WorkbenchStore {
sha: blob!.sha,
})),
});

// Create a new commit
const { data: newCommit } = await octokit.git.createCommit({
owner: repo.owner.login,
Expand All @@ -425,20 +425,28 @@ export class WorkbenchStore {
tree: newTree.sha,
parents: [latestCommitSha],
});

// Update the reference
await octokit.git.updateRef({
owner: repo.owner.login,
repo: repo.name,
ref: `heads/${repo.default_branch || 'main'}`, // Handle dynamic branch
sha: newCommit.sha,
});

alert(`Repository created and code pushed: ${repo.html_url}`);
} catch (error) {
console.error('Error pushing to GitHub:', error instanceof Error ? error.message : String(error));
}
}

addCustomFile: () => void = () => {
return;
};

addCustomFolder: () => void = () => {
return;
};
}

export const workbenchStore = new WorkbenchStore();

0 comments on commit 21b4021

Please sign in to comment.