Sessions - move more code into the view model (#306951)

* Sessions - move more code into the view model

* Hide the path in the tree
This commit is contained in:
Ladislau Szomoru
2026-03-31 22:20:10 +00:00
committed by GitHub
parent f7c3f8d5fd
commit b37b15b44d

View File

@@ -257,6 +257,8 @@ class ChangesViewModel extends Disposable {
readonly activeSessionIsolationModeObs: IObservable<IsolationMode>;
readonly activeSessionRepositoryObs: IObservableWithChange<IGitRepository | undefined>;
readonly activeSessionChangesObs: IObservable<readonly (IChatSessionFileChange | IChatSessionFileChange2)[]>;
readonly activeSessionReviewCommentCountByFileObs: IObservable<Map<string, number>>;
readonly activeSessionAgentFeedbackCountByFileObs: IObservable<Map<string, number>>;
readonly activeSessionHasGitRepositoryObs: IObservable<boolean>;
readonly activeSessionFirstCheckpointRefObs: IObservable<string | undefined>;
readonly activeSessionLastCheckpointRefObs: IObservable<string | undefined>;
@@ -279,7 +281,9 @@ class ChangesViewModel extends Disposable {
}
constructor(
@IAgentFeedbackService private readonly agentFeedbackService: IAgentFeedbackService,
@IAgentSessionsService private readonly agentSessionsService: IAgentSessionsService,
@ICodeReviewService private readonly codeReviewService: ICodeReviewService,
@IGitService private readonly gitService: IGitService,
@ISessionsManagementService private readonly sessionManagementService: ISessionsManagementService,
@IStorageService private readonly storageService: IStorageService,
@@ -404,6 +408,62 @@ class ChangesViewModel extends Disposable {
return model?.metadata?.lastCheckpointRef as string | undefined;
});
this.activeSessionReviewCommentCountByFileObs = derived(reader => {
const sessionResource = this.activeSessionResourceObs.read(reader);
const changes = [...this.activeSessionChangesObs.read(reader)];
if (!sessionResource) {
return new Map<string, number>();
}
const result = new Map<string, number>();
const prReviewState = this.codeReviewService.getPRReviewState(sessionResource).read(reader);
if (prReviewState.kind === PRReviewStateKind.Loaded) {
for (const comment of prReviewState.comments) {
const uriKey = comment.uri.fsPath;
result.set(uriKey, (result.get(uriKey) ?? 0) + 1);
}
}
if (changes.length === 0) {
return result;
}
const reviewFiles = getCodeReviewFilesFromSessionChanges(changes as readonly IChatSessionFileChange[] | readonly IChatSessionFileChange2[]);
const reviewVersion = getCodeReviewVersion(reviewFiles);
const reviewState = this.codeReviewService.getReviewState(sessionResource).read(reader);
if (reviewState.kind !== CodeReviewStateKind.Result || reviewState.version !== reviewVersion) {
return result;
}
for (const comment of reviewState.comments) {
const uriKey = comment.uri.fsPath;
result.set(uriKey, (result.get(uriKey) ?? 0) + 1);
}
return result;
});
this.activeSessionAgentFeedbackCountByFileObs = derived(reader => {
const sessionResource = this.activeSessionResourceObs.read(reader);
if (!sessionResource) {
return new Map<string, number>();
}
observableSignalFromEvent(this, this.agentFeedbackService.onDidChangeFeedback).read(reader);
const feedbackItems = this.agentFeedbackService.getFeedback(sessionResource);
const result = new Map<string, number>();
for (const item of feedbackItems) {
if (!item.sourcePRReviewCommentId) {
const uriKey = item.resourceUri.fsPath;
result.set(uriKey, (result.get(uriKey) ?? 0) + 1);
}
}
return result;
});
// Version mode
this.versionModeObs = observableValue<ChangesVersionMode>(this, ChangesVersionMode.BranchChanges);
@@ -464,7 +524,6 @@ export class ChangesViewPane extends ViewPane {
@ILabelService private readonly labelService: ILabelService,
@ICodeReviewService private readonly codeReviewService: ICodeReviewService,
@IGitHubService private readonly gitHubService: IGitHubService,
@IAgentFeedbackService private readonly agentFeedbackService: IAgentFeedbackService,
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
) {
super({ ...options, titleMenuId: MenuId.ChatEditingSessionTitleToolbar }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, hoverService);
@@ -660,66 +719,10 @@ export class ChangesViewPane extends ViewPane {
private onVisible(): void {
this.renderDisposables.clear();
const reviewCommentCountByFileObs = derived(reader => {
const sessionResource = this.viewModel.activeSessionResourceObs.read(reader);
const changes = [...this.viewModel.activeSessionChangesObs.read(reader)];
if (!sessionResource) {
return new Map<string, number>();
}
const result = new Map<string, number>();
const prReviewState = this.codeReviewService.getPRReviewState(sessionResource).read(reader);
if (prReviewState.kind === PRReviewStateKind.Loaded) {
for (const comment of prReviewState.comments) {
const uriKey = comment.uri.fsPath;
result.set(uriKey, (result.get(uriKey) ?? 0) + 1);
}
}
if (changes.length === 0) {
return result;
}
const reviewFiles = getCodeReviewFilesFromSessionChanges(changes as readonly IChatSessionFileChange[] | readonly IChatSessionFileChange2[]);
const reviewVersion = getCodeReviewVersion(reviewFiles);
const reviewState = this.codeReviewService.getReviewState(sessionResource).read(reader);
if (reviewState.kind !== CodeReviewStateKind.Result || reviewState.version !== reviewVersion) {
return result;
}
for (const comment of reviewState.comments) {
const uriKey = comment.uri.fsPath;
result.set(uriKey, (result.get(uriKey) ?? 0) + 1);
}
return result;
});
const agentFeedbackCountByFileObs = derived(reader => {
const sessionResource = this.viewModel.activeSessionResourceObs.read(reader);
if (!sessionResource) {
return new Map<string, number>();
}
observableSignalFromEvent(this, this.agentFeedbackService.onDidChangeFeedback).read(reader);
const feedbackItems = this.agentFeedbackService.getFeedback(sessionResource);
const result = new Map<string, number>();
for (const item of feedbackItems) {
if (!item.sourcePRReviewCommentId) {
const uriKey = item.resourceUri.fsPath;
result.set(uriKey, (result.get(uriKey) ?? 0) + 1);
}
}
return result;
});
// Convert session file changes to list items (cloud/background sessions)
const sessionFilesObs = derived(reader => {
const reviewCommentCountByFile = reviewCommentCountByFileObs.read(reader);
const agentFeedbackCountByFile = agentFeedbackCountByFileObs.read(reader);
const reviewCommentCountByFile = this.viewModel.activeSessionReviewCommentCountByFileObs.read(reader);
const agentFeedbackCountByFile = this.viewModel.activeSessionAgentFeedbackCountByFileObs.read(reader);
const changes = [...this.viewModel.activeSessionChangesObs.read(reader)];
return changes.map((entry): IChangesFileItem => {
@@ -1582,7 +1585,7 @@ class ChangesTreeRenderer implements ICompressibleTreeRenderer<ChangesTreeElemen
fileKind: FileKind.FILE,
fileDecorations: undefined,
strikethrough: data.changeType === 'deleted',
hidePath: false
hidePath: this.viewModel.viewModeObs.get() === ChangesViewMode.Tree
});
const showChangeDecorations = data.changeType !== 'none';
@@ -1798,7 +1801,9 @@ class ChangesPickerActionItem extends ActionWidgetDropdownActionViewItem {
? localize('chatEditing.versionsBranchChanges', 'Branch Changes')
: localize('chatEditing.versionsFolderChanges', 'Folder Changes'),
description: hasGitRepository
? `${branchName}${baseBranchName}`
? branchName && baseBranchName
? `${branchName}${baseBranchName}`
: branchName
: this.workspaceContextService.getWorkspace().folders[0]?.uri.fsPath,
checked: viewModel.versionModeObs.get() === ChangesVersionMode.BranchChanges,
category: { label: 'changes', order: 1, showHeader: false },