Export Settings
diff --git a/js/editor-actions.js b/js/editor-actions.js
index 15cba5a..f1712c4 100644
--- a/js/editor-actions.js
+++ b/js/editor-actions.js
@@ -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() {
@@ -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(" Downloaded");
+ window.showToast(" Exported");
},
handleImportMd(file) {
diff --git a/js/ui.js b/js/ui.js
index fb5fe30..7256d8e 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -30,6 +30,7 @@ window.closePromptModal = function () { document.getElementById('prompt-modal')?
window.closePatGuideModal = function () { document.getElementById('pat-guide-modal')?.classList.remove('show'); };
window.closeDocsModal = function () { document.getElementById('docs-modal')?.classList.remove('show'); };
window.closeManageModal = function () { document.getElementById('management-modal')?.classList.remove('show'); };
+window.closeTransferModal = function () { document.getElementById('transfer-modal')?.classList.remove('show'); };
// window.closeNotesModal is now handled in editor-core.js
@@ -45,23 +46,62 @@ document.addEventListener('DOMContentLoaded', () => {
let tooltipTimeout;
const showTooltip = (el, text) => {
- const rect = el.getBoundingClientRect();
+ if (!el || el.offsetWidth === 0) return;
+
tooltip.textContent = text;
- tooltip.classList.add('show');
- // Centered position above the element
+ // Temporarily show to measure dimensions accurately
+ tooltip.style.display = 'block';
+ tooltip.style.visibility = 'hidden';
+ tooltip.classList.remove('show');
+
+ const rect = el.getBoundingClientRect();
const tooltipRect = tooltip.getBoundingClientRect();
- tooltip.style.top = `${rect.top - tooltipRect.height - 8}px`;
- tooltip.style.left = `${rect.left + (rect.width / 2) - (tooltipRect.width / 2)}px`;
+
+ let top = rect.top - tooltipRect.height - 10;
+ let left = rect.left + (rect.width / 2) - (tooltipRect.width / 2);
+
+ // Viewport boundaries
+ const padding = 12;
+ if (left < padding) left = padding;
+ if (left + tooltipRect.width > window.innerWidth - padding) {
+ left = window.innerWidth - tooltipRect.width - padding;
+ }
+
+ // Vertical flipping with bottom boundary check
+ if (top < padding) {
+ const bottomTop = rect.bottom + 10;
+ if (bottomTop + tooltipRect.height > window.innerHeight - padding) {
+ // If it doesn't fit at bottom either, pick the side with more space
+ if (rect.top > (window.innerHeight - rect.bottom)) {
+ top = padding;
+ } else {
+ top = window.innerHeight - tooltipRect.height - padding;
+ }
+ } else {
+ top = bottomTop;
+ }
+ }
+
+ tooltip.style.top = `${top}px`;
+ tooltip.style.left = `${left}px`;
+
+ // Clear measurement styles and show
+ tooltip.style.display = '';
+ tooltip.style.visibility = '';
+ tooltip.classList.add('show');
};
const hideTooltip = () => {
tooltip.classList.remove('show');
};
+ let currentTooltipTarget = null;
+
document.addEventListener('mouseover', (e) => {
const target = e.target.closest('[data-tooltip]');
- if (target) {
+ if (target && target !== currentTooltipTarget) {
+ currentTooltipTarget = target;
clearTimeout(tooltipTimeout);
tooltipTimeout = setTimeout(() => showTooltip(target, target.getAttribute('data-tooltip')), 400);
}
@@ -69,7 +109,10 @@ document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('mouseout', (e) => {
const target = e.target.closest('[data-tooltip]');
- if (target) {
+ const related = e.relatedTarget?.closest?.('[data-tooltip]');
+
+ if (target && target !== related) {
+ currentTooltipTarget = null;
clearTimeout(tooltipTimeout);
hideTooltip();
}
@@ -154,6 +197,7 @@ document.addEventListener('DOMContentLoaded', () => {
document.getElementById('manage-modal-close')?.addEventListener('click', window.closeManageModal);
document.getElementById('notes-modal-close')?.addEventListener('click', window.closeNotesModal);
+ document.getElementById('transfer-modal-close')?.addEventListener('click', window.closeTransferModal);
document.getElementById('btn-docs')?.addEventListener('click', () => {
document.getElementById('docs-modal')?.classList.add('show');
@@ -220,6 +264,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (document.getElementById('delete-modal')?.classList.contains('show')) { document.getElementById('delete-cancel')?.click(); return; }
if (document.getElementById('pdf-modal')?.classList.contains('show')) { document.getElementById('modal-cancel')?.click(); return; }
if (document.getElementById('rename-modal')?.classList.contains('show')) { document.getElementById('rename-cancel')?.click(); return; }
+ if (document.getElementById('transfer-modal')?.classList.contains('show')) { window.closeTransferModal(); return; }
if (document.getElementById('setup-modal')?.classList.contains('show')) { document.getElementById('btn-cancel-setup')?.click(); return; }
if (document.getElementById('pat-guide-modal')?.classList.contains('show')) { document.getElementById('pat-guide-close')?.click(); return; }
diff --git a/mobile.css b/mobile.css
index 0436d1c..7ebb935 100644
--- a/mobile.css
+++ b/mobile.css
@@ -37,64 +37,28 @@
box-shadow: 0 2px 10px var(--shadow-color);
}
- #mobile-menu-btn {
- appearance: none;
- outline: none;
- background: transparent;
- border: none;
- color: var(--text-color);
- cursor: pointer;
- padding: 10px;
- margin-left: -8px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 12px;
+ #mobile-menu-btn, #mobile-view-toggle {
+ width: 36px !important;
+ height: 36px !important;
+ border: none !important;
+ opacity: 0.8;
}
- #mobile-menu-btn:active {
- background-color: var(--hover-bg);
- transform: scale(0.95);
+ #mobile-menu-btn:active, #mobile-view-toggle:active {
+ background-color: var(--toggle-pill) !important;
+ opacity: 1;
+ transform: scale(0.92);
}
.brand {
font-size: 1.15rem;
flex: 1;
- text-align: left;
+ text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
- #mobile-view-toggle {
- appearance: none;
- outline: none;
- background-color: transparent !important;
- border: 1.5px solid var(--border-color) !important;
- color: var(--text-color) !important;
- width: 40px !important;
- height: 40px !important;
- border-radius: 12px !important;
- display: flex !important;
- align-items: center;
- justify-content: center;
- padding: 0 !important;
- box-shadow: none !important;
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
- flex-shrink: 0;
- }
-
- #mobile-view-toggle i {
- width: 20px !important;
- height: 20px !important;
- margin: 0 !important;
- }
-
- #mobile-view-toggle:active {
- background-color: var(--hover-bg) !important;
- transform: scale(0.92);
- }
-
/* WORKSPACE */
.app-container {
flex: 1 !important;
diff --git a/style.css b/style.css
index 79452db..6d238b6 100644
--- a/style.css
+++ b/style.css
@@ -530,25 +530,6 @@ body.dark-mode .action-pill-group {
opacity: 0.9;
}
-.sync-note-btn {
- color: #10b981;
- border: 1px solid rgba(16, 185, 129, 0.4);
-}
-
-.sync-note-btn:hover {
- background: rgba(16, 185, 129, 0.1);
- border-color: #10b981;
-}
-
-.push-all-btn {
- color: #3b82f6;
- border: 1px solid rgba(59, 130, 246, 0.4);
-}
-
-.push-all-btn:hover {
- background: rgba(59, 130, 246, 0.1);
- border-color: #3b82f6;
-}
.sb-action-btn:disabled {
opacity: 0.5;
@@ -654,14 +635,14 @@ body.dark-mode .toolbar-group {
background-color: var(--toggle-pill);
opacity: 1;
transform: translateY(-1px);
- box-shadow: 0 2px 8px var(--toggle-shadow);
+ box-shadow: 0 2px 8px var(--toggle-shadow), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.toolbar-group .tool-btn.active {
background-color: var(--toggle-pill);
color: var(--accent-color);
opacity: 1;
- box-shadow: 0 2px 8px var(--toggle-shadow);
+ box-shadow: 0 2px 8px var(--toggle-shadow), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.toolbar-spacer {
@@ -2262,7 +2243,7 @@ input:checked + .slider:before {
opacity: 0;
transform: translateY(5px);
transition: opacity 0.2s ease, transform 0.2s ease;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.25);
white-space: nowrap;
}