Skip to content

Commit

Permalink
#723: Right-click to add to AI chat + Hotkey for adding to chat (#855)
Browse files Browse the repository at this point in the history
* Right-click to add to AI chat + Hotkey for adding to chat

---------

Co-authored-by: Raghav Yadlapalli <[email protected]>
  • Loading branch information
RaghavGanesh7 and Raghav Yadlapalli authored Dec 7, 2024
1 parent 2e40d6a commit 9d820dc
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 24 deletions.
2 changes: 2 additions & 0 deletions apps/studio/common/hotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export class Hotkey {
static readonly UNGROUP = new Hotkey('mod+shift+g', 'Ungroup');
static readonly REFRESH_LAYERS = new Hotkey('mod+l', 'Refresh Layers');
static readonly OPEN_DEV_TOOL = new Hotkey('mod+shift+i', 'Open Devtool');
static readonly ADD_AI_CHAT = new Hotkey('mod+shift+l', 'Add to AI chat');
static readonly NEW_AI_CHAT = new Hotkey('mod+l', 'New AI Chat');

// Text
static readonly INSERT_TEXT = new Hotkey('t', 'Insert Text');
Expand Down
11 changes: 9 additions & 2 deletions apps/studio/src/lib/editor/engine/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EditorMode } from '@/lib/models';
import { EditorMode, EditorTabValue } from '@/lib/models';
import type { ProjectsManager } from '@/lib/projects';
import { invokeMainChannel } from '@/lib/utils';
import { MainChannels } from '@onlook/models/constants';
Expand All @@ -23,6 +23,7 @@ import { WebviewManager } from './webview';

export class EditorEngine {
private editorMode: EditorMode = EditorMode.DESIGN;
private editorPanelTab: EditorTabValue = EditorTabValue.STYLES;
private canvasManager: CanvasManager;
private chatManager: ChatManager;
private webviewManager: WebviewManager;
Expand Down Expand Up @@ -98,11 +99,17 @@ export class EditorEngine {
get chat() {
return this.chatManager;
}

get editPanelTab() {
return this.editorPanelTab;
}
set mode(mode: EditorMode) {
this.editorMode = mode;
}

set editPanelTab(tab: EditorTabValue) {
this.editorPanelTab = tab;
}

dispose() {
this.clear();
this.webviews.deregisterAll();
Expand Down
5 changes: 5 additions & 0 deletions apps/studio/src/lib/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ export enum EditorMode {
INSERT_TEXT = 'insert-text',
INSERT_DIV = 'insert-div',
}

export enum EditorTabValue {
STYLES = 'styles',
CHAT = 'chat',
}
39 changes: 21 additions & 18 deletions apps/studio/src/routes/editor/EditPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import { Separator } from '@onlook/ui/separator';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@onlook/ui/tabs';
import { cn } from '@onlook/ui/utils';
import { observer } from 'mobx-react-lite';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import ChatTab from './ChatTab';
import ChatControls from './ChatTab/ChatControls';
import ManualTab from './StylesTab';

enum TabValue {
STYLES = 'styles',
CHAT = 'chat',
}
import { EditorTabValue } from '@/lib/models';

const EditPanel = observer(() => {
const editorEngine = useEditorEngine();
const [isOpen, setIsOpen] = useState(true);
const [selectedTab, setSelectedTab] = useState(TabValue.STYLES);
const [selectedTab, setSelectedTab] = useState<EditorTabValue>(editorEngine.editPanelTab);

useEffect(() => {
tabChange(editorEngine.editPanelTab);
}, [editorEngine.editPanelTab]);

function renderEmptyState() {
return (
Expand All @@ -28,12 +28,15 @@ const EditPanel = observer(() => {
);
}

function tabChange(value: EditorTabValue) {
editorEngine.editPanelTab = value;
setSelectedTab(value);
setIsOpen(true);
}

function renderTabs() {
return (
<Tabs
defaultValue={selectedTab}
onValueChange={(value: string) => setSelectedTab(value as TabValue)}
>
<Tabs onValueChange={(value) => tabChange(value as EditorTabValue)} value={selectedTab}>
<TabsList className="bg-transparent w-full gap-2 select-none justify-between items-center h-full px-2">
<div className="flex flex-row items-center gap-2">
<button
Expand All @@ -44,30 +47,30 @@ const EditPanel = observer(() => {
</button>
<TabsTrigger
className="bg-transparent py-2 px-1 text-xs hover:text-foreground-hover"
value={TabValue.STYLES}
value={EditorTabValue.STYLES}
>
Styles
</TabsTrigger>
<TabsTrigger
className="bg-transparent py-2 px-1 text-xs hover:text-foreground-hover"
value={TabValue.CHAT}
value={EditorTabValue.CHAT}
>
<Icons.MagicWand className="mr-2" />
{'Chat (beta)'}
</TabsTrigger>
</div>
{selectedTab === TabValue.CHAT && <ChatControls />}
{selectedTab === EditorTabValue.CHAT && <ChatControls />}
</TabsList>
<Separator />
<div className="h-[calc(100vh-7.75rem)] overflow-auto">
<TabsContent value={TabValue.STYLES}>
<TabsContent value={EditorTabValue.STYLES}>
{editorEngine.elements.selected.length > 0 ? (
<ManualTab />
) : (
renderEmptyState()
)}
</TabsContent>
<TabsContent value={TabValue.CHAT}>
<TabsContent value={EditorTabValue.CHAT}>
<ChatTab />
</TabsContent>
</div>
Expand All @@ -83,8 +86,8 @@ const EditPanel = observer(() => {
editorEngine.mode === EditorMode.INTERACT ? 'hidden' : 'visible',
!isOpen && 'w-10 h-10 rounded-l-xl cursor-pointer',
isOpen && 'h-[calc(100vh-5rem)]',
isOpen && selectedTab == TabValue.STYLES && 'w-60',
isOpen && selectedTab == TabValue.CHAT && 'w-[22rem]',
isOpen && selectedTab == EditorTabValue.STYLES && 'w-60',
isOpen && selectedTab == EditorTabValue.CHAT && 'w-[22rem]',
)}
>
{!isOpen && (
Expand Down
19 changes: 15 additions & 4 deletions apps/studio/src/routes/editor/RightClickMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEditorEngine } from '@/components/Context';
import { EditorTabValue } from '@/lib/models';
import type { DomElement } from '@onlook/models/element';
import {
ContextMenu,
Expand Down Expand Up @@ -46,12 +47,22 @@ export const RightClickMenu = observer(({ children }: RightClickMenuProps) => {
hotkey: Hotkey.OPEN_DEV_TOOL,
},
{
label: 'Refresh layers',
label: 'Add to AI Chat',
action: () => {
editorEngine.refreshLayers();
editorEngine.editPanelTab = EditorTabValue.CHAT;
},
icon: <Icons.Reload className="mr-2 h-4 w-4" />,
hotkey: Hotkey.REFRESH_LAYERS,
icon: <Icons.MagicWand className="mr-2 h-4 w-4" />,
hotkey: Hotkey.ADD_AI_CHAT,
disabled: !editorEngine.elements.selected.length,
},
{
label: 'New AI Chat',
action: () => {
editorEngine.editPanelTab = EditorTabValue.CHAT;
editorEngine.chat.startNewConversation();
},
icon: <Icons.MagicWand className="mr-2 h-4 w-4" />,
hotkey: Hotkey.NEW_AI_CHAT,
},
];

Expand Down

0 comments on commit 9d820dc

Please sign in to comment.