diff --git a/src-tauri/src/vault.rs b/src-tauri/src/vault.rs index 4d571bbd..faa54dd1 100644 --- a/src-tauri/src/vault.rs +++ b/src-tauri/src/vault.rs @@ -25,6 +25,9 @@ pub struct VaultEntry { pub owner: Option, pub cadence: Option, pub archived: bool, + pub trashed: bool, + #[serde(rename = "trashedAt")] + pub trashed_at: Option, #[serde(rename = "modifiedAt")] pub modified_at: Option, #[serde(rename = "createdAt")] @@ -60,6 +63,10 @@ struct Frontmatter { cadence: Option, #[serde(rename = "Archived")] archived: Option, + #[serde(rename = "Trashed")] + trashed: Option, + #[serde(rename = "Trashed at")] + trashed_at: Option, #[serde(rename = "Created at")] created_at: Option, #[serde(rename = "Created time")] @@ -213,8 +220,8 @@ fn parse_frontmatter(data: &HashMap) -> Frontmatter { /// Known non-relationship frontmatter keys to skip (case-insensitive comparison). /// Only skip keys that can never contain wikilinks. const SKIP_KEYS: &[&str] = &[ - "is a", "aliases", "status", "cadence", "archived", "created at", "created time", - "icon", "color", + "is a", "aliases", "status", "cadence", "archived", "trashed", "trashed at", + "created at", "created time", "icon", "color", ]; /// Check if a string contains a wikilink pattern `[[...]]`. @@ -364,6 +371,8 @@ pub fn parse_md_file(path: &Path) -> Result { owner: frontmatter.owner, cadence: frontmatter.cadence, archived: frontmatter.archived.unwrap_or(false), + trashed: frontmatter.trashed.unwrap_or(false), + trashed_at: frontmatter.trashed_at.as_deref().and_then(parse_iso_date), modified_at, created_at, file_size, icon: frontmatter.icon, color: frontmatter.color, diff --git a/src/mock-tauri.ts b/src/mock-tauri.ts index 82ca683d..4f0fe632 100644 --- a/src/mock-tauri.ts +++ b/src/mock-tauri.ts @@ -583,6 +583,45 @@ A **book** you're reading or have read. Track reading progress, notes, and key t - **Author**: The book's author - **Status**: Reading, Finished, Abandoned - **Rating**: 1-5 stars +`, + // --- Trashed entries --- + '/Users/luca/Laputa/note/old-draft-notes.md': `--- +title: Old Draft Notes +is_a: Note +trashed: true +trashed_at: ${new Date(Date.now() - 86400000 * 5).toISOString().slice(0, 10)} +belongs_to: + - "[[project/26q1-laputa-app]]" +--- + +# Old Draft Notes + +Some rough draft content that is no longer relevant. Moving to trash. +`, + '/Users/luca/Laputa/note/deprecated-api-notes.md': `--- +title: Deprecated API Notes +is_a: Note +trashed: true +trashed_at: ${new Date(Date.now() - 86400000 * 35).toISOString().slice(0, 10)} +--- + +# Deprecated API Notes + +Old API documentation for the v1 endpoint. Replaced by v2 docs. +`, + '/Users/luca/Laputa/experiment/failed-seo-experiment.md': `--- +title: Failed SEO Experiment +is_a: Experiment +status: Dropped +trashed: true +trashed_at: ${new Date(Date.now() - 86400000 * 10).toISOString().slice(0, 10)} +related_to: + - "[[responsibility/grow-newsletter]]" +--- + +# Failed SEO Experiment + +Tried programmatic SEO pages. Results were negligible — trashing this. `, // --- Archived entries --- '/Users/luca/Laputa/project/25q3-website-redesign.md': `--- @@ -672,6 +711,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Luca Rossi', cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000, createdAt: null, fileSize: 2048, @@ -696,6 +737,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Luca Rossi', cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 3600, createdAt: null, fileSize: 1024, @@ -725,6 +768,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Matteo Cellini', cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 7200, createdAt: null, fileSize: 890, @@ -748,6 +793,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Luca Rossi', cadence: 'Weekly', archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400, createdAt: null, fileSize: 512, @@ -771,6 +818,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Matteo Cellini', cadence: 'Weekly', archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 2, createdAt: null, fileSize: 640, @@ -794,6 +843,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Luca Rossi', cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400, createdAt: null, fileSize: 3200, @@ -818,6 +869,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 3600 * 5, createdAt: null, fileSize: 847, @@ -842,6 +895,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400, createdAt: null, fileSize: 560, @@ -865,6 +920,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 7, createdAt: null, fileSize: 320, @@ -887,6 +944,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 3600 * 2, createdAt: null, fileSize: 1200, @@ -910,6 +969,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 30, createdAt: null, fileSize: 256, @@ -933,6 +994,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 14, createdAt: null, fileSize: 180, @@ -956,6 +1019,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 3, createdAt: null, fileSize: 4200, @@ -979,6 +1044,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 7, createdAt: null, fileSize: 3800, @@ -1003,6 +1070,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 10, createdAt: null, fileSize: 5100, @@ -1027,6 +1096,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 320, @@ -1047,6 +1118,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 280, @@ -1067,6 +1140,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 310, @@ -1087,6 +1162,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 290, @@ -1107,6 +1184,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 200, @@ -1127,6 +1206,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 180, @@ -1147,6 +1228,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 170, @@ -1167,6 +1250,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 200, @@ -1187,6 +1272,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 90, createdAt: null, fileSize: 190, @@ -1208,6 +1295,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 30, createdAt: null, fileSize: 250, @@ -1228,6 +1317,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 30, createdAt: null, fileSize: 220, @@ -1249,6 +1340,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 5, createdAt: null, fileSize: 420, @@ -1271,6 +1364,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: null, cadence: null, archived: false, + trashed: false, + trashedAt: null, modifiedAt: Date.now() / 1000 - 86400 * 14, createdAt: null, fileSize: 380, @@ -1281,6 +1376,81 @@ const MOCK_ENTRIES: VaultEntry[] = [ icon: null, color: null, }, + // --- Trashed entries --- + { + path: '/Users/luca/Laputa/note/old-draft-notes.md', + filename: 'old-draft-notes.md', + title: 'Old Draft Notes', + isA: 'Note', + aliases: [], + belongsTo: ['[[project/26q1-laputa-app]]'], + relatedTo: [], + status: null, + owner: null, + cadence: null, + archived: false, + trashed: true, + trashedAt: Date.now() / 1000 - 86400 * 5, + modifiedAt: Date.now() / 1000 - 86400 * 10, + createdAt: null, + fileSize: 280, + snippet: 'Some rough draft content that is no longer relevant. Moving to trash.', + relationships: { + 'Belongs to': ['[[project/26q1-laputa-app]]'], + 'Type': ['[[type/note]]'], + }, + icon: null, + color: null, + }, + { + path: '/Users/luca/Laputa/note/deprecated-api-notes.md', + filename: 'deprecated-api-notes.md', + title: 'Deprecated API Notes', + isA: 'Note', + aliases: [], + belongsTo: [], + relatedTo: [], + status: null, + owner: null, + cadence: null, + archived: false, + trashed: true, + trashedAt: Date.now() / 1000 - 86400 * 35, + modifiedAt: Date.now() / 1000 - 86400 * 40, + createdAt: null, + fileSize: 190, + snippet: 'Old API documentation for the v1 endpoint. Replaced by v2 docs.', + relationships: { + 'Type': ['[[type/note]]'], + }, + icon: null, + color: null, + }, + { + path: '/Users/luca/Laputa/experiment/failed-seo-experiment.md', + filename: 'failed-seo-experiment.md', + title: 'Failed SEO Experiment', + isA: 'Experiment', + aliases: [], + belongsTo: [], + relatedTo: ['[[responsibility/grow-newsletter]]'], + status: 'Dropped', + owner: 'Luca Rossi', + cadence: null, + archived: false, + trashed: true, + trashedAt: Date.now() / 1000 - 86400 * 10, + modifiedAt: Date.now() / 1000 - 86400 * 15, + createdAt: null, + fileSize: 340, + snippet: 'Tried programmatic SEO pages. Results were negligible — trashing this.', + relationships: { + 'Related to': ['[[responsibility/grow-newsletter]]'], + 'Type': ['[[type/experiment]]'], + }, + icon: null, + color: null, + }, // --- Archived entries --- { path: '/Users/luca/Laputa/project/25q3-website-redesign.md', @@ -1294,6 +1464,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Luca Rossi', cadence: null, archived: true, + trashed: false, + trashedAt: null, icon: null, color: null, modifiedAt: Date.now() / 1000 - 86400 * 120, @@ -1317,6 +1489,8 @@ const MOCK_ENTRIES: VaultEntry[] = [ owner: 'Luca Rossi', cadence: null, archived: true, + trashed: false, + trashedAt: null, icon: null, color: null, modifiedAt: Date.now() / 1000 - 86400 * 90, diff --git a/src/types.ts b/src/types.ts index 3bf8ec29..c43019a7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,6 +10,8 @@ export interface VaultEntry { owner: string | null cadence: string | null archived: boolean + trashed: boolean + trashedAt: number | null modifiedAt: number | null createdAt: number | null fileSize: number @@ -37,7 +39,7 @@ export interface ModifiedFile { } export type SidebarSelection = - | { kind: 'filter'; filter: 'all' | 'favorites' | 'archived' } + | { kind: 'filter'; filter: 'all' | 'favorites' | 'archived' | 'trash' } | { kind: 'sectionGroup'; type: string } | { kind: 'entity'; entry: VaultEntry } | { kind: 'topic'; entry: VaultEntry }