Compare commits
4 Commits
tmp-mediaS
...
v0.24.1
Author | SHA1 | Date | |
---|---|---|---|
f9419a98b5 | |||
999f72bccf | |||
9dbe74e008 | |||
88d9cdc52b |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "untitled-app",
|
"name": "untitled-app",
|
||||||
"version": "0.24.0",
|
"version": "0.24.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.17.0",
|
"@codemirror/autocomplete": "^6.17.0",
|
||||||
|
@ -93,23 +93,10 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
private doSemanticTokens: boolean = false
|
private doSemanticTokens: boolean = false
|
||||||
private doFoldingRanges: boolean = false
|
private doFoldingRanges: boolean = false
|
||||||
|
|
||||||
private _defferer = deferExecution((code: string) => {
|
// When a doc update needs to be sent to the server, this holds the
|
||||||
try {
|
// timeout handle for it. When null, the server has the up-to-date
|
||||||
// Update the state (not the editor) with the new code.
|
// document.
|
||||||
this.client.textDocumentDidChange({
|
private sendScheduled: number | null = null
|
||||||
textDocument: {
|
|
||||||
uri: this.getDocUri(),
|
|
||||||
version: this.documentVersion++,
|
|
||||||
},
|
|
||||||
contentChanges: [{ text: code }],
|
|
||||||
})
|
|
||||||
|
|
||||||
this.requestSemanticTokens()
|
|
||||||
this.updateFoldingRanges()
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}, this.changesDelay)
|
|
||||||
|
|
||||||
constructor(options: LanguageServerOptions, private view: EditorView) {
|
constructor(options: LanguageServerOptions, private view: EditorView) {
|
||||||
this.client = options.client
|
this.client = options.client
|
||||||
@ -152,14 +139,9 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(viewUpdate: ViewUpdate) {
|
update(viewUpdate: ViewUpdate) {
|
||||||
// If the doc didn't change we can return early.
|
if (viewUpdate.docChanged) {
|
||||||
if (!viewUpdate.docChanged) {
|
this.scheduleSendDoc()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendChange({
|
|
||||||
documentText: viewUpdate.state.doc.toString(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
@ -184,16 +166,6 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
this.updateFoldingRanges()
|
this.updateFoldingRanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendChange({ documentText }: { documentText: string }) {
|
|
||||||
if (!this.client.ready) return
|
|
||||||
|
|
||||||
this._defferer(documentText)
|
|
||||||
}
|
|
||||||
|
|
||||||
requestDiagnostics() {
|
|
||||||
this.sendChange({ documentText: this.getDocText() })
|
|
||||||
}
|
|
||||||
|
|
||||||
async requestHoverTooltip(
|
async requestHoverTooltip(
|
||||||
view: EditorView,
|
view: EditorView,
|
||||||
{ line, character }: { line: number; character: number }
|
{ line, character }: { line: number; character: number }
|
||||||
@ -204,7 +176,7 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
this.sendChange({ documentText: this.getDocText() })
|
this.ensureDocSent()
|
||||||
const result = await this.client.textDocumentHover({
|
const result = await this.client.textDocumentHover({
|
||||||
textDocument: { uri: this.getDocUri() },
|
textDocument: { uri: this.getDocUri() },
|
||||||
position: { line, character },
|
position: { line, character },
|
||||||
@ -227,6 +199,42 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
return { pos, end, create: (view) => ({ dom }), above: true }
|
return { pos, end, create: (view) => ({ dom }), above: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduleSendDoc() {
|
||||||
|
if (this.sendScheduled != null) window.clearTimeout(this.sendScheduled)
|
||||||
|
this.sendScheduled = window.setTimeout(
|
||||||
|
() => this.sendDoc(),
|
||||||
|
this.changesDelay
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sendDoc() {
|
||||||
|
if (this.sendScheduled != null) {
|
||||||
|
window.clearTimeout(this.sendScheduled)
|
||||||
|
this.sendScheduled = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.client.ready) return
|
||||||
|
try {
|
||||||
|
// Update the state (not the editor) with the new code.
|
||||||
|
this.client.textDocumentDidChange({
|
||||||
|
textDocument: {
|
||||||
|
uri: this.getDocUri(),
|
||||||
|
version: this.documentVersion++,
|
||||||
|
},
|
||||||
|
contentChanges: [{ text: this.view.state.doc.toString() }],
|
||||||
|
})
|
||||||
|
|
||||||
|
this.requestSemanticTokens()
|
||||||
|
this.updateFoldingRanges()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureDocSent() {
|
||||||
|
if (this.sendScheduled != null) this.sendDoc()
|
||||||
|
}
|
||||||
|
|
||||||
async getFoldingRanges(): Promise<LSP.FoldingRange[] | null> {
|
async getFoldingRanges(): Promise<LSP.FoldingRange[] | null> {
|
||||||
if (
|
if (
|
||||||
!this.doFoldingRanges ||
|
!this.doFoldingRanges ||
|
||||||
@ -284,13 +292,7 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
this.client.textDocumentDidChange({
|
this.ensureDocSent()
|
||||||
textDocument: {
|
|
||||||
uri: this.getDocUri(),
|
|
||||||
version: this.documentVersion++,
|
|
||||||
},
|
|
||||||
contentChanges: [{ text: this.getDocText() }],
|
|
||||||
})
|
|
||||||
|
|
||||||
const result = await this.client.textDocumentFormatting({
|
const result = await this.client.textDocumentFormatting({
|
||||||
textDocument: { uri: this.getDocUri() },
|
textDocument: { uri: this.getDocUri() },
|
||||||
@ -330,9 +332,7 @@ export class LanguageServerPlugin implements PluginValue {
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
this.sendChange({
|
this.ensureDocSent()
|
||||||
documentText: context.state.doc.toString(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const result = await this.client.textDocumentCompletion({
|
const result = await this.client.textDocumentCompletion({
|
||||||
textDocument: { uri: this.getDocUri() },
|
textDocument: { uri: this.getDocUri() },
|
||||||
|
@ -80,5 +80,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"productName": "Zoo Modeling App",
|
"productName": "Zoo Modeling App",
|
||||||
"version": "0.24.0"
|
"version": "0.24.1"
|
||||||
}
|
}
|
||||||
|
11
src/App.tsx
@ -26,7 +26,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 { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
useRefreshSettings(paths.FILE + 'SETTINGS')
|
useRefreshSettings(paths.FILE + 'SETTINGS')
|
||||||
@ -46,8 +45,6 @@ export function App() {
|
|||||||
|
|
||||||
useHotKeyListener()
|
useHotKeyListener()
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { streamDimensions, didDragInStream, buttonDownInStream } =
|
|
||||||
useAppState()
|
|
||||||
|
|
||||||
const { auth, settings } = useSettingsAuthContext()
|
const { auth, settings } = useSettingsAuthContext()
|
||||||
const token = auth?.context?.token
|
const token = auth?.context?.token
|
||||||
@ -77,7 +74,7 @@ export function App() {
|
|||||||
(p) => p === onboardingStatus.current
|
(p) => p === onboardingStatus.current
|
||||||
)
|
)
|
||||||
? 'opacity-20'
|
? 'opacity-20'
|
||||||
: didDragInStream
|
: context.store?.didDragInStream
|
||||||
? 'opacity-40'
|
? 'opacity-40'
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
@ -95,11 +92,11 @@ export function App() {
|
|||||||
clientX: e.clientX,
|
clientX: e.clientX,
|
||||||
clientY: e.clientY,
|
clientY: e.clientY,
|
||||||
el: e.currentTarget,
|
el: e.currentTarget,
|
||||||
...streamDimensions,
|
...context.store?.streamDimensions,
|
||||||
})
|
})
|
||||||
|
|
||||||
const newCmdId = uuidv4()
|
const newCmdId = uuidv4()
|
||||||
if (buttonDownInStream === undefined) {
|
if (context.store?.buttonDownInStream === undefined) {
|
||||||
debounceSocketSend({
|
debounceSocketSend({
|
||||||
type: 'modeling_cmd_req',
|
type: 'modeling_cmd_req',
|
||||||
cmd: {
|
cmd: {
|
||||||
@ -121,7 +118,7 @@ export function App() {
|
|||||||
className={
|
className={
|
||||||
'transition-opacity transition-duration-75 ' +
|
'transition-opacity transition-duration-75 ' +
|
||||||
paneOpacity +
|
paneOpacity +
|
||||||
(buttonDownInStream ? ' pointer-events-none' : '')
|
(context.store?.buttonDownInStream ? ' pointer-events-none' : '')
|
||||||
}
|
}
|
||||||
project={{ project, file }}
|
project={{ project, file }}
|
||||||
enableMenu={true}
|
enableMenu={true}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
import {
|
import { createContext, useContext, useState, ReactNode } from 'react'
|
||||||
createContext,
|
|
||||||
useContext,
|
|
||||||
useState,
|
|
||||||
ReactNode,
|
|
||||||
useEffect,
|
|
||||||
} from 'react'
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -17,23 +11,11 @@ Please do not fill this up with junk.
|
|||||||
interface AppState {
|
interface AppState {
|
||||||
isStreamReady: boolean
|
isStreamReady: boolean
|
||||||
setAppState: (newAppState: Partial<AppState>) => void
|
setAppState: (newAppState: Partial<AppState>) => void
|
||||||
|
|
||||||
mediaStream?: MediaStream
|
|
||||||
buttonDownInStream: number | undefined
|
|
||||||
didDragInStream: boolean
|
|
||||||
streamDimensions: { streamWidth: number; streamHeight: number }
|
|
||||||
// openPanes: SidebarType[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppStateContext = createContext<AppState>({
|
const AppStateContext = createContext<AppState>({
|
||||||
isStreamReady: false,
|
isStreamReady: false,
|
||||||
setAppState: () => {},
|
setAppState: () => {},
|
||||||
|
|
||||||
buttonDownInStream: undefined,
|
|
||||||
didDragInStream: false,
|
|
||||||
streamDimensions: { streamWidth: 1280, streamHeight: 720 },
|
|
||||||
mediaStream: undefined,
|
|
||||||
// openPanes: persistedContext.openPanes || ['code'],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const useAppState = () => useContext(AppStateContext)
|
export const useAppState = () => useContext(AppStateContext)
|
||||||
@ -42,38 +24,47 @@ export const AppStateProvider = ({ children }: { children: ReactNode }) => {
|
|||||||
const [appState, _setAppState] = useState<AppState>({
|
const [appState, _setAppState] = useState<AppState>({
|
||||||
isStreamReady: false,
|
isStreamReady: false,
|
||||||
setAppState: () => {},
|
setAppState: () => {},
|
||||||
|
|
||||||
buttonDownInStream: undefined,
|
|
||||||
didDragInStream: false,
|
|
||||||
streamDimensions: { streamWidth: 1280, streamHeight: 720 },
|
|
||||||
mediaStream: undefined,
|
|
||||||
// openPanes: persistedContext.openPanes || ['code'],
|
|
||||||
})
|
})
|
||||||
useEffect(() => {
|
const setAppState = (newAppState: Partial<AppState>) =>
|
||||||
// console.log('appState change', appState)
|
_setAppState({ ...appState, ...newAppState })
|
||||||
}, [appState])
|
|
||||||
const setAppState = (newAppState: Partial<AppState>) => {
|
|
||||||
// console.log('appstate', newAppState)
|
|
||||||
_setAppState({
|
|
||||||
...appState,
|
|
||||||
...newAppState,
|
|
||||||
mediaStream: newAppState.mediaStream || appState.mediaStream,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppStateContext.Provider
|
<AppStateContext.Provider
|
||||||
value={{
|
value={{
|
||||||
isStreamReady: appState.isStreamReady,
|
isStreamReady: appState.isStreamReady,
|
||||||
setAppState,
|
setAppState,
|
||||||
|
|
||||||
mediaStream: appState.mediaStream,
|
|
||||||
buttonDownInStream: appState.buttonDownInStream,
|
|
||||||
didDragInStream: appState.didDragInStream,
|
|
||||||
streamDimensions: appState.streamDimensions,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</AppStateContext.Provider>
|
</AppStateContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AppStream {
|
||||||
|
mediaStream: MediaStream
|
||||||
|
setMediaStream: (mediaStream: MediaStream) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppStreamContext = createContext<AppStream>({
|
||||||
|
mediaStream: undefined as unknown as MediaStream,
|
||||||
|
setMediaStream: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const useAppStream = () => useContext(AppStreamContext)
|
||||||
|
|
||||||
|
export const AppStreamProvider = ({ children }: { children: ReactNode }) => {
|
||||||
|
const [mediaStream, setMediaStream] = useState<MediaStream>(
|
||||||
|
undefined as unknown as MediaStream
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppStreamContext.Provider
|
||||||
|
value={{
|
||||||
|
mediaStream,
|
||||||
|
setMediaStream,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</AppStreamContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -49,17 +49,17 @@ const router = createBrowserRouter([
|
|||||||
/* Make sure auth is the outermost provider or else we will have
|
/* Make sure auth is the outermost provider or else we will have
|
||||||
* inefficient re-renders, use the react profiler to see. */
|
* inefficient re-renders, use the react profiler to see. */
|
||||||
element: (
|
element: (
|
||||||
<AppStateProvider>
|
<CommandBarProvider>
|
||||||
<CommandBarProvider>
|
<SettingsAuthProvider>
|
||||||
<SettingsAuthProvider>
|
<LspProvider>
|
||||||
<LspProvider>
|
<KclContextProvider>
|
||||||
<KclContextProvider>
|
<AppStateProvider>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</KclContextProvider>
|
</AppStateProvider>
|
||||||
</LspProvider>
|
</KclContextProvider>
|
||||||
</SettingsAuthProvider>
|
</LspProvider>
|
||||||
</CommandBarProvider>
|
</SettingsAuthProvider>
|
||||||
</AppStateProvider>
|
</CommandBarProvider>
|
||||||
),
|
),
|
||||||
errorElement: <ErrorPage />,
|
errorElement: <ErrorPage />,
|
||||||
children: [
|
children: [
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
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 { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export interface ModelingPaneProps
|
export interface ModelingPaneProps
|
||||||
extends React.PropsWithChildren,
|
extends React.PropsWithChildren,
|
||||||
@ -34,10 +33,9 @@ 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 { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const pointerEventsCssClass =
|
const pointerEventsCssClass =
|
||||||
buttonDownInStream || onboardingStatus.current === 'camera'
|
context.store?.buttonDownInStream || onboardingStatus.current === 'camera'
|
||||||
? 'pointer-events-none '
|
? 'pointer-events-none '
|
||||||
: 'pointer-events-auto '
|
: 'pointer-events-auto '
|
||||||
return (
|
return (
|
||||||
|
@ -15,7 +15,6 @@ import styles from './ModelingSidebar.module.css'
|
|||||||
import { ModelingPane } from './ModelingPane'
|
import { ModelingPane } from './ModelingPane'
|
||||||
import { isTauri } from 'lib/isTauri'
|
import { isTauri } from 'lib/isTauri'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
interface ModelingSidebarProps {
|
interface ModelingSidebarProps {
|
||||||
paneOpacity: '' | 'opacity-20' | 'opacity-40'
|
paneOpacity: '' | 'opacity-20' | 'opacity-40'
|
||||||
@ -25,9 +24,8 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
|||||||
const { settings } = useSettingsAuthContext()
|
const { settings } = useSettingsAuthContext()
|
||||||
const onboardingStatus = settings.context.app.onboardingStatus
|
const onboardingStatus = settings.context.app.onboardingStatus
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const pointerEventsCssClass =
|
const pointerEventsCssClass =
|
||||||
buttonDownInStream ||
|
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 '
|
||||||
|
@ -9,7 +9,7 @@ import { ClientSideScene } from 'clientSideScene/ClientSideSceneComp'
|
|||||||
import { btnName } from 'lib/cameraControls'
|
import { btnName } from 'lib/cameraControls'
|
||||||
import { sendSelectEventToEngine } from 'lib/selections'
|
import { sendSelectEventToEngine } from 'lib/selections'
|
||||||
import { kclManager, engineCommandManager, sceneInfra } from 'lib/singletons'
|
import { kclManager, engineCommandManager, sceneInfra } from 'lib/singletons'
|
||||||
import { useAppState } from 'AppState'
|
import { useAppStream } from 'AppState'
|
||||||
|
|
||||||
export const Stream = () => {
|
export const Stream = () => {
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
@ -17,10 +17,8 @@ export const Stream = () => {
|
|||||||
const [clickCoords, setClickCoords] = useState<{ x: number; y: number }>()
|
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 } = useModelingContext()
|
const { state, send, context } = useModelingContext()
|
||||||
const { mediaStream, streamDimensions, didDragInStream, setAppState } =
|
const { mediaStream } = useAppStream()
|
||||||
useAppState()
|
|
||||||
|
|
||||||
const { overallState } = useNetworkContext()
|
const { overallState } = useNetworkContext()
|
||||||
const [isFreezeFrame, setIsFreezeFrame] = useState(false)
|
const [isFreezeFrame, setIsFreezeFrame] = useState(false)
|
||||||
|
|
||||||
@ -128,19 +126,12 @@ export const Stream = () => {
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
if (!videoRef.current) return
|
if (!videoRef.current) return
|
||||||
// console.log('setting mideastrema to vi2', mediaStream, (window as any).mediaStream)
|
if (!mediaStream) return
|
||||||
const _mediaStream = mediaStream || (window as any).mediaStream
|
|
||||||
if (!_mediaStream) return
|
|
||||||
|
|
||||||
// console.log('setting mideastrema to vi')
|
|
||||||
// Do not immediately play the stream!
|
// Do not immediately play the stream!
|
||||||
videoRef.current.srcObject = _mediaStream
|
videoRef.current.srcObject = mediaStream
|
||||||
videoRef.current.pause()
|
videoRef.current.pause()
|
||||||
|
|
||||||
// setAppState({
|
|
||||||
// mediaStream,
|
|
||||||
// })
|
|
||||||
|
|
||||||
send({
|
send({
|
||||||
type: 'Set context',
|
type: 'Set context',
|
||||||
data: {
|
data: {
|
||||||
@ -159,49 +150,44 @@ export const Stream = () => {
|
|||||||
clientX: e.clientX,
|
clientX: e.clientX,
|
||||||
clientY: e.clientY,
|
clientY: e.clientY,
|
||||||
el: videoRef.current,
|
el: videoRef.current,
|
||||||
...streamDimensions,
|
...context.store?.streamDimensions,
|
||||||
})
|
})
|
||||||
|
|
||||||
setAppState({
|
send({
|
||||||
buttonDownInStream: e.button,
|
type: 'Set context',
|
||||||
|
data: {
|
||||||
|
buttonDownInStream: e.button,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
// send({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: {
|
|
||||||
// buttonDownInStream: e.button,
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
setClickCoords({ x, y })
|
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
|
||||||
setAppState({
|
send({
|
||||||
buttonDownInStream: undefined,
|
type: 'Set context',
|
||||||
|
data: {
|
||||||
|
buttonDownInStream: undefined,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
// send({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: {
|
|
||||||
// buttonDownInStream: undefined,
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
if (state.matches('Sketch')) return
|
if (state.matches('Sketch')) return
|
||||||
if (state.matches('Sketch no face')) return
|
if (state.matches('Sketch no face')) return
|
||||||
|
|
||||||
if (!didDragInStream && btnName(e).left) {
|
if (!context.store?.didDragInStream && btnName(e).left) {
|
||||||
sendSelectEventToEngine(e, videoRef.current, streamDimensions)
|
sendSelectEventToEngine(
|
||||||
|
e,
|
||||||
|
videoRef.current,
|
||||||
|
context.store?.streamDimensions
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
setAppState({
|
send({
|
||||||
didDragInStream: false,
|
type: 'Set context',
|
||||||
|
data: {
|
||||||
|
didDragInStream: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
// send({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: {
|
|
||||||
// didDragInStream: false,
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
setClickCoords(undefined)
|
setClickCoords(undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,16 +201,13 @@ export const Stream = () => {
|
|||||||
((clickCoords.x - e.clientX) ** 2 + (clickCoords.y - e.clientY) ** 2) **
|
((clickCoords.x - e.clientX) ** 2 + (clickCoords.y - e.clientY) ** 2) **
|
||||||
0.5
|
0.5
|
||||||
|
|
||||||
if (delta > 5 && !didDragInStream) {
|
if (delta > 5 && !context.store?.didDragInStream) {
|
||||||
setAppState({
|
send({
|
||||||
didDragInStream: true,
|
type: 'Set context',
|
||||||
|
data: {
|
||||||
|
didDragInStream: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
// send({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: {
|
|
||||||
// didDragInStream: true,
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,14 +195,15 @@ export class CompletionRequester implements PluginValue {
|
|||||||
|
|
||||||
private queuedUids: string[] = []
|
private queuedUids: string[] = []
|
||||||
|
|
||||||
private _deffererCodeUpdate = deferExecution(() => {
|
|
||||||
this.requestCompletions()
|
|
||||||
}, changesDelay)
|
|
||||||
|
|
||||||
private _deffererUserSelect = deferExecution(() => {
|
private _deffererUserSelect = deferExecution(() => {
|
||||||
this.rejectSuggestionCommand()
|
this.rejectSuggestionCommand()
|
||||||
}, changesDelay)
|
}, changesDelay)
|
||||||
|
|
||||||
|
// When a doc update needs to be sent to the server, this holds the
|
||||||
|
// timeout handle for it. When null, the server has the up-to-date
|
||||||
|
// document.
|
||||||
|
private sendScheduledInput: number | null = null
|
||||||
|
|
||||||
constructor(readonly view: EditorView, client: LanguageServerClient) {
|
constructor(readonly view: EditorView, client: LanguageServerClient) {
|
||||||
this.client = client
|
this.client = client
|
||||||
}
|
}
|
||||||
@ -245,7 +246,34 @@ export class CompletionRequester implements PluginValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.lastPos = this.view.state.selection.main.head
|
this.lastPos = this.view.state.selection.main.head
|
||||||
if (viewUpdate.docChanged) this._deffererCodeUpdate(true)
|
if (viewUpdate.docChanged) this.scheduleUpdateDoc()
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleUpdateDoc() {
|
||||||
|
if (this.sendScheduledInput != null)
|
||||||
|
window.clearTimeout(this.sendScheduledInput)
|
||||||
|
this.sendScheduledInput = window.setTimeout(
|
||||||
|
() => this.updateDoc(),
|
||||||
|
changesDelay
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDoc() {
|
||||||
|
if (this.sendScheduledInput != null) {
|
||||||
|
window.clearTimeout(this.sendScheduledInput)
|
||||||
|
this.sendScheduledInput = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.client.ready) return
|
||||||
|
try {
|
||||||
|
this.requestCompletions()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureDocUpdated() {
|
||||||
|
if (this.sendScheduledInput != null) this.updateDoc()
|
||||||
}
|
}
|
||||||
|
|
||||||
ghostText(): GhostText | null {
|
ghostText(): GhostText | null {
|
||||||
|
@ -27,13 +27,10 @@ export class KclPlugin implements PluginValue {
|
|||||||
this.client = client
|
this.client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
private _deffererCodeUpdate = deferExecution(() => {
|
// When a doc update needs to be sent to the server, this holds the
|
||||||
if (this.viewUpdate === null) {
|
// timeout handle for it. When null, the server has the up-to-date
|
||||||
return
|
// document.
|
||||||
}
|
private sendScheduledInput: number | null = null
|
||||||
|
|
||||||
kclManager.executeCode()
|
|
||||||
}, changesDelay)
|
|
||||||
|
|
||||||
private _deffererUserSelect = deferExecution(() => {
|
private _deffererUserSelect = deferExecution(() => {
|
||||||
if (this.viewUpdate === null) {
|
if (this.viewUpdate === null) {
|
||||||
@ -101,7 +98,34 @@ export class KclPlugin implements PluginValue {
|
|||||||
codeManager.code = newCode
|
codeManager.code = newCode
|
||||||
codeManager.writeToFile()
|
codeManager.writeToFile()
|
||||||
|
|
||||||
this._deffererCodeUpdate(true)
|
this.scheduleUpdateDoc()
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleUpdateDoc() {
|
||||||
|
if (this.sendScheduledInput != null)
|
||||||
|
window.clearTimeout(this.sendScheduledInput)
|
||||||
|
this.sendScheduledInput = window.setTimeout(
|
||||||
|
() => this.updateDoc(),
|
||||||
|
changesDelay
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDoc() {
|
||||||
|
if (this.sendScheduledInput != null) {
|
||||||
|
window.clearTimeout(this.sendScheduledInput)
|
||||||
|
this.sendScheduledInput = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.client.ready) return
|
||||||
|
try {
|
||||||
|
kclManager.executeCode()
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureDocUpdated() {
|
||||||
|
if (this.sendScheduledInput != null) this.updateDoc()
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateUnits(
|
async updateUnits(
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { useLayoutEffect, useEffect, useRef } from 'react'
|
import { useLayoutEffect, useEffect, useRef } from 'react'
|
||||||
import { engineCommandManager, kclManager, sceneInfra } from 'lib/singletons'
|
import { engineCommandManager, kclManager } from 'lib/singletons'
|
||||||
import { deferExecution } from 'lib/utils'
|
import { deferExecution } from 'lib/utils'
|
||||||
import { Themes } from 'lib/theme'
|
import { Themes } from 'lib/theme'
|
||||||
import { makeDefaultPlanes, modifyGrid } from 'lang/wasm'
|
import { makeDefaultPlanes, modifyGrid } from 'lang/wasm'
|
||||||
import { useModelingContext } from './useModelingContext'
|
import { useModelingContext } from './useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
import { useAppState, useAppStream } from 'AppState'
|
||||||
|
|
||||||
export function useSetupEngineManager(
|
export function useSetupEngineManager(
|
||||||
streamRef: React.RefObject<HTMLDivElement>,
|
streamRef: React.RefObject<HTMLDivElement>,
|
||||||
@ -27,7 +27,8 @@ export function useSetupEngineManager(
|
|||||||
showScaleGrid: boolean
|
showScaleGrid: boolean
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const { setAppState, streamDimensions } = useAppState()
|
const { setAppState } = useAppState()
|
||||||
|
const { setMediaStream } = useAppStream()
|
||||||
|
|
||||||
const streamWidth = streamRef?.current?.offsetWidth
|
const streamWidth = streamRef?.current?.offsetWidth
|
||||||
const streamHeight = streamRef?.current?.offsetHeight
|
const streamHeight = streamRef?.current?.offsetHeight
|
||||||
@ -47,17 +48,14 @@ export function useSetupEngineManager(
|
|||||||
streamWidth,
|
streamWidth,
|
||||||
streamHeight
|
streamHeight
|
||||||
)
|
)
|
||||||
if (!hasSetNonZeroDimensions.current && quadHeight && quadWidth) {
|
if (
|
||||||
|
!hasSetNonZeroDimensions.current &&
|
||||||
|
quadHeight &&
|
||||||
|
quadWidth &&
|
||||||
|
settings.modelingSend
|
||||||
|
) {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
// setMediaStream: (mediaStream) =>
|
setMediaStream: setMediaStream,
|
||||||
// settings.modelingSend({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: { mediaStream },
|
|
||||||
// }),
|
|
||||||
setMediaStream: (mediaStream) => {
|
|
||||||
;(window as any).mediaStream = mediaStream
|
|
||||||
setAppState({ mediaStream })
|
|
||||||
},
|
|
||||||
setIsStreamReady: (isStreamReady) => setAppState({ isStreamReady }),
|
setIsStreamReady: (isStreamReady) => setAppState({ isStreamReady }),
|
||||||
width: quadWidth,
|
width: quadWidth,
|
||||||
height: quadHeight,
|
height: quadHeight,
|
||||||
@ -78,22 +76,15 @@ export function useSetupEngineManager(
|
|||||||
return modifyGrid(kclManager.engineCommandManager, hidden)
|
return modifyGrid(kclManager.engineCommandManager, hidden)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
setAppState({
|
settings.modelingSend({
|
||||||
streamDimensions: { streamWidth: quadWidth, streamHeight: quadHeight },
|
type: 'Set context',
|
||||||
|
data: {
|
||||||
|
streamDimensions: {
|
||||||
|
streamWidth: quadWidth,
|
||||||
|
streamHeight: quadHeight,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
sceneInfra._streamDimensions = {
|
|
||||||
streamWidth: quadWidth,
|
|
||||||
streamHeight: quadHeight,
|
|
||||||
}
|
|
||||||
// settings.modelingSend({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: {
|
|
||||||
// streamDimensions: {
|
|
||||||
// streamWidth: quadWidth,
|
|
||||||
// streamHeight: quadHeight,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
hasSetNonZeroDimensions.current = true
|
hasSetNonZeroDimensions.current = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +93,6 @@ export function useSetupEngineManager(
|
|||||||
streamRef?.current?.offsetWidth,
|
streamRef?.current?.offsetWidth,
|
||||||
streamRef?.current?.offsetHeight,
|
streamRef?.current?.offsetHeight,
|
||||||
settings.modelingSend,
|
settings.modelingSend,
|
||||||
setAppState,
|
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -112,29 +102,22 @@ export function useSetupEngineManager(
|
|||||||
streamRef?.current?.offsetHeight
|
streamRef?.current?.offsetHeight
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
streamDimensions.streamWidth !== width ||
|
settings.modelingContext.store.streamDimensions.streamWidth !== width ||
|
||||||
streamDimensions.streamHeight !== height
|
settings.modelingContext.store.streamDimensions.streamHeight !== height
|
||||||
) {
|
) {
|
||||||
engineCommandManager.handleResize({
|
engineCommandManager.handleResize({
|
||||||
streamWidth: width,
|
streamWidth: width,
|
||||||
streamHeight: height,
|
streamHeight: height,
|
||||||
})
|
})
|
||||||
setAppState({
|
settings.modelingSend({
|
||||||
streamDimensions: { streamWidth: width, streamHeight: height },
|
type: 'Set context',
|
||||||
|
data: {
|
||||||
|
streamDimensions: {
|
||||||
|
streamWidth: width,
|
||||||
|
streamHeight: height,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
sceneInfra._streamDimensions = {
|
|
||||||
streamWidth: width,
|
|
||||||
streamHeight: height,
|
|
||||||
}
|
|
||||||
// settings.modelingSend({
|
|
||||||
// type: 'Set context',
|
|
||||||
// data: {
|
|
||||||
// streamDimensions: {
|
|
||||||
// streamWidth: width,
|
|
||||||
// streamHeight: height,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
}, 500)
|
}, 500)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
UpdaterRestartModal,
|
UpdaterRestartModal,
|
||||||
createUpdaterRestartModal,
|
createUpdaterRestartModal,
|
||||||
} from 'components/UpdaterRestartModal'
|
} from 'components/UpdaterRestartModal'
|
||||||
|
import { AppStreamProvider } from 'AppState'
|
||||||
|
|
||||||
// uncomment for xstate inspector
|
// uncomment for xstate inspector
|
||||||
// import { DEV } from 'env'
|
// import { DEV } from 'env'
|
||||||
@ -26,28 +27,30 @@ const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
|
|||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<HotkeysProvider>
|
<HotkeysProvider>
|
||||||
<Router />
|
<AppStreamProvider>
|
||||||
<Toaster
|
<Router />
|
||||||
position="bottom-center"
|
<Toaster
|
||||||
toastOptions={{
|
position="bottom-center"
|
||||||
style: {
|
toastOptions={{
|
||||||
borderRadius: '3px',
|
style: {
|
||||||
},
|
borderRadius: '3px',
|
||||||
className:
|
|
||||||
'bg-chalkboard-10 dark:bg-chalkboard-90 text-chalkboard-110 dark:text-chalkboard-10 rounded-sm border-chalkboard-20/50 dark:border-chalkboard-80/50',
|
|
||||||
success: {
|
|
||||||
iconTheme: {
|
|
||||||
primary: 'oklch(89% 0.16 143.4deg)',
|
|
||||||
secondary: 'oklch(48.62% 0.1654 142.5deg)',
|
|
||||||
},
|
},
|
||||||
duration:
|
className:
|
||||||
window?.localStorage.getItem('playwright') === 'true'
|
'bg-chalkboard-10 dark:bg-chalkboard-90 text-chalkboard-110 dark:text-chalkboard-10 rounded-sm border-chalkboard-20/50 dark:border-chalkboard-80/50',
|
||||||
? 10 // speed up e2e tests
|
success: {
|
||||||
: 1500,
|
iconTheme: {
|
||||||
},
|
primary: 'oklch(89% 0.16 143.4deg)',
|
||||||
}}
|
secondary: 'oklch(48.62% 0.1654 142.5deg)',
|
||||||
/>
|
},
|
||||||
<ModalContainer />
|
duration:
|
||||||
|
window?.localStorage.getItem('playwright') === 'true'
|
||||||
|
? 10 // speed up e2e tests
|
||||||
|
: 1500,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ModalContainer />
|
||||||
|
</AppStreamProvider>
|
||||||
</HotkeysProvider>
|
</HotkeysProvider>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -138,7 +138,6 @@ export type SegmentOverlayPayload =
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Store {
|
interface Store {
|
||||||
mediaStream?: MediaStream
|
|
||||||
videoElement?: HTMLVideoElement
|
videoElement?: HTMLVideoElement
|
||||||
buttonDownInStream: number | undefined
|
buttonDownInStream: number | undefined
|
||||||
didDragInStream: boolean
|
didDragInStream: boolean
|
||||||
|
@ -8,11 +8,9 @@ import {
|
|||||||
} from 'lib/cameraControls'
|
} from 'lib/cameraControls'
|
||||||
import { SettingsSection } from 'components/Settings/SettingsSection'
|
import { SettingsSection } from 'components/Settings/SettingsSection'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function Units() {
|
export default function Units() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.STREAMING)
|
const next = useNextClick(onboardingPaths.STREAMING)
|
||||||
const {
|
const {
|
||||||
@ -31,7 +29,7 @@ export default function Units() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SettingsSection
|
<SettingsSection
|
||||||
|
@ -2,11 +2,9 @@ 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 { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function CmdK() {
|
export default function CmdK() {
|
||||||
// const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.USER_MENU)
|
const next = useNextClick(onboardingPaths.USER_MENU)
|
||||||
const platformName = usePlatform()
|
const platformName = usePlatform()
|
||||||
@ -16,7 +14,7 @@ export default function CmdK() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(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,12 +1,10 @@
|
|||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { OnboardingButtons, useDemoCode, useDismiss, useNextClick } from '.'
|
import { OnboardingButtons, useDemoCode, useDismiss, useNextClick } from '.'
|
||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function OnboardingCodeEditor() {
|
export default function OnboardingCodeEditor() {
|
||||||
useDemoCode()
|
useDemoCode()
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.PARAMETRIC_MODELING)
|
const next = useNextClick(onboardingPaths.PARAMETRIC_MODELING)
|
||||||
|
|
||||||
@ -15,7 +13,7 @@ export default function OnboardingCodeEditor() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto">
|
<section className="flex-1 overflow-y-auto">
|
||||||
|
@ -2,11 +2,9 @@ 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'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function Export() {
|
export default function Export() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.SKETCHING)
|
const next = useNextClick(onboardingPaths.SKETCHING)
|
||||||
|
|
||||||
@ -15,7 +13,7 @@ export default function Export() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1">
|
<section className="flex-1">
|
||||||
|
@ -8,12 +8,10 @@ import {
|
|||||||
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'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function OnboardingInteractiveNumbers() {
|
export default function OnboardingInteractiveNumbers() {
|
||||||
useDemoCode()
|
useDemoCode()
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.COMMAND_K)
|
const next = useNextClick(onboardingPaths.COMMAND_K)
|
||||||
|
|
||||||
@ -22,7 +20,7 @@ export default function OnboardingInteractiveNumbers() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto mb-6">
|
<section className="flex-1 overflow-y-auto mb-6">
|
||||||
|
@ -4,12 +4,10 @@ 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'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function OnboardingParametricModeling() {
|
export default function OnboardingParametricModeling() {
|
||||||
useDemoCode()
|
useDemoCode()
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const {
|
const {
|
||||||
settings: {
|
settings: {
|
||||||
context: {
|
context: {
|
||||||
@ -32,7 +30,7 @@ export default function OnboardingParametricModeling() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto mb-6">
|
<section className="flex-1 overflow-y-auto mb-6">
|
||||||
|
@ -2,11 +2,9 @@ import { OnboardingButtons, useDismiss, useNextClick } from '.'
|
|||||||
import { onboardingPaths } from 'routes/Onboarding/paths'
|
import { onboardingPaths } from 'routes/Onboarding/paths'
|
||||||
import { isTauri } from 'lib/isTauri'
|
import { isTauri } from 'lib/isTauri'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function ProjectMenu() {
|
export default function ProjectMenu() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.EXPORT)
|
const next = useNextClick(onboardingPaths.EXPORT)
|
||||||
const tauri = isTauri()
|
const tauri = isTauri()
|
||||||
@ -16,7 +14,7 @@ export default function ProjectMenu() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1">
|
<section className="flex-1">
|
||||||
|
@ -3,11 +3,9 @@ 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'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function Sketching() {
|
export default function Sketching() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.FUTURE_WORK)
|
const next = useNextClick(onboardingPaths.FUTURE_WORK)
|
||||||
|
|
||||||
@ -25,7 +23,7 @@ export default function Sketching() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<h1 className="text-2xl font-bold">Sketching</h1>
|
<h1 className="text-2xl font-bold">Sketching</h1>
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
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'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function Streaming() {
|
export default function Streaming() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.EDITOR)
|
const next = useNextClick(onboardingPaths.EDITOR)
|
||||||
|
|
||||||
@ -14,7 +12,7 @@ export default function Streaming() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1 overflow-y-auto">
|
<section className="flex-1 overflow-y-auto">
|
||||||
|
@ -3,11 +3,9 @@ import { onboardingPaths } from 'routes/Onboarding/paths'
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useModelingContext } from 'hooks/useModelingContext'
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
import { useAppState } from 'AppState'
|
|
||||||
|
|
||||||
export default function UserMenu() {
|
export default function UserMenu() {
|
||||||
const { context } = useModelingContext()
|
const { context } = useModelingContext()
|
||||||
const { buttonDownInStream } = useAppState()
|
|
||||||
const { auth } = useSettingsAuthContext()
|
const { auth } = useSettingsAuthContext()
|
||||||
const dismiss = useDismiss()
|
const dismiss = useDismiss()
|
||||||
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
const next = useNextClick(onboardingPaths.PROJECT_MENU)
|
||||||
@ -38,7 +36,7 @@ export default function UserMenu() {
|
|||||||
<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' +
|
'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' +
|
||||||
(buttonDownInStream ? '' : ' pointer-events-auto')
|
(context.store?.buttonDownInStream ? '' : ' pointer-events-auto')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<section className="flex-1">
|
<section className="flex-1">
|
||||||
|
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 333 KiB After Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |