Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 111 additions & 61 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,19 @@
</script>

<header class="navbar">
<button id="mobile-menu-btn" class="mobile-only" data-tooltip="Menu"><i data-lucide="menu"></i></button>
<div class="action-pill-group mobile-only" style="margin-left: -8px;">
<button id="mobile-menu-btn" class="pill-action-btn" data-tooltip="Menu">
<i data-lucide="menu"></i>
</button>
</div>
<div class="brand">Markdown Studio</div>

<div class="actions">
<button id="mobile-view-toggle" class="mobile-only" data-tooltip="Toggle Preview">
<i data-lucide="eye"></i>
</button>
<div class="action-pill-group mobile-only">
<button id="mobile-view-toggle" class="pill-action-btn" data-tooltip="Toggle Preview">
<i data-lucide="eye"></i>
</button>
</div>

<div class="mode-toggle desktop-only" id="nav-mode-toggle">
<button class="mode-tab active" data-target="local" id="nav-tab-local" data-tooltip="Switch to Local Mode">
Expand Down Expand Up @@ -76,7 +82,7 @@
<i data-lucide="book" style="width: 16px; height: 16px;"></i>
</button>
<button id="btn-exit-focus" class="pill-action-btn" data-tooltip="Exit Focus Mode" style="display: none;">
<i data-lucide="minimize"></i>
<i data-lucide="minimize" style="width: 16px; height: 16px;"></i>
</button>
</div>
</div>
Expand Down Expand Up @@ -137,68 +143,71 @@ <h3>Menu</h3>
<button class="tool-btn" data-action="heading" data-tooltip="Heading"><i data-lucide="heading"></i></button>
</div>

<div class="toolbar-divider"></div>
<button class="tool-btn" data-action="align-left" data-tooltip="Align Left"><i
data-lucide="align-left"></i></button>
<button class="tool-btn" data-action="align-center" data-tooltip="Align Center"><i
data-lucide="align-center"></i></button>
<button class="tool-btn" data-action="align-right" data-tooltip="Align Right"><i
data-lucide="align-right"></i></button>
<div class="toolbar-divider"></div>
<button class="tool-btn" data-action="note-link" data-tooltip="Link to another Note"><i
data-lucide="file-symlink"></i></button>
<button class="tool-btn" data-action="link" data-tooltip="Web Link"><i data-lucide="link"></i></button>
<button class="tool-btn" data-action="image" data-tooltip="Image"><i data-lucide="image"></i></button>
<button class="tool-btn" data-action="code" data-tooltip="Code Block"><i data-lucide="code"></i></button>
<button class="tool-btn" data-action="table" data-tooltip="Table"><i data-lucide="table"></i></button>
<button class="tool-btn" data-action="math" data-tooltip="Math Formula"><i data-lucide="sigma"></i></button>
<div class="toolbar-group">
<button class="tool-btn" data-action="align-left" data-tooltip="Align Left"><i
data-lucide="align-left"></i></button>
<button class="tool-btn" data-action="align-center" data-tooltip="Align Center"><i
data-lucide="align-center"></i></button>
<button class="tool-btn" data-action="align-right" data-tooltip="Align Right"><i
data-lucide="align-right"></i></button>
</div>

<div class="toolbar-group">
<button class="tool-btn" data-action="note-link" data-tooltip="Link to another Note"><i
data-lucide="file-symlink"></i></button>
<button class="tool-btn" data-action="link" data-tooltip="Web Link"><i data-lucide="link"></i></button>
<button class="tool-btn" data-action="image" data-tooltip="Image"><i data-lucide="image"></i></button>
<button class="tool-btn" data-action="code" data-tooltip="Code Block"><i data-lucide="code"></i></button>
<button class="tool-btn" data-action="table" data-tooltip="Table"><i data-lucide="table"></i></button>
<button class="tool-btn" data-action="math" data-tooltip="Math Formula"><i data-lucide="sigma"></i></button>
</div>

<div class="toolbar-divider desktop-only"></div>

