diff --git a/modules/rnotes/components/folk-notes-app.ts b/modules/rnotes/components/folk-notes-app.ts index 15c10b5..f60fc0a 100644 --- a/modules/rnotes/components/folk-notes-app.ts +++ b/modules/rnotes/components/folk-notes-app.ts @@ -137,6 +137,8 @@ class FolkNotesApp extends HTMLElement { private expandedNotebooks = new Set(); private notebookNotes = new Map(); private sidebarOpen = true; + private mobileEditing = false; + private _resizeHandler: (() => void) | null = null; // Zone-based rendering private navZone!: HTMLDivElement; @@ -219,6 +221,18 @@ class FolkNotesApp extends HTMLElement { if (!localStorage.getItem("rnotes_tour_done")) { setTimeout(() => this._tour.start(), 1200); } + + // Mobile resize handler — sync mobile-editing state on viewport change + this._resizeHandler = () => { + if (window.innerWidth > 768) { + // Switched to desktop — remove mobile-editing so both panels show + this.setMobileEditing(false); + } else if (this.selectedNote && this.editor) { + // Went back to mobile with a note open — restore editor screen + this.setMobileEditing(true); + } + }; + window.addEventListener('resize', this._resizeHandler); } private async subscribeOfflineRuntime() { @@ -285,27 +299,6 @@ class FolkNotesApp extends HTMLElement { this.shadow.appendChild(style); this.shadow.appendChild(layout); - - // Mobile sidebar toggle - const mobileToggle = document.createElement('button'); - mobileToggle.className = 'mobile-sidebar-toggle'; - mobileToggle.innerHTML = '\u{1F4C4}Docs'; - mobileToggle.addEventListener('click', () => { - this.sidebarOpen = !this.sidebarOpen; - this.navZone.querySelector('.notes-sidebar')?.classList.toggle('open', this.sidebarOpen); - this.shadow.querySelector('.sidebar-overlay')?.classList.toggle('open', this.sidebarOpen); - }); - this.shadow.appendChild(mobileToggle); - - // Mobile overlay - const overlay = document.createElement('div'); - overlay.className = 'sidebar-overlay'; - overlay.addEventListener('click', () => { - this.sidebarOpen = false; - this.navZone.querySelector('.notes-sidebar')?.classList.remove('open'); - overlay.classList.remove('open'); - }); - this.shadow.appendChild(overlay); } // ── Demo data ── @@ -577,9 +570,33 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF this.mountEditor(newNote); } + // ── Mobile stack navigation ── + + private setMobileEditing(editing: boolean) { + this.mobileEditing = editing; + this.shadow.getElementById('notes-layout')?.classList.toggle('mobile-editing', editing); + } + + private mobileGoBack() { + this.setMobileEditing(false); + } + + private mobileBackBarHtml(): string { + const title = this.selectedNotebook?.title || 'Notes'; + return `

`; + } + + private isMobile(): boolean { + return window.innerWidth <= 768; + } + disconnectedCallback() { this.destroyEditor(); this.cleanupPresence(); + if (this._resizeHandler) { + window.removeEventListener('resize', this._resizeHandler); + this._resizeHandler = null; + } this._offlineUnsub?.(); this._offlineUnsub = null; for (const unsub of this._offlineNotebookUnsubs) unsub(); @@ -1051,11 +1068,9 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF private async openNote(noteId: string, notebookId: string) { const isDemo = this.space === "demo"; - // Auto-close sidebar on mobile - if (window.innerWidth <= 768) { - this.sidebarOpen = false; - this.navZone.querySelector('.notes-sidebar')?.classList.remove('open'); - this.shadow.querySelector('.sidebar-overlay')?.classList.remove('open'); + // Mobile: slide to editor screen + if (this.isMobile()) { + this.setMobileEditing(true); } // Expand notebook if not expanded @@ -1210,6 +1225,11 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF case 'AUDIO': this.mountAudioView(note, isEditable, isDemo); break; default: this.mountTiptapEditor(note, isEditable, isDemo); break; } + + // Mobile: inject back bar and slide to editor + this.contentZone.insertAdjacentHTML('afterbegin', this.mobileBackBarHtml()); + this.contentZone.querySelector('.mobile-back-btn')?.addEventListener('click', () => this.mobileGoBack()); + if (this.isMobile()) this.setMobileEditing(true); } private mountTiptapEditor(note: Note, isEditable: boolean, isDemo: boolean) { @@ -3229,22 +3249,9 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF .editor-empty-state svg { width: 48px; height: 48px; opacity: 0.4; } .editor-empty-state p { font-size: 14px; } - /* Mobile sidebar */ - .mobile-sidebar-toggle { - display: none; position: fixed; bottom: 20px; left: 20px; z-index: 198; - min-width: 44px; height: 44px; border-radius: 22px; border: none; - padding: 0 14px; gap: 4px; - background: var(--rs-primary); color: #fff; font-size: 13px; - cursor: pointer; box-shadow: var(--rs-shadow-md); - align-items: center; justify-content: center; - } - .mobile-toggle-icon { font-size: 18px; } - .mobile-toggle-label { font-weight: 600; font-family: inherit; } - .sidebar-overlay { - display: none; position: fixed; inset: 0; - background: rgba(0,0,0,0.4); z-index: 199; - } - .sidebar-overlay.open { display: block; } + /* Mobile sidebar (legacy — hidden, replaced by stack nav) */ + .mobile-sidebar-toggle { display: none; } + .sidebar-overlay { display: none; } /* ── Navigation ── */ .rapp-nav__btn { padding: 6px 14px; border-radius: 6px; border: none; background: var(--rs-primary); color: #fff; font-weight: 600; cursor: pointer; font-size: 13px; transition: background 0.15s; display: flex; align-items: center; gap: 4px; } @@ -3521,15 +3528,42 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF .tiptap-container .tiptap s { color: var(--rs-text-muted); } .tiptap-container .tiptap u { text-underline-offset: 3px; } + /* ── Mobile back bar (hidden on desktop) ── */ + .mobile-back-bar { display: none; } @media (max-width: 768px) { - #notes-layout { grid-template-columns: 1fr; } - .notes-sidebar { - position: fixed; left: 0; top: 0; bottom: 0; width: 280px; - z-index: 200; transform: translateX(-100%); - transition: transform 0.25s ease; box-shadow: var(--rs-shadow-lg); + /* Two-screen horizontal stack: nav (100%) + editor (100%) side-by-side */ + #notes-layout { + display: flex; overflow: hidden; + grid-template-columns: unset; } - .notes-sidebar.open { transform: translateX(0); } - .mobile-sidebar-toggle { display: flex !important; } + #nav-zone, .notes-right-col { + flex: 0 0 100%; min-width: 0; + transition: transform 0.3s ease; + } + /* Slide both panels left when editing */ + #notes-layout.mobile-editing > #nav-zone, + #notes-layout.mobile-editing > .notes-right-col { + transform: translateX(-100%); + } + /* Sidebar fills screen width */ + .notes-sidebar { width: 100%; position: static; transform: none; box-shadow: none; } + /* Hide old overlay FAB (no longer needed) */ + .mobile-sidebar-toggle, .sidebar-overlay { display: none !important; } + /* Hide empty state on mobile — user sees doc list */ + .editor-empty-state { display: none; } + /* Show back bar */ + .mobile-back-bar { + display: flex; align-items: center; + padding: 8px 12px; border-bottom: 1px solid var(--rs-border-subtle); + background: var(--rs-bg-surface); + } + .mobile-back-btn { + background: none; border: none; color: var(--rs-primary); + font-size: 15px; font-weight: 600; cursor: pointer; + padding: 4px 8px; border-radius: 6px; font-family: inherit; + } + .mobile-back-btn:hover { background: var(--rs-bg-surface-raised); } + /* Tighten editor padding */ .editor-wrapper .editable-title { padding: 12px 14px 0; } .tiptap-container .tiptap { padding: 14px 16px; } .sidebar-footer-btn { min-height: 36px; padding: 7px 12px; }