mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-26 11:26:56 +01:00
add saved cue
This commit is contained in:
@@ -5,26 +5,41 @@
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IAccessibilityService, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { AccessibleNotificationEvent, IAccessibilityService, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
export class AccessibleNotificationService extends Disposable implements IAccessibleNotificationService {
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private _events: Map<AccessibleNotificationEvent, { audioCue: AudioCue; alertMessage: string }> = new Map();
|
||||
constructor(
|
||||
@IAudioCueService private readonly _audioCueService: IAudioCueService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService) {
|
||||
super();
|
||||
this._events.set(AccessibleNotificationEvent.Clear, { audioCue: AudioCue.clear, alertMessage: localize('cleared', "Cleared") });
|
||||
this._events.set(AccessibleNotificationEvent.Save, { audioCue: AudioCue.save, alertMessage: localize('saved', "Saved") });
|
||||
}
|
||||
|
||||
notifyCleared(): void {
|
||||
const audioCueValue = this._configurationService.getValue(AudioCue.clear.settingsKey);
|
||||
notify(event: AccessibleNotificationEvent): void {
|
||||
const { audioCue, alertMessage } = this._events.get(event)!;
|
||||
const audioCueValue = this._configurationService.getValue(audioCue.settingsKey);
|
||||
if (audioCueValue === 'on' || audioCueValue === 'auto' && this._accessibilityService.isScreenReaderOptimized()) {
|
||||
this._audioCueService.playAudioCue(AudioCue.clear);
|
||||
this._audioCueService.playAudioCue(audioCue);
|
||||
} else {
|
||||
alert(localize('cleared', "Cleared"));
|
||||
alert(alertMessage);
|
||||
}
|
||||
}
|
||||
notifySaved(userGesture: boolean): void {
|
||||
const { audioCue, alertMessage } = this._events.get(AccessibleNotificationEvent.Save)!;
|
||||
const audioCueSetting = this._configurationService.getValue(audioCue.settingsKey);
|
||||
if (audioCueSetting === 'off') {
|
||||
alert(alertMessage);
|
||||
return;
|
||||
} else if (audioCueSetting === 'always') {
|
||||
this._audioCueService.playAudioCue(audioCue);
|
||||
} else if (audioCueSetting === 'userGesture' && userGesture) {
|
||||
this._audioCueService.playAudioCue(audioCue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,5 +48,6 @@ export class TestAccessibleNotificationService extends Disposable implements IAc
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
notifyCleared(): void { }
|
||||
notify(event: AccessibleNotificationEvent): void { }
|
||||
notifySaved(userGesture: boolean): void { }
|
||||
}
|
||||
|
||||
@@ -55,6 +55,12 @@ export const IAccessibleNotificationService = createDecorator<IAccessibleNotific
|
||||
*/
|
||||
export interface IAccessibleNotificationService {
|
||||
readonly _serviceBrand: undefined;
|
||||
notifyCleared(): void;
|
||||
notify(event: AccessibleNotificationEvent): void;
|
||||
notifySaved(userGesture: boolean): void;
|
||||
}
|
||||
|
||||
export const enum AccessibleNotificationEvent {
|
||||
Clear = 'clear',
|
||||
Save = 'save',
|
||||
Format = 'format'
|
||||
}
|
||||
|
||||
@@ -255,6 +255,7 @@ export class Sound {
|
||||
public static readonly chatResponseReceived3 = Sound.register({ fileName: 'chatResponseReceived3.mp3' });
|
||||
public static readonly chatResponseReceived4 = Sound.register({ fileName: 'chatResponseReceived4.mp3' });
|
||||
public static readonly clear = Sound.register({ fileName: 'clear.mp3' });
|
||||
public static readonly save = Sound.register({ fileName: 'save.mp3' });
|
||||
|
||||
private constructor(public readonly fileName: string) { }
|
||||
}
|
||||
@@ -426,6 +427,12 @@ export class AudioCue {
|
||||
settingsKey: 'audioCues.clear'
|
||||
});
|
||||
|
||||
public static readonly save = AudioCue.register({
|
||||
name: localize('audioCues.save', 'Save'),
|
||||
sound: Sound.save,
|
||||
settingsKey: 'audioCues.save'
|
||||
});
|
||||
|
||||
private constructor(
|
||||
public readonly sound: SoundSource,
|
||||
public readonly name: string,
|
||||
|
||||
Binary file not shown.
@@ -137,6 +137,18 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
|
||||
...audioCueFeatureBase,
|
||||
default: 'off'
|
||||
},
|
||||
'audioCues.save': {
|
||||
'description': localize('audioCues.save', "Plays a sound when a file is saved."),
|
||||
'type': 'string',
|
||||
'enum': ['userGesture', 'always', 'off'],
|
||||
'default': 'off',
|
||||
'enumDescriptions': [
|
||||
localize('audioCues.enabled.userGesture', "Plays the audio cue when a user explicitly saves a file."),
|
||||
localize('audioCues.enabled.always', "Plays the audio cue whenever a file is saved, including auto save."),
|
||||
localize('audioCues.enabled.off', "Disable audio cue.")
|
||||
],
|
||||
tags: ['accessibility']
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Codicon } from 'vs/base/common/codicons';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { AccessibleNotificationEvent, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { Action2, IAction2Options, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
@@ -118,5 +118,5 @@ export function getClearAction(viewId: string, providerId: string) {
|
||||
}
|
||||
|
||||
function announceChatCleared(accessor: ServicesAccessor): void {
|
||||
accessor.get(IAccessibleNotificationService).notifyCleared();
|
||||
accessor.get(IAccessibleNotificationService).notify(AccessibleNotificationEvent.Clear);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ import { Variable } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { ReplEvaluationResult, ReplGroup } from 'vs/workbench/contrib/debug/common/replModel';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { registerNavigableContainer } from 'vs/workbench/browser/actions/widgetNavigationCommands';
|
||||
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { AccessibleNotificationEvent, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -978,7 +978,7 @@ registerAction2(class extends ViewAction<Repl> {
|
||||
runInView(_accessor: ServicesAccessor, view: Repl): void {
|
||||
const accessibleNotificationService = _accessor.get(IAccessibleNotificationService);
|
||||
view.clearRepl();
|
||||
accessibleNotificationService.notifyCleared();
|
||||
accessibleNotificationService.notify(AccessibleNotificationEvent.Clear);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
|
||||
import { Disposable, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
|
||||
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { AccessibleNotificationEvent, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
// Register Service
|
||||
registerSingleton(IOutputService, OutputService, InstantiationType.Delayed);
|
||||
@@ -225,7 +225,7 @@ class OutputContribution extends Disposable implements IWorkbenchContribution {
|
||||
const activeChannel = outputService.getActiveChannel();
|
||||
if (activeChannel) {
|
||||
activeChannel.clear();
|
||||
accessibleNotificationService.notifyCleared();
|
||||
accessibleNotificationService.notify(AccessibleNotificationEvent.Clear);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -43,7 +43,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
|
||||
import { debounce } from 'vs/base/common/decorators';
|
||||
import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { AccessibleNotificationEvent, IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
const enum RenderConstants {
|
||||
/**
|
||||
@@ -590,7 +590,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
|
||||
// the prompt being written
|
||||
this._capabilities.get(TerminalCapability.CommandDetection)?.handlePromptStart();
|
||||
this._capabilities.get(TerminalCapability.CommandDetection)?.handleCommandStart();
|
||||
this._accessibleNotificationService.notifyCleared();
|
||||
this._accessibleNotificationService.notify(AccessibleNotificationEvent.Clear);
|
||||
}
|
||||
|
||||
hasSelection(): boolean {
|
||||
|
||||
@@ -33,6 +33,7 @@ import { IWorkspaceTrustRequestService, WorkspaceTrustUriResponse } from 'vs/pla
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { findGroup } from 'vs/workbench/services/editor/common/editorGroupFinder';
|
||||
import { ITextEditorService } from 'vs/workbench/services/textfile/common/textEditorService';
|
||||
import { IAccessibleNotificationService } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
export class EditorService extends Disposable implements EditorServiceImpl {
|
||||
|
||||
@@ -70,7 +71,8 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
||||
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
|
||||
@IWorkspaceTrustRequestService private readonly workspaceTrustRequestService: IWorkspaceTrustRequestService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@ITextEditorService private readonly textEditorService: ITextEditorService
|
||||
@ITextEditorService private readonly textEditorService: ITextEditorService,
|
||||
@IAccessibleNotificationService private readonly accessibleNotificationService: IAccessibleNotificationService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -972,9 +974,12 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const success = saveResults.every(result => !!result);
|
||||
if (success) {
|
||||
this.accessibleNotificationService.notifySaved(options?.reason === SaveReason.EXPLICIT);
|
||||
}
|
||||
return {
|
||||
success: saveResults.every(result => !!result),
|
||||
success,
|
||||
editors: coalesce(saveResults)
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user