From a27378047265948852b863628bcfc8ab4cf7bc13 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 14 Nov 2024 03:38:41 -0800 Subject: [PATCH] update services to not use a Provider --- .../react/src/markdown/MarkdownRender.tsx | 2 +- .../browser/react/src/sidebar-tsx/Sidebar.tsx | 2 +- .../react/src/sidebar-tsx/SidebarChat.tsx | 2 +- .../react/src/sidebar-tsx/SidebarSettings.tsx | 2 +- .../src/sidebar-tsx/SidebarThreadSelector.tsx | 2 +- .../react/src/util/mountFnGenerator.tsx | 17 +++--- .../{contextForServices.tsx => services.tsx} | 56 +++++++------------ 7 files changed, 34 insertions(+), 49 deletions(-) rename src/vs/workbench/contrib/void/browser/react/src/util/{contextForServices.tsx => services.tsx} (64%) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/MarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/MarkdownRender.tsx index 7d476841..e17beb37 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/MarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/MarkdownRender.tsx @@ -1,7 +1,7 @@ import React, { JSX, useCallback, useEffect, useState } from 'react' import { marked, MarkedToken, Token } from 'marked' import { BlockCode } from './BlockCode.js' -import { useService } from '../util/contextForServices.js' +import { useService } from '../util/services.js' enum CopyButtonState { diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx index 9ec08598..542eeccf 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react' import { mountFnGenerator } from '../util/mountFnGenerator.js' import { SidebarSettings } from './SidebarSettings.js'; -import { useSidebarState } from '../util/contextForServices.js'; +import { useSidebarState } from '../util/services.js'; // import { SidebarThreadSelector } from './SidebarThreadSelector.js'; // import { SidebarChat } from './SidebarChat.js'; diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 10aeb6a4..868e164e 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -1,7 +1,7 @@ import React, { FormEvent, useCallback, useRef, useState } from 'react'; -import { useConfigState, useService, useSidebarState, useThreadsState } from '../util/contextForServices.js'; +import { useConfigState, useService, useSidebarState, useThreadsState } from '../util/services.js'; import { URI } from '../../../../../../../base/common/uri.js'; import { VSReadFile } from '../../../registerInlineDiffs.js'; import { sendLLMMessage } from '../util/sendLLMMessage.js'; diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarSettings.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarSettings.tsx index 8032e994..42bf4bfb 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarSettings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarSettings.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { useConfigState, useService } from '../util/contextForServices.js'; +import { useConfigState, useService } from '../util/services.js'; import { IVoidConfigStateService, nonDefaultConfigFields, PartialVoidConfig, VoidConfig, VoidConfigField, VoidConfigInfo, SetFieldFnType, ConfigState } from '../../../registerConfig.js'; diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx index 6d617497..f3269b43 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { useService, useThreadsState } from '../util/contextForServices.js'; +import { useService, useThreadsState } from '../util/services.js'; const truncate = (s: string) => { diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx index 421ee75a..f075e9ac 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx @@ -1,7 +1,9 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import * as ReactDOM from 'react-dom/client' -import { AccessorProvider } from './contextForServices.js'; -import { ReactServicesType } from '../../../registerSidebar.js'; +import { ReactServicesType, VoidSidebarState } from '../../../registerSidebar.js'; +import { ConfigState } from '../../../registerConfig.js'; +import { ThreadsState } from '../../../registerThreads.js'; +import { _registerServices } from './services.js'; export const mountFnGenerator = (Component: React.FC) => (rootElement: HTMLElement, services: ReactServicesType) => { @@ -9,10 +11,9 @@ export const mountFnGenerator = (Component: React.FC) => (rootElement: HTMLEleme console.error('index.tsx error: document was undefined') return } + + _registerServices(services) + const root = ReactDOM.createRoot(rootElement) - root.render( - - - - ); + root.render(); } diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/contextForServices.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx similarity index 64% rename from src/vs/workbench/contrib/void/browser/react/src/util/contextForServices.tsx rename to src/vs/workbench/contrib/void/browser/react/src/util/services.tsx index cf0b4d04..788bd810 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/contextForServices.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx @@ -1,35 +1,12 @@ -import React, { createContext, useContext, useEffect, useState } from 'react' -import { ReactServicesType, VoidSidebarState } from '../../../registerSidebar.js'; -import { ConfigState } from '../../../registerConfig.js'; -import { ThreadsState } from '../../../registerThreads.js'; - -const AccessorContext = createContext(undefined) - -export const AccessorProvider = ({ children, services }: { children: React.ReactNode; services: ReactServicesType }) => { - registerStateListeners(services) - return - {children} - -} +import { useState, useEffect } from 'react' +import { ConfigState } from '../../../registerConfig.js' +import { VoidSidebarState, ReactServicesType } from '../../../registerSidebar.js' +import { ThreadsState } from '../../../registerThreads.js' -// -- services -- +// 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 | null = null -const useServices = (): ReactServicesType => { - const context = useContext(AccessorContext) - if (context === undefined) { - throw new Error('useAccessor must be used within an AccessorProvider') - } - return context; -} - -export const useService = (serviceName: T) => { - const services = useServices() - return services[serviceName] as ReactServicesType[T] -} - -// -- state of services -- -// normally to do this you'd use a useEffect that calls .onDidChangeState(), but here, useEffect mounts too late and misses initial state changes let sidebarState: VoidSidebarState | null = null let configState: ConfigState | null = null let threadsState: ThreadsState | null = null @@ -38,12 +15,10 @@ const sidebarStateListeners: Set<(s: VoidSidebarState) => void> = new Set() const configStateListeners: Set<(s: ConfigState) => void> = new Set() const threadsStateListeners: Set<(s: ThreadsState) => void> = new Set() -let isRegistered = false -const registerStateListeners = (context: ReactServicesType) => { - if (isRegistered) return - isRegistered = true - - const { sidebarStateService, configStateService, threadsStateService, } = context +// must call this before you can use any of the hooks below +export const _registerServices = (services_: ReactServicesType) => { + services = services_ + const { sidebarStateService, configStateService, threadsStateService, } = services sidebarState = sidebarStateService.state sidebarStateService.onDidChangeState(() => { @@ -66,7 +41,16 @@ const registerStateListeners = (context: ReactServicesType) => { } -// track the config state using React state so visual updates happen +// -- services -- +export const useService = (serviceName: T) => { + if (services === null) { + throw new Error('useAccessor must be used within an AccessorProvider') + } + return services[serviceName] as ReactServicesType[T] +} + +// -- state of services -- + export const useSidebarState = () => { const [s, ss] = useState(sidebarState) useEffect(() => {