|
| 1 | +# NoteDelight Roadmap 🗺️ |
| 2 | + |
| 3 | +This document outlines the strategic plan, architectural considerations, and prioritized milestones for future NoteDelight development. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## 🎯 Release Milestones Overview |
| 8 | + |
| 9 | +| Milestone | Focus | Key Features | Status | |
| 10 | +| :--- | :--- | :--- | :--- | |
| 11 | +| **v1.1** | **Performance & List Usability** | Note list SQL projection (`NoteHeader`), Note sorting, Pin to top | 📋 Planned | |
| 12 | +| **v1.2** | **Inter-App Sharing & Integration** | Share export (`ShareInteractor`), Share import (`ACTION_SEND`), Encrypted pending state | 📋 Planned | |
| 13 | +| **v1.3** | **Search & Content Formatting** | Full-text / local search, basic Markdown support, Single-note export/import (.md/.txt) | 💡 Backlog | |
| 14 | +| **v1.4** | **Security & Safety Enhancements** | Trash / Soft delete, Auto-lock background timer | 💡 Backlog | |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## 🚀 Milestone Details |
| 19 | + |
| 20 | +### Milestone 1.1: Performance & List Usability |
| 21 | + |
| 22 | +#### 1. Note List Memory Optimization (`NoteHeader` Projection) |
| 23 | +* **Problem:** The current query (`SELECT * FROM note`) retrieves the entire note body (`text`), which can be large, for all rows when loading the paged list. This retains unnecessary text blobs in heap memory and forces SQLite to load overflow pages. |
| 24 | +* **Architecture & Solution:** |
| 25 | + * Define a lightweight domain model [`NoteHeader`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/domain/src/commonMain/kotlin/com/softartdev/notedelight/model/Note.kt): |
| 26 | + ```kotlin |
| 27 | + data class NoteHeader( |
| 28 | + val id: Long, |
| 29 | + val title: String, |
| 30 | + val dateCreated: LocalDateTime, |
| 31 | + val dateModified: LocalDateTime, |
| 32 | + ) |
| 33 | + ``` |
| 34 | + * In SQLDelight ([`Note.sq`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/data/db-sqldelight/src/commonMain/sqldelight/com/softartdev/notedelight/shared/db/Note.sq)): |
| 35 | + ```sql |
| 36 | + pagedHeaders: |
| 37 | + SELECT id, title, dateCreated, dateModified FROM note ORDER BY dateModified DESC LIMIT :limit OFFSET :offset; |
| 38 | + ``` |
| 39 | + * In Room ([`NoteRoomDao`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/data/db-room/src/commonMain/kotlin/com/softartdev/notedelight/db/Database.kt)): define a Room projection DTO and update the paging source. |
| 40 | + * In UI ([`NoteItem.kt`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/NoteItem.kt)): bind to `NoteHeader` instead of full `Note`. |
| 41 | + * The full note text continues to be retrieved on-demand via `noteDAO.load(id)` only when opening [`NoteDetail`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/NoteDetail.kt). |
| 42 | + |
| 43 | +#### 2. Note Sorting |
| 44 | +* **UI:** Add a Sort action with `Icons.AutoMirrored.Filled.Sort` in [`MainScreen`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/MainScreen.kt) top app bar actions with a dropdown menu: |
| 45 | + * By Last Modified Date (*default: Descending*) |
| 46 | + * By Creation Date (Descending / Ascending) |
| 47 | + * By Title (A-Z / Z-A) |
| 48 | +* **Dynamic Date Display:** Update [`NoteItem.kt`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/NoteItem.kt): |
| 49 | + * When sorted by modification date, display `dateModified` in `overlineContent`. |
| 50 | + * When sorted by creation date, display `dateCreated` in `overlineContent`. |
| 51 | +* **Persistence:** Persist selected sort order in settings/preferences so it survives app restarts. |
| 52 | + |
| 53 | +#### 3. Pin to Top / Favorite Notes |
| 54 | +* **Data Layer:** Add `isPinned: Boolean` flag in SQLite schema with migration. |
| 55 | +* **Behavior:** Pinned notes stay at the top of the list irrespective of the active sort order, with a distinct visual pin indicator in [`NoteItem.kt`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/NoteItem.kt). |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +### Milestone 1.2: Inter-App Sharing & Integration |
| 60 | + |
| 61 | +#### 1. Share Export (Outbound) |
| 62 | +* **UI:** Add a "Share" action icon in [`NoteDetailBody`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/NoteDetail.kt) top app bar (`Icons.Default.Share`). |
| 63 | +* **Platform Abstraction:** Implement `ShareInteractor` in `:core:presentation` (or `:core:domain`): |
| 64 | + * Android: fires `Intent(Intent.ACTION_SEND)` with `text/plain` via `Intent.createChooser()`. |
| 65 | + * iOS: presents `UIActivityViewController`. |
| 66 | + * Web: calls `navigator.share()` with clipboard fallback. |
| 67 | + * Desktop: copies note text to clipboard with snackbar feedback. |
| 68 | + |
| 69 | +#### 2. Share Import (Inbound) & Encrypted DB Flow |
| 70 | +* **Inbound Handler:** |
| 71 | + * Android: Configure `<intent-filter>` for `android.intent.action.SEND` with MIME type `text/plain` in [`AndroidManifest.xml`](file:///Users/artur/AndroidStudioProjects/NoteDelight/app/android/src/main/AndroidManifest.xml) for [`MainActivity`](file:///Users/artur/AndroidStudioProjects/NoteDelight/app/android/src/main/java/com/softartdev/notedelight/MainActivity.kt). |
| 72 | + * Hold incoming text in memory inside `ShareInteractor`: |
| 73 | + ```kotlin |
| 74 | + class ShareInteractor { |
| 75 | + var pendingIncomingText: String? = null |
| 76 | + private set |
| 77 | + fun setPendingIncomingText(text: String?) { pendingIncomingText = text } |
| 78 | + fun consumePendingIncomingText(): String? { ... } |
| 79 | + } |
| 80 | + ``` |
| 81 | +* **Security & Immediate Persistence Strategy:** |
| 82 | + * **When DB is encrypted:** SQLite operations are blocked until the user authenticates on [`SignInScreen`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/signin/SignInScreen.kt). The text is safely retained in `ShareInteractor`. |
| 83 | + * **Upon DB unlock (or if unencrypted):** Immediately create and persist the note in SQLite using [`CreateNoteUseCase(title, text)`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/domain/src/commonMain/kotlin/com/softartdev/notedelight/usecase/note/CreateNoteUseCase.kt#L10). |
| 84 | + * **Rationale:** Immediate saving guarantees no data loss if the app process is terminated or backgrounded, keeps encrypted data secure, and seamlessly aligns with NoteDelight's existing note creation architecture. |
| 85 | + * Clear pending text and navigate straight to editing the created note. |
| 86 | +
|
| 87 | +--- |
| 88 | +
|
| 89 | +### Milestone 1.3: Search & Content Formatting |
| 90 | +
|
| 91 | +#### 1. Note Search (Local / Full-Text Search) |
| 92 | +* Add a search bar or expandable search action in [`MainScreen`](file:///Users/artur/AndroidStudioProjects/NoteDelight/core/ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/main/MainScreen.kt). |
| 93 | +* Filter notes by title and content using SQLite queries (or evaluate SQLite `FTS5` virtual table indexing in SQLCipher). |
| 94 | +
|
| 95 | +#### 2. Basic Markdown Support |
| 96 | +* Render headings, lists, bold/italics, and interactive checklist items in the note editor and preview mode. |
| 97 | +
|
| 98 | +#### 3. Single-Note File Export & Import (.md / .txt) |
| 99 | +* Allow exporting individual notes as plaintext `.txt` or `.md` files to device storage. |
| 100 | +* Allow opening and importing `.txt` / `.md` files directly into a new note. |
| 101 | +
|
| 102 | +--- |
| 103 | +
|
| 104 | +### Milestone 1.4: Security & Data Safety |
| 105 | +
|
| 106 | +#### 1. Soft Delete & Trash (Recycle Bin) |
| 107 | +* Instead of immediate permanent deletion (`DELETE FROM note WHERE id = :id`), mark deleted notes with `isDeleted = true` / `deletedAt`. |
| 108 | +* Provide a "Trash" view under Settings to view, restore, or permanently purge deleted notes. |
| 109 | +
|
| 110 | +#### 2. Background Auto-Lock Timer |
| 111 | +* Configurable timeout (e.g. Immediately, 1 min, 5 min, 15 min) in Security Settings. |
| 112 | +* When NoteDelight goes to the background and the timeout expires, purge the decrypted database connection from memory and require password / biometric re-authentication on resume. |
| 113 | +
|
| 114 | +--- |
| 115 | +
|
| 116 | +## 📌 Feature Roadmap Matrix |
| 117 | +
|
| 118 | +| Feature | Target Milestone | Domain / Data Layer | Presentation / UI Layer | Platforms Affected | |
| 119 | +| :--- | :---: | :--- | :--- | :--- | |
| 120 | +| **Note List Memory Optimization** | v1.1 | `NoteHeader`, SQLDelight query, Room DAO | `MainViewModel`, `NoteItem` | All | |
| 121 | +| **Note Sorting** | v1.1 | `NoteDAO` sort order parameter | `MainScreen`, `NoteItem`, Settings | All | |
| 122 | +| **Pin to Top** | v1.1 | Schema `isPinned`, queries | `NoteItem`, `MainViewModel` | All | |
| 123 | +| **Share Outbound** | v1.2 | `ShareInteractor` contract | `NoteDetail`, platform share handlers | Android, iOS, Desktop, Web | |
| 124 | +| **Share Inbound** | v1.2 | `ShareInteractor`, `CreateNoteUseCase` | `MainActivity`, `SplashViewModel`, `SignInViewModel` | Android (primary), iOS | |
| 125 | +| **Search / FTS** | v1.3 | FTS5 / SQL queries | `MainViewModel`, `MainScreen` search bar | All | |
| 126 | +| **Markdown Editor** | v1.3 | Text formatting parser | `NoteDetail`, `NoteDetailBody` | All | |
| 127 | +| **Single-Note Export/Import** | v1.3 | `FileRepo` / Document file picker | `NoteDetail` menu | All | |
| 128 | +| **Trash (Soft Delete)** | v1.4 | `isDeleted` schema flag, cleanup job | Settings / Trash UI | All | |
| 129 | +| **Auto-Lock Timer** | v1.4 | Lifecycle observer, `SafeRepo` close | App lifecycle, Security settings | All | |
0 commit comments