prepare edit button

This commit is contained in:
Mathew Pareles 2025-01-13 03:23:38 -08:00
parent 7dd5171bd2
commit 261736bde5
2 changed files with 73 additions and 28 deletions

View file

@ -28,6 +28,7 @@ import { useScrollbarStyles } from '../util/useScrollbarStyles.js';
import { VOID_CTRL_L_ACTION_ID } from '../../../actionIDs.js'; import { VOID_CTRL_L_ACTION_ID } from '../../../actionIDs.js';
import { ArrowBigLeftDash, CopyX, Delete, FileX2, SquareX, X } from 'lucide-react'; import { ArrowBigLeftDash, CopyX, Delete, FileX2, SquareX, X } from 'lucide-react';
import { filenameToVscodeLanguage } from '../../../helpers/detectLanguage.js'; import { filenameToVscodeLanguage } from '../../../helpers/detectLanguage.js';
import { Pencil } from 'lucide-react'
export const IconX = ({ size, className = '', ...props }: { size: number, className?: string } & React.SVGProps<SVGSVGElement>) => { export const IconX = ({ size, className = '', ...props }: { size: number, className?: string } & React.SVGProps<SVGSVGElement>) => {
@ -332,7 +333,7 @@ export const SelectedFiles = (
{/* X button */} {/* X button */}
{type === 'staging' && {type === 'staging' &&
<span <span
className='cursor-pointer hover:bg-vscode-toolbar-hover-bg rounded-md z-1' className='cursor-pointer hover:brightness-95 rounded-md z-1'
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); // don't open/close selection e.stopPropagation(); // don't open/close selection
if (type !== 'staging') return; if (type !== 'staging') return;
@ -346,7 +347,7 @@ export const SelectedFiles = (
</div> </div>
{/* delete all selections button */} {/* clear all selections button */}
{type !== 'staging' || selections.length === 0 || i !== selections.length - 1 {type !== 'staging' || selections.length === 0 || i !== selections.length - 1
? null ? null
: <div key={i} className={`flex items-center gap-0.5 ${isThisSelectionOpened ? 'w-full' : ''}`}> : <div key={i} className={`flex items-center gap-0.5 ${isThisSelectionOpened ? 'w-full' : ''}`}>
@ -357,10 +358,14 @@ export const SelectedFiles = (
> >
<Delete <Delete
size={16} size={16}
className='stroke-[1] stroke-void-fg-3 className={`stroke-[1]
fill-void-bg-3 stroke-void-fg-1
hover:brightness-105 fill-void-bg-3
cursor-pointer' opacity-40
hover:opacity-60
transition-all duration-150
cursor-pointer
`}
onClick={() => { setStaging([]) }} onClick={() => { setStaging([]) }}
/> />
</div> </div>
@ -381,7 +386,8 @@ export const SelectedFiles = (
maxHeight={100} maxHeight={100}
showScrollbars={true} showScrollbars={true}
/> />
</div>} </div>
}
</div> </div>
})} })}
@ -393,6 +399,7 @@ export const SelectedFiles = (
} }
const ChatBubble = ({ chatMessage, isLoading }: { const ChatBubble = ({ chatMessage, isLoading }: {
chatMessage: ChatMessage, chatMessage: ChatMessage,
isLoading?: boolean, isLoading?: boolean,
@ -400,6 +407,9 @@ const ChatBubble = ({ chatMessage, isLoading }: {
const role = chatMessage.role const role = chatMessage.role
// edit mode state
const [isEditMode, setIsEditMode] = useState(false)
if (!chatMessage.displayContent) if (!chatMessage.displayContent)
return null return null
@ -409,30 +419,61 @@ const ChatBubble = ({ chatMessage, isLoading }: {
chatbubbleContents = <> chatbubbleContents = <>
<SelectedFiles type='past' selections={chatMessage.selections} /> <SelectedFiles type='past' selections={chatMessage.selections} />
{chatMessage.displayContent} {chatMessage.displayContent}
{/* {!isEditMode ? chatMessage.displayContent : <></>} */}
{/* edit mode content */}
{/* TODO this should be the same input box as in the Sidebar */}
{/* <textarea
value={editModeText}
className={`
w-full max-w-full
h-auto min-h-[81px] max-h-[500px]
bg-void-bg-1 resize-none
`}
style={{ marginTop: 0 }}
hidden={!isEditMode}
/> */}
</> </>
} }
else if (role === 'assistant') { else if (role === 'assistant') {
chatbubbleContents = <ChatMarkdownRender string={chatMessage.displayContent} /> // sectionsHTML chatbubbleContents = <ChatMarkdownRender string={chatMessage.displayContent} />
} }
return <div return <div
// align chatbubble accoridng to role // align chatbubble accoridng to role
className={` className={`
${role === 'user' ? `px-2 self-end w-fit max-w-full` : ''} relative
${role === 'assistant' ? `px-2 self-start w-full max-w-full` : ''} ${isEditMode ? 'px-2 w-full max-w-full'
`} : role === 'user' ? `px-2 self-end w-fit max-w-full`
: role === 'assistant' ? `px-2 self-start w-full max-w-full` : ''
}
`}
> >
<div <div
// style chatbubble according to role // style chatbubble according to role
className={` className={`
p-2 text-left space-y-2 rounded-lg p-2 text-left space-y-2 rounded-lg
overflow-x-auto max-w-full overflow-x-auto max-w-full
${role === 'user' ? 'bg-vscode-input-bg text-vscode-input-fg' : ''} ${role === 'user' ? 'bg-void-bg-1 text-void-fg-1' : ''}
`} `}
> >
{chatbubbleContents} {chatbubbleContents}
{isLoading && <IconLoading className='opacity-50 text-sm' />} {isLoading && <IconLoading className='opacity-50 text-sm' />}
</div> </div>
{/* edit button */}
{/* {role === 'user' &&
<Pencil
size={16}
className={`
absolute top-0 right-2
translate-x-0 -translate-y-0
cursor-pointer z-1
`}
onClick={() => { setIsEditMode(v => !v); }}
/>
} */}
</div> </div>
} }
@ -610,7 +651,7 @@ export const SidebarChat = () => {
> >
{/* thread selector */} {/* thread selector */}
<div ref={historyRef} <div ref={historyRef}
className={`w-full h-auto mb-2 ${isHistoryOpen ? '' : 'hidden'} ring-2 ring-widget-shadow ring-inset z-10`} className={`w-full h-auto ${isHistoryOpen ? '' : 'hidden'} ring-2 ring-widget-shadow ring-inset z-10`}
> >
<SidebarThreadSelector /> <SidebarThreadSelector />
</div> </div>
@ -623,6 +664,7 @@ export const SidebarChat = () => {
flex flex-col gap-0 flex flex-col gap-0
overflow-x-hidden overflow-x-hidden
overflow-y-auto overflow-y-auto
${previousMessages.length > 0 ? 'pt-2' : ''}
`} `}
style={{ maxHeight: sidebarDimensions.height - historyDimensions.height - formDimensions.height - 30 }} // the height of the previousMessages is determined by all other heights style={{ maxHeight: sidebarDimensions.height - historyDimensions.height - formDimensions.height - 30 }} // the height of the previousMessages is determined by all other heights
> >

View file

@ -51,9 +51,8 @@ export const SidebarThreadSelector = () => {
</div> </div>
{/* a list of all the past threads */} {/* a list of all the past threads */}
<div className="px-1">
<div className="px-1 "> <ul className="flex flex-col gap-y-0.5 overflow-y-auto list-disc">
<ul className="flex flex-col gap-y-1 overflow-y-auto list-disc">
{sortedThreadIds.length === 0 {sortedThreadIds.length === 0
@ -66,25 +65,26 @@ export const SidebarThreadSelector = () => {
const pastThread = allThreads[threadId]; const pastThread = allThreads[threadId];
let firstMsg = null; let firstMsg = null;
let secondMsg = null; // let secondMsg = null;
const firstMsgIdx = pastThread.messages.findIndex( const firstMsgIdx = pastThread.messages.findIndex(
(msg) => msg.role !== 'system' && !!msg.displayContent (msg) => msg.role !== 'system' && !!msg.displayContent
); );
if (firstMsgIdx !== -1) { if (firstMsgIdx !== -1) {
firstMsg = truncate(pastThread.messages[firstMsgIdx].displayContent ?? ''); // firstMsg = truncate(pastThread.messages[firstMsgIdx].displayContent ?? '');
firstMsg = pastThread.messages[firstMsgIdx].displayContent ?? '';
} else { } else {
firstMsg = '""'; firstMsg = '""';
} }
const secondMsgIdx = pastThread.messages.findIndex( // const secondMsgIdx = pastThread.messages.findIndex(
(msg, i) => msg.role !== 'system' && !!msg.displayContent && i > firstMsgIdx // (msg, i) => msg.role !== 'system' && !!msg.displayContent && i > firstMsgIdx
); // );
if (secondMsgIdx !== -1) { // if (secondMsgIdx !== -1) {
secondMsg = truncate(pastThread.messages[secondMsgIdx].displayContent ?? ''); // secondMsg = truncate(pastThread.messages[secondMsgIdx].displayContent ?? '');
} // }
const numMessages = pastThread.messages.filter( const numMessages = pastThread.messages.filter(
(msg) => msg.role !== 'system' (msg) => msg.role !== 'system'
@ -93,17 +93,20 @@ export const SidebarThreadSelector = () => {
return ( return (
<li key={pastThread.id}> <li key={pastThread.id}>
<button <button
type='button'
className={` className={`
hover:bg-void-bg-1 hover:bg-void-bg-1
${threadsState._currentThreadId === pastThread.id ? 'bg-void-bg-1' : ''} ${threadsState._currentThreadId === pastThread.id ? 'bg-void-bg-1' : ''}
rounded-sm px-2 py-1 rounded-sm px-2 py-1
w-full w-full
text-left text-left
flex items-center
`} `}
onClick={() => threadsStateService.switchToThread(pastThread.id)} onClick={() => threadsStateService.switchToThread(pastThread.id)}
title={new Date(pastThread.createdAt).toLocaleString()} title={new Date(pastThread.createdAt).toLocaleString()}
> >
{`${firstMsg} (${numMessages})`} <div className='truncate'>{`${firstMsg}`}</div>
<div>{`\u00A0(${numMessages})`}</div>
</button> </button>
</li> </li>
); );