File size: 3,913 Bytes
4af09f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { useEffect, useState } from 'react';
import { getSettings, SettingsType, DEFAULT_SETTINGS, getBackgroundImage } from './lib/db';
import { useFileStore } from './stores/fileStore';
import TreeView from './components/Sidebar/TreeView';
import EditorCore from './components/Editor/EditorCore';
import SettingsModal from './components/Settings/SettingsModal';
import { 
  Settings01Icon, Download01Icon, BorderAll01Icon
} from 'hugeicons-react';

function App() {
  const [settings, setSettings] = useState<SettingsType>(DEFAULT_SETTINGS);
  const [bgImage, setBgImage] = useState<string | null>(null);
  const [showSettings, setShowSettings] = useState(false);
  const [showSidebar, setShowSidebar] = useState(true);

  const { loadFiles } = useFileStore();

  useEffect(() => {
    // Initial data load
    loadFiles();
    
    // Load config from DB
    getSettings().then(setSettings);
    // Load background image
    getBackgroundImage().then(blob => {
      if (blob) {
        if (blob instanceof Blob) {
          setBgImage(URL.createObjectURL(blob));
        } else {
          setBgImage(blob);
        }
      }
    });

    // Entry/Exit Listener
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        setShowSettings(false);
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, []);

  return (
    <div 
      className={`app-container font-${settings.typography.replace(/\s+/g, '-').toLowerCase()}`}
      style={{ '--bg-opacity': settings.bgOpacity, '--fg-opacity': settings.fgOpacity } as any}
    >
      {bgImage && (
        <div 
          className="app-background" 
          style={{ backgroundImage: `url(${bgImage})` }} 
        />
      )}
      
      {showSettings && <SettingsModal onClose={() => setShowSettings(false)} />}
      
      <aside className="mini-sidebar">
        <button 
          className={`btn-icon ${showSidebar ? 'active' : ''}`} 
          onClick={() => setShowSidebar(!showSidebar)} 
          title="Toggle Sidebar" 
          style={{ padding: 8, background: showSidebar ? 'rgba(0,0,0,0.03)' : 'transparent' }}
        >
           <BorderAll01Icon size={20} color={showSidebar ? 'var(--text-primary)' : 'var(--text-secondary)'} />
        </button>
        
        <div style={{ flex: 1 }} />
        <button className="btn-icon" onClick={() => setShowSettings(true)} title="Settings" style={{ padding: 8 }}>
          <Settings01Icon size={20} color="var(--text-secondary)" />
        </button>
        <button 
          className="btn-icon" 
          onClick={async () => {
             const { exportFullWorkspace } = await import('./lib/db');
             const data = await exportFullWorkspace();
             const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
             const url = URL.createObjectURL(blob);
             const a = document.createElement('a');
             a.href = url;
             a.download = `hybrid-workspace-${new Date().toISOString().split('T')[0]}.json`;
             a.click();
          }}
          title="Download Workspace" 
          style={{ padding: 8 }}
        >
          <Download01Icon size={20} color="var(--text-secondary)" />
        </button>
      </aside>

      {showSidebar && (
        <aside className="sidebar-panel">
          <div className="sidebar-header" style={{ padding: '4px 16px', display: 'flex', alignItems: 'center', height: '48px', borderBottom: '1px solid var(--border-color)' }}>
            <span style={{ letterSpacing: '0.05em', textTransform: 'uppercase', fontSize: '10px', fontWeight: 700, opacity: 0.4 }}>WORKSPACE</span>
          </div>
          <TreeView />
        </aside>
      )}

      <main className="editor-main">
        <EditorCore />
      </main>
    </div>
  );
}

export default App;