Add recent files menu functionality

Implemented comprehensive recent files tracking system:
- Created RecentFilesManager singleton with UserDefaults persistence
- Added Recent Files submenu to File menu with up to 10 recent files
- Automatic file validation that removes deleted files from list
- Smart file tracking that adds files when opened and moves to top
- Clear Recent Files option for user control
- User-friendly display showing filename and relative path
- Error handling for missing files with user notification

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
0x8664b2
2025-06-20 10:48:11 -07:00
parent 732f633086
commit a3e8b09a8f
4 changed files with 149 additions and 26 deletions

View File

@@ -10,6 +10,7 @@
1A2345678901234567890001 /* MarkdownViewerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2345678901234567890002 /* MarkdownViewerApp.swift */; };
1A2345678901234567890003 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2345678901234567890004 /* ContentView.swift */; };
1A2345678901234567890005 /* MarkdownRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2345678901234567890006 /* MarkdownRenderer.swift */; };
1A2345678901234567890020 /* RecentFilesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2345678901234567890021 /* RecentFilesManager.swift */; };
1A2345678901234567890007 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A2345678901234567890008 /* Assets.xcassets */; };
1A2345678901234567890009 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A234567890123456789000A /* Preview Assets.xcassets */; };
/* End PBXBuildFile section */
@@ -19,6 +20,7 @@
1A2345678901234567890002 /* MarkdownViewerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownViewerApp.swift; sourceTree = "<group>"; };
1A2345678901234567890004 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
1A2345678901234567890006 /* MarkdownRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownRenderer.swift; sourceTree = "<group>"; };
1A2345678901234567890021 /* RecentFilesManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentFilesManager.swift; sourceTree = "<group>"; };
1A2345678901234567890008 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
1A234567890123456789000A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -48,6 +50,7 @@
1A2345678901234567890002 /* MarkdownViewerApp.swift */,
1A2345678901234567890004 /* ContentView.swift */,
1A2345678901234567890006 /* MarkdownRenderer.swift */,
1A2345678901234567890021 /* RecentFilesManager.swift */,
1A2345678901234567890008 /* Assets.xcassets */,
1A2345678901234567890010 /* Preview Content */,
);
@@ -142,6 +145,7 @@
files = (
1A2345678901234567890003 /* ContentView.swift in Sources */,
1A2345678901234567890005 /* MarkdownRenderer.swift in Sources */,
1A2345678901234567890020 /* RecentFilesManager.swift in Sources */,
1A2345678901234567890001 /* MarkdownViewerApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;