diff --git a/app/gui2/src/components/GraphEditor.vue b/app/gui2/src/components/GraphEditor.vue index 51e577012c..ec9079f912 100644 --- a/app/gui2/src/components/GraphEditor.vue +++ b/app/gui2/src/components/GraphEditor.vue @@ -29,12 +29,12 @@ import { colorFromString } from '@/util/colors' import { Rect } from '@/util/data/rect' import { Vec2 } from '@/util/data/vec2' import * as set from 'lib0/set' +import { toast } from 'react-toastify' import type { ExprId, NodeMetadata } from 'shared/yjsModel' -import { computed, onMounted, onScopeDispose, ref, watch } from 'vue' -import { toast, type Id as ToastId } from 'vue3-toastify' +import { computed, onMounted, onScopeDispose, onUnmounted, ref, watch } from 'vue' +import { ProjectManagerEvents } from '../../../ide-desktop/lib/dashboard/src/authentication/src/dashboard/projectManager' import { type Usage } from './ComponentBrowser/input' -const STARTUP_TOAST_DELAY_MS = 100 const EXECUTION_MODES = ['design', 'live'] // Assumed size of a newly created node. This is used to place the component browser. const DEFAULT_NODE_SIZE = new Vec2(0, 24) @@ -52,18 +52,52 @@ const componentBrowserUsage = ref({ type: 'newNode' }) const suggestionDb = useSuggestionDbStore() const interaction = provideInteractionHandler() +/// === UI Messages and Errors === function initStartupToast() { let startupToast = toast.info('Initializing the project. This can take up to one minute.', { autoClose: false, }) - const removeToast = () => toast.remove(startupToast) + const removeToast = () => toast.dismiss(startupToast) projectStore.firstExecution.then(removeToast) onScopeDispose(removeToast) } +function initConnectionLostToast() { + let connectionLostToast = 'connectionLostToast' + document.addEventListener( + ProjectManagerEvents.loadingFailed, + () => { + toast.error('Lost connection to Language Server.', { + autoClose: false, + toastId: connectionLostToast, + }) + }, + { once: true }, + ) + onUnmounted(() => { + toast.dismiss(connectionLostToast) + }) +} + +projectStore.lsRpcConnection.then( + (ls) => { + ls.client.onError((err) => { + toast.error(`Language server error: ${err}`) + }) + }, + (err) => { + toast.error(`Connection to language server failed: ${err}`) + }, +) + +projectStore.executionContext.on('executionFailed', (err) => { + toast.error(`Execution Failed: ${err}`, {}) +}) + onMounted(() => { initStartupToast() + initConnectionLostToast() }) const nodeSelection = provideGraphSelection(graphNavigator, graphStore.nodeRects, { diff --git a/app/gui2/src/createApp.ts b/app/gui2/src/createApp.ts index 360e5f0077..ee4cc3279d 100644 --- a/app/gui2/src/createApp.ts +++ b/app/gui2/src/createApp.ts @@ -3,7 +3,6 @@ import '@/assets/main.css' import type { ApplicationConfig } from '@/util/config' import { createPinia } from 'pinia' import { createApp } from 'vue' -import Vue3Toastify, { type ToastContainerOptions } from 'vue3-toastify' export function mountProjectApp(rootProps: { config: ApplicationConfig @@ -13,13 +12,6 @@ export function mountProjectApp(rootProps: { }) { const app = createApp(App, rootProps) app.use(createPinia()) - app.use(Vue3Toastify, { - position: 'top-center', - theme: 'light', - closeOnClick: false, - draggable: false, - toastClassName: 'text-sm leading-170 bg-frame-selected rounded-2xl backdrop-blur-3xl', - } as ToastContainerOptions) app.mount('#app') return app } diff --git a/app/gui2/stories/GraphEditor.story.vue b/app/gui2/stories/GraphEditor.story.vue index e6ba30cb13..5dc8e7cc03 100644 --- a/app/gui2/stories/GraphEditor.story.vue +++ b/app/gui2/stories/GraphEditor.story.vue @@ -1,8 +1,11 @@