diff --git a/src/lib/components/studio/chatWrapper.svelte b/src/lib/components/studio/chatWrapper.svelte new file mode 100644 index 000000000..93ffcf5be --- /dev/null +++ b/src/lib/components/studio/chatWrapper.svelte @@ -0,0 +1,196 @@ + + + + +{#if !$isSmallViewport && ($showChat || isResizing)} + +{/if} + + diff --git a/src/lib/layout/shellStudio.svelte b/src/lib/layout/shellStudio.svelte index e1c910c7a..cace4256f 100644 --- a/src/lib/layout/shellStudio.svelte +++ b/src/lib/layout/shellStudio.svelte @@ -16,11 +16,11 @@ import { user } from '$lib/stores/user'; import SidebarProject from '$lib/components/studio/sidebarProject.svelte'; import SidebarOrganization from '$lib/components/studio/sidebarOrganization.svelte'; + import ChatWrapper from '$lib/components/studio/chatWrapper.svelte'; import { BillingPlan } from '$lib/constants.js'; import { isCloud } from '$lib/system.js'; import { tierToPlan } from '$lib/stores/billing.js'; import type { NavbarProject } from '$lib/components/navbar.svelte'; - import Chat from '$lib/components/studio/chat/chat.svelte'; import { IconChevronRight, IconLogoutRight, @@ -35,18 +35,7 @@ import { logout } from '$lib/helpers/logout'; import { Click, trackEvent } from '$lib/actions/analytics'; import { conversation, showChat } from '$lib/stores/chat'; - import { createStreamParser } from '$lib/components/studio/chat/parser'; import { type Snippet } from 'svelte'; - import { sdk } from '$lib/stores/sdk'; - import { filesystem } from '$lib/components/editor/filesystem'; - import { previewFrameRef } from '$routes/(console)/project-[project]/store'; - import { - disableBodySelect, - enabledBodySelect, - getChatWidthFromPrefs, - saveChatWidthToPrefs - } from '$lib/helpers/studioLayout'; - import { synapse } from '$lib/components/studio/synapse.svelte'; let hasProjectSidebar = $state(false); @@ -114,141 +103,6 @@ }; }); }); - - $effect(() => { - if ($isSmallViewport || page.params.artifact) { - showChat.set(true); - } - if (!page.params.artifact) { - showChat.set(false); - } - }); - - let resizer = $state(null); - let resizerLeftPosition = $state( - page.data?.subNavigation ? getChatWidthFromPrefs() + 24 : getChatWidthFromPrefs() - ); - let resizerLeftOffset = $state(page.data?.subNavigation ? 52 : 9); - let chatWidth = $derived(resizerLeftPosition - resizerLeftOffset); - - $effect(() => { - chatWidth = resizerLeftPosition - resizerLeftOffset; - }); - - let isResizing = false; - - function startResize() { - isResizing = true; - window.addEventListener('mousemove', resize); - window.addEventListener('mouseup', stopResize); - window.addEventListener('touchmove', resize); - window.addEventListener('touchend', stopResize); - disableBodySelect(); - - if ($previewFrameRef) { - $previewFrameRef.style.pointerEvents = 'none'; - } - } - - function resize(event: TouchEvent | MouseEvent) { - if (!isResizing) return; - if (resizer) { - resizerLeftPosition = - ('touches' in event ? event.touches[0].clientX : event.clientX) - 60; - const maxSize = page.data?.subNavigation - ? window.innerWidth - 660 - : window.innerWidth - 540; - - const minSize = 320; - if (resizerLeftPosition > maxSize) { - resizerLeftPosition = maxSize; - } else if (resizerLeftPosition < minSize) { - if (resizerLeftPosition < minSize - 100) { - showChat.set(false); - } - - resizerLeftPosition = minSize; - } else if (resizerLeftPosition > minSize && !$showChat) { - showChat.set(true); - } - } - } - - function stopResize() { - if (!$showChat) { - resizerLeftPosition = 500; - } - const saveWidth = page.data?.subNavigation ? resizerLeftPosition - 24 : resizerLeftPosition; - saveChatWidthToPrefs(saveWidth); - - isResizing = false; - window.removeEventListener('mousemove', resize); - window.removeEventListener('mouseup', stopResize); - window.removeEventListener('touchmove', resize); - window.removeEventListener('touchend', stopResize); - enabledBodySelect(); - - if ($previewFrameRef) { - $previewFrameRef.style.pointerEvents = ''; - } - } - - const parser = createStreamParser(); - - async function getConversation(artifactId: string) { - parser.reset(); - const { conversations } = await sdk.forProject.imagine.listConversations(artifactId); - if (conversations.length === 0) { - const convo = sdk.forProject.imagine.createConversation( - artifactId, - `Conversation ${new Date().getTime()}` - ); - conversation.set(convo); - } else { - conversation.set(conversations[0]); - } - } - - $effect(() => { - if (page.params.artifact && $conversation.data?.artifactId !== page.params.artifact) { - getConversation(page.params.artifact); - } - }); - - conversation.subscribe(async (convo) => { - if (!convo.data) return; - const { messages } = await sdk.forProject.imagine.listMessages( - convo.data.artifactId, - convo.data.$id - ); - const text = messages.reduce((curr, next) => { - return curr + next.content; - }, ''); - parser.init(text); - }); - - parser.on('complete', async (action) => { - switch (action.type) { - case 'file': - await synapse.dispatch('fs', { - operation: 'updateFile', - params: { - filepath: action.src, - content: action.content - } - }); - $filesystem = [...$filesystem, action.src]; - break; - case 'shell': - synapse.dispatch('terminal', { - operation: 'createCommand', - params: { - command: action.content + '\n' - } - }); - break; - } - });
@@ -370,9 +224,10 @@ class:project-sidebar={hasProjectSidebar} class:sub-navigation={page.data.subNavigation}> {#if $isSmallViewport} - {#if hasProjectSidebar} - + {#if isOnEditorPage} + {/if} + {#if page.data?.subNavigation} @@ -386,19 +241,8 @@
- {#if hasProjectSidebar} - - {#if $showChat || isResizing} - - {/if} + {#if isOnEditorPage} + {/if} {@const Header = page.data.header} @@ -551,33 +395,6 @@ } } - .resizer { - width: 16px; - cursor: col-resize; - margin-inline: 10px; - position: absolute; - height: calc(100vh - 72px); - margin-block-start: calc(-1 * var(--base-8)); - margin-inline-start: 0; - - &::after { - content: ''; - cursor: col-resize; - position: absolute; - height: 100%; - width: 1px; - margin-left: -1px; - left: 8px; - background-color: var(--border-neutral); - opacity: 1; - transition: all 0.3s ease-in-out; - } - - &:hover::after { - width: 2px; - background-color: var(--border-neutral-strong); - } - } .hidden { opacity: 0; }