mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-05-03 21:05:00 -04:00
[ENG-871] - Rename shortcut update (#1422)
* f2 to rename * Update RenameTextBox.tsx * Keybindings some refactoring to accommodate our needs * Update keybindings.tsx * correct direction for nav * Update keybindings.tsx * ts documentation + key -> keys * Update keybindings.tsx
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
useState,
|
||||
type ComponentProps
|
||||
} from 'react';
|
||||
import { useKey } from 'rooks';
|
||||
import { useKey, useKeys } from 'rooks';
|
||||
import { useLibraryMutation, useRspcLibraryContext } from '@sd/client';
|
||||
import { toast, Tooltip } from '@sd/ui';
|
||||
import { useIsTextTruncated, useOperatingSystem } from '~/hooks';
|
||||
@@ -115,9 +115,9 @@ export const RenameTextBoxBase = forwardRef<HTMLDivElement | null, Props>(
|
||||
}
|
||||
};
|
||||
|
||||
useKey('Enter', (e) => {
|
||||
useKey(['F2', 'Enter'], (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (os === 'windows' && e.key === 'Enter') return;
|
||||
if (allowRename) blur();
|
||||
else if (!disabled) setAllowRename(true);
|
||||
});
|
||||
|
||||
@@ -15,9 +15,15 @@ import { Heading } from '../Layout';
|
||||
import Setting from '../Setting';
|
||||
|
||||
type Shortcut = {
|
||||
action: string;
|
||||
description?: string;
|
||||
key: [ModifierKeys[], string[]][];
|
||||
action: string; //the name of the action the shortcut is performing
|
||||
description?: string; //what does this shortcut do?
|
||||
keys: {
|
||||
//the operating system the shortcut is for
|
||||
[K in OperatingSystem | 'all']?: {
|
||||
value: string | ModifierKeys | (string | ModifierKeys)[]; //if the shortcut is a single key, use a string, if it's a combination of keys, make it an array
|
||||
split?: boolean; //if the 'length' of the shortcut is 2, should it be split into 2 keys?
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
const shortcutCategories: Record<string, Shortcut[]> = {
|
||||
@@ -25,72 +31,115 @@ const shortcutCategories: Record<string, Shortcut[]> = {
|
||||
{
|
||||
description: 'Different pages in the app',
|
||||
action: 'Navigate to Settings page',
|
||||
key: [
|
||||
[[], ['G']],
|
||||
[[], ['S']]
|
||||
]
|
||||
keys: {
|
||||
all: {
|
||||
value: ['G', 'S']
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
Dialogs: [
|
||||
{
|
||||
description: 'To perform actions and operations',
|
||||
action: 'Toggle Job Manager',
|
||||
key: [[[ModifierKeys.Control], ['J']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, 'J']
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
Explorer: [
|
||||
{
|
||||
description: 'Where you explore your folders and files',
|
||||
action: 'Navigate explorer items',
|
||||
key: [
|
||||
[[], ['ArrowUp']],
|
||||
[[], ['ArrowDown']],
|
||||
[[], ['ArrowRight']],
|
||||
[[], ['ArrowLeft']]
|
||||
]
|
||||
keys: {
|
||||
all: {
|
||||
value: ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Navigate forward in folder history',
|
||||
key: [[[ModifierKeys.Control], [']']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, ']']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Navigate backward in folder history',
|
||||
key: [[[ModifierKeys.Control], ['[']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, '[']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Switch explorer layout',
|
||||
key: [[[ModifierKeys.Control], ['b']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, 'b']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Open selected item',
|
||||
key: [[[ModifierKeys.Control], ['ArrowUp']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, 'ArrowUp']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Show inspector',
|
||||
key: [[[ModifierKeys.Control], ['i']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, 'i']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Show path bar',
|
||||
key: [[[ModifierKeys.Control], ['p']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: [ModifierKeys.Control, 'p']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Rename file or folder',
|
||||
key: [[[], ['Enter']]]
|
||||
keys: {
|
||||
windows: {
|
||||
value: 'F2',
|
||||
split: false
|
||||
},
|
||||
all: {
|
||||
value: 'Enter'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Select first item in explorer',
|
||||
key: [[[], ['ArrowDown']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: 'ArrowDown'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: 'Open Quick Preview on selected item',
|
||||
key: [[[], [' ']]]
|
||||
keys: {
|
||||
all: {
|
||||
value: ' '
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const Component = () => {
|
||||
const [syncWithLibrary, setSyncWithLibrary] = useState(true);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading title="Keybinds" description="View and manage client keybinds" />{' '}
|
||||
@@ -111,12 +160,9 @@ export const Component = () => {
|
||||
<div key={category} className="mb-4 space-y-0.5">
|
||||
<h1 className="inline-block text-lg font-bold text-ink">{category}</h1>
|
||||
<div className="pb-3">
|
||||
{shortcutCategories[category]?.map((category) => {
|
||||
{shortcutCategories[category]?.map((category, i) => {
|
||||
return (
|
||||
<p
|
||||
className="text-sm text-ink-faint"
|
||||
key={category.description}
|
||||
>
|
||||
<p className="text-sm text-ink-faint" key={i.toString()}>
|
||||
{category.description}
|
||||
</p>
|
||||
);
|
||||
@@ -152,21 +198,25 @@ function KeybindTable({ data }: { data: Shortcut[] }) {
|
||||
))}
|
||||
</thead>
|
||||
<tbody className="divide-y divide-app-line/30">
|
||||
{table.getRowModel().rows.map((row) => (
|
||||
<tr key={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<td
|
||||
className={clsx(
|
||||
'py-3 hover:brightness-125',
|
||||
cell.id.includes('key') ? 'w-fit text-right' : 'w-fit'
|
||||
)}
|
||||
key={cell.id}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
{table.getRowModel().rows.map((row) => {
|
||||
return (
|
||||
<tr key={row.id}>
|
||||
{row.getVisibleCells().map((cell) => {
|
||||
return (
|
||||
<td
|
||||
className={clsx(
|
||||
'py-3 hover:brightness-125',
|
||||
cell.id.includes('key') ? 'w-fit text-right' : 'w-fit'
|
||||
)}
|
||||
key={cell.id}
|
||||
>
|
||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
@@ -180,29 +230,49 @@ function createKeybindColumns(os: OperatingSystem) {
|
||||
header: 'Description',
|
||||
cell: (info) => <p className="w-full text-sm text-ink-faint">{info.getValue()}</p>
|
||||
}),
|
||||
columnHelper.accessor('key', {
|
||||
columnHelper.accessor('keys', {
|
||||
header: () => <p className="text-right">Key</p>,
|
||||
size: 200,
|
||||
cell: (info) => {
|
||||
const shortcuts = info
|
||||
.getValue()
|
||||
.map(([modifiers, keys]) => keybind(modifiers, keys));
|
||||
return shortcuts.map((shortcut, i) => (
|
||||
<div key={i} className="inline-flex items-center">
|
||||
{shortcut.split('').map((key) => {
|
||||
const controlSymbolCheck =
|
||||
key === '⌘' ? (os === 'macOS' ? '⌘' : 'Ctrl') : key;
|
||||
const checkData = info.getValue()[os]?.value ?? info.getValue()['all']?.value;
|
||||
const data = Array.isArray(checkData) ? checkData : [checkData];
|
||||
const shortcuts = data.map((value) => {
|
||||
if (value) {
|
||||
const modifierKeyCheck = value in ModifierKeys ? [value] : [];
|
||||
return keybind(modifierKeyCheck as ModifierKeys[], [value]);
|
||||
}
|
||||
});
|
||||
return shortcuts.map((shortcut, idx) => {
|
||||
if (shortcut) {
|
||||
if (shortcut.length === 2) {
|
||||
return (
|
||||
<kbd
|
||||
className="ml-2 rounded-lg border border-app-line bg-app-box px-2 py-1 text-[10.5px] tracking-widest shadow"
|
||||
key={key}
|
||||
>
|
||||
{controlSymbolCheck}
|
||||
</kbd>
|
||||
<div key={idx.toString()} className="inline-flex items-center">
|
||||
<kbd
|
||||
className="ml-2 rounded-lg border border-app-line bg-app-box px-2 py-1 text-[10.5px] tracking-widest shadow"
|
||||
key={idx.toString()}
|
||||
>
|
||||
{shortcut}
|
||||
</kbd>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
));
|
||||
} else {
|
||||
return shortcut?.split(' ').map(([key]) => {
|
||||
const controlSymbolCheck =
|
||||
key === '⌘' ? (os === 'macOS' ? '⌘' : 'Ctrl') : key;
|
||||
return (
|
||||
<div key={idx.toString()} className="inline-flex items-center">
|
||||
<kbd
|
||||
className="ml-2 rounded-lg border border-app-line bg-app-box px-2 py-1 text-[10.5px] tracking-widest shadow"
|
||||
key={idx.toString()}
|
||||
>
|
||||
{controlSymbolCheck}
|
||||
</kbd>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user