diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx index dc67784c..90455ee0 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx @@ -5,7 +5,7 @@ import React, { useState, useEffect, useCallback } from 'react' import { MCPUserState, RefreshableProviderName, SettingsOfProvider } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js' -import { IDisposable } from '../../../../../../../base/common/lifecycle.js' +import { DisposableStore, IDisposable } from '../../../../../../../base/common/lifecycle.js' import { VoidSettingsState } from '../../../../../../../workbench/contrib/void/common/voidSettingsService.js' import { ColorScheme } from '../../../../../../../platform/theme/common/theme.js' import { RefreshModelStateOfProvider } from '../../../../../../../workbench/contrib/void/common/refreshModelService.js' @@ -52,6 +52,8 @@ import { ITerminalService } from '../../../../../terminal/browser/terminal.js' import { ISearchService } from '../../../../../../services/search/common/search.js' import { IExtensionManagementService } from '../../../../../../../platform/extensionManagement/common/extensionManagement.js' import { IMCPService } from '../../../../common/mcpService.js'; +import { IStorageService, StorageScope } from '../../../../../../../platform/storage/common/storage.js' +import { OPT_OUT_KEY } from '../../../../common/storageKeys.js' // normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes @@ -226,6 +228,8 @@ const getReactAccessor = (accessor: ServicesAccessor) => { IExtensionTransferService: accessor.get(IExtensionTransferService), IMCPService: accessor.get(IMCPService), + IStorageService: accessor.get(IStorageService), + } as const return reactAccessor } @@ -399,3 +403,26 @@ export const useMCPServiceState = () => { return s } + + +export const useIsOptedOut = () => { + const accessor = useAccessor() + const storageService = accessor.get('IStorageService') + + const getVal = useCallback(() => { + return storageService.getBoolean(OPT_OUT_KEY, StorageScope.APPLICATION, false) + }, [storageService]) + + const [s, ss] = useState(getVal()) + + useEffect(() => { + const disposables = new DisposableStore(); + const d = storageService.onDidChangeValue(StorageScope.APPLICATION, OPT_OUT_KEY, disposables)(e => { + ss(getVal()) + }) + disposables.add(d) + return () => disposables.clear() + }, [storageService, getVal]) + + return s +} diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index c8ba4da4..acc3c6d6 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -7,7 +7,7 @@ import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react' import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidStatefulModelInfo, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, nonlocalProviderNames, localProviderNames, GlobalSettingName, featureNames, displayInfoOfFeatureName, isProviderNameDisabled, FeatureName, hasDownloadButtonsOnModelsProviderNames, subTextMdOfProviderName } from '../../../../common/voidSettingsTypes.js' import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' import { VoidButtonBgDarken, VoidCustomDropdownBox, VoidInputBox2, VoidSimpleInputBox, VoidSwitch } from '../util/inputs.js' -import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' +import { useAccessor, useIsDark, useIsOptedOut, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' import { X, RefreshCw, Loader2, Check, Asterisk, Plus } from 'lucide-react' import { URI } from '../../../../../../../base/common/uri.js' import { ModelDropdown } from './ModelDropdown.js' @@ -21,6 +21,8 @@ import { getModelCapabilities, modelOverrideKeys, ModelOverrides } from '../../. import { TransferEditorType, TransferFilesInfo } from '../../../extensionTransferTypes.js'; import { MCPServer } from '../../../../common/mcpServiceTypes.js'; import { useMCPServiceState } from '../util/services.js'; +import { OPT_OUT_KEY } from '../../../../common/storageKeys.js'; +import { StorageScope, StorageTarget } from '../../../../../../../platform/storage/common/storage.js'; type Tab = | 'models' @@ -215,10 +217,10 @@ const SimpleModelSettingsDialog = ({ if (!isOpen || !modelInfo) return null; const { modelName, providerName, type } = modelInfo; - const accessor = useAccessor(); - const settingsState = useSettingsState(); + const accessor = useAccessor() + const settingsState = useSettingsState() const mouseDownInsideModal = useRef(false); // Ref to track mousedown origin - const settingsStateService = accessor.get('IVoidSettingsService'); + const settingsStateService = accessor.get('IVoidSettingsService') // current overrides and defaults const defaultModelCapabilities = getModelCapabilities(providerName, modelName, undefined); @@ -1036,7 +1038,7 @@ export const Settings = () => { const navItems: { tab: Tab; label: string }[] = [ { tab: 'models', label: 'Models' }, { tab: 'localProviders', label: 'Local Providers' }, - { tab: 'providers', label: 'Other Providers' }, + { tab: 'providers', label: 'Main Providers' }, { tab: 'featureOptions', label: 'Feature Options' }, { tab: 'general', label: 'General' }, { tab: 'mcp', label: 'MCP' }, @@ -1052,6 +1054,9 @@ export const Settings = () => { const chatThreadsService = accessor.get('IChatThreadService') const notificationService = accessor.get('INotificationService') const mcpService = accessor.get('IMCPService') + const storageService = accessor.get('IStorageService') + const metricsService = accessor.get('IMetricsService') + const isOptedOut = useIsOptedOut() const onDownload = (t: 'Chats' | 'Settings') => { let dataStr: string @@ -1194,10 +1199,10 @@ export const Settings = () => { - {/* Other Providers section */} + {/* Main Providers section */}