import gradio as gr from typing import Dict, Optional, Tuple from file_manager import FileManager, CodeFile, Language from preview_handler import PreviewHandler class CodeShower: """Right panel component for code display, file tree, and previews""" def __init__(self): self.current_files: Dict[str, CodeFile] = {} self.active_file: Optional[str] = None self.preview_handler = PreviewHandler() self.file_manager = FileManager() def create_ui(self): """Create the Gradio UI components for the code shower""" with gr.Column(visible=True, elem_classes="code-shower") as code_column: gr.Markdown("### 📁 Code Shower") with gr.Tabs(): with gr.TabItem("📂 Files"): self.file_tree = gr.HTML( label="", value='
No files yet.
Generate code to see files here.
' ) with gr.TabItem("👁️ Preview"): self.preview_area = gr.HTML( label="", value='
Select a file to preview
' ) with gr.TabItem("📝 View Code"): self.code_area = gr.Code( label="", language="python", value="# Select a file to view code", interactive=False ) # Language selector for new files with gr.Row(): self.new_lang = gr.Dropdown( choices=["python", "javascript", "html", "css", "json"], value="python", label="New file language" ) self.new_filename = gr.Textbox( placeholder="filename.py", label="Filename", scale=2 ) self.add_file_btn = gr.Button("➕ Add File", size="sm", scale=1) return { "file_tree": self.file_tree, "preview_area": self.preview_area, "code_area": self.code_area, "new_lang": self.new_lang, "new_filename": self.new_filename, "add_file_btn": self.add_file_btn } def update_files_display(self): """Update the file tree HTML based on current files""" if not self.current_files: return '
📂 No files yet
Generate code to see files here
' html = '
' for name, file in self.current_files.items(): active_class = "active" if self.active_file == name else "" html += f'''
{name} {file.language.value}
''' html += '
' # Add JavaScript handlers (will be injected via Gradio's JS) html += ''' ''' return html def display_file(self, filename: str): """Display a file's content and preview""" if filename not in self.current_files: return "File not found", "File not found", "" file = self.current_files[filename] self.active_file = filename # Generate preview preview = self.preview_handler.create_preview(file) # Format code code_view = self.preview_handler.format_code_with_syntax(file.content, file.language.value) return preview, code_view, file.content def add_new_file(self, lang: str, filename: str): """Add a new empty file""" if not filename: # Generate default filename ext_map = { "python": "new_file.py", "javascript": "new_file.js", "html": "new_file.html", "css": "new_file.css", "json": "new_file.json", } filename = ext_map.get(lang, "new_file.txt") # Template content based on language templates = { "python": '# New Python file\n\n\ndef main():\n print("Hello World")\n\nif __name__ == "__main__":\n main()', "javascript": '// New JavaScript file\n\nconsole.log("Hello World");', "html": '\n\n\n New Page\n\n\n

Hello World

\n\n', "css": '/* New CSS file */\n\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 20px;\n}', "json": '{\n "name": "example",\n "version": "1.0.0"\n}', } content = templates.get(lang, "# New file") language = self.file_manager.detect_language(filename, content) self.current_files[filename] = CodeFile( name=filename, content=content, language=language, logo=self.file_manager.get_logo(language), extension="." + lang if lang != "javascript" else ".js", can_preview=language in self.file_manager.PREVIEWABLE ) return self.update_files_display(), *self.display_file(filename) def delete_file(self, filename: str): """Delete a file from the current collection""" if filename in self.current_files: del self.current_files[filename] if self.active_file == filename: self.active_file = None if self.current_files: first_file = list(self.current_files.keys())[0] return self.update_files_display(), *self.display_file(first_file) else: empty_preview = '
No files to preview
' empty_code = '# No files to view' return self.update_files_display(), empty_preview, empty_code, "" def extract_and_add_files(self, response_text: str): """Parse AI response and extract code blocks as files""" files = self.file_manager.extract_files_from_code(response_text) # Add/update files for name, file in files.items(): self.current_files[name] = file # Select first file if any if self.current_files: first_file = list(self.current_files.keys())[0] self.active_file = first_file return self.update_files_display(), *self.display_file(first_file) return self.update_files_display(), '
No code blocks found
', '# No code', ""