🎨 Redesign from AnyCoder

#83
Files changed (1) hide show
  1. app.py +222 -31
app.py CHANGED
@@ -1,31 +1,222 @@
1
- """
2
- AnyCoder - AI Code Generator
3
- Main application entry point - now with modular architecture!
4
- """
5
-
6
- # Import initialization functions from modules
7
- from anycoder_app.docs_manager import (
8
- initialize_gradio_docs,
9
- initialize_comfyui_docs,
10
- initialize_fastrtc_docs
11
- )
12
- from anycoder_app.ui import demo
13
-
14
- if __name__ == "__main__":
15
- # Initialize documentation systems
16
- print("Initializing Gradio documentation...")
17
- initialize_gradio_docs()
18
-
19
- print("Initializing ComfyUI documentation...")
20
- initialize_comfyui_docs()
21
-
22
- print("Initializing FastRTC documentation...")
23
- initialize_fastrtc_docs()
24
-
25
- # Launch the application
26
- print("Launching AnyCoder application...")
27
- demo.queue(api_open=False, default_concurrency_limit=20).launch(
28
- show_api=False,
29
- ssr_mode=True,
30
- mcp_server=False
31
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use client';
2
+
3
+ import { useState, useEffect, useRef } from 'react';
4
+ import { CodeEditor } from '@/components/CodeEditor';
5
+ import { ChatPanel } from '@/components/ChatPanel';
6
+ import { Header } from '@/components/Header';
7
+ import { Sidebar } from '@/components/Sidebar';
8
+ import { api } from '@/lib/api';
9
+ import type { Message, Model } from '@/types';
10
+
11
+ export default function Home() {
12
+ const [messages, setMessages] = useState<Message[]>([]);
13
+ const [code, setCode] = useState('');
14
+ const [language, setLanguage] = useState('html');
15
+ const [selectedModel, setSelectedModel] = useState<Model | null>(null);
16
+ const [isGenerating, setIsGenerating] = useState(false);
17
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
18
+ const [username, setUsername] = useState('');
19
+ const [sidebarOpen, setSidebarOpen] = useState(false);
20
+ const [leftPanelWidth, setLeftPanelWidth] = useState(40); // percentage
21
+ const [isResizing, setIsResizing] = useState(false);
22
+
23
+ // Check auth status on mount
24
+ useEffect(() => {
25
+ checkAuth();
26
+ loadModels();
27
+ }, []);
28
+
29
+ const checkAuth = async () => {
30
+ try {
31
+ const status = await api.getAuthStatus();
32
+ setIsAuthenticated(status.authenticated);
33
+ setUsername(status.username || '');
34
+ } catch (error) {
35
+ console.error('Auth check failed:', error);
36
+ }
37
+ };
38
+
39
+ const loadModels = async () => {
40
+ try {
41
+ const models = await api.getModels();
42
+ if (models.length > 0) {
43
+ setSelectedModel(models[0]);
44
+ }
45
+ } catch (error) {
46
+ console.error('Failed to load models:', error);
47
+ }
48
+ };
49
+
50
+ const handleSendMessage = async (message: string, imageUrl?: string) => {
51
+ if (!message.trim() || isGenerating) return;
52
+
53
+ const userMessage: Message = {
54
+ role: 'user',
55
+ content: message,
56
+ timestamp: new Date(),
57
+ };
58
+
59
+ setMessages((prev) => [...prev, userMessage]);
60
+ setIsGenerating(true);
61
+
62
+ try {
63
+ let generatedCode = '';
64
+
65
+ await api.generateCode(
66
+ {
67
+ query: message,
68
+ language,
69
+ model_id: selectedModel?.id || 'zai-org/GLM-4.6V:zai-org',
70
+ provider: 'auto',
71
+ history: messages.map((m) => [m.role, m.content]),
72
+ image_url: imageUrl,
73
+ },
74
+ (chunk) => {
75
+ generatedCode += chunk;
76
+ setCode(generatedCode);
77
+ }
78
+ );
79
+
80
+ const assistantMessage: Message = {
81
+ role: 'assistant',
82
+ content: 'βœ… Code generated successfully!',
83
+ timestamp: new Date(),
84
+ };
85
+
86
+ setMessages((prev) => [...prev, assistantMessage]);
87
+ } catch (error) {
88
+ const errorMessage: Message = {
89
+ role: 'assistant',
90
+ content: `❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
91
+ timestamp: new Date(),
92
+ };
93
+ setMessages((prev) => [...prev, errorMessage]);
94
+ } finally {
95
+ setIsGenerating(false);
96
+ }
97
+ };
98
+
99
+ const handleDeploy = async () => {
100
+ if (!code.trim()) {
101
+ alert('No code to deploy');
102
+ return;
103
+ }
104
+
105
+ try {
106
+ const result = await api.deployCode({
107
+ code,
108
+ language,
109
+ history: messages.map((m) => ({ role: m.role, content: m.content })),
110
+ });
111
+
112
+ if (result.success && result.space_url) {
113
+ alert(`πŸš€ Deployed successfully!\n\nView at: ${result.space_url}`);
114
+ } else {
115
+ alert(`❌ Deployment failed: ${result.message}`);
116
+ }
117
+ } catch (error) {
118
+ alert(`❌ Deployment error: ${error instanceof Error ? error.message : 'Unknown error'}`);
119
+ }
120
+ };
121
+
122
+ // Handle panel resizing
123
+ const handleMouseDown = (e: React.MouseEvent) => {
124
+ e.preventDefault();
125
+ setIsResizing(true);
126
+ document.body.classList.add('resizing');
127
+ };
128
+
129
+ useEffect(() => {
130
+ const handleMouseMove = (e: MouseEvent) => {
131
+ if (!isResizing) return;
132
+
133
+ const containerWidth = window.innerWidth;
134
+ const newWidth = (e.clientX / containerWidth) * 100;
135
+
136
+ // Clamp between 25% and 75%
137
+ const clampedWidth = Math.min(Math.max(newWidth, 25), 75);
138
+ setLeftPanelWidth(clampedWidth);
139
+ };
140
+
141
+ const handleMouseUp = () => {
142
+ setIsResizing(false);
143
+ document.body.classList.remove('resizing');
144
+ };
145
+
146
+ if (isResizing) {
147
+ document.addEventListener('mousemove', handleMouseMove);
148
+ document.addEventListener('mouseup', handleMouseUp);
149
+ }
150
+
151
+ return () => {
152
+ document.removeEventListener('mousemove', handleMouseMove);
153
+ document.removeEventListener('mouseup', handleMouseUp);
154
+ };
155
+ }, [isResizing]);
156
+
157
+ return (
158
+ <div className="flex flex-col h-screen bg-[#1d1d1f] text-[#e5e5e7]">
159
+ <Header
160
+ isAuthenticated={isAuthenticated}
161
+ username={username}
162
+ onMenuClick={() => setSidebarOpen(!sidebarOpen)}
163
+ />
164
+
165
+ <div className="flex flex-1 overflow-hidden">
166
+ {/* Mobile Sidebar Overlay */}
167
+ {sidebarOpen && (
168
+ <div
169
+ className="fixed inset-0 bg-black/50 z-40 md:hidden"
170
+ onClick={() => setSidebarOpen(false)}
171
+ />
172
+ )}
173
+
174
+ {/* Sidebar */}
175
+ <Sidebar
176
+ isOpen={sidebarOpen}
177
+ onClose={() => setSidebarOpen(false)}
178
+ language={language}
179
+ onLanguageChange={setLanguage}
180
+ selectedModel={selectedModel}
181
+ onModelChange={setSelectedModel}
182
+ onDeploy={handleDeploy}
183
+ isAuthenticated={isAuthenticated}
184
+ />
185
+
186
+ {/* Main Content Area - Split View */}
187
+ <div className="flex flex-1 overflow-hidden">
188
+ {/* Left Panel - Chat */}
189
+ <div
190
+ className="flex flex-col bg-[#1d1d1f] border-r border-[#3e3e42]"
191
+ style={{ width: `${leftPanelWidth}%` }}
192
+ >
193
+ <ChatPanel
194
+ messages={messages}
195
+ onSendMessage={handleSendMessage}
196
+ isGenerating={isGenerating}
197
+ isAuthenticated={isAuthenticated}
198
+ />
199
+ </div>
200
+
201
+ {/* Resize Handle */}
202
+ <div
203
+ className="resize-handle"
204
+ onMouseDown={handleMouseDown}
205
+ />
206
+
207
+ {/* Right Panel - Code Editor */}
208
+ <div
209
+ className="flex flex-col bg-[#1e1e1e]"
210
+ style={{ width: `${100 - leftPanelWidth}%` }}
211
+ >
212
+ <CodeEditor
213
+ code={code}
214
+ language={language}
215
+ onChange={setCode}
216
+ />
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </div>
221
+ );
222
+ }