@@ -3,6 +3,9 @@ import { useGit } from '~/lib/hooks/useGit';
33import type { Message } from 'ai' ;
44import { detectProjectCommands , createCommandsMessage } from '~/utils/projectCommands' ;
55import { generateId } from '~/utils/fileUtils' ;
6+ import { useState } from 'react' ;
7+ import { toast } from 'react-toastify' ;
8+ import { LoadingOverlay } from '~/components/ui/LoadingOverlay' ;
69
710const IGNORE_PATTERNS = [
811 'node_modules/**' ,
@@ -37,6 +40,8 @@ interface GitCloneButtonProps {
3740
3841export default function GitCloneButton ( { importChat } : GitCloneButtonProps ) {
3942 const { ready, gitClone } = useGit ( ) ;
43+ const [ loading , setLoading ] = useState ( false ) ;
44+
4045 const onClick = async ( _e : any ) => {
4146 if ( ! ready ) {
4247 return ;
@@ -45,33 +50,34 @@ export default function GitCloneButton({ importChat }: GitCloneButtonProps) {
4550 const repoUrl = prompt ( 'Enter the Git url' ) ;
4651
4752 if ( repoUrl ) {
48- const { workdir, data } = await gitClone ( repoUrl ) ;
49-
50- if ( importChat ) {
51- const filePaths = Object . keys ( data ) . filter ( ( filePath ) => ! ig . ignores ( filePath ) ) ;
52- console . log ( filePaths ) ;
53-
54- const textDecoder = new TextDecoder ( 'utf-8' ) ;
55-
56- // Convert files to common format for command detection
57- const fileContents = filePaths
58- . map ( ( filePath ) => {
59- const { data : content , encoding } = data [ filePath ] ;
60- return {
61- path : filePath ,
62- content : encoding === 'utf8' ? content : content instanceof Uint8Array ? textDecoder . decode ( content ) : '' ,
63- } ;
64- } )
65- . filter ( ( f ) => f . content ) ;
66-
67- // Detect and create commands message
68- const commands = await detectProjectCommands ( fileContents ) ;
69- const commandsMessage = createCommandsMessage ( commands ) ;
70-
71- // Create files message
72- const filesMessage : Message = {
73- role : 'assistant' ,
74- content : `Cloning the repo ${ repoUrl } into ${ workdir }
53+ setLoading ( true ) ;
54+
55+ try {
56+ const { workdir, data } = await gitClone ( repoUrl ) ;
57+
58+ if ( importChat ) {
59+ const filePaths = Object . keys ( data ) . filter ( ( filePath ) => ! ig . ignores ( filePath ) ) ;
60+ console . log ( filePaths ) ;
61+
62+ const textDecoder = new TextDecoder ( 'utf-8' ) ;
63+
64+ const fileContents = filePaths
65+ . map ( ( filePath ) => {
66+ const { data : content , encoding } = data [ filePath ] ;
67+ return {
68+ path : filePath ,
69+ content :
70+ encoding === 'utf8' ? content : content instanceof Uint8Array ? textDecoder . decode ( content ) : '' ,
71+ } ;
72+ } )
73+ . filter ( ( f ) => f . content ) ;
74+
75+ const commands = await detectProjectCommands ( fileContents ) ;
76+ const commandsMessage = createCommandsMessage ( commands ) ;
77+
78+ const filesMessage : Message = {
79+ role : 'assistant' ,
80+ content : `Cloning the repo ${ repoUrl } into ${ workdir }
7581<boltArtifact id="imported-files" title="Git Cloned Files" type="bundled">
7682${ fileContents
7783 . map (
@@ -82,29 +88,38 @@ ${file.content}
8288 )
8389 . join ( '\n' ) }
8490</boltArtifact>` ,
85- id : generateId ( ) ,
86- createdAt : new Date ( ) ,
87- } ;
91+ id : generateId ( ) ,
92+ createdAt : new Date ( ) ,
93+ } ;
8894
89- const messages = [ filesMessage ] ;
95+ const messages = [ filesMessage ] ;
9096
91- if ( commandsMessage ) {
92- messages . push ( commandsMessage ) ;
93- }
97+ if ( commandsMessage ) {
98+ messages . push ( commandsMessage ) ;
99+ }
94100
95- await importChat ( `Git Project:${ repoUrl . split ( '/' ) . slice ( - 1 ) [ 0 ] } ` , messages ) ;
101+ await importChat ( `Git Project:${ repoUrl . split ( '/' ) . slice ( - 1 ) [ 0 ] } ` , messages ) ;
102+ }
103+ } catch ( error ) {
104+ console . error ( 'Error during import:' , error ) ;
105+ toast . error ( 'Failed to import repository' ) ;
106+ } finally {
107+ setLoading ( false ) ;
96108 }
97109 }
98110 } ;
99111
100112 return (
101- < button
102- onClick = { onClick }
103- title = "Clone a Git Repo"
104- className = "px-4 py-2 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary hover:bg-bolt-elements-background-depth-3 transition-all flex items-center gap-2"
105- >
106- < span className = "i-ph:git-branch" />
107- Clone a Git Repo
108- </ button >
113+ < >
114+ < button
115+ onClick = { onClick }
116+ title = "Clone a Git Repo"
117+ className = "px-4 py-2 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary hover:bg-bolt-elements-background-depth-3 transition-all flex items-center gap-2"
118+ >
119+ < span className = "i-ph:git-branch" />
120+ Clone a Git Repo
121+ </ button >
122+ { loading && < LoadingOverlay message = "Please wait while we clone the repository..." /> }
123+ </ >
109124 ) ;
110125}
0 commit comments