mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 13:23:28 +00:00
valtio
This commit is contained in:
parent
7be22c96e5
commit
a9087ca429
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -27,7 +27,8 @@
|
||||||
"trivago",
|
"trivago",
|
||||||
"tsparticles",
|
"tsparticles",
|
||||||
"unlisten",
|
"unlisten",
|
||||||
"upsert"
|
"upsert",
|
||||||
|
"valtio"
|
||||||
],
|
],
|
||||||
"[rust]": {
|
"[rust]": {
|
||||||
"editor.defaultFormatter": "rust-lang.rust-analyzer"
|
"editor.defaultFormatter": "rust-lang.rust-analyzer"
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rspc/client": "^0.0.5",
|
"@rspc/client": "^0.0.5",
|
||||||
"@sd/core": "workspace:*",
|
|
||||||
"@sd/config": "workspace:*",
|
"@sd/config": "workspace:*",
|
||||||
|
"@sd/core": "workspace:*",
|
||||||
"@sd/interface": "workspace:*",
|
"@sd/interface": "workspace:*",
|
||||||
"@tanstack/react-query": "^4.0.10",
|
"@tanstack/react-query": "^4.0.10",
|
||||||
"eventemitter3": "^4.0.7",
|
"eventemitter3": "^4.0.7",
|
||||||
"immer": "^9.0.15",
|
"immer": "^9.0.15",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"valtio": "^1.6.4",
|
||||||
|
"valtio-persist": "^1.0.2",
|
||||||
"zustand": "4.0.0"
|
"zustand": "4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
48
packages/client/src/stores/explorerStore.ts
Normal file
48
packages/client/src/stores/explorerStore.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import { proxy, ref } from 'valtio';
|
||||||
|
|
||||||
|
export type ExplorerLayoutMode = 'list' | 'grid';
|
||||||
|
|
||||||
|
export enum ExplorerKind {
|
||||||
|
Location,
|
||||||
|
Tag,
|
||||||
|
Space
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
locationId: null as number | null,
|
||||||
|
layoutMode: 'grid' as ExplorerLayoutMode,
|
||||||
|
gridItemSize: 100,
|
||||||
|
listItemSize: 40,
|
||||||
|
selectedRowIndex: 1,
|
||||||
|
showInspector: true,
|
||||||
|
multiSelectIndexes: [] as number[],
|
||||||
|
contextMenuObjectId: null as number | null,
|
||||||
|
newThumbnails: {} as Record<string, boolean>
|
||||||
|
};
|
||||||
|
|
||||||
|
export const explorerStore = proxy({
|
||||||
|
...state,
|
||||||
|
reset: () => resetStore(explorerStore, state),
|
||||||
|
addNewThumbnail: (cas_id: string) => {
|
||||||
|
explorerStore.newThumbnails[cas_id] = true;
|
||||||
|
},
|
||||||
|
selectMore: (indexes: number[]) => {
|
||||||
|
if (!explorerStore.multiSelectIndexes.length && indexes.length) {
|
||||||
|
explorerStore.multiSelectIndexes = [explorerStore.selectedRowIndex, ...indexes];
|
||||||
|
} else {
|
||||||
|
explorerStore.multiSelectIndexes = [
|
||||||
|
...new Set([...explorerStore.multiSelectIndexes, ...indexes])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export function resetStore<T extends Record<string, any>, E extends Record<string, any>>(
|
||||||
|
store: T,
|
||||||
|
defaults: E
|
||||||
|
) {
|
||||||
|
for (const key in defaults) {
|
||||||
|
// @ts-ignore
|
||||||
|
store[key] = defaults[key];
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,2 @@
|
||||||
export * from './useLibraryStore';
|
export * from './useLibraryStore';
|
||||||
export * from './useExplorerStore';
|
export * from './explorerStore';
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
import produce from 'immer';
|
|
||||||
import create from 'zustand';
|
|
||||||
|
|
||||||
export type ExplorerLayoutMode = 'list' | 'grid';
|
|
||||||
|
|
||||||
export enum ExplorerKind {
|
|
||||||
Location,
|
|
||||||
Tag,
|
|
||||||
Space
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExplorerStore = {
|
|
||||||
layoutMode: ExplorerLayoutMode;
|
|
||||||
locationId: number | null; // used by top bar
|
|
||||||
gridItemSize: number;
|
|
||||||
listItemSize: number;
|
|
||||||
showInspector: boolean;
|
|
||||||
selectedRowIndex: number;
|
|
||||||
multiSelectIndexes: number[];
|
|
||||||
contextMenuObjectId: number | null;
|
|
||||||
newThumbnails: Record<string, boolean>;
|
|
||||||
addNewThumbnail: (cas_id: string) => void;
|
|
||||||
selectMore: (indexes: number[]) => void;
|
|
||||||
reset: () => void;
|
|
||||||
set: (changes: Partial<ExplorerStore>) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useExplorerStore = create<ExplorerStore>((set) => ({
|
|
||||||
layoutMode: 'grid',
|
|
||||||
locationId: null,
|
|
||||||
gridItemSize: 100,
|
|
||||||
listItemSize: 40,
|
|
||||||
showInspector: true,
|
|
||||||
selectedRowIndex: 1,
|
|
||||||
multiSelectIndexes: [],
|
|
||||||
contextMenuObjectId: -1,
|
|
||||||
newThumbnails: {},
|
|
||||||
addNewThumbnail: (cas_id) =>
|
|
||||||
set((state) =>
|
|
||||||
produce(state, (draft) => {
|
|
||||||
draft.newThumbnails[cas_id] = true;
|
|
||||||
})
|
|
||||||
),
|
|
||||||
selectMore: (indexes) => {
|
|
||||||
set((state) =>
|
|
||||||
produce(state, (draft) => {
|
|
||||||
if (!draft.multiSelectIndexes.length && indexes.length) {
|
|
||||||
draft.multiSelectIndexes = [draft.selectedRowIndex, ...indexes];
|
|
||||||
} else {
|
|
||||||
draft.multiSelectIndexes = [...new Set([...draft.multiSelectIndexes, ...indexes])];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
reset: () => set(() => ({})),
|
|
||||||
set: (changes) => set((state) => ({ ...state, ...changes }))
|
|
||||||
}));
|
|
|
@ -5,7 +5,7 @@ import create from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
|
|
||||||
import { useBridgeQuery } from '../index';
|
import { useBridgeQuery } from '../index';
|
||||||
import { useExplorerStore } from './useExplorerStore';
|
import { explorerStore } from './explorerStore';
|
||||||
|
|
||||||
type LibraryStore = {
|
type LibraryStore = {
|
||||||
// the uuid of the currently active library
|
// the uuid of the currently active library
|
||||||
|
@ -28,7 +28,7 @@ export const useLibraryStore = create<LibraryStore>()(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
// reset other stores
|
// reset other stores
|
||||||
useExplorerStore().reset();
|
explorerStore.reset();
|
||||||
},
|
},
|
||||||
init: async (libraries) => {
|
init: async (libraries) => {
|
||||||
set((state) =>
|
set((state) =>
|
||||||
|
|
|
@ -68,6 +68,8 @@
|
||||||
"tailwindcss": "^3.1.6",
|
"tailwindcss": "^3.1.6",
|
||||||
"use-count-up": "^3.0.1",
|
"use-count-up": "^3.0.1",
|
||||||
"use-debounce": "^8.0.3",
|
"use-debounce": "^8.0.3",
|
||||||
|
"valtio": "^1.6.4",
|
||||||
|
"valtio-persist": "^1.0.2",
|
||||||
"zod": "^3.18.0",
|
"zod": "^3.18.0",
|
||||||
"zustand": "4.0.0"
|
"zustand": "4.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {
|
import {
|
||||||
|
explorerStore,
|
||||||
rspc,
|
rspc,
|
||||||
useExplorerStore,
|
|
||||||
useLibraryMutation,
|
useLibraryMutation,
|
||||||
useLibraryQuery,
|
useLibraryQuery,
|
||||||
useLibraryStore
|
useLibraryStore
|
||||||
|
@ -17,6 +17,7 @@ import {
|
||||||
TrashSimple
|
TrashSimple
|
||||||
} from 'phosphor-react';
|
} from 'phosphor-react';
|
||||||
import React, { memo, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
import React, { memo, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import { Inspector } from '../explorer/Inspector';
|
import { Inspector } from '../explorer/Inspector';
|
||||||
import { WithContextMenu } from '../layout/MenuOverlay';
|
import { WithContextMenu } from '../layout/MenuOverlay';
|
||||||
|
@ -29,7 +30,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Explorer(props: Props) {
|
export default function Explorer(props: Props) {
|
||||||
const addNewThumbnail = useExplorerStore((store) => store.addNewThumbnail);
|
const { addNewThumbnail, selectedRowIndex, showInspector } = useSnapshot(explorerStore);
|
||||||
|
|
||||||
const currentLibraryUuid = useLibraryStore((store) => store.currentLibraryUuid);
|
const currentLibraryUuid = useLibraryStore((store) => store.currentLibraryUuid);
|
||||||
|
|
||||||
|
@ -39,11 +40,6 @@ export default function Explorer(props: Props) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { selectedRowIndex, showInspector } = useExplorerStore((store) => ({
|
|
||||||
selectedRowIndex: store.selectedRowIndex,
|
|
||||||
showInspector: store.showInspector
|
|
||||||
}));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<ExplorerContextMenu>
|
<ExplorerContextMenu>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useExplorerStore, useLibraryMutation, useLibraryQuery } from '@sd/client';
|
import { explorerStore, useLibraryMutation, useLibraryQuery } from '@sd/client';
|
||||||
import { ExplorerData } from '@sd/core';
|
import { ExplorerData } from '@sd/core';
|
||||||
import {
|
import {
|
||||||
ArrowBendUpRight,
|
ArrowBendUpRight,
|
||||||
|
@ -11,6 +11,7 @@ import {
|
||||||
TrashSimple
|
TrashSimple
|
||||||
} from 'phosphor-react';
|
} from 'phosphor-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import { WithContextMenu } from '../layout/MenuOverlay';
|
import { WithContextMenu } from '../layout/MenuOverlay';
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ExplorerContextMenu(props: Props) {
|
export default function ExplorerContextMenu(props: Props) {
|
||||||
const contextMenuObjectId = useExplorerStore((store) => store.contextMenuObjectId);
|
const contextMenuObjectId = useSnapshot(explorerStore).contextMenuObjectId;
|
||||||
|
|
||||||
const { data: tags } = useLibraryQuery(['tags.getAll'], {});
|
const { data: tags } = useLibraryQuery(['tags.getAll'], {});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { useExplorerStore } from '@sd/client';
|
import { explorerStore } from '@sd/client';
|
||||||
import { ExplorerItem } from '@sd/core';
|
import { ExplorerItem } from '@sd/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import FileThumb from './FileThumb';
|
import FileThumb from './FileThumb';
|
||||||
import { isObject } from './utils';
|
import { isObject } from './utils';
|
||||||
|
@ -13,17 +14,17 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function FileItem(props: Props) {
|
function FileItem(props: Props) {
|
||||||
const set = useExplorerStore.getState().set;
|
const { gridItemSize } = useSnapshot(explorerStore);
|
||||||
|
|
||||||
const size = useExplorerStore((state) => state.gridItemSize) || 100;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
const objectId = isObject(props.data) ? props.data.id : props.data.file?.id;
|
const objectId = isObject(props.data) ? props.data.id : props.data.file?.id;
|
||||||
if (objectId != undefined) {
|
if (objectId != undefined) {
|
||||||
set({ contextMenuObjectId: objectId });
|
explorerStore.contextMenuObjectId = objectId;
|
||||||
if (props.index != undefined) set({ selectedRowIndex: props.index });
|
if (props.index != undefined) {
|
||||||
|
explorerStore.selectedRowIndex = props.index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
draggable
|
draggable
|
||||||
|
@ -31,7 +32,7 @@ function FileItem(props: Props) {
|
||||||
className={clsx('inline-block w-[100px] mb-3', props.className)}
|
className={clsx('inline-block w-[100px] mb-3', props.className)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{ width: size, height: size }}
|
style={{ width: gridItemSize, height: gridItemSize }}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'border-2 border-transparent rounded-lg text-center mb-1 active:translate-y-[1px]',
|
'border-2 border-transparent rounded-lg text-center mb-1 active:translate-y-[1px]',
|
||||||
{
|
{
|
||||||
|
@ -49,7 +50,7 @@ function FileItem(props: Props) {
|
||||||
'border-4 border-gray-250 rounded-sm shadow-md shadow-gray-750 max-h-full max-w-full overflow-hidden'
|
'border-4 border-gray-250 rounded-sm shadow-md shadow-gray-750 max-h-full max-w-full overflow-hidden'
|
||||||
)}
|
)}
|
||||||
data={props.data}
|
data={props.data}
|
||||||
size={size}
|
size={gridItemSize}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { EllipsisHorizontalIcon } from '@heroicons/react/24/solid';
|
import { EllipsisHorizontalIcon } from '@heroicons/react/24/solid';
|
||||||
import { LocationContext, useBridgeQuery, useExplorerStore, useLibraryQuery } from '@sd/client';
|
import { LocationContext, explorerStore, useBridgeQuery, useLibraryQuery } from '@sd/client';
|
||||||
import { ExplorerContext, ExplorerItem, FilePath } from '@sd/core';
|
import { ExplorerContext, ExplorerItem, FilePath } from '@sd/core';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { AppPropsContext, useExplorerStore } from '@sd/client';
|
import { AppPropsContext, explorerStore } from '@sd/client';
|
||||||
import { ExplorerItem } from '@sd/core';
|
import { ExplorerItem } from '@sd/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import icons from '../../assets/icons';
|
import icons from '../../assets/icons';
|
||||||
import { Folder } from '../icons/Folder';
|
import { Folder } from '../icons/Folder';
|
||||||
|
@ -16,7 +17,7 @@ interface Props {
|
||||||
|
|
||||||
export default function FileThumb({ data, ...props }: Props) {
|
export default function FileThumb({ data, ...props }: Props) {
|
||||||
const appProps = useContext(AppPropsContext);
|
const appProps = useContext(AppPropsContext);
|
||||||
const newThumbnails = useExplorerStore((store) => store.newThumbnails);
|
const { newThumbnails } = useSnapshot(explorerStore);
|
||||||
|
|
||||||
if (isPath(data) && data.is_dir) return <Folder size={props.size * 0.7} />;
|
if (isPath(data) && data.is_dir) return <Folder size={props.size * 0.7} />;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { ExplorerLayoutMode, useExplorerStore } from '@sd/client';
|
import { ExplorerLayoutMode, explorerStore } from '@sd/client';
|
||||||
import { ExplorerContext, ExplorerItem, FilePath } from '@sd/core';
|
import { ExplorerContext, ExplorerItem, FilePath } from '@sd/core';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import React, { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
import React, { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useKey, useWindowSize } from 'rooks';
|
import { useKey, useWindowSize } from 'rooks';
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import FileItem from './FileItem';
|
import FileItem from './FileItem';
|
||||||
import FileRow from './FileRow';
|
import FileRow from './FileRow';
|
||||||
|
@ -23,16 +24,16 @@ export const VirtualizedList: React.FC<Props> = ({ data, context }) => {
|
||||||
const [goingUp, setGoingUp] = useState(false);
|
const [goingUp, setGoingUp] = useState(false);
|
||||||
const [width, setWidth] = useState(0);
|
const [width, setWidth] = useState(0);
|
||||||
|
|
||||||
const { gridItemSize, layoutMode, listItemSize, selectedRowIndex } = useExplorerStore(
|
// const { gridItemSize, layoutMode, listItemSize, selectedRowIndex } = useExplorerStore(
|
||||||
(state) => ({
|
// (state) => ({
|
||||||
selectedRowIndex: state.selectedRowIndex,
|
// selectedRowIndex: state.selectedRowIndex,
|
||||||
gridItemSize: state.gridItemSize,
|
// gridItemSize: state.gridItemSize,
|
||||||
layoutMode: state.layoutMode,
|
// layoutMode: state.layoutMode,
|
||||||
listItemSize: state.listItemSize
|
// listItemSize: state.listItemSize
|
||||||
})
|
// })
|
||||||
);
|
// );
|
||||||
|
|
||||||
const set = useExplorerStore.getState().set;
|
const { gridItemSize, layoutMode, listItemSize, selectedRowIndex } = useSnapshot(explorerStore);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
setWidth(innerRef.current?.offsetWidth || 0);
|
setWidth(innerRef.current?.offsetWidth || 0);
|
||||||
|
@ -61,14 +62,14 @@ export const VirtualizedList: React.FC<Props> = ({ data, context }) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setGoingUp(true);
|
setGoingUp(true);
|
||||||
if (selectedRowIndex !== -1 && selectedRowIndex !== 0)
|
if (selectedRowIndex !== -1 && selectedRowIndex !== 0)
|
||||||
set({ selectedRowIndex: selectedRowIndex - 1 });
|
explorerStore.selectedRowIndex = selectedRowIndex - 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
useKey('ArrowDown', (e) => {
|
useKey('ArrowDown', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setGoingUp(false);
|
setGoingUp(false);
|
||||||
if (selectedRowIndex !== -1 && selectedRowIndex !== (data.length ?? 1) - 1)
|
if (selectedRowIndex !== -1 && selectedRowIndex !== (data.length ?? 1) - 1)
|
||||||
set({ selectedRowIndex: selectedRowIndex + 1 });
|
explorerStore.selectedRowIndex = selectedRowIndex + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
// const Header = () => (
|
// const Header = () => (
|
||||||
|
@ -164,7 +165,7 @@ const WrappedItem: React.FC<WrappedItemProps> = memo(({ item, index, isSelected,
|
||||||
}, [item, setSearchParams]);
|
}, [item, setSearchParams]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
useExplorerStore.getState().set({ selectedRowIndex: isSelected ? -1 : index });
|
explorerStore.selectedRowIndex = isSelected ? -1 : index;
|
||||||
}, [isSelected, index]);
|
}, [isSelected, index]);
|
||||||
|
|
||||||
if (kind === 'list') {
|
if (kind === 'list') {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
||||||
import { AppPropsContext, useExplorerStore, useLibraryMutation } from '@sd/client';
|
import { AppPropsContext, explorerStore, useLibraryMutation } from '@sd/client';
|
||||||
import { Dropdown } from '@sd/ui';
|
import { Dropdown } from '@sd/ui';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import {
|
import {
|
||||||
|
@ -13,6 +13,7 @@ import {
|
||||||
} from 'phosphor-react';
|
} from 'phosphor-react';
|
||||||
import React, { DetailedHTMLProps, HTMLAttributes, RefAttributes, useContext } from 'react';
|
import React, { DetailedHTMLProps, HTMLAttributes, RefAttributes, useContext } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import { Shortcut } from '../primitive/Shortcut';
|
import { Shortcut } from '../primitive/Shortcut';
|
||||||
import { DefaultProps } from '../primitive/types';
|
import { DefaultProps } from '../primitive/types';
|
||||||
|
@ -80,7 +81,7 @@ const SearchBar = React.forwardRef<HTMLInputElement, DefaultProps>((props, ref)
|
||||||
});
|
});
|
||||||
|
|
||||||
export const TopBar: React.FC<TopBarProps> = (props) => {
|
export const TopBar: React.FC<TopBarProps> = (props) => {
|
||||||
const { layoutMode, set, locationId, showInspector } = useExplorerStore();
|
const { layoutMode, locationId, showInspector } = useSnapshot(explorerStore);
|
||||||
const { mutate: generateThumbsForLocation } = useLibraryMutation(
|
const { mutate: generateThumbsForLocation } = useLibraryMutation(
|
||||||
'jobs.generateThumbsForLocation',
|
'jobs.generateThumbsForLocation',
|
||||||
{
|
{
|
||||||
|
@ -159,7 +160,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
||||||
left
|
left
|
||||||
active={layoutMode === 'list'}
|
active={layoutMode === 'list'}
|
||||||
icon={Rows}
|
icon={Rows}
|
||||||
onClick={() => set({ layoutMode: 'list' })}
|
onClick={() => (explorerStore.layoutMode = 'list')}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="Grid view">
|
<Tooltip label="Grid view">
|
||||||
|
@ -168,7 +169,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
||||||
right
|
right
|
||||||
active={layoutMode === 'grid'}
|
active={layoutMode === 'grid'}
|
||||||
icon={SquaresFour}
|
icon={SquaresFour}
|
||||||
onClick={() => set({ layoutMode: 'grid' })}
|
onClick={() => (explorerStore.layoutMode = 'grid')}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -194,7 +195,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
||||||
<div className="flex mr-3 space-x-2">
|
<div className="flex mr-3 space-x-2">
|
||||||
<TopBarButton
|
<TopBarButton
|
||||||
active={showInspector}
|
active={showInspector}
|
||||||
onClick={() => set({ showInspector: !showInspector })}
|
onClick={() => (explorerStore.showInspector = !showInspector)}
|
||||||
className="my-2"
|
className="my-2"
|
||||||
icon={SidebarSimple}
|
icon={SidebarSimple}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import { useExplorerStore, useLibraryQuery, useLibraryStore } from '@sd/client';
|
import { explorerStore, useLibraryQuery, useLibraryStore } from '@sd/client';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { useParams, useSearchParams } from 'react-router-dom';
|
||||||
import z from 'zod';
|
import z from 'zod';
|
||||||
|
@ -20,10 +20,8 @@ export function useExplorerParams() {
|
||||||
export const LocationExplorer: React.FC<unknown> = () => {
|
export const LocationExplorer: React.FC<unknown> = () => {
|
||||||
const { location_id, path } = useExplorerParams();
|
const { location_id, path } = useExplorerParams();
|
||||||
|
|
||||||
// for top bar location context, could be replaced with react context as it is child component
|
|
||||||
const set = useExplorerStore((state) => state.set);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
set({ locationId: location_id });
|
explorerStore.locationId = location_id;
|
||||||
}, [location_id]);
|
}, [location_id]);
|
||||||
|
|
||||||
const library_id = useLibraryStore((state) => state.currentLibraryUuid);
|
const library_id = useLibraryStore((state) => state.currentLibraryUuid);
|
||||||
|
|
|
@ -236,6 +236,8 @@ importers:
|
||||||
scripts: '*'
|
scripts: '*'
|
||||||
tsconfig: '*'
|
tsconfig: '*'
|
||||||
typescript: ^4.7.4
|
typescript: ^4.7.4
|
||||||
|
valtio: ^1.6.4
|
||||||
|
valtio-persist: ^1.0.2
|
||||||
zustand: 4.0.0
|
zustand: 4.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rspc/client': 0.0.5
|
'@rspc/client': 0.0.5
|
||||||
|
@ -246,6 +248,8 @@ importers:
|
||||||
eventemitter3: 4.0.7
|
eventemitter3: 4.0.7
|
||||||
immer: 9.0.15
|
immer: 9.0.15
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
|
valtio: 1.6.4
|
||||||
|
valtio-persist: 1.0.2_valtio@1.6.4
|
||||||
zustand: 4.0.0_immer@9.0.15
|
zustand: 4.0.0_immer@9.0.15
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/lodash': 4.14.182
|
'@types/lodash': 4.14.182
|
||||||
|
@ -340,6 +344,8 @@ importers:
|
||||||
typescript: ^4.7.4
|
typescript: ^4.7.4
|
||||||
use-count-up: ^3.0.1
|
use-count-up: ^3.0.1
|
||||||
use-debounce: ^8.0.3
|
use-debounce: ^8.0.3
|
||||||
|
valtio: ^1.6.4
|
||||||
|
valtio-persist: ^1.0.2
|
||||||
vite: ^3.0.3
|
vite: ^3.0.3
|
||||||
vite-plugin-svgr: ^2.2.1
|
vite-plugin-svgr: ^2.2.1
|
||||||
zod: ^3.18.0
|
zod: ^3.18.0
|
||||||
|
@ -369,7 +375,7 @@ importers:
|
||||||
byte-size: 8.1.0
|
byte-size: 8.1.0
|
||||||
clsx: 1.2.1
|
clsx: 1.2.1
|
||||||
immer: 9.0.15
|
immer: 9.0.15
|
||||||
jotai: 1.8.2_immer@9.0.15+react@18.2.0
|
jotai: 1.8.2_umupx7nluxw42lgh4svggrlwmq
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
moment: 2.29.4
|
moment: 2.29.4
|
||||||
phosphor-react: 1.4.1_react@18.2.0
|
phosphor-react: 1.4.1_react@18.2.0
|
||||||
|
@ -398,6 +404,8 @@ importers:
|
||||||
tailwindcss: 3.1.8
|
tailwindcss: 3.1.8
|
||||||
use-count-up: 3.0.1_react@18.2.0
|
use-count-up: 3.0.1_react@18.2.0
|
||||||
use-debounce: 8.0.4_react@18.2.0
|
use-debounce: 8.0.4_react@18.2.0
|
||||||
|
valtio: 1.6.4_react@18.2.0+vite@3.0.9
|
||||||
|
valtio-persist: 1.0.2_valtio@1.6.4
|
||||||
zod: 3.18.0
|
zod: 3.18.0
|
||||||
zustand: 4.0.0_immer@9.0.15+react@18.2.0
|
zustand: 4.0.0_immer@9.0.15+react@18.2.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
@ -12458,7 +12466,7 @@ packages:
|
||||||
regenerator-runtime: 0.13.9
|
regenerator-runtime: 0.13.9
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/jotai/1.8.2_immer@9.0.15+react@18.2.0:
|
/jotai/1.8.2_umupx7nluxw42lgh4svggrlwmq:
|
||||||
resolution: {integrity: sha512-jRKTQKChLAJGB3zG5zklJoMtpWYixUi2jK3pZd5ZRpH4pQnjYYEOAVYCzZGr4Ce5Uj7j0ffYoLM4ULAAQXUoGw==}
|
resolution: {integrity: sha512-jRKTQKChLAJGB3zG5zklJoMtpWYixUi2jK3pZd5ZRpH4pQnjYYEOAVYCzZGr4Ce5Uj7j0ffYoLM4ULAAQXUoGw==}
|
||||||
engines: {node: '>=12.7.0'}
|
engines: {node: '>=12.7.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -12494,6 +12502,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
immer: 9.0.15
|
immer: 9.0.15
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
|
valtio: 1.6.4_react@18.2.0+vite@3.0.9
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/jpeg-js/0.4.2:
|
/jpeg-js/0.4.2:
|
||||||
|
@ -14942,6 +14951,10 @@ packages:
|
||||||
forwarded: 0.2.0
|
forwarded: 0.2.0
|
||||||
ipaddr.js: 1.9.1
|
ipaddr.js: 1.9.1
|
||||||
|
|
||||||
|
/proxy-compare/2.3.0:
|
||||||
|
resolution: {integrity: sha512-c3L2CcAi7f7pvlD0D7xsF+2CQIW8C3HaYx2Pfgq8eA4HAl3GAH6/dVYsyBbYF/0XJs2ziGLrzmz5fmzPm6A0pQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prr/1.0.1:
|
/prr/1.0.1:
|
||||||
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -18311,6 +18324,73 @@ packages:
|
||||||
spdx-expression-parse: 3.0.1
|
spdx-expression-parse: 3.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/valtio-persist/1.0.2_valtio@1.6.4:
|
||||||
|
resolution: {integrity: sha512-OBVEUZTS1heiA5R3j8CPDuXIMmmjIvq/4CiO+pElXd7f7b7nR3vIH5qql35hXw/AkLdftqTUcVCNVf6yAJ1ypA==}
|
||||||
|
peerDependencies:
|
||||||
|
valtio: ^1.2.5
|
||||||
|
dependencies:
|
||||||
|
lodash: 4.17.21
|
||||||
|
valtio: 1.6.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/valtio/1.6.4:
|
||||||
|
resolution: {integrity: sha512-wEslN1bO1ihuv2Xj4jIxkGaDgsnwSvZdcaYcJ6aSwaNYU0ZMe+eZipfEzbTqd4CwnMu7ihDBNes0ZP5CIl1NqA==}
|
||||||
|
engines: {node: '>=12.7.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/helper-module-imports': '>=7.12'
|
||||||
|
'@babel/types': '>=7.13'
|
||||||
|
aslemammad-vite-plugin-macro: '>=1.0.0-alpha.1'
|
||||||
|
babel-plugin-macros: '>=3.0'
|
||||||
|
react: '>=16.8'
|
||||||
|
vite: '>=2.8.6'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@babel/helper-module-imports':
|
||||||
|
optional: true
|
||||||
|
'@babel/types':
|
||||||
|
optional: true
|
||||||
|
aslemammad-vite-plugin-macro:
|
||||||
|
optional: true
|
||||||
|
babel-plugin-macros:
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
vite:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
proxy-compare: 2.3.0
|
||||||
|
use-sync-external-store: 1.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/valtio/1.6.4_react@18.2.0+vite@3.0.9:
|
||||||
|
resolution: {integrity: sha512-wEslN1bO1ihuv2Xj4jIxkGaDgsnwSvZdcaYcJ6aSwaNYU0ZMe+eZipfEzbTqd4CwnMu7ihDBNes0ZP5CIl1NqA==}
|
||||||
|
engines: {node: '>=12.7.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/helper-module-imports': '>=7.12'
|
||||||
|
'@babel/types': '>=7.13'
|
||||||
|
aslemammad-vite-plugin-macro: '>=1.0.0-alpha.1'
|
||||||
|
babel-plugin-macros: '>=3.0'
|
||||||
|
react: '>=16.8'
|
||||||
|
vite: '>=2.8.6'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@babel/helper-module-imports':
|
||||||
|
optional: true
|
||||||
|
'@babel/types':
|
||||||
|
optional: true
|
||||||
|
aslemammad-vite-plugin-macro:
|
||||||
|
optional: true
|
||||||
|
babel-plugin-macros:
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
vite:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
proxy-compare: 2.3.0
|
||||||
|
react: 18.2.0
|
||||||
|
use-sync-external-store: 1.2.0_react@18.2.0
|
||||||
|
vite: 3.0.9
|
||||||
|
dev: false
|
||||||
|
|
||||||
/varname/2.0.3:
|
/varname/2.0.3:
|
||||||
resolution: {integrity: sha512-+DofT9mJAUALhnr9ipZ5Z2icwaEZ7DAajOZT4ffXy3MQqnXtG3b7atItLQEJCkfcJTOf9WcsywneOEibD4eqJg==}
|
resolution: {integrity: sha512-+DofT9mJAUALhnr9ipZ5Z2icwaEZ7DAajOZT4ffXy3MQqnXtG3b7atItLQEJCkfcJTOf9WcsywneOEibD4eqJg==}
|
||||||
engines: {node: '>=0.10'}
|
engines: {node: '>=0.10'}
|
||||||
|
|
Loading…
Reference in a new issue