Skip to content

Commit

Permalink
[Fix] Fix broken studio ui instance (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandraFlavia9 authored Nov 21, 2024
1 parent 141af31 commit 19297fd
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 130 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"validate-versions": "node validate_versions.cjs"
},
"dependencies": {
"@chili-publish/grafx-shared-components": "^0.85.8",
"@chili-publish/grafx-shared-components": "^0.85.9",
"@chili-publish/studio-sdk": "^1.16.0-rc.12",
"axios": "^1.6.0",
"react": "^18.2.0",
Expand Down
129 changes: 68 additions & 61 deletions src/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { APP_WRAPPER_ID } from './utils/constants';
import ShortcutProvider from './contexts/ShortcutManager/ShortcutProvider';
import { SuiCanvas } from './MainContent.styles';
import { useAuthToken } from './contexts/AuthTokenProvider';
import AppProvider from './contexts/AppProvider';

declare global {
interface Window {
Expand Down Expand Up @@ -303,76 +304,82 @@ function MainContent({ projectConfig, updateToken: setAuthToken }: MainContentPr
}, [authToken, fetchedDocument]);

return (
<ShortcutProvider projectConfig={projectConfig} undoStackState={undoStackState} zoom={currentZoom}>
<Container canvas={canvas}>
<UiConfigContextProvider projectConfig={projectConfig} layoutIntent={layoutIntent}>
<VariablePanelContextProvider
connectors={{ mediaConnectors, fontsConnectors }}
variables={variables}
>
<div id={APP_WRAPPER_ID} className="app">
{projectConfig.sandboxMode ? (
<UiThemeProvider theme="studio" mode="dark">
<StudioNavbar
<AppProvider isDocumentLoaded={isDocumentLoaded} isAnimationPlaying={animationStatus}>
<ShortcutProvider projectConfig={projectConfig} undoStackState={undoStackState} zoom={currentZoom}>
<Container canvas={canvas}>
<UiConfigContextProvider projectConfig={projectConfig} layoutIntent={layoutIntent}>
<VariablePanelContextProvider
connectors={{ mediaConnectors, fontsConnectors }}
variables={variables}
>
<div id={APP_WRAPPER_ID} className="app">
{projectConfig.sandboxMode ? (
<UiThemeProvider theme="studio" mode="dark">
<StudioNavbar
projectName={projectConfig?.projectName || currentProject?.name}
goBack={projectConfig?.onUserInterfaceBack}
projectConfig={projectConfig}
undoStackState={undoStackState}
zoom={currentZoom}
/>
</UiThemeProvider>
) : (
<Navbar
projectName={projectConfig?.projectName || currentProject?.name}
goBack={projectConfig?.onUserInterfaceBack}
projectConfig={projectConfig}
undoStackState={undoStackState}
zoom={currentZoom}
/>
</UiThemeProvider>
) : (
<Navbar
projectName={projectConfig?.projectName || currentProject?.name}
goBack={projectConfig?.onUserInterfaceBack}
projectConfig={projectConfig}
undoStackState={undoStackState}
zoom={currentZoom}
/>
)}

<MainContentContainer sandboxMode={projectConfig.sandboxMode}>
{!isMobileSize && (
<LeftPanel variables={variables} isDocumentLoaded={isDocumentLoaded} />
)}
<CanvasContainer>
{isMobileSize && (
<MobileVariablesTray
variables={variables}
isTimelineDisplayed={layoutIntent === LayoutIntent.digitalAnimated}
isDocumentLoaded={isDocumentLoaded}
/>

<MainContentContainer sandboxMode={projectConfig.sandboxMode}>
{!isMobileSize && (
<LeftPanel variables={variables} isDocumentLoaded={isDocumentLoaded} />
)}
<SuiCanvas
hasAnimationTimeline={layoutIntent === LayoutIntent.digitalAnimated}
data-id={getDataIdForSUI('canvas')}
data-testid={getDataTestIdForSUI('canvas')}
>
<div className="chili-editor" id={EDITOR_ID} />
</SuiCanvas>
{layoutIntent === LayoutIntent.digitalAnimated ? (
<AnimationTimeline
scrubberTimeMs={scrubberTimeMs}
animationLength={animationLength}
isAnimationPlaying={animationStatus}
<CanvasContainer>
{isMobileSize && (
<MobileVariablesTray
variables={variables}
isTimelineDisplayed={layoutIntent === LayoutIntent.digitalAnimated}
isDocumentLoaded={isDocumentLoaded}
/>
)}
<SuiCanvas
hasAnimationTimeline={layoutIntent === LayoutIntent.digitalAnimated}
data-id={getDataIdForSUI('canvas')}
data-testid={getDataTestIdForSUI('canvas')}
>
<div className="chili-editor" id={EDITOR_ID} />
</SuiCanvas>
{layoutIntent === LayoutIntent.digitalAnimated ? (
<AnimationTimeline
scrubberTimeMs={scrubberTimeMs}
animationLength={animationLength}
isAnimationPlaying={animationStatus}
/>
) : null}
</CanvasContainer>
</MainContentContainer>
{pendingAuthentications.length &&
pendingAuthentications.map((authFlow) => (
<ConnectorAuthenticationModal
key={authFlow.connectorId}
name={authFlow.connectorName}
onConfirm={() =>
connectorAuthenticationProcess(authFlow.connectorId)?.start()
}
onCancel={() =>
connectorAuthenticationProcess(authFlow.connectorId)?.cancel()
}
/>
) : null}
</CanvasContainer>
</MainContentContainer>
{pendingAuthentications.length &&
pendingAuthentications.map((authFlow) => (
<ConnectorAuthenticationModal
key={authFlow.connectorId}
name={authFlow.connectorName}
onConfirm={() => connectorAuthenticationProcess(authFlow.connectorId)?.start()}
onCancel={() => connectorAuthenticationProcess(authFlow.connectorId)?.cancel()}
/>
))}
</div>
</VariablePanelContextProvider>
</UiConfigContextProvider>
</Container>
</ShortcutProvider>
))}
</div>
</VariablePanelContextProvider>
</UiConfigContextProvider>
</Container>
</ShortcutProvider>
</AppProvider>
);
}

Expand Down
5 changes: 3 additions & 2 deletions src/components/animationTimeline/AnimationTimeline.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Timeline, useTheme } from '@chili-publish/grafx-shared-components';
import { useCallback } from 'react';
import { AnimationTimelineWrapper } from './AnimationTimeline.styles';
import { getDataTestIdForSUI } from '../../utils/dataIds';

Expand All @@ -15,9 +16,9 @@ function AnimationTimeline(props: IAnimationTimeline) {
await window.StudioUISDK.animation.play();
};

const handlePause = async () => {
const handlePause = useCallback(async () => {
await window.StudioUISDK.animation.pause();
};
}, []);

const handleSetScrubberPosition = async (milliseconds: number) => {
await window.StudioUISDK.animation.setScrubberPosition(milliseconds);
Expand Down
32 changes: 22 additions & 10 deletions src/components/navbar/navbarItems/useNavbarModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,49 @@
import { Toggle, ToggleOption } from '@chili-publish/grafx-shared-components';
import { ChangeEvent, useCallback, useMemo, useState } from 'react';
import { ChangeEvent, startTransition, useCallback, useMemo } from 'react';
import { css } from 'styled-components';
import { useAppContext } from '../../../contexts/AppProvider';
import { ProjectConfig } from '../../../types/types';

type Mode = 'design' | 'run';

const options: ToggleOption[] = [
{ id: 'design', label: 'Design' },
{ id: 'run', label: 'Run' },
];

const useNavbarModeToggle = (projectConfig: ProjectConfig) => {
const [selectedMode, setSelectedMode] = useState<Mode>('run');
const { selectedMode, isDocumentLoaded, updateSelectedMode, cleanRunningTasks } = useAppContext();

const onToggle = useCallback(
(ev: ChangeEvent<HTMLInputElement>) => {
setSelectedMode(ev.target.value as Mode);
projectConfig?.onSandboxModeToggle?.();
async (ev: ChangeEvent<HTMLInputElement>) => {
ev.stopPropagation();
ev.preventDefault();

updateSelectedMode(ev.target.value);

await cleanRunningTasks();

startTransition(() => projectConfig?.onSandboxModeToggle?.());
},
[projectConfig],
[projectConfig, cleanRunningTasks, updateSelectedMode],
);

const navbarItem = useMemo(
() => ({
label: 'Toggle',
content: (
<Toggle onChange={onToggle} checked={selectedMode} options={options} width="9.5rem" height="2rem" />
<Toggle
disabled={!isDocumentLoaded}
onChange={onToggle}
checked={selectedMode}
options={options}
width="9.5rem"
height="2rem"
/>
),
styles: css`
padding-left: 0.125rem;
`,
}),
[selectedMode, onToggle],
[isDocumentLoaded, selectedMode, onToggle],
);

return {
Expand Down
2 changes: 1 addition & 1 deletion src/components/variablesComponents/BooleanVariable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function BooleanVariable(props: IBooleanVariable) {
dataId={getDataIdForSUI(`switch-${variable.id}`)}
dataTestId={getDataTestIdForSUI(`switch-${variable.id}`)}
isChecked={toggled}
id={variable.id}
id={`ui-${variable.id}`}
label={{
key: 'visible',
value: featureFlags?.STUDIO_LABEL_PROPERTY_ENABLED ? variable.label : variable.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const useVariableConnector = (variable: ImageVariable) => {
setSelectedConnector(remoteMediaConnector);
}
})();
}, [graFxStudioEnvironmentApiBaseUrl, variable.value?.connectorId]);
}, [graFxStudioEnvironmentApiBaseUrl, authToken, variable.value?.connectorId]);

return {
selectedConnector,
Expand Down
55 changes: 55 additions & 0 deletions src/contexts/AppProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { createContext, ReactNode, useCallback, useContext, useMemo, useState } from 'react';

type Mode = 'design' | 'run';

interface IAppContext {
isDocumentLoaded: boolean;
selectedMode: Mode;
updateSelectedMode: (_: string) => void;
cleanRunningTasks: () => Promise<void>;
}

const AppContext = createContext<IAppContext>({
isDocumentLoaded: false,
selectedMode: 'run',
updateSelectedMode: () => null,
cleanRunningTasks: () => Promise.resolve(),
});

export const useAppContext = () => {
return useContext(AppContext);
};

function AppProvider({
isDocumentLoaded,
isAnimationPlaying,
children,
}: {
isDocumentLoaded: boolean;
isAnimationPlaying: boolean;
children: ReactNode;
}) {
const [selectedMode, setSelectedMode] = useState<Mode>('run');

const cleanRunningTasks = useCallback(async () => {
if (isAnimationPlaying) await window.StudioUISDK.animation.pause();
}, [isAnimationPlaying]);

const updateSelectedMode = useCallback((val: string) => {
setSelectedMode(val as Mode);
}, []);

const data = useMemo(
() => ({
isDocumentLoaded,
selectedMode,
updateSelectedMode,
cleanRunningTasks,
}),
[isDocumentLoaded, selectedMode, updateSelectedMode, cleanRunningTasks],
);

return <AppContext.Provider value={data}>{children}</AppContext.Provider>;
}

export default AppProvider;
39 changes: 29 additions & 10 deletions src/contexts/ShortcutManager/ShortcutProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useCallback, useEffect, useMemo } from 'react';
import { startTransition, useCallback, useEffect, useMemo } from 'react';
import { useGetIframeAsync } from '@chili-publish/grafx-shared-components';
import { ProjectConfig } from '../../types/types';
import { isMac } from './shortcuts';
import useUndoRedo from './useUndoRedo';
import useZoom from './useZoom';
import { useAppContext } from '../AppProvider';

interface ShortcutProviderProps {
projectConfig: ProjectConfig;
Expand All @@ -21,13 +22,22 @@ function ShortcutProvider({ projectConfig, undoStackState, zoom, children }: Sho

const { handleUndo, handleRedo } = useUndoRedo(undoStackState);
const { zoomIn, zoomOut } = useZoom(zoom);
const { isDocumentLoaded, selectedMode, updateSelectedMode, cleanRunningTasks } = useAppContext();

const shortcuts = useMemo(
() => [
{
keys: 'm',
action: () => {
projectConfig?.onSandboxModeToggle?.();
action: async () => {
if (!isDocumentLoaded) return;

updateSelectedMode('design');

document.removeEventListener('keydown', handleKeyDown);
iframe?.removeEventListener('keydown', handleKeyDown);

if (selectedMode === 'run') await cleanRunningTasks();
startTransition(() => projectConfig?.onSandboxModeToggle?.());
},
},
{
Expand Down Expand Up @@ -59,7 +69,20 @@ function ShortcutProvider({ projectConfig, undoStackState, zoom, children }: Sho
},
},
],
[projectConfig, undoStackState, handleUndo, handleRedo, zoom, zoomIn, zoomOut, commandKey],
[

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

View workflow job for this annotation

GitHub Actions / update-bundle-size (20)

React Hook useMemo has missing dependencies: 'handleKeyDown' and 'iframe'. Either include them or remove the dependency array

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

View workflow job for this annotation

GitHub Actions / build-preflight (20)

React Hook useMemo has missing dependencies: 'handleKeyDown' and 'iframe'. Either include them or remove the dependency array
selectedMode,
updateSelectedMode,
isDocumentLoaded,
projectConfig,
undoStackState,
handleUndo,
handleRedo,
zoom,
zoomIn,
zoomOut,
commandKey,
cleanRunningTasks,
],
);

const compareShortcuts = (shortcut: string | string[], pressedKeys: string) => {
Expand Down Expand Up @@ -101,15 +124,11 @@ function ShortcutProvider({ projectConfig, undoStackState, zoom, children }: Sho
iframe?.addEventListener('keydown', handleKeyDown);
};

const removeShortcutListeners = () => {
document.removeEventListener('keydown', handleKeyDown);
iframe?.removeEventListener('keydown', handleKeyDown);
};

addShortcutListeners();

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

Expand Down
Loading

0 comments on commit 19297fd

Please sign in to comment.