<div class="custom-dropdown desktop-only" id="font-dropdown" style="margin-right: 4px;">
<div class="dropdown-header" data-tooltip="Change Font">
<span id="font-selected-text">Fredoka</span>
<span class="chevron"><i data-lucide="chevron-down" style="width: 14px; height: 14px;"></i></span>
</div>
<div class="dropdown-list">
<div class="dropdown-item active" data-value="Fredoka" style="font-family: 'Fredoka', sans-serif;">
Fredoka</div>
<div class="dropdown-item" data-value="Playpen Sans" style="font-family: 'Playpen Sans', cursive;">
Playpen Sans</div>
<div class="dropdown-item" data-value="Kalam" style="font-family: 'Kalam', cursive;">Kalam</div>
<div class="dropdown-item" data-value="Comic Neue" style="font-family: 'Comic Neue', cursive;">Comic
Neue</div>
<div class="dropdown-item" data-value="Delius" style="font-family: 'Delius', cursive;">Delius</div>
<div class="toolbar-group desktop-only">
<div class="custom-dropdown" id="font-dropdown">
<div class="dropdown-header" data-tooltip="Change Font">
<span id="font-selected-text">Fredoka</span>
<span class="chevron"><i data-lucide="chevron-down" style="width: 14px; height: 14px;"></i></span>
</div>
<div class="dropdown-list">
<div class="dropdown-item active" data-value="Fredoka" style="font-family: 'Fredoka', sans-serif;">
Fredoka</div>
<div class="dropdown-item" data-value="Playpen Sans" style="font-family: 'Playpen Sans', cursive;">
Playpen Sans</div>
<div class="dropdown-item" data-value="Kalam" style="font-family: 'Kalam', cursive;">Kalam</div>
<div class="dropdown-item" data-value="Comic Neue" style="font-family: 'Comic Neue', cursive;">Comic
Neue</div>
<div class="dropdown-item" data-value="Delius" style="font-family: 'Delius', cursive;">Delius</div>
</div>
</div>
</div>

<div class="toolbar-spacer"></div>

<button class="tool-btn desktop-only" id="btn-focus-mode" data-tooltip="Focus Mode" style="margin-right: 8px;">
<i data-lucide="scan"></i>
</button>

<button class="tool-btn active desktop-only" id="btn-scroll-sync" data-tooltip="Toggle Scroll Sync"
style="margin-right: 8px;">
<i data-lucide="arrow-down-up"></i>
</button>
<div class="toolbar-divider desktop-only" style="margin-right: 8px;"></div>
<div class="toolbar-group desktop-only">
<button class="tool-btn" id="btn-focus-mode" data-tooltip="Focus Mode">
<i data-lucide="scan"></i>
</button>
<button class="tool-btn active" id="btn-scroll-sync" data-tooltip="Toggle Scroll Sync">
<i data-lucide="arrow-down-up"></i>
</button>
</div>

<div class="desktop-only"
style="display: flex; gap: 4px; border: 1px solid var(--border-color); border-radius: 8px; padding: 2px;">
<div class="toolbar-group desktop-only">
<button class="tool-btn view-btn" data-view="editor" data-tooltip="Editor Only"><i
data-lucide="file-edit"></i></button>
<button class="tool-btn view-btn active" data-view="split" data-tooltip="Split View"><i
data-lucide="columns"></i></button>
<button class="tool-btn view-btn" data-view="preview" data-tooltip="Preview Only"><i
data-lucide="monitor"></i></button>
</div>
<div class="toolbar-divider desktop-only"></div>

<input type="file" id="import-file" accept=".md,.txt" style="display: none;" />
<button class="tool-btn" id="btn-import-md" data-tooltip="Import .md file"><i data-lucide="file-up"></i></button>
<button class="tool-btn" id="btn-export-md" data-tooltip="Download .md file"><i
data-lucide="file-down"></i></button>
<div class="toolbar-group">
<button class="tool-btn" id="btn-import-export" data-tooltip="Transfer Notes">
<i data-lucide="arrow-up-down"></i>
</button>
</div>
</div>

