Pinning Mechanism
Relevant source files
The following files were used as context for generating this wiki page:
The Pinning Mechanism in Augenblick is a core feature designed to provide permanence in an otherwise ephemeral note-taking environment. While the application's default behavior is to auto-expire notes after a period of inactivity, pinning allows users to designate specific notes as "important," exempting them from the automated cleanup processes and keeping them anchored at the top of the sidebar. Sources: README.md, plans/migration.inventory.md:144-150
Overview and Constraints
Pinning changes the lifecycle of a note by modifying its metadata and how it is processed by the backend sweeper. The system enforces a strict limit to maintain the "ephemeral-first" philosophy of the application.
- Pin Limit: Users can only pin up to 5 notes at any given time. Attempting to pin a 6th note results in an error toast. Sources: plans/migration.inventory.md:144, src/test/lib/tauriShim.test.ts:168-171
- Storage Flag: Pinning is tracked via the
is_pinnedinteger (boolean) field in the SQLite database and theisPinnedproperty in the frontend state. Sources: plans/migration.inventory.md:25, src/lib/tauri/shim.ts:4-15 - Sectioning: Pinned notes are moved to a dedicated "PINNED" section in the sidebar, separate from the general "NOTES" list. Sources: plans/migration.inventory.md:154, src/stores/notesStore.ts:109-126
Architecture and Data Flow
The pinning process involves a request from the React frontend via the notesStore, which invokes a Tauri IPC command to the Rust backend.
Pinning Logic Flow
When a user toggles a pin, the system calculates the new sort_order to ensure the newly pinned note appears at the end of the pinned section. Conversely, when unpinning, the note is returned to the active notes section.
This diagram illustrates the logical branching between pinning and unpinning, emphasizing the limit check and the interaction reset during unpinning. Sources: src/lib/tauri/shim.ts:182-209, plans/migration.inventory.md:144-152
State Management (Zustand)
The notesStore manages the local cache of pinned notes. It provides a togglePin function that handles the optimistic update or refresh after the API call.
| Function | Description |
|---|---|
togglePin(id) | Invokes api.notePin and updates the local list with the returned metadata. |
reorder(section, ids) | Handles drag-and-drop reordering specifically within the "pinned" section. |
undoReorder() | Reverts the last sort order change for the pinned section (stack depth 20). |
Sources: src/stores/notesStore.ts:25-30, src/stores/notesStore.ts:323-330, plans/migration.inventory.md:154-160
Expiry Integration
A critical function of the pinning mechanism is its interaction with the auto-retention system. Pinned notes are explicitly ignored by the background thread that moves inactive notes to the trash.
- Immunity: The auto-sweeper query filters for
is_pinned = 0. Any note withis_pinned = 1will never be moved to trash regardless of itslast_interactiontimestamp. Sources: plans/migration.inventory.md:181-188, src/lib/tauri/shim.ts:255-260 - Unpinning Behavior: When a note is unpinned, its
last_interactiontimestamp is reset to the current time. This provides the user with a full fresh expiry window (e.g., 7 days) before the note becomes eligible for auto-trashing again. Sources: plans/migration.inventory.md:151-152, src/lib/tauri/shim.ts:206 - UI Feedback: The "Expiry Ring" (visual timer) is hidden for pinned notes, as they no longer have an expiration deadline. Sources: src/test/features/NoteItem.test.tsx:43-52, plans/migration.inventory.md:195
Interaction and Controls
Users interact with the pinning system through multiple entry points in the UI.
Control Summary
| Input | Action | Logic |
|---|---|---|
| Cmd + P | Toggle Pin | Triggers note_pin on the currently selected note. |
| Command Palette | Pin/Unpin | Searchable actions that dispatch the same toggle. |
| Sidebar Drag | Reorder | Updates sort_order within the pinned group only. |
Sources: plans/migration.md:183, plans/migration.inventory.md:144-150, README.md
Sort Order Management
Sort orders are maintained independently for the pinned and unpinned sections. Pinned notes use sort_order values relative to other pinned notes. When a note is unpinned, it is appended to the end of the unpinned active list by taking max(unpinned_sort_order) + 1. Sources: src/lib/tauri/shim.ts:196-209, plans/migration.inventory.md:144-152
Summary
The pinning mechanism serves as the primary "save" internal to the application's ephemeral database. By enforcing a 5-note limit and resetting expiry timers upon unpinning, Augenblick ensures that pinning remains a deliberate act for only the most essential active items. Sources: README.md, plans/migration.inventory.md:144-150