mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 06:44:13 +00:00
feat: added hotkey functionalities
This commit is contained in:
parent
37d4de440a
commit
4c6d8cddc8
7 changed files with 78 additions and 39 deletions
|
@ -1,9 +1,15 @@
|
|||
import { Icon } from '@iconify/react';
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import cx from 'classnames';
|
||||
import Button from 'renderer/components/Button';
|
||||
import { IBookmarks, selectBookmarks } from 'renderer/store/features/bookmarks';
|
||||
import {
|
||||
IBookmarks,
|
||||
addBookmark,
|
||||
selectBookmarks,
|
||||
} from 'renderer/store/features/bookmarks';
|
||||
import useKeyboardShortcut from 'renderer/components/KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import { SHORTCUT_CHANNEL } from 'renderer/components/KeyboardShortcutsManager/constants';
|
||||
import BookmarkFlyout from '../Menu/Flyout/Bookmark/ViewAllBookmarks/BookmarkFlyout';
|
||||
|
||||
interface Props {
|
||||
|
@ -13,6 +19,8 @@ interface Props {
|
|||
|
||||
const BookmarkButton = ({ currentAddress, pageTitle }: Props) => {
|
||||
const [openFlyout, setOpenFlyout] = useState<boolean>(false);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const initbookmark = {
|
||||
id: '',
|
||||
name: pageTitle,
|
||||
|
@ -31,6 +39,13 @@ const BookmarkButton = ({ currentAddress, pageTitle }: Props) => {
|
|||
setOpenFlyout(!openFlyout);
|
||||
};
|
||||
|
||||
const handleKeyboardShortcut = () => {
|
||||
handleFlyout();
|
||||
dispatch(addBookmark(bookmarkFound || initbookmark));
|
||||
};
|
||||
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.BOOKMARK, handleKeyboardShortcut);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
|
|
|
@ -18,6 +18,8 @@ import {
|
|||
selectPageTitle,
|
||||
setAddress,
|
||||
} from 'renderer/store/features/renderer';
|
||||
import useKeyboardShortcut from 'renderer/components/KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import { SHORTCUT_CHANNEL } from 'renderer/components/KeyboardShortcutsManager/constants';
|
||||
import AuthModal from './AuthModal';
|
||||
import SuggestionList from './SuggestionList';
|
||||
import Bookmark from './BookmarkButton';
|
||||
|
@ -154,8 +156,27 @@ const AddressBar = () => {
|
|||
setDeleteCacheLoading(false);
|
||||
};
|
||||
|
||||
const deleteAll = () => {
|
||||
deleteCache();
|
||||
deleteStorage();
|
||||
deleteCookies();
|
||||
};
|
||||
|
||||
const handleEditUrl = () => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.focus();
|
||||
inputRef.current.select();
|
||||
}
|
||||
};
|
||||
|
||||
const isHomepage = address === homepage;
|
||||
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.DELETE_CACHE, deleteCache);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.DELETE_STORAGE, deleteStorage);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.DELETE_COOKIES, deleteCookies);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.DELETE_ALL, deleteAll);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.EDIT_URL, handleEditUrl);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="relative z-10 w-full flex-grow">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Icon } from '@iconify/react';
|
||||
import { PREVIEW_LAYOUTS } from 'common/constants';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { SHORTCUT_CHANNEL } from 'renderer/components/KeyboardShortcutsManager/constants';
|
||||
import useKeyboardShortcut from 'renderer/components/KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import Toggle from 'renderer/components/Toggle';
|
||||
import { selectLayout, setLayout } from 'renderer/store/features/renderer';
|
||||
|
||||
|
@ -8,6 +10,14 @@ const PreviewLayout = () => {
|
|||
const layout = useSelector(selectLayout);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleLayout = () => {
|
||||
if (layout === PREVIEW_LAYOUTS.FLEX)
|
||||
dispatch(setLayout(PREVIEW_LAYOUTS.COLUMN));
|
||||
else dispatch(setLayout(PREVIEW_LAYOUTS.FLEX));
|
||||
};
|
||||
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.PREVIEW_LAYOUT, handleLayout);
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-start px-4">
|
||||
<span className="w-1/2">Preview Layout</span>
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
import { Icon } from '@iconify/react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import Button from 'renderer/components/Button';
|
||||
import { SHORTCUT_CHANNEL } from 'renderer/components/KeyboardShortcutsManager/constants';
|
||||
import useKeyboardShortcut from 'renderer/components/KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import { selectDarkMode, setDarkMode } from 'renderer/store/features/ui';
|
||||
|
||||
const UITheme = () => {
|
||||
const darkMode = useSelector(selectDarkMode);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleTheme = () => dispatch(setDarkMode(!darkMode));
|
||||
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.THEME, handleTheme);
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-start px-4">
|
||||
<span className="w-1/2">UI Theme</span>
|
||||
<div className="flex items-center gap-2 border-l px-4 dark:border-slate-400">
|
||||
<Button
|
||||
onClick={() => {
|
||||
dispatch(setDarkMode(!darkMode));
|
||||
}}
|
||||
subtle
|
||||
>
|
||||
<Button onClick={handleTheme} subtle>
|
||||
<Icon icon={darkMode ? 'carbon:moon' : 'carbon:sun'} />
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import Button from 'renderer/components/Button';
|
||||
import { SHORTCUT_CHANNEL } from 'renderer/components/KeyboardShortcutsManager/constants';
|
||||
import { keyboardShortcutsPubsub } from 'renderer/components/KeyboardShortcutsManager/useMousetrapEmitter';
|
||||
import useKeyboardShortcut from 'renderer/components/KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import {
|
||||
selectZoomFactor,
|
||||
zoomIn,
|
||||
|
@ -34,15 +34,8 @@ const Zoom = () => {
|
|||
dispatch(zoomOut());
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
keyboardShortcutsPubsub.subscribe(SHORTCUT_CHANNEL.ZOOM_IN, onZoomIn);
|
||||
keyboardShortcutsPubsub.subscribe(SHORTCUT_CHANNEL.ZOOM_OUT, onZoomOut);
|
||||
|
||||
return () => {
|
||||
keyboardShortcutsPubsub.unsubscribe(SHORTCUT_CHANNEL.ZOOM_IN, onZoomIn);
|
||||
keyboardShortcutsPubsub.unsubscribe(SHORTCUT_CHANNEL.ZOOM_OUT, onZoomOut);
|
||||
};
|
||||
}, [onZoomIn, onZoomOut]);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.ZOOM_IN, onZoomIn);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.ZOOM_OUT, onZoomOut);
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-center justify-start px-4">
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import { Icon } from '@iconify/react';
|
||||
import { webViewPubSub } from 'renderer/lib/pubsub';
|
||||
import Button from '../Button';
|
||||
import useKeyboardShortcut from '../KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import {
|
||||
SHORTCUT_CHANNEL,
|
||||
ShortcutChannel,
|
||||
} from '../KeyboardShortcutsManager/constants';
|
||||
|
||||
export const NAVIGATION_EVENTS = {
|
||||
BACK: 'back',
|
||||
|
@ -15,6 +20,8 @@ interface NavigationItemProps {
|
|||
}
|
||||
|
||||
const NavigationButton = ({ label, icon, action }: NavigationItemProps) => {
|
||||
const shortcutName: ShortcutChannel = label.toUpperCase() as ShortcutChannel;
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL[shortcutName], action);
|
||||
return (
|
||||
<Button className="!rounded-full px-2 py-1" onClick={action} title={label}>
|
||||
<Icon icon={icon} />
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
setRotate,
|
||||
} from 'renderer/store/features/renderer';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { ScreenshotAllArgs } from 'main/screenshot';
|
||||
import { selectActiveSuite } from 'renderer/store/features/device-manager';
|
||||
import WebPage from 'main/screenshot/webpage';
|
||||
|
@ -21,6 +20,8 @@ import AddressBar from './AddressBar';
|
|||
import ColorSchemeToggle from './ColorSchemeToggle';
|
||||
import ModalLoader from '../ModalLoader';
|
||||
import { PreviewSuiteSelector } from './PreviewSuiteSelector';
|
||||
import useKeyboardShortcut from '../KeyboardShortcutsManager/useKeyboardShortcut';
|
||||
import { SHORTCUT_CHANNEL } from '../KeyboardShortcutsManager/constants';
|
||||
|
||||
const Divider = () => <div className="h-6 w-px bg-gray-300 dark:bg-gray-700" />;
|
||||
|
||||
|
@ -80,26 +81,17 @@ const ToolBar = () => {
|
|||
// Do nothing. Prevent Dialog from closing.
|
||||
};
|
||||
|
||||
function useKey(key: string, cb: () => void) {
|
||||
const callbackRef = useRef(cb);
|
||||
const handleRotate = () => {
|
||||
dispatch(setRotate(!rotateDevices));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callbackRef.current = cb;
|
||||
}, [cb]);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.ROTATE_ALL, handleRotate);
|
||||
useKeyboardShortcut(
|
||||
SHORTCUT_CHANNEL.SCREENSHOT_ALL,
|
||||
screenshotCaptureHandler
|
||||
);
|
||||
useKeyboardShortcut(SHORTCUT_CHANNEL.INSPECT_ELEMENTS, handleInspectShortcut);
|
||||
|
||||
useEffect(() => {
|
||||
function handle(event: { code: string }) {
|
||||
if (event.code === key) {
|
||||
callbackRef.current();
|
||||
}
|
||||
}
|
||||
// current(event)
|
||||
document.addEventListener('keypress', handle);
|
||||
return () => document.removeEventListener('keypress', handle);
|
||||
}, [key]);
|
||||
}
|
||||
// setting shortcut I for inspect element
|
||||
useKey('KeyI', handleInspectShortcut);
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<NavigationControls />
|
||||
|
@ -107,7 +99,7 @@ const ToolBar = () => {
|
|||
<AddressBar />
|
||||
|
||||
<Button
|
||||
onClick={() => dispatch(setRotate(!rotateDevices))}
|
||||
onClick={handleRotate}
|
||||
isActive={rotateDevices}
|
||||
title="Rotate Devices"
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue