diff --git a/README.md b/README.md index 51264377d..44852f615 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ https://thinktank.ottomator.ai - ✅ Better prompt enhancing (@SujalXplores) - ✅ Attach images to prompts (@atrokhym) - ✅ Detect package.json and commands to auto install and run preview for folder and git import (@wonderwhy-er) +- ✅ Selection tool to target changes visually (@emcconnell) - ⬜ **HIGH PRIORITY** - Prevent Bolt from rewriting files as often (file locking and diffs) - ⬜ **HIGH PRIORITY** - Better prompting for smaller LLMs (code window sometimes doesn't start) - ⬜ **HIGH PRIORITY** - Run agents in the backend as opposed to a single model call diff --git a/app/commit.json b/app/commit.json index ff64112c7..1636c99bd 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "9666b2ab67d25345542722ab9d870b36ad06252e" } +{ "commit": "ece0213500a94a6b29e29512c5040baf57884014" } diff --git a/app/components/chat/BaseChat.tsx b/app/components/chat/BaseChat.tsx index 13382baa1..09f3c1681 100644 --- a/app/components/chat/BaseChat.tsx +++ b/app/components/chat/BaseChat.tsx @@ -26,6 +26,7 @@ import FilePreview from './FilePreview'; import { ModelSelector } from '~/components/chat/ModelSelector'; import { SpeechRecognitionButton } from '~/components/chat/SpeechRecognition'; import type { IProviderSetting, ProviderInfo } from '~/types/model'; +import { ScreenshotStateManager } from './ScreenshotStateManager'; const TEXTAREA_MIN_HEIGHT = 76; @@ -376,6 +377,16 @@ export const BaseChat = React.forwardRef( setImageDataList?.(imageDataList.filter((_, i) => i !== index)); }} /> + + {() => ( + + )} +
( return; } + // ignore if using input method engine + if (event.nativeEvent.isComposing) { + return; + } + handleSendMessage?.(event); } }} diff --git a/app/components/chat/ScreenshotStateManager.tsx b/app/components/chat/ScreenshotStateManager.tsx new file mode 100644 index 000000000..7dfdd7683 --- /dev/null +++ b/app/components/chat/ScreenshotStateManager.tsx @@ -0,0 +1,33 @@ +import { useEffect } from 'react'; + +interface ScreenshotStateManagerProps { + setUploadedFiles?: (files: File[]) => void; + setImageDataList?: (dataList: string[]) => void; + uploadedFiles: File[]; + imageDataList: string[]; +} + +export const ScreenshotStateManager = ({ + setUploadedFiles, + setImageDataList, + uploadedFiles, + imageDataList, +}: ScreenshotStateManagerProps) => { + useEffect(() => { + if (setUploadedFiles && setImageDataList) { + (window as any).__BOLT_SET_UPLOADED_FILES__ = setUploadedFiles; + (window as any).__BOLT_SET_IMAGE_DATA_LIST__ = setImageDataList; + (window as any).__BOLT_UPLOADED_FILES__ = uploadedFiles; + (window as any).__BOLT_IMAGE_DATA_LIST__ = imageDataList; + } + + return () => { + delete (window as any).__BOLT_SET_UPLOADED_FILES__; + delete (window as any).__BOLT_SET_IMAGE_DATA_LIST__; + delete (window as any).__BOLT_UPLOADED_FILES__; + delete (window as any).__BOLT_IMAGE_DATA_LIST__; + }; + }, [setUploadedFiles, setImageDataList, uploadedFiles, imageDataList]); + + return null; +}; diff --git a/app/components/settings/connections/ConnectionsTab.tsx b/app/components/settings/connections/ConnectionsTab.tsx index 8338395f0..4fe43d96e 100644 --- a/app/components/settings/connections/ConnectionsTab.tsx +++ b/app/components/settings/connections/ConnectionsTab.tsx @@ -15,6 +15,7 @@ export default function ConnectionsTab() { hasToken: !!githubToken, }); toast.success('GitHub credentials saved successfully!'); + Cookies.set('git:github.com', JSON.stringify({ username: githubToken, password: 'x-oauth-basic' })); }; return ( diff --git a/app/components/workbench/Preview.tsx b/app/components/workbench/Preview.tsx index 8235bc2b5..b2d97e314 100644 --- a/app/components/workbench/Preview.tsx +++ b/app/components/workbench/Preview.tsx @@ -3,6 +3,7 @@ import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { IconButton } from '~/components/ui/IconButton'; import { workbenchStore } from '~/lib/stores/workbench'; import { PortDropdown } from './PortDropdown'; +import { ScreenshotSelector } from './ScreenshotSelector'; type ResizeSide = 'left' | 'right' | null; @@ -20,6 +21,7 @@ export const Preview = memo(() => { const [url, setUrl] = useState(''); const [iframeUrl, setIframeUrl] = useState(); + const [isSelectionMode, setIsSelectionMode] = useState(false); // Toggle between responsive mode and device mode const [isDeviceModeOn, setIsDeviceModeOn] = useState(false); @@ -218,12 +220,17 @@ export const Preview = memo(() => { )}
- + setIsSelectionMode(!isSelectionMode)} + className={isSelectionMode ? 'bg-bolt-elements-background-depth-3' : ''} + />
{ }} > {activePreview ? ( -