[ENG-1119] - Open folder shortcut + select item with arrow down (#1355)

* Open folder shortcut + select item with arrow down

* tweaks

* symbol tweaks

* Update index.tsx
This commit is contained in:
ameer2468
2023-09-18 17:09:40 +03:00
committed by GitHub
parent 710f6ba51f
commit ce9ccec98d
7 changed files with 77 additions and 27 deletions

View File

@@ -11,9 +11,8 @@ import {
import clsx from 'clsx';
import { useEffect, useRef } from 'react';
import { useRspcLibraryContext } from '@sd/client';
import { ModifierKeys } from '~/../packages/ui/src';
import { ModifierKeys, modifierSymbols } from '@sd/ui';
import { useOperatingSystem } from '~/hooks';
import { keybindForOs } from '~/util/keybinds';
import { KeyManager } from '../KeyManager';
import TopBarOptions, { ToolOption, TOP_BAR_ICON_STYLE } from '../TopBar/TopBarOptions';
@@ -26,7 +25,14 @@ export const useExplorerTopBarOptions = () => {
const explorerStore = useExplorerStore();
const explorer = useExplorerContext();
const os = useOperatingSystem();
const keybind = keybindForOs(os);
const controlSymbol = (letter: string) => {
return [
os === 'macOS'
? modifierSymbols[ModifierKeys.Meta][os]
: modifierSymbols[ModifierKeys.Control]['Other'],
letter
] as string[];
};
const settings = explorer.useSettingsSnapshot();
@@ -34,7 +40,7 @@ export const useExplorerTopBarOptions = () => {
{
toolTipLabel: 'Grid view',
icon: <SquaresFour className={TOP_BAR_ICON_STYLE} />,
keybinds: [keybind([ModifierKeys.Meta], ['V'])],
keybinds: controlSymbol('V'),
topBarActive: settings.layoutMode === 'grid',
onClick: () => (explorer.settingsStore.layoutMode = 'grid'),
showAtResolution: 'sm:flex'
@@ -42,7 +48,7 @@ export const useExplorerTopBarOptions = () => {
{
toolTipLabel: 'List view',
icon: <Rows className={TOP_BAR_ICON_STYLE} />,
keybinds: [keybind([ModifierKeys.Meta], ['V'])],
keybinds: controlSymbol('V'),
topBarActive: settings.layoutMode === 'list',
onClick: () => (explorer.settingsStore.layoutMode = 'list'),
showAtResolution: 'sm:flex'
@@ -57,7 +63,7 @@ export const useExplorerTopBarOptions = () => {
{
toolTipLabel: 'Media view',
icon: <MonitorPlay className={TOP_BAR_ICON_STYLE} />,
keybinds: [keybind([ModifierKeys.Meta], ['V'])],
keybinds: controlSymbol('V'),
topBarActive: settings.layoutMode === 'media',
onClick: () => (explorer.settingsStore.layoutMode = 'media'),
showAtResolution: 'sm:flex'
@@ -74,7 +80,7 @@ export const useExplorerTopBarOptions = () => {
},
{
toolTipLabel: 'Show Inspector',
keybinds: [keybind([ModifierKeys.Meta], ['I'])],
keybinds: controlSymbol('I'),
onClick: () => (getExplorerStore().showInspector = !explorerStore.showInspector),
icon: (
<SidebarSimple

View File

@@ -84,7 +84,7 @@ const GridListItem = (props: {
return (
<div
className="h-full w-full"
className="w-full h-full"
data-selectable=""
data-selectable-index={props.index}
data-selectable-id={itemId}
@@ -248,6 +248,20 @@ export default ({ children }: { children: RenderItem }) => {
return;
}
if (e.key === 'ArrowDown' && explorer.selectedItems.size === 0) {
const item = grid.getItem(0);
if (!item?.data) return;
const selectedItemDom = document.querySelector(
`[data-selectable-id="${uniqueId(item.data)}"]`
);
if (selectedItemDom) {
explorer.resetSelectedItems([item.data]);
selecto.current?.setSelectedTargets([selectedItemDom as HTMLElement]);
activeItem.current = item.data;
}
return;
}
if (explorer.selectedItems.size > 0) e.preventDefault();
const lastItem = activeItem.current;

View File

@@ -59,7 +59,7 @@ interface ListViewItemProps {
const ListViewItem = memo((props: ListViewItemProps) => {
return (
<ViewItem data={props.row.original} className="w-full">
<div role="row" className="flex h-full items-center">
<div role="row" className="flex items-center h-full">
{props.row.getVisibleCells().map((cell) => (
<div
role="cell"
@@ -819,6 +819,15 @@ export default () => {
const range = getRangeByIndex(ranges.length - 1);
if (e.key === 'ArrowDown' && explorer.selectedItems.size === 0) {
const item = rows[0]?.original;
if (item) {
explorer.addSelectedItem(item);
setRanges([[uniqueId(item), uniqueId(item)]]);
}
return;
}
if (!range) return;
if (e.key === 'Escape') {
@@ -1019,7 +1028,7 @@ export default () => {
useLayoutEffect(() => setListOffset(tableRef.current?.offsetTop ?? 0), []);
return (
<div className="flex w-full flex-col" ref={tableRef}>
<div className="flex flex-col w-full" ref={tableRef}>
{sized && (
<ScrollSync>
<>
@@ -1041,7 +1050,7 @@ export default () => {
<div
ref={tableHeaderRef}
key={headerGroup.id}
className="flex grow border-b border-app-line/50"
className="flex border-b grow border-app-line/50"
onMouseDown={(e) => e.stopPropagation()}
>
{headerGroup.headers.map((header, i) => {
@@ -1064,7 +1073,7 @@ export default () => {
return (
<div
key={header.id}
className="relative shrink-0 px-4 py-2 text-xs first:pl-24"
className="relative px-4 py-2 text-xs shrink-0 first:pl-24"
style={{
width:
i === 0
@@ -1181,7 +1190,7 @@ export default () => {
</ScrollSyncPane>
<ScrollSyncPane>
<div className="no-scrollbar overflow-x-auto overscroll-x-none">
<div className="overflow-x-auto no-scrollbar overscroll-x-none">
<div
ref={tableBodyRef}
className="relative"
@@ -1209,7 +1218,7 @@ export default () => {
return (
<div
key={row.id}
className="absolute left-0 top-0 flex w-full"
className="absolute top-0 left-0 flex w-full"
style={{
height: virtualRow.size,
transform: `translateY(${
@@ -1242,7 +1251,7 @@ export default () => {
)}
>
{selectedPrior && (
<div className="absolute inset-x-3 top-0 h-px bg-accent/10" />
<div className="absolute top-0 h-px inset-x-3 bg-accent/10" />
)}
<ListViewItem

View File

@@ -13,6 +13,7 @@ import {
} from 'react';
import { createPortal } from 'react-dom';
import { createSearchParams, useNavigate } from 'react-router-dom';
import { useKeys } from 'rooks';
import {
getItemObject,
isPath,
@@ -53,8 +54,15 @@ export const ViewItem = ({ data, children, ...props }: ViewItemProps) => {
const navigate = useNavigate();
const { library } = useLibraryContext();
const { openFilePaths } = usePlatform();
const os = useOperatingSystem();
const updateAccessTime = useLibraryMutation('files.updateAccessTime');
const metaCtrlKey = os === 'macOS' ? ModifierKeys.Meta : ModifierKeys.Control;
useKeys([metaCtrlKey, 'ArrowUp'], async (e) => {
e.stopPropagation();
await onDoubleClick();
});
const onDoubleClick = async () => {
const selectedItems = [...explorer.selectedItems];
@@ -279,7 +287,7 @@ export const EmptyNotice = (props: { icon?: Icon | ReactNode; message?: ReactNod
};
return (
<div className="flex h-full flex-col items-center justify-center text-ink-faint">
<div className="flex flex-col items-center justify-center h-full text-ink-faint">
{props.icon
? isValidElement(props.icon)
? props.icon

View File

@@ -1,9 +1,16 @@
import { Gear } from '@phosphor-icons/react';
import { useNavigate } from 'react-router';
import { JobManagerContextProvider, useClientContext, useDebugState } from '@sd/client';
import { Button, ButtonLink, dialogManager, ModifierKeys, Popover, Tooltip } from '@sd/ui';
import {
Button,
ButtonLink,
dialogManager,
ModifierKeys,
modifierSymbols,
Popover,
Tooltip
} from '@sd/ui';
import { useKeyBind, useOperatingSystem } from '~/hooks';
import { keybindForOs } from '~/util/keybinds';
import DebugPopover from './DebugPopover';
import FeedbackDialog from './FeedbackDialog';
@@ -13,8 +20,12 @@ export default () => {
const { library } = useClientContext();
const debugState = useDebugState();
const os = useOperatingSystem();
const keybind = keybindForOs(os);
const navigate = useNavigate();
const jobManagerKeys = [os === 'macOS' ? ModifierKeys.Meta : ModifierKeys.Control, 'j'];
const recentJobsSymbol =
os === 'macOS'
? modifierSymbols[ModifierKeys.Meta][os]
: modifierSymbols[ModifierKeys.Control]['Other'];
useKeyBind(['g', 's'], (e) => {
e.stopPropagation();
@@ -23,7 +34,7 @@ export default () => {
return (
<div className="space-y-2">
<div className="flex w-full items-center justify-between">
<div className="flex items-center justify-between w-full">
<div className="flex">
<ButtonLink
to="settings/client/general"
@@ -32,12 +43,12 @@ export default () => {
className="text-sidebar-inkFaint ring-offset-sidebar"
>
<Tooltip label="Settings" keybinds={['G', 'S']}>
<Gear className="h-5 w-5" />
<Gear className="w-5 h-5" />
</Tooltip>
</ButtonLink>
<JobManagerContextProvider>
<Popover
keybind={['Meta', 'j']}
keybind={jobManagerKeys}
trigger={
<Button
size="icon"
@@ -48,7 +59,7 @@ export default () => {
{library && (
<Tooltip
label="Recent Jobs"
keybinds={[keybind([ModifierKeys.Meta], ['J'])]}
keybinds={[recentJobsSymbol as string, 'J']}
>
<IsRunningJob />
</Tooltip>

View File

@@ -3,6 +3,7 @@ import { useLayoutEffect, useState } from 'react';
import { useKeys } from 'rooks';
import { ModifierKeys, Popover, Tooltip } from '@sd/ui';
import { ExplorerLayout } from '~/../packages/client/src';
import { useKeyBind, useOperatingSystem } from '~/hooks';
import { useExplorerContext } from '../Explorer/Context';
import TopBarButton from './TopBarButton';
@@ -33,8 +34,10 @@ export default ({ options }: TopBarChildrenProps) => {
const toolsNotSmFlex = options
?.flatMap((group) => group)
.filter((t) => t.showAtResolution !== 'sm:flex');
const os = useOperatingSystem();
const keys = [os === 'macOS' ? ModifierKeys.Meta : ModifierKeys.Control, 'v'];
useKeys(['Meta', 'v'], (e) => {
useKeyBind(keys, (e) => {
e.stopPropagation();
const explorerLayouts: ExplorerLayout[] = ['grid', 'list', 'media']; //based on the order of the icons
const currentLayout = explorerLayouts.indexOf(
@@ -56,7 +59,7 @@ export default ({ options }: TopBarChildrenProps) => {
}, []);
return (
<div data-tauri-drag-region className="flex flex-1 justify-end">
<div data-tauri-drag-region className="flex justify-end flex-1">
<div data-tauri-drag-region className={`flex gap-0`}>
{options?.map((group, groupIndex) => {
return group.map(

View File

@@ -2,8 +2,8 @@ import clsx from 'clsx';
import { forwardRef } from 'react';
import { useFormContext } from 'react-hook-form';
import { InputField, InputFieldProps, toast } from '@sd/ui';
import { usePlatform } from '~/util/Platform';
import { openDirectoryPickerDialog } from './openDirectoryPickerDialog';
export const LocationPathInputField = forwardRef<
@@ -12,7 +12,6 @@ export const LocationPathInputField = forwardRef<
>((props, ref) => {
const platform = usePlatform();
const form = useFormContext();
console.log(form.formState.isDirty);
return (
<InputField