feat(explorer-sidebar): add right-side file explorer and git diff panel
- Add swipe-left gesture to open explorer sidebar on mobile - Implement Changes (git diff) and Files tabs with toggle - Add responsive gallery columns based on container width - Handle hardware back button to close sidebar first - Add gesture conflict resolution for horizontal scroll in diffs - Add resize handle with cursor change on desktop - Add sorting selector (name, modified, size) in file explorer 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
9d7e44851c
commit
8c33df472f
@@ -0,0 +1,64 @@
|
||||
import { create } from "zustand";
|
||||
import { persist, createJSONStorage } from "zustand/middleware";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
|
||||
type ExplorerTab = "changes" | "files";
|
||||
export type ViewMode = "list" | "grid";
|
||||
export type SortOption = "name" | "modified" | "size";
|
||||
|
||||
export const DEFAULT_EXPLORER_SIDEBAR_WIDTH = 400;
|
||||
export const MIN_EXPLORER_SIDEBAR_WIDTH = 280;
|
||||
export const MAX_EXPLORER_SIDEBAR_WIDTH = 800;
|
||||
|
||||
interface ExplorerSidebarState {
|
||||
isOpen: boolean;
|
||||
activeTab: ExplorerTab;
|
||||
width: number;
|
||||
viewMode: ViewMode;
|
||||
sortOption: SortOption;
|
||||
toggle: () => void;
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
setActiveTab: (tab: ExplorerTab) => void;
|
||||
setWidth: (width: number) => void;
|
||||
setViewMode: (mode: ViewMode) => void;
|
||||
setSortOption: (option: SortOption) => void;
|
||||
}
|
||||
|
||||
function clampWidth(width: number): number {
|
||||
return Math.max(MIN_EXPLORER_SIDEBAR_WIDTH, Math.min(MAX_EXPLORER_SIDEBAR_WIDTH, width));
|
||||
}
|
||||
|
||||
export const useExplorerSidebarStore = create<ExplorerSidebarState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
isOpen: false,
|
||||
activeTab: "changes",
|
||||
width: DEFAULT_EXPLORER_SIDEBAR_WIDTH,
|
||||
viewMode: "list",
|
||||
sortOption: "name",
|
||||
toggle: () => set((state) => ({ isOpen: !state.isOpen })),
|
||||
open: () => set({ isOpen: true }),
|
||||
close: () => set({ isOpen: false }),
|
||||
setActiveTab: (tab) => set({ activeTab: tab }),
|
||||
setWidth: (width) => set({ width: clampWidth(width) }),
|
||||
setViewMode: (mode) => set({ viewMode: mode }),
|
||||
setSortOption: (option) => set({ sortOption: option }),
|
||||
}),
|
||||
{
|
||||
name: "explorer-sidebar-state",
|
||||
storage: createJSONStorage(() => AsyncStorage),
|
||||
partialize: (state) => ({
|
||||
isOpen: state.isOpen,
|
||||
activeTab: state.activeTab,
|
||||
width: state.width,
|
||||
viewMode: state.viewMode,
|
||||
sortOption: state.sortOption,
|
||||
}),
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export function useExplorerSidebar() {
|
||||
return useExplorerSidebarStore();
|
||||
}
|
||||
Reference in New Issue
Block a user