|
1 | 1 | import Editor, { OnChange } from '@monaco-editor/react'; |
2 | 2 | import { invoke } from '@tauri-apps/api/core'; |
3 | | -import { open } from '@tauri-apps/plugin-dialog'; |
| 3 | +import { open, save } from '@tauri-apps/plugin-dialog'; |
4 | 4 | import { openUrl } from '@tauri-apps/plugin-opener'; |
5 | 5 | import { |
6 | 6 | Bug, |
7 | 7 | Check, |
8 | 8 | Copy, |
| 9 | + Download, |
9 | 10 | Eraser, |
10 | 11 | FolderOpen, |
11 | 12 | Github, |
@@ -197,6 +198,42 @@ function App() { |
197 | 198 | } |
198 | 199 | }; |
199 | 200 |
|
| 201 | + const handleDownload = async () => { |
| 202 | + if (!formattedString || isError) { |
| 203 | + return; |
| 204 | + } |
| 205 | + |
| 206 | + try { |
| 207 | + const now = new Date(); |
| 208 | + const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-'); |
| 209 | + const defaultFilename = `formatted-json-${timestamp}.json`; |
| 210 | + |
| 211 | + const filePath = await save({ |
| 212 | + title: 'Save JSON File', |
| 213 | + defaultPath: defaultFilename, |
| 214 | + filters: [ |
| 215 | + { |
| 216 | + name: 'JSON Files', |
| 217 | + extensions: ['json'], |
| 218 | + }, |
| 219 | + { |
| 220 | + name: 'All Files', |
| 221 | + extensions: ['*'], |
| 222 | + }, |
| 223 | + ], |
| 224 | + }); |
| 225 | + |
| 226 | + if (filePath) { |
| 227 | + await invoke('write_file', { |
| 228 | + path: filePath, |
| 229 | + content: formattedString, |
| 230 | + }); |
| 231 | + } |
| 232 | + } catch (error) { |
| 233 | + console.error('Failed to download:', error); |
| 234 | + } |
| 235 | + }; |
| 236 | + |
200 | 237 | const updateUndoRedoState = () => { |
201 | 238 | if (editorRef.current) { |
202 | 239 | const model = editorRef.current.getModel(); |
@@ -374,21 +411,32 @@ function App() { |
374 | 411 | <div |
375 | 412 | className={`editor-header ${isDarkTheme ? 'dark-theme' : ''}`} |
376 | 413 | style={{ fontSize: `${fontSize}px` }}> |
377 | | - <div></div> |
378 | | - <button |
379 | | - onClick={handleCopy} |
380 | | - className={`copy-button ${isCopied ? 'copied' : ''} ${ |
381 | | - isDarkTheme ? 'dark-theme' : '' |
382 | | - }`} |
383 | | - style={{ fontSize: `${fontSize}px` }} |
384 | | - title={isCopied ? 'Copied!' : 'Copy to Clipboard'} |
385 | | - disabled={formattedString === ''}> |
386 | | - {isCopied ? ( |
387 | | - <Check size={Math.max(12, fontSize * 0.8)} /> |
388 | | - ) : ( |
389 | | - <Copy size={Math.max(12, fontSize * 0.8)} /> |
390 | | - )} |
391 | | - </button> |
| 414 | + <div className="editor-actions-left"> |
| 415 | + <button |
| 416 | + onClick={handleCopy} |
| 417 | + className={`copy-button ${isCopied ? 'copied' : ''} ${ |
| 418 | + isDarkTheme ? 'dark-theme' : '' |
| 419 | + }`} |
| 420 | + style={{ fontSize: `${fontSize}px` }} |
| 421 | + title={isCopied ? 'Copied!' : 'Copy to Clipboard'} |
| 422 | + disabled={formattedString === ''}> |
| 423 | + {isCopied ? ( |
| 424 | + <Check size={Math.max(12, fontSize * 0.8)} /> |
| 425 | + ) : ( |
| 426 | + <Copy size={Math.max(12, fontSize * 0.8)} /> |
| 427 | + )} |
| 428 | + </button> |
| 429 | + </div> |
| 430 | + <div className="editor-actions-right"> |
| 431 | + <button |
| 432 | + onClick={handleDownload} |
| 433 | + className={`action-button ${isDarkTheme ? 'dark-theme' : ''}`} |
| 434 | + style={{ fontSize: `${fontSize}px` }} |
| 435 | + title="Download JSON" |
| 436 | + disabled={formattedString === '' || isError}> |
| 437 | + <Download size={Math.max(12, fontSize * 0.8)} /> |
| 438 | + </button> |
| 439 | + </div> |
392 | 440 | </div> |
393 | 441 | <div className={`output ${isError ? 'error' : ''}`}> |
394 | 442 | <Editor |
|
0 commit comments