mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
add code editor block
This commit is contained in:
parent
81282e16b3
commit
97fd332c4e
11 changed files with 227 additions and 71 deletions
|
|
@ -10,7 +10,6 @@ import { Disposable } from '../../../../base/common/lifecycle.js';
|
|||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||
import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';
|
||||
import { mountCtrlK } from './react/out/ctrl-k-tsx/index.js';
|
||||
import { getReactServices } from './helpers/reactServicesHelper.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
|
||||
|
||||
|
|
@ -83,12 +82,10 @@ class VoidQuickEditService extends Disposable implements IQuickEditService {
|
|||
accessor.addZone(viewZone)
|
||||
|
||||
this._instantiationService.invokeFunction(accessor => {
|
||||
const services = getReactServices(accessor)
|
||||
|
||||
const props: QuickEditPropsType = {
|
||||
quickEditId: this.quickEditId++,
|
||||
}
|
||||
mountCtrlK(domNode, services, props)
|
||||
mountCtrlK(domNode, accessor, props)
|
||||
})
|
||||
|
||||
// disposeInThisEditorFns.push(() => { editor.changeViewZones(accessor => { if (zoneId) accessor.removeZone(zoneId) }) })
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
import React, { ReactNode } from "react"
|
||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||
import { atomOneDarkReasonable } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
||||
import { VoidCodeEditor } from '../util/inputs.js';
|
||||
|
||||
|
||||
export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, buttonsOnHover?: ReactNode, language?: string }) => {
|
||||
|
|
@ -27,7 +28,11 @@ export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, bu
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
<VoidCodeEditor
|
||||
initValue={text}
|
||||
language={language}
|
||||
/>
|
||||
{/* <div
|
||||
className={`overflow-x-auto rounded-sm text-vscode-editor-fg bg-vscode-editor-bg`}
|
||||
>
|
||||
<SyntaxHighlighter
|
||||
|
|
@ -38,7 +43,7 @@ export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, bu
|
|||
{text}
|
||||
</SyntaxHighlighter>
|
||||
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import React, { JSX, useCallback, useEffect, useState } from 'react'
|
||||
import { marked, MarkedToken, Token } from 'marked'
|
||||
import { BlockCode } from './BlockCode.js'
|
||||
import { useService } from '../util/services.js'
|
||||
import { useAccessor } from '../util/services.js'
|
||||
|
||||
|
||||
enum CopyButtonState {
|
||||
|
|
@ -18,13 +18,13 @@ enum CopyButtonState {
|
|||
const COPY_FEEDBACK_TIMEOUT = 1000 // amount of time to say 'Copied!'
|
||||
|
||||
const CodeButtonsOnHover = ({ diffRepr: text }: { diffRepr: string }) => {
|
||||
const accessor = useAccessor()
|
||||
|
||||
const [copyButtonState, setCopyButtonState] = useState(CopyButtonState.Copy)
|
||||
const inlineDiffService = useService('inlineDiffService')
|
||||
|
||||
const clipboardService = useService('clipboardService')
|
||||
|
||||
|
||||
const inlineDiffService = accessor.get('IInlineDiffsService')
|
||||
const clipboardService = accessor.get('IClipboardService')
|
||||
useEffect(() => {
|
||||
|
||||
if (copyButtonState !== CopyButtonState.Copy) {
|
||||
setTimeout(() => {
|
||||
setCopyButtonState(CopyButtonState.Copy)
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@
|
|||
import React, { ButtonHTMLAttributes, FormEvent, FormHTMLAttributes, Fragment, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
|
||||
import { useSettingsState, useService, useSidebarState, useThreadsState } from '../util/services.js';
|
||||
import { ChatMessage, CodeSelection, CodeStagingSelection } from '../../../threadHistoryService.js';
|
||||
import { useAccessor, useThreadsState } from '../util/services.js';
|
||||
import { ChatMessage, CodeSelection, CodeStagingSelection, IThreadHistoryService } from '../../../threadHistoryService.js';
|
||||
|
||||
import { BlockCode } from '../markdown/BlockCode.js';
|
||||
import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js';
|
||||
import { IModelService } from '../../../../../../../editor/common/services/model.js';
|
||||
import { URI } from '../../../../../../../base/common/uri.js';
|
||||
import { EndOfLinePreference } from '../../../../../../../editor/common/model.js';
|
||||
import { IDisposable } from '../../../../../../../base/common/lifecycle.js';
|
||||
|
|
@ -19,9 +18,12 @@ import { ErrorDisplay } from './ErrorDisplay.js';
|
|||
import { OnError, ServiceSendLLMMessageParams } from '../../../../../../../platform/void/common/llmMessageTypes.js';
|
||||
import { getCmdKey } from '../../../helpers/getCmdKey.js'
|
||||
import { HistoryInputBox, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js';
|
||||
import { VoidInputBox } from '../util/inputs.js';
|
||||
import { VoidCodeEditor, VoidInputBox } from '../util/inputs.js';
|
||||
import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js';
|
||||
import { ctrlLSystem, generateCtrlLPrompt } from '../../../prompt/prompts.js';
|
||||
import { ISidebarStateService } from '../../../sidebarStateService.js';
|
||||
import { ILLMMessageService } from '../../../../../../../platform/void/common/llmMessageService.js';
|
||||
import { IModelService } from '../../../../../../../editor/common/services/model.js';
|
||||
|
||||
|
||||
const IconX = ({ size, className = '' }: { size: number, className?: string }) => {
|
||||
|
|
@ -285,11 +287,12 @@ export const SidebarChat = () => {
|
|||
|
||||
const inputBoxRef: React.MutableRefObject<InputBox | null> = useRef(null);
|
||||
|
||||
const modelService = useService('modelService')
|
||||
const accessor = useAccessor()
|
||||
const modelService = accessor.get('IModelService')
|
||||
|
||||
// ----- HIGHER STATE -----
|
||||
// sidebar state
|
||||
const sidebarStateService = useService('sidebarStateService')
|
||||
const sidebarStateService = accessor.get('ISidebarStateService')
|
||||
useEffect(() => {
|
||||
const disposables: IDisposable[] = []
|
||||
disposables.push(
|
||||
|
|
@ -301,9 +304,9 @@ export const SidebarChat = () => {
|
|||
|
||||
// threads state
|
||||
const threadsState = useThreadsState()
|
||||
const threadsStateService = useService('threadsStateService')
|
||||
const threadsStateService = accessor.get('IThreadHistoryService')
|
||||
|
||||
const llmMessageService = useService('llmMessageService')
|
||||
const llmMessageService = accessor.get('ILLMMessageService')
|
||||
|
||||
// ----- SIDEBAR CHAT state (local) -----
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import React from "react";
|
||||
import { useService, useThreadsState } from '../util/services.js';
|
||||
import { useAccessor, useThreadsState } from '../util/services.js';
|
||||
import { IThreadHistoryService } from '../../../threadHistoryService.js';
|
||||
import { ISidebarStateService } from '../../../sidebarStateService.js';
|
||||
|
||||
|
||||
const truncate = (s: string) => {
|
||||
|
|
@ -18,8 +20,10 @@ const truncate = (s: string) => {
|
|||
|
||||
export const SidebarThreadSelector = () => {
|
||||
const threadsState = useThreadsState()
|
||||
const threadsStateService = useService('threadsStateService')
|
||||
const sidebarStateService = useService('sidebarStateService')
|
||||
|
||||
const accessor = useAccessor()
|
||||
const threadsStateService = accessor.get('IThreadHistoryService')
|
||||
const sidebarStateService = accessor.get('ISidebarStateService')
|
||||
|
||||
const { allThreads } = threadsState
|
||||
|
||||
|
|
|
|||
|
|
@ -4,19 +4,26 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { useIsDark, useService } from '../util/services.js';
|
||||
import { IInputBoxStyles, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js';
|
||||
import { defaultCheckboxStyles, defaultInputBoxStyles, defaultSelectBoxStyles } from '../../../../../../../platform/theme/browser/defaultStyles.js';
|
||||
import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js';
|
||||
import { IDisposable } from '../../../../../../../base/common/lifecycle.js';
|
||||
import { Checkbox } from '../../../../../../../base/browser/ui/toggle/toggle.js';
|
||||
|
||||
import { CodeEditorWidget } from '../../../../../../../editor/browser/widget/codeEditor/codeEditorWidget.js'
|
||||
import { useAccessor } from './services.js';
|
||||
|
||||
|
||||
// type guard
|
||||
const isConstructor = (f: any)
|
||||
: f is { new(...params: any[]): any } => {
|
||||
return !!f.prototype && f.prototype.constructor === f;
|
||||
}
|
||||
|
||||
export const WidgetComponent = <CtorParams extends any[], Instance>({ ctor, propsFn, dispose, onCreateInstance, children, className }
|
||||
: {
|
||||
ctor: { new(...params: CtorParams): Instance },
|
||||
propsFn: (container: HTMLDivElement) => CtorParams,
|
||||
ctor: { new(...params: CtorParams): Instance } | ((container: HTMLDivElement) => Instance),
|
||||
propsFn: (container: HTMLDivElement) => CtorParams, // unused if fn
|
||||
onCreateInstance: (instance: Instance) => IDisposable[],
|
||||
dispose: (instance: Instance) => void,
|
||||
children?: React.ReactNode,
|
||||
|
|
@ -26,7 +33,7 @@ export const WidgetComponent = <CtorParams extends any[], Instance>({ ctor, prop
|
|||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const instance = new ctor(...propsFn(containerRef.current!));
|
||||
const instance = isConstructor(ctor) ? new ctor(...propsFn(containerRef.current!)) : ctor(containerRef.current!)
|
||||
const disposables = onCreateInstance(instance);
|
||||
return () => {
|
||||
disposables.forEach(d => d.dispose());
|
||||
|
|
@ -48,7 +55,9 @@ export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, plac
|
|||
multiline: boolean;
|
||||
}) => {
|
||||
|
||||
const contextViewProvider = useService('contextViewService');
|
||||
const accessor = useAccessor()
|
||||
|
||||
const contextViewProvider = accessor.get('IContextViewService')
|
||||
return <WidgetComponent
|
||||
ctor={InputBox}
|
||||
propsFn={useCallback((container) => [
|
||||
|
|
@ -189,7 +198,8 @@ export const VoidSelectBox = <T,>({ onChangeSelection, onCreateInstance, selectB
|
|||
selectBoxRef?: React.MutableRefObject<SelectBox | null>;
|
||||
options: readonly { text: string, value: T }[];
|
||||
}) => {
|
||||
const contextViewProvider = useService('contextViewService');
|
||||
const accessor = useAccessor()
|
||||
const contextViewProvider = accessor.get('IContextViewService')
|
||||
|
||||
let containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
|
|
@ -237,6 +247,61 @@ export const VoidSelectBox = <T,>({ onChangeSelection, onCreateInstance, selectB
|
|||
};
|
||||
|
||||
|
||||
|
||||
export const VoidCodeEditor = ({ initValue, language }: { initValue: string, language: string | undefined }) => {
|
||||
const divRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
const accessor = useAccessor()
|
||||
const instantiationService = accessor.get('IInstantiationService')
|
||||
const modelService = accessor.get('IModelService')
|
||||
|
||||
return <div ref={divRef}>
|
||||
<WidgetComponent
|
||||
ctor={useCallback((container) =>
|
||||
instantiationService.createInstance(
|
||||
CodeEditorWidget,
|
||||
container,
|
||||
{
|
||||
automaticLayout: true,
|
||||
wordWrap: 'on',
|
||||
scrollbar: {
|
||||
vertical: 'hidden',
|
||||
horizontal: 'auto',
|
||||
}
|
||||
},
|
||||
{
|
||||
isSimpleWidget: true,
|
||||
})
|
||||
, [instantiationService])
|
||||
}
|
||||
|
||||
onCreateInstance={useCallback((editor: CodeEditorWidget) => {
|
||||
|
||||
const model = modelService.createModel(initValue, null)
|
||||
editor.setModel(model);
|
||||
model.setLanguage(language ?? 'plaintext')
|
||||
|
||||
const container = editor.getDomNode()
|
||||
const parentNode = container?.parentElement
|
||||
if (parentNode)
|
||||
parentNode.style.height = `${editor.getScrollHeight() + 1}px` // the +1 is if there's a half pixel issue
|
||||
|
||||
return []
|
||||
}, [modelService, initValue, language])}
|
||||
|
||||
dispose={useCallback((editor: CodeEditorWidget) => {
|
||||
editor.dispose();
|
||||
}, [])}
|
||||
|
||||
// ignored
|
||||
propsFn={useCallback(() => { return [] }, [])}
|
||||
|
||||
/>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
|
||||
// export const VoidScrollableElt = ({ options, children }: { options: ScrollableElementCreationOptions, children: React.ReactNode }) => {
|
||||
// const instanceRef = useRef<DomScrollableElement | null>(null);
|
||||
// const [childrenPortal, setChildrenPortal] = useState<React.ReactNode | null>(null)
|
||||
|
|
@ -270,8 +335,6 @@ export const VoidSelectBox = <T,>({ onChangeSelection, onCreateInstance, selectB
|
|||
// options: readonly { text: string, value: T }[];
|
||||
// onChangeSelection: (value: T) => void;
|
||||
// }) => {
|
||||
// const contextViewProvider = useService('contextViewService');
|
||||
// const contextMenuProvider = useService('contextMenuService');
|
||||
|
||||
|
||||
// return <WidgetComponent
|
||||
|
|
@ -317,9 +380,6 @@ export const VoidSelectBox = <T,>({ onChangeSelection, onCreateInstance, selectB
|
|||
// }) => {
|
||||
// const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// const themeService = useService('themeService');
|
||||
// const contextViewService = useService('contextViewService');
|
||||
// const hoverService = useService('hoverService');
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!containerRef.current) return;
|
||||
|
|
|
|||
|
|
@ -6,15 +6,17 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import * as ReactDOM from 'react-dom/client'
|
||||
import { _registerServices } from './services.js';
|
||||
import { ReactServicesType } from '../../../helpers/reactServicesHelper.js';
|
||||
|
||||
export const mountFnGenerator = (Component: (params: any) => React.ReactNode) => (rootElement: HTMLElement, services: ReactServicesType, props?: any) => {
|
||||
|
||||
import { ServicesAccessor } from '../../../../../../../editor/browser/editorExtensions.js';
|
||||
|
||||
export const mountFnGenerator = (Component: (params: any) => React.ReactNode) => (rootElement: HTMLElement, accessor: ServicesAccessor, props?: any) => {
|
||||
if (typeof document === 'undefined') {
|
||||
console.error('index.tsx error: document was undefined')
|
||||
return
|
||||
}
|
||||
|
||||
const disposables = _registerServices(services)
|
||||
const disposables = _registerServices(accessor)
|
||||
|
||||
|
||||
const root = ReactDOM.createRoot(rootElement)
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { ThreadsState } from '../../../threadHistoryService.js'
|
||||
import { RefreshableProviderName, SettingsOfProvider } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
|
||||
import { IDisposable } from '../../../../../../../base/common/lifecycle.js'
|
||||
import { ReactServicesType } from '../../../helpers/reactServicesHelper.js'
|
||||
import { VoidSidebarState } from '../../../sidebarStateService.js'
|
||||
import { VoidSettingsState } from '../../../../../../../platform/void/common/voidSettingsService.js'
|
||||
import { ColorScheme } from '../../../../../../../platform/theme/common/theme.js'
|
||||
|
|
@ -15,9 +14,35 @@ import { VoidQuickEditState } from '../../../quickEditStateService.js'
|
|||
import { RefreshModelStateOfProvider } from '../../../../../../../platform/void/common/refreshModelService.js'
|
||||
|
||||
|
||||
// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes
|
||||
|
||||
let services: ReactServicesType
|
||||
|
||||
|
||||
import { ServicesAccessor } from '../../../../../../../editor/browser/editorExtensions.js';
|
||||
import { IModelService } from '../../../../../../../editor/common/services/model.js';
|
||||
import { IClipboardService } from '../../../../../../../platform/clipboard/common/clipboardService.js';
|
||||
import { IContextViewService, IContextMenuService } from '../../../../../../../platform/contextview/browser/contextView.js';
|
||||
import { IFileService } from '../../../../../../../platform/files/common/files.js';
|
||||
import { IHoverService } from '../../../../../../../platform/hover/browser/hover.js';
|
||||
import { IThemeService } from '../../../../../../../platform/theme/common/themeService.js';
|
||||
import { ILLMMessageService } from '../../../../../../../platform/void/common/llmMessageService.js';
|
||||
import { IRefreshModelService } from '../../../../../../../platform/void/common/refreshModelService.js';
|
||||
import { IVoidSettingsService } from '../../../../../../../platform/void/common/voidSettingsService.js';
|
||||
import { IInlineDiffsService } from '../../../inlineDiffsService.js';
|
||||
import { IQuickEditStateService } from '../../../quickEditStateService.js';
|
||||
import { ISidebarStateService } from '../../../sidebarStateService.js';
|
||||
import { IThreadHistoryService } from '../../../threadHistoryService.js';
|
||||
import { IInstantiationService } from '../../../../../../../platform/instantiation/common/instantiation.js'
|
||||
import { ICodeEditorService } from '../../../../../../../editor/browser/services/codeEditorService.js'
|
||||
import { ICommandService } from '../../../../../../../platform/commands/common/commands.js'
|
||||
import { IContextKeyService } from '../../../../../../../platform/contextkey/common/contextkey.js'
|
||||
import { INotificationService } from '../../../../../../../platform/notification/common/notification.js'
|
||||
import { IAccessibilityService } from '../../../../../../../platform/accessibility/common/accessibility.js'
|
||||
import { ILanguageConfigurationService } from '../../../../../../../editor/common/languages/languageConfigurationRegistry.js'
|
||||
import { ILanguageFeaturesService } from '../../../../../../../editor/common/services/languageFeatures.js'
|
||||
|
||||
|
||||
|
||||
// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes
|
||||
|
||||
// even if React hasn't mounted yet, the variables are always updated to the latest state.
|
||||
// React listens by adding a setState function to these listeners.
|
||||
|
|
@ -43,7 +68,7 @@ const colorThemeStateListeners: Set<(s: ColorScheme) => void> = new Set()
|
|||
// must call this before you can use any of the hooks below
|
||||
// this should only be called ONCE! this is the only place you don't need to dispose onDidChange. If you use state.onDidChange anywhere else, make sure to dispose it!
|
||||
let wasCalled = false
|
||||
export const _registerServices = (services_: ReactServicesType) => {
|
||||
export const _registerServices = (accessor: ServicesAccessor) => {
|
||||
|
||||
const disposables: IDisposable[] = []
|
||||
|
||||
|
|
@ -54,8 +79,18 @@ export const _registerServices = (services_: ReactServicesType) => {
|
|||
}
|
||||
wasCalled = true
|
||||
|
||||
services = services_
|
||||
const { sidebarStateService, quickEditStateService, settingsStateService, threadsStateService, refreshModelService, themeService, } = services
|
||||
_registerAccessor(accessor)
|
||||
|
||||
const stateServices = {
|
||||
quickEditStateService: accessor.get(IQuickEditStateService),
|
||||
sidebarStateService: accessor.get(ISidebarStateService),
|
||||
threadsStateService: accessor.get(IThreadHistoryService),
|
||||
settingsStateService: accessor.get(IVoidSettingsService),
|
||||
refreshModelService: accessor.get(IRefreshModelService),
|
||||
themeService: accessor.get(IThemeService),
|
||||
}
|
||||
|
||||
const { sidebarStateService, quickEditStateService, settingsStateService, threadsStateService, refreshModelService, themeService, } = stateServices
|
||||
|
||||
quickEditState = quickEditStateService.state
|
||||
disposables.push(
|
||||
|
|
@ -110,14 +145,56 @@ export const _registerServices = (services_: ReactServicesType) => {
|
|||
}
|
||||
|
||||
|
||||
// -- services --
|
||||
export const useService = <T extends keyof ReactServicesType,>(serviceName: T): ReactServicesType[T] => {
|
||||
if (services === null) {
|
||||
throw new Error('useAccessor must be used within an AccessorProvider')
|
||||
}
|
||||
return services[serviceName]
|
||||
const getReactAccessor = (accessor: ServicesAccessor) => {
|
||||
const reactAccessor = {
|
||||
IModelService: accessor.get(IModelService),
|
||||
IClipboardService: accessor.get(IClipboardService),
|
||||
IContextViewService: accessor.get(IContextViewService),
|
||||
IContextMenuService: accessor.get(IContextMenuService),
|
||||
IFileService: accessor.get(IFileService),
|
||||
IHoverService: accessor.get(IHoverService),
|
||||
IThemeService: accessor.get(IThemeService),
|
||||
ILLMMessageService: accessor.get(ILLMMessageService),
|
||||
IRefreshModelService: accessor.get(IRefreshModelService),
|
||||
IVoidSettingsService: accessor.get(IVoidSettingsService),
|
||||
IInlineDiffsService: accessor.get(IInlineDiffsService),
|
||||
IQuickEditStateService: accessor.get(IQuickEditStateService),
|
||||
ISidebarStateService: accessor.get(ISidebarStateService),
|
||||
IThreadHistoryService: accessor.get(IThreadHistoryService),
|
||||
|
||||
IInstantiationService: accessor.get(IInstantiationService),
|
||||
ICodeEditorService: accessor.get(ICodeEditorService),
|
||||
ICommandService: accessor.get(ICommandService),
|
||||
IContextKeyService: accessor.get(IContextKeyService),
|
||||
INotificationService: accessor.get(INotificationService),
|
||||
IAccessibilityService: accessor.get(IAccessibilityService),
|
||||
ILanguageConfigurationService: accessor.get(ILanguageConfigurationService),
|
||||
ILanguageFeaturesService: accessor.get(ILanguageFeaturesService),
|
||||
|
||||
} as const
|
||||
return reactAccessor
|
||||
}
|
||||
|
||||
type ReactAccessor = ReturnType<typeof getReactAccessor>
|
||||
|
||||
|
||||
let reactAccessor_: ReactAccessor | null = null
|
||||
const _registerAccessor = (accessor: ServicesAccessor) => {
|
||||
const reactAccessor = getReactAccessor(accessor)
|
||||
reactAccessor_ = reactAccessor
|
||||
}
|
||||
|
||||
// -- services --
|
||||
export const useAccessor = () => {
|
||||
if (!reactAccessor_) {
|
||||
throw new Error(`⚠️ Void useAccessor was called before _registerServices!`)
|
||||
}
|
||||
|
||||
return { get: <S extends keyof ReactAccessor,>(service: S): ReactAccessor[S] => reactAccessor_![service] }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- state of services --
|
||||
|
||||
export const useQuickEditState = () => {
|
||||
|
|
|
|||
|
|
@ -5,13 +5,15 @@
|
|||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { FeatureName, featureNames, ModelSelection, modelSelectionsEqual, ProviderName, providerNames } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
|
||||
import { useSettingsState, useRefreshModelState, useService } from '../util/services.js'
|
||||
import { useSettingsState, useRefreshModelState, useAccessor } from '../util/services.js'
|
||||
import { VoidSelectBox } from '../util/inputs.js'
|
||||
import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js'
|
||||
|
||||
|
||||
const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
|
||||
const voidSettingsService = useService('settingsStateService')
|
||||
const accessor = useAccessor()
|
||||
|
||||
const voidSettingsService = accessor.get('IVoidSettingsService')
|
||||
const settingsState = useSettingsState()
|
||||
|
||||
let weChangedText = false
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox
|
|||
import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, featureFlagNames, displayInfoOfFeatureFlag, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
|
||||
import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js'
|
||||
import { VoidCheckBox, VoidInputBox, VoidSelectBox, VoidSwitch } from '../util/inputs.js'
|
||||
import { useIsDark, useRefreshModelListener, useRefreshModelState, useService, useSettingsState } from '../util/services.js'
|
||||
import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js'
|
||||
import { X, RefreshCw, Loader2, Check } from 'lucide-react'
|
||||
import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'
|
||||
|
||||
|
|
@ -12,7 +12,9 @@ import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'
|
|||
// models
|
||||
const RefreshModelButton = ({ providerName }: { providerName: RefreshableProviderName }) => {
|
||||
const refreshModelState = useRefreshModelState()
|
||||
const refreshModelService = useService('refreshModelService')
|
||||
|
||||
const accessor = useAccessor()
|
||||
const refreshModelService = accessor.get('IRefreshModelService')
|
||||
|
||||
const [justFinished, setJustSucceeded] = useState(false)
|
||||
|
||||
|
|
@ -60,7 +62,10 @@ const RefreshableModels = () => {
|
|||
|
||||
|
||||
const AddModelMenu = ({ onSubmit }: { onSubmit: () => void }) => {
|
||||
const settingsStateService = useService('settingsStateService')
|
||||
|
||||
const accessor = useAccessor()
|
||||
const settingsStateService = accessor.get('IVoidSettingsService')
|
||||
|
||||
const settingsState = useSettingsState()
|
||||
|
||||
const providerNameRef = useRef<ProviderName | null>(null)
|
||||
|
|
@ -147,7 +152,9 @@ const AddModelMenuFull = () => {
|
|||
|
||||
export const ModelDump = () => {
|
||||
|
||||
const settingsStateService = useService('settingsStateService')
|
||||
const accessor = useAccessor()
|
||||
const settingsStateService = accessor.get('IVoidSettingsService')
|
||||
|
||||
const settingsState = useSettingsState()
|
||||
|
||||
// a dump of all the enabled providers' models
|
||||
|
|
@ -204,7 +211,9 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider
|
|||
const { title: providerTitle, } = displayInfoOfProviderName(providerName)
|
||||
|
||||
const { title: settingTitle, placeholder, subTextMd } = displayInfoOfSettingName(providerName, settingName)
|
||||
const voidSettingsService = useService('settingsStateService')
|
||||
|
||||
const accessor = useAccessor()
|
||||
const voidSettingsService = accessor.get('IVoidSettingsService')
|
||||
|
||||
let weChangedTextRef = false
|
||||
|
||||
|
|
@ -243,7 +252,8 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider
|
|||
|
||||
const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) => {
|
||||
const voidSettingsState = useSettingsState()
|
||||
const voidSettingsService = useService('settingsStateService')
|
||||
const accessor = useAccessor()
|
||||
const voidSettingsService = accessor.get('IVoidSettingsService')
|
||||
|
||||
const { enabled } = voidSettingsState.settingsOfProvider[providerName]
|
||||
const settingNames = customSettingNamesOfProvider(providerName)
|
||||
|
|
@ -286,7 +296,9 @@ export const VoidProviderSettings = () => {
|
|||
|
||||
|
||||
export const VoidFeatureFlagSettings = () => {
|
||||
const voidSettingsService = useService('settingsStateService')
|
||||
const accessor = useAccessor()
|
||||
const voidSettingsService = accessor.get('IVoidSettingsService')
|
||||
|
||||
const voidSettingsState = useSettingsState()
|
||||
|
||||
return <>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import { IViewPaneOptions, ViewPane } from '../../../browser/parts/views/viewPan
|
|||
|
||||
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
// import { IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
|
||||
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
|
||||
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';
|
||||
|
|
@ -33,16 +33,12 @@ import { IKeybindingService } from '../../../../platform/keybinding/common/keybi
|
|||
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
|
||||
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
|
||||
import { IHoverService } from '../../../../platform/hover/browser/hover.js';
|
||||
|
||||
import { mountSidebar } from './react/out/sidebar-tsx/index.js';
|
||||
|
||||
import { getReactServices } from './helpers/reactServicesHelper.js';
|
||||
import { Codicon } from '../../../../base/common/codicons.js';
|
||||
import { Orientation } from '../../../../base/browser/ui/sash/sash.js';
|
||||
// import { Orientation } from '../../../../base/browser/ui/sash/sash.js';
|
||||
// import { Codicon } from '../../../../base/common/codicons.js';
|
||||
// import { Codicon } from '../../../../base/common/codicons.js';
|
||||
|
||||
// import { IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
|
||||
// compare against search.contribution.ts and debug.contribution.ts, scm.contribution.ts (source control)
|
||||
|
||||
|
|
@ -62,6 +58,8 @@ class SidebarViewPane extends ViewPane {
|
|||
@IOpenerService openerService: IOpenerService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IHoverService hoverService: IHoverService,
|
||||
// @ICodeEditorService private readonly editorService: ICodeEditorService,
|
||||
// @IContextKeyService private readonly editorContextKeyService: IContextKeyService,
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService)
|
||||
|
||||
|
|
@ -76,10 +74,8 @@ class SidebarViewPane extends ViewPane {
|
|||
|
||||
// gets set immediately
|
||||
this.instantiationService.invokeFunction(accessor => {
|
||||
const services = getReactServices(accessor)
|
||||
|
||||
// mount react
|
||||
const disposables: IDisposable[] | undefined = mountSidebar(parent, services);
|
||||
const disposables: IDisposable[] | undefined = mountSidebar(parent, accessor);
|
||||
disposables?.forEach(d => this._register(d))
|
||||
});
|
||||
}
|
||||
|
|
@ -88,8 +84,6 @@ class SidebarViewPane extends ViewPane {
|
|||
super.layoutBody(height, width)
|
||||
this.element.style.height = `${height}px`
|
||||
this.element.style.width = `${width}px`
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue