mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-02 11:13:29 +00:00
[ENG-1745] Mouse wheel resize (#2366)
* Resize layout items with mouse wheel icon/item size using mouse wheel Update useMouseItemResize.ts Update useMouseItemResize.ts * improve comment * fb * Update useMouseItemResize.ts * Update IconSize.tsx
This commit is contained in:
parent
5624054f1e
commit
f97a761346
|
@ -15,8 +15,8 @@ export const IconSize = () => {
|
|||
const explorer = useExplorerContext();
|
||||
const settings = explorer.useSettingsSnapshot();
|
||||
|
||||
const defaultValue = useMemo(
|
||||
() => sizes.findIndex((size) => size[0] === settings.listViewIconSize),
|
||||
const value = useMemo(
|
||||
() => sizes.indexMap.get(settings.listViewIconSize),
|
||||
[settings.listViewIconSize]
|
||||
);
|
||||
|
||||
|
@ -25,11 +25,11 @@ export const IconSize = () => {
|
|||
<Subheading>{t('icon_size')}</Subheading>
|
||||
<Slider
|
||||
step={1}
|
||||
max={sizes.length - 1}
|
||||
defaultValue={[defaultValue]}
|
||||
max={sizes.sizeMap.size - 1}
|
||||
value={[value ?? 0]}
|
||||
onValueChange={([value]) => {
|
||||
const size = value !== undefined && sizes[value];
|
||||
if (size) explorer.settingsStore.listViewIconSize = size[0];
|
||||
const size = value !== undefined && sizes.sizeMap.get(value);
|
||||
if (size) explorer.settingsStore.listViewIconSize = size;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -16,7 +16,7 @@ export const TextSize = () => {
|
|||
const settings = explorer.useSettingsSnapshot();
|
||||
|
||||
const defaultValue = useMemo(
|
||||
() => sizes.findIndex((size) => size[0] === settings.listViewTextSize),
|
||||
() => sizes.indexMap.get(settings.listViewTextSize),
|
||||
[settings.listViewTextSize]
|
||||
);
|
||||
|
||||
|
@ -25,11 +25,11 @@ export const TextSize = () => {
|
|||
<Subheading>{t('text_size')}</Subheading>
|
||||
<Slider
|
||||
step={1}
|
||||
max={sizes.length - 1}
|
||||
defaultValue={[defaultValue]}
|
||||
max={sizes.sizeMap.size - 1}
|
||||
defaultValue={[defaultValue ?? 0]}
|
||||
onValueChange={([value]) => {
|
||||
const size = value !== undefined && sizes[value];
|
||||
if (size) explorer.settingsStore.listViewTextSize = size[0];
|
||||
const size = value !== undefined && sizes.sizeMap.get(value);
|
||||
if (size) explorer.settingsStore.listViewTextSize = size;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
export function getSizes<T extends { [key: string]: number }>(sizes: T) {
|
||||
return (Object.entries(sizes) as [keyof T, T[keyof T]][]).sort((a, b) => a[1] - b[1]);
|
||||
const sizesArr = (Object.entries(sizes) as [keyof T, T[keyof T]][]).sort((a, b) => a[1] - b[1]);
|
||||
|
||||
// Map fo size to index
|
||||
const indexMap = new Map<keyof T, number>();
|
||||
|
||||
// Map of index to size
|
||||
const sizeMap = new Map<number, keyof T>();
|
||||
|
||||
for (let i = 0; i < sizesArr.length; i++) {
|
||||
const size = sizesArr[i];
|
||||
if (!size) continue;
|
||||
indexMap.set(size[0], i);
|
||||
sizeMap.set(i, size[0]);
|
||||
}
|
||||
|
||||
return { indexMap, sizeMap };
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ export default () => {
|
|||
onValueChange={(value) => {
|
||||
explorer.settingsStore.gridItemSize = value[0] || 100;
|
||||
}}
|
||||
defaultValue={[settings.gridItemSize]}
|
||||
value={[settings.gridItemSize]}
|
||||
max={200}
|
||||
step={10}
|
||||
min={60}
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from '@sd/client';
|
||||
import { dialogManager } from '@sd/ui';
|
||||
import { Loader } from '~/components';
|
||||
import { useKeyMatcher, useShortcut } from '~/hooks';
|
||||
import { useKeyMatcher, useMouseItemResize, useShortcut } from '~/hooks';
|
||||
import { useRoutingContext } from '~/RoutingContext';
|
||||
import { isNonEmpty } from '~/util';
|
||||
|
||||
|
@ -139,6 +139,9 @@ export const View = ({ emptyNotice, ...contextProps }: ExplorerViewProps) => {
|
|||
return () => element.removeEventListener('wheel', handleWheel);
|
||||
}, [explorer.scrollRef, drag?.type]);
|
||||
|
||||
// Handle resizing of items in the Explorer grid and list view using the mouse wheel
|
||||
useMouseItemResize();
|
||||
|
||||
if (!explorer.layouts[layoutMode]) return null;
|
||||
|
||||
return (
|
||||
|
|
|
@ -18,6 +18,9 @@ export * from './useIsLocationIndexing';
|
|||
export * from './useIsTextTruncated';
|
||||
export * from './useKeyMatcher';
|
||||
export * from './useLocale';
|
||||
export * from './useMouseItemResize';
|
||||
export * from './usePrefersReducedMotion';
|
||||
export * from './useRandomInterval';
|
||||
export * from './useRedirectToNewLocation';
|
||||
export * from './useRouteTitle';
|
||||
export * from './useShortcut';
|
||||
|
@ -25,8 +28,6 @@ export * from './useShowControls';
|
|||
export * from './useTheme';
|
||||
export * from './useWindowSize';
|
||||
export * from './useWindowState';
|
||||
export * from './useZodParams';
|
||||
export * from './useZodRouteParams';
|
||||
export * from './useZodSearchParams';
|
||||
export * from './usePrefersReducedMotion';
|
||||
export * from './useRandomInterval';
|
||||
export * from './useZodParams';
|
||||
|
|
65
interface/hooks/useMouseItemResize.ts
Normal file
65
interface/hooks/useMouseItemResize.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
import { useExplorerContext } from '~/app/$libraryId/Explorer/Context';
|
||||
import { LIST_VIEW_ICON_SIZES } from '~/app/$libraryId/Explorer/View/ListView/useTable';
|
||||
|
||||
import { useOperatingSystem } from './useOperatingSystem';
|
||||
import { getSizes } from '~/app/$libraryId/Explorer/OptionsPanel/ListView/util';
|
||||
|
||||
/**
|
||||
* Hook that allows resizing of items in the Explorer views for GRID and LIST only - using the mouse wheel.
|
||||
*/
|
||||
|
||||
export const useMouseItemResize = () => {
|
||||
const os = useOperatingSystem();
|
||||
const explorer = useExplorerContext();
|
||||
const { layoutMode } = explorer.useSettingsSnapshot();
|
||||
|
||||
const handleWheel = useCallback(
|
||||
(e: WheelEvent) => {
|
||||
const isList = layoutMode === 'list';
|
||||
const deltaYModifier = isList ? Math.sign(e.deltaY) : e.deltaY / 10; // Sensitivity adjustment
|
||||
const newSize =
|
||||
Number(
|
||||
isList
|
||||
? explorer.settingsStore.listViewIconSize
|
||||
: explorer.settingsStore.gridItemSize
|
||||
) + deltaYModifier;
|
||||
|
||||
const minSize = isList ? 0 : 60;
|
||||
const maxSize = isList ? 2 : 200;
|
||||
const clampedSize = Math.max(minSize, Math.min(maxSize, newSize));
|
||||
|
||||
if (isList) {
|
||||
const listSizes = getSizes(LIST_VIEW_ICON_SIZES);
|
||||
explorer.settingsStore.listViewIconSize = listSizes.sizeMap.get(clampedSize) ?? "0"
|
||||
} else if (layoutMode === 'grid') {
|
||||
explorer.settingsStore.gridItemSize = Number(clampedSize.toFixed(0));
|
||||
}
|
||||
},
|
||||
[explorer.settingsStore, layoutMode]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (os !== 'windows') return;
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Control') {
|
||||
document.addEventListener('wheel', handleWheel);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyUp = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Control') {
|
||||
document.removeEventListener('wheel', handleWheel);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
document.addEventListener('keyup', handleKeyUp);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown);
|
||||
document.removeEventListener('keyup', handleKeyUp);
|
||||
};
|
||||
}, [os, handleWheel]);
|
||||
};
|
Loading…
Reference in a new issue