Skip to content

Commit 4d917a1

Browse files
authored
show desktop about details even when using custom dialogs (microsoft#261265)
1 parent b95f5fd commit 4d917a1

7 files changed

Lines changed: 93 additions & 66 deletions

File tree

src/vs/platform/dialogs/browser/dialog.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
import { EventHelper } from '../../../base/browser/dom.js';
77
import { StandardKeyboardEvent } from '../../../base/browser/keyboardEvent.js';
88
import { IDialogOptions } from '../../../base/browser/ui/dialog/dialog.js';
9+
import { fromNow } from '../../../base/common/date.js';
10+
import { localize } from '../../../nls.js';
911
import { IKeybindingService } from '../../keybinding/common/keybinding.js';
1012
import { ResultKind } from '../../keybinding/common/keybindingResolver.js';
1113
import { ILayoutService } from '../../layout/browser/layoutService.js';
14+
import { IProductService } from '../../product/common/productService.js';
1215
import { defaultButtonStyles, defaultCheckboxStyles, defaultInputBoxStyles, defaultDialogStyles } from '../../theme/browser/defaultStyles.js';
1316

1417
const defaultDialogAllowableCommands = [
@@ -39,3 +42,25 @@ export function createWorkbenchDialogOptions(options: Partial<IDialogOptions>, k
3942
...options
4043
};
4144
}
45+
46+
export function createBrowserAboutDialogDetails(productService: IProductService): { title: string; details: string; detailsToCopy: string } {
47+
const detailString = (useAgo: boolean): string => {
48+
return localize('aboutDetail',
49+
"Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
50+
productService.version || 'Unknown',
51+
productService.commit || 'Unknown',
52+
productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown',
53+
navigator.userAgent
54+
);
55+
};
56+
57+
const details = detailString(true);
58+
const detailsToCopy = detailString(false);
59+
60+
return {
61+
title: productService.nameLong,
62+
details: details,
63+
detailsToCopy: detailsToCopy
64+
};
65+
}
66+

src/vs/platform/dialogs/common/dialogs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ export interface IDialogHandler {
310310
/**
311311
* Present the about dialog to the user.
312312
*/
313-
about(): Promise<void>;
313+
about(title: string, details: string, detailsToCopy: string): Promise<void>;
314314
}
315315

316316
enum DialogKind {
@@ -440,7 +440,7 @@ export abstract class AbstractDialogHandler implements IDialogHandler {
440440
abstract confirm(confirmation: IConfirmation): Promise<IConfirmationResult>;
441441
abstract input(input: IInput): Promise<IInputResult>;
442442
abstract prompt<T>(prompt: IPrompt<T>): Promise<IAsyncPromptResult<T>>;
443-
abstract about(): Promise<void>;
443+
abstract about(title: string, details: string, detailsToCopy: string): Promise<void>;
444444
}
445445

446446
/**
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { fromNow } from '../../../base/common/date.js';
7+
import { isLinuxSnap } from '../../../base/common/platform.js';
8+
import { localize } from '../../../nls.js';
9+
import { IOSProperties } from '../../native/common/native.js';
10+
import { IProductService } from '../../product/common/productService.js';
11+
import { process } from '../../../base/parts/sandbox/electron-browser/globals.js';
12+
13+
export function createNativeAboutDialogDetails(productService: IProductService, osProps: IOSProperties): { title: string; details: string; detailsToCopy: string } {
14+
let version = productService.version;
15+
if (productService.target) {
16+
version = `${version} (${productService.target} setup)`;
17+
} else if (productService.darwinUniversalAssetId) {
18+
version = `${version} (Universal)`;
19+
}
20+
21+
const getDetails = (useAgo: boolean): string => {
22+
return localize({ key: 'aboutDetail', comment: ['Electron, Chromium, Node.js and V8 are product names that need no translation'] },
23+
"Version: {0}\nCommit: {1}\nDate: {2}\nElectron: {3}\nElectronBuildId: {4}\nChromium: {5}\nNode.js: {6}\nV8: {7}\nOS: {8}",
24+
version,
25+
productService.commit || 'Unknown',
26+
productService.date ? `${productService.date}${useAgo ? ' (' + fromNow(new Date(productService.date), true) + ')' : ''}` : 'Unknown',
27+
process.versions['electron'],
28+
process.versions['microsoft-build'],
29+
process.versions['chrome'],
30+
process.versions['node'],
31+
process.versions['v8'],
32+
`${osProps.type} ${osProps.arch} ${osProps.release}${isLinuxSnap ? ' snap' : ''}`
33+
);
34+
};
35+
36+
const details = getDetails(true);
37+
const detailsToCopy = getDetails(false);
38+
39+
return {
40+
title: productService.nameLong,
41+
details: details,
42+
detailsToCopy: detailsToCopy
43+
};
44+
}

src/vs/workbench/browser/parts/dialogs/dialog.web.contribution.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Disposable } from '../../../../base/common/lifecycle.js';
1717
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
1818
import { Lazy } from '../../../../base/common/lazy.js';
1919
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
20+
import { createBrowserAboutDialogDetails } from '../../../../platform/dialogs/browser/dialog.js';
2021

2122
export class DialogHandlerContribution extends Disposable implements IWorkbenchContribution {
2223

@@ -33,13 +34,13 @@ export class DialogHandlerContribution extends Disposable implements IWorkbenchC
3334
@ILayoutService layoutService: ILayoutService,
3435
@IKeybindingService keybindingService: IKeybindingService,
3536
@IInstantiationService instantiationService: IInstantiationService,
36-
@IProductService productService: IProductService,
37+
@IProductService private productService: IProductService,
3738
@IClipboardService clipboardService: IClipboardService,
3839
@IOpenerService openerService: IOpenerService
3940
) {
4041
super();
4142

42-
this.impl = new Lazy(() => new BrowserDialogHandler(logService, layoutService, keybindingService, instantiationService, productService, clipboardService, openerService));
43+
this.impl = new Lazy(() => new BrowserDialogHandler(logService, layoutService, keybindingService, instantiationService, clipboardService, openerService));
4344

4445
this.model = (this.dialogService as DialogService).model;
4546

@@ -68,7 +69,8 @@ export class DialogHandlerContribution extends Disposable implements IWorkbenchC
6869
const args = this.currentDialog.args.promptArgs;
6970
result = await this.impl.value.prompt(args.prompt);
7071
} else {
71-
await this.impl.value.about();
72+
const aboutDialogDetails = createBrowserAboutDialogDetails(this.productService);
73+
await this.impl.value.about(aboutDialogDetails.title, aboutDialogDetails.details, aboutDialogDetails.detailsToCopy);
7274
}
7375
} catch (error) {
7476
result = error;

src/vs/workbench/browser/parts/dialogs/dialogHandler.ts

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import Severity from '../../../../base/common/severity.js';
1111
import { Dialog, IDialogResult } from '../../../../base/browser/ui/dialog/dialog.js';
1212
import { DisposableStore } from '../../../../base/common/lifecycle.js';
1313
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
14-
import { IProductService } from '../../../../platform/product/common/productService.js';
1514
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
16-
import { fromNow } from '../../../../base/common/date.js';
1715
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
1816
import { MarkdownRenderer, openLinkFromMarkdown } from '../../../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js';
1917
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
@@ -37,7 +35,6 @@ export class BrowserDialogHandler extends AbstractDialogHandler {
3735
@ILayoutService private readonly layoutService: ILayoutService,
3836
@IKeybindingService private readonly keybindingService: IKeybindingService,
3937
@IInstantiationService instantiationService: IInstantiationService,
40-
@IProductService private readonly productService: IProductService,
4138
@IClipboardService private readonly clipboardService: IClipboardService,
4239
@IOpenerService private readonly openerService: IOpenerService
4340
) {
@@ -76,33 +73,21 @@ export class BrowserDialogHandler extends AbstractDialogHandler {
7673
return { confirmed: button === 0, checkboxChecked, values };
7774
}
7875

79-
async about(): Promise<void> {
80-
const detailString = (useAgo: boolean): string => {
81-
return localize('aboutDetail',
82-
"Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
83-
this.productService.version || 'Unknown',
84-
this.productService.commit || 'Unknown',
85-
this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown',
86-
navigator.userAgent
87-
);
88-
};
89-
90-
const detail = detailString(true);
91-
const detailToCopy = detailString(false);
76+
async about(title: string, details: string, detailsToCopy: string): Promise<void> {
9277

9378
const { button } = await this.doShow(
9479
Severity.Info,
95-
this.productService.nameLong,
80+
title,
9681
[
9782
localize({ key: 'copy', comment: ['&& denotes a mnemonic'] }, "&&Copy"),
9883
localize('ok', "OK")
9984
],
100-
detail,
85+
details,
10186
1
10287
);
10388

10489
if (button === 0) {
105-
this.clipboardService.writeText(detailToCopy);
90+
this.clipboardService.writeText(detailsToCopy);
10691
}
10792
}
10893

src/vs/workbench/electron-browser/parts/dialogs/dialog.contribution.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { Disposable } from '../../../../base/common/lifecycle.js';
2020
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
2121
import { Lazy } from '../../../../base/common/lazy.js';
2222
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
23+
import { createNativeAboutDialogDetails } from '../../../../platform/dialogs/electron-browser/dialog.js';
2324

2425
export class DialogHandlerContribution extends Disposable implements IWorkbenchContribution {
2526

@@ -38,15 +39,15 @@ export class DialogHandlerContribution extends Disposable implements IWorkbenchC
3839
@ILayoutService layoutService: ILayoutService,
3940
@IKeybindingService keybindingService: IKeybindingService,
4041
@IInstantiationService instantiationService: IInstantiationService,
41-
@IProductService productService: IProductService,
42+
@IProductService private productService: IProductService,
4243
@IClipboardService clipboardService: IClipboardService,
43-
@INativeHostService nativeHostService: INativeHostService,
44+
@INativeHostService private nativeHostService: INativeHostService,
4445
@IOpenerService openerService: IOpenerService
4546
) {
4647
super();
4748

48-
this.browserImpl = new Lazy(() => new BrowserDialogHandler(logService, layoutService, keybindingService, instantiationService, productService, clipboardService, openerService));
49-
this.nativeImpl = new Lazy(() => new NativeDialogHandler(logService, nativeHostService, productService, clipboardService));
49+
this.browserImpl = new Lazy(() => new BrowserDialogHandler(logService, layoutService, keybindingService, instantiationService, clipboardService, openerService));
50+
this.nativeImpl = new Lazy(() => new NativeDialogHandler(logService, nativeHostService, clipboardService));
5051

5152
this.model = (this.dialogService as DialogService).model;
5253

@@ -90,10 +91,12 @@ export class DialogHandlerContribution extends Disposable implements IWorkbenchC
9091

9192
// About
9293
else {
94+
const aboutDialogDetails = createNativeAboutDialogDetails(this.productService, await this.nativeHostService.getOSProperties());
95+
9396
if (this.useCustomDialog) {
94-
await this.browserImpl.value.about();
97+
await this.browserImpl.value.about(aboutDialogDetails.title, aboutDialogDetails.details, aboutDialogDetails.detailsToCopy);
9598
} else {
96-
await this.nativeImpl.value.about();
99+
await this.nativeImpl.value.about(aboutDialogDetails.title, aboutDialogDetails.details, aboutDialogDetails.detailsToCopy);
97100
}
98101
}
99102
} catch (error) {

src/vs/workbench/electron-browser/parts/dialogs/dialogHandler.ts

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,17 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { localize } from '../../../../nls.js';
7-
import { fromNow } from '../../../../base/common/date.js';
8-
import { isLinuxSnap } from '../../../../base/common/platform.js';
97
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
108
import { AbstractDialogHandler, IConfirmation, IConfirmationResult, IPrompt, IAsyncPromptResult } from '../../../../platform/dialogs/common/dialogs.js';
119
import { ILogService } from '../../../../platform/log/common/log.js';
1210
import { INativeHostService } from '../../../../platform/native/common/native.js';
13-
import { IProductService } from '../../../../platform/product/common/productService.js';
14-
import { process } from '../../../../base/parts/sandbox/electron-browser/globals.js';
1511
import { getActiveWindow } from '../../../../base/browser/dom.js';
1612

1713
export class NativeDialogHandler extends AbstractDialogHandler {
1814

1915
constructor(
2016
@ILogService private readonly logService: ILogService,
2117
@INativeHostService private readonly nativeHostService: INativeHostService,
22-
@IProductService private readonly productService: IProductService,
2318
@IClipboardService private readonly clipboardService: IClipboardService
2419
) {
2520
super();
@@ -69,38 +64,11 @@ export class NativeDialogHandler extends AbstractDialogHandler {
6964
throw new Error('Unsupported'); // we have no native API for password dialogs in Electron
7065
}
7166

72-
async about(): Promise<void> {
73-
let version = this.productService.version;
74-
if (this.productService.target) {
75-
version = `${version} (${this.productService.target} setup)`;
76-
} else if (this.productService.darwinUniversalAssetId) {
77-
version = `${version} (Universal)`;
78-
}
79-
80-
const osProps = await this.nativeHostService.getOSProperties();
81-
82-
const detailString = (useAgo: boolean): string => {
83-
return localize({ key: 'aboutDetail', comment: ['Electron, Chromium, Node.js and V8 are product names that need no translation'] },
84-
"Version: {0}\nCommit: {1}\nDate: {2}\nElectron: {3}\nElectronBuildId: {4}\nChromium: {5}\nNode.js: {6}\nV8: {7}\nOS: {8}",
85-
version,
86-
this.productService.commit || 'Unknown',
87-
this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown',
88-
process.versions['electron'],
89-
process.versions['microsoft-build'],
90-
process.versions['chrome'],
91-
process.versions['node'],
92-
process.versions['v8'],
93-
`${osProps.type} ${osProps.arch} ${osProps.release}${isLinuxSnap ? ' snap' : ''}`
94-
);
95-
};
96-
97-
const detail = detailString(true);
98-
const detailToCopy = detailString(false);
99-
67+
async about(title: string, details: string, detailsToCopy: string): Promise<void> {
10068
const { response } = await this.nativeHostService.showMessageBox({
10169
type: 'info',
102-
message: this.productService.nameLong,
103-
detail: `\n${detail}`,
70+
message: title,
71+
detail: `\n${details}`,
10472
buttons: [
10573
localize({ key: 'copy', comment: ['&& denotes a mnemonic'] }, "&&Copy"),
10674
localize('okButton', "OK")
@@ -109,7 +77,7 @@ export class NativeDialogHandler extends AbstractDialogHandler {
10977
});
11078

11179
if (response === 0) {
112-
this.clipboardService.writeText(detailToCopy);
80+
this.clipboardService.writeText(detailsToCopy);
11381
}
11482
}
11583
}

0 commit comments

Comments
 (0)