import { useEffect } from 'react' ; import { getLogger } from '../shared/logger' ; import { Screens } from './ScreenController' ; const log = getLogger ( 'renderer/keybindings' ) ; export enum KeybindAction { ChatList_SelectNextChat = 'chatlist:select-next-chat' , ChatList_SelectPreviousChat = 'chatlist:select-previous-chat' , ChatList_ScrollToSelectedChat = 'chatlist:scroll-to-selected-chat' , ChatList_SelectFirstChat = 'chatlist:select-first-chat' , ChatList_FocusSearchInput = 'chatlist:focus-search' , ChatList_ClearSearchInput = 'chatlist:clear-search' , Composer_Focus = 'composer:focus' , Settings_Open = 'settings:open' , MessageList_PageUp = 'msglist:pageup' , MessageList_PageDown = 'msglist:pagedown' , ChatList_SwitchToArchiveView = 'chatlist:switch-to-archive-view' , ChatList_SwitchToNormalView = 'chatlist:switch-to-normal-view' , ChatList_FocusAndClearSearchInput = 'chatlist:focus-and-clear-search' , ChatList_ExitSearch = 'chatlist:exit-search' , ChatList_SearchSelectFirstChat = 'chatlist:search-select-first-chat' , Debug_MaybeNetwork = 'debug:maybe_network' } export namespace ActionEmitter { const handlers = { } ; export function registerHandler ( action , handler ) { if ( ! Array . isArray ( handlers [ action ] ) ) { handlers [ action ] = [ ] ; } ; ( handlers [ action ] as any [ ] ) . push ( handler ) ; } export function unRegisterHandler ( action , handler ) { if ( ! Array . isArray ( handlers [ action ] ) ) { return ; } handlers [ action ] = ( handlers [ action ] as any [ ] ) . filter ( h => h !== handler ) ; } export function emitAction ( action ) { if ( ! Array . isArray ( handlers [ action ] ) ) { return ; } log . debug ( 'fire action' , action , 'handlers:' , handlers [ action ] ) ; ( handlers [ action ] as any [ ] ) . forEach ( handler => handler ( ) ) ; } } export function useKeyBindingAction ( action , handler ) { useEffect ( ( ) => { ActionEmitter . registerHandler ( action , handler ) ; return ( ) => ActionEmitter . unRegisterHandler ( action , handler ) ; } ) ; } function keyDownEvent2Action ( ev ) { if ( window . __contextMenuActive ) { return ; } if ( ! ev . repeat ) { if ( ev . altKey && ev . key === 'ArrowDown' ) { return KeybindAction . ChatList_SelectNextChat ; } else if ( ev . altKey && ev . key === 'ArrowUp' ) { return KeybindAction . ChatList_SelectPreviousChat ; } else if ( ev . ctrlKey && ev . key === 'k' ) { return KeybindAction . ChatList_FocusAndClearSearchInput ; } else if ( ev . ctrlKey && ev . key === 'n' ) { return KeybindAction . Composer_Focus ; } else if ( ( ev . metaKey || ev . ctrlKey ) && ev . key === ',' ) { return KeybindAction . Settings_Open ; } else if ( ev . key === 'Escape' && ( ev . target as any ) . id === 'chat-list-search' ) { return KeybindAction . ChatList_ExitSearch ; } else if ( ev . key === 'Enter' && ( ev . target as any ) . id === 'chat-list-search' ) { return KeybindAction . ChatList_SearchSelectFirstChat ; } else if ( ev . key === 'F5' ) { return KeybindAction . Debug_MaybeNetwork ; } else if ( ev . key === 'PageUp' ) { return KeybindAction . MessageList_PageUp ; } else if ( ev . key === 'PageDown' ) { return KeybindAction . MessageList_PageDown ; } } else { if ( ev . key === 'PageUp' ) { return KeybindAction . MessageList_PageUp ; } else if ( ev . key === 'PageDown' ) { return KeybindAction . MessageList_PageDown ; } else if ( ev . altKey && ev . key === 'ArrowDown' ) { return KeybindAction . ChatList_SelectNextChat ; } else if ( ev . altKey && ev . key === 'ArrowUp' ) { return KeybindAction . ChatList_SelectPreviousChat ; } } } export default function attachKeybindingsListener ( ) { document . addEventListener ( 'keydown' , function ( ev ) { const action = keyDownEvent2Action ( ev ) ; if ( action ) { ev . stopImmediatePropagation ( ) ; ev . preventDefault ( ) ; ActionEmitter . emitAction ( action ) ; } } ) ; } ActionEmitter . registerHandler ( KeybindAction . ChatList_FocusAndClearSearchInput , ( ) => { ActionEmitter . emitAction ( KeybindAction . ChatList_FocusSearchInput ) ; ActionEmitter . emitAction ( KeybindAction . ChatList_ClearSearchInput ) ; } ) ; ActionEmitter . registerHandler ( KeybindAction . Settings_Open , ( ) => { if ( window . __screen === Screens . Main ) { if ( ! window . __settingsOpened && window . __openDialog ) { window . __openDialog ( 'Settings' ) ; } } } ) ; ActionEmitter . registerHandler ( KeybindAction . ChatList_ExitSearch , ( ) => { ActionEmitter . emitAction ( KeybindAction . ChatList_ClearSearchInput ) ; ActionEmitter . emitAction ( KeybindAction . Composer_Focus ) ; } ) ; ActionEmitter . registerHandler ( KeybindAction . ChatList_SearchSelectFirstChat , ( ) => { ActionEmitter . emitAction ( KeybindAction . ChatList_SelectFirstChat ) ; ActionEmitter . emitAction ( KeybindAction . Composer_Focus ) ; } ) ;