diff --git a/src/plus/integrations/authentication/configuredIntegrationService.ts b/src/plus/integrations/authentication/configuredIntegrationService.ts index 7fd3b39b6c761..01064e33c5e41 100644 --- a/src/plus/integrations/authentication/configuredIntegrationService.ts +++ b/src/plus/integrations/authentication/configuredIntegrationService.ts @@ -1,7 +1,10 @@ +import type { Event } from 'vscode'; +import { EventEmitter } from 'vscode'; import type { IntegrationId } from '../../../constants.integrations'; import { HostingIntegrationId } from '../../../constants.integrations'; import type { StoredConfiguredIntegrationDescriptor } from '../../../constants.storage'; import type { Container } from '../../../container'; +import { debounce } from '../../../system/function'; import { flatten } from '../../../system/iterable'; import { getBuiltInIntegrationSession } from '../../gk/utils/-webview/integrationAuthentication.utils'; import { isSelfHostedIntegrationId, providersMetadata } from '../providers/models'; @@ -24,7 +27,16 @@ interface StoredSession { export type ConfiguredIntegrationType = 'cloud' | 'local'; +export interface ConfiguredIntegrationsChangeEvent { + ids: IntegrationId[]; +} + export class ConfiguredIntegrationService { + private readonly _onDidChange = new EventEmitter(); + get onDidChange(): Event { + return this._onDidChange.event; + } + private _configured?: Map; constructor(private readonly container: Container) {} @@ -165,6 +177,7 @@ export class ConfiguredIntegrationService { descriptors.push(descriptor); this.configured.set(descriptor.integrationId, descriptors); + this.queueDidChange(descriptor.integrationId); await this.storeConfigured(); } @@ -187,6 +200,7 @@ export class ConfiguredIntegrationService { } this.configured.set(id, descriptors ?? []); + this.queueDidChange(id); await this.storeConfigured(); } @@ -346,6 +360,18 @@ export class ConfiguredIntegrationService { getSessionId(descriptor: IntegrationAuthenticationSessionDescriptor): string { return descriptor.domain; } + + private changedIds = new Set(); + private debouncedFireDidChange?: () => void; + private queueDidChange(id: IntegrationId) { + this.debouncedFireDidChange ??= debounce(() => { + this._onDidChange.fire({ ids: [...this.changedIds] }); + this.changedIds.clear(); + }, 300); + + this.changedIds.add(id); + this.debouncedFireDidChange(); + } } function convertStoredSessionToSession( diff --git a/src/plus/integrations/integrationService.ts b/src/plus/integrations/integrationService.ts index 7296621f94f15..87ebfe7e907e0 100644 --- a/src/plus/integrations/integrationService.ts +++ b/src/plus/integrations/integrationService.ts @@ -24,7 +24,10 @@ import { filterMap, flatten, join } from '../../system/iterable'; import { Logger } from '../../system/logger'; import { getLogScope } from '../../system/logger.scope'; import type { SubscriptionChangeEvent } from '../gk/subscriptionService'; -import type { ConfiguredIntegrationService } from './authentication/configuredIntegrationService'; +import type { + ConfiguredIntegrationsChangeEvent, + ConfiguredIntegrationService, +} from './authentication/configuredIntegrationService'; import type { IntegrationAuthenticationService } from './authentication/integrationAuthenticationService'; import type { ConfiguredIntegrationDescriptor } from './authentication/models'; import { @@ -69,6 +72,10 @@ export class IntegrationService implements Disposable { return this._onDidSyncCloudIntegrations.event; } + get onDidChangeConfiguredIntegrations(): Event { + return this.configuredIntegrationService.onDidChange; + } + private readonly _connectedCache = new Set(); private readonly _disposable: Disposable; private _integrations = new Map(); diff --git a/src/webviews/home/homeWebview.ts b/src/webviews/home/homeWebview.ts index 3431fe6d5ec3b..79185cee9e54a 100644 --- a/src/webviews/home/homeWebview.ts +++ b/src/webviews/home/homeWebview.ts @@ -41,6 +41,7 @@ import { showPatchesView } from '../../plus/drafts/actions'; import type { Subscription } from '../../plus/gk/models/subscription'; import type { SubscriptionChangeEvent } from '../../plus/gk/subscriptionService'; import { isSubscriptionStatePaidOrTrial } from '../../plus/gk/utils/subscription.utils'; +import type { ConfiguredIntegrationsChangeEvent } from '../../plus/integrations/authentication/configuredIntegrationService'; import { providersMetadata } from '../../plus/integrations/providers/models'; import type { LaunchpadCategorizedResult } from '../../plus/launchpad/launchpadProvider'; import { getLaunchpadItemGroups } from '../../plus/launchpad/launchpadProvider'; @@ -157,7 +158,7 @@ export class HomeWebviewProvider implements WebviewProvider