diff --git a/src/index.html b/src/index.html index 7f8ca89..f0ea436 100644 --- a/src/index.html +++ b/src/index.html @@ -10,6 +10,7 @@ + diff --git a/src/renderer.js b/src/renderer.js index e8e1167..91b76e4 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -18,6 +18,7 @@ const { renderSnippetsPanel } = require('./sidebar/snippets-panel'); const { ReplPanel } = require('./repl/repl-panel'); const { CommandPalette } = require('./command-palette'); const { PrintPreview } = require('./print-preview'); +const { createWelcomeContent } = require('./welcome'); // Configure marked with highlight extension marked.use(markedHighlight({ @@ -1192,6 +1193,52 @@ document.addEventListener('DOMContentLoaded', () => { }) }); + // Welcome tab on startup + const hasLaunched = localStorage.getItem('hasLaunchedBefore'); + const showWelcome = localStorage.getItem('showWelcomeOnStartup') !== 'false'; + + if (!hasLaunched || showWelcome) { + localStorage.setItem('hasLaunchedBefore', 'true'); + + // Set welcome content in the first tab's preview + const recentFiles = JSON.parse(localStorage.getItem('recentFiles') || '[]'); + const welcomeHtml = createWelcomeContent(recentFiles); + + const tab = tabManager.tabs.get(tabManager.activeTabId); + if (tab) { + tab.title = 'Welcome'; + tab.content = ''; + const preview = document.getElementById(`preview-${tab.id}`); + if (preview) { + preview.innerHTML = welcomeHtml; + // Wire up card actions + preview.querySelectorAll('.welcome-card').forEach(card => { + card.addEventListener('click', () => { + const action = card.dataset.action; + if (action === 'new-file') tabManager.createNewTab(); + else if (action === 'open-file') ipcRenderer.send('menu-open'); + else if (action === 'open-template') sidebarManager.togglePanel('templates'); + else if (action === 'command-palette') { + if (typeof commandPalette !== 'undefined') commandPalette.open(); + } + }); + }); + // Wire up recent files + preview.querySelectorAll('.welcome-recent-item').forEach(item => { + item.addEventListener('click', () => ipcRenderer.send('open-file-path', item.dataset.path)); + }); + // Wire up show-on-startup checkbox + const checkbox = document.getElementById('show-welcome-startup'); + if (checkbox) { + checkbox.addEventListener('change', () => { + localStorage.setItem('showWelcomeOnStartup', checkbox.checked); + }); + } + } + tabManager.updateTabBar(); + } + } + // Image paste handler document.addEventListener('paste', async (e) => { const items = e.clipboardData?.items; diff --git a/src/styles-welcome.css b/src/styles-welcome.css new file mode 100644 index 0000000..329e178 --- /dev/null +++ b/src/styles-welcome.css @@ -0,0 +1,24 @@ +.welcome-container { padding: 40px; max-width: 900px; margin: 0 auto; } +.welcome-hero { text-align: center; margin-bottom: 40px; } +.welcome-title { font-size: 32px; font-weight: 700; color: var(--gray-800, #1f2937); } +.welcome-version { font-size: 14px; color: var(--primary-dark, #5661b3); margin-top: 4px; font-weight: 500; } +.welcome-subtitle { font-size: 16px; color: var(--gray-500, #6b7280); margin-top: 8px; } +.welcome-grid { display: grid; gap: 32px; } +.welcome-section h2 { font-size: 18px; margin-bottom: 16px; color: var(--gray-700, #374151); } +.welcome-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; } +.welcome-card { padding: 20px; border: 1px solid var(--gray-200, #e5e7eb); border-radius: 12px; cursor: pointer; text-align: center; transition: all 0.2s; } +.welcome-card:hover { border-color: var(--primary-dark, #5661b3); box-shadow: 0 4px 12px rgba(0,0,0,0.08); transform: translateY(-2px); } +.welcome-card-icon { font-size: 28px; margin-bottom: 8px; } +.welcome-card h3 { font-size: 15px; margin-bottom: 4px; } +.welcome-card p { font-size: 13px; color: var(--gray-500); } +.welcome-card kbd { display: inline-block; margin-top: 8px; padding: 2px 8px; background: var(--gray-100); border: 1px solid var(--gray-300); border-radius: 4px; font-size: 12px; font-family: 'JetBrains Mono', monospace; } +.welcome-features { list-style: none; padding: 0; } +.welcome-features li { padding: 6px 0; font-size: 14px; border-bottom: 1px solid var(--gray-100, #f3f4f6); } +.welcome-features strong { color: var(--primary-dark, #5661b3); } +.welcome-recent-item { padding: 8px 12px; border-radius: 6px; cursor: pointer; margin-bottom: 4px; } +.welcome-recent-item:hover { background: var(--gray-100); } +.welcome-recent-name { font-size: 14px; font-weight: 500; display: block; } +.welcome-recent-path { font-size: 12px; color: var(--gray-500); display: block; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; } +.welcome-muted { color: var(--gray-400); font-size: 14px; } +.welcome-footer { margin-top: 32px; text-align: center; } +.welcome-checkbox { font-size: 13px; color: var(--gray-500); cursor: pointer; } diff --git a/src/welcome.js b/src/welcome.js new file mode 100644 index 0000000..8045727 --- /dev/null +++ b/src/welcome.js @@ -0,0 +1,78 @@ +function createWelcomeContent(recentFiles = []) { + const recentHtml = recentFiles.length + ? recentFiles.map(f => { + const name = f.split(/[/\\]/).pop(); + return `
No recent files
'; + + return ` +Version 4.0.0
+Professional Markdown Editor & Universal Document Converter
+Create a blank document
+ Ctrl+N +Open an existing file
+ Ctrl+O +Start from a template
+Search all actions
+ Ctrl+Shift+P +