Remove most of modelingMachine.context.store (#3867)
This commit is contained in:
@ -12,8 +12,8 @@ test.afterEach(async ({ page }, testInfo) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test.describe('Testing Camera Movement', () => {
|
test.describe('Testing Camera Movement', () => {
|
||||||
test('Can moving camera', async ({ page, context }) => {
|
test('Can move camera reliably', async ({ page, context }) => {
|
||||||
test.skip(process.platform === 'darwin', 'Can moving camera')
|
test.skip(process.platform === 'darwin', 'Can move camera reliably')
|
||||||
const u = await getUtils(page)
|
const u = await getUtils(page)
|
||||||
await page.setViewportSize({ width: 1200, height: 500 })
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
|
||||||
@ -102,6 +102,13 @@ test.describe('Testing Camera Movement', () => {
|
|||||||
await bakeInRetries(async () => {
|
await bakeInRetries(async () => {
|
||||||
await page.mouse.move(700, 200)
|
await page.mouse.move(700, 200)
|
||||||
await page.mouse.down({ button: 'right' })
|
await page.mouse.down({ button: 'right' })
|
||||||
|
const appLogoBBox = await page.getByTestId('app-logo').boundingBox()
|
||||||
|
expect(appLogoBBox).not.toBeNull()
|
||||||
|
if (!appLogoBBox) throw new Error('app logo not found')
|
||||||
|
await page.mouse.move(
|
||||||
|
appLogoBBox.x + appLogoBBox.width / 2,
|
||||||
|
appLogoBBox.y + appLogoBBox.height / 2
|
||||||
|
)
|
||||||
await page.mouse.move(600, 303)
|
await page.mouse.move(600, 303)
|
||||||
await page.mouse.up({ button: 'right' })
|
await page.mouse.up({ button: 'right' })
|
||||||
}, [4, -10.5, -120])
|
}, [4, -10.5, -120])
|
||||||
@ -295,11 +302,11 @@ test.describe('Testing Camera Movement', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
page.getByRole('button', { name: 'Edit Sketch' })
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
|
await hoverOverNothing()
|
||||||
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
|
|
||||||
await page.waitForTimeout(400)
|
await page.waitForTimeout(400)
|
||||||
|
|
||||||
await hoverOverNothing()
|
|
||||||
x = 975
|
x = 975
|
||||||
y = 468
|
y = 468
|
||||||
|
|
||||||
|
@ -31,8 +31,18 @@ test.describe('Testing selections', () => {
|
|||||||
|
|
||||||
const xAxisClick = () =>
|
const xAxisClick = () =>
|
||||||
page.mouse.click(700, 253).then(() => page.waitForTimeout(100))
|
page.mouse.click(700, 253).then(() => page.waitForTimeout(100))
|
||||||
|
const emptySpaceHover = () =>
|
||||||
|
test.step('Hover over empty space', async () => {
|
||||||
|
await page.mouse.move(700, 143, { steps: 5 })
|
||||||
|
await expect(page.locator('.hover-highlight')).not.toBeVisible()
|
||||||
|
})
|
||||||
const emptySpaceClick = () =>
|
const emptySpaceClick = () =>
|
||||||
page.mouse.click(700, 343).then(() => page.waitForTimeout(100))
|
test.step(`Click in empty space`, async () => {
|
||||||
|
await page.mouse.click(700, 143)
|
||||||
|
await expect(page.locator('.cm-line').last()).toHaveClass(
|
||||||
|
/cm-activeLine/
|
||||||
|
)
|
||||||
|
})
|
||||||
const topHorzSegmentClick = () =>
|
const topHorzSegmentClick = () =>
|
||||||
page.mouse.click(709, 290).then(() => page.waitForTimeout(100))
|
page.mouse.click(709, 290).then(() => page.waitForTimeout(100))
|
||||||
const bottomHorzSegmentClick = () =>
|
const bottomHorzSegmentClick = () =>
|
||||||
@ -171,7 +181,9 @@ test.describe('Testing selections', () => {
|
|||||||
await emptySpaceClick()
|
await emptySpaceClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
await selectionSequence()
|
await test.step(`Test hovering and selecting on fresh sketch`, async () => {
|
||||||
|
await selectionSequence()
|
||||||
|
})
|
||||||
|
|
||||||
// hovering in fresh sketch worked, lets try exiting and re-entering
|
// hovering in fresh sketch worked, lets try exiting and re-entering
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
@ -184,16 +196,15 @@ test.describe('Testing selections', () => {
|
|||||||
|
|
||||||
// select a line, this verifies that sketches in the scene can be selected outside of sketch mode
|
// select a line, this verifies that sketches in the scene can be selected outside of sketch mode
|
||||||
await topHorzSegmentClick()
|
await topHorzSegmentClick()
|
||||||
await page.waitForTimeout(100)
|
await emptySpaceHover()
|
||||||
|
|
||||||
// enter sketch again
|
// enter sketch again
|
||||||
await u.doAndWaitForCmd(
|
await u.doAndWaitForCmd(
|
||||||
() => page.getByRole('button', { name: 'Edit Sketch' }).click(),
|
() => page.getByRole('button', { name: 'Edit Sketch' }).click(),
|
||||||
'default_camera_get_settings'
|
'default_camera_get_settings'
|
||||||
)
|
)
|
||||||
await page.waitForTimeout(150)
|
|
||||||
|
|
||||||
await page.waitForTimeout(300) // wait for animation
|
await page.waitForTimeout(450) // wait for animation
|
||||||
|
|
||||||
await u.openAndClearDebugPanel()
|
await u.openAndClearDebugPanel()
|
||||||
await u.sendCustomCmd({
|
await u.sendCustomCmd({
|
||||||
@ -220,8 +231,9 @@ test.describe('Testing selections', () => {
|
|||||||
|
|
||||||
await u.closeDebugPanel()
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
// hover again and check it works
|
await test.step(`Test hovering and selecting on edited sketch`, async () => {
|
||||||
await selectionSequence()
|
await selectionSequence()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Solids should be select and deletable', async ({ page }) => {
|
test('Solids should be select and deletable', async ({ page }) => {
|
||||||
|
60
src/App.tsx
60
src/App.tsx
@ -1,12 +1,8 @@
|
|||||||
import { MouseEventHandler, useEffect, useMemo, useRef } from 'react'
|
import { useEffect, useMemo, useRef } from 'react'
|
||||||
import { uuidv4 } from 'lib/utils'
|
|
||||||
import { useHotKeyListener } from './hooks/useHotKeyListener'
|
import { useHotKeyListener } from './hooks/useHotKeyListener'
|
||||||
import { Stream } from './components/Stream'
|
import { Stream } from './components/Stream'
|
||||||
import { EngineCommand } from 'lang/std/artifactGraph'
|
|
||||||
import { throttle } from './lib/utils'
|
|
||||||
import { AppHeader } from './components/AppHeader'
|
import { AppHeader } from './components/AppHeader'
|
||||||
import { useHotkeys } from 'react-hotkeys-hook'
|
import { useHotkeys } from 'react-hotkeys-hook'
|
||||||
import { getNormalisedCoordinates } from './lib/utils'
|
|
||||||
import { useLoaderData, useNavigate } from 'react-router-dom'
|
import { useLoaderData, useNavigate } from 'react-router-dom'
|
||||||
import { type IndexLoaderData } from 'lib/types'
|
import { type IndexLoaderData } from 'lib/types'
|
||||||
import { PATHS } from 'lib/paths'
|
import { PATHS } from 'lib/paths'
|
||||||
@ -14,7 +10,6 @@ import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
|||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useEngineConnectionSubscriptions } from 'hooks/useEngineConnectionSubscriptions'
|
import { useEngineConnectionSubscriptions } from 'hooks/useEngineConnectionSubscriptions'
|
||||||
import { codeManager, engineCommandManager } from 'lib/singletons'
|
import { codeManager, engineCommandManager } from 'lib/singletons'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
||||||
import { isDesktop } from 'lib/isDesktop'
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
import { useLspContext } from 'components/LspProvider'
|
import { useLspContext } from 'components/LspProvider'
|
||||||
@ -26,7 +21,6 @@ import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
|||||||
import Gizmo from 'components/Gizmo'
|
import Gizmo from 'components/Gizmo'
|
||||||
import { CoreDumpManager } from 'lib/coredump'
|
import { CoreDumpManager } from 'lib/coredump'
|
||||||
import { UnitsMenu } from 'components/UnitsMenu'
|
import { UnitsMenu } from 'components/UnitsMenu'
|
||||||
import { reportRejection } from 'lib/trap'
|
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
const { project, file } = useLoaderData() as IndexLoaderData
|
const { project, file } = useLoaderData() as IndexLoaderData
|
||||||
@ -45,7 +39,6 @@ export function App() {
|
|||||||
}, [projectName, projectPath])
|
}, [projectName, projectPath])
|
||||||
|
|
||||||
useHotKeyListener()
|
useHotKeyListener()
|
||||||
const { context, state } = useModelingContext()
|
|
||||||
|
|
||||||
const { auth, settings } = useSettingsAuthContext()
|
const { auth, settings } = useSettingsAuthContext()
|
||||||
const token = auth?.context?.token
|
const token = auth?.context?.token
|
||||||
@ -74,61 +67,14 @@ export function App() {
|
|||||||
(p) => p === onboardingStatus.current
|
(p) => p === onboardingStatus.current
|
||||||
)
|
)
|
||||||
? 'opacity-20'
|
? 'opacity-20'
|
||||||
: context.store?.didDragInStream
|
|
||||||
? 'opacity-40'
|
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
useEngineConnectionSubscriptions()
|
useEngineConnectionSubscriptions()
|
||||||
|
|
||||||
const debounceSocketSend = throttle<EngineCommand>((message) => {
|
|
||||||
engineCommandManager.sendSceneCommand(message).catch(reportRejection)
|
|
||||||
}, 1000 / 15)
|
|
||||||
const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {
|
|
||||||
if (state.matches('Sketch')) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const { x, y } = getNormalisedCoordinates({
|
|
||||||
clientX: e.clientX,
|
|
||||||
clientY: e.clientY,
|
|
||||||
el: e.currentTarget,
|
|
||||||
...context.store?.streamDimensions,
|
|
||||||
})
|
|
||||||
|
|
||||||
const newCmdId = uuidv4()
|
|
||||||
if (state.matches({ idle: 'showPlanes' })) return
|
|
||||||
if (context.store?.buttonDownInStream !== undefined) return
|
|
||||||
debounceSocketSend({
|
|
||||||
type: 'modeling_cmd_req',
|
|
||||||
cmd: {
|
|
||||||
type: 'highlight_set_entity',
|
|
||||||
selected_at_window: { x, y },
|
|
||||||
},
|
|
||||||
cmd_id: newCmdId,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="relative h-full flex flex-col" ref={ref}>
|
||||||
className="relative h-full flex flex-col"
|
|
||||||
onMouseMove={handleMouseMove}
|
|
||||||
ref={ref}
|
|
||||||
>
|
|
||||||
<AppHeader
|
<AppHeader
|
||||||
className={
|
className={'transition-opacity transition-duration-75 ' + paneOpacity}
|
||||||
'transition-opacity transition-duration-75 ' +
|
|
||||||
paneOpacity +
|
|
||||||
(context.store?.buttonDownInStream ? ' pointer-events-none' : '')
|
|
||||||
}
|
|
||||||
// Override the electron window draggable region behavior as well
|
|
||||||
// when the button is down in the stream
|
|
||||||
style={
|
|
||||||
isDesktop() && context.store?.buttonDownInStream
|
|
||||||
? ({
|
|
||||||
'-webkit-app-region': 'no-drag',
|
|
||||||
} as React.CSSProperties)
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
project={{ project, file }}
|
project={{ project, file }}
|
||||||
enableMenu={true}
|
enableMenu={true}
|
||||||
/>
|
/>
|
||||||
|
@ -343,7 +343,8 @@ export class CameraControls {
|
|||||||
this.camera.updateProjectionMatrix()
|
this.camera.updateProjectionMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseDown = (event: MouseEvent) => {
|
onMouseDown = (event: PointerEvent) => {
|
||||||
|
this.domElement.setPointerCapture(event.pointerId)
|
||||||
this.isDragging = true
|
this.isDragging = true
|
||||||
this.mouseDownPosition.set(event.clientX, event.clientY)
|
this.mouseDownPosition.set(event.clientX, event.clientY)
|
||||||
let interaction = this.getInteractionType(event)
|
let interaction = this.getInteractionType(event)
|
||||||
@ -363,7 +364,7 @@ export class CameraControls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseMove = (event: MouseEvent) => {
|
onMouseMove = (event: PointerEvent) => {
|
||||||
if (this.isDragging) {
|
if (this.isDragging) {
|
||||||
this.mouseNewPosition.set(event.clientX, event.clientY)
|
this.mouseNewPosition.set(event.clientX, event.clientY)
|
||||||
const deltaMove = this.mouseNewPosition
|
const deltaMove = this.mouseNewPosition
|
||||||
@ -401,10 +402,29 @@ export class CameraControls {
|
|||||||
this.pendingPan.x += -deltaMove.x * panSpeed
|
this.pendingPan.x += -deltaMove.x * panSpeed
|
||||||
this.pendingPan.y += deltaMove.y * panSpeed
|
this.pendingPan.y += deltaMove.y * panSpeed
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* If we're not in sketch mode and not dragging, we can highlight entities
|
||||||
|
* under the cursor. This recently moved from being handled in App.tsx.
|
||||||
|
* This might not be the right spot, but it is more consolidated.
|
||||||
|
*/
|
||||||
|
if (this.syncDirection === 'engineToClient') {
|
||||||
|
const newCmdId = uuidv4()
|
||||||
|
|
||||||
|
this.throttledEngCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd: {
|
||||||
|
type: 'highlight_set_entity',
|
||||||
|
selected_at_window: { x: event.clientX, y: event.clientY },
|
||||||
|
},
|
||||||
|
cmd_id: newCmdId,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseUp = (event: MouseEvent) => {
|
onMouseUp = (event: PointerEvent) => {
|
||||||
|
this.domElement.releasePointerCapture(event.pointerId)
|
||||||
this.isDragging = false
|
this.isDragging = false
|
||||||
this.handleEnd()
|
this.handleEnd()
|
||||||
if (this.syncDirection === 'engineToClient') {
|
if (this.syncDirection === 'engineToClient') {
|
||||||
|
@ -105,10 +105,6 @@ export class SceneInfra {
|
|||||||
_baseUnit: BaseUnit = 'mm'
|
_baseUnit: BaseUnit = 'mm'
|
||||||
_baseUnitMultiplier = 1
|
_baseUnitMultiplier = 1
|
||||||
_theme: Themes = Themes.System
|
_theme: Themes = Themes.System
|
||||||
_streamDimensions: { streamWidth: number; streamHeight: number } = {
|
|
||||||
streamWidth: 1280,
|
|
||||||
streamHeight: 720,
|
|
||||||
}
|
|
||||||
extraSegmentTexture: Texture
|
extraSegmentTexture: Texture
|
||||||
lastMouseState: MouseState = { type: 'idle' }
|
lastMouseState: MouseState = { type: 'idle' }
|
||||||
onDragStartCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragStartCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import styles from './ModelingPane.module.css'
|
import styles from './ModelingPane.module.css'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
import { ActionButton } from 'components/ActionButton'
|
import { ActionButton } from 'components/ActionButton'
|
||||||
import Tooltip from 'components/Tooltip'
|
import Tooltip from 'components/Tooltip'
|
||||||
import { CustomIconName } from 'components/CustomIcon'
|
import { CustomIconName } from 'components/CustomIcon'
|
||||||
@ -69,9 +68,8 @@ export const ModelingPane = ({
|
|||||||
}: ModelingPaneProps) => {
|
}: ModelingPaneProps) => {
|
||||||
const { settings } = useSettingsAuthContext()
|
const { settings } = useSettingsAuthContext()
|
||||||
const onboardingStatus = settings.context.app.onboardingStatus
|
const onboardingStatus = settings.context.app.onboardingStatus
|
||||||
const { context } = useModelingContext()
|
|
||||||
const pointerEventsCssClass =
|
const pointerEventsCssClass =
|
||||||
context.store?.buttonDownInStream || onboardingStatus.current === 'camera'
|
onboardingStatus.current === 'camera'
|
||||||
? 'pointer-events-none '
|
? 'pointer-events-none '
|
||||||
: 'pointer-events-auto '
|
: 'pointer-events-auto '
|
||||||
return (
|
return (
|
||||||
|
@ -31,7 +31,6 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
|||||||
const onboardingStatus = settings.context.app.onboardingStatus
|
const onboardingStatus = settings.context.app.onboardingStatus
|
||||||
const { send, context } = useModelingContext()
|
const { send, context } = useModelingContext()
|
||||||
const pointerEventsCssClass =
|
const pointerEventsCssClass =
|
||||||
context.store?.buttonDownInStream ||
|
|
||||||
onboardingStatus.current === 'camera' ||
|
onboardingStatus.current === 'camera' ||
|
||||||
context.store?.openPanes.length === 0
|
context.store?.openPanes.length === 0
|
||||||
? 'pointer-events-none '
|
? 'pointer-events-none '
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { MouseEventHandler, useEffect, useRef, useState } from 'react'
|
import { MouseEventHandler, useEffect, useRef, useState } from 'react'
|
||||||
import { getNormalisedCoordinates } from '../lib/utils'
|
|
||||||
import Loading from './Loading'
|
import Loading from './Loading'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
@ -28,10 +27,9 @@ enum StreamState {
|
|||||||
|
|
||||||
export const Stream = () => {
|
export const Stream = () => {
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
const [clickCoords, setClickCoords] = useState<{ x: number; y: number }>()
|
|
||||||
const videoRef = useRef<HTMLVideoElement>(null)
|
const videoRef = useRef<HTMLVideoElement>(null)
|
||||||
const { settings } = useSettingsAuthContext()
|
const { settings } = useSettingsAuthContext()
|
||||||
const { state, send, context } = useModelingContext()
|
const { state, send } = useModelingContext()
|
||||||
const { mediaStream } = useAppStream()
|
const { mediaStream } = useAppStream()
|
||||||
const { overallState, immediateState } = useNetworkContext()
|
const { overallState, immediateState } = useNetworkContext()
|
||||||
const [streamState, setStreamState] = useState(StreamState.Unset)
|
const [streamState, setStreamState] = useState(StreamState.Unset)
|
||||||
@ -256,75 +254,15 @@ export const Stream = () => {
|
|||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}, [mediaStream])
|
}, [mediaStream])
|
||||||
|
|
||||||
const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {
|
|
||||||
if (!isNetworkOkay) return
|
|
||||||
if (!videoRef.current) return
|
|
||||||
if (state.matches('Sketch')) return
|
|
||||||
if (state.matches('Sketch no face')) return
|
|
||||||
|
|
||||||
const { x, y } = getNormalisedCoordinates({
|
|
||||||
clientX: e.clientX,
|
|
||||||
clientY: e.clientY,
|
|
||||||
el: videoRef.current,
|
|
||||||
...context.store?.streamDimensions,
|
|
||||||
})
|
|
||||||
|
|
||||||
send({
|
|
||||||
type: 'Set context',
|
|
||||||
data: {
|
|
||||||
buttonDownInStream: e.button,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
setClickCoords({ x, y })
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMouseUp: MouseEventHandler<HTMLDivElement> = (e) => {
|
const handleMouseUp: MouseEventHandler<HTMLDivElement> = (e) => {
|
||||||
if (!isNetworkOkay) return
|
if (!isNetworkOkay) return
|
||||||
if (!videoRef.current) return
|
if (!videoRef.current) return
|
||||||
send({
|
|
||||||
type: 'Set context',
|
|
||||||
data: {
|
|
||||||
buttonDownInStream: undefined,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (state.matches('Sketch')) return
|
if (state.matches('Sketch')) return
|
||||||
if (state.matches({ idle: 'showPlanes' })) return
|
if (state.matches({ idle: 'showPlanes' })) return
|
||||||
|
|
||||||
if (!context.store?.didDragInStream && btnName(e).left) {
|
if (btnName(e).left) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
sendSelectEventToEngine(
|
sendSelectEventToEngine(e, videoRef.current)
|
||||||
e,
|
|
||||||
videoRef.current,
|
|
||||||
context.store?.streamDimensions
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
send({
|
|
||||||
type: 'Set context',
|
|
||||||
data: {
|
|
||||||
didDragInStream: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
setClickCoords(undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMouseMove: MouseEventHandler<HTMLVideoElement> = (e) => {
|
|
||||||
if (!isNetworkOkay) return
|
|
||||||
if (state.matches('Sketch')) return
|
|
||||||
if (state.matches('Sketch no face')) return
|
|
||||||
if (!clickCoords) return
|
|
||||||
|
|
||||||
const delta =
|
|
||||||
((clickCoords.x - e.clientX) ** 2 + (clickCoords.y - e.clientY) ** 2) **
|
|
||||||
0.5
|
|
||||||
|
|
||||||
if (delta > 5 && !context.store?.didDragInStream) {
|
|
||||||
send({
|
|
||||||
type: 'Set context',
|
|
||||||
data: {
|
|
||||||
didDragInStream: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,8 +271,7 @@ export const Stream = () => {
|
|||||||
className="absolute inset-0 z-0"
|
className="absolute inset-0 z-0"
|
||||||
id="stream"
|
id="stream"
|
||||||
data-testid="stream"
|
data-testid="stream"
|
||||||
onMouseUp={handleMouseUp}
|
onClick={handleMouseUp}
|
||||||
onMouseDown={handleMouseDown}
|
|
||||||
onContextMenu={(e) => e.preventDefault()}
|
onContextMenu={(e) => e.preventDefault()}
|
||||||
onContextMenuCapture={(e) => e.preventDefault()}
|
onContextMenuCapture={(e) => e.preventDefault()}
|
||||||
>
|
>
|
||||||
@ -344,7 +281,6 @@ export const Stream = () => {
|
|||||||
autoPlay
|
autoPlay
|
||||||
controls={false}
|
controls={false}
|
||||||
onPlay={() => setIsLoading(false)}
|
onPlay={() => setIsLoading(false)}
|
||||||
onMouseMoveCapture={handleMouseMove}
|
|
||||||
className="w-full cursor-pointer h-full"
|
className="w-full cursor-pointer h-full"
|
||||||
disablePictureInPicture
|
disablePictureInPicture
|
||||||
id="video-stream"
|
id="video-stream"
|
||||||
|
@ -59,15 +59,6 @@ export function useSetupEngineManager(
|
|||||||
return modifyGrid(kclManager.engineCommandManager, hidden)
|
return modifyGrid(kclManager.engineCommandManager, hidden)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
modelingSend({
|
|
||||||
type: 'Set context',
|
|
||||||
data: {
|
|
||||||
streamDimensions: {
|
|
||||||
streamWidth: quadWidth,
|
|
||||||
streamHeight: quadHeight,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
hasSetNonZeroDimensions.current = true
|
hasSetNonZeroDimensions.current = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,24 +102,10 @@ export function useSetupEngineManager(
|
|||||||
streamRef?.current?.offsetWidth ?? 0,
|
streamRef?.current?.offsetWidth ?? 0,
|
||||||
streamRef?.current?.offsetHeight ?? 0
|
streamRef?.current?.offsetHeight ?? 0
|
||||||
)
|
)
|
||||||
if (
|
engineCommandManager.handleResize({
|
||||||
modelingContext.store.streamDimensions.streamWidth !== width ||
|
streamWidth: width,
|
||||||
modelingContext.store.streamDimensions.streamHeight !== height
|
streamHeight: height,
|
||||||
) {
|
})
|
||||||
engineCommandManager.handleResize({
|
|
||||||
streamWidth: width,
|
|
||||||
streamHeight: height,
|
|
||||||
})
|
|
||||||
modelingSend({
|
|
||||||
type: 'Set context',
|
|
||||||
data: {
|
|
||||||
streamDimensions: {
|
|
||||||
streamWidth: width,
|
|
||||||
streamHeight: height,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, 500)
|
}, 500)
|
||||||
|
|
||||||
const onOnline = () => {
|
const onOnline = () => {
|
||||||
|
@ -617,14 +617,14 @@ function codeToIdSelections(
|
|||||||
|
|
||||||
export async function sendSelectEventToEngine(
|
export async function sendSelectEventToEngine(
|
||||||
e: MouseEvent | React.MouseEvent<HTMLDivElement, MouseEvent>,
|
e: MouseEvent | React.MouseEvent<HTMLDivElement, MouseEvent>,
|
||||||
el: HTMLVideoElement,
|
el: HTMLVideoElement
|
||||||
streamDimensions: { streamWidth: number; streamHeight: number }
|
|
||||||
) {
|
) {
|
||||||
const { x, y } = getNormalisedCoordinates({
|
const { x, y } = getNormalisedCoordinates({
|
||||||
clientX: e.clientX,
|
clientX: e.clientX,
|
||||||
clientY: e.clientY,
|
clientY: e.clientY,
|
||||||
el,
|
el,
|
||||||
...streamDimensions,
|
streamWidth: el.clientWidth,
|
||||||
|
streamHeight: el.clientHeight,
|
||||||
})
|
})
|
||||||
const res = await engineCommandManager.sendSceneCommand({
|
const res = await engineCommandManager.sendSceneCommand({
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
|
File diff suppressed because one or more lines are too long
@ -7,10 +7,8 @@ import {
|
|||||||
cameraSystems,
|
cameraSystems,
|
||||||
} from 'lib/cameraControls'
|
} from 'lib/cameraControls'
|
||||||
import { SettingsSection } from 'components/Settings/SettingsSection'
|
import { SettingsSection } from 'components/Settings/SettingsSection'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
|
|
||||||
export default function Units() {
|
export default function Units() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.STREAMING)
|
const next = useNextClick(onboardingPaths.STREAMING)
|
||||||
const {
|
const {
|
||||||
@ -28,8 +26,7 @@ export default function Units() {
|
|||||||
<div className="fixed inset-0 z-50 grid items-end justify-start px-4 pointer-events-none">
|
<div className="fixed inset-0 z-50 grid items-end justify-start px-4 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SettingsSection
|
<SettingsSection
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import usePlatform from 'hooks/usePlatform'
|
import usePlatform from 'hooks/usePlatform'
|
||||||
import { OnboardingButtons, kbdClasses, useDismiss, useNextClick } from '.'
|
import { OnboardingButtons, kbdClasses, useDismiss, useNextClick } from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
import { hotkeyDisplay } from 'lib/hotkeyWrapper'
|
import { hotkeyDisplay } from 'lib/hotkeyWrapper'
|
||||||
import { COMMAND_PALETTE_HOTKEY } from 'components/CommandBar/CommandBar'
|
import { COMMAND_PALETTE_HOTKEY } from 'components/CommandBar/CommandBar'
|
||||||
|
|
||||||
export default function CmdK() {
|
export default function CmdK() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.USER_MENU)
|
const next = useNextClick(onboardingPaths.USER_MENU)
|
||||||
const platformName = usePlatform()
|
const platformName = usePlatform()
|
||||||
@ -15,8 +13,7 @@ export default function CmdK() {
|
|||||||
<div className="fixed inset-0 z-50 grid items-end justify-center pointer-events-none">
|
<div className="fixed inset-0 z-50 grid items-end justify-center pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-full xl:max-w-4xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-full xl:max-w-4xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<h2 className="text-2xl font-bold">Command Bar</h2>
|
<h2 className="text-2xl font-bold">Command Bar</h2>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
import {
|
import {
|
||||||
kbdClasses,
|
kbdClasses,
|
||||||
OnboardingButtons,
|
OnboardingButtons,
|
||||||
@ -10,7 +9,6 @@ import { onboardingPaths } from 'routes/Onboarding/paths'
|
|||||||
|
|
||||||
export default function OnboardingCodeEditor() {
|
export default function OnboardingCodeEditor() {
|
||||||
useDemoCode()
|
useDemoCode()
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.PARAMETRIC_MODELING)
|
const next = useNextClick(onboardingPaths.PARAMETRIC_MODELING)
|
||||||
|
|
||||||
@ -18,8 +16,7 @@ export default function OnboardingCodeEditor() {
|
|||||||
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto">
|
<section className="flex-1 overflow-y-auto">
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { APP_NAME } from 'lib/constants'
|
import { APP_NAME } from 'lib/constants'
|
||||||
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
|
|
||||||
export default function Export() {
|
export default function Export() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.SKETCHING)
|
const next = useNextClick(onboardingPaths.SKETCHING)
|
||||||
|
|
||||||
@ -12,8 +10,7 @@ export default function Export() {
|
|||||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1">
|
<section className="flex-1">
|
||||||
|
@ -7,11 +7,9 @@ import {
|
|||||||
} from '.'
|
} from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { bracketWidthConstantLine } from 'lib/exampleKcl'
|
import { bracketWidthConstantLine } from 'lib/exampleKcl'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
|
|
||||||
export default function OnboardingInteractiveNumbers() {
|
export default function OnboardingInteractiveNumbers() {
|
||||||
useDemoCode()
|
useDemoCode()
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.COMMAND_K)
|
const next = useNextClick(onboardingPaths.COMMAND_K)
|
||||||
|
|
||||||
@ -19,8 +17,7 @@ export default function OnboardingInteractiveNumbers() {
|
|||||||
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto mb-6">
|
<section className="flex-1 overflow-y-auto mb-6">
|
||||||
|
@ -3,11 +3,9 @@ import { onboardingPaths } from 'routes/Onboarding/paths'
|
|||||||
import { Themes, getSystemTheme } from 'lib/theme'
|
import { Themes, getSystemTheme } from 'lib/theme'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
import { bracketThicknessCalculationLine } from 'lib/exampleKcl'
|
import { bracketThicknessCalculationLine } from 'lib/exampleKcl'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
|
|
||||||
export default function OnboardingParametricModeling() {
|
export default function OnboardingParametricModeling() {
|
||||||
useDemoCode()
|
useDemoCode()
|
||||||
const { context } = useModelingContext()
|
|
||||||
const {
|
const {
|
||||||
settings: {
|
settings: {
|
||||||
context: {
|
context: {
|
||||||
@ -29,8 +27,7 @@ export default function OnboardingParametricModeling() {
|
|||||||
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto z-10 max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto mb-6">
|
<section className="flex-1 overflow-y-auto mb-6">
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { isDesktop } from 'lib/isDesktop'
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
|
|
||||||
export default function ProjectMenu() {
|
export default function ProjectMenu() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.EXPORT)
|
const next = useNextClick(onboardingPaths.EXPORT)
|
||||||
const onDesktop = isDesktop()
|
const onDesktop = isDesktop()
|
||||||
@ -13,8 +11,7 @@ export default function ProjectMenu() {
|
|||||||
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-xl flex flex-col border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-xl flex flex-col border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1">
|
<section className="flex-1">
|
||||||
|
@ -2,10 +2,8 @@ import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
|||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { codeManager, kclManager } from 'lib/singletons'
|
import { codeManager, kclManager } from 'lib/singletons'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
|
|
||||||
export default function Sketching() {
|
export default function Sketching() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.FUTURE_WORK)
|
const next = useNextClick(onboardingPaths.FUTURE_WORK)
|
||||||
|
|
||||||
@ -24,8 +22,7 @@ export default function Sketching() {
|
|||||||
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-full xl:max-w-2xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<h1 className="text-2xl font-bold">Sketching</h1>
|
<h1 className="text-2xl font-bold">Sketching</h1>
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
|
|
||||||
export default function Streaming() {
|
export default function Streaming() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.EDITOR)
|
const next = useNextClick(onboardingPaths.EDITOR)
|
||||||
|
|
||||||
@ -11,8 +9,7 @@ export default function Streaming() {
|
|||||||
<div className="fixed grid justify-start items-center inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-start items-center inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-xl border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg h-[75vh] flex flex-col justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto">
|
<section className="flex-1 overflow-y-auto">
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
|
|
||||||
export default function UserMenu() {
|
export default function UserMenu() {
|
||||||
const { context } = useModelingContext()
|
|
||||||
const { auth } = useSettingsAuthContext()
|
const { auth } = useSettingsAuthContext()
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
||||||
@ -35,8 +33,7 @@ export default function UserMenu() {
|
|||||||
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'max-w-xl flex flex-col border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded' +
|
'pointer-events-auto max-w-xl flex flex-col border border-chalkboard-50 dark:border-chalkboard-80 shadow-lg justify-center bg-chalkboard-10 dark:bg-chalkboard-90 p-8 rounded'
|
||||||
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1">
|
<section className="flex-1">
|
||||||
|
Reference in New Issue
Block a user