@codingame/monaco-vscode-scm-service-override 9.0.2 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,20 +1,19 @@
1
1
  import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
2
  import './media/scm.css.js';
3
- import { Event } from 'vscode/vscode/vs/base/common/event';
4
3
  import { language } from 'vscode/vscode/vs/base/common/platform';
5
- import { append, $ } from 'vscode/vscode/vs/base/browser/dom';
6
- import { getDefaultHoverDelegate } from 'vscode/vscode/vs/base/browser/ui/hover/hoverDelegateFactory';
4
+ import { $, reset, append, h } from 'vscode/vscode/vs/base/browser/dom';
7
5
  import { IconLabel } from 'vscode/vscode/vs/base/browser/ui/iconLabel/iconLabel';
8
6
  import { fromNow } from 'vscode/vscode/vs/base/common/date';
9
7
  import { createMatches } from 'vscode/vscode/vs/base/common/filters';
10
8
  import { MarkdownString } from 'vscode/vscode/vs/base/common/htmlContent';
11
- import { DisposableStore, combinedDisposable, Disposable, DisposableMap } from 'vscode/vscode/vs/base/common/lifecycle';
9
+ import { DisposableStore, Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
12
10
  import { observableValue } from 'vscode/vscode/vs/base/common/observableInternal/base';
13
- import 'vscode/vscode/vs/base/common/observableInternal/derived';
11
+ import { tail, delta, groupBy as groupBy$1 } from 'vscode/vscode/vs/base/common/arrays';
12
+ import { Event } from 'vscode/vscode/vs/base/common/event';
14
13
  import { autorun, autorunWithStore } from 'vscode/vscode/vs/base/common/observableInternal/autorun';
15
- import 'vscode/vscode/vs/base/common/observableInternal/utils';
16
- import 'vscode/vscode/vs/base/common/cancellation';
17
- import { tail } from 'vscode/vscode/vs/base/common/arrays';
14
+ import { derived } from 'vscode/vscode/vs/base/common/observableInternal/derived';
15
+ import { waitForState } from 'vscode/vscode/vs/base/common/observableInternal/utilsCancellation';
16
+ import { observableFromEvent, constObservable, latestChangedValue, observableSignal, runOnChange } from 'vscode/vscode/vs/base/common/observableInternal/utils';
18
17
  import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
19
18
  import { localize } from 'vscode/vscode/vs/nls';
20
19
  import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration.service';
@@ -26,11 +25,10 @@ import { IHoverService } from 'vscode/vscode/vs/platform/hover/browser/hover.ser
26
25
  import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
27
26
  import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding.service';
28
27
  import { WorkbenchAsyncDataTree } from 'vscode/vscode/vs/platform/list/browser/listService';
29
- import { observableConfigValue } from 'vscode/vscode/vs/platform/observable/common/platformObservableUtils';
30
28
  import { IOpenerService } from 'vscode/vscode/vs/platform/opener/common/opener.service';
31
29
  import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry.service';
32
- import { registerColor } from 'vscode/vscode/vs/platform/theme/common/colorUtils';
33
- import 'vscode/vscode/vs/platform/theme/common/colors/baseColors';
30
+ import { asCssVariable } from 'vscode/vscode/vs/platform/theme/common/colorUtils';
31
+ import { foreground } from 'vscode/vscode/vs/platform/theme/common/colors/baseColors';
34
32
  import 'vscode/vscode/vs/platform/theme/common/colors/chartsColors';
35
33
  import 'vscode/vscode/vs/platform/theme/common/colors/editorColors';
36
34
  import 'vscode/vscode/vs/platform/theme/common/colors/inputColors';
@@ -41,59 +39,234 @@ import 'vscode/vscode/vs/platform/theme/common/colors/miscColors';
41
39
  import 'vscode/vscode/vs/platform/theme/common/colors/quickpickColors';
42
40
  import 'vscode/vscode/vs/platform/theme/common/colors/searchColors';
43
41
  import { IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService.service';
44
- import { ViewAction, ViewPane } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
45
- import { ViewContainerLocation } from 'vscode/vscode/vs/workbench/common/views';
42
+ import { ViewAction, ViewPane, ViewPaneShowActions } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
46
43
  import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views.service';
47
- import { renderSCMHistoryItemGraph, historyItemGroupLocal, historyItemGroupRemote, historyItemGroupBase, historyItemGroupHoverLabelForeground, SWIMLANE_WIDTH, renderSCMHistoryGraphPlaceholder, toISCMHistoryItemViewModelArray } from './scmHistory.js';
48
- import { RepositoryActionRunner } from './scmRepositoryRenderer.js';
49
- import { isSCMRepository, isSCMHistoryItemViewModelTreeElement, isSCMHistoryItemLoadMoreTreeElement, connectPrimaryMenu, isSCMViewService, getActionViewItemProvider, collectContextMenuActions } from './util.js';
44
+ import { renderSCMHistoryItemGraph, historyItemHoverLabelForeground, historyItemHoverDefaultLabelBackground, historyItemHoverAdditionsForeground, historyItemHoverDeletionsForeground, historyItemHoverDefaultLabelForeground, SWIMLANE_WIDTH, renderSCMHistoryGraphPlaceholder, toISCMHistoryItemViewModelArray } from 'vscode/vscode/vs/workbench/contrib/scm/browser/scmHistory';
45
+ import { getHistoryItemEditorTitle, isSCMHistoryItemViewModelTreeElement, isSCMHistoryItemLoadMoreTreeElement, isSCMRepository, getProviderKey } from 'vscode/vscode/vs/workbench/contrib/scm/browser/util';
50
46
  import { HISTORY_VIEW_PANE_ID } from 'vscode/vscode/vs/workbench/contrib/scm/common/scm';
51
47
  import { ISCMService, ISCMViewService } from 'vscode/vscode/vs/workbench/contrib/scm/common/scm.service';
52
48
  import { stripIcons } from 'vscode/vscode/vs/base/common/iconLabels';
53
- import { Position } from 'vscode/vscode/vs/workbench/services/layout/browser/layoutService';
54
49
  import { IWorkbenchLayoutService } from 'vscode/vscode/vs/workbench/services/layout/browser/layoutService.service';
55
- import { HoverPosition } from 'vscode/vscode/vs/base/browser/ui/hover/hoverWidget';
56
- import { registerAction2, MenuId, MenuItemAction } from 'vscode/vscode/vs/platform/actions/common/actions';
57
- import { IMenuService } from 'vscode/vscode/vs/platform/actions/common/actions.service';
58
- import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
50
+ import { registerAction2, MenuId, Action2 } from 'vscode/vscode/vs/platform/actions/common/actions';
59
51
  import { Sequencer, Throttler } from 'vscode/vscode/vs/base/common/async';
60
52
  import { URI } from 'vscode/vscode/vs/base/common/uri';
61
53
  import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands.service';
62
54
  import { ActionRunner } from 'vscode/vscode/vs/base/common/actions';
63
55
  import { Codicon } from 'vscode/vscode/vs/base/common/codicons';
64
- import { ContextKeys } from './scmViewPane.js';
65
- import { WorkbenchToolBar } from 'vscode/vscode/vs/platform/actions/browser/toolbar';
66
56
  import { IProgressService } from 'vscode/vscode/vs/platform/progress/common/progress.service';
57
+ import { ContextKeys } from './scmViewPane.js';
58
+ import { ActionViewItem } from 'vscode/vscode/vs/base/browser/ui/actionbar/actionViewItems';
59
+ import { IQuickInputService } from 'vscode/vscode/vs/platform/quickinput/common/quickInput.service';
60
+ import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
61
+ import { clamp } from 'vscode/vscode/vs/base/common/numbers';
62
+ import { observableConfigValue } from 'vscode/vscode/vs/platform/observable/common/platformObservableUtils';
63
+ import { compare } from 'vscode/vscode/vs/base/common/strings';
64
+ import { IClipboardService } from 'vscode/vscode/vs/platform/clipboard/common/clipboardService.service';
65
+ import { getDefaultHoverDelegate } from 'vscode/vscode/vs/base/browser/ui/hover/hoverDelegateFactory';
66
+ import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service';
67
+ import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification.service';
68
+ import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions.service';
69
+ import { groupBy } from 'vscode/vscode/vs/base/common/collections';
67
70
 
68
- var RepositoryRenderer_1, HistoryItemRenderer_1, HistoryItemLoadMoreRenderer_1;
69
- const historyItemAdditionsForeground = registerColor('scmGraph.historyItemHoverAdditionsForeground', 'gitDecoration.addedResourceForeground', ( localize(6467, "History item hover additions foreground color.")));
70
- const historyItemDeletionsForeground = registerColor('scmGraph.historyItemHoverDeletionsForeground', 'gitDecoration.deletedResourceForeground', ( localize(6468, "History item hover deletions foreground color.")));
71
+ var HistoryItemRenderer_1, HistoryItemLoadMoreRenderer_1;
72
+ const PICK_REPOSITORY_ACTION_ID = 'workbench.scm.action.graph.pickRepository';
73
+ const PICK_HISTORY_ITEM_REFS_ACTION_ID = 'workbench.scm.action.graph.pickHistoryItemRefs';
74
+ class SCMRepositoryActionViewItem extends ActionViewItem {
75
+ constructor(_repository, action, options) {
76
+ super(null, action, { ...options, icon: false, label: true });
77
+ this._repository = _repository;
78
+ }
79
+ updateLabel() {
80
+ if (this.options.label && this.label) {
81
+ this.label.classList.add('scm-graph-repository-picker');
82
+ const icon = $('.icon');
83
+ icon.classList.add(...ThemeIcon.asClassNameArray(Codicon.repo));
84
+ const name = $('.name');
85
+ name.textContent = this._repository.provider.name;
86
+ reset(this.label, icon, name);
87
+ }
88
+ }
89
+ getTooltip() {
90
+ return this._repository.provider.name;
91
+ }
92
+ }
93
+ class SCMHistoryItemRefsActionViewItem extends ActionViewItem {
94
+ constructor(_repository, _historyItemsFilter, action, options) {
95
+ super(null, action, { ...options, icon: false, label: true });
96
+ this._repository = _repository;
97
+ this._historyItemsFilter = _historyItemsFilter;
98
+ }
99
+ updateLabel() {
100
+ if (this.options.label && this.label) {
101
+ this.label.classList.add('scm-graph-history-item-picker');
102
+ const icon = $('.icon');
103
+ icon.classList.add(...ThemeIcon.asClassNameArray(Codicon.gitBranch));
104
+ const name = $('.name');
105
+ if (this._historyItemsFilter === 'all') {
106
+ name.textContent = ( localize(6622, "All"));
107
+ }
108
+ else if (this._historyItemsFilter === 'auto') {
109
+ name.textContent = ( localize(6623, "Auto"));
110
+ }
111
+ else if (this._historyItemsFilter.length === 1) {
112
+ name.textContent = this._historyItemsFilter[0].name;
113
+ }
114
+ else {
115
+ name.textContent = ( localize(6624, "{0} Items", this._historyItemsFilter.length));
116
+ }
117
+ reset(this.label, icon, name);
118
+ }
119
+ }
120
+ getTooltip() {
121
+ if (this._historyItemsFilter === 'all') {
122
+ return ( localize(6625, "All history item references"));
123
+ }
124
+ else if (this._historyItemsFilter === 'auto') {
125
+ const historyProvider = this._repository.provider.historyProvider.get();
126
+ return [
127
+ historyProvider?.historyItemRef.get()?.name,
128
+ historyProvider?.historyItemRemoteRef.get()?.name,
129
+ historyProvider?.historyItemBaseRef.get()?.name
130
+ ].filter(ref => !!ref).join(', ');
131
+ }
132
+ else if (this._historyItemsFilter.length === 1) {
133
+ return this._historyItemsFilter[0].name;
134
+ }
135
+ else {
136
+ return ( (this._historyItemsFilter.map(ref => ref.name))).join(', ');
137
+ }
138
+ }
139
+ }
71
140
  registerAction2(class extends ViewAction {
72
141
  constructor() {
73
142
  super({
74
- id: 'workbench.scm.action.refreshGraph',
75
- title: ( localize(6469, "Refresh")),
143
+ id: PICK_REPOSITORY_ACTION_ID,
144
+ title: ( localize(6626, "Repository Picker")),
76
145
  viewId: HISTORY_VIEW_PANE_ID,
77
146
  f1: false,
78
- icon: Codicon.refresh,
79
147
  menu: {
80
148
  id: MenuId.SCMHistoryTitle,
81
- when: ( (ContextKeyExpr.or(
82
- (ContextKeyExpr.has('scmRepository')),
83
- (ContextKeyExpr.and(
84
- (ContextKeys.RepositoryVisibilityCount.isEqualTo(1)),
85
- (ContextKeyExpr.equals('config.scm.alwaysShowRepositories', false))
86
- ))
149
+ when: ( (ContextKeyExpr.and(
150
+ (ContextKeyExpr.has('scm.providerCount')),
151
+ ContextKeyExpr.greater('scm.providerCount', 1)
87
152
  ))),
88
153
  group: 'navigation',
154
+ order: 0
155
+ }
156
+ });
157
+ }
158
+ async runInView(_, view) {
159
+ view.pickRepository();
160
+ }
161
+ });
162
+ registerAction2(class extends ViewAction {
163
+ constructor() {
164
+ super({
165
+ id: PICK_HISTORY_ITEM_REFS_ACTION_ID,
166
+ title: ( localize(6627, "History Item Reference Picker")),
167
+ icon: Codicon.gitBranch,
168
+ viewId: HISTORY_VIEW_PANE_ID,
169
+ precondition: ( (ContextKeys.SCMHistoryItemCount.notEqualsTo(0))),
170
+ f1: false,
171
+ menu: {
172
+ id: MenuId.SCMHistoryTitle,
173
+ group: 'navigation',
174
+ order: 1
175
+ }
176
+ });
177
+ }
178
+ async runInView(_, view) {
179
+ view.pickHistoryItemRef();
180
+ }
181
+ });
182
+ registerAction2(class extends ViewAction {
183
+ constructor() {
184
+ super({
185
+ id: 'workbench.scm.action.graph.revealCurrentHistoryItem',
186
+ title: ( localize(6628, "Go to Current History Item")),
187
+ icon: Codicon.target,
188
+ viewId: HISTORY_VIEW_PANE_ID,
189
+ precondition: ( (ContextKeys.SCMHistoryItemCount.notEqualsTo(0))),
190
+ f1: false,
191
+ menu: {
192
+ id: MenuId.SCMHistoryTitle,
193
+ group: 'navigation',
194
+ order: 2
195
+ }
196
+ });
197
+ }
198
+ async runInView(_, view) {
199
+ view.revealCurrentHistoryItem();
200
+ }
201
+ });
202
+ registerAction2(class extends ViewAction {
203
+ constructor() {
204
+ super({
205
+ id: 'workbench.scm.action.graph.refresh',
206
+ title: ( localize(6629, "Refresh")),
207
+ viewId: HISTORY_VIEW_PANE_ID,
208
+ f1: false,
209
+ icon: Codicon.refresh,
210
+ menu: {
211
+ id: MenuId.SCMHistoryTitle,
212
+ group: 'navigation',
89
213
  order: 1000
90
214
  }
91
215
  });
92
216
  }
93
- async runInView(accessor, view, provider) {
94
- const scmService = accessor.get(ISCMService);
95
- const repository = provider ? scmService.getRepository(provider.id) : undefined;
96
- view.refresh(repository);
217
+ async runInView(_, view) {
218
+ view.refresh();
219
+ }
220
+ });
221
+ registerAction2(class extends Action2 {
222
+ constructor() {
223
+ super({
224
+ id: 'workbench.scm.action.graph.viewChanges',
225
+ title: ( localize(6630, "View Changes")),
226
+ f1: false,
227
+ menu: [
228
+ {
229
+ id: MenuId.SCMChangesContext,
230
+ group: '0_view',
231
+ when: ( (ContextKeyExpr.equals('config.multiDiffEditor.experimental.enabled', true)))
232
+ }
233
+ ]
234
+ });
235
+ }
236
+ async run(accessor, provider, ...historyItems) {
237
+ const commandService = accessor.get(ICommandService);
238
+ if (!provider || historyItems.length === 0) {
239
+ return;
240
+ }
241
+ const historyItem = historyItems[0];
242
+ const historyItemLast = historyItems[historyItems.length - 1];
243
+ const historyProvider = provider.historyProvider.get();
244
+ if (historyItems.length > 1) {
245
+ const ancestor = await historyProvider?.resolveHistoryItemRefsCommonAncestor([historyItem.id, historyItemLast.id]);
246
+ if (!ancestor || (ancestor !== historyItem.id && ancestor !== historyItemLast.id)) {
247
+ return;
248
+ }
249
+ }
250
+ const historyItemParentId = historyItemLast.parentIds.length > 0 ? historyItemLast.parentIds[0] : undefined;
251
+ const historyItemChanges = await historyProvider?.provideHistoryItemChanges(historyItem.id, historyItemParentId);
252
+ if (!historyItemChanges?.length) {
253
+ return;
254
+ }
255
+ const title = historyItems.length === 1 ?
256
+ getHistoryItemEditorTitle(historyItem) :
257
+ ( localize(
258
+ 6631,
259
+ "All Changes ({0} ↔ {1})",
260
+ historyItemLast.displayId ?? historyItemLast.id,
261
+ historyItem.displayId ?? historyItem.id
262
+ ));
263
+ const rootUri = provider.rootUri;
264
+ const path = rootUri ? rootUri.path : provider.label;
265
+ const multiDiffSourceUri = ( (URI.from(
266
+ { scheme: 'scm-history-item', path: `${path}/${historyItemParentId}..${historyItem.id}` },
267
+ true
268
+ )));
269
+ commandService.executeCommand('_workbench.openMultiDiffEditor', { title, multiDiffSourceUri, resources: historyItemChanges });
97
270
  }
98
271
  });
99
272
  class ListDelegate {
@@ -101,10 +274,7 @@ class ListDelegate {
101
274
  return 22;
102
275
  }
103
276
  getTemplateId(element) {
104
- if (isSCMRepository(element)) {
105
- return RepositoryRenderer.TEMPLATE_ID;
106
- }
107
- else if (isSCMHistoryItemViewModelTreeElement(element)) {
277
+ if (isSCMHistoryItemViewModelTreeElement(element)) {
108
278
  return HistoryItemRenderer.TEMPLATE_ID;
109
279
  }
110
280
  else if (isSCMHistoryItemLoadMoreTreeElement(element)) {
@@ -115,94 +285,17 @@ class ListDelegate {
115
285
  }
116
286
  }
117
287
  }
118
- let RepositoryRenderer = class RepositoryRenderer {
119
- static { RepositoryRenderer_1 = this; }
120
- static { this.TEMPLATE_ID = 'repository'; }
121
- get templateId() { return RepositoryRenderer_1.TEMPLATE_ID; }
122
- constructor(description, actionRunner, actionViewItemProvider, commandService, contextKeyService, contextMenuService, hoverService, keybindingService, menuService, telemetryService) {
123
- this.description = description;
124
- this.actionRunner = actionRunner;
125
- this.actionViewItemProvider = actionViewItemProvider;
126
- this.commandService = commandService;
127
- this.contextKeyService = contextKeyService;
128
- this.contextMenuService = contextMenuService;
129
- this.hoverService = hoverService;
130
- this.keybindingService = keybindingService;
131
- this.menuService = menuService;
132
- this.telemetryService = telemetryService;
133
- }
134
- renderTemplate(container) {
135
- if (container.classList.contains('monaco-tl-contents')) {
136
- container.parentElement.parentElement.querySelector('.monaco-tl-twistie').classList.add('force-twistie');
137
- }
138
- const element = append(container, $('.scm-provider'));
139
- const label = ( (new IconLabel(element)));
140
- const labelCustomHover = this.hoverService.setupManagedHover(getDefaultHoverDelegate('mouse'), label.element, '', {});
141
- const stateLabel = append(element, $('div.state-label.monaco-count-badge.long'));
142
- const toolBar = ( (new WorkbenchToolBar(
143
- append(element, $('.actions')),
144
- { actionRunner: this.actionRunner, actionViewItemProvider: this.actionViewItemProvider, resetMenu: MenuId.SCMHistoryTitle },
145
- this.menuService,
146
- this.contextKeyService,
147
- this.contextMenuService,
148
- this.keybindingService,
149
- this.commandService,
150
- this.telemetryService
151
- )));
152
- return { label, labelCustomHover, stateLabel, toolBar, elementDisposables: ( (new DisposableStore())), templateDisposable: combinedDisposable(labelCustomHover, toolBar) };
153
- }
154
- renderElement(arg, index, templateData, height) {
155
- const repository = isSCMRepository(arg) ? arg : arg.element;
156
- templateData.elementDisposables.add(autorun(reader => {
157
- const description = this.description(repository).read(reader);
158
- templateData.stateLabel.style.display = description !== '' ? '' : 'none';
159
- templateData.stateLabel.textContent = description;
160
- }));
161
- templateData.label.setLabel(repository.provider.name);
162
- templateData.labelCustomHover.update(repository.provider.rootUri ? `${repository.provider.label}: ${repository.provider.rootUri.fsPath}` : repository.provider.label);
163
- templateData.elementDisposables.add(autorunWithStore((reader, store) => {
164
- const currentHistoryItemGroup = repository.provider.historyProvider.read(reader)?.currentHistoryItemGroup.read(reader);
165
- if (!currentHistoryItemGroup) {
166
- templateData.toolBar.setActions([], []);
167
- return;
168
- }
169
- const contextKeyService = this.contextKeyService.createOverlay([
170
- ['scmRepository', repository.id],
171
- ['scmProvider', repository.provider.contextValue],
172
- ['scmHistoryItemGroupHasRemote', !!currentHistoryItemGroup.remote],
173
- ]);
174
- const menu = this.menuService.createMenu(MenuId.SCMHistoryTitle, contextKeyService);
175
- store.add(connectPrimaryMenu(menu, (primary, secondary) => {
176
- templateData.toolBar.setActions(primary, secondary);
177
- }));
178
- }));
179
- templateData.toolBar.context = repository.provider;
180
- }
181
- disposeElement(group, index, template) {
182
- template.elementDisposables.clear();
183
- }
184
- disposeTemplate(templateData) {
185
- templateData.elementDisposables.dispose();
186
- templateData.templateDisposable.dispose();
187
- }
188
- };
189
- RepositoryRenderer = RepositoryRenderer_1 = ( (__decorate([
190
- ( (__param(3, ICommandService))),
191
- ( (__param(4, IContextKeyService))),
192
- ( (__param(5, IContextMenuService))),
193
- ( (__param(6, IHoverService))),
194
- ( (__param(7, IKeybindingService))),
195
- ( (__param(8, IMenuService))),
196
- ( (__param(9, ITelemetryService)))
197
- ], RepositoryRenderer)));
198
288
  let HistoryItemRenderer = class HistoryItemRenderer {
199
289
  static { HistoryItemRenderer_1 = this; }
200
290
  static { this.TEMPLATE_ID = 'history-item'; }
201
291
  get templateId() { return HistoryItemRenderer_1.TEMPLATE_ID; }
202
- constructor(hoverDelegate, hoverService, themeService) {
292
+ constructor(hoverDelegate, _clipboardService, _configurationService, _hoverService, _themeService) {
203
293
  this.hoverDelegate = hoverDelegate;
204
- this.hoverService = hoverService;
205
- this.themeService = themeService;
294
+ this._clipboardService = _clipboardService;
295
+ this._configurationService = _configurationService;
296
+ this._hoverService = _hoverService;
297
+ this._themeService = _themeService;
298
+ this._badgesConfig = observableConfigValue('scm.graph.badges', 'filter', this._configurationService);
206
299
  }
207
300
  renderTemplate(container) {
208
301
  container.parentElement.parentElement.querySelector('.monaco-tl-twistie').classList.add('force-no-twistie');
@@ -219,39 +312,77 @@ let HistoryItemRenderer = class HistoryItemRenderer {
219
312
  renderElement(node, index, templateData, height) {
220
313
  const historyItemViewModel = node.element.historyItemViewModel;
221
314
  const historyItem = historyItemViewModel.historyItem;
222
- const historyItemHover = this.hoverService.setupManagedHover(this.hoverDelegate, templateData.element, this.getTooltip(node.element));
315
+ const historyItemHover = this._hoverService.setupManagedHover(this.hoverDelegate, templateData.element, this._getHoverContent(node.element), {
316
+ actions: this._getHoverActions(historyItem),
317
+ });
223
318
  templateData.elementDisposables.add(historyItemHover);
224
319
  templateData.graphContainer.textContent = '';
320
+ templateData.graphContainer.classList.toggle('current', historyItemViewModel.isCurrent);
225
321
  templateData.graphContainer.appendChild(renderSCMHistoryItemGraph(historyItemViewModel));
226
- const [matches, descriptionMatches] = this.processMatches(historyItemViewModel, node.filterData);
227
- templateData.label.setLabel(historyItem.message, historyItem.author, { matches, descriptionMatches });
228
- templateData.labelContainer.textContent = '';
229
- if (historyItem.labels) {
230
- const labels = this.getLabels(node.element.repository);
231
- for (const label of historyItem.labels) {
232
- if (label.icon && ThemeIcon.isThemeIcon(label.icon) && labels.includes(label.title)) {
233
- const icon = append(templateData.labelContainer, $('div.label'));
234
- icon.classList.add(...ThemeIcon.asClassNameArray(label.icon));
322
+ const provider = node.element.repository.provider;
323
+ const historyItemRef = provider.historyProvider.get()?.historyItemRef?.get();
324
+ const extraClasses = historyItemRef?.revision === historyItem.id ? ['history-item-current'] : [];
325
+ const [matches, descriptionMatches] = this._processMatches(historyItemViewModel, node.filterData);
326
+ templateData.label.setLabel(historyItem.subject, historyItem.author, { matches, descriptionMatches, extraClasses });
327
+ this._renderBadges(historyItem, templateData);
328
+ }
329
+ _renderBadges(historyItem, templateData) {
330
+ templateData.elementDisposables.add(autorun(reader => {
331
+ const labelConfig = this._badgesConfig.read(reader);
332
+ const firstColoredRef = historyItem.references?.find(ref => ref.color);
333
+ templateData.labelContainer.textContent = '';
334
+ const historyItemRefsByColor = groupBy((historyItem.references ?? []), ref => ref.color ? ref.color : '');
335
+ for (const [key, historyItemRefs] of Object.entries(historyItemRefsByColor)) {
336
+ if (key === '' && labelConfig !== 'all') {
337
+ continue;
338
+ }
339
+ const historyItemRefByIconId = groupBy(historyItemRefs, ref => ThemeIcon.isThemeIcon(ref.icon) ? ref.icon.id : '');
340
+ for (const [key, historyItemRefs] of Object.entries(historyItemRefByIconId)) {
341
+ if (key === '' || historyItemRefs.length === 0) {
342
+ continue;
343
+ }
344
+ this._renderBadge(historyItemRefs[0], historyItemRefs[0] === firstColoredRef, templateData);
235
345
  }
236
346
  }
237
- }
347
+ }));
238
348
  }
239
- getLabels(repository) {
240
- const currentHistoryItemGroup = repository.provider.historyProvider.get()?.currentHistoryItemGroup.get();
241
- if (!currentHistoryItemGroup) {
242
- return [];
349
+ _renderBadge(historyItemRef, showDescription, templateData) {
350
+ if (!ThemeIcon.isThemeIcon(historyItemRef.icon)) {
351
+ return;
243
352
  }
353
+ const elements = h('div.label', {
354
+ style: {
355
+ color: historyItemRef.color ? asCssVariable(historyItemHoverLabelForeground) : asCssVariable(foreground),
356
+ backgroundColor: historyItemRef.color ? asCssVariable(historyItemRef.color) : asCssVariable(historyItemHoverDefaultLabelBackground)
357
+ }
358
+ }, [
359
+ h('div.icon@icon'),
360
+ h('div.description@description')
361
+ ]);
362
+ elements.icon.classList.add(...ThemeIcon.asClassNameArray(historyItemRef.icon));
363
+ elements.description.textContent = historyItemRef.name;
364
+ elements.description.style.display = showDescription ? '' : 'none';
365
+ append(templateData.labelContainer, elements.root);
366
+ }
367
+ _getHoverActions(historyItem) {
244
368
  return [
245
- currentHistoryItemGroup.name,
246
- currentHistoryItemGroup.remote?.name,
247
- currentHistoryItemGroup.base?.name
248
- ]
249
- .filter(l => l !== undefined);
250
- }
251
- getTooltip(element) {
252
- const colorTheme = this.themeService.getColorTheme();
369
+ {
370
+ commandId: 'workbench.scm.action.graph.copyHistoryItemId',
371
+ iconClass: 'codicon.codicon-copy',
372
+ label: historyItem.displayId ?? historyItem.id,
373
+ run: () => this._clipboardService.writeText(historyItem.id)
374
+ },
375
+ {
376
+ commandId: 'workbench.scm.action.graph.copyHistoryItemMessage',
377
+ iconClass: 'codicon.codicon-copy',
378
+ label: ( localize(6632, "Message")),
379
+ run: () => this._clipboardService.writeText(historyItem.message)
380
+ }
381
+ ];
382
+ }
383
+ _getHoverContent(element) {
384
+ const colorTheme = this._themeService.getColorTheme();
253
385
  const historyItem = element.historyItemViewModel.historyItem;
254
- const currentHistoryItemGroup = element.repository.provider.historyProvider.get()?.currentHistoryItemGroup?.get();
255
386
  const markdown = ( (new MarkdownString('', { isTrusted: true, supportThemeIcons: true })));
256
387
  if (historyItem.author) {
257
388
  markdown.appendMarkdown(`$(account) **${historyItem.author}**`);
@@ -265,42 +396,33 @@ let HistoryItemRenderer = class HistoryItemRenderer {
265
396
  if (historyItem.statistics) {
266
397
  markdown.appendMarkdown(`---\n\n`);
267
398
  markdown.appendMarkdown(`<span>${historyItem.statistics.files === 1 ?
268
- ( localize(6470, "{0} file changed", historyItem.statistics.files)) :
269
- ( localize(6471, "{0} files changed", historyItem.statistics.files))}</span>`);
399
+ ( localize(6633, "{0} file changed", historyItem.statistics.files)) :
400
+ ( localize(6634, "{0} files changed", historyItem.statistics.files))}</span>`);
270
401
  if (historyItem.statistics.insertions) {
271
- const historyItemAdditionsForegroundColor = colorTheme.getColor(historyItemAdditionsForeground);
272
- markdown.appendMarkdown(`,&nbsp;<span style="color:${historyItemAdditionsForegroundColor};">${historyItem.statistics.insertions === 1 ?
273
- ( localize(6472, "{0} insertion{1}", historyItem.statistics.insertions, '(+)')) :
274
- ( localize(6473, "{0} insertions{1}", historyItem.statistics.insertions, '(+)'))}</span>`);
402
+ const additionsForegroundColor = colorTheme.getColor(historyItemHoverAdditionsForeground);
403
+ markdown.appendMarkdown(`,&nbsp;<span style="color:${additionsForegroundColor};">${historyItem.statistics.insertions === 1 ?
404
+ ( localize(6635, "{0} insertion{1}", historyItem.statistics.insertions, '(+)')) :
405
+ ( localize(6636, "{0} insertions{1}", historyItem.statistics.insertions, '(+)'))}</span>`);
275
406
  }
276
407
  if (historyItem.statistics.deletions) {
277
- const historyItemDeletionsForegroundColor = colorTheme.getColor(historyItemDeletionsForeground);
278
- markdown.appendMarkdown(`,&nbsp;<span style="color:${historyItemDeletionsForegroundColor};">${historyItem.statistics.deletions === 1 ?
279
- ( localize(6474, "{0} deletion{1}", historyItem.statistics.deletions, '(-)')) :
280
- ( localize(6475, "{0} deletions{1}", historyItem.statistics.deletions, '(-)'))}</span>`);
281
- }
282
- }
283
- const labels = this.getLabels(element.repository);
284
- const historyItemLabels = (historyItem.labels ?? [])
285
- .filter(l => labels.includes(l.title));
286
- if (historyItemLabels.length > 0) {
287
- const historyItemGroupLocalColor = colorTheme.getColor(historyItemGroupLocal);
288
- const historyItemGroupRemoteColor = colorTheme.getColor(historyItemGroupRemote);
289
- const historyItemGroupBaseColor = colorTheme.getColor(historyItemGroupBase);
290
- const historyItemGroupHoverLabelForegroundColor = colorTheme.getColor(historyItemGroupHoverLabelForeground);
408
+ const deletionsForegroundColor = colorTheme.getColor(historyItemHoverDeletionsForeground);
409
+ markdown.appendMarkdown(`,&nbsp;<span style="color:${deletionsForegroundColor};">${historyItem.statistics.deletions === 1 ?
410
+ ( localize(6637, "{0} deletion{1}", historyItem.statistics.deletions, '(-)')) :
411
+ ( localize(6638, "{0} deletions{1}", historyItem.statistics.deletions, '(-)'))}</span>`);
412
+ }
413
+ }
414
+ if ((historyItem.references ?? []).length > 0) {
291
415
  markdown.appendMarkdown(`\n\n---\n\n`);
292
- markdown.appendMarkdown(( (historyItemLabels.map(label => {
293
- const historyItemGroupHoverLabelBackgroundColor = label.title === currentHistoryItemGroup?.name ? historyItemGroupLocalColor :
294
- label.title === currentHistoryItemGroup?.remote?.name ? historyItemGroupRemoteColor :
295
- label.title === currentHistoryItemGroup?.base?.name ? historyItemGroupBaseColor :
296
- undefined;
297
- const historyItemGroupHoverLabelIconId = ThemeIcon.isThemeIcon(label.icon) ? label.icon.id : '';
298
- return `<span style="color:${historyItemGroupHoverLabelForegroundColor};background-color:${historyItemGroupHoverLabelBackgroundColor};border-radius:2px;">&nbsp;$(${historyItemGroupHoverLabelIconId})&nbsp;${label.title}&nbsp;</span>`;
416
+ markdown.appendMarkdown(( ((historyItem.references ?? []).map(ref => {
417
+ const labelIconId = ThemeIcon.isThemeIcon(ref.icon) ? ref.icon.id : '';
418
+ const labelBackgroundColor = ref.color ? asCssVariable(ref.color) : asCssVariable(historyItemHoverDefaultLabelBackground);
419
+ const labelForegroundColor = ref.color ? asCssVariable(historyItemHoverLabelForeground) : asCssVariable(historyItemHoverDefaultLabelForeground);
420
+ return `<span style="color:${labelForegroundColor};background-color:${labelBackgroundColor};border-radius:10px;">&nbsp;$(${labelIconId})&nbsp;${ref.name}&nbsp;&nbsp;</span>`;
299
421
  }))).join('&nbsp;&nbsp;'));
300
422
  }
301
423
  return { markdown, markdownNotSupportedFallback: historyItem.message };
302
424
  }
303
- processMatches(historyItemViewModel, filterData) {
425
+ _processMatches(historyItemViewModel, filterData) {
304
426
  if (!filterData) {
305
427
  return [undefined, undefined];
306
428
  }
@@ -317,18 +439,19 @@ let HistoryItemRenderer = class HistoryItemRenderer {
317
439
  }
318
440
  };
319
441
  HistoryItemRenderer = HistoryItemRenderer_1 = ( (__decorate([
320
- ( (__param(1, IHoverService))),
321
- ( (__param(2, IThemeService)))
442
+ ( (__param(1, IClipboardService))),
443
+ ( (__param(2, IConfigurationService))),
444
+ ( (__param(3, IHoverService))),
445
+ ( (__param(4, IThemeService)))
322
446
  ], HistoryItemRenderer)));
323
447
  let HistoryItemLoadMoreRenderer = class HistoryItemLoadMoreRenderer {
324
448
  static { HistoryItemLoadMoreRenderer_1 = this; }
325
449
  static { this.TEMPLATE_ID = 'historyItemLoadMore'; }
326
450
  get templateId() { return HistoryItemLoadMoreRenderer_1.TEMPLATE_ID; }
327
- constructor(_loadingMore, _loadMoreCallback, _configurationService, _scmViewService) {
328
- this._loadingMore = _loadingMore;
451
+ constructor(_isLoadingMore, _loadMoreCallback, _configurationService) {
452
+ this._isLoadingMore = _isLoadingMore;
329
453
  this._loadMoreCallback = _loadMoreCallback;
330
454
  this._configurationService = _configurationService;
331
- this._scmViewService = _scmViewService;
332
455
  }
333
456
  renderTemplate(container) {
334
457
  container.parentElement.parentElement.querySelector('.monaco-tl-twistie').classList.add('force-no-twistie');
@@ -339,70 +462,33 @@ let HistoryItemLoadMoreRenderer = class HistoryItemLoadMoreRenderer {
339
462
  return { element, graphPlaceholder, historyItemPlaceholderContainer, historyItemPlaceholderLabel, elementDisposables: ( (new DisposableStore())), disposables: ( (new DisposableStore())) };
340
463
  }
341
464
  renderElement(element, index, templateData, height) {
342
- const repositoryCount = this._scmViewService.visibleRepositories.length;
343
- const alwaysShowRepositories = this._configurationService.getValue('scm.alwaysShowRepositories') === true;
344
465
  templateData.graphPlaceholder.textContent = '';
345
466
  templateData.graphPlaceholder.style.width = `${SWIMLANE_WIDTH * (element.element.graphColumns.length + 1)}px`;
346
467
  templateData.graphPlaceholder.appendChild(renderSCMHistoryGraphPlaceholder(element.element.graphColumns));
347
- templateData.historyItemPlaceholderContainer.classList.toggle('shimmer', repositoryCount === 1 && !alwaysShowRepositories);
348
- if (repositoryCount > 1 || alwaysShowRepositories) {
349
- templateData.elementDisposables.add(autorun(reader => {
350
- const loadingMore = this._loadingMore(element.element.repository).read(reader);
351
- const icon = `$(${loadingMore ? 'loading~spin' : 'fold-down'})`;
352
- templateData.historyItemPlaceholderLabel.setLabel(( localize(6476, "{0} Load More...", icon)));
353
- }));
468
+ const pageOnScroll = this._configurationService.getValue('scm.graph.pageOnScroll') === true;
469
+ templateData.historyItemPlaceholderContainer.classList.toggle('shimmer', pageOnScroll);
470
+ if (pageOnScroll) {
471
+ templateData.historyItemPlaceholderLabel.setLabel('');
472
+ this._loadMoreCallback();
354
473
  }
355
474
  else {
356
- templateData.historyItemPlaceholderLabel.setLabel('');
357
- this._loadMoreCallback(element.element.repository);
475
+ templateData.elementDisposables.add(autorun(reader => {
476
+ const isLoadingMore = this._isLoadingMore.read(reader);
477
+ const icon = `$(${isLoadingMore ? 'loading~spin' : 'fold-down'})`;
478
+ templateData.historyItemPlaceholderLabel.setLabel(( localize(6639, "{0} Load More...", icon)));
479
+ }));
358
480
  }
359
481
  }
482
+ disposeElement(element, index, templateData, height) {
483
+ templateData.elementDisposables.clear();
484
+ }
360
485
  disposeTemplate(templateData) {
361
486
  templateData.disposables.dispose();
362
487
  }
363
488
  };
364
489
  HistoryItemLoadMoreRenderer = HistoryItemLoadMoreRenderer_1 = ( (__decorate([
365
- ( (__param(2, IConfigurationService))),
366
- ( (__param(3, ISCMViewService)))
490
+ ( (__param(2, IConfigurationService)))
367
491
  ], HistoryItemLoadMoreRenderer)));
368
- class HistoryItemActionRunner extends ActionRunner {
369
- constructor(getSelectedHistoryItems) {
370
- super();
371
- this.getSelectedHistoryItems = getSelectedHistoryItems;
372
- }
373
- async runAction(action, context) {
374
- if (!(action instanceof MenuItemAction)) {
375
- return super.runAction(action, context);
376
- }
377
- const args = [];
378
- args.push(context.repository.provider);
379
- const selection = this.getSelectedHistoryItems();
380
- const contextIsSelected = ( (selection.some(s => s === context)));
381
- if (contextIsSelected && selection.length > 1) {
382
- args.push(...( (selection.map(h => ({
383
- id: h.historyItemViewModel.historyItem.id,
384
- parentIds: h.historyItemViewModel.historyItem.parentIds,
385
- message: h.historyItemViewModel.historyItem.message,
386
- author: h.historyItemViewModel.historyItem.author,
387
- icon: h.historyItemViewModel.historyItem.icon,
388
- timestamp: h.historyItemViewModel.historyItem.timestamp,
389
- statistics: h.historyItemViewModel.historyItem.statistics,
390
- })))));
391
- }
392
- else {
393
- args.push({
394
- id: context.historyItemViewModel.historyItem.id,
395
- parentIds: context.historyItemViewModel.historyItem.parentIds,
396
- message: context.historyItemViewModel.historyItem.message,
397
- author: context.historyItemViewModel.historyItem.author,
398
- icon: context.historyItemViewModel.historyItem.icon,
399
- timestamp: context.historyItemViewModel.historyItem.timestamp,
400
- statistics: context.historyItemViewModel.historyItem.statistics,
401
- });
402
- }
403
- await action.run(...args);
404
- }
405
- }
406
492
  let HistoryItemHoverDelegate = class HistoryItemHoverDelegate extends WorkbenchHoverDelegate {
407
493
  constructor(_viewContainerLocation, layoutService, configurationService, hoverService) {
408
494
  super('element', true, () => this.getHoverOptions(), configurationService, hoverService);
@@ -412,14 +498,14 @@ let HistoryItemHoverDelegate = class HistoryItemHoverDelegate extends WorkbenchH
412
498
  getHoverOptions() {
413
499
  const sideBarPosition = this.layoutService.getSideBarPosition();
414
500
  let hoverPosition;
415
- if (this._viewContainerLocation === ViewContainerLocation.Sidebar) {
416
- hoverPosition = sideBarPosition === Position.LEFT ? HoverPosition.RIGHT : HoverPosition.LEFT;
501
+ if (this._viewContainerLocation === 0 ) {
502
+ hoverPosition = sideBarPosition === 0 ? 1 : 0 ;
417
503
  }
418
- else if (this._viewContainerLocation === ViewContainerLocation.AuxiliaryBar) {
419
- hoverPosition = sideBarPosition === Position.LEFT ? HoverPosition.LEFT : HoverPosition.RIGHT;
504
+ else if (this._viewContainerLocation === 2 ) {
505
+ hoverPosition = sideBarPosition === 0 ? 0 : 1 ;
420
506
  }
421
507
  else {
422
- hoverPosition = HoverPosition.RIGHT;
508
+ hoverPosition = 1 ;
423
509
  }
424
510
  return { additionalClasses: ['history-item-hover'], position: { hoverPosition, forcePosition: true } };
425
511
  }
@@ -443,7 +529,7 @@ SCMHistoryViewPaneActionRunner = ( (__decorate([
443
529
  ], SCMHistoryViewPaneActionRunner)));
444
530
  class SCMHistoryTreeAccessibilityProvider {
445
531
  getWidgetAriaLabel() {
446
- return ( localize(6477, "Source Control History"));
532
+ return ( localize(6640, "Source Control History"));
447
533
  }
448
534
  getAriaLabel(element) {
449
535
  if (isSCMRepository(element)) {
@@ -494,179 +580,609 @@ class SCMHistoryTreeKeyboardNavigationLabelProvider {
494
580
  }
495
581
  }
496
582
  }
497
- let SCMHistoryTreeDataSource = class SCMHistoryTreeDataSource extends Disposable {
498
- constructor(_configurationService, _scmViewService) {
583
+ class SCMHistoryTreeDataSource extends Disposable {
584
+ async getChildren(inputOrElement) {
585
+ if (!(inputOrElement instanceof SCMHistoryViewModel)) {
586
+ return [];
587
+ }
588
+ const children = [];
589
+ const historyItems = await inputOrElement.getHistoryItems();
590
+ children.push(...historyItems);
591
+ const repository = inputOrElement.repository.get();
592
+ const lastHistoryItem = tail(historyItems);
593
+ if (repository && lastHistoryItem && lastHistoryItem.historyItemViewModel.outputSwimlanes.length > 0) {
594
+ children.push({
595
+ repository,
596
+ graphColumns: lastHistoryItem.historyItemViewModel.outputSwimlanes,
597
+ type: 'historyItemLoadMore'
598
+ });
599
+ }
600
+ return children;
601
+ }
602
+ hasChildren(inputOrElement) {
603
+ return inputOrElement instanceof SCMHistoryViewModel;
604
+ }
605
+ }
606
+ let SCMHistoryViewModel = class SCMHistoryViewModel extends Disposable {
607
+ constructor(_configurationService, _contextKeyService, _extensionService, _scmService, _scmViewService, _storageService) {
499
608
  super();
500
609
  this._configurationService = _configurationService;
610
+ this._contextKeyService = _contextKeyService;
611
+ this._extensionService = _extensionService;
612
+ this._scmService = _scmService;
501
613
  this._scmViewService = _scmViewService;
502
- this._state = ( (new Map()));
503
- }
504
- async getChildren(inputOrElement) {
505
- const repositoryCount = this._scmViewService.visibleRepositories.length;
506
- const alwaysShowRepositories = this._configurationService.getValue('scm.alwaysShowRepositories') === true;
507
- if (isSCMViewService(inputOrElement) && (repositoryCount > 1 || alwaysShowRepositories)) {
508
- return this._scmViewService.visibleRepositories;
509
- }
510
- else if ((isSCMViewService(inputOrElement) && repositoryCount === 1 && !alwaysShowRepositories) || isSCMRepository(inputOrElement)) {
511
- const children = [];
512
- inputOrElement = isSCMRepository(inputOrElement) ? inputOrElement : this._scmViewService.visibleRepositories[0];
513
- const historyItems = await this._getHistoryItems(inputOrElement);
514
- children.push(...historyItems);
515
- const lastHistoryItem = tail(historyItems);
516
- if (lastHistoryItem && lastHistoryItem.historyItemViewModel.outputSwimlanes.length > 0) {
517
- children.push({
518
- repository: inputOrElement,
519
- graphColumns: lastHistoryItem.historyItemViewModel.outputSwimlanes,
520
- type: 'historyItemLoadMore'
521
- });
614
+ this._storageService = _storageService;
615
+ this._closedRepository = observableFromEvent(this, this._scmService.onDidRemoveRepository, repository => repository);
616
+ this._firstRepository = this._scmService.repositoryCount > 0 ?
617
+ constObservable(Iterable.first(this._scmService.repositories)) :
618
+ observableFromEvent(this, Event.once(this._scmService.onDidAddRepository), repository => repository);
619
+ this._selectedRepository = observableValue(this, 'auto');
620
+ this._graphRepository = derived(reader => {
621
+ const selectedRepository = this._selectedRepository.read(reader);
622
+ if (selectedRepository !== 'auto') {
623
+ return selectedRepository;
522
624
  }
523
- return children;
524
- }
525
- return [];
625
+ return this._scmViewService.activeRepository.read(reader);
626
+ });
627
+ this.repository = latestChangedValue(this, [this._firstRepository, this._graphRepository]);
628
+ this.onDidChangeHistoryItemsFilter = observableSignal(this);
629
+ this.isViewModelEmpty = observableValue(this, false);
630
+ this._repositoryState = ( (new Map()));
631
+ this._repositoryFilterState = ( (new Map()));
632
+ this._repositoryFilterState = this._loadHistoryItemsFilterState();
633
+ this._extensionService.onWillStop(this._saveHistoryItemsFilterState, this, this._store);
634
+ this._storageService.onWillSaveState(this._saveHistoryItemsFilterState, this, this._store);
635
+ this._scmHistoryItemCountCtx = ContextKeys.SCMHistoryItemCount.bindTo(this._contextKeyService);
636
+ this._register(autorun(reader => {
637
+ const repository = this._closedRepository.read(reader);
638
+ if (!repository) {
639
+ return;
640
+ }
641
+ if (this.repository.get() === repository) {
642
+ this._selectedRepository.set(Iterable.first(this._scmService.repositories) ?? 'auto', undefined);
643
+ }
644
+ this._repositoryState.delete(repository);
645
+ }));
526
646
  }
527
- hasChildren(inputOrElement) {
528
- if (isSCMViewService(inputOrElement)) {
529
- return this._scmViewService.visibleRepositories.length !== 0;
647
+ clearRepositoryState() {
648
+ const repository = this.repository.get();
649
+ if (!repository) {
650
+ return;
530
651
  }
531
- else if (isSCMRepository(inputOrElement)) {
532
- return true;
652
+ this._repositoryState.delete(repository);
653
+ }
654
+ getHistoryItemsFilter() {
655
+ const repository = this.repository.get();
656
+ if (!repository) {
657
+ return;
533
658
  }
534
- else if (isSCMHistoryItemViewModelTreeElement(inputOrElement)) {
535
- return false;
659
+ const filterState = this._repositoryFilterState.get(getProviderKey(repository.provider)) ?? 'auto';
660
+ if (filterState === 'all' || filterState === 'auto') {
661
+ return filterState;
536
662
  }
537
- else if (isSCMHistoryItemLoadMoreTreeElement(inputOrElement)) {
538
- return false;
663
+ const repositoryState = this._repositoryState.get(repository);
664
+ return repositoryState?.historyItemsFilter;
665
+ }
666
+ getCurrentHistoryItemTreeElement() {
667
+ const repository = this.repository.get();
668
+ if (!repository) {
669
+ return undefined;
539
670
  }
540
- else {
541
- throw ( (new Error('hasChildren not implemented.')));
671
+ const state = this._repositoryState.get(repository);
672
+ if (!state) {
673
+ return undefined;
542
674
  }
675
+ const historyProvider = repository?.provider.historyProvider.get();
676
+ const historyItemRef = historyProvider?.historyItemRef.get();
677
+ return state.viewModels
678
+ .find(viewModel => viewModel.historyItemViewModel.historyItem.id === historyItemRef?.revision);
543
679
  }
544
- clearState(repository) {
680
+ loadMore(cursor) {
681
+ const repository = this.repository.get();
545
682
  if (!repository) {
546
- this._state.clear();
547
683
  return;
548
684
  }
549
- this._state.delete(repository);
550
- }
551
- loadMore(repository) {
552
- const state = this._state.get(repository);
685
+ const state = this._repositoryState.get(repository);
553
686
  if (!state) {
554
687
  return;
555
688
  }
556
- this._state.set(repository, { ...state, loadMore: true });
689
+ this._repositoryState.set(repository, { ...state, loadMore: cursor ?? true });
557
690
  }
558
- async _getHistoryItems(element) {
559
- let state = this._state.get(element);
560
- const historyProvider = element.provider.historyProvider.get();
561
- const currentHistoryItemGroup = state?.currentHistoryItemGroup ?? historyProvider?.currentHistoryItemGroup.get();
562
- if (!historyProvider || !currentHistoryItemGroup) {
691
+ async getHistoryItems() {
692
+ const repository = this.repository.get();
693
+ const historyProvider = repository?.provider.historyProvider.get();
694
+ if (!repository || !historyProvider) {
695
+ this._scmHistoryItemCountCtx.set(0);
696
+ this.isViewModelEmpty.set(true, undefined);
563
697
  return [];
564
698
  }
565
- if (!state || state.loadMore) {
566
- const historyItemGroupIds = [
567
- currentHistoryItemGroup.revision ?? currentHistoryItemGroup.id,
568
- ...(currentHistoryItemGroup.remote ? [currentHistoryItemGroup.remote.revision ?? currentHistoryItemGroup.remote.id] : []),
569
- ...(currentHistoryItemGroup.base ? [currentHistoryItemGroup.base.revision ?? currentHistoryItemGroup.base.id] : []),
570
- ];
571
- const existingHistoryItems = state?.items ?? [];
572
- const historyItems = (await historyProvider.provideHistoryItems2({
573
- historyItemGroupIds, limit: 50, skip: existingHistoryItems.length
574
- })) ?? [];
575
- state = {
576
- currentHistoryItemGroup,
577
- items: [...existingHistoryItems, ...historyItems],
578
- loadMore: false
579
- };
580
- this._state.set(element, state);
581
- }
582
- const colorMap = ( (new Map([
583
- [currentHistoryItemGroup.name, historyItemGroupLocal]
584
- ])));
585
- if (currentHistoryItemGroup.remote) {
586
- colorMap.set(currentHistoryItemGroup.remote.name, historyItemGroupRemote);
587
- }
588
- if (currentHistoryItemGroup.base) {
589
- colorMap.set(currentHistoryItemGroup.base.name, historyItemGroupBase);
590
- }
591
- return (
592
- (toISCMHistoryItemViewModelArray(state.items, colorMap)
699
+ let state = this._repositoryState.get(repository);
700
+ if (!state || state.loadMore !== false) {
701
+ const historyItems = state?.viewModels
702
+ .map(vm => vm.historyItemViewModel.historyItem) ?? [];
703
+ const historyItemRefs = state?.historyItemsFilter ??
704
+ (await this._resolveHistoryItemFilter(repository, historyProvider));
705
+ const limit = clamp(this._configurationService.getValue('scm.graph.pageSize'), 1, 1000);
706
+ const historyItemRefIds = ( (historyItemRefs.map(ref => ref.revision ?? ref.id)));
707
+ do {
708
+ historyItems.push(...((await historyProvider.provideHistoryItems({
709
+ historyItemRefs: historyItemRefIds, limit, skip: historyItems.length
710
+ })) ?? []));
711
+ } while (typeof state?.loadMore === 'string' && !historyItems.find(item => item.id === state?.loadMore));
712
+ const colorMap = this._getGraphColorMap(historyItemRefs);
713
+ const viewModels = ( (toISCMHistoryItemViewModelArray(historyItems, colorMap, historyProvider.historyItemRef.get())
593
714
  .map(historyItemViewModel => ({
594
- repository: element,
715
+ repository,
595
716
  historyItemViewModel,
596
- type: 'historyItem2'
597
- })))
717
+ type: 'historyItemViewModel'
718
+ }))));
719
+ state = { historyItemsFilter: historyItemRefs, viewModels, loadMore: false };
720
+ this._repositoryState.set(repository, state);
721
+ this._scmHistoryItemCountCtx.set(viewModels.length);
722
+ this.isViewModelEmpty.set(viewModels.length === 0, undefined);
723
+ }
724
+ return state.viewModels;
725
+ }
726
+ setRepository(repository) {
727
+ this._selectedRepository.set(repository, undefined);
728
+ }
729
+ setHistoryItemsFilter(filter) {
730
+ const repository = this.repository.get();
731
+ if (!repository) {
732
+ return;
733
+ }
734
+ if (filter !== 'auto') {
735
+ this._repositoryFilterState.set(getProviderKey(repository.provider), filter);
736
+ }
737
+ else {
738
+ this._repositoryFilterState.delete(getProviderKey(repository.provider));
739
+ }
740
+ this._saveHistoryItemsFilterState();
741
+ this.onDidChangeHistoryItemsFilter.trigger(undefined);
742
+ }
743
+ _getGraphColorMap(historyItemRefs) {
744
+ const repository = this.repository.get();
745
+ const historyProvider = repository?.provider.historyProvider.get();
746
+ const historyItemRef = historyProvider?.historyItemRef.get();
747
+ const historyItemRemoteRef = historyProvider?.historyItemRemoteRef.get();
748
+ const historyItemBaseRef = historyProvider?.historyItemBaseRef.get();
749
+ const colorMap = ( (new Map()));
750
+ if (historyItemRef) {
751
+ colorMap.set(historyItemRef.id, historyItemRef.color);
752
+ if (historyItemRemoteRef) {
753
+ colorMap.set(historyItemRemoteRef.id, historyItemRemoteRef.color);
754
+ }
755
+ if (historyItemBaseRef) {
756
+ colorMap.set(historyItemBaseRef.id, historyItemBaseRef.color);
757
+ }
758
+ }
759
+ for (const ref of historyItemRefs) {
760
+ if (!( (colorMap.has(ref.id)))) {
761
+ colorMap.set(ref.id, undefined);
762
+ }
763
+ }
764
+ return colorMap;
765
+ }
766
+ async _resolveHistoryItemFilter(repository, historyProvider) {
767
+ const historyItemRefs = [];
768
+ const historyItemsFilter = this._repositoryFilterState.get(getProviderKey(repository.provider)) ?? 'auto';
769
+ switch (historyItemsFilter) {
770
+ case 'all':
771
+ historyItemRefs.push(...((await historyProvider.provideHistoryItemRefs()) ?? []));
772
+ break;
773
+ case 'auto':
774
+ historyItemRefs.push(...[
775
+ historyProvider.historyItemRef.get(),
776
+ historyProvider.historyItemRemoteRef.get(),
777
+ historyProvider.historyItemBaseRef.get(),
778
+ ].filter(ref => !!ref));
779
+ break;
780
+ default: {
781
+ const refs = ((await historyProvider.provideHistoryItemRefs(historyItemsFilter)) ?? [])
782
+ .filter(ref => ( (historyItemsFilter.some(filter => filter === ref.id))));
783
+ if (refs.length === 0) {
784
+ historyItemRefs.push(...[
785
+ historyProvider.historyItemRef.get(),
786
+ historyProvider.historyItemRemoteRef.get(),
787
+ historyProvider.historyItemBaseRef.get(),
788
+ ].filter(ref => !!ref));
789
+ this._repositoryFilterState.delete(getProviderKey(repository.provider));
790
+ }
791
+ else {
792
+ historyItemRefs.push(...refs);
793
+ this._repositoryFilterState.set(getProviderKey(repository.provider), ( (refs.map(ref => ref.id))));
794
+ }
795
+ this._saveHistoryItemsFilterState();
796
+ break;
797
+ }
798
+ }
799
+ return historyItemRefs;
800
+ }
801
+ _loadHistoryItemsFilterState() {
802
+ try {
803
+ const filterData = this._storageService.get('scm.graphView.referencesFilter', 1 );
804
+ if (filterData) {
805
+ return (
806
+ (new Map(JSON.parse(filterData)))
807
+ );
808
+ }
809
+ }
810
+ catch { }
811
+ return (
812
+ (new Map())
598
813
  );
599
814
  }
815
+ _saveHistoryItemsFilterState() {
816
+ const filter = Array.from(this._repositoryFilterState.entries());
817
+ this._storageService.store('scm.graphView.referencesFilter', JSON.stringify(filter), 1 , 0 );
818
+ }
600
819
  dispose() {
601
- this._state.clear();
820
+ this._repositoryState.clear();
602
821
  super.dispose();
603
822
  }
604
823
  };
605
- SCMHistoryTreeDataSource = ( (__decorate([
824
+ SCMHistoryViewModel = ( (__decorate([
606
825
  ( (__param(0, IConfigurationService))),
826
+ ( (__param(1, IContextKeyService))),
827
+ ( (__param(2, IExtensionService))),
828
+ ( (__param(3, ISCMService))),
829
+ ( (__param(4, ISCMViewService))),
830
+ ( (__param(5, IStorageService)))
831
+ ], SCMHistoryViewModel)));
832
+ let RepositoryPicker = class RepositoryPicker extends Disposable {
833
+ constructor(_quickInputService, _scmViewService) {
834
+ super();
835
+ this._quickInputService = _quickInputService;
836
+ this._scmViewService = _scmViewService;
837
+ this._autoQuickPickItem = {
838
+ label: ( localize(6623, "Auto")),
839
+ description: ( localize(6641, "Show the source control graph for the active repository")),
840
+ repository: 'auto'
841
+ };
842
+ }
843
+ async pickRepository() {
844
+ const picks = [
845
+ this._autoQuickPickItem,
846
+ { type: 'separator' }
847
+ ];
848
+ picks.push(...( (this._scmViewService.repositories.map(r => ({
849
+ label: r.provider.name,
850
+ description: r.provider.rootUri?.fsPath,
851
+ iconClass: ThemeIcon.asClassName(Codicon.repo),
852
+ repository: r
853
+ })))));
854
+ return this._quickInputService.pick(picks, {
855
+ placeHolder: ( localize(6642, "Select the repository to view, type to filter all repositories"))
856
+ });
857
+ }
858
+ };
859
+ RepositoryPicker = ( (__decorate([
860
+ ( (__param(0, IQuickInputService))),
607
861
  ( (__param(1, ISCMViewService)))
608
- ], SCMHistoryTreeDataSource)));
862
+ ], RepositoryPicker)));
863
+ let HistoryItemRefPicker = class HistoryItemRefPicker extends Disposable {
864
+ constructor(_historyProvider, _historyItemsFilter, _quickInputService) {
865
+ super();
866
+ this._historyProvider = _historyProvider;
867
+ this._historyItemsFilter = _historyItemsFilter;
868
+ this._quickInputService = _quickInputService;
869
+ this._allQuickPickItem = {
870
+ id: 'all',
871
+ label: ( localize(6622, "All")),
872
+ description: ( localize(6625, "All history item references")),
873
+ historyItemRef: 'all'
874
+ };
875
+ this._autoQuickPickItem = {
876
+ id: 'auto',
877
+ label: ( localize(6623, "Auto")),
878
+ description: ( localize(6643, "Current history item reference(s)")),
879
+ historyItemRef: 'auto'
880
+ };
881
+ }
882
+ async pickHistoryItemRef() {
883
+ const quickPick = this._quickInputService.createQuickPick({ useSeparators: true });
884
+ this._store.add(quickPick);
885
+ quickPick.placeholder = ( localize(6644, "Select one/more history item references to view, type to filter"));
886
+ quickPick.canSelectMany = true;
887
+ quickPick.hideCheckAll = true;
888
+ quickPick.busy = true;
889
+ quickPick.show();
890
+ const items = await this._createQuickPickItems();
891
+ let selectedItems = [];
892
+ if (this._historyItemsFilter === 'all') {
893
+ selectedItems.push(this._allQuickPickItem);
894
+ }
895
+ else if (this._historyItemsFilter === 'auto') {
896
+ selectedItems.push(this._autoQuickPickItem);
897
+ }
898
+ else {
899
+ let index = 0;
900
+ while (index < items.length) {
901
+ if (items[index].type === 'separator') {
902
+ index++;
903
+ continue;
904
+ }
905
+ if (( (this._historyItemsFilter.some(ref => ref.id === items[index].id)))) {
906
+ const item = items.splice(index, 1);
907
+ selectedItems.push(...item);
908
+ }
909
+ else {
910
+ index++;
911
+ }
912
+ }
913
+ items.splice(2, 0, { type: 'separator' }, ...selectedItems);
914
+ }
915
+ quickPick.items = items;
916
+ quickPick.selectedItems = selectedItems;
917
+ quickPick.busy = false;
918
+ return (
919
+ (new Promise(resolve => {
920
+ this._store.add(quickPick.onDidChangeSelection(items => {
921
+ const { added } = delta(selectedItems, items, (a, b) => compare(a.id ?? '', b.id ?? ''));
922
+ if (added.length > 0) {
923
+ if (added[0].historyItemRef === 'all' || added[0].historyItemRef === 'auto') {
924
+ quickPick.selectedItems = [added[0]];
925
+ }
926
+ else {
927
+ quickPick.selectedItems = [...quickPick.selectedItems
928
+ .filter(i => i.historyItemRef !== 'all' && i.historyItemRef !== 'auto')];
929
+ }
930
+ }
931
+ selectedItems = [...quickPick.selectedItems];
932
+ }));
933
+ this._store.add(quickPick.onDidAccept(() => {
934
+ if (selectedItems.length === 0) {
935
+ resolve(undefined);
936
+ }
937
+ else if (selectedItems.length === 1 && selectedItems[0].historyItemRef === 'all') {
938
+ resolve('all');
939
+ }
940
+ else if (selectedItems.length === 1 && selectedItems[0].historyItemRef === 'auto') {
941
+ resolve('auto');
942
+ }
943
+ else {
944
+ resolve(( (selectedItems.map(item => item.historyItemRef.id))));
945
+ }
946
+ quickPick.hide();
947
+ }));
948
+ this._store.add(quickPick.onDidHide(() => {
949
+ resolve(undefined);
950
+ this.dispose();
951
+ }));
952
+ }))
953
+ );
954
+ }
955
+ async _createQuickPickItems() {
956
+ const picks = [
957
+ this._allQuickPickItem, this._autoQuickPickItem
958
+ ];
959
+ const historyItemRefs = (await this._historyProvider.provideHistoryItemRefs()) ?? [];
960
+ const historyItemRefsByCategory = groupBy$1(historyItemRefs, (a, b) => compare(a.category ?? '', b.category ?? ''));
961
+ for (const refs of historyItemRefsByCategory) {
962
+ if (refs.length === 0) {
963
+ continue;
964
+ }
965
+ picks.push({ type: 'separator', label: refs[0].category });
966
+ picks.push(...( (refs.map(ref => {
967
+ return {
968
+ id: ref.id,
969
+ label: ref.name,
970
+ description: ref.description,
971
+ iconClass: ThemeIcon.isThemeIcon(ref.icon) ?
972
+ ThemeIcon.asClassName(ref.icon) : undefined,
973
+ historyItemRef: ref
974
+ };
975
+ }))));
976
+ }
977
+ return picks;
978
+ }
979
+ };
980
+ HistoryItemRefPicker = ( (__decorate([
981
+ ( (__param(2, IQuickInputService)))
982
+ ], HistoryItemRefPicker)));
609
983
  let SCMHistoryViewPane = class SCMHistoryViewPane extends ViewPane {
610
- constructor(options, _commandService, _scmViewService, _progressService, configurationService, contextMenuService, keybindingService, instantiationService, viewDescriptorService, contextKeyService, openerService, themeService, telemetryService, hoverService) {
611
- super({ ...options, titleMenuId: MenuId.SCMHistoryTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService);
984
+ constructor(options, _commandService, _instantiationService, _notificationService, _progressService, configurationService, contextMenuService, keybindingService, instantiationService, viewDescriptorService, contextKeyService, openerService, themeService, telemetryService, hoverService) {
985
+ super({
986
+ ...options,
987
+ titleMenuId: MenuId.SCMHistoryTitle,
988
+ showActions: ViewPaneShowActions.WhenExpanded
989
+ }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService);
612
990
  this._commandService = _commandService;
613
- this._scmViewService = _scmViewService;
991
+ this._instantiationService = _instantiationService;
992
+ this._notificationService = _notificationService;
614
993
  this._progressService = _progressService;
615
- this._repositoryDescription = ( (new Map()));
616
- this._repositoryLoadMore = ( (new Map()));
617
- this._repositories = ( (new DisposableMap()));
994
+ this._repositoryIsLoadingMore = observableValue(this, false);
995
+ this._repositoryOutdated = observableValue(this, false);
618
996
  this._visibilityDisposables = ( (new DisposableStore()));
619
997
  this._treeOperationSequencer = ( (new Sequencer()));
998
+ this._treeLoadMoreSequencer = ( (new Sequencer()));
620
999
  this._updateChildrenThrottler = ( (new Throttler()));
621
- this._providerCountBadgeConfig = observableConfigValue('scm.providerCountBadge', 'hidden', this.configurationService);
622
- this._scmHistoryItemGroupHasRemoteContextKey = this.scopedContextKeyService.createKey('scmHistoryItemGroupHasRemote', undefined);
1000
+ this._scmProviderCtx = ContextKeys.SCMProvider.bindTo(this.scopedContextKeyService);
623
1001
  this._actionRunner = this.instantiationService.createInstance(SCMHistoryViewPaneActionRunner);
624
1002
  this._register(this._actionRunner);
625
1003
  this._register(this._updateChildrenThrottler);
626
1004
  }
627
- layoutBody(height, width) {
628
- super.layoutBody(height, width);
629
- this._tree.layout(height, width);
1005
+ renderHeaderTitle(container) {
1006
+ super.renderHeaderTitle(container, this.title);
1007
+ const element = h('div.scm-graph-view-badge-container', [
1008
+ h('div.scm-graph-view-badge.monaco-count-badge.long@badge')
1009
+ ]);
1010
+ element.badge.textContent = 'Outdated';
1011
+ container.appendChild(element.root);
1012
+ this._register(this.hoverService.setupManagedHover(getDefaultHoverDelegate('mouse'), element.root, {
1013
+ markdown: {
1014
+ value: ( localize(6645, "Please refresh the graph using the refresh action ($(refresh)).")),
1015
+ supportThemeIcons: true
1016
+ },
1017
+ markdownNotSupportedFallback: undefined
1018
+ }));
1019
+ this._register(autorun(reader => {
1020
+ const outdated = this._repositoryOutdated.read(reader);
1021
+ element.root.style.display = outdated ? '' : 'none';
1022
+ }));
630
1023
  }
631
1024
  renderBody(container) {
632
1025
  super.renderBody(container);
633
1026
  this._treeContainer = append(container, $('.scm-view.scm-history-view'));
634
1027
  this._treeContainer.classList.add('file-icon-themable-tree');
635
- this._register(autorun(reader => {
636
- const providerCountBadgeConfig = this._providerCountBadgeConfig.read(reader);
637
- this._treeContainer.classList.toggle('hide-provider-counts', providerCountBadgeConfig === 'hidden');
638
- this._treeContainer.classList.toggle('auto-provider-counts', providerCountBadgeConfig === 'auto');
639
- }));
640
1028
  this._createTree(this._treeContainer);
641
- this.onDidChangeBodyVisibility(visible => {
642
- if (visible) {
643
- this._treeOperationSequencer.queue(async () => {
644
- await this._tree.setInput(this._scmViewService);
645
- Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.alwaysShowRepositories'), this._visibilityDisposables)(() => {
646
- this.updateActions();
647
- this.refresh();
648
- }, this, this._visibilityDisposables);
649
- this._scmViewService.onDidChangeVisibleRepositories(this._onDidChangeVisibleRepositories, this, this._visibilityDisposables);
650
- this._onDidChangeVisibleRepositories({ added: this._scmViewService.visibleRepositories, removed: Iterable.empty() });
651
- this._tree.scrollTop = 0;
652
- });
653
- }
654
- else {
655
- this._treeDataSource.clearState();
1029
+ this.onDidChangeBodyVisibility(async (visible) => {
1030
+ if (!visible) {
656
1031
  this._visibilityDisposables.clear();
657
- this._repositories.clearAndDisposeAll();
1032
+ return;
658
1033
  }
1034
+ this._treeViewModel = this.instantiationService.createInstance(SCMHistoryViewModel);
1035
+ this._visibilityDisposables.add(this._treeViewModel);
1036
+ await this._progressService.withProgress({ location: this.id }, async () => {
1037
+ const firstRepositoryInitialized = derived(this, reader => {
1038
+ const repository = this._treeViewModel.repository.read(reader);
1039
+ const historyProvider = repository?.provider.historyProvider.read(reader);
1040
+ const historyItemRef = historyProvider?.historyItemRef.read(reader);
1041
+ return historyItemRef !== undefined ? true : undefined;
1042
+ });
1043
+ await waitForState(firstRepositoryInitialized);
1044
+ await this._treeOperationSequencer.queue(async () => {
1045
+ await this._tree.setInput(this._treeViewModel);
1046
+ this._tree.scrollTop = 0;
1047
+ });
1048
+ });
1049
+ this._visibilityDisposables.add(autorun(reader => {
1050
+ this._treeViewModel.isViewModelEmpty.read(reader);
1051
+ this._onDidChangeViewWelcomeState.fire();
1052
+ }));
1053
+ let isFirstRun = true;
1054
+ this._visibilityDisposables.add(autorunWithStore((reader, store) => {
1055
+ const repository = this._treeViewModel.repository.read(reader);
1056
+ const historyProvider = repository?.provider.historyProvider.read(reader);
1057
+ if (!repository || !historyProvider) {
1058
+ return;
1059
+ }
1060
+ this._scmProviderCtx.set(repository.provider.contextValue);
1061
+ const historyItemRefId = derived(reader => {
1062
+ return historyProvider.historyItemRef.read(reader)?.id;
1063
+ });
1064
+ store.add(runOnChange(historyItemRefId, () => {
1065
+ this.refresh();
1066
+ }));
1067
+ store.add(runOnChange(historyProvider.historyItemRefChanges, changes => {
1068
+ if (changes.silent) {
1069
+ if (this._tree.scrollTop === 0) {
1070
+ this.refresh();
1071
+ return;
1072
+ }
1073
+ this._repositoryOutdated.set(true, undefined);
1074
+ return;
1075
+ }
1076
+ this.refresh();
1077
+ }));
1078
+ store.add(runOnChange(this._treeViewModel.onDidChangeHistoryItemsFilter, () => {
1079
+ this.refresh();
1080
+ }));
1081
+ if (!isFirstRun) {
1082
+ this.refresh();
1083
+ }
1084
+ isFirstRun = false;
1085
+ }));
659
1086
  });
660
1087
  }
1088
+ layoutBody(height, width) {
1089
+ super.layoutBody(height, width);
1090
+ this._tree.layout(height, width);
1091
+ }
661
1092
  getActionRunner() {
662
1093
  return this._actionRunner;
663
1094
  }
664
- async refresh(repository) {
665
- this._treeDataSource.clearState(repository);
666
- await this._updateChildren(repository);
667
- this._setRepositoryDescription(repository, '');
1095
+ getActionsContext() {
1096
+ return this._treeViewModel?.repository.get()?.provider;
1097
+ }
1098
+ getActionViewItem(action, options) {
1099
+ if (action.id === PICK_REPOSITORY_ACTION_ID) {
1100
+ const repository = this._treeViewModel?.repository.get();
1101
+ if (repository) {
1102
+ return (
1103
+ (new SCMRepositoryActionViewItem(repository, action, options))
1104
+ );
1105
+ }
1106
+ }
1107
+ else if (action.id === PICK_HISTORY_ITEM_REFS_ACTION_ID) {
1108
+ const repository = this._treeViewModel?.repository.get();
1109
+ const historyItemsFilter = this._treeViewModel?.getHistoryItemsFilter();
1110
+ if (repository && historyItemsFilter) {
1111
+ return (
1112
+ (new SCMHistoryItemRefsActionViewItem(repository, historyItemsFilter, action, options))
1113
+ );
1114
+ }
1115
+ }
1116
+ return super.getActionViewItem(action, options);
1117
+ }
1118
+ focus() {
1119
+ super.focus();
1120
+ const fakeKeyboardEvent = ( (new KeyboardEvent('keydown')));
1121
+ this._tree.focusFirst(fakeKeyboardEvent);
1122
+ this._tree.domFocus();
1123
+ }
1124
+ shouldShowWelcome() {
1125
+ return this._treeViewModel?.isViewModelEmpty.get() === true;
1126
+ }
1127
+ async refresh() {
1128
+ this._treeViewModel.clearRepositoryState();
1129
+ await this._updateChildren();
1130
+ this.updateActions();
1131
+ this._repositoryOutdated.set(false, undefined);
668
1132
  this._tree.scrollTop = 0;
669
1133
  }
1134
+ async pickRepository() {
1135
+ const picker = this._instantiationService.createInstance(RepositoryPicker);
1136
+ const result = await picker.pickRepository();
1137
+ if (result) {
1138
+ this._treeViewModel.setRepository(result.repository);
1139
+ }
1140
+ }
1141
+ async pickHistoryItemRef() {
1142
+ const repository = this._treeViewModel.repository.get();
1143
+ const historyProvider = repository?.provider.historyProvider.get();
1144
+ const historyItemsFilter = this._treeViewModel.getHistoryItemsFilter();
1145
+ if (!historyProvider || !historyItemsFilter) {
1146
+ return;
1147
+ }
1148
+ const picker = this._instantiationService.createInstance(HistoryItemRefPicker, historyProvider, historyItemsFilter);
1149
+ const result = await picker.pickHistoryItemRef();
1150
+ if (result) {
1151
+ this._treeViewModel.setHistoryItemsFilter(result);
1152
+ }
1153
+ }
1154
+ async revealCurrentHistoryItem() {
1155
+ const repository = this._treeViewModel.repository.get();
1156
+ const historyProvider = repository?.provider.historyProvider.get();
1157
+ const historyItemRef = historyProvider?.historyItemRef.get();
1158
+ const historyItemFilter = this._treeViewModel.getHistoryItemsFilter();
1159
+ if (!repository || !historyItemRef?.revision || !historyItemFilter) {
1160
+ return;
1161
+ }
1162
+ if (Array.isArray(historyItemFilter) &&
1163
+ !historyItemFilter.find(ref => ref.id === historyItemRef.id)) {
1164
+ this._notificationService.info(( localize(
1165
+ 6646,
1166
+ "The current history item is not present in the source control graph. Please use the history item references picker to expand the set of history items in the graph."
1167
+ )));
1168
+ return;
1169
+ }
1170
+ const revealTreeNode = () => {
1171
+ const historyItemTreeElement = this._treeViewModel.getCurrentHistoryItemTreeElement();
1172
+ if (historyItemTreeElement && this._tree.hasNode(historyItemTreeElement)) {
1173
+ this._tree.reveal(historyItemTreeElement, 0.5);
1174
+ this._tree.setSelection([historyItemTreeElement]);
1175
+ this._tree.setFocus([historyItemTreeElement]);
1176
+ return true;
1177
+ }
1178
+ return false;
1179
+ };
1180
+ if (revealTreeNode()) {
1181
+ return;
1182
+ }
1183
+ await this._loadMore(historyItemRef.revision);
1184
+ revealTreeNode();
1185
+ }
670
1186
  _createTree(container) {
671
1187
  this._treeIdentityProvider = ( (new SCMHistoryTreeIdentityProvider()));
672
1188
  const historyItemHoverDelegate = this.instantiationService.createInstance(HistoryItemHoverDelegate, this.viewDescriptorService.getViewLocationById(this.id));
@@ -674,13 +1190,12 @@ let SCMHistoryViewPane = class SCMHistoryViewPane extends ViewPane {
674
1190
  this._treeDataSource = this.instantiationService.createInstance(SCMHistoryTreeDataSource);
675
1191
  this._register(this._treeDataSource);
676
1192
  this._tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'SCM History Tree', container, ( (new ListDelegate())), [
677
- this.instantiationService.createInstance(RepositoryRenderer, repository => this._getRepositoryDescription(repository), this._actionRunner, getActionViewItemProvider(this.instantiationService)),
678
1193
  this.instantiationService.createInstance(HistoryItemRenderer, historyItemHoverDelegate),
679
- this.instantiationService.createInstance(HistoryItemLoadMoreRenderer, repository => this._getLoadMore(repository), repository => this._loadMoreCallback(repository)),
1194
+ this.instantiationService.createInstance(HistoryItemLoadMoreRenderer, this._repositoryIsLoadingMore, () => this._loadMore()),
680
1195
  ], this._treeDataSource, {
681
1196
  accessibilityProvider: ( (new SCMHistoryTreeAccessibilityProvider())),
682
1197
  identityProvider: this._treeIdentityProvider,
683
- collapseByDefault: (e) => !isSCMRepository(e),
1198
+ collapseByDefault: (e) => false,
684
1199
  keyboardNavigationLabelProvider: ( (new SCMHistoryTreeKeyboardNavigationLabelProvider())),
685
1200
  horizontalScrolling: false,
686
1201
  multipleSelectionSupport: false,
@@ -693,16 +1208,13 @@ let SCMHistoryViewPane = class SCMHistoryViewPane extends ViewPane {
693
1208
  if (!e.element) {
694
1209
  return;
695
1210
  }
696
- else if (isSCMRepository(e.element)) {
697
- this._scmViewService.focus(e.element);
698
- }
699
1211
  else if (isSCMHistoryItemViewModelTreeElement(e.element)) {
700
1212
  const historyItem = e.element.historyItemViewModel.historyItem;
701
1213
  const historyItemParentId = historyItem.parentIds.length > 0 ? historyItem.parentIds[0] : undefined;
702
1214
  const historyProvider = e.element.repository.provider.historyProvider.get();
703
1215
  const historyItemChanges = await historyProvider?.provideHistoryItemChanges(historyItem.id, historyItemParentId);
704
1216
  if (historyItemChanges) {
705
- const title = `${historyItem.id.substring(0, 8)} - ${historyItem.message}`;
1217
+ const title = getHistoryItemEditorTitle(historyItem);
706
1218
  const rootUri = e.element.repository.provider.rootUri;
707
1219
  const path = rootUri ? rootUri.path : e.element.repository.provider.label;
708
1220
  const multiDiffSourceUri = ( (URI.from(
@@ -711,169 +1223,70 @@ let SCMHistoryViewPane = class SCMHistoryViewPane extends ViewPane {
711
1223
  )));
712
1224
  await this._commandService.executeCommand('_workbench.openMultiDiffEditor', { title, multiDiffSourceUri, resources: historyItemChanges });
713
1225
  }
714
- this._scmViewService.focus(e.element.repository);
715
1226
  }
716
1227
  else if (isSCMHistoryItemLoadMoreTreeElement(e.element)) {
717
- const repositoryCount = this._scmViewService.visibleRepositories.length;
718
- const alwaysShowRepositories = this.configurationService.getValue('scm.alwaysShowRepositories') === true;
719
- if (repositoryCount > 1 || alwaysShowRepositories) {
720
- this._loadMoreCallback(e.element.repository);
1228
+ const pageOnScroll = this.configurationService.getValue('scm.graph.pageOnScroll') === true;
1229
+ if (!pageOnScroll) {
1230
+ this._loadMore();
721
1231
  this._tree.setSelection([]);
722
1232
  }
723
1233
  }
724
1234
  }
725
1235
  _onContextMenu(e) {
726
1236
  const element = e.element;
727
- if (!element) {
1237
+ if (!element || !isSCMHistoryItemViewModelTreeElement(element)) {
728
1238
  return;
729
1239
  }
730
- let actions = [];
731
- let context = element;
732
- let actionRunner = ( (new HistoryItemActionRunner(() => this._getSelectedHistoryItems())));
733
- if (isSCMRepository(element)) {
734
- const menus = this._scmViewService.menus.getRepositoryMenus(element.provider);
735
- const menu = menus.repositoryContextMenu;
736
- actions = collectContextMenuActions(menu);
737
- actionRunner = ( (new RepositoryActionRunner(() => this._getSelectedRepositories())));
738
- context = element.provider;
739
- }
740
- else if (isSCMHistoryItemViewModelTreeElement(element)) {
741
- const menus = this._scmViewService.menus.getRepositoryMenus(element.repository.provider);
742
- const menu = menus.historyProviderMenu?.getHistoryItemMenu2(element);
743
- actions = menu ? collectContextMenuActions(menu) : [];
744
- }
745
- actionRunner.onWillRun(() => this._tree.domFocus());
746
1240
  this.contextMenuService.showContextMenu({
1241
+ contextKeyService: this.scopedContextKeyService,
1242
+ menuId: MenuId.SCMChangesContext,
1243
+ menuActionOptions: {
1244
+ arg: element.repository.provider,
1245
+ shouldForwardArgs: true
1246
+ },
747
1247
  getAnchor: () => e.anchor,
748
- getActions: () => actions,
749
- getActionsContext: () => context,
750
- actionRunner
1248
+ getActionsContext: () => element.historyItemViewModel.historyItem
751
1249
  });
752
1250
  }
753
- _onDidChangeVisibleRepositories({ added, removed }) {
754
- for (const repository of added) {
755
- const repositoryDisposables = ( (new DisposableStore()));
756
- repositoryDisposables.add(autorun(reader => {
757
- const historyProvider = repository.provider.historyProvider.read(reader);
758
- const currentHistoryItemGroupId = historyProvider?.currentHistoryItemGroupId.read(reader);
759
- const currentHistoryItemGroupRevision = historyProvider?.currentHistoryItemGroupRevision.read(reader);
760
- const currentHistoryItemGroupRemoteId = historyProvider?.currentHistoryItemGroupRemoteId.read(reader);
761
- if (this._scmViewService.visibleRepositories.length === 1) {
762
- this._scmHistoryItemGroupHasRemoteContextKey.set(!!currentHistoryItemGroupRemoteId);
763
- }
764
- else {
765
- this._scmHistoryItemGroupHasRemoteContextKey.reset();
766
- }
767
- if (!currentHistoryItemGroupId && !currentHistoryItemGroupRevision && !currentHistoryItemGroupRemoteId) {
768
- return;
769
- }
770
- this.refresh(repository);
771
- }));
772
- repositoryDisposables.add(autorun(reader => {
773
- const historyProvider = repository.provider.historyProvider.read(reader);
774
- const currentHistoryItemGroupRemoteRevision = historyProvider?.currentHistoryItemGroupRemoteRevision.read(reader);
775
- if (!currentHistoryItemGroupRemoteRevision) {
776
- return;
777
- }
778
- if (this._tree.scrollTop === 0) {
779
- this.refresh(repository);
780
- return;
781
- }
782
- const description = ( localize(6478, "OUTDATED"));
783
- this._setRepositoryDescription(this._isRepositoryNodeVisible() ? repository : undefined, description);
784
- }));
785
- this._repositories.set(repository, repositoryDisposables);
786
- }
787
- for (const repository of removed) {
788
- this._treeDataSource.clearState(repository);
789
- this._repositoryDescription.delete(repository);
790
- this._repositoryLoadMore.delete(repository);
791
- this._repositories.deleteAndDispose(repository);
792
- }
793
- this._updateChildren();
794
- }
795
- _getSelectedRepositories() {
796
- const focusedRepositories = this._tree.getFocus().filter(r => !!r && isSCMRepository(r));
797
- const selectedRepositories = this._tree.getSelection().filter(r => !!r && isSCMRepository(r));
798
- return Array.from(( (new Set([...focusedRepositories, ...selectedRepositories]))));
799
- }
800
- _getSelectedHistoryItems() {
801
- return this._tree.getSelection()
802
- .filter(r => !!r && isSCMHistoryItemViewModelTreeElement(r));
803
- }
804
- _getLoadMore(repository) {
805
- let loadMore = this._repositoryLoadMore.get(repository);
806
- if (!loadMore) {
807
- loadMore = observableValue(this, false);
808
- this._repositoryLoadMore.set(repository, loadMore);
809
- }
810
- return loadMore;
811
- }
812
- async _loadMoreCallback(repository) {
813
- const loadMore = this._getLoadMore(repository);
814
- if (loadMore.get()) {
815
- return;
816
- }
817
- loadMore.set(true, undefined);
818
- this._treeDataSource.loadMore(repository);
819
- await this._updateChildren(repository);
820
- loadMore.set(false, undefined);
821
- }
822
- _getRepositoryDescription(repository) {
823
- let description = this._repositoryDescription.get(repository);
824
- if (!description) {
825
- description = observableValue(this, '');
826
- this._repositoryDescription.set(repository, description);
827
- }
828
- return description;
829
- }
830
- _setRepositoryDescription(repository, description) {
831
- if (!repository) {
832
- this.updateTitleDescription(description);
833
- }
834
- else {
835
- this._getRepositoryDescription(repository).set(description, undefined);
836
- }
837
- }
838
- _isRepositoryNodeVisible() {
839
- const repositoryCount = this._scmViewService.visibleRepositories.length;
840
- const alwaysShowRepositories = this.configurationService.getValue('scm.alwaysShowRepositories') === true;
841
- return alwaysShowRepositories || repositoryCount > 1;
1251
+ async _loadMore(cursor) {
1252
+ return this._treeLoadMoreSequencer.queue(async () => {
1253
+ if (this._repositoryIsLoadingMore.get()) {
1254
+ return;
1255
+ }
1256
+ this._repositoryIsLoadingMore.set(true, undefined);
1257
+ this._treeViewModel.loadMore(cursor);
1258
+ await this._updateChildren();
1259
+ this._repositoryIsLoadingMore.set(false, undefined);
1260
+ });
842
1261
  }
843
- _updateChildren(element) {
1262
+ _updateChildren() {
844
1263
  return this._updateChildrenThrottler.queue(() => this._treeOperationSequencer.queue(async () => {
845
1264
  await this._progressService.withProgress({ location: this.id }, async () => {
846
- if (element && this._tree.hasNode(element)) {
847
- await this._tree.updateChildren(element, undefined, undefined, {
848
- });
849
- }
850
- else {
851
- await this._tree.updateChildren(undefined, undefined, undefined, {
852
- });
853
- }
1265
+ await this._tree.updateChildren(undefined, undefined, undefined, {
1266
+ });
854
1267
  });
855
1268
  }));
856
1269
  }
857
1270
  dispose() {
858
1271
  this._visibilityDisposables.dispose();
859
- this._repositories.dispose();
860
1272
  super.dispose();
861
1273
  }
862
1274
  };
863
1275
  SCMHistoryViewPane = ( (__decorate([
864
1276
  ( (__param(1, ICommandService))),
865
- ( (__param(2, ISCMViewService))),
866
- ( (__param(3, IProgressService))),
867
- ( (__param(4, IConfigurationService))),
868
- ( (__param(5, IContextMenuService))),
869
- ( (__param(6, IKeybindingService))),
870
- ( (__param(7, IInstantiationService))),
871
- ( (__param(8, IViewDescriptorService))),
872
- ( (__param(9, IContextKeyService))),
873
- ( (__param(10, IOpenerService))),
874
- ( (__param(11, IThemeService))),
875
- ( (__param(12, ITelemetryService))),
876
- ( (__param(13, IHoverService)))
1277
+ ( (__param(2, IInstantiationService))),
1278
+ ( (__param(3, INotificationService))),
1279
+ ( (__param(4, IProgressService))),
1280
+ ( (__param(5, IConfigurationService))),
1281
+ ( (__param(6, IContextMenuService))),
1282
+ ( (__param(7, IKeybindingService))),
1283
+ ( (__param(8, IInstantiationService))),
1284
+ ( (__param(9, IViewDescriptorService))),
1285
+ ( (__param(10, IContextKeyService))),
1286
+ ( (__param(11, IOpenerService))),
1287
+ ( (__param(12, IThemeService))),
1288
+ ( (__param(13, ITelemetryService))),
1289
+ ( (__param(14, IHoverService)))
877
1290
  ], SCMHistoryViewPane)));
878
1291
 
879
1292
  export { SCMHistoryViewPane };