Add Notes / Resources Linking#25
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds comprehensive linking functionality to the note-taking app, enabling users to create clickable links that can either reference other notes internally (via UUID) or point to external URLs. The implementation includes a new LinkItem canvas element with its own rendering system, a floating window viewer for linked content, and a full UUID-based indexing system to support persistent note-to-note references.
Changes:
- Adds LinkItem model with serialization, rendering, and canvas integration
- Implements UUID-based note identification and indexing for reliable internal linking
- Creates floating window UI for viewing linked notes and external URLs in-app
- Adds NotePickerActivity for browsing and selecting link targets
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| LinkItem.kt | New canvas item model for clickable links with label, target, type, and styling |
| LinkRenderer.kt | Renders link items as styled capsules with icons |
| InsertLinkDialog.kt | Dialog for creating/editing links with internal/external type selection |
| CanvasContextMenu.xml | Adds "Link" button to canvas context menu |
| FloatingWindowView.kt | Draggable/resizable floating window for viewing linked content |
| NotePickerActivity.kt | Activity for browsing and selecting notes to link to |
| CanvasActivity.kt | Handles link activation, resolution, and floating window management |
| MainActivity.kt | Adds picker mode for note selection with project locking |
| StorageProvider.kt | Implements ensureUuid() for assigning UUIDs to existing notes |
| FileIndexManager.kt | Adds UUID-to-path mapping for fast link resolution |
| InfiniteCanvasModel.kt | Integrates LinkItem into canvas data model |
| CanvasSerializer.kt | Serialization support for LinkItem |
| SerializationModels.kt | Proto models for LinkItemData and UUID fields |
| Logger.kt | Changes debug logging behavior (unconditional) |
| ZipUtils.kt | Adds debug logging and size-matching for incremental zips |
| Various drawables/layouts | UI resources for link icons, dialogs, and floating windows |
Comments suppressed due to low confidence (1)
app/src/main/java/com/alexdremov/notate/ui/OnyxCanvasView.kt:288
- There's no UI for editing an existing LinkItem after it's placed. When a user taps on a TextItem in select mode, it opens the text editor (lines 285-287), but there's no equivalent for LinkItem. Users can move and delete links via selection, but cannot edit the label, target, or type. Consider adding an edit dialog that opens when a LinkItem is long-pressed or double-tapped in select mode, similar to how text editing works.
if (currentTool.type == ToolType.TEXT) {
if (item is TextItem) {
showTextEditor(item)
} else {
showTextEditor(null, worldX, worldY)
}
return@launch
} else if (currentTool.type == ToolType.SELECT && item is TextItem) {
showTextEditor(item)
return@launch
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 35 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 39 out of 39 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (1)
app/src/main/java/com/alexdremov/notate/MainActivity.kt:334
FileBrowserScreennow has anisReadOnlyflag to disable long-press actions, butMainScreennever passes it. In picker mode this means users can still open the manage dialog (rename/duplicate/delete) while picking a note. PassisReadOnly = isPickerMode(or otherwise disableonItemDelete/rename/duplicate) whenisPickerModeis true.
FileBrowserScreen(
items = browserItems,
breadcrumbs = breadcrumbs,
allTags = tags,
disabledItemUuid = disabledItemUuid,
onBreadcrumbClick = { viewModel.loadBrowserItems(it.path) },
onItemClick = { item ->
when (item) {
is ProjectItem -> {
viewModel.loadBrowserItems(item.path)
}
is CanvasItem -> {
if (isPickerMode && onFilePicked != null) {
onFilePicked(item)
} else {
val intent =
Intent(context, CanvasActivity::class.java).apply {
putExtra("CANVAS_PATH", item.path)
}
context.startActivity(intent)
}
}
}
},
onItemDelete = { viewModel.deleteItem(it) },
onItemRename = { item, newName -> viewModel.renameItem(item, newName) },
onItemDuplicate = { item -> viewModel.duplicateItem(item) },
onSetFileTags = { item, newTags -> viewModel.setFileTags(item, newTags) },
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 41 out of 41 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Closes #22