From 1f63ecb8206b776a808b92ffe83aa3e6567255e8 Mon Sep 17 00:00:00 2001 From: Alexopus Date: Mon, 21 Jul 2025 22:55:21 +0200 Subject: [PATCH] Add font size controls --- CLAUDE.md | 3 +- js/extension.js | 83 ++++++++++++++++++++++++++++++++++++++------ js/notes-sidebar.css | 24 ++++++++++--- 3 files changed, 94 insertions(+), 16 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a7c2285..ead826e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -65,12 +65,13 @@ The extension exposes these REST endpoints: - Active note tracking with tab highlighting - Content persistence across sidebar open/close cycles - Real-time tab rendering on note operations -- Button layout: Save/Rename/LoRA submenu on left, Refresh/Delete on right +- Button layout: Save/Rename/LoRA submenu on left, Delete on right, Zoom in/out and Refresh in tabs area - **Search Functionality**: Live search through note content with highlighted results and line navigation - **Unsaved Changes Tracking**: Visual indicators (*) for modified notes - **Content Preservation**: Tab switching preserves unsaved content - **Change Detection**: Automatic tracking of modifications vs saved state - **Append Integration**: Submenu with three formatting options for appending LoRA lists (extensible for other content types) +- **Font Size Control**: Zoom in/out buttons with persistent settings storage (8-24px range) ### Search Functionality - **Search Input**: Located below button container with "Search lines..." placeholder diff --git a/js/extension.js b/js/extension.js index 64b4f99..563df44 100644 --- a/js/extension.js +++ b/js/extension.js @@ -24,6 +24,8 @@ class NotesSidebar { this.searchResults = null; this.isInitialized = false; this.sidebarElement = null; + this.currentFontSize = app.extensionManager.setting.get('Notes Sidebar.Font Size') || 14; + this.leftButtonContainer = null; // Listen to state changes this.store.addEventListener('stateChanged', (event) => { @@ -162,15 +164,41 @@ class NotesSidebar { this.tabsContainer.appendChild(newTabBtn); - // Right side: refresh button + // Right side: zoom controls and refresh button + const rightControls = document.createElement('div'); + rightControls.style.display = 'flex'; + rightControls.style.gap = '10px'; + + // Zoom button group + const zoomButtonGroup = document.createElement('div'); + zoomButtonGroup.className = 'notes-button-group'; + + const zoomOutBtn = document.createElement('button'); + zoomOutBtn.innerHTML = ''; + zoomOutBtn.className = 'notes-btn'; + zoomOutBtn.title = 'Zoom Out'; + zoomOutBtn.onclick = () => this.zoomOut(); + + const zoomInBtn = document.createElement('button'); + zoomInBtn.innerHTML = ''; + zoomInBtn.className = 'notes-btn'; + zoomInBtn.title = 'Zoom In'; + zoomInBtn.onclick = () => this.zoomIn(); + + zoomButtonGroup.appendChild(zoomOutBtn); + zoomButtonGroup.appendChild(zoomInBtn); + const refreshBtn = document.createElement('button'); refreshBtn.innerHTML = ''; refreshBtn.className = 'notes-btn refresh'; refreshBtn.title = 'Refresh'; refreshBtn.onclick = () => this.refreshNotes(); + rightControls.appendChild(zoomButtonGroup); + rightControls.appendChild(refreshBtn); + tabsWrapper.appendChild(this.tabsContainer); - tabsWrapper.appendChild(refreshBtn); + tabsWrapper.appendChild(rightControls); parent.appendChild(tabsWrapper); } @@ -178,8 +206,8 @@ class NotesSidebar { const buttonContainer = document.createElement('div'); buttonContainer.className = 'notes-button-container'; - const leftButtonContainer = document.createElement('div'); - leftButtonContainer.className = 'notes-button-group'; + this.leftButtonContainer = document.createElement('div'); + this.leftButtonContainer.className = 'notes-button-group'; const rightButtonContainer = document.createElement('div'); rightButtonContainer.className = 'notes-button-group'; @@ -205,12 +233,12 @@ class NotesSidebar { this.deleteBtn.onclick = () => this.deleteActiveNote(); this.deleteBtn.disabled = true; - leftButtonContainer.appendChild(this.saveBtn); - leftButtonContainer.appendChild(this.renameBtn); + this.leftButtonContainer.appendChild(this.saveBtn); + this.leftButtonContainer.appendChild(this.renameBtn); // Append menu will be added later after textarea is created rightButtonContainer.appendChild(this.deleteBtn); - buttonContainer.appendChild(leftButtonContainer); + buttonContainer.appendChild(this.leftButtonContainer); buttonContainer.appendChild(rightButtonContainer); parent.appendChild(buttonContainer); @@ -254,6 +282,9 @@ class NotesSidebar { this.textArea.className = 'notes-textarea'; this.textArea.placeholder = 'Select a note to start editing...'; + // Apply saved font size + this.updateFontSize(); + // Initialize as disabled (will be enabled reactively if there's an active note) this.textArea.disabled = true; @@ -267,9 +298,8 @@ class NotesSidebar { this.appendMenu = new AppendMenu(this.textArea, () => this.onTextAreaChange()); // Add append menu to the left button container - const leftButtonContainer = this.sidebarElement.querySelector('.notes-button-group'); - if (leftButtonContainer) { - leftButtonContainer.appendChild(this.appendMenu.createMenuElements()); + if (this.leftButtonContainer) { + this.leftButtonContainer.appendChild(this.appendMenu.createMenuElements()); } this.contentArea.appendChild(this.textArea); @@ -599,6 +629,28 @@ class NotesSidebar { }); } + zoomIn() { + if (this.currentFontSize < 24) { // Max font size + this.currentFontSize += 1; + this.updateFontSize(); + } + } + + zoomOut() { + if (this.currentFontSize > 8) { // Min font size + this.currentFontSize -= 1; + this.updateFontSize(); + } + } + + updateFontSize() { + if (this.textArea) { + this.textArea.style.fontSize = `${this.currentFontSize}px`; + } + // Save to settings + app.extensionManager.setting.set('Notes Sidebar.Font Size', this.currentFontSize); + } + } @@ -617,6 +669,17 @@ app.registerExtension({ { value: "both", text: "Ctrl+S (note + workflow)" } ], defaultValue: "note_only" + }, + { + id: "Notes Sidebar.Font Size", + name: "Notes Font Size", + type: "slider", + attrs: { + min: 8, + max: 24, + step: 1 + }, + defaultValue: 14 } ], async setup() { diff --git a/js/notes-sidebar.css b/js/notes-sidebar.css index b3e89aa..6f3318b 100644 --- a/js/notes-sidebar.css +++ b/js/notes-sidebar.css @@ -142,6 +142,23 @@ border-right: none; } +.notes-btn:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.notes-btn:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.notes-submenu-container:last-child .notes-btn { + border-top-left-radius: 0px; + border-bottom-left-radius: 0px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + /* Refresh button is standalone and needs group-like styling */ .notes-btn.refresh { border: 1px solid #444; @@ -154,14 +171,11 @@ display: inline-block; } -.notes-submenu-container .notes-btn { - border-right: 1px solid #444; -} - -.notes-submenu-container .notes-btn:last-child { +.notes-submenu-container:last-child .notes-btn { border-right: none; } + .notes-submenu { position: absolute; top: calc(100% + 2px);