Merge branch 'streamline-file-explorer'
This commit is contained in:
@@ -10,9 +10,10 @@ import {
|
|||||||
ScrollView as RNScrollView,
|
ScrollView as RNScrollView,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
|
Platform,
|
||||||
useWindowDimensions,
|
useWindowDimensions,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { ScrollView } from "react-native-gesture-handler";
|
import { ScrollView, Gesture, GestureDetector } from "react-native-gesture-handler";
|
||||||
import { StyleSheet, UnistylesRuntime, useUnistyles } from "react-native-unistyles";
|
import { StyleSheet, UnistylesRuntime, useUnistyles } from "react-native-unistyles";
|
||||||
import { Fonts } from "@/constants/theme";
|
import { Fonts } from "@/constants/theme";
|
||||||
import * as Clipboard from "expo-clipboard";
|
import * as Clipboard from "expo-clipboard";
|
||||||
@@ -83,6 +84,8 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
} = useFileExplorerActions(serverId);
|
} = useFileExplorerActions(serverId);
|
||||||
const sortOption = usePanelStore((state) => state.explorerSortOption);
|
const sortOption = usePanelStore((state) => state.explorerSortOption);
|
||||||
const setSortOption = usePanelStore((state) => state.setExplorerSortOption);
|
const setSortOption = usePanelStore((state) => state.setExplorerSortOption);
|
||||||
|
const splitRatio = usePanelStore((state) => state.explorerFilesSplitRatio);
|
||||||
|
const setSplitRatio = usePanelStore((state) => state.setExplorerFilesSplitRatio);
|
||||||
|
|
||||||
const directories = explorerState?.directories ?? new Map();
|
const directories = explorerState?.directories ?? new Map();
|
||||||
const files = explorerState?.files ?? new Map();
|
const files = explorerState?.files ?? new Map();
|
||||||
@@ -110,6 +113,7 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
const [menuEntry, setMenuEntry] = useState<ExplorerEntry | null>(null);
|
const [menuEntry, setMenuEntry] = useState<ExplorerEntry | null>(null);
|
||||||
const [menuAnchor, setMenuAnchor] = useState({ top: 0, left: 0 });
|
const [menuAnchor, setMenuAnchor] = useState({ top: 0, left: 0 });
|
||||||
const [menuHeight, setMenuHeight] = useState(0);
|
const [menuHeight, setMenuHeight] = useState(0);
|
||||||
|
const [containerWidth, setContainerWidth] = useState(0);
|
||||||
|
|
||||||
// Bottom sheet for file preview (mobile)
|
// Bottom sheet for file preview (mobile)
|
||||||
const previewSheetRef = useRef<BottomSheetModal>(null);
|
const previewSheetRef = useRef<BottomSheetModal>(null);
|
||||||
@@ -261,7 +265,7 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
if (!menuEntry) {
|
if (!menuEntry) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const menuWidth = 180;
|
const menuWidth = 240;
|
||||||
const horizontalPadding = theme.spacing[2];
|
const horizontalPadding = theme.spacing[2];
|
||||||
const verticalPadding = theme.spacing[2];
|
const verticalPadding = theme.spacing[2];
|
||||||
const maxLeft = Math.max(horizontalPadding, windowWidth - menuWidth - horizontalPadding);
|
const maxLeft = Math.max(horizontalPadding, windowWidth - menuWidth - horizontalPadding);
|
||||||
@@ -301,6 +305,66 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
Boolean(isExplorerLoading && pendingRequest?.mode === "list" && pendingRequest?.path === ".");
|
Boolean(isExplorerLoading && pendingRequest?.mode === "list" && pendingRequest?.path === ".");
|
||||||
|
|
||||||
const shouldShowInlinePreview = !isMobile && Boolean(selectedEntryPath);
|
const shouldShowInlinePreview = !isMobile && Boolean(selectedEntryPath);
|
||||||
|
const dividerWidth = 10;
|
||||||
|
const minTreeWidth = 220;
|
||||||
|
const minPreviewWidth = 320;
|
||||||
|
|
||||||
|
const treePaneWidth = useMemo(() => {
|
||||||
|
if (!shouldShowInlinePreview || containerWidth <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const available = Math.max(0, containerWidth - dividerWidth);
|
||||||
|
const maxTree = Math.max(minTreeWidth, available - minPreviewWidth);
|
||||||
|
const raw = Math.round(available * splitRatio);
|
||||||
|
return Math.max(minTreeWidth, Math.min(maxTree, raw));
|
||||||
|
}, [containerWidth, shouldShowInlinePreview, splitRatio]);
|
||||||
|
|
||||||
|
const resizeStartRef = useRef<{ startWidth: number; startX: number; available: number } | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const splitResizeGesture = useMemo(() => {
|
||||||
|
if (!shouldShowInlinePreview || containerWidth <= 0 || treePaneWidth === null) {
|
||||||
|
return Gesture.Pan().enabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const available = Math.max(0, containerWidth - dividerWidth);
|
||||||
|
|
||||||
|
return Gesture.Pan()
|
||||||
|
.enabled(!isMobile)
|
||||||
|
.hitSlop({ left: 12, right: 12, top: 0, bottom: 0 })
|
||||||
|
.onBegin((event) => {
|
||||||
|
resizeStartRef.current = {
|
||||||
|
startWidth: treePaneWidth,
|
||||||
|
startX: event.absoluteX,
|
||||||
|
available,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.onUpdate((event) => {
|
||||||
|
const start = resizeStartRef.current;
|
||||||
|
if (!start) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const deltaX = event.absoluteX - start.startX;
|
||||||
|
const nextWidth = start.startWidth + deltaX;
|
||||||
|
const maxTree = Math.max(minTreeWidth, start.available - minPreviewWidth);
|
||||||
|
const clamped = Math.max(minTreeWidth, Math.min(maxTree, nextWidth));
|
||||||
|
const nextRatio = start.available > 0 ? clamped / start.available : splitRatio;
|
||||||
|
setSplitRatio(nextRatio);
|
||||||
|
})
|
||||||
|
.onFinalize(() => {
|
||||||
|
resizeStartRef.current = null;
|
||||||
|
});
|
||||||
|
}, [
|
||||||
|
containerWidth,
|
||||||
|
dividerWidth,
|
||||||
|
isMobile,
|
||||||
|
setSplitRatio,
|
||||||
|
shouldShowInlinePreview,
|
||||||
|
splitRatio,
|
||||||
|
treePaneWidth,
|
||||||
|
]);
|
||||||
|
|
||||||
const renderTreeRow = useCallback(
|
const renderTreeRow = useCallback(
|
||||||
({ item }: ListRenderItemInfo<TreeRow>) => {
|
({ item }: ListRenderItemInfo<TreeRow>) => {
|
||||||
@@ -401,7 +465,10 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View
|
||||||
|
style={styles.container}
|
||||||
|
onLayout={(event) => setContainerWidth(event.nativeEvent.layout.width)}
|
||||||
|
>
|
||||||
{error ? (
|
{error ? (
|
||||||
<View style={styles.centerState}>
|
<View style={styles.centerState}>
|
||||||
<Text style={styles.errorText}>{error}</Text>
|
<Text style={styles.errorText}>{error}</Text>
|
||||||
@@ -430,7 +497,13 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<View style={styles.desktopSplit}>
|
<View style={styles.desktopSplit}>
|
||||||
<View style={[styles.treePane, shouldShowInlinePreview && styles.treePaneWithPreview]}>
|
<View
|
||||||
|
style={[
|
||||||
|
styles.treePane,
|
||||||
|
shouldShowInlinePreview && styles.treePaneWithPreview,
|
||||||
|
shouldShowInlinePreview && treePaneWidth !== null ? { width: treePaneWidth } : null,
|
||||||
|
]}
|
||||||
|
>
|
||||||
<FlatList
|
<FlatList
|
||||||
data={treeRows}
|
data={treeRows}
|
||||||
renderItem={renderTreeRow}
|
renderItem={renderTreeRow}
|
||||||
@@ -444,7 +517,16 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
{shouldShowInlinePreview ? (
|
{shouldShowInlinePreview ? (
|
||||||
<View style={styles.previewPane}>
|
<>
|
||||||
|
<GestureDetector gesture={splitResizeGesture}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.splitResizeHandle,
|
||||||
|
Platform.OS === "web" && ({ cursor: "col-resize" } as any),
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</GestureDetector>
|
||||||
|
<View style={styles.previewPane}>
|
||||||
<View style={styles.previewHeaderContainer}>
|
<View style={styles.previewHeaderContainer}>
|
||||||
<View style={styles.previewHeaderInner}>
|
<View style={styles.previewHeaderInner}>
|
||||||
<Pressable
|
<Pressable
|
||||||
@@ -482,6 +564,7 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
|
|
||||||
<FilePreviewBody preview={preview} isLoading={isPreviewLoading} variant="inline" />
|
<FilePreviewBody preview={preview} isLoading={isPreviewLoading} variant="inline" />
|
||||||
</View>
|
</View>
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
@@ -517,7 +600,10 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
</View>
|
</View>
|
||||||
<View style={styles.entryMenuDivider} />
|
<View style={styles.entryMenuDivider} />
|
||||||
<Pressable
|
<Pressable
|
||||||
style={styles.entryMenuItem}
|
style={({ hovered, pressed }) => [
|
||||||
|
styles.entryMenuItem,
|
||||||
|
(hovered || pressed) && styles.entryMenuItemHovered,
|
||||||
|
]}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
handleCopyPath(menuEntry.path);
|
handleCopyPath(menuEntry.path);
|
||||||
handleCloseMenu();
|
handleCloseMenu();
|
||||||
@@ -527,7 +613,10 @@ export function FileExplorerPane({ serverId, agentId }: FileExplorerPaneProps) {
|
|||||||
</Pressable>
|
</Pressable>
|
||||||
{menuEntry.kind === "file" ? (
|
{menuEntry.kind === "file" ? (
|
||||||
<Pressable
|
<Pressable
|
||||||
style={styles.entryMenuItem}
|
style={({ hovered, pressed }) => [
|
||||||
|
styles.entryMenuItem,
|
||||||
|
(hovered || pressed) && styles.entryMenuItemHovered,
|
||||||
|
]}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
handleCloseMenu();
|
handleCloseMenu();
|
||||||
handleDownloadEntry(menuEntry);
|
handleDownloadEntry(menuEntry);
|
||||||
@@ -869,8 +958,12 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
minWidth: 0,
|
minWidth: 0,
|
||||||
},
|
},
|
||||||
treePaneWithPreview: {
|
treePaneWithPreview: {
|
||||||
borderRightWidth: 1,
|
},
|
||||||
borderRightColor: theme.colors.border,
|
splitResizeHandle: {
|
||||||
|
width: 10,
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
borderLeftWidth: 1,
|
||||||
|
borderLeftColor: theme.colors.border,
|
||||||
},
|
},
|
||||||
previewPane: {
|
previewPane: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@@ -974,36 +1067,43 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
backgroundColor: "rgba(0, 0, 0, 0.2)",
|
backgroundColor: "rgba(0, 0, 0, 0.2)",
|
||||||
},
|
},
|
||||||
entryMenu: {
|
entryMenu: {
|
||||||
borderRadius: theme.borderRadius.md,
|
borderRadius: theme.borderRadius.lg,
|
||||||
borderWidth: theme.borderWidth[1],
|
backgroundColor: theme.colors.surface1,
|
||||||
borderColor: theme.colors.border,
|
overflow: "hidden",
|
||||||
backgroundColor: theme.colors.surface2,
|
...(Platform.OS === "web"
|
||||||
padding: theme.spacing[1],
|
? ({ boxShadow: "0 10px 30px rgba(0, 0, 0, 0.35)" } as any)
|
||||||
|
: {
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOpacity: 0.35,
|
||||||
|
shadowRadius: 16,
|
||||||
|
shadowOffset: { width: 0, height: 10 },
|
||||||
|
elevation: 14,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
entryMenuHeader: {
|
entryMenuHeader: {
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
paddingVertical: theme.spacing[2],
|
paddingVertical: theme.spacing[3],
|
||||||
paddingHorizontal: theme.spacing[3],
|
paddingHorizontal: theme.spacing[4],
|
||||||
},
|
},
|
||||||
entryMenuMeta: {
|
entryMenuMeta: {
|
||||||
color: theme.colors.foregroundMuted,
|
color: theme.colors.foregroundMuted,
|
||||||
fontSize: theme.fontSize.xs,
|
fontSize: theme.fontSize.sm,
|
||||||
},
|
},
|
||||||
entryMenuDivider: {
|
entryMenuDivider: {
|
||||||
height: 1,
|
height: 1,
|
||||||
backgroundColor: theme.colors.border,
|
backgroundColor: theme.colors.border,
|
||||||
marginHorizontal: theme.spacing[2],
|
|
||||||
marginVertical: theme.spacing[1],
|
|
||||||
},
|
},
|
||||||
entryMenuItem: {
|
entryMenuItem: {
|
||||||
paddingVertical: theme.spacing[2],
|
paddingVertical: theme.spacing[4],
|
||||||
paddingHorizontal: theme.spacing[3],
|
paddingHorizontal: theme.spacing[4],
|
||||||
borderRadius: theme.borderRadius.md,
|
},
|
||||||
|
entryMenuItemHovered: {
|
||||||
|
backgroundColor: theme.colors.surface2,
|
||||||
},
|
},
|
||||||
entryMenuText: {
|
entryMenuText: {
|
||||||
color: theme.colors.foreground,
|
color: theme.colors.foreground,
|
||||||
fontSize: theme.fontSize.sm,
|
fontSize: theme.fontSize.lg,
|
||||||
fontWeight: theme.fontWeight.semibold,
|
fontWeight: theme.fontWeight.semibold,
|
||||||
},
|
},
|
||||||
previewHeaderContainer: {
|
previewHeaderContainer: {
|
||||||
|
|||||||
@@ -30,11 +30,15 @@ interface DesktopSidebarState {
|
|||||||
export type ExplorerTab = "changes" | "files";
|
export type ExplorerTab = "changes" | "files";
|
||||||
export type SortOption = "name" | "modified" | "size";
|
export type SortOption = "name" | "modified" | "size";
|
||||||
|
|
||||||
export const DEFAULT_EXPLORER_SIDEBAR_WIDTH = 400;
|
export const DEFAULT_EXPLORER_SIDEBAR_WIDTH = Platform.OS === "web" ? 520 : 400;
|
||||||
export const MIN_EXPLORER_SIDEBAR_WIDTH = 280;
|
export const MIN_EXPLORER_SIDEBAR_WIDTH = 280;
|
||||||
// Upper bound is intentionally generous; desktop resizing enforces a min-chat-width constraint.
|
// Upper bound is intentionally generous; desktop resizing enforces a min-chat-width constraint.
|
||||||
export const MAX_EXPLORER_SIDEBAR_WIDTH = 2000;
|
export const MAX_EXPLORER_SIDEBAR_WIDTH = 2000;
|
||||||
|
|
||||||
|
export const DEFAULT_EXPLORER_FILES_SPLIT_RATIO = 0.38;
|
||||||
|
export const MIN_EXPLORER_FILES_SPLIT_RATIO = 0.2;
|
||||||
|
export const MAX_EXPLORER_FILES_SPLIT_RATIO = 0.8;
|
||||||
|
|
||||||
interface PanelState {
|
interface PanelState {
|
||||||
// Mobile: which panel is currently shown
|
// Mobile: which panel is currently shown
|
||||||
mobileView: MobilePanelView;
|
mobileView: MobilePanelView;
|
||||||
@@ -46,6 +50,7 @@ interface PanelState {
|
|||||||
explorerTab: ExplorerTab;
|
explorerTab: ExplorerTab;
|
||||||
explorerWidth: number;
|
explorerWidth: number;
|
||||||
explorerSortOption: SortOption;
|
explorerSortOption: SortOption;
|
||||||
|
explorerFilesSplitRatio: number;
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
openAgentList: () => void;
|
openAgentList: () => void;
|
||||||
@@ -58,10 +63,19 @@ interface PanelState {
|
|||||||
setExplorerTab: (tab: ExplorerTab) => void;
|
setExplorerTab: (tab: ExplorerTab) => void;
|
||||||
setExplorerWidth: (width: number) => void;
|
setExplorerWidth: (width: number) => void;
|
||||||
setExplorerSortOption: (option: SortOption) => void;
|
setExplorerSortOption: (option: SortOption) => void;
|
||||||
|
setExplorerFilesSplitRatio: (ratio: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clampNumber(value: number, min: number, max: number): number {
|
||||||
|
return Math.max(min, Math.min(max, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function clampWidth(width: number): number {
|
function clampWidth(width: number): number {
|
||||||
return Math.max(MIN_EXPLORER_SIDEBAR_WIDTH, Math.min(MAX_EXPLORER_SIDEBAR_WIDTH, width));
|
return clampNumber(width, MIN_EXPLORER_SIDEBAR_WIDTH, MAX_EXPLORER_SIDEBAR_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clampExplorerFilesSplitRatio(ratio: number): number {
|
||||||
|
return clampNumber(ratio, MIN_EXPLORER_FILES_SPLIT_RATIO, MAX_EXPLORER_FILES_SPLIT_RATIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_DESKTOP_OPEN = Platform.OS === "web";
|
const DEFAULT_DESKTOP_OPEN = Platform.OS === "web";
|
||||||
@@ -82,6 +96,7 @@ export const usePanelStore = create<PanelState>()(
|
|||||||
explorerTab: "changes",
|
explorerTab: "changes",
|
||||||
explorerWidth: DEFAULT_EXPLORER_SIDEBAR_WIDTH,
|
explorerWidth: DEFAULT_EXPLORER_SIDEBAR_WIDTH,
|
||||||
explorerSortOption: "name",
|
explorerSortOption: "name",
|
||||||
|
explorerFilesSplitRatio: DEFAULT_EXPLORER_FILES_SPLIT_RATIO,
|
||||||
|
|
||||||
openAgentList: () =>
|
openAgentList: () =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
@@ -137,16 +152,39 @@ export const usePanelStore = create<PanelState>()(
|
|||||||
setExplorerTab: (tab) => set({ explorerTab: tab }),
|
setExplorerTab: (tab) => set({ explorerTab: tab }),
|
||||||
setExplorerWidth: (width) => set({ explorerWidth: clampWidth(width) }),
|
setExplorerWidth: (width) => set({ explorerWidth: clampWidth(width) }),
|
||||||
setExplorerSortOption: (option) => set({ explorerSortOption: option }),
|
setExplorerSortOption: (option) => set({ explorerSortOption: option }),
|
||||||
|
setExplorerFilesSplitRatio: (ratio) =>
|
||||||
|
set({ explorerFilesSplitRatio: clampExplorerFilesSplitRatio(ratio) }),
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: "panel-state",
|
name: "panel-state",
|
||||||
|
version: 2,
|
||||||
storage: createJSONStorage(() => AsyncStorage),
|
storage: createJSONStorage(() => AsyncStorage),
|
||||||
|
migrate: (persistedState, version) => {
|
||||||
|
const state = persistedState as Partial<PanelState> & Record<string, unknown>;
|
||||||
|
|
||||||
|
if (version < 2) {
|
||||||
|
if (
|
||||||
|
Platform.OS === "web" &&
|
||||||
|
typeof state.explorerWidth === "number" &&
|
||||||
|
state.explorerWidth === 400
|
||||||
|
) {
|
||||||
|
state.explorerWidth = DEFAULT_EXPLORER_SIDEBAR_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof state.explorerFilesSplitRatio !== "number") {
|
||||||
|
state.explorerFilesSplitRatio = DEFAULT_EXPLORER_FILES_SPLIT_RATIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state as PanelState;
|
||||||
|
},
|
||||||
partialize: (state) => ({
|
partialize: (state) => ({
|
||||||
mobileView: state.mobileView,
|
mobileView: state.mobileView,
|
||||||
desktop: state.desktop,
|
desktop: state.desktop,
|
||||||
explorerTab: state.explorerTab,
|
explorerTab: state.explorerTab,
|
||||||
explorerWidth: state.explorerWidth,
|
explorerWidth: state.explorerWidth,
|
||||||
explorerSortOption: state.explorerSortOption,
|
explorerSortOption: state.explorerSortOption,
|
||||||
|
explorerFilesSplitRatio: state.explorerFilesSplitRatio,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -177,9 +215,11 @@ export function usePanelState(isMobile: boolean) {
|
|||||||
explorerTab: store.explorerTab,
|
explorerTab: store.explorerTab,
|
||||||
explorerWidth: store.explorerWidth,
|
explorerWidth: store.explorerWidth,
|
||||||
explorerSortOption: store.explorerSortOption,
|
explorerSortOption: store.explorerSortOption,
|
||||||
|
explorerFilesSplitRatio: store.explorerFilesSplitRatio,
|
||||||
setExplorerTab: store.setExplorerTab,
|
setExplorerTab: store.setExplorerTab,
|
||||||
setExplorerWidth: store.setExplorerWidth,
|
setExplorerWidth: store.setExplorerWidth,
|
||||||
setExplorerSortOption: store.setExplorerSortOption,
|
setExplorerSortOption: store.setExplorerSortOption,
|
||||||
|
setExplorerFilesSplitRatio: store.setExplorerFilesSplitRatio,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,8 +243,10 @@ export function usePanelState(isMobile: boolean) {
|
|||||||
explorerTab: store.explorerTab,
|
explorerTab: store.explorerTab,
|
||||||
explorerWidth: store.explorerWidth,
|
explorerWidth: store.explorerWidth,
|
||||||
explorerSortOption: store.explorerSortOption,
|
explorerSortOption: store.explorerSortOption,
|
||||||
|
explorerFilesSplitRatio: store.explorerFilesSplitRatio,
|
||||||
setExplorerTab: store.setExplorerTab,
|
setExplorerTab: store.setExplorerTab,
|
||||||
setExplorerWidth: store.setExplorerWidth,
|
setExplorerWidth: store.setExplorerWidth,
|
||||||
setExplorerSortOption: store.setExplorerSortOption,
|
setExplorerSortOption: store.setExplorerSortOption,
|
||||||
|
setExplorerFilesSplitRatio: store.setExplorerFilesSplitRatio,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user