<div class="split-workspace" id="split-workspace">
Expand All @@ -223,20 +232,24 @@ <h3>Menu</h3>

<div class="status-bar">
<div class="sb-section" id="sb-left-controls">
<span id="active-mode-indicator"
style="font-weight: 600; color: var(--accent-color); display: flex; align-items: center; gap: 6px;">
<i data-lucide="hard-drive" style="width:14px; height:14px;"></i> Local
</span>
<div class="action-pill-group" style="padding: 4px 12px; gap: 12px;">
<span id="active-mode-indicator"
style="font-weight: 600; color: var(--accent-color); display: flex; align-items: center; gap: 6px; font-size: 0.75rem;">
<i data-lucide="hard-drive" style="width:14px; height:14px;"></i> Local
</span>
<div class="toolbar-divider" style="height: 12px; margin: 0; opacity: 0.3;"></div>
<span id="stat-line-col" style="opacity: 0.8;">Line 1, Col 1</span>
</div>
</div>

<div class="sb-section">
<span id="stat-words">0 Words</span>
<div class="toolbar-divider" style="height: 12px; margin: 0 6px;"></div>
<span id="stat-chars" class="desktop-only">0 Characters</span>
<div class="toolbar-divider desktop-only" style="height: 12px; margin: 0 6px;"></div>
<span id="stat-reading-time" class="desktop-only">0 min read</span>

<div class="toolbar-divider desktop-only" style="height: 14px; margin: 0 12px;"></div>
<div class="action-pill-group desktop-only" style="padding: 4px 16px; gap: 12px;">
<span id="stat-words" style="opacity: 0.8;">0 Words</span>
<div class="toolbar-divider" style="height: 12px; margin: 0; opacity: 0.3;"></div>
<span id="stat-chars" style="opacity: 0.8;">0 Characters</span>
<div class="toolbar-divider" style="height: 12px; margin: 0; opacity: 0.3;"></div>
<span id="stat-reading-time" style="opacity: 0.8;">0 min read</span>
</div>

<div class="mode-toggle sb-theme-toggle desktop-only" id="theme-toggle-desktop">
<button class="mode-tab theme-tab active" data-theme="light">
Expand Down Expand Up @@ -516,6 +529,43 @@ <h3 class="modal-title delete-title" id="delete-modal-title">Delete?</h3>
</div>
</div>

<div class="modal-overlay" id="transfer-modal" style="z-index: 2000;">
<div class="modal-box premium-modal">
<div class="premium-modal-header">
<div class="premium-icon-wrapper" style="background-color: rgba(59, 130, 246, 0.1); color: #3b82f6;"><i data-lucide="arrow-up-down"></i></div>
<h3 class="modal-title">Transfer Notes</h3>
<p class="modal-subtitle">Import or Export your work.</p>
</div>

<div class="mode-toggle" id="transfer-toggle" style="margin-bottom: 24px;">
<button class="mode-tab active" data-target="import">Import</button>
<button class="mode-tab" data-target="export">Export</button>
</div>

<div id="import-section" class="transfer-section">
<div id="drop-zone" class="drop-zone" style="border: 2px dashed var(--border-color); border-radius: 16px; padding: 32px; margin-bottom: 16px; transition: all 0.3s ease;">
<i data-lucide="upload-cloud" style="width: 48px; height: 48px; opacity: 0.5; margin-bottom: 12px;"></i>
<p style="margin-bottom: 12px; font-weight: 500;">Drag & Drop Markdown File</p>
<span style="font-size: 0.8rem; opacity: 0.5; margin-bottom: 12px; display: block;">or</span>
<button class="modal-btn btn-confirm" id="btn-browse-file">Browse File</button>
<input type="file" id="transfer-import-file" accept=".md,.txt" style="display: none;" />
</div>
</div>

