Skip to content
This repository has been archived by the owner on Feb 25, 2024. It is now read-only.

Commit

Permalink
embed mode
Browse files Browse the repository at this point in the history
  • Loading branch information
farskid committed Aug 19, 2021
1 parent 40f0440 commit 1365176
Show file tree
Hide file tree
Showing 16 changed files with 249 additions and 91 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.next/*
53 changes: 40 additions & 13 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import {
Tabs,
} from '@chakra-ui/react';
import { useInterpret, useSelector } from '@xstate/react';
import { useEffect, useMemo } from 'react';
import React, { useEffect, useMemo } from 'react';
import { isElement } from 'react-dom/test-utils';
import { ActorsPanel } from './ActorsPanel';
import { AuthProvider } from './authContext';
import { authMachine } from './authMachine';
import { CanvasProvider } from './CanvasContext';
import { CanvasPanel } from './CanvasPanel';
import { toDirectedGraph } from './directedGraph';
import { EditorPanel } from './EditorPanel';
import { EmbedContext, EmbedProvider, useEmbed } from './embedContext';
import { EventsPanel } from './EventsPanel';
import './Graph';
import { Login } from './Login';
Expand All @@ -32,9 +34,12 @@ import { SpinnerWithText } from './SpinnerWithText';
import { StatePanel } from './StatePanel';
import { theme } from './theme';
import { EditorThemeProvider } from './themeContext';
import { EmbedPanel } from './types';
import { useInterpretCanvas } from './useInterpretCanvas';
import { Visibility } from './Visibility';

function App() {
const App: React.FC = () => {
const embed = useEmbed();
const paletteService = useInterpret(paletteMachine);
// don't use `devTools: true` here as it would freeze your browser
const simService = useInterpret(simulationMachine);
Expand All @@ -54,12 +59,14 @@ function App() {
});
}, [machine?.id, sendToSourceService]);

const sourceID = sourceState.context.sourceID
const sourceID = sourceState.context.sourceID;

const canvasService = useInterpretCanvas({
sourceID,
});

console.log(embed);

return (
<ChakraProvider theme={theme}>
<EditorThemeProvider>
Expand All @@ -76,23 +83,43 @@ function App() {
gridTemplateAreas="'canvas panels' 'footer footer'"
height="100vh"
>
<CanvasProvider value={canvasService}>
<CanvasPanel />
</CanvasProvider>
<Visibility
isHidden={embed.isEmbedded && embed.mode === 'panels'}
>
<CanvasProvider value={canvasService}>
<CanvasPanel />
</CanvasProvider>
</Visibility>

<ResizableBox gridArea="panels" minHeight={0}>
<ResizableBox
gridArea="panels"
minHeight={0}
hidden={embed.isEmbedded && embed.mode === 'viz'}
>
<Tabs
bg="gray.800"
display="grid"
gridTemplateRows="3rem 1fr"
height="100%"
>
<TabList>
<Tab>Code</Tab>
<Tab>State</Tab>
<Tab>Events</Tab>
<Tab>Actors</Tab>
<Tab marginLeft="auto" marginRight="2">
<Tab isSelected={embed.panel === EmbedPanel.Code}>
Code
</Tab>
<Tab isSelected={embed.panel === EmbedPanel.State}>
State
</Tab>
<Tab isSelected={embed.panel === EmbedPanel.Events}>
Events
</Tab>
<Tab isSelected={embed.panel === EmbedPanel.Actors}>
Actors
</Tab>
<Tab
isSelected={embed.panel === EmbedPanel.Settings}
marginLeft="auto"
marginRight="2"
>
<SettingsIcon />
</Tab>
<Login />
Expand Down Expand Up @@ -165,6 +192,6 @@ function App() {
</EditorThemeProvider>
</ChakraProvider>
);
}
};

export default App;
13 changes: 11 additions & 2 deletions src/CanvasPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import { Graph } from './Graph';
import { useSimulation, useSimulationMode } from './SimulationContext';
import { CanvasPanelHeader } from './CanvasPanelHeader';
import { Overlay } from './Overlay';
import { useEmbed } from './embedContext';

export const CanvasPanel: React.FC = () => {
const embed = useEmbed();
const simService = useSimulation();
const canvasService = useCanvas();
const machine = useSelector(simService, (state) => {
Expand Down Expand Up @@ -53,7 +55,7 @@ export const CanvasPanel: React.FC = () => {

return (
<Box display="grid" gridTemplateRows="3rem 1fr">
<Box bg="gray.800" zIndex={1} padding="0">
<Box bg="gray.800" zIndex={1} padding="0" hidden={embed.isEmbedded}>
<CanvasPanelHeader />
</Box>
<CanvasContainer>
Expand All @@ -74,7 +76,14 @@ export const CanvasPanel: React.FC = () => {
</Overlay>
)}
</CanvasContainer>
<HStack position="absolute" bottom={0} left={0} padding="2" zIndex={1}>
<HStack
position="absolute"
bottom={0}
left={0}
padding="2"
zIndex={1}
hidden={embed.isEmbedded}
>
<ButtonGroup size="sm" spacing={2} isAttached>
<IconButton
aria-label="Zoom out"
Expand Down
18 changes: 12 additions & 6 deletions src/EditorPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ActorRefFrom, assign, DoneInvokeEvent, send, spawn } from 'xstate';
import { createModel } from 'xstate/lib/model';
import { useAuth } from './authContext';
import { CommandPalette } from './CommandPalette';
import { useEmbed } from './embedContext';
import { ForkIcon, MagicIcon, SaveIcon } from './Icons';
import { notifMachine } from './notificationMachine';
import { parseMachines } from './parseMachine';
Expand Down Expand Up @@ -139,13 +140,12 @@ const editorPanelMachine = editorPanelModel.createMachine(
src: async (ctx) => {
const monaco = ctx.monacoRef!;
const uri = monaco.Uri.parse(ctx.mainFile);
const getWorker =
await monaco.languages.typescript.getTypeScriptWorker();
const getWorker = await monaco.languages.typescript.getTypeScriptWorker();
const tsWorker = await getWorker(uri);

const usedXStateGistIdentifiers: string[] = await (
tsWorker as any
).queryXStateGistIdentifiers(uri.toString());
const usedXStateGistIdentifiers: string[] = await (tsWorker as any).queryXStateGistIdentifiers(
uri.toString(),
);

if (usedXStateGistIdentifiers.length > 0) {
const fixupImportsText = buildGistFixupImportsText(
Expand Down Expand Up @@ -375,6 +375,7 @@ export const EditorPanel: React.FC<{
onChange: (machine: AnyStateMachine[]) => void;
onChangedCodeValue: (code: string) => void;
}> = ({ onSave, onChange, onChangedCodeValue, onFork, onCreateNew }) => {
const { isEmbedded } = useEmbed();
const authService = useAuth();
const [authState] = useActor(authService);
const sourceService = useSelector(
Expand Down Expand Up @@ -450,7 +451,12 @@ export const EditorPanel: React.FC<{
onSave();
}}
/>
<HStack padding="2" w="full" justifyContent="space-between">
<HStack
padding="2"
w="full"
justifyContent="space-between"
hidden={isEmbedded}
>
<HStack>
<Tooltip
bg="black"
Expand Down
6 changes: 4 additions & 2 deletions src/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ export const Login: React.FC = () => {
const session = state.context!.client.auth.session();

return (
<Box zIndex="1" height="42" display="flex">
<Box zIndex="1" display="flex" alignItems="center" width="60px">
{!state.hasTag('authorized') && (
<Button
className="btn-login"
zIndex="1"
colorScheme="blue"
// colorScheme=""
variant="link"
rounded="false"
isFullWidth
onClick={() => {
authService.send('CHOOSE_PROVIDER');
}}
Expand Down
13 changes: 11 additions & 2 deletions src/ResizableBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Box, BoxProps } from '@chakra-ui/react';
import { useMachine } from '@xstate/react';
import { useEffect, useState } from 'react';
import { createModel } from 'xstate/lib/model';
import { useEmbed } from './embedContext';
import { Point } from './pathUtils';

const dragDropModel = createModel(
Expand Down Expand Up @@ -108,14 +109,22 @@ export const ResizableBox: React.FC<Omit<BoxProps, 'width'>> = ({
children,
...props
}) => {
const { isEmbedded } = useEmbed();
const [widthDelta, setWidthDelta] = useState(0);

return (
// 35rem to avoid shortcut codes breaking
// into multiple lines
<Box width={`clamp(35rem, calc(35rem + ${widthDelta}px), 70vw)`} {...props}>
<Box
{...(!isEmbedded && {
width: `clamp(35rem, calc(35rem + ${widthDelta}px), 70vw)`,
...props,
})}
>
{children}
<ResizeHandle onChange={(value) => setWidthDelta(value)} />
{!isEmbedded && (
<ResizeHandle onChange={(value) => setWidthDelta(value)} />
)}
</Box>
);
};
18 changes: 18 additions & 0 deletions src/Visibility.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Box } from '@chakra-ui/react';
import React from 'react';

export const Visibility: React.FC<
{
isHidden: any;
} & React.ComponentProps<typeof Box>
> = ({ isHidden, children, ...props }) => {
return (
<Box
hidden={isHidden}
// {...(isHidden && { style: hiddenCSS })}
{...(!isHidden && { ...props })}
>
{children}
</Box>
);
};
82 changes: 49 additions & 33 deletions src/canvasMachine.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { castDraft } from 'immer';
import { assign, createMachine, Receiver, StateFrom } from 'xstate';
import { createModel } from 'xstate/lib/model';
import { ModelEventsFrom } from 'xstate/lib/model.types';
Expand Down Expand Up @@ -27,39 +28,42 @@ export type Pan = {
dy: number;
};

export const canvasModel = createModel(initialPosition, {
events: {
'ZOOM.OUT': (x?: number, y?: number, zoomFactor?: ZoomFactor) => ({
zoomFactor,
x,
y,
}),
'ZOOM.IN': (x?: number, y?: number, zoomFactor?: ZoomFactor) => ({
zoomFactor,
x,
y,
}),
'POSITION.RESET': () => ({}),
PAN: (dx: number, dy: number) => ({ dx, dy }),
/**
* Occurs when a source changed id
*/
SOURCE_CHANGED: (id: string | null) => ({
id,
}),
CANVAS_RECT_CHANGED: (
offsetY: number,
offsetX: number,
width: number,
height: number,
) => ({
offsetX,
offsetY,
width,
height,
}),
export const canvasModel = createModel(
{ ...initialPosition, isEmbedded: false },
{
events: {
'ZOOM.OUT': (x?: number, y?: number, zoomFactor?: ZoomFactor) => ({
zoomFactor,
x,
y,
}),
'ZOOM.IN': (x?: number, y?: number, zoomFactor?: ZoomFactor) => ({
zoomFactor,
x,
y,
}),
'POSITION.RESET': () => ({}),
PAN: (dx: number, dy: number) => ({ dx, dy }),
/**
* Occurs when a source changed id
*/
SOURCE_CHANGED: (id: string | null) => ({
id,
}),
CANVAS_RECT_CHANGED: (
offsetY: number,
offsetX: number,
width: number,
height: number,
) => ({
offsetX,
offsetY,
width,
height,
}),
},
},
});
);

const DEFAULT_ZOOM_IN_FACTOR = ZoomFactor.normal;
// exactly reversed factor so zooming in & out results in the same zoom values
Expand Down Expand Up @@ -181,7 +185,19 @@ export const canvasMachine = createMachine<typeof canvasModel>({
},
initial: 'idle',
states: {
idle: {},
idle: {
always: [
{ target: 'in_embedded_mode', cond: (ctx) => ctx.isEmbedded },
{ target: 'idle' },
],
},
in_embedded_mode: {
on: {
PAN: undefined,
'ZOOM.IN': undefined,
'ZOOM.OUT': undefined,
},
},
throttling: {
after: {
300: 'saving',
Expand Down
8 changes: 8 additions & 0 deletions src/embedContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { EmbedMode, EmbedPanel } from './types';
import { createRequiredContext } from './utils';

export const [EmbedProvider, useEmbed] = createRequiredContext<{
isEmbedded: boolean;
mode: EmbedMode;
panel: EmbedPanel;
}>('Embed');
Loading

0 comments on commit 1365176

Please sign in to comment.