Files
dotfiles/noctalia/plugins/clipper/CHANGELOG_v2.0.0.md
T
Domipoke 955801c666 noctalia
2026-06-25 19:58:23 +02:00

275 lines
9.0 KiB
Markdown

# Clipper Plugin - Changelog
## Version 2.0.0 (2026-02-05)
### 🎯 Major Changes
**New Feature: Add Selection to NoteCard**
- New IPC command: `addSelectionToNoteCard`
- Captures selected text and presents context menu to add to existing notes or create new note
- Text is automatically formatted as bullet points with "- " prefix
- Integrated with Hyprland keybind: Super+V, X (chord)
**Translation System Overhaul**
- Migrated from `I18n.tr()` to `pluginApi?.tr()` across all files
- Added comprehensive `i18n/en.json` with 28 toast message keys
- All user-facing strings now use translation system with fallbacks
- Translation key structure: `component.key` (e.g., `toast.note-created`)
**Architecture Improvements**
- Fixed IPC handlers to use `pluginApi.withCurrentScreen()` instead of direct `Quickshell.screens[0]` access
- Added proper Component.onDestruction cleanup for 6 data structures (pinnedItems, noteCards, items, firstSeenById, imageCache, imageCacheOrder)
- Memory leak prevention with proper process termination
- Unified translation syntax: `pluginApi?.tr("key") || "fallback"`
### 📁 New Files
1. **NoteCardSelector.qml** (173 lines)
- Fullscreen overlay for note selection menu
- Synchronously loads notecards from files
- Shows "Create New Note" + list of existing notes
- Mouse-position-aware context menu
- ESC to cancel, click outside to close
2. **NoteCard.qml** (~300 lines)
- Updated visual style to match ClipboardCard
- Icon + title left-aligned (not centered)
- Transparent buttons without background
- Increased font sizes (13-14px)
- Auto-height expansion based on content
- Drag handle on icon only (24px width)
- All corners rounded on main card
- Only top corners rounded on header
3. **NoteCardsPanel.qml** (updated)
- Background click-to-close functionality
- Controls moved to top-left corner
- Note counter and add button repositioned
- Starting Y position increased to 80px to avoid control overlap
### 🔧 Files Modified
**Main.qml** (+250 lines, massive refactoring)
*New IPC Handlers:*
- `addSelectionToNoteCard()` - Main entry point for feature
- Uses same pattern as `addSelectionToTodo()` for consistency
*New Functions:*
- `getSelectionAndShowNoteSelector()` - Triggers selection capture
- `showNoteCardSelector(text)` - Displays note selection menu
- `handleNoteCardSelected(noteId, noteTitle)` - Handles existing note selection
- `handleCreateNewNoteFromSelection()` - Creates new note with bullet text
- `appendTextToNoteCard(noteId, text)` - Adds bullet point to existing note
*New Process:*
- `getSelectionForNoteSelectorProcess` - Captures primary selection via wl-paste
- StdioCollector: `noteSelectionStdout`
- Calls `showNoteCardSelector()` on successful capture
*New Variants:*
- `NoteCardSelector` instances for each screen
- Registered as `noteCardSelector` property
- Connected to signal handlers for note selection/creation
*New Properties:*
- `noteCardSelector: null` - Reference to selector instance
- `pendingNoteCardText: ""` - Stores captured selection
*Translation Updates:*
- All 28 Toast messages now use `pluginApi?.tr()`
- String interpolation for dynamic values ({max}, {fileName}, {count})
- Consistent error handling with translated messages
*Bug Fixes:*
- Fixed `createNoteCard()` to call `saveNoteCard()` after creation
- Removed duplicate `saveNoteCard(newNote)` calls from wrong functions
- Fixed Component.onDestruction syntax error (duplicate `}`)
**i18n/en.json** (+30 keys)
*New Toast Section:*
```json
"toast": {
"invalid-clipboard-item": "Invalid clipboard item",
"max-pinned-items": "Maximum {max} pinned items reached",
"note-created": "Note created",
"note-not-found": "Note not found",
"text-added-to-note": "Text added to note",
"could-not-open-note-selector": "Could not open note selector",
// ... 22 more keys
}
```
**NoteCard.qml** (visual redesign)
- Header layout changed from centered to left-aligned
- Icon (note) + title in RowLayout
- Drag handle isolated to icon Item (24px width)
- Separate MouseArea for title focus
- Transparent button styling: `colorBg: "transparent"`
- Font changes: removed bold, increased size to 14px
- Radius system:
- Main card: `radius: Style.radiusM` (all corners)
- Header: `topLeftRadius/topRightRadius: Style.radiusM`, bottom: 0
- Auto-height expansion via ScrollView content measurement
- Size changed: 300x180 → 350x280px
- Title input wider, better usability
**NoteCardsPanel.qml**
- Background MouseArea with `z: -1` for click-to-close
- Controls repositioned to `anchors.top` + `anchors.left`
- Note counter + add button in top-left corner
- 16px margins from edges
**ClipboardCard.qml**
- Applied same radius pattern as NoteCard
- Main card: all corners rounded
- Header: top corners only
**BarWidget.qml**
- Migrated `I18n.tr()``pluginApi?.tr()`
- Keys: `bar.tooltip`, `context.toggle`, `context.settings`
**Settings.qml**
- Already had full translation coverage
- Verified all labels use `pluginApi?.tr()`
### 🎨 UI/UX Changes
**NoteCard Visual Updates:**
- More modern, cleaner look matching ClipboardCard
- Better readability with larger fonts
- Improved drag interaction (icon-only handle)
- Responsive to global radius settings (Style.radiusM)
- Auto-expands height based on content
**NoteCardsPanel Improvements:**
- Better spatial organization (controls top-left)
- No accidental close when clicking on notes
- Clear visual hierarchy
**Context Menu for Note Selection:**
- Appears at cursor position
- Smooth 150ms delay for compositor
- First option always "Create New Note"
- Separator before existing notes
- Note icons for visual distinction
### ⚙️ Technical Improvements
**Memory Management:**
- Cleanup of 6 data structures in Component.onDestruction
- Process termination for `getSelectionForNoteSelectorProcess`
- Proper array clearing: `items = []`, `imageCache = {}`
**Code Quality:**
- Consistent translation syntax across codebase
- No hardcoded user-facing strings
- Proper null-safe operators: `pluginApi?.tr()`
- Immutable array updates maintained
**IPC Architecture:**
- Correct use of `pluginApi.withCurrentScreen()`
- No direct `Quickshell.screens` access in IPC handlers
- Consistent pattern with existing `addSelectionToTodo`
### 🐛 Bug Fixes
1. **Syntax Errors:**
- Fixed duplicate `}` in Component.onDestruction
- Removed extra closing braces in function declarations
- Fixed missing `} catch(e) {` block in loadNoteCardsProc
2. **Runtime Errors:**
- Fixed `ReferenceError: newNote is not defined` by removing invalid `saveNoteCard(newNote)` calls from functions that don't have access to `newNote`
- Only `createNoteCard()` calls `saveNoteCard(newNote)` now
3. **Functional Issues:**
- Fixed note selector not showing existing notes (timing issue with async loading)
- Fixed "Create New Note" not working (signal connection verified)
- Fixed notes not being saved to files (added `saveNoteCard()` call)
### 📝 Usage Examples
**IPC Commands:**
```bash
# Add selected text to note via keybind
qs -c noctalia-shell ipc call plugin:clipper addSelectionToNoteCard
# Or with dev repo
qs -c ~/dev/repo/noctalia ipc call plugin:clipper addSelectionToNoteCard
```
**Hyprland Keybind (chord):**
```bash
# In ~/.config/hypr/keybind.conf
binds = SUPER_L, V&C, exec, qs -c ~/dev/repo/noctalia ipc call plugin:clipper addSelectionToTodo
binds = SUPER_L, V&X, exec, qs -c ~/dev/repo/noctalia ipc call plugin:clipper addSelectionToNoteCard
```
**User Flow:**
1. Select text anywhere
2. Press Super+V (opens chord mode)
3. Press X (triggers addSelectionToNoteCard)
4. Context menu appears at cursor
5. Click "Create New Note" or select existing note
6. Text is added as bullet point: `- selected text`
### 📊 Statistics
**Lines Changed:**
- Main.qml: +250 lines
- NoteCard.qml: ~300 lines (redesigned)
- NoteCardSelector.qml: +173 lines (new)
- NoteCardsPanel.qml: +50 lines
- i18n/en.json: +30 keys
- Total: ~800 lines added/modified
**Files:**
- New: 1 file (NoteCardSelector.qml)
- Modified: 7 files
- Total: 8 files changed
**Translation Coverage:**
- 28 new toast message keys
- 100% coverage for user-facing strings
- All components use pluginApi?.tr()
### 🔄 Breaking Changes
**Translation System:**
- Old: `I18n.tr("clipboard.key", "Fallback")`
- New: `pluginApi?.tr("component.key") || "Fallback"`
- All plugins must update if they were using I18n
**IPC Handlers:**
- Now use `pluginApi.withCurrentScreen()` instead of `Quickshell.screens[0]`
- More robust multi-screen support
### 🚀 Next Steps (Future Enhancements)
1. **i18n Completion:**
- Translate en.json to all other language files (de, es, fr, etc.)
- Maintain identical structure across all languages
2. **Feature Enhancements:**
- Resizable note cards
- Rich text formatting
- Note categories/tags
- Search functionality
3. **Performance:**
- Lazy loading for large note collections
- Virtual scrolling if >20 notes
4. **Integration:**
- Share notes between devices
- Sync with cloud services
---
**Version:** 2.0.0
**Date:** 2026-02-05
**Author:** Development Team
**Reviewed by:** Code Review (QML-code-reviewer.md)