Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse never show again logic - work in progress #73968

Merged
merged 8 commits into from
Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build/lib/i18n.resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@
{
"name": "vs/workbench/services/preferences",
"project": "vscode-preferences"
},
{
"name": "vs/workbench/services/notification",
"project": "vscode-workbench"
}
]
}
22 changes: 22 additions & 0 deletions src/vs/platform/notification/common/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export interface INotificationProperties {
* catch some attention.
*/
silent?: boolean;

/**
* Add a "never show again" action. If user selects the action, the notification will not appear again.
*/
neverShowAgainOptions?: INeverShowAgainOptions;
}

export interface INotification extends INotificationProperties {
Expand Down Expand Up @@ -173,6 +178,23 @@ export interface IPromptOptions extends INotificationProperties {
onCancel?: () => void;
}


export interface INeverShowAgainOptions {
/**
* Sending prompt id automatically adds a "never show again" action to the prompt.
* If user picks this option, future calls to 'prompt' with the same prompt id will be ignored.
* The id is used to persist the selection to storage
*/
id: string;

/**
*
* Primary: The never show again action will show up as a button on the notificaion.
* Secondary The never show again action will show up under the gear icon.
*/
isSecondary?: boolean;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to add a comment explaining the purpose.

}

export interface IStatusMessageOptions {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';

/**
* Shows a message when opening a large file which has been memory optimized (and features disabled).
Expand All @@ -20,26 +19,19 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC

private static readonly ID = 'editor.contrib.largeFileOptimizationsWarner';

private _isDisabled: boolean;

constructor(
private readonly _editor: ICodeEditor,
@INotificationService private readonly _notificationService: INotificationService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IStorageService private readonly _storageService: IStorageService,
) {
super();

this._isDisabled = Boolean(this._storageService.getBoolean('editor.neverPromptForLargeFiles', StorageScope.GLOBAL, false));

this._register(this._editor.onDidChangeModel((e) => {
const model = this._editor.getModel();
if (!model) {
return;
}
if (this._isDisabled) {
return;
}

if (model.isTooLargeForTokenization()) {
const message = nls.localize(
Expand All @@ -54,13 +46,6 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC
);

this._notificationService.prompt(Severity.Info, message, [
{
label: nls.localize('dontShowAgain', "Don't Show Again"),
run: () => {
this._isDisabled = true;
this._storageService.store('editor.neverPromptForLargeFiles', true, StorageScope.GLOBAL);
}
},
{
label: nls.localize('removeOptimizations', "Forcefully enable features"),
run: () => {
Expand All @@ -71,7 +56,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC
});
}
}
]);
], { neverShowAgainOptions: { id: 'editor.contrib.largeFileOptimizationsWarner' } });
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions } from 'vs/platform/notification/common/notification';
import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification';
import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications';
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IAction } from 'vs/base/common/actions';
import { IAction, Action } from 'vs/base/common/actions';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import * as nls from 'vs/nls';

export class NotificationService extends Disposable implements INotificationService {

Expand All @@ -21,6 +23,10 @@ export class NotificationService extends Disposable implements INotificationServ
return this._model;
}

constructor(@IStorageService private readonly storageService: IStorageService) {
super();
}

info(message: NotificationMessage | NotificationMessage[]): void {
if (Array.isArray(message)) {
message.forEach(m => this.info(m));
Expand Down Expand Up @@ -52,12 +58,61 @@ export class NotificationService extends Disposable implements INotificationServ
}

notify(notification: INotification): INotificationHandle {
return this.model.addNotification(notification);

let handle: INotificationHandle;
if (notification.neverShowAgainOptions) {
const id = notification.neverShowAgainOptions.id;
if (!!this.storageService.get(id, StorageScope.GLOBAL)) {
return new NoOpNotification();
}

const neverShowAction = new Action(
'workbench.dialog.choice.neverShowAgain',
nls.localize('neverShowAgain', "Don't Show Again"),
undefined, true, () => {
handle.close();
this.storageService.store(id, true, StorageScope.GLOBAL);
return Promise.resolve();
});

notification.actions = notification.actions || {};
if (notification.neverShowAgainOptions.isSecondary) {
notification.actions.secondary = notification.actions.secondary || [];
notification.actions.secondary = [...notification.actions.secondary, neverShowAction];
}
else {
notification.actions.primary = notification.actions.primary || [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to add the "Don't show again" as first entry to the primary actions so that it appears first and the most important button is to the right.

notification.actions.primary = [neverShowAction, ...notification.actions.primary];
}
}

handle = this.model.addNotification(notification);
return handle;
}

prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {
const toDispose = new DisposableStore();


if (options && options.neverShowAgainOptions) {
const id = options.neverShowAgainOptions.id;
if (!!this.storageService.get(id, StorageScope.GLOBAL)) {
return new NoOpNotification();
}

const neverShowAgainChoice = {
label: nls.localize('neverShowAgain', "Don't Show Again"),
run: () => this.storageService.store(id, true, StorageScope.GLOBAL),
isSecondary: options.neverShowAgainOptions.isSecondary
};
if (options.neverShowAgainOptions.isSecondary) {
choices = [...choices, neverShowAgainChoice];
}
else {
choices = [neverShowAgainChoice, ...choices];
}
}

let choiceClicked = false;
let handle: INotificationHandle;

Expand Down