<div id="export-section" class="transfer-section" style="display: none;">
<div class="input-group premium-input-group" style="margin-bottom: 24px;">
<label style="text-align: left; display: block; margin-left: 8px;">FILE NAME</label>
<input type="text" class="modal-input" id="export-filename-input" placeholder="note-name" />
</div>
<div class="modal-actions premium-actions">
<button class="modal-btn btn-confirm" id="btn-execute-export" style="width: 100%;">Download .md File</button>
</div>
</div>

<button class="btn-close-dashboard" id="transfer-modal-close" style="position: absolute; top: 16px; right: 16px;"><i data-lucide="x"></i></button>
</div>
</div>

<div class="modal-overlay" id="pdf-modal" style="z-index: 2000;">
<div class="modal-box">
<h3 class="modal-title flex-title"><i data-lucide="file-text"></i> Export Settings</h3>
Expand Down
85 changes: 81 additions & 4 deletions js/editor-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,80 @@ window.EditorActions = {
editor.dispatchEvent(new Event('input'));
});
});

// Transfer Modal Toggle Logic
document.getElementById('btn-import-export')?.addEventListener('click', () => {
const modal = document.getElementById('transfer-modal');
modal.classList.add('show');
const note = window.EditorState.getActiveNote();
const exportInput = document.getElementById('export-filename-input');
if (note && exportInput) {
exportInput.value = note.title;
}
});

document.querySelectorAll('#transfer-toggle .mode-tab').forEach(btn => {
btn.addEventListener('click', (e) => {
const target = e.currentTarget.getAttribute('data-target');
document.querySelectorAll('#transfer-toggle .mode-tab').forEach(b => b.classList.remove('active'));
e.currentTarget.classList.add('active');

if (target === 'import') {
document.getElementById('import-section').style.display = 'block';
document.getElementById('export-section').style.display = 'none';
} else {
document.getElementById('import-section').style.display = 'none';
document.getElementById('export-section').style.display = 'block';
}
});
});

// Browse File
document.getElementById('btn-browse-file')?.addEventListener('click', () => {
document.getElementById('transfer-import-file').click();
});

document.getElementById('transfer-import-file')?.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
this.handleImportMd(e.target.files[0]);
window.closeTransferModal();
}
});

// Drag & Drop
const dropZone = document.getElementById('drop-zone');
if (dropZone) {
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(name => {
dropZone.addEventListener(name, (e) => {
e.preventDefault();
e.stopPropagation();
});
});

['dragenter', 'dragover'].forEach(name => {
dropZone.addEventListener(name, () => dropZone.classList.add('drag-over'));
});

['dragleave', 'drop'].forEach(name => {
dropZone.addEventListener(name, () => dropZone.classList.remove('drag-over'));
});

dropZone.addEventListener('drop', (e) => {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length > 0) {
this.handleImportMd(files[0]);
window.closeTransferModal();
}
});
}

// Execute Export
document.getElementById('btn-execute-export')?.addEventListener('click', () => {
const filename = document.getElementById('export-filename-input').value.trim();
this.handleExportMd(filename);
window.closeTransferModal();
});
},

async handleNoteCreation() {
Expand Down Expand Up @@ -253,19 +327,22 @@ window.EditorActions = {
this.pendingNewNoteData = null;
},

handleExportMd() {
handleExportMd(customFilename = null) {
const editor = document.getElementById('markdown-input');
const text = editor.value;
const blob = new Blob([text], { type: 'text/markdown' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
let safeTitle = window.EditorState.getActiveNote().title.replace(/[/\\?%*:|"<>]/g, '_').toLowerCase();
if (safeTitle === 'untitled_note' || !safeTitle) safeTitle = 'markdown_document';

let filename = customFilename || window.EditorState.getActiveNote().title;
let safeTitle = filename.replace(/[/\\?%*:|"<>]/g, '_');
if (!safeTitle || safeTitle.trim() === '') safeTitle = 'markdown_document';

a.download = `${safeTitle}.md`;
a.click();
URL.revokeObjectURL(url);
window.showToast("<i data-lucide='download'></i> Downloaded");
window.showToast("<i data-lucide='download'></i> Exported");
},

handleImportMd(file) {
Expand Down
Loading