11import type { Disposable , Uri } from 'vscode' ;
22import { workspace } from 'vscode' ;
3+ import type { AIFeedbackEvent } from '../constants.telemetry' ;
34import type { AIResultContext } from '../plus/ai/aiProviderService' ;
45import { setContext } from '../system/-webview/context' ;
6+ import { UriMap } from '../system/-webview/uriMap' ;
57import type { Deferrable } from '../system/function/debounce' ;
68import { debounce } from '../system/function/debounce' ;
9+ import { filterMap } from '../system/iterable' ;
710
811export class AIFeedbackProvider implements Disposable {
912 constructor ( ) {
@@ -26,8 +29,10 @@ export class AIFeedbackProvider implements Disposable {
2629 private readonly _disposables : Disposable [ ] = [ ] ;
2730 dispose ( ) : void {
2831 this . _disposables . forEach ( d => void d . dispose ( ) ) ;
32+ this . _uriResponses . clear ( ) ;
2933 this . _changelogFeedbacks . clear ( ) ;
3034 this . _changelogUris . clear ( ) ;
35+ this . _updateFeedbackContextDebounced = undefined ;
3136 this . _updateChangelogContextDebounced = undefined ;
3237 }
3338
@@ -64,4 +69,29 @@ export class AIFeedbackProvider implements Disposable {
6469 private deleteChangelogFeedback ( documentUri : string ) : void {
6570 this . _changelogFeedbacks . delete ( documentUri ) ;
6671 }
72+
73+ // Storage for AI feedback responses by URI
74+ private readonly _uriResponses = new UriMap < AIFeedbackEvent [ 'sentiment' ] > ( ) ;
75+ private _updateFeedbackContextDebounced : Deferrable < ( ) => void > | undefined ;
76+ private updateFeedbackContext ( ) : void {
77+ this . _updateFeedbackContextDebounced ??= debounce ( ( ) => {
78+ void setContext ( 'gitlens:tabs:ai:helpful' , [
79+ ...filterMap ( this . _uriResponses , ( [ uri , sentiment ] ) => ( sentiment === 'helpful' ? uri : undefined ) ) ,
80+ ] ) ;
81+ void setContext ( 'gitlens:tabs:ai:unhelpful' , [
82+ ...filterMap ( this . _uriResponses , ( [ uri , sentiment ] ) => ( sentiment === 'unhelpful' ? uri : undefined ) ) ,
83+ ] ) ;
84+ } , 100 ) ;
85+ this . _updateFeedbackContextDebounced ( ) ;
86+ }
87+ setFeedbackResponse ( uri : Uri , sentiment : AIFeedbackEvent [ 'sentiment' ] ) : void {
88+ const previous = this . _uriResponses . get ( uri ) ;
89+ if ( sentiment === previous ) return ;
90+
91+ this . _uriResponses . set ( uri , sentiment ) ;
92+ this . updateFeedbackContext ( ) ;
93+ }
94+ getFeedbackResponse ( uri : Uri ) : AIFeedbackEvent [ 'sentiment' ] | undefined {
95+ return this . _uriResponses . get ( uri ) ;
96+ }
6797}
0 commit comments