Reubencf Claude commited on
Commit
19e8993
·
1 Parent(s): 353ed65

Fix FlutterRunner to load public dart files and add manual save

Browse files

- Add polling mechanism to detect new files loaded into sessionStorage
- Fix issue where public dart files wouldn't load when FlutterRunner already open
- Replace auto-save with manual save button (floppy disk icon)
- Disable save for public files, only allow for secure storage files
- Add visual feedback for save status and loading states

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (1) hide show
  1. app/components/FlutterRunner.tsx +77 -24
app/components/FlutterRunner.tsx CHANGED
@@ -6,7 +6,8 @@ import {
6
  Download,
7
  SidebarSimple,
8
  FileCode,
9
- CaretDown
 
10
  } from '@phosphor-icons/react'
11
  import Window from './Window'
12
 
@@ -167,32 +168,72 @@ export function FlutterRunner({ onClose, onMinimize, onMaximize, onFocus, zIndex
167
  }
168
  }, [initialCode])
169
 
170
- // Auto-save to file every 2 seconds when code changes (only if passkey is set)
171
  useEffect(() => {
172
- if (!passkey || !activeFileName) return
173
-
174
- const saveTimer = setTimeout(async () => {
175
- try {
176
- // Save to secure data
177
- await fetch('/api/data', {
178
- method: 'POST',
179
- headers: { 'Content-Type': 'application/json' },
180
- body: JSON.stringify({
181
- key: passkey,
182
- passkey: passkey,
183
- action: 'save_file',
184
- fileName: activeFileName,
185
- content: code
186
- })
187
- })
188
- setLastSaved(new Date())
189
- } catch (error) {
190
- console.error('Auto-save failed:', error)
 
 
 
 
 
 
 
 
191
  }
192
- }, 2000)
 
 
 
193
 
194
- return () => clearTimeout(saveTimer)
195
- }, [code, passkey, activeFileName])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
 
197
  const handleDownload = () => {
198
  const blob = new Blob([code], { type: 'text/plain' })
@@ -248,6 +289,18 @@ export function FlutterRunner({ onClose, onMinimize, onMaximize, onFocus, zIndex
248
  </div>
249
 
250
  <div className="flex items-center gap-2">
 
 
 
 
 
 
 
 
 
 
 
 
251
  <button
252
  onClick={handleDownload}
253
  className="p-1.5 text-gray-400 hover:text-white hover:bg-[#3e3e42] rounded transition-colors"
 
6
  Download,
7
  SidebarSimple,
8
  FileCode,
9
+ CaretDown,
10
+ FloppyDisk
11
  } from '@phosphor-icons/react'
12
  import Window from './Window'
13
 
 
168
  }
169
  }, [initialCode])
170
 
171
+ // Listen for new files being loaded while the component is already open
172
  useEffect(() => {
173
+ const checkForNewFile = () => {
174
+ const sessionFileContent = sessionStorage.getItem('flutterFileContent')
175
+ const sessionFileName = sessionStorage.getItem('currentFileName')
176
+ const sessionPasskey = sessionStorage.getItem('currentPasskey')
177
+
178
+ if (sessionFileContent) {
179
+ console.log('Detected new file in session storage:', sessionFileName)
180
+ setCode(sessionFileContent)
181
+ setActiveFileName(sessionFileName || 'main.dart')
182
+
183
+ if (sessionPasskey) {
184
+ setPasskey(sessionPasskey)
185
+ }
186
+
187
+ // Update file structure
188
+ setFiles([{
189
+ id: 'root',
190
+ name: 'lib',
191
+ type: 'folder',
192
+ isOpen: true,
193
+ children: [
194
+ { id: 'main', name: sessionFileName || 'main.dart', type: 'file', content: sessionFileContent }
195
+ ]
196
+ }])
197
+
198
+ // Clear session storage after loading
199
+ sessionStorage.removeItem('flutterFileContent')
200
  }
201
+ }
202
+
203
+ // Check every 500ms for new files
204
+ const interval = setInterval(checkForNewFile, 500)
205
 
206
+ return () => clearInterval(interval)
207
+ }, [])
208
+
209
+ // Manual save function
210
+ const handleSave = async () => {
211
+ if (!passkey || !activeFileName) {
212
+ alert('Cannot save: No passkey set. This file is from public storage.')
213
+ return
214
+ }
215
+
216
+ try {
217
+ setLoading(true)
218
+ await fetch('/api/data', {
219
+ method: 'POST',
220
+ headers: { 'Content-Type': 'application/json' },
221
+ body: JSON.stringify({
222
+ key: passkey,
223
+ passkey: passkey,
224
+ action: 'save_file',
225
+ fileName: activeFileName,
226
+ content: code
227
+ })
228
+ })
229
+ setLastSaved(new Date())
230
+ } catch (error) {
231
+ console.error('Save failed:', error)
232
+ alert('Failed to save file')
233
+ } finally {
234
+ setLoading(false)
235
+ }
236
+ }
237
 
238
  const handleDownload = () => {
239
  const blob = new Blob([code], { type: 'text/plain' })
 
289
  </div>
290
 
291
  <div className="flex items-center gap-2">
292
+ <button
293
+ onClick={handleSave}
294
+ disabled={!passkey || loading}
295
+ className={`p-1.5 rounded transition-colors ${
296
+ passkey && !loading
297
+ ? 'text-blue-400 hover:text-blue-300 hover:bg-[#3e3e42]'
298
+ : 'text-gray-600 cursor-not-allowed'
299
+ }`}
300
+ title={passkey ? "Save to Secure Storage" : "Cannot save public files"}
301
+ >
302
+ <FloppyDisk size={16} />
303
+ </button>
304
  <button
305
  onClick={handleDownload}
306
  className="p-1.5 text-gray-400 hover:text-white hover:bg-[#3e3e42] rounded transition-colors"