-
Notifications
You must be signed in to change notification settings - Fork 736
Expand file tree
/
Copy pathfilesCategoryNode.ts
More file actions
118 lines (106 loc) · 4.64 KB
/
filesCategoryNode.ts
File metadata and controls
118 lines (106 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ViewedState } from '../../common/comment';
import Logger, { PR_TREE } from '../../common/logger';
import { FILE_LIST_LAYOUT, HIDE_VIEWED_FILES, PR_SETTINGS_NAMESPACE } from '../../common/settingKeys';
import { compareIgnoreCase } from '../../common/utils';
import { PullRequestModel } from '../../github/pullRequestModel';
import { ReviewModel } from '../reviewModel';
import { DirectoryTreeNode } from './directoryTreeNode';
import { LabelOnlyNode, TreeNode, TreeNodeParent } from './treeNode';
export class FilesCategoryNode extends TreeNode implements vscode.TreeItem {
public override readonly label: string = vscode.l10n.t('Files');
public collapsibleState: vscode.TreeItemCollapsibleState;
private directories: TreeNode[] = [];
constructor(
parent: TreeNodeParent,
private _reviewModel: ReviewModel,
_pullRequestModel: PullRequestModel
) {
super(parent);
this.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
this.childrenDisposables = [];
this.childrenDisposables.push(this._reviewModel.onDidChangeLocalFileChanges(() => {
Logger.appendLine(`Local files have changed, refreshing Files node`, PR_TREE);
this.refresh(this);
}));
this.childrenDisposables.push(_pullRequestModel.onDidChangeReviewThreads(() => {
Logger.appendLine(`Review threads have changed, refreshing Files node`, PR_TREE);
this.refresh(this);
}));
this.childrenDisposables.push(_pullRequestModel.onDidChange(e => {
if (e.comments) {
Logger.appendLine(`Comments have changed, refreshing Files node`, PR_TREE);
this.refresh(this);
}
}));
this.childrenDisposables.push(_pullRequestModel.onDidChangeFileViewedState(() => {
Logger.appendLine(`File viewed state has changed, refreshing Files node`, PR_TREE);
this.refresh(this);
}));
this.childrenDisposables.push(vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(`${PR_SETTINGS_NAMESPACE}.${HIDE_VIEWED_FILES}`)) {
Logger.appendLine(`Hide viewed files setting has changed, refreshing Files node`, PR_TREE);
this.refresh(this);
}
}));
}
getTreeItem(): vscode.TreeItem {
return this;
}
override async getChildren(): Promise<TreeNode[]> {
super.getChildren(false);
Logger.appendLine(`Getting children for Files node`, PR_TREE);
if (!this._reviewModel.hasLocalFileChanges) {
// Provide loading feedback until we get the files.
return new Promise<TreeNode[]>(resolve => {
const promiseResolver = this._reviewModel.onDidChangeLocalFileChanges(() => {
resolve([]);
promiseResolver.dispose();
});
});
}
if (this._reviewModel.localFileChanges.length === 0) {
return [new LabelOnlyNode(this, vscode.l10n.t('No changed files'))];
}
let nodes: TreeNode[];
const layout = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE).get<string>(FILE_LIST_LAYOUT);
const hideViewedFiles = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE).get<boolean>(HIDE_VIEWED_FILES, false);
// Filter files based on hideViewedFiles setting
const filesToShow = hideViewedFiles
? this._reviewModel.localFileChanges.filter(f => f.changeModel.viewed !== ViewedState.VIEWED)
: this._reviewModel.localFileChanges;
if (filesToShow.length === 0 && hideViewedFiles) {
return [new LabelOnlyNode(this, vscode.l10n.t('All files viewed'))];
}
const dirNode = new DirectoryTreeNode(this, '');
filesToShow.forEach(f => dirNode.addFile(f));
dirNode.finalize();
if (dirNode.label === '') {
// nothing on the root changed, pull children to parent
this.directories = dirNode._children;
this.directories.forEach(child => { child.parent = this; });
} else {
this.directories = [dirNode];
}
if (layout === 'tree') {
nodes = this.directories;
} else {
const fileNodes = [...filesToShow];
fileNodes.sort((a, b) => compareIgnoreCase(a.fileChangeResourceUri.toString(), b.fileChangeResourceUri.toString()));
// In flat layout, files are rendered as direct children of this node.
// Keep parent pointers aligned with the rendered hierarchy so reveal/getParent
// don't try to walk through hidden DirectoryTreeNode instances.
fileNodes.forEach(fileNode => {
fileNode.parent = this;
});
nodes = fileNodes;
}
Logger.appendLine(`Got all children for Files node`, PR_TREE);
this._children = nodes;
return nodes;
}
}