@ -31,6 +31,7 @@ import {
|
|||||||
} from './lib/tauriFS'
|
} from './lib/tauriFS'
|
||||||
import { metadata, type Metadata } from 'tauri-plugin-fs-extra-api'
|
import { metadata, type Metadata } from 'tauri-plugin-fs-extra-api'
|
||||||
import DownloadAppBanner from './components/DownloadAppBanner'
|
import DownloadAppBanner from './components/DownloadAppBanner'
|
||||||
|
import { WasmErrBanner } from './components/WasmErrBanner'
|
||||||
import { GlobalStateProvider } from './components/GlobalStateProvider'
|
import { GlobalStateProvider } from './components/GlobalStateProvider'
|
||||||
import {
|
import {
|
||||||
SETTINGS_PERSIST_KEY,
|
SETTINGS_PERSIST_KEY,
|
||||||
@ -150,6 +151,7 @@ const router = createBrowserRouter(
|
|||||||
<ModelingMachineProvider>
|
<ModelingMachineProvider>
|
||||||
<App />
|
<App />
|
||||||
</ModelingMachineProvider>
|
</ModelingMachineProvider>
|
||||||
|
<WasmErrBanner />
|
||||||
</KclContextProvider>
|
</KclContextProvider>
|
||||||
</FileMachineProvider>
|
</FileMachineProvider>
|
||||||
{!isTauri() && import.meta.env.PROD && <DownloadAppBanner />}
|
{!isTauri() && import.meta.env.PROD && <DownloadAppBanner />}
|
||||||
|
63
src/components/WasmErrBanner.tsx
Normal file
63
src/components/WasmErrBanner.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { Dialog } from '@headlessui/react'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { ActionButton } from './ActionButton'
|
||||||
|
import { faX } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { useKclContext } from 'lang/KclSinglton'
|
||||||
|
|
||||||
|
export function WasmErrBanner() {
|
||||||
|
const [isBannerDismissed, setBannerDismissed] = useState(false)
|
||||||
|
|
||||||
|
const { wasmInitFailed } = useKclContext()
|
||||||
|
|
||||||
|
if (!wasmInitFailed) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
className="fixed inset-0 top-auto z-50 bg-warn-20 text-warn-80 px-8 py-4"
|
||||||
|
open={!isBannerDismissed}
|
||||||
|
onClose={() => ({})}
|
||||||
|
>
|
||||||
|
<Dialog.Panel className="max-w-3xl mx-auto">
|
||||||
|
<div className="flex gap-2 justify-between items-start">
|
||||||
|
<h2 className="text-xl font-bold mb-4">
|
||||||
|
Problem with our WASM blob :(
|
||||||
|
</h2>
|
||||||
|
<ActionButton
|
||||||
|
Element="button"
|
||||||
|
onClick={() => setBannerDismissed(true)}
|
||||||
|
icon={{
|
||||||
|
icon: faX,
|
||||||
|
bgClassName:
|
||||||
|
'bg-warn-70 hover:bg-warn-80 dark:bg-warn-70 dark:hover:bg-warn-80',
|
||||||
|
iconClassName:
|
||||||
|
'text-warn-10 group-hover:text-warn-10 dark:text-warn-10 dark:group-hover:text-warn-10',
|
||||||
|
}}
|
||||||
|
className="!p-0 !bg-transparent !border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="https://webassembly.org/"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
className="text-warn-80 dark:text-warn-80 dark:hover:text-warn-70 underline"
|
||||||
|
>
|
||||||
|
WASM or web assembly
|
||||||
|
</a>{' '}
|
||||||
|
is core part of how our app works. It might because you OS is not
|
||||||
|
up-to-date. If you're able to update your OS to a later version, try
|
||||||
|
that. If not create an issue on{' '}
|
||||||
|
<a
|
||||||
|
href="https://github.com/KittyCAD/modeling-app"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
className="text-warn-80 dark:text-warn-80 dark:hover:text-warn-70 underline"
|
||||||
|
>
|
||||||
|
our Github
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</Dialog.Panel>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
@ -40,6 +40,7 @@ class KclManager {
|
|||||||
private _logs: string[] = []
|
private _logs: string[] = []
|
||||||
private _kclErrors: KCLError[] = []
|
private _kclErrors: KCLError[] = []
|
||||||
private _isExecuting = false
|
private _isExecuting = false
|
||||||
|
private _wasmInitFailed = true
|
||||||
|
|
||||||
engineCommandManager: EngineCommandManager
|
engineCommandManager: EngineCommandManager
|
||||||
private _defferer = deferExecution((code: string) => {
|
private _defferer = deferExecution((code: string) => {
|
||||||
@ -47,12 +48,13 @@ class KclManager {
|
|||||||
this.executeAst(ast)
|
this.executeAst(ast)
|
||||||
}, 600)
|
}, 600)
|
||||||
|
|
||||||
private _isExecutingCallback: (a: boolean) => void = () => {}
|
private _isExecutingCallback: (arg: boolean) => void = () => {}
|
||||||
private _codeCallBack: (arg: string) => void = () => {}
|
private _codeCallBack: (arg: string) => void = () => {}
|
||||||
private _astCallBack: (arg: Program) => void = () => {}
|
private _astCallBack: (arg: Program) => void = () => {}
|
||||||
private _programMemoryCallBack: (arg: ProgramMemory) => void = () => {}
|
private _programMemoryCallBack: (arg: ProgramMemory) => void = () => {}
|
||||||
private _logsCallBack: (arg: string[]) => void = () => {}
|
private _logsCallBack: (arg: string[]) => void = () => {}
|
||||||
private _kclErrorsCallBack: (arg: KCLError[]) => void = () => {}
|
private _kclErrorsCallBack: (arg: KCLError[]) => void = () => {}
|
||||||
|
private _wasmInitFailedCallback: (arg: boolean) => void = () => {}
|
||||||
|
|
||||||
get ast() {
|
get ast() {
|
||||||
return this._ast
|
return this._ast
|
||||||
@ -106,6 +108,14 @@ class KclManager {
|
|||||||
this._isExecutingCallback(isExecuting)
|
this._isExecutingCallback(isExecuting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get wasmInitFailed() {
|
||||||
|
return this._wasmInitFailed
|
||||||
|
}
|
||||||
|
set wasmInitFailed(wasmInitFailed) {
|
||||||
|
this._wasmInitFailed = wasmInitFailed
|
||||||
|
this._wasmInitFailedCallback(wasmInitFailed)
|
||||||
|
}
|
||||||
|
|
||||||
constructor(engineCommandManager: EngineCommandManager) {
|
constructor(engineCommandManager: EngineCommandManager) {
|
||||||
this.engineCommandManager = engineCommandManager
|
this.engineCommandManager = engineCommandManager
|
||||||
const storedCode = localStorage.getItem(PERSIST_CODE_TOKEN)
|
const storedCode = localStorage.getItem(PERSIST_CODE_TOKEN)
|
||||||
@ -131,6 +141,7 @@ class KclManager {
|
|||||||
setLogs,
|
setLogs,
|
||||||
setKclErrors,
|
setKclErrors,
|
||||||
setIsExecuting,
|
setIsExecuting,
|
||||||
|
setWasmInitFailed,
|
||||||
}: {
|
}: {
|
||||||
setCode: (arg: string) => void
|
setCode: (arg: string) => void
|
||||||
setProgramMemory: (arg: ProgramMemory) => void
|
setProgramMemory: (arg: ProgramMemory) => void
|
||||||
@ -138,6 +149,7 @@ class KclManager {
|
|||||||
setLogs: (arg: string[]) => void
|
setLogs: (arg: string[]) => void
|
||||||
setKclErrors: (arg: KCLError[]) => void
|
setKclErrors: (arg: KCLError[]) => void
|
||||||
setIsExecuting: (arg: boolean) => void
|
setIsExecuting: (arg: boolean) => void
|
||||||
|
setWasmInitFailed: (arg: boolean) => void
|
||||||
}) {
|
}) {
|
||||||
this._codeCallBack = setCode
|
this._codeCallBack = setCode
|
||||||
this._programMemoryCallBack = setProgramMemory
|
this._programMemoryCallBack = setProgramMemory
|
||||||
@ -145,11 +157,23 @@ class KclManager {
|
|||||||
this._logsCallBack = setLogs
|
this._logsCallBack = setLogs
|
||||||
this._kclErrorsCallBack = setKclErrors
|
this._kclErrorsCallBack = setKclErrors
|
||||||
this._isExecutingCallback = setIsExecuting
|
this._isExecutingCallback = setIsExecuting
|
||||||
|
this._wasmInitFailedCallback = setWasmInitFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
async ensureWasmInit() {
|
||||||
|
try {
|
||||||
|
await initPromise
|
||||||
|
if (this.wasmInitFailed) {
|
||||||
|
this.wasmInitFailed = false
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.wasmInitFailed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async executeAst(ast: Program = this._ast, updateCode = false) {
|
async executeAst(ast: Program = this._ast, updateCode = false) {
|
||||||
|
await this.ensureWasmInit()
|
||||||
this.isExecuting = true
|
this.isExecuting = true
|
||||||
await initPromise
|
|
||||||
const { logs, errors, programMemory } = await executeAst({
|
const { logs, errors, programMemory } = await executeAst({
|
||||||
ast,
|
ast,
|
||||||
engineCommandManager: this.engineCommandManager,
|
engineCommandManager: this.engineCommandManager,
|
||||||
@ -166,7 +190,7 @@ class KclManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
async executeAstMock(ast: Program = this._ast, updateCode = false) {
|
async executeAstMock(ast: Program = this._ast, updateCode = false) {
|
||||||
await initPromise
|
await this.ensureWasmInit()
|
||||||
const newCode = recast(ast)
|
const newCode = recast(ast)
|
||||||
const newAst = parse(newCode)
|
const newAst = parse(newCode)
|
||||||
await this?.engineCommandManager?.waitForReady
|
await this?.engineCommandManager?.waitForReady
|
||||||
@ -186,7 +210,7 @@ class KclManager {
|
|||||||
this._programMemory = programMemory
|
this._programMemory = programMemory
|
||||||
}
|
}
|
||||||
async executeCode(code?: string) {
|
async executeCode(code?: string) {
|
||||||
await initPromise
|
await this.ensureWasmInit()
|
||||||
await this?.engineCommandManager?.waitForReady
|
await this?.engineCommandManager?.waitForReady
|
||||||
if (!this?.engineCommandManager?.planesInitialized()) return
|
if (!this?.engineCommandManager?.planesInitialized()) return
|
||||||
const result = await executeCode({
|
const result = await executeCode({
|
||||||
@ -306,6 +330,7 @@ const KclContext = createContext({
|
|||||||
isExecuting: kclManager.isExecuting,
|
isExecuting: kclManager.isExecuting,
|
||||||
errors: kclManager.kclErrors,
|
errors: kclManager.kclErrors,
|
||||||
logs: kclManager.logs,
|
logs: kclManager.logs,
|
||||||
|
wasmInitFailed: kclManager.wasmInitFailed,
|
||||||
})
|
})
|
||||||
|
|
||||||
export function useKclContext() {
|
export function useKclContext() {
|
||||||
@ -326,6 +351,7 @@ export function KclContextProvider({
|
|||||||
const [isExecuting, setIsExecuting] = useState(false)
|
const [isExecuting, setIsExecuting] = useState(false)
|
||||||
const [errors, setErrors] = useState<KCLError[]>([])
|
const [errors, setErrors] = useState<KCLError[]>([])
|
||||||
const [logs, setLogs] = useState<string[]>([])
|
const [logs, setLogs] = useState<string[]>([])
|
||||||
|
const [wasmInitFailed, setWasmInitFailed] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
kclManager.registerCallBacks({
|
kclManager.registerCallBacks({
|
||||||
@ -335,6 +361,7 @@ export function KclContextProvider({
|
|||||||
setLogs,
|
setLogs,
|
||||||
setKclErrors: setErrors,
|
setKclErrors: setErrors,
|
||||||
setIsExecuting,
|
setIsExecuting,
|
||||||
|
setWasmInitFailed,
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
return (
|
return (
|
||||||
@ -346,6 +373,7 @@ export function KclContextProvider({
|
|||||||
isExecuting,
|
isExecuting,
|
||||||
errors,
|
errors,
|
||||||
logs,
|
logs,
|
||||||
|
wasmInitFailed,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
Reference in New Issue
Block a user