diff --git a/src/audioPlayer.ts b/src/audioPlayer.ts index 2a5b5c4..4b6f8d0 100644 --- a/src/audioPlayer.ts +++ b/src/audioPlayer.ts @@ -18,7 +18,7 @@ export async function playSound(filePath: string): Promise { gainNode.connect(audioContext.destination); source.connect(gainNode); source.buffer = audioBuffer; - source.start(0); // Play the sound from the beginning + source.start(0); } catch (error: unknown) { throw new Error(`AudioPlayer: ${error}`); } diff --git a/src/extension.ts b/src/extension.ts index dea7382..18d5af2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -22,6 +22,7 @@ import { getTokenTypeAtCursorStart, clearTokenCache, } from "./tokenTypeProvider"; +import type { ITokenConfiguration } from "./interfaces/ITokenConfiguration"; export function activate(context: vscode.ExtensionContext) { let isSoundSyntaxEnabled = vscode.workspace @@ -52,17 +53,23 @@ export function activate(context: vscode.ExtensionContext) { } }); - vscode.commands.registerCommand("soundSyntax.setVolume", async () => { - const volume = await vscode.window.showInputBox({ - placeHolder: "Enter volume level (0-100)", - }); - - if (volume) { - const config = vscode.workspace.getConfiguration("soundSyntax"); - return config.update("volume", volume, vscode.ConfigurationTarget.Global); + vscode.workspace.onDidChangeConfiguration((event) => { + if (event.affectsConfiguration("soundSyntax.enable")) { + const updatedConfig = vscode.workspace.getConfiguration(); + isSoundSyntaxEnabled = updatedConfig.get("soundSyntax.enable", false); } }); + vscode.workspace.onDidChangeTextDocument((event) => { + const documentUri = event.document.uri.toString(); + clearTokenCache(documentUri); + }); + + vscode.workspace.onDidCloseTextDocument((document) => { + const documentUri = document.uri.toString(); + clearTokenCache(documentUri); + }); + vscode.commands.registerCommand("soundSyntax.toggle", async () => { isSoundSyntaxEnabled = !isSoundSyntaxEnabled; const config = vscode.workspace.getConfiguration("soundSyntax"); @@ -73,26 +80,155 @@ export function activate(context: vscode.ExtensionContext) { ); vscode.window.showInformationMessage( - `SoundSyntax ${isSoundSyntaxEnabled ? "enabled" : "disabled"}!`, + `Sound Syntax ${isSoundSyntaxEnabled ? "enabled" : "disabled"}!`, ); }); - vscode.workspace.onDidChangeConfiguration((event) => { - if (event.affectsConfiguration("soundSyntax.enable")) { - const updatedConfig = vscode.workspace.getConfiguration(); - isSoundSyntaxEnabled = updatedConfig.get("soundSyntax.enable", false); + vscode.commands.registerCommand( + "soundSyntax.toggleNotification", + async () => { + const config = vscode.workspace.getConfiguration("soundSyntax"); + const notificationMessage = config.get("notificationMessage", false); + await config.update( + "notificationMessage", + !notificationMessage, + vscode.ConfigurationTarget.Global, + ); + + vscode.window.showInformationMessage( + `Notification message ${ + !notificationMessage ? "enabled" : "disabled" + }!`, + ); + }, + ); + + vscode.commands.registerCommand("soundSyntax.setVolume", async () => { + const volume = await vscode.window.showInputBox({ + placeHolder: "Enter volume level (1-100)", + }); + + if (volume) { + const config = vscode.workspace.getConfiguration("soundSyntax"); + return config.update("volume", volume, vscode.ConfigurationTarget.Global); } }); - vscode.workspace.onDidChangeTextDocument((event) => { - const documentUri = event.document.uri.toString(); - clearTokenCache(documentUri); + vscode.commands.registerCommand("soundSyntax.tokenSettings", async () => { + const config = vscode.workspace.getConfiguration("soundSyntax"); + const tokens = config.get("tokens") as ITokenConfiguration[]; + const tokenLabels = tokens.map((token) => token.tokenLabel); + + const selectedOption = await vscode.window.showQuickPick( + [...tokenLabels, "Create new token..."], + { placeHolder: "Select an existing token or create a new one" }, + ); + + if (selectedOption === "Create new token...") { + await createNewToken(tokens); + } else if (selectedOption) { + const token = tokens.find((t) => t.tokenLabel === selectedOption); + if (token) { + await configureExistingToken(token, tokens); + } else { + showMessage("Token not found"); + } + } }); +} - vscode.workspace.onDidCloseTextDocument((document) => { - const documentUri = document.uri.toString(); - clearTokenCache(documentUri); +async function updateTokensConfig(tokens: ITokenConfiguration[]) { + const config = vscode.workspace.getConfiguration("soundSyntax"); + await config.update("tokens", tokens, vscode.ConfigurationTarget.Global); +} + +function showMessage(message: string) { + vscode.window.showInformationMessage(message); +} + +async function createNewToken(tokens: ITokenConfiguration[]): Promise { + const newTokenLabel = await vscode.window.showInputBox({ + placeHolder: "Enter new token name", }); + + if (newTokenLabel) { + let token = tokens.find((t) => t.tokenLabel === newTokenLabel); + if (token) { + return showMessage(`Token "${newTokenLabel}" already exists`); + } + token = { + tokenLabel: newTokenLabel, + enableSound: true, + enableInformation: true, + }; + tokens.push(token); + await updateTokensConfig(tokens); + showMessage(`New token "${newTokenLabel}" created`); + } +} + +async function configureExistingToken( + token: ITokenConfiguration, + tokens: ITokenConfiguration[], +) { + showMessage(`Selected token: "${token.tokenLabel}"`); + + const tokenConfigOption = await vscode.window.showQuickPick([ + { label: "Enable sound", description: "Enable sound for this token" }, + { + label: "Enable information", + description: "Enable information for this token", + }, + { + label: "Edit token sound path", + description: "Edit token sound configuration", + }, + { + label: "Edit token information text", + description: "Edit token information notification text", + }, + ]); + + if (tokenConfigOption) { + switch (tokenConfigOption.label) { + case "Enable sound": { + token.enableSound = !token.enableSound; + showMessage( + `${token.tokenLabel} sound has been ${token.enableSound ? "enabled" : "disabled"}`, + ); + break; + } + case "Enable information": { + token.enableInformation = !token.enableInformation; + showMessage( + `${token.tokenLabel} information has been ${token.enableInformation ? "enabled" : "disabled"}`, + ); + break; + } + case "Edit token sound path": { + const audioFilePath = await vscode.window.showInputBox({ + placeHolder: "Enter audio file path", + }); + token.audioFilePath = audioFilePath || undefined; + showMessage(`${token.tokenLabel} sound path has been updated`); + break; + } + case "Edit token information notification text": { + const overrideInformationText = await vscode.window.showInputBox({ + placeHolder: "Enter override information notification text", + }); + if (overrideInformationText) { + token.overrideInformationText = overrideInformationText; + } + showMessage( + `${token.tokenLabel} information notification text has been updated`, + ); + break; + } + } + + await updateTokensConfig(tokens); + } } export function deactivate() {} diff --git a/src/feedbackHandler.ts b/src/feedbackHandler.ts index eaf14ef..6ab481c 100644 --- a/src/feedbackHandler.ts +++ b/src/feedbackHandler.ts @@ -8,6 +8,7 @@ const defaultSoundPath = path.resolve(__dirname, "../sounds/default.mp3"); export async function handleTokenType(tokenType: string) { const tokenConfig = getTokenConfiguration(tokenType); + const notificationMessagesAllowed = isNotificationMessagesAllowed(); if (!tokenConfig) { await playSound(defaultSoundPath).catch((error: Error) => { @@ -18,7 +19,7 @@ export async function handleTokenType(tokenType: string) { return; } - if (tokenConfig.enableInformation) { + if (notificationMessagesAllowed && tokenConfig.enableInformation) { const message = tokenConfig.overrideInformationText || tokenType; vscode.window.showInformationMessage(message); } @@ -43,6 +44,11 @@ function getTokenConfiguration( return tokens?.find((token) => token.tokenLabel === tokenType); } +function isNotificationMessagesAllowed(): boolean { + const config = vscode.workspace.getConfiguration("soundSyntax"); + return config.get("notificationMessage", false); +} + function resolveSoundPath( tokenConfig: ITokenConfiguration, tokenType: string, diff --git a/src/interfaces/ITokenConfiguration.ts b/src/interfaces/ITokenConfiguration.ts index cc309e5..0eb7ac2 100644 --- a/src/interfaces/ITokenConfiguration.ts +++ b/src/interfaces/ITokenConfiguration.ts @@ -2,6 +2,6 @@ export interface ITokenConfiguration { tokenLabel: string; enableSound: boolean; enableInformation: boolean; - audioFilePath: string; - overrideInformationText: string; + audioFilePath?: string; + overrideInformationText?: string; }