diff --git a/src/index.html b/src/index.html index 7912757..7f8ca89 100644 --- a/src/index.html +++ b/src/index.html @@ -1536,6 +1536,18 @@ + +
Error rendering preview. Please check your markdown syntax.
'; @@ -1118,23 +1142,42 @@ class TabManager { // Initialize tab manager let tabManager; +let replPanel; document.addEventListener('DOMContentLoaded', () => { tabManager = new TabManager(); + replPanel = new ReplPanel(); // Initialize sidebar const sidebarManager = new SidebarManager(); + let explorerCurrentDir = null; + sidebarManager.registerPanel('explorer', { title: 'Explorer', - render: (container) => { container.innerHTML = 'File explorer coming soon...
'; } + render: (container) => renderExplorerPanel(container, { + listDirectory: (dir) => ipcRenderer.invoke('list-directory', dir), + onFileOpen: (filePath) => ipcRenderer.send('open-file-path', filePath), + currentDir: explorerCurrentDir, + }) }); sidebarManager.registerPanel('git', { title: 'Git', - render: (container) => { container.innerHTML = 'Git panel coming soon...
'; } + render: (container) => renderGitPanel(container, { + gitStatus: () => ipcRenderer.invoke('git-status'), + gitDiff: (file) => ipcRenderer.invoke('git-diff', { file }), + gitStage: (files) => ipcRenderer.invoke('git-stage', { files }), + gitCommit: (message) => ipcRenderer.invoke('git-commit', { message }), + gitLog: () => ipcRenderer.invoke('git-log'), + }) }); sidebarManager.registerPanel('snippets', { title: 'Snippets', - render: (container) => { container.innerHTML = 'Snippets coming soon...
'; } + render: (container) => renderSnippetsPanel(container, { + getSnippets: () => ipcRenderer.invoke('get-snippets'), + saveSnippet: (s) => ipcRenderer.invoke('save-snippet', s), + deleteSnippet: (id) => ipcRenderer.invoke('delete-snippet', id), + onInsert: (code) => tabManager.insertAtCursor(code), + }) }); sidebarManager.registerPanel('templates', { title: 'Templates', diff --git a/src/styles-sidebar.css b/src/styles-sidebar.css index e735570..c32aad6 100644 --- a/src/styles-sidebar.css +++ b/src/styles-sidebar.css @@ -161,3 +161,108 @@ body[class*="dark"] .panel-list-item-title { body[class*="dark"] .panel-list-item-desc { color: #888; } + +/* Explorer Panel */ +.explorer-toolbar { + display: flex; + gap: 4px; + margin-bottom: 8px; +} +.explorer-path { + flex: 1; + padding: 6px 8px; + border: 1px solid var(--gray-300, #d1d5db); + border-radius: 6px; + font-size: 12px; + background: white; + overflow: hidden; + text-overflow: ellipsis; +} +.explorer-browse-btn { + border: 1px solid var(--gray-300, #d1d5db); + border-radius: 6px; + background: white; + cursor: pointer; + padding: 4px 8px; +} +.tree-item { + padding: 3px 0; + cursor: pointer; + font-size: 13px; + user-select: none; +} +.tree-item:hover { + background: var(--gray-100, #f3f4f6); + border-radius: 4px; +} +.tree-icon { + margin-right: 4px; + font-size: 12px; +} +.tree-children { + padding-left: 16px; +} +.tree-folder.collapsed .tree-children { + display: none; +} +.tree-name { + font-size: 13px; +} + +/* Git Panel */ +.git-section { margin-bottom: 16px; } +.git-section-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--gray-500); margin-bottom: 8px; } +.git-file { display: flex; align-items: center; padding: 4px 6px; border-radius: 4px; font-size: 13px; gap: 6px; } +.git-file:hover { background: var(--gray-100, #f3f4f6); } +.git-file-status { font-weight: 700; font-family: monospace; width: 16px; text-align: center; } +.git-file-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.git-stage-btn { border: none; background: var(--gray-200); border-radius: 4px; cursor: pointer; font-size: 14px; width: 22px; height: 22px; } +.git-commit-input { width: 100%; padding: 8px; border: 1px solid var(--gray-300); border-radius: 6px; font-size: 13px; font-family: inherit; resize: vertical; box-sizing: border-box; } +.git-commit-btn { width: 100%; margin-top: 8px; padding: 8px; background: var(--primary-dark, #5661b3); color: white; border: none; border-radius: 6px; font-size: 13px; cursor: pointer; } +.git-commit-btn:hover { opacity: 0.9; } +.git-log-entry { padding: 6px 0; border-bottom: 1px solid var(--gray-100); } +.git-log-msg { font-size: 13px; } +.git-log-meta { font-size: 11px; color: var(--gray-500); margin-top: 2px; } +.git-info { font-size: 13px; color: var(--gray-500); padding: 8px 0; } +.git-loading { font-size: 13px; color: var(--gray-400); } + +/* Snippets Panel */ +.snippets-toolbar { display: flex; gap: 4px; margin-bottom: 8px; } +.snippets-search { flex: 1; padding: 6px 10px; border: 1px solid var(--gray-300); border-radius: 6px; font-size: 13px; } +.snippets-add-btn { width: 32px; border: 1px solid var(--gray-300); border-radius: 6px; background: white; font-size: 18px; cursor: pointer; } +.snippet-item { padding: 8px; border: 1px solid var(--gray-200); border-radius: 6px; margin-bottom: 6px; } +.snippet-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } +.snippet-name { font-size: 13px; font-weight: 500; } +.snippet-lang { font-size: 11px; background: var(--gray-100); padding: 2px 6px; border-radius: 4px; color: var(--gray-500); } +.snippet-preview { font-size: 12px; background: var(--gray-50); padding: 6px; border-radius: 4px; margin: 4px 0; overflow: hidden; max-height: 60px; } +.snippet-preview code { font-family: 'JetBrains Mono', monospace; } +.snippet-actions { display: flex; gap: 4px; } +.snippet-insert { font-size: 12px; padding: 4px 8px; border: 1px solid var(--gray-300); border-radius: 4px; background: white; cursor: pointer; } +.snippet-delete { font-size: 14px; padding: 4px 8px; border: 1px solid var(--gray-300); border-radius: 4px; background: white; cursor: pointer; color: #ef4444; } + +/* Dark theme for sidebar panels */ +body[class*="dark"] .explorer-path, +body[class*="dark"] .explorer-browse-btn, +body[class*="dark"] .snippets-search, +body[class*="dark"] .snippets-add-btn, +body[class*="dark"] .snippet-insert, +body[class*="dark"] .snippet-delete { + background: #2d2d2d; + border-color: #444; + color: #ccc; +} +body[class*="dark"] .git-commit-input { + background: #2d2d2d; + border-color: #444; + color: #ccc; +} +body[class*="dark"] .snippet-item { + border-color: #444; +} +body[class*="dark"] .snippet-preview { + background: #2d2d2d; +} +body[class*="dark"] .tree-item:hover, +body[class*="dark"] .git-file:hover { + background: #333; +} diff --git a/src/styles.css b/src/styles.css index a901a8a..639f488 100644 --- a/src/styles.css +++ b/src/styles.css @@ -290,6 +290,43 @@ body { line-height: 1.6; } +/* Bottom Panel (REPL Output) */ +.bottom-panel { display: flex; flex-direction: column; border-top: 1px solid var(--gray-200, #e5e7eb); flex-shrink: 0; } +.bottom-panel.collapsed { height: 0; overflow: hidden; border: none; } +.bottom-panel:not(.collapsed) { height: 200px; } +.bottom-panel-header { display: flex; justify-content: space-between; align-items: center; padding: 6px 12px; background: var(--gray-50, #f9fafb); border-bottom: 1px solid var(--gray-200); } +.bottom-panel-title { font-size: 13px; font-weight: 600; color: var(--gray-600); } +.bottom-panel-actions { display: flex; gap: 4px; } +.bottom-panel-btn { font-size: 12px; padding: 4px 8px; border: 1px solid var(--gray-300); border-radius: 4px; background: white; cursor: pointer; } +.bottom-panel-content { flex: 1; overflow-y: auto; padding: 12px; font-family: 'JetBrains Mono', monospace; font-size: 13px; background: #1e1e1e; color: #d4d4d4; } +.repl-entry { margin-bottom: 8px; } +.repl-command { color: #569cd6; margin-bottom: 2px; } +.repl-stdout { color: #d4d4d4; white-space: pre-wrap; } +.repl-stderr { color: #f44747; white-space: pre-wrap; } +.repl-error { color: #f44747; } + +/* Code Run Button */ +.code-run-btn { + position: absolute; + top: 6px; + right: 6px; + padding: 4px 10px; + font-size: 12px; + background: var(--primary-dark, #5661b3); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + opacity: 0; + transition: opacity 0.2s; +} +pre:hover .code-run-btn { opacity: 1; } + +/* Dark theme bottom panel */ +body[class*="dark"] .bottom-panel-header { background: #1e1e1e; border-color: #333; } +body[class*="dark"] .bottom-panel-btn { background: #2d2d2d; border-color: #444; color: #ccc; } +body[class*="dark"] .bottom-panel-title { color: #ccc; } + /* Status Bar */ .status-bar { display: flex;