slightly fix refresh state

This commit is contained in:
Andrew Pareles 2024-12-18 16:48:04 -08:00
parent f49a6f8e41
commit c3c53b5e81
3 changed files with 34 additions and 24 deletions

View file

@ -36,7 +36,7 @@ function eq<T>(a: T[], b: T[]): boolean {
export interface IRefreshModelService {
readonly _serviceBrand: undefined;
refreshModels: (providerName: RefreshableProviderName) => Promise<void>;
onDidChangeState: Event<void>;
onDidChangeState: Event<RefreshableProviderName>;
state: RefreshModelStateOfProvider;
}
@ -46,8 +46,8 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
readonly _serviceBrand: undefined;
private readonly _onDidChangeState = new Emitter<void>();
readonly onDidChangeState: Event<void> = this._onDidChangeState.event; // this is primarily for use in react, so react can listen + update on state changes
private readonly _onDidChangeState = new Emitter<RefreshableProviderName>();
readonly onDidChangeState: Event<RefreshableProviderName> = this._onDidChangeState.event; // this is primarily for use in react, so react can listen + update on state changes
constructor(
@IVoidSettingsService private readonly voidSettingsService: IVoidSettingsService,
@ -67,7 +67,7 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
// every time providerName.enabled changes, refresh models too, like useEffect
let relevantVals = () => refreshables[providerName].map(settingName => this.voidSettingsService.state.settingsOfProvider[providerName][settingName])
let prevVals = relevantVals()
let prevVals = relevantVals() // each iteration of a for loop has its own context and vars, so this is ok
this._register(
this.voidSettingsService.onDidChangeState(() => { // we might want to debounce this
const newVals = relevantVals()
@ -79,9 +79,6 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
)
}
}
state: RefreshModelStateOfProvider = {
@ -133,7 +130,7 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
private _setIsRefreshing(providerName: RefreshableProviderName, state: ModelRefreshState) {
this.state[providerName].state = state
this._onDidChangeState.fire()
this._onDidChangeState.fire(providerName)
}
}

View file

@ -11,7 +11,7 @@ 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'
import { RefreshModelStateOfProvider } from '../../../../../../../platform/void/common/refreshModelService.js'
import { RefreshableProviderName, 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
@ -31,6 +31,7 @@ const settingsStateListeners: Set<(s: VoidSettingsState) => void> = new Set()
let refreshModelState: RefreshModelStateOfProvider
const refreshModelStateListeners: Set<(s: RefreshModelStateOfProvider) => void> = new Set()
const refreshModelProviderListeners: Set<(p: RefreshableProviderName, s: RefreshModelStateOfProvider) => void> = new Set()
let colorThemeState: ColorScheme
const colorThemeStateListeners: Set<(s: ColorScheme) => void> = new Set()
@ -78,9 +79,10 @@ export const _registerServices = (services_: ReactServicesType) => {
refreshModelState = refreshModelService.state
disposables.push(
refreshModelService.onDidChangeState(() => {
refreshModelService.onDidChangeState((providerName) => {
refreshModelState = refreshModelService.state
refreshModelStateListeners.forEach(l => l(refreshModelState))
refreshModelProviderListeners.forEach(l => l(providerName, refreshModelState))
})
)
@ -148,7 +150,12 @@ export const useRefreshModelState = () => {
}
export const useRefreshModelListener = (listener: (providerName: RefreshableProviderName, s: RefreshModelStateOfProvider) => void) => {
useEffect(() => {
refreshModelProviderListeners.add(listener)
return () => { refreshModelProviderListeners.delete(listener) }
}, [listener])
}
export const useIsDark = () => {

View file

@ -3,7 +3,7 @@ import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox
import { ProviderName, SettingName, displayInfoOfSettingName, titleOfProviderName, providerNames, ModelInfo } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js'
import { VoidInputBox, VoidSelectBox } from '../util/inputs.js'
import { useIsDark, useRefreshModelState, useService, useSettingsState } from '../util/services.js'
import { useIsDark, useRefreshModelListener, useRefreshModelState, useService, useSettingsState } from '../util/services.js'
import { X, RefreshCw, Loader2, Check } from 'lucide-react'
import { RefreshableProviderName, refreshableProviderNames } from '../../../../../../../platform/void/common/refreshModelService.js'
@ -14,17 +14,21 @@ const RefreshModelButton = ({ providerName }: { providerName: RefreshableProvide
const refreshModelState = useRefreshModelState()
const refreshModelService = useService('refreshModelService')
const [justFinished, setJustSucceeded] = useState(false)
useRefreshModelListener(
useCallback((providerName2, refreshModelState) => {
if (providerName2 !== providerName) return
const { state } = refreshModelState[providerName]
if (state !== 'success') return
// now we know we just entered 'success' state for this providerName
setJustSucceeded(true)
const tid = setTimeout(() => { setJustSucceeded(false) }, 2000)
return () => clearTimeout(tid)
}, [providerName])
)
const [justFinished, setJustFinished] = useState(false)
const { state } = refreshModelState[providerName]
useEffect(() => {
if (state !== 'success') return
// if no longer refreshing
setJustFinished(true)
const tid = setTimeout(() => { setJustFinished(false) }, 2000)
return () => clearTimeout(tid)
}, [state])
const isRefreshing = state === 'refreshing'
const providerTitle = titleOfProviderName(providerName)
@ -283,9 +287,11 @@ export const Settings = () => {
<RefreshableModels />
</ErrorBoundary>
<h2 className={`text-3xl mt-4 mb-2`}>Providers</h2>
<ErrorBoundary>
<VoidProviderSettings />
</ErrorBoundary>
<div className='px-3'>
<ErrorBoundary>
<VoidProviderSettings />
</ErrorBoundary>
</div>
</div>
<div className={`${tab !== 'features' ? 'hidden' : ''}`}>