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:
71
MarkdownViewer/RecentFilesManager.swift
Normal file
71
MarkdownViewer/RecentFilesManager.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
import Foundation
|
||||
|
||||
class RecentFilesManager: ObservableObject {
|
||||
static let shared = RecentFilesManager()
|
||||
|
||||
@Published var recentFiles: [URL] = []
|
||||
|
||||
private let maxRecentFiles = 10
|
||||
private let userDefaultsKey = "RecentMarkdownFiles"
|
||||
|
||||
private init() {
|
||||
loadRecentFiles()
|
||||
}
|
||||
|
||||
func addRecentFile(_ url: URL) {
|
||||
// Remove if already exists to move it to top
|
||||
recentFiles.removeAll { $0 == url }
|
||||
|
||||
// Add to beginning
|
||||
recentFiles.insert(url, at: 0)
|
||||
|
||||
// Limit to max count
|
||||
if recentFiles.count > maxRecentFiles {
|
||||
recentFiles = Array(recentFiles.prefix(maxRecentFiles))
|
||||
}
|
||||
|
||||
saveRecentFiles()
|
||||
}
|
||||
|
||||
func removeRecentFile(_ url: URL) {
|
||||
recentFiles.removeAll { $0 == url }
|
||||
saveRecentFiles()
|
||||
}
|
||||
|
||||
func clearRecentFiles() {
|
||||
recentFiles.removeAll()
|
||||
saveRecentFiles()
|
||||
}
|
||||
|
||||
private func loadRecentFiles() {
|
||||
if let data = UserDefaults.standard.data(forKey: userDefaultsKey),
|
||||
let urls = try? JSONDecoder().decode([URL].self, from: data) {
|
||||
// Filter out files that no longer exist
|
||||
recentFiles = urls.filter { FileManager.default.fileExists(atPath: $0.path) }
|
||||
|
||||
// Save filtered list back if any files were removed
|
||||
if recentFiles.count != urls.count {
|
||||
saveRecentFiles()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func saveRecentFiles() {
|
||||
if let data = try? JSONEncoder().encode(recentFiles) {
|
||||
UserDefaults.standard.set(data, forKey: userDefaultsKey)
|
||||
}
|
||||
}
|
||||
|
||||
func getDisplayName(for url: URL) -> String {
|
||||
return url.lastPathComponent
|
||||
}
|
||||
|
||||
func getRelativePath(for url: URL) -> String {
|
||||
let homeURL = FileManager.default.homeDirectoryForCurrentUser
|
||||
if url.path.hasPrefix(homeURL.path) {
|
||||
let relativePath = String(url.path.dropFirst(homeURL.path.count))
|
||||
return "~" + relativePath
|
||||
}
|
||||
return url.path
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user