feat(phase-13): implement recent files tracking system
Add recent files store for tracking recently opened/saved projects. Features: - Recent files store with persistence - Track up to 10 recent files (configurable) - Store file metadata: * Unique ID * File name * File path * Timestamp * Optional thumbnail - Automatic duplicate removal (by path) - Most recent files appear first - Functions for managing recent files: * addRecentFile() - Add to recent list * removeRecentFile() - Remove specific file * clearRecentFiles() - Clear all recent * updateThumbnail() - Update file thumbnail - localStorage persistence Changes: - Created store/recent-files-store.ts with RecentFile interface - Exported from store/index.ts - Ready for UI integration in File menu 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -12,3 +12,4 @@ export * from './ui-store';
|
|||||||
export * from './toast-store';
|
export * from './toast-store';
|
||||||
export * from './context-menu-store';
|
export * from './context-menu-store';
|
||||||
export * from './guides-store';
|
export * from './guides-store';
|
||||||
|
export * from './recent-files-store';
|
||||||
|
|||||||
78
store/recent-files-store.ts
Normal file
78
store/recent-files-store.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { create } from 'zustand';
|
||||||
|
import { persist } from 'zustand/middleware';
|
||||||
|
|
||||||
|
export interface RecentFile {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
timestamp: number;
|
||||||
|
thumbnail?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RecentFilesStore {
|
||||||
|
/** List of recent files */
|
||||||
|
recentFiles: RecentFile[];
|
||||||
|
/** Maximum number of recent files to keep */
|
||||||
|
maxRecent: number;
|
||||||
|
|
||||||
|
/** Add file to recent list */
|
||||||
|
addRecentFile: (name: string, path: string, thumbnail?: string) => void;
|
||||||
|
/** Remove file from recent list */
|
||||||
|
removeRecentFile: (id: string) => void;
|
||||||
|
/** Clear all recent files */
|
||||||
|
clearRecentFiles: () => void;
|
||||||
|
/** Update file thumbnail */
|
||||||
|
updateThumbnail: (id: string, thumbnail: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useRecentFilesStore = create<RecentFilesStore>()(
|
||||||
|
persist(
|
||||||
|
(set, get) => ({
|
||||||
|
recentFiles: [],
|
||||||
|
maxRecent: 10,
|
||||||
|
|
||||||
|
addRecentFile: (name, path, thumbnail) => {
|
||||||
|
const id = `${path}-${Date.now()}`;
|
||||||
|
const newFile: RecentFile = {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
path,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
thumbnail,
|
||||||
|
};
|
||||||
|
|
||||||
|
set((state) => {
|
||||||
|
// Remove duplicate if exists (same path)
|
||||||
|
const filtered = state.recentFiles.filter((f) => f.path !== path);
|
||||||
|
// Add new file at the beginning
|
||||||
|
const updated = [newFile, ...filtered];
|
||||||
|
// Keep only maxRecent files
|
||||||
|
return {
|
||||||
|
recentFiles: updated.slice(0, state.maxRecent),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
removeRecentFile: (id) => {
|
||||||
|
set((state) => ({
|
||||||
|
recentFiles: state.recentFiles.filter((f) => f.id !== id),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
clearRecentFiles: () => {
|
||||||
|
set({ recentFiles: [] });
|
||||||
|
},
|
||||||
|
|
||||||
|
updateThumbnail: (id, thumbnail) => {
|
||||||
|
set((state) => ({
|
||||||
|
recentFiles: state.recentFiles.map((f) =>
|
||||||
|
f.id === id ? { ...f, thumbnail } : f
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: 'recent-files-storage',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user