memo model dropdown + add ability to remove ctrlK zone

This commit is contained in:
Andrew Pareles 2024-12-31 16:18:18 -08:00
parent d3b61867f0
commit 110534df30
3 changed files with 57 additions and 9 deletions

View file

@ -171,6 +171,7 @@ export interface IInlineDiffsService {
startApplying(opts: StartApplyingOpts): number | undefined;
interruptStreaming(diffareaid: number): void;
addCtrlKZone(opts: AddCtrlKOpts): number | undefined;
removeCtrlKZone(opts: { diffareaid: number }): void;
}
export const IInlineDiffsService = createDecorator<IInlineDiffsService>('inlineDiffAreasService');
@ -910,6 +911,17 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
return ctrlKZone.diffareaid
}
public removeCtrlKZone({ diffareaid }: { diffareaid: number }) {
const ctrlKZone = this.diffAreaOfId[diffareaid]
if (!ctrlKZone) return
if (ctrlKZone.type !== 'CtrlKZone') return
const uri = ctrlKZone._URI
const { onFinishEdit } = this._addToHistory(uri)
this._deleteCtrlKZone(ctrlKZone)
onFinishEdit()
}
public startApplying(opts: StartApplyingOpts) {

View file

@ -12,6 +12,7 @@ import { VoidInputBox } from '../util/inputs.js';
import { QuickEditPropsType } from '../../../quickEditActions.js';
import { ButtonStop, ButtonSubmit } from '../sidebar-tsx/SidebarChat.js';
import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js';
import { X } from 'lucide-react';
export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChangeHeight, initText }: QuickEditPropsType) => {
@ -108,10 +109,16 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang
>
<div // this div is used to position the input box properly
className={`w-full p-2 z-[999]`}
className={`w-full p-2 z-[999] relative`}
>
<div className='flex flex-row justify-between items-end gap-1'>
{/* left (input) */}
<div className='absolute size-0.5 top-0 right-0 z-[1]'>
<X
onClick={() => { inlineDiffsService.removeCtrlKZone({ diffareaid }) }}
/>
</div>
{/* input */}
<div // copied from SidebarChat.tsx
className={`w-full
@@[&_textarea]:!void-bg-transparent @@[&_textarea]:!void-outline-none @@[&_textarea]:!void-text-vscode-input-fg @@[&_div.monaco-inputbox]:!void-outline-none`}>
@ -131,8 +138,8 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang
</div>
{/* bottom row */}
<div
{/* bottom row */}
<div
className='flex flex-row justify-between items-end gap-1'
>
{/* submit options */}

View file

@ -3,24 +3,36 @@
* Void Editor additions licensed under the AGPL 3.0 License.
*--------------------------------------------------------------------------------------------*/
import { useCallback, useEffect, useRef, useState } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { FeatureName, featureNames, ModelSelection, modelSelectionsEqual, ProviderName, providerNames } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
import { useSettingsState, useRefreshModelState, useAccessor } from '../util/services.js'
import { VoidSelectBox } from '../util/inputs.js'
import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js'
import { IconWarning } from '../sidebar-tsx/SidebarChat.js'
import { VOID_OPEN_SETTINGS_ACTION_ID } from '../../../voidSettingsPane.js'
import { ModelOption } from '../../../../../../../platform/void/common/voidSettingsService.js'
const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
const optionsEqual = (m1: ModelOption[], m2: ModelOption[]) => {
if (m1.length !== m2.length) return false
for (let i = 0; i < m1.length; i++) {
if (!modelSelectionsEqual(m1[i].value, m2[i].value)) return false
}
return true
}
const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], featureName: FeatureName }) => {
const accessor = useAccessor()
const voidSettingsService = accessor.get('IVoidSettingsService')
const settingsState = useSettingsState()
let weChangedText = false
return <VoidSelectBox
options={settingsState._modelOptions}
options={options}
onChangeSelection={useCallback((newVal: ModelSelection) => {
if (weChangedText) return
voidSettingsService.setModelSelectionOfFeature(featureName, newVal)
@ -42,6 +54,23 @@ const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
/>
}
const MemoizedModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
const settingsState = useSettingsState()
const oldOptionsRef = useRef<ModelOption[]>([])
const [memoizedOptions, setMemoizedOptions] = useState(oldOptionsRef.current)
useEffect(() => {
const oldOptions = oldOptionsRef.current
const newOptions = settingsState._modelOptions
if (!optionsEqual(oldOptions, newOptions)) {
setMemoizedOptions(newOptions)
}
oldOptionsRef.current = newOptions
}, [settingsState._modelOptions])
return <ModelSelectBox featureName={featureName} options={memoizedOptions} />
}
const DummySelectBox = () => {
const accessor = useAccessor()
@ -76,6 +105,6 @@ const DummySelectBox = () => {
export const ModelDropdown = ({ featureName }: { featureName: FeatureName }) => {
const settingsState = useSettingsState()
return <>
{settingsState._modelOptions.length === 0 ? <DummySelectBox /> : <ModelSelectBox featureName={featureName} />}
{settingsState._modelOptions.length === 0 ? <DummySelectBox /> : <MemoizedModelSelectBox featureName={featureName} />}
</>
}