feat: added new hot key hook since useKey doesnt ignore special keys

replaced all alpha numeric shortcuts
pull/3083/head
William Grant 10 months ago
parent f5cd3ba1f9
commit cf34db53c8

@ -1,7 +1,7 @@
import { isEmpty } from 'lodash';
import { useState } from 'react';
import useCopyToClipboard from 'react-use/lib/useCopyToClipboard';
import useKey from 'react-use/lib/useKey';
import { useHotkey } from '../../hooks/useHotkey';
import { ToastUtils } from '../../session/utils';
import { SessionButton, SessionButtonProps } from '../basic/SessionButton';
import { SessionIconButton } from '../icon';
@ -30,17 +30,7 @@ export const CopyToClipboardButton = (props: CopyToClipboardButtonProps) => {
}
};
useKey(
(event: KeyboardEvent) => {
return event.key === 'c';
},
() => {
if (!hotkey) {
return;
}
onClick();
}
);
useHotkey('c', onClick, !hotkey);
return (
<SessionButton
@ -73,17 +63,7 @@ export const CopyToClipboardIcon = (props: CopyToClipboardIconProps) => {
}
};
useKey(
(event: KeyboardEvent) => {
return event.key === 'c';
},
() => {
if (!hotkey) {
return;
}
onClick();
}
);
useHotkey('c', onClick, !hotkey);
return (
<SessionIconButton

@ -2,7 +2,6 @@ import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { useRef } from 'react';
import useKey from 'react-use/lib/useKey';
import useMount from 'react-use/lib/useMount';
import { ToastUtils } from '../../session/utils';
import { matchesHash } from '../../util/passwordUtils';
@ -10,6 +9,7 @@ import { matchesHash } from '../../util/passwordUtils';
import { updateEnterPasswordModal } from '../../state/ducks/modalDialog';
import { SpacerSM } from '../basic/Text';
import { useHotkey } from '../../hooks/useHotkey';
import { SessionWrapperModal } from '../SessionWrapperModal';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
@ -65,16 +65,11 @@ export const EnterPasswordModal = (props: EnterPasswordModalProps) => {
}
});
useKey(
(event: KeyboardEvent) => event.key === 'Enter',
(event: KeyboardEvent) => {
if (event.key === 'Enter') {
if (event.target === passwordInputRef.current) {
confirmPassword();
}
}
useHotkey('Enter', (event: KeyboardEvent) => {
if (event.target === passwordInputRef.current) {
confirmPassword();
}
);
});
return (
<SessionWrapperModal

@ -1,13 +1,13 @@
import { isEmpty } from 'lodash';
import { RefObject, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import useKey from 'react-use/lib/useKey';
import styled from 'styled-components';
import { Dispatch } from '@reduxjs/toolkit';
import { SyncUtils, UserUtils } from '../../../session/utils';
import { YourSessionIDPill, YourSessionIDSelectable } from '../../basic/YourSessionIDPill';
import { useHotkey } from '../../../hooks/useHotkey';
import { useOurAvatarPath, useOurConversationUsername } from '../../../hooks/useParamSelector';
import { ConversationTypeEnum } from '../../../models/conversationAttributes';
import { getConversationController } from '../../../session/conversations';
@ -65,36 +65,34 @@ const handleKeyEditMode = (
}
};
const handleKeyCancel =
(
mode: ProfileDialogModes,
setMode: (mode: ProfileDialogModes) => void,
inputRef: RefObject<HTMLInputElement>,
updatedProfileName: string,
setProfileName: (name: string) => void,
setProfileNameError: (error: string | undefined) => void,
loading: boolean
) =>
() => {
if (loading) {
return;
}
switch (mode) {
case 'edit':
case 'qr':
if (inputRef.current !== null && document.activeElement === inputRef.current) {
return;
}
setMode('default');
if (mode === 'edit') {
setProfileNameError(undefined);
setProfileName(updatedProfileName);
}
break;
case 'default':
default:
}
};
const handleKeyCancel = (
mode: ProfileDialogModes,
setMode: (mode: ProfileDialogModes) => void,
inputRef: RefObject<HTMLInputElement>,
updatedProfileName: string,
setProfileName: (name: string) => void,
setProfileNameError: (error: string | undefined) => void,
loading: boolean
) => {
if (loading) {
return;
}
switch (mode) {
case 'edit':
case 'qr':
if (inputRef.current !== null && document.activeElement === inputRef.current) {
return;
}
setMode('default');
if (mode === 'edit') {
setProfileNameError(undefined);
setProfileName(updatedProfileName);
}
break;
case 'default':
default:
}
};
const handleKeyEscape = (
mode: ProfileDialogModes,
@ -249,50 +247,35 @@ export const EditProfileDialog = () => {
);
};
useKey(
(event: KeyboardEvent) => {
return (
event.key === 'v' ||
event.key === 'Enter' ||
event.key === 'Backspace' ||
event.key === 'Esc' ||
event.key === 'Escape'
);
},
(event: KeyboardEvent) => {
switch (event.key) {
case 'v':
handleKeyQRMode(mode, setMode, loading);
break;
case 'Enter':
handleKeyEditMode(mode, setMode, onClickOK, loading);
break;
case 'Backspace':
handleKeyCancel(
mode,
setMode,
inputRef,
updatedProfileName,
setProfileName,
setProfileNameError,
loading
);
break;
case 'Esc':
case 'Escape':
handleKeyEscape(
mode,
setMode,
updatedProfileName,
setProfileName,
setProfileNameError,
loading,
dispatch
);
break;
default:
}
}
useHotkey('v', () => handleKeyQRMode(mode, setMode, loading), loading);
useHotkey('Enter', () => handleKeyEditMode(mode, setMode, onClickOK, loading), loading);
useHotkey(
'Backspace',
() =>
handleKeyCancel(
mode,
setMode,
inputRef,
updatedProfileName,
setProfileName,
setProfileNameError,
loading
),
loading
);
useHotkey(
'Escape',
() =>
handleKeyEscape(
mode,
setMode,
updatedProfileName,
setProfileName,
setProfileNameError,
loading,
dispatch
),
loading
);
return (

@ -0,0 +1,66 @@
import useKey, { Handler, KeyPredicate, UseKeyOptions } from 'react-use/lib/useKey';
function specialKeyPressed(event: KeyboardEvent) {
const pressed = [];
if (event.metaKey) {
pressed.push('super');
}
if (event.ctrlKey) {
pressed.push('ctrl');
}
if (event.altKey) {
pressed.push('alt');
}
if (event.shiftKey) {
pressed.push('shift');
}
return pressed.join(' + ');
}
export function useHotkey(
key: string,
onPress: (event: KeyboardEvent) => void | Promise<void>,
disabled?: boolean
) {
const opts: UseKeyOptions<HTMLElement> = {};
const predicate: KeyPredicate = event => {
const lowerKey = key.toLowerCase();
const eventKey = event.key.toLowerCase();
window.log.debug(
`WIP: [useHotkey] key: ${key} lowerKey: ${lowerKey} eventKey: ${eventKey} event.target: ${JSON.stringify(event)}`
);
switch (lowerKey) {
case 'esc':
case 'escape':
return eventKey === 'escape' || eventKey === 'esc';
default:
return eventKey === lowerKey;
}
};
const handler: Handler = event => {
if (disabled) {
window.log.debug(`WIP: [useHotkey] '${key}' is disabled. Triggered by ${event.key}`);
return;
}
const specialKeys = specialKeyPressed(event);
if (specialKeys) {
window.log.debug(
`WIP: [useHotkey] '${key}' was ignored because it was pressed with ${specialKeys}. Triggered by ${event.key} + ${specialKeys}`
);
return;
}
window.log.debug(`WIP: [useHotkey] '${key}' onPress event. Triggered by ${event.key}`);
void onPress(event);
};
useKey(predicate, handler, opts);
}
Loading…
Cancel
Save