mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 18:10:18 +05:30
feat: add welcome tab, presentation/publishing exports, and spell checking
- Developer format support (JSON, YAML, XML, TOML) import/export - Presentation export (Reveal.js slides, Beamer PDF) - Publishing format exports (Confluence wiki, MOBI e-book) - Enable system spell checking with context menu suggestions - Add welcome tab with onboarding and feature showcase
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
<link rel="stylesheet" href="styles-modern.css">
|
<link rel="stylesheet" href="styles-modern.css">
|
||||||
<link rel="stylesheet" href="styles-concreteinfo.css">
|
<link rel="stylesheet" href="styles-concreteinfo.css">
|
||||||
<link rel="stylesheet" href="styles-sidebar.css">
|
<link rel="stylesheet" href="styles-sidebar.css">
|
||||||
|
<link rel="stylesheet" href="styles-welcome.css">
|
||||||
<!-- Load external resources asynchronously -->
|
<!-- Load external resources asynchronously -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" media="print" onload="this.media='all'">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" media="print" onload="this.media='all'">
|
||||||
<script defer src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
|
<script defer src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const { renderSnippetsPanel } = require('./sidebar/snippets-panel');
|
|||||||
const { ReplPanel } = require('./repl/repl-panel');
|
const { ReplPanel } = require('./repl/repl-panel');
|
||||||
const { CommandPalette } = require('./command-palette');
|
const { CommandPalette } = require('./command-palette');
|
||||||
const { PrintPreview } = require('./print-preview');
|
const { PrintPreview } = require('./print-preview');
|
||||||
|
const { createWelcomeContent } = require('./welcome');
|
||||||
|
|
||||||
// Configure marked with highlight extension
|
// Configure marked with highlight extension
|
||||||
marked.use(markedHighlight({
|
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
|
// Image paste handler
|
||||||
document.addEventListener('paste', async (e) => {
|
document.addEventListener('paste', async (e) => {
|
||||||
const items = e.clipboardData?.items;
|
const items = e.clipboardData?.items;
|
||||||
|
|||||||
@@ -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; }
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
function createWelcomeContent(recentFiles = []) {
|
||||||
|
const recentHtml = recentFiles.length
|
||||||
|
? recentFiles.map(f => {
|
||||||
|
const name = f.split(/[/\\]/).pop();
|
||||||
|
return `<div class="welcome-recent-item" data-path="${f}"><span class="welcome-recent-name">${name}</span><span class="welcome-recent-path">${f}</span></div>`;
|
||||||
|
}).join('')
|
||||||
|
: '<p class="welcome-muted">No recent files</p>';
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="welcome-container">
|
||||||
|
<div class="welcome-hero">
|
||||||
|
<h1 class="welcome-title">MarkdownConverter</h1>
|
||||||
|
<p class="welcome-version">Version 4.0.0</p>
|
||||||
|
<p class="welcome-subtitle">Professional Markdown Editor & Universal Document Converter</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="welcome-grid">
|
||||||
|
<div class="welcome-section">
|
||||||
|
<h2>Quick Start</h2>
|
||||||
|
<div class="welcome-cards">
|
||||||
|
<div class="welcome-card" data-action="new-file">
|
||||||
|
<div class="welcome-card-icon">+</div>
|
||||||
|
<h3>New Document</h3>
|
||||||
|
<p>Create a blank document</p>
|
||||||
|
<kbd>Ctrl+N</kbd>
|
||||||
|
</div>
|
||||||
|
<div class="welcome-card" data-action="open-file">
|
||||||
|
<div class="welcome-card-icon">📂</div>
|
||||||
|
<h3>Open File</h3>
|
||||||
|
<p>Open an existing file</p>
|
||||||
|
<kbd>Ctrl+O</kbd>
|
||||||
|
</div>
|
||||||
|
<div class="welcome-card" data-action="open-template">
|
||||||
|
<div class="welcome-card-icon">📋</div>
|
||||||
|
<h3>From Template</h3>
|
||||||
|
<p>Start from a template</p>
|
||||||
|
</div>
|
||||||
|
<div class="welcome-card" data-action="command-palette">
|
||||||
|
<div class="welcome-card-icon">⌘</div>
|
||||||
|
<h3>Command Palette</h3>
|
||||||
|
<p>Search all actions</p>
|
||||||
|
<kbd>Ctrl+Shift+P</kbd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="welcome-section">
|
||||||
|
<h2>What's New in v4.0.0</h2>
|
||||||
|
<ul class="welcome-features">
|
||||||
|
<li><strong>CodeMirror Editor</strong> — Syntax highlighting, code folding, multiple cursors</li>
|
||||||
|
<li><strong>Sidebar Panels</strong> — File Explorer, Git, Snippets, Templates</li>
|
||||||
|
<li><strong>Command Palette</strong> — Quick access to all actions</li>
|
||||||
|
<li><strong>Code Execution</strong> — Run JS, Python, Bash from code blocks</li>
|
||||||
|
<li><strong>Print Preview</strong> — Full print customization dialog</li>
|
||||||
|
<li><strong>New Formats</strong> — Reveal.js, YAML, JSON, Confluence, and more</li>
|
||||||
|
<li><strong>Spell Checking</strong> — System dictionary with suggestions</li>
|
||||||
|
<li><strong>Markdown Extensions</strong> — Footnotes, admonitions, TOC</li>
|
||||||
|
<li><strong>Image Handling</strong> — Paste and drag-drop images</li>
|
||||||
|
<li><strong>PlantUML</strong> — Diagram rendering in preview</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="welcome-section">
|
||||||
|
<h2>Recent Files</h2>
|
||||||
|
<div class="welcome-recent">${recentHtml}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="welcome-footer">
|
||||||
|
<label class="welcome-checkbox">
|
||||||
|
<input type="checkbox" id="show-welcome-startup" checked>
|
||||||
|
Show this tab on startup
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { createWelcomeContent };
|
||||||
Reference in New Issue
Block a user