Closed
Description
Description
Create a dropdown component to select and view different versions of a gist, integrated with the version history system.
Requirements
- Dropdown showing version list with numbers and timestamps
- Current version clearly highlighted
- Human-readable timestamps (e.g., "2 hours ago", "Dec 5 at 3:45 PM")
- Load selected version on change
- Show version metadata (who edited, if PIN was used)
- Maximum 50 versions as per spec
- Reverse chronological order (newest first)
- Loading state while fetching version
- Error handling for failed loads
- Mobile-friendly dropdown UI
Acceptance Criteria
- Lists all available versions (up to 50)
- Current version is highlighted and marked
- Selection triggers version load with loading state
- Timestamps are human-readable and relative
- Shows version number (e.g., "Version 3 of 12")
- Dropdown is keyboard navigable
- Works well on mobile devices
- Shows helpful empty state if only 1 version
- Indicates if version was PIN-protected edit
- Smooth transition between versions
UI Structure
Version: 3 of 12 [▼]
┌─────────────────────────────────────┐
│ ✓ Version 3 (current) │
│ 2 hours ago │
├─────────────────────────────────────┤
│ Version 2 │
│ Yesterday at 4:32 PM │
├─────────────────────────────────────┤
│ Version 1 (original) │
│ Dec 5 at 10:15 AM │
└─────────────────────────────────────┘
Props Interface
interface VersionSelectorProps {
currentVersion: number;
versions: Array<{
version: number;
created_at: string;
size: number;
file_count: number;
edited_with_pin?: boolean;
}>;
onVersionChange: (version: number) => void;
loading?: boolean;
disabled?: boolean;
}
Technical Implementation
// Format relative timestamps
function formatVersionTime(timestamp: string): string {
const date = new Date(timestamp);
const now = new Date();
const diffMs = now.getTime() - date.getTime();
// Use relative time for recent versions
if (diffMs < 24 * 60 * 60 * 1000) {
return formatRelative(date); // "2 hours ago"
}
// Use absolute time for older versions
return format(date, 'MMM d at h:mm a'); // "Dec 5 at 3:45 PM"
}
Version History Storage
Per the spec, versions are stored at:
versions/{gist-id}/{timestamp}.bin
The component should:
- Display available versions from metadata
- Fetch specific version blob when selected
- Decrypt with the same key (versions share encryption key)
- Update the UI with the historical content
Technical Notes
- Use shadcn/ui Select component
- Implement with React hooks for state management
- Consider caching recently viewed versions
- Show loading spinner during version fetch
- Handle errors gracefully (toast notification)
- Ensure smooth UX when switching versions
- Consider showing diff indicator in future enhancement
Accessibility
- Announce version changes to screen readers
- Keyboard navigation with arrow keys
- Clear labels for current vs. historical versions
- Escape key to close dropdown
Related
- Used by feat: create gist viewer component #61 (GistViewer component)
- Works with version history system from spec
- Part of Phase 4 UI Components
- Integrates with storage structure defined in SPEC.md