mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
should work, just need to debug
This commit is contained in:
parent
1079893527
commit
63b71dec24
5 changed files with 144 additions and 126 deletions
|
|
@ -121,19 +121,19 @@ const findTextInCode = (text: string, fileContents: string, startingAtLine?: num
|
|||
}
|
||||
|
||||
|
||||
type AcceptRejectAllState = 'idle' | 'acceptRejectAll' | 'streaming'
|
||||
export type URIStreamState = 'idle' | 'acceptRejectAll' | 'streaming'
|
||||
|
||||
|
||||
export type StartApplyingOpts = {
|
||||
from: 'QuickEdit';
|
||||
type: 'rewrite';
|
||||
diffareaid: number; // id of the CtrlK area (contains text selection)
|
||||
chatCodeBoxId: string | null;
|
||||
chatApplyBoxId: string | null;
|
||||
} | {
|
||||
from: 'ClickApply';
|
||||
type: 'searchReplace' | 'rewrite';
|
||||
applyStr: string;
|
||||
chatCodeBoxId: string | null;
|
||||
chatApplyBoxId: string | null;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -177,6 +177,7 @@ type CommonZoneProps = {
|
|||
type CtrlKZone = {
|
||||
type: 'CtrlKZone';
|
||||
originalCode?: undefined;
|
||||
chatApplyBoxId?: undefined;
|
||||
|
||||
editorId: string; // the editor the input lives on
|
||||
|
||||
|
|
@ -196,11 +197,11 @@ type DiffZone = {
|
|||
type: 'DiffZone',
|
||||
originalCode: string;
|
||||
_diffOfId: Record<string, Diff>; // diffid -> diff in this DiffArea
|
||||
chatApplyBoxId: string | null;
|
||||
_streamState: {
|
||||
isStreaming: true;
|
||||
streamRequestIdRef: { current: string | null };
|
||||
line: number;
|
||||
codeBoxId: string | null;
|
||||
} | {
|
||||
isStreaming: false;
|
||||
streamRequestIdRef?: undefined;
|
||||
|
|
@ -219,6 +220,7 @@ type TrackingZone<T> = {
|
|||
originalCode?: undefined;
|
||||
editorId?: undefined;
|
||||
_removeStylesFns?: undefined;
|
||||
chatApplyBoxId?: undefined;
|
||||
} & CommonZoneProps
|
||||
|
||||
|
||||
|
|
@ -232,6 +234,7 @@ const diffAreaSnapshotKeys = [
|
|||
'startLine',
|
||||
'endLine',
|
||||
'editorId',
|
||||
'chatApplyBoxId',
|
||||
|
||||
] as const satisfies (keyof DiffArea)[]
|
||||
|
||||
|
|
@ -256,6 +259,7 @@ export interface IEditCodeService {
|
|||
|
||||
addCtrlKZone(opts: AddCtrlKOpts): number | undefined;
|
||||
removeCtrlKZone(opts: { diffareaid: number }): void;
|
||||
removeDiffAreas(opts: { uri: URI, removeCtrlKs: boolean, behavior: 'reject' | 'accept' }): void;
|
||||
|
||||
// CtrlKZone streaming state
|
||||
isCtrlKZoneStreaming(opts: { diffareaid: number }): boolean;
|
||||
|
|
@ -263,9 +267,9 @@ export interface IEditCodeService {
|
|||
onDidChangeCtrlKZoneStreaming: Event<{ uri: URI; diffareaid: number }>;
|
||||
|
||||
// // DiffZone codeBoxId streaming state
|
||||
isCodeBoxIdStreaming(opts: { codeBoxId: string }): boolean;
|
||||
interruptCodeBoxId(opts: { codeBoxId: string }): void;
|
||||
onDidChangeCodeBoxIdStreaming: Event<{ codeBoxId: string }>;
|
||||
getURIStreamState(opts: { uri: URI | null }): URIStreamState;
|
||||
interruptURIStreaming(opts: { uri: URI }): void;
|
||||
onDidChangeURIStreamState: Event<{ uri: URI; state: URIStreamState }>;
|
||||
|
||||
// testDiffs(): void;
|
||||
}
|
||||
|
|
@ -291,8 +295,11 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
private readonly _onDidChangeCtrlKZoneStreaming = new Emitter<{ uri: URI; diffareaid: number }>();
|
||||
onDidChangeCtrlKZoneStreaming = this._onDidChangeCtrlKZoneStreaming.event
|
||||
|
||||
private readonly _onDidChangeCodeBoxIdStreaming = new Emitter<{ uri: URI; diffareaid: number; codeBoxId: string }>();
|
||||
onDidChangeCodeBoxIdStreaming = this._onDidChangeCodeBoxIdStreaming.event
|
||||
private readonly _onDidChangeURIStreamState = new Emitter<{ uri: URI; state: URIStreamState }>();
|
||||
onDidChangeURIStreamState = this._onDidChangeURIStreamState.event
|
||||
|
||||
|
||||
|
||||
|
||||
constructor(
|
||||
// @IHistoryService private readonly _historyService: IHistoryService, // history service is the history of pressing alt left/right
|
||||
|
|
@ -327,36 +334,30 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
})
|
||||
)
|
||||
|
||||
// when a stream starts or ends, add/remove the accept|reject UI
|
||||
let _removeAcceptRejectAllUI: (() => void) | null = null
|
||||
// when a stream starts or ends, fire the event for onDidChangeURIStreamState
|
||||
let prevStreamState = this.getURIStreamState({ uri: model.uri })
|
||||
const updateAcceptRejectAllUI = () => {
|
||||
const uri = model.uri
|
||||
const diffZones = [...this.diffAreasOfURI[uri.fsPath].values()]
|
||||
.map(diffareaid => this.diffAreaOfId[diffareaid])
|
||||
.filter(diffArea => !!diffArea && diffArea.type === 'DiffZone')
|
||||
const isStreaming = diffZones.find(diffZone => !!diffZone._streamState.isStreaming)
|
||||
const state = this.getURIStreamState({ uri: model.uri })
|
||||
if (prevStreamState === state) return
|
||||
this._onDidChangeURIStreamState.fire({ uri: model.uri, state })
|
||||
}
|
||||
|
||||
const state: AcceptRejectAllState = isStreaming ? 'streaming' : (diffZones.length === 0 ? 'idle' : 'acceptRejectAll')
|
||||
// add/remove the accept|reject UI
|
||||
let _removeAcceptRejectAllUI: (() => void) | null = null
|
||||
this._register(this._onDidChangeURIStreamState.event(({ uri: uri_ }) => {
|
||||
if (uri_.fsPath !== model.uri.fsPath) return
|
||||
const state = this.getURIStreamState({ uri: model.uri })
|
||||
if (state === 'acceptRejectAll' && !_removeAcceptRejectAllUI) {
|
||||
_removeAcceptRejectAllUI = this._addAcceptRejectAllUI(uri) ?? null
|
||||
_removeAcceptRejectAllUI = this._addAcceptRejectAllUI(model.uri) ?? null
|
||||
} else {
|
||||
_removeAcceptRejectAllUI?.()
|
||||
_removeAcceptRejectAllUI = null
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
this._register(this._onDidChangeDiffZoneStreaming.event(({ uri: uri_ }) => { if (uri_.fsPath === model.uri.fsPath) updateAcceptRejectAllUI() }))
|
||||
this._register(this._onDidAddOrDeleteDiffZones.event(({ uri: uri_ }) => { if (uri_.fsPath === model.uri.fsPath) updateAcceptRejectAllUI() }))
|
||||
|
||||
// codeBoxId
|
||||
this._register(this._onDidChangeDiffZoneStreaming.event(({ diffareaid }) => {
|
||||
const diffZone = this.diffAreaOfId[diffareaid]
|
||||
if (diffZone?.type !== 'DiffZone') return
|
||||
if (!diffZone._streamState.isStreaming) return
|
||||
const { codeBoxId } = diffZone._streamState
|
||||
if (codeBoxId === null) return
|
||||
this._onDidChangeCodeBoxIdStreaming.fire({ uri: model.uri, codeBoxId, diffareaid })
|
||||
}))
|
||||
|
||||
}
|
||||
// initialize all existing models + initialize when a new model mounts
|
||||
|
|
@ -505,7 +506,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
const buttonsWidget = new AcceptAllRejectAllWidget({
|
||||
editor,
|
||||
onAcceptAll: () => {
|
||||
this.removeDiffAreas({ uri, behavior: 'keep', removeCtrlKs: false })
|
||||
this.removeDiffAreas({ uri, behavior: 'accept', removeCtrlKs: false })
|
||||
this._metricsService.capture('Accept All', {})
|
||||
},
|
||||
onRejectAll: () => {
|
||||
|
|
@ -1266,7 +1267,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
private _initializeWriteoverStream(opts: StartApplyingOpts): DiffZone | undefined {
|
||||
|
||||
const { from, chatCodeBoxId } = opts
|
||||
const { from, chatApplyBoxId } = opts
|
||||
|
||||
let startLine: number
|
||||
let endLine: number
|
||||
|
|
@ -1318,6 +1319,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
const adding: Omit<DiffZone, 'diffareaid'> = {
|
||||
type: 'DiffZone',
|
||||
chatApplyBoxId,
|
||||
originalCode,
|
||||
startLine,
|
||||
endLine,
|
||||
|
|
@ -1326,7 +1328,6 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
isStreaming: true,
|
||||
streamRequestIdRef,
|
||||
line: startLine,
|
||||
codeBoxId: chatCodeBoxId,
|
||||
},
|
||||
_diffOfId: {}, // added later
|
||||
_removeStylesFns: new Set(),
|
||||
|
|
@ -1452,7 +1453,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
|
||||
private _initializeSearchAndReplaceStream(opts: StartApplyingOpts & { from: 'ClickApply' }) {
|
||||
const { applyStr, chatCodeBoxId } = opts
|
||||
const { applyStr, chatApplyBoxId } = opts
|
||||
|
||||
const uri_ = this._getActiveEditorURI()
|
||||
if (!uri_) return
|
||||
|
|
@ -1493,6 +1494,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
const adding: Omit<DiffZone, 'diffareaid'> = {
|
||||
type: 'DiffZone',
|
||||
chatApplyBoxId,
|
||||
originalCode: originalFileCode,
|
||||
startLine,
|
||||
endLine,
|
||||
|
|
@ -1501,7 +1503,6 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
isStreaming: true,
|
||||
streamRequestIdRef,
|
||||
line: startLine,
|
||||
codeBoxId: chatCodeBoxId,
|
||||
},
|
||||
_diffOfId: {}, // added later
|
||||
_removeStylesFns: new Set(),
|
||||
|
|
@ -1555,7 +1556,6 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
this._deleteTrackingZone(trackingZone)
|
||||
|
||||
onFinishEdit()
|
||||
shouldSendAnotherMessage = false
|
||||
}
|
||||
|
||||
// refresh now in case onText takes a while to get 1st message
|
||||
|
|
@ -1746,7 +1746,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
|
||||
|
||||
_interruptDiffZoneStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
_interruptSingleDiffZoneStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
const diffZone = this.diffAreaOfId[diffareaid]
|
||||
if (diffZone?.type !== 'DiffZone') return
|
||||
if (!diffZone._streamState.isStreaming) return
|
||||
|
|
@ -1774,35 +1774,33 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
if (!linkedStreamingDiffZone) return
|
||||
if (linkedStreamingDiffZone.type !== 'DiffZone') return
|
||||
|
||||
this._interruptDiffZoneStreaming({ diffareaid: linkedStreamingDiffZone.diffareaid })
|
||||
this._interruptSingleDiffZoneStreaming({ diffareaid: linkedStreamingDiffZone.diffareaid })
|
||||
}
|
||||
|
||||
|
||||
|
||||
isCodeBoxIdStreaming({ codeBoxId }: { codeBoxId: string }) {
|
||||
// brute force is OK for now
|
||||
for (const diffareaid in this.diffAreaOfId) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (!diffArea) continue
|
||||
if (diffArea.type !== 'DiffZone') continue
|
||||
if (!diffArea._streamState.isStreaming) continue
|
||||
if (diffArea._streamState.codeBoxId === codeBoxId) return true
|
||||
}
|
||||
return false
|
||||
|
||||
getURIStreamState = ({ uri }: { uri: URI | null }) => {
|
||||
if (uri === null) return 'idle'
|
||||
|
||||
const diffZones = [...this.diffAreasOfURI[uri.fsPath].values()]
|
||||
.map(diffareaid => this.diffAreaOfId[diffareaid])
|
||||
.filter(diffArea => !!diffArea && diffArea.type === 'DiffZone')
|
||||
const isStreaming = diffZones.find(diffZone => !!diffZone._streamState.isStreaming)
|
||||
|
||||
const state: URIStreamState = isStreaming ? 'streaming' : (diffZones.length === 0 ? 'idle' : 'acceptRejectAll')
|
||||
return state
|
||||
}
|
||||
|
||||
interruptCodeBoxId({ codeBoxId }: { codeBoxId: string }) {
|
||||
interruptURIStreaming({ uri }: { uri: URI }) {
|
||||
// brute force for now is OK
|
||||
for (const diffareaid in this.diffAreaOfId) {
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (!diffArea) continue
|
||||
if (diffArea.type !== 'DiffZone') continue
|
||||
if (diffArea?.type !== 'DiffZone') continue
|
||||
if (!diffArea._streamState.isStreaming) continue
|
||||
if (diffArea._streamState.codeBoxId === codeBoxId) {
|
||||
this._interruptDiffZoneStreaming({ diffareaid: diffArea.diffareaid })
|
||||
return
|
||||
}
|
||||
this._stopIfStreaming(diffArea)
|
||||
}
|
||||
this._undoHistory(uri)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1829,7 +1827,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
|
||||
// remove a batch of diffareas all at once (and handle accept/reject of their diffs)
|
||||
public removeDiffAreas({ uri, removeCtrlKs, behavior }: { uri: URI, removeCtrlKs: boolean, behavior: 'reject' | 'keep' }) {
|
||||
public removeDiffAreas({ uri, removeCtrlKs, behavior }: { uri: URI, removeCtrlKs: boolean, behavior: 'reject' | 'accept' }) {
|
||||
|
||||
const diffareaids = this.diffAreasOfURI[uri.fsPath]
|
||||
if (diffareaids.size === 0) return // do nothing
|
||||
|
|
@ -1842,7 +1840,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
if (diffArea.type == 'DiffZone') {
|
||||
if (behavior === 'reject') this._revertAndDeleteDiffZone(diffArea)
|
||||
else if (behavior === 'keep') this._deleteDiffZone(diffArea)
|
||||
else if (behavior === 'accept') this._deleteDiffZone(diffArea)
|
||||
}
|
||||
else if (diffArea.type === 'CtrlKZone' && removeCtrlKs) {
|
||||
this._deleteCtrlKZone(diffArea)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useAccessor, useCodeBoxIdStreamingState, useSettingsState } from '../util/services.js'
|
||||
import { useAccessor, useURIStreamState, useSettingsState } from '../util/services.js'
|
||||
import { useRefState } from '../util/helpers.js'
|
||||
import { isFeatureNameDisabled } from '../../../../common/voidSettingsTypes.js'
|
||||
import { URI } from '../../../../../../../base/common/uri.js'
|
||||
|
||||
enum CopyButtonText {
|
||||
Idle = 'Copy',
|
||||
|
|
@ -44,80 +45,71 @@ const CopyButton = ({ codeStr }: { codeStr: string }) => {
|
|||
}
|
||||
|
||||
|
||||
const useStreamStateRef = ({ codeBoxId }: { codeBoxId: string | null }) => {
|
||||
const accessor = useAccessor()
|
||||
const editCodeService = accessor.get('IEditCodeService')
|
||||
const [isStreamingRef, setIsStreamingRef] = useRefState(editCodeService.isCodeBoxIdStreaming({ codeBoxId }))
|
||||
useCodeBoxIdStreamingState(useCallback((codeBoxId2, isStreaming) => {
|
||||
if (codeBoxId !== codeBoxId2) return
|
||||
setIsStreamingRef(isStreaming)
|
||||
}, [codeBoxId, setIsStreamingRef]))
|
||||
return [isStreamingRef, setIsStreamingRef] as const
|
||||
|
||||
|
||||
|
||||
// state persisted for duration of react only
|
||||
const streamingURIOfApplyBoxIdRef: { current: { [applyBoxId: string]: URI | undefined } } = { current: {} }
|
||||
const useStreamingURIOfApplyBoxId = (applyBoxId: string | null) => {
|
||||
const [_, ss] = useState(0)
|
||||
const uri = applyBoxId === null ? null : streamingURIOfApplyBoxIdRef.current[applyBoxId]
|
||||
const setUri = useCallback((uri: URI | null) => {
|
||||
if (applyBoxId === null) return
|
||||
ss(c => c + 1)
|
||||
if (uri === null) {
|
||||
delete streamingURIOfApplyBoxIdRef.current[applyBoxId]
|
||||
}
|
||||
else {
|
||||
streamingURIOfApplyBoxIdRef.current = {
|
||||
...streamingURIOfApplyBoxIdRef.current,
|
||||
[applyBoxId]: uri,
|
||||
}
|
||||
}
|
||||
}, [applyBoxId])
|
||||
return [uri, setUri] as const
|
||||
}
|
||||
|
||||
|
||||
export const ApplyBlockHoverButtons = ({ codeStr, applyBoxId }: { codeStr: string, applyBoxId: string | null }) => {
|
||||
|
||||
const StopButton = ({ codeBoxId }: { codeBoxId: string }) => {
|
||||
const accessor = useAccessor()
|
||||
|
||||
const editCodeService = accessor.get('IEditCodeService')
|
||||
const metricsService = accessor.get('IMetricsService')
|
||||
|
||||
const settingsState = useSettingsState()
|
||||
|
||||
const [isStreamingRef, _] = useStreamStateRef({ codeBoxId })
|
||||
|
||||
|
||||
|
||||
return <button
|
||||
// btn btn-secondary btn-sm border text-sm border-vscode-input-border rounded
|
||||
className={`${isSingleLine ? '' : 'px-1 py-0.5'} text-sm bg-void-bg-1 text-void-fg-1 hover:brightness-110 border border-vscode-input-border rounded`}
|
||||
onClick={onInterrupt}
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const ApplyBlockHoverButtons = ({ codeStr, codeBoxId }: { codeStr: string, codeBoxId: string | null }) => {
|
||||
|
||||
|
||||
const isDisabled = !!isFeatureNameDisabled('Apply', settingsState) || applyBoxId === null
|
||||
|
||||
const accessor = useAccessor()
|
||||
|
||||
const editCodeService = accessor.get('IEditCodeService')
|
||||
const metricsService = accessor.get('IMetricsService')
|
||||
|
||||
const settingsState = useSettingsState()
|
||||
// get streaming URI of this applyBlockId (cached in react)
|
||||
const [appliedURI, setAppliedURI] = useStreamingURIOfApplyBoxId(applyBoxId)
|
||||
|
||||
const isDisabled = !!isFeatureNameDisabled('Apply', settingsState)
|
||||
// get stream state of this URI
|
||||
const [streamStateRef, setStreamState] = useRefState(editCodeService.getURIStreamState({ uri: appliedURI ?? null }))
|
||||
useURIStreamState(useCallback((uri, streamState) => {
|
||||
if (appliedURI?.fsPath !== uri.fsPath) return
|
||||
setStreamState(streamState)
|
||||
}, [appliedURI, setStreamState]))
|
||||
|
||||
const [isStreamingRef, _] = useStreamStateRef({ codeBoxId })
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
if (isDisabled) return
|
||||
if (isStreamingRef.current) return
|
||||
editCodeService.startApplying({
|
||||
const uri = editCodeService.startApplying({
|
||||
from: 'ClickApply',
|
||||
type: 'searchReplace',
|
||||
applyStr: codeStr,
|
||||
chatCodeBoxId: codeBoxId,
|
||||
chatApplyBoxId: applyBoxId,
|
||||
})
|
||||
setAppliedURI(uri)
|
||||
metricsService.capture('Apply Code', { length: codeStr.length }) // capture the length only
|
||||
}, [isStreamingRef, editCodeService, codeBoxId, codeStr, metricsService])
|
||||
}, [streamStateRef, setAppliedURI, editCodeService, applyBoxId, codeStr, metricsService])
|
||||
|
||||
|
||||
const onInterrupt = useCallback(() => {
|
||||
if (isStreamingRef.current) return
|
||||
if (codeBoxId === null) return
|
||||
editCodeService.interruptCodeBoxId({ codeBoxId, })
|
||||
if (!appliedURI) return
|
||||
editCodeService.interruptURIStreaming({ uri: appliedURI, })
|
||||
metricsService.capture('Stop Apply', {})
|
||||
}, [isStreamingRef, editCodeService, codeBoxId, metricsService])
|
||||
|
||||
}, [streamStateRef, editCodeService, appliedURI, metricsService])
|
||||
|
||||
|
||||
const isSingleLine = !codeStr.includes('\n')
|
||||
|
|
@ -130,11 +122,42 @@ export const ApplyBlockHoverButtons = ({ codeStr, codeBoxId }: { codeStr: string
|
|||
Apply
|
||||
</button>
|
||||
|
||||
const stopButton = <button
|
||||
// btn btn-secondary btn-sm border text-sm border-vscode-input-border rounded
|
||||
className={`${isSingleLine ? '' : 'px-1 py-0.5'} text-sm bg-void-bg-1 text-void-fg-1 hover:brightness-110 border border-vscode-input-border rounded`}
|
||||
onClick={onInterrupt}
|
||||
>
|
||||
Stop
|
||||
</button>
|
||||
|
||||
const acceptRejectButtons = <>
|
||||
<button
|
||||
// btn btn-secondary btn-sm border text-sm border-vscode-input-border rounded
|
||||
className={`${isSingleLine ? '' : 'px-1 py-0.5'} text-sm bg-void-bg-1 text-void-fg-1 hover:brightness-110 border border-vscode-input-border rounded`}
|
||||
onClick={() => {
|
||||
if (!appliedURI) return
|
||||
editCodeService.removeDiffAreas({ uri: appliedURI, behavior: 'accept', removeCtrlKs: false })
|
||||
}}
|
||||
>
|
||||
Accept
|
||||
</button>
|
||||
<button
|
||||
// btn btn-secondary btn-sm border text-sm border-vscode-input-border rounded
|
||||
className={`${isSingleLine ? '' : 'px-1 py-0.5'} text-sm bg-void-bg-1 text-void-fg-1 hover:brightness-110 border border-vscode-input-border rounded`}
|
||||
onClick={() => {
|
||||
if (!appliedURI) return
|
||||
editCodeService.removeDiffAreas({ uri: appliedURI, behavior: 'reject', removeCtrlKs: false })
|
||||
}}
|
||||
>
|
||||
Reject
|
||||
</button>
|
||||
</>
|
||||
|
||||
|
||||
return <>
|
||||
{!isStreamingRef.current && <CopyButton codeStr={codeStr} />}
|
||||
{!isStreamingRef.current && codeBoxId !== null && <ApplyButton codeBoxId={codeBoxId} codeStr={codeStr} />}
|
||||
{!isStreamingRef.current && <StopButton codeStr={codeStr} />}
|
||||
{streamStateRef.current !== 'streaming' && <CopyButton codeStr={codeStr} />}
|
||||
{streamStateRef.current === 'idle' && !isDisabled && applyButton}
|
||||
{streamStateRef.current === 'streaming' && stopButton}
|
||||
{streamStateRef.current === 'acceptRejectAll' && acceptRejectButtons}
|
||||
</>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { URI } from '../../../../../../../base/common/uri.js'
|
|||
|
||||
type ApplyBoxLocation = ChatMessageLocation & { tokenIdx: string }
|
||||
|
||||
const getCodeBoxId = ({ threadId, messageIdx, tokenIdx }: ApplyBoxLocation) => {
|
||||
const getApplyBoxId = ({ threadId, messageIdx, tokenIdx }: ApplyBoxLocation) => {
|
||||
return `${threadId}-${messageIdx}-${tokenIdx}`
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ const RenderToken = ({ token, nested, noSpace, chatMessageLocation, tokenIdx }:
|
|||
|
||||
if (t.type === "code") {
|
||||
|
||||
const codeBoxId = chatMessageLocation ? getCodeBoxId({
|
||||
const applyBoxId = chatMessageLocation ? getApplyBoxId({
|
||||
threadId: chatMessageLocation.threadId,
|
||||
messageIdx: chatMessageLocation.messageIdx,
|
||||
tokenIdx: tokenIdx,
|
||||
|
|
@ -55,7 +55,7 @@ const RenderToken = ({ token, nested, noSpace, chatMessageLocation, tokenIdx }:
|
|||
return <BlockCode
|
||||
initValue={t.text}
|
||||
language={t.lang === undefined ? undefined : nameToVscodeLanguage[t.lang]}
|
||||
buttonsOnHover={<ApplyBlockHoverButtons codeBoxId={codeBoxId} codeStr={t.text} />}
|
||||
buttonsOnHover={<ApplyBlockHoverButtons applyBoxId={applyBoxId} codeStr={t.text} />}
|
||||
/>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export const QuickEditChat = ({
|
|||
from: 'QuickEdit',
|
||||
type: 'rewrite',
|
||||
diffareaid,
|
||||
chatCodeBoxId: null,
|
||||
chatApplyBoxId: null,
|
||||
})
|
||||
}, [isStreamingRef, isDisabled, editCodeService, diffareaid])
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import React, { useState, useEffect, useCallback } from 'react'
|
||||
import { ThreadStreamState, ThreadsState } from '../../../chatThreadService.js'
|
||||
import { RefreshableProviderName, SettingsOfProvider } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js'
|
||||
import { IDisposable } from '../../../../../../../base/common/lifecycle.js'
|
||||
|
|
@ -24,7 +24,7 @@ import { IThemeService } from '../../../../../../../platform/theme/common/themeS
|
|||
import { ILLMMessageService } from '../../../../../../../workbench/contrib/void/common/llmMessageService.js';
|
||||
import { IRefreshModelService } from '../../../../../../../workbench/contrib/void/common/refreshModelService.js';
|
||||
import { IVoidSettingsService } from '../../../../../../../workbench/contrib/void/common/voidSettingsService.js';
|
||||
import { IEditCodeService } from '../../../editCodeService.js';
|
||||
import { IEditCodeService, URIStreamState } from '../../../editCodeService.js';
|
||||
import { IVoidUriStateService } from '../../../voidUriStateService.js';
|
||||
import { IQuickEditStateService } from '../../../quickEditStateService.js';
|
||||
import { ISidebarStateService } from '../../../sidebarStateService.js';
|
||||
|
|
@ -43,6 +43,7 @@ import { IEnvironmentService } from '../../../../../../../platform/environment/c
|
|||
import { IConfigurationService } from '../../../../../../../platform/configuration/common/configuration.js'
|
||||
import { IPathService } from '../../../../../../../workbench/services/path/common/pathService.js'
|
||||
import { IMetricsService } from '../../../../../../../workbench/contrib/void/common/metricsService.js'
|
||||
import { URI } from '../../../../../../../base/common/uri.js'
|
||||
|
||||
|
||||
|
||||
|
|
@ -76,7 +77,7 @@ let colorThemeState: ColorScheme
|
|||
const colorThemeStateListeners: Set<(s: ColorScheme) => void> = new Set()
|
||||
|
||||
const ctrlKZoneStreamingStateListeners: Set<(diffareaid: number, s: boolean) => void> = new Set()
|
||||
const codeBoxIdStreamingStateListeners: Set<(codeBoxId: string, s: boolean) => void> = new Set()
|
||||
const uriStreamingStateListeners: Set<(uri: URI, s: URIStreamState) => void> = new Set()
|
||||
|
||||
|
||||
|
||||
|
|
@ -183,9 +184,9 @@ export const _registerServices = (accessor: ServicesAccessor) => {
|
|||
})
|
||||
)
|
||||
disposables.push(
|
||||
editCodeService.onDidChangeCodeBoxIdStreaming(({ codeBoxId }) => {
|
||||
const isStreaming = editCodeService.isCodeBoxIdStreaming({ codeBoxId })
|
||||
codeBoxIdStreamingStateListeners.forEach(l => l(codeBoxId, isStreaming))
|
||||
editCodeService.onDidChangeURIStreamState(({ uri }) => {
|
||||
const isStreaming = editCodeService.getURIStreamState({ uri })
|
||||
uriStreamingStateListeners.forEach(l => l(uri, isStreaming))
|
||||
})
|
||||
)
|
||||
|
||||
|
|
@ -362,18 +363,14 @@ export const useCtrlKZoneStreamingState = (listener: (diffareaid: number, s: boo
|
|||
}, [listener, ctrlKZoneStreamingStateListeners])
|
||||
}
|
||||
|
||||
export const useCodeBoxIdStreamingState = (listener: (codeBoxId: string, s: boolean) => void) => {
|
||||
export const useURIStreamState = (listener: (uri: URI, s: URIStreamState) => void) => {
|
||||
useEffect(() => {
|
||||
codeBoxIdStreamingStateListeners.add(listener)
|
||||
return () => { codeBoxIdStreamingStateListeners.delete(listener) }
|
||||
}, [listener, codeBoxIdStreamingStateListeners])
|
||||
uriStreamingStateListeners.add(listener)
|
||||
return () => { uriStreamingStateListeners.delete(listener) }
|
||||
}, [listener, uriStreamingStateListeners])
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const useIsDark = () => {
|
||||
const [s, ss] = useState(colorThemeState)
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue