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;
}