Skip to content

Commit

Permalink
refactor to attach listeners in pages component
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastian-mereuta committed Dec 17, 2024
1 parent fb23d66 commit de92116
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 142 deletions.
8 changes: 1 addition & 7 deletions src/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,7 @@ function MainContent({ projectConfig, updateToken: setAuthToken }: MainContentPr

return (
<AppProvider isDocumentLoaded={isDocumentLoaded} isAnimationPlaying={animationStatus}>
<ShortcutProvider
projectConfig={projectConfig}
undoStackState={undoStackState}
zoom={currentZoom}
pages={pages}
activePageId={activePageId}
>
<ShortcutProvider projectConfig={projectConfig} undoStackState={undoStackState} zoom={currentZoom}>
<Container canvas={canvas}>
<UiConfigContextProvider projectConfig={projectConfig} layoutIntent={layoutIntent}>
<VariablePanelContextProvider
Expand Down
7 changes: 3 additions & 4 deletions src/components/pagesPanel/Pages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ScrollableContainer, Card, Container } from './Pages.styles';
import { BORDER_SIZE, PAGES_CONTAINER_HEIGHT, PREVIEW_FALLBACK } from '../../utils/constants';
import { PageSnapshot } from '../../types/types';
import { PreviewCardBadge } from './PreviewCardBadge';
import { useAttachArrowKeysListener } from './useAttachArrowKeysListener';

interface PagesProps {
pages: Page[];
Expand All @@ -25,10 +26,6 @@ function Pages({ pages, activePageId, pagesToRefresh, setPagesToRefresh }: Pages
const [pageSnapshots, setPageSnapshots] = useState<PageSnapshot[]>([]);
const isMobileSize = useMobileSize();

const handleSelectPage = async (pageId: string) => {
await window.StudioUISDK.page.select(pageId);
};

const getPagesSnapshot = useCallback(async (ids: string[]) => {
const snapArray = ids.map((id) =>
window.SDK.page.getSnapshot(id).then((snapshot) => ({
Expand All @@ -41,6 +38,8 @@ function Pages({ pages, activePageId, pagesToRefresh, setPagesToRefresh }: Pages
return awaitedArray as PageSnapshot[];
}, []);

const { handleSelectPage } = useAttachArrowKeysListener({ pages, activePageId });

useEffect(() => {
if (pages?.length && !pageSnapshots.length) {
getPagesSnapshot(pages.map((i) => i.id));
Expand Down
60 changes: 60 additions & 0 deletions src/components/pagesPanel/useAttachArrowKeysListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useGetIframeAsync } from '@chili-publish/grafx-shared-components';
import { Page } from '@chili-publish/studio-sdk';
import { useCallback, useEffect, useState } from 'react';

export const useAttachArrowKeysListener = ({ pages, activePageId }: { pages: Page[]; activePageId: string | null }) => {
const iframe = useGetIframeAsync({ containerId: 'studio-ui-chili-editor' })?.contentWindow;

const [selectedPageIndex, setSelectedPageIndex] = useState<number>(pages.findIndex((i) => i.id === activePageId));

const handleSelectPage = async (pageId: string) => {
await window.StudioUISDK.page.select(pageId);
};
const handleOnArrowKeyDown = useCallback(
async (event: KeyboardEvent) => {
const formElements = ['INPUT', 'TEXTAREA', 'SELECT', 'OPTION'];
if (formElements.includes((event.target as HTMLElement).tagName)) {
return;
}
switch (event.key) {
case 'ArrowLeft': {
let index = selectedPageIndex - 1;
setSelectedPageIndex((prevIndex) => {
index = prevIndex > 0 ? prevIndex - 1 : prevIndex;
return index;
});
handleSelectPage(pages[index].id);
break;
}
case 'ArrowRight': {
let index = selectedPageIndex + 1;
setSelectedPageIndex((prevIndex) => {
index = prevIndex + 1 < pages.length ? prevIndex + 1 : prevIndex;
return index;
});
handleSelectPage(pages[index].id);
break;
}
default:
break;
}
},
[selectedPageIndex, pages],
);

useEffect(() => {
const addShortcutListeners = () => {
document.addEventListener('keydown', handleOnArrowKeyDown);
iframe?.addEventListener('keydown', handleOnArrowKeyDown);
};

addShortcutListeners();

return () => {
document.removeEventListener('keydown', handleOnArrowKeyDown);
iframe?.removeEventListener('keydown', handleOnArrowKeyDown);
};
}, [handleOnArrowKeyDown, iframe]);

return { handleSelectPage };
};
34 changes: 1 addition & 33 deletions src/contexts/ShortcutManager/ShortcutProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import { startTransition, useCallback, useEffect, useMemo } from 'react';
import { useGetIframeAsync } from '@chili-publish/grafx-shared-components';
import { Page } from '@chili-publish/studio-sdk';
import { ProjectConfig } from '../../types/types';
import { isMac } from './shortcuts';
import useUndoRedo from './useUndoRedo';
import useZoom from './useZoom';
import { useAppContext } from '../AppProvider';
import { useSelectPage } from './useSelectPage';

interface ShortcutProviderProps {
projectConfig: ProjectConfig;
zoom: number;
undoStackState: { canUndo: boolean; canRedo: boolean };
children: React.ReactNode;
pages: Page[];
activePageId: string | null;
}
function ShortcutProvider({
projectConfig,
undoStackState,
zoom,
children,
pages,
activePageId,
}: ShortcutProviderProps) {
function ShortcutProvider({ projectConfig, undoStackState, zoom, children }: ShortcutProviderProps) {
const commandKey = isMac ? 'metaKey' : 'ctrlKey';
const iframe = useGetIframeAsync({ containerId: 'studio-ui-chili-editor' })?.contentWindow;

Expand All @@ -34,7 +23,6 @@ function ShortcutProvider({
const { handleUndo, handleRedo } = useUndoRedo(undoStackState);
const { zoomIn, zoomOut } = useZoom(zoom);
const { isDocumentLoaded, selectedMode, updateSelectedMode, cleanRunningTasks } = useAppContext();
const { selectedPageIndex, handleOnArrowKeyDown } = useSelectPage({ pages, activePageId });

const shortcuts = useMemo(
() => [
Expand Down Expand Up @@ -80,24 +68,6 @@ function ShortcutProvider({
if (zoom) zoomOut();
},
},
{
keys: `ArrowLeft`,
action: (e: KeyboardEvent) => {
e.preventDefault();
if (selectedPageIndex >= 0) {
handleOnArrowKeyDown(e);
}
},
},
{
keys: `ArrowRight`,
action: (e: KeyboardEvent) => {
e.preventDefault();
if (selectedPageIndex >= 0) {
handleOnArrowKeyDown(e);
}
},
},
],
[

Check warning on line 72 in src/contexts/ShortcutManager/ShortcutProvider.tsx

View workflow job for this annotation

GitHub Actions / build (20)

React Hook useMemo has missing dependencies: 'handleKeyDown' and 'iframe'. Either include them or remove the dependency array
selectedMode,
Expand All @@ -112,8 +82,6 @@ function ShortcutProvider({
zoomOut,
commandKey,
cleanRunningTasks,
selectedPageIndex,
handleOnArrowKeyDown,
],
);

Expand Down
46 changes: 0 additions & 46 deletions src/contexts/ShortcutManager/useSelectPage.ts

This file was deleted.

52 changes: 0 additions & 52 deletions src/tests/contexts/ShortcutProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ describe('ShortcutProvider', () => {

mockSDK.canvas.setZoomPercentage = jest.fn().mockImplementation().mockReturnValue({ success: true, code: 200 });

mockSDK.page.select = jest.fn();

window.StudioUISDK = mockSDK;
it('triggers the sandbox toggle shortcut', async () => {
const user = userEvent.setup();
Expand All @@ -28,11 +26,6 @@ describe('ShortcutProvider', () => {
projectConfig={projectConfig}
zoom={100}
undoStackState={{ canRedo: true, canUndo: true }}
pages={[
{ id: '0', number: 0 },
{ id: '1', number: 1 },
]}
activePageId="0"
>
<h1>This is a test</h1>
</ShortcutProvider>
Expand All @@ -52,11 +45,6 @@ describe('ShortcutProvider', () => {
projectConfig={projectConfig}
zoom={100}
undoStackState={{ canRedo: true, canUndo: true }}
pages={[
{ id: '0', number: 0 },
{ id: '1', number: 1 },
]}
activePageId="0"
>
<h1>This is a test</h1>
</ShortcutProvider>
Expand All @@ -75,11 +63,6 @@ describe('ShortcutProvider', () => {
projectConfig={projectConfig}
zoom={100}
undoStackState={{ canRedo: true, canUndo: true }}
pages={[
{ id: '0', number: 0 },
{ id: '1', number: 1 },
]}
activePageId="0"
>
<h1>This is a test</h1>
</ShortcutProvider>
Expand All @@ -99,11 +82,6 @@ describe('ShortcutProvider', () => {
projectConfig={projectConfig}
zoom={zoom}
undoStackState={{ canRedo: true, canUndo: true }}
pages={[
{ id: '0', number: 0 },
{ id: '1', number: 1 },
]}
activePageId="0"
>
<h1>This is a test</h1>
</ShortcutProvider>
Expand All @@ -122,11 +100,6 @@ describe('ShortcutProvider', () => {
projectConfig={projectConfig}
zoom={zoom}
undoStackState={{ canRedo: true, canUndo: true }}
pages={[
{ id: '0', number: 0 },
{ id: '1', number: 1 },
]}
activePageId="0"
>
<h1>This is a test</h1>
</ShortcutProvider>
Expand All @@ -135,29 +108,4 @@ describe('ShortcutProvider', () => {
fireEvent.keyDown(screen.getByText('This is a test'), { key: '-', ctrlKey: true });
expect(mockSDK.canvas.setZoomPercentage).toHaveBeenCalledWith(zoom * 0.875);
});
it('triggers change page on arrow key press hortcut', async () => {
const projectConfig = {} as unknown as ProjectConfig;
const user = userEvent.setup();

render(
<AppProvider isDocumentLoaded isAnimationPlaying={false}>
<ShortcutProvider
projectConfig={projectConfig}
zoom={100}
undoStackState={{ canRedo: true, canUndo: true }}
pages={[
{ id: '0', number: 0 },
{ id: '1', number: 1 },
]}
activePageId="0"
>
<h1>This is a test</h1>
</ShortcutProvider>
</AppProvider>,
);
await user.keyboard('[ArrowRight]');
expect(mockSDK.page.select).toHaveBeenCalledWith('1');
await user.keyboard('[ArrowLeft]');
expect(mockSDK.page.select).toHaveBeenCalledWith('0');
});
});

0 comments on commit de92116

Please sign in to comment.