Skip to content

Commit 628661c

Browse files
SmartManojsamhvw8
andauthored
feat: move play audio to webview to ensure cross-platform (#3659)
Co-authored-by: sam hoang <[email protected]>
1 parent a0735bb commit 628661c

File tree

14 files changed

+84
-122
lines changed

14 files changed

+84
-122
lines changed

package-lock.json

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,6 @@
411411
"say": "^0.16.0",
412412
"serialize-error": "^11.0.3",
413413
"simple-git": "^3.27.0",
414-
"sound-play": "^1.1.0",
415414
"string-similarity": "^4.0.4",
416415
"strip-ansi": "^7.1.0",
417416
"strip-bom": "^5.0.0",

src/core/webview/ClineProvider.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { McpHub } from "../../services/mcp/McpHub"
2929
import { McpServerManager } from "../../services/mcp/McpServerManager"
3030
import { ShadowCheckpointService } from "../../services/checkpoints/ShadowCheckpointService"
3131
import { fileExistsAtPath } from "../../utils/fs"
32-
import { setSoundEnabled } from "../../utils/sound"
3332
import { setTtsEnabled, setTtsSpeed } from "../../utils/tts"
3433
import { ContextProxy } from "../config/ContextProxy"
3534
import { ProviderSettingsManager } from "../config/ProviderSettingsManager"
@@ -327,7 +326,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
327326
// Initialize out-of-scope variables that need to recieve persistent global state values
328327
this.getState().then(
329328
({
330-
soundEnabled = false,
331329
terminalShellIntegrationTimeout = Terminal.defaultShellIntegrationTimeout,
332330
terminalShellIntegrationDisabled = false,
333331
terminalCommandDelay = 0,
@@ -337,7 +335,6 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
337335
terminalPowershellCounter = false,
338336
terminalZdotdir = false,
339337
}) => {
340-
setSoundEnabled(soundEnabled)
341338
Terminal.setShellIntegrationTimeout(terminalShellIntegrationTimeout)
342339
Terminal.setShellIntegrationDisabled(terminalShellIntegrationDisabled)
343340
Terminal.setCommandDelay(terminalCommandDelay)
@@ -579,6 +576,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
579576
])
580577

581578
const imagesUri = getUri(webview, this.contextProxy.extensionUri, ["assets", "images"])
579+
const audioUri = getUri(webview, this.contextProxy.extensionUri, ["webview-ui", "audio"])
582580

583581
const file = "src/index.tsx"
584582
const scriptUri = `http://${localServerUrl}/${file}`
@@ -598,6 +596,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
598596
`font-src ${webview.cspSource}`,
599597
`style-src ${webview.cspSource} 'unsafe-inline' https://* http://${localServerUrl} http://0.0.0.0:${localPort}`,
600598
`img-src ${webview.cspSource} data:`,
599+
`media-src ${webview.cspSource}`,
601600
`script-src 'unsafe-eval' ${webview.cspSource} https://* https://*.posthog.com http://${localServerUrl} http://0.0.0.0:${localPort} 'nonce-${nonce}'`,
602601
`connect-src https://* https://*.posthog.com ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`,
603602
]
@@ -613,6 +612,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
613612
<link href="${codiconsUri}" rel="stylesheet" />
614613
<script nonce="${nonce}">
615614
window.IMAGES_BASE_URI = "${imagesUri}"
615+
window.AUDIO_BASE_URI = "${audioUri}"
616616
window.MATERIAL_ICONS_BASE_URI = "${materialIconsUri}"
617617
</script>
618618
<title>Roo Code</title>
@@ -672,6 +672,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
672672
])
673673

674674
const imagesUri = getUri(webview, this.contextProxy.extensionUri, ["assets", "images"])
675+
const audioUri = getUri(webview, this.contextProxy.extensionUri, ["webview-ui", "audio"])
675676

676677
// const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "assets", "main.js"))
677678

@@ -702,11 +703,12 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
702703
<meta charset="utf-8">
703704
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
704705
<meta name="theme-color" content="#000000">
705-
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; font-src ${webview.cspSource}; style-src ${webview.cspSource} 'unsafe-inline'; img-src ${webview.cspSource} data:; script-src ${webview.cspSource} 'wasm-unsafe-eval' 'nonce-${nonce}' https://us-assets.i.posthog.com 'strict-dynamic'; connect-src https://openrouter.ai https://api.requesty.ai https://us.i.posthog.com https://us-assets.i.posthog.com;">
706+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; font-src ${webview.cspSource}; style-src ${webview.cspSource} 'unsafe-inline'; img-src ${webview.cspSource} data:; media-src ${webview.cspSource}; script-src ${webview.cspSource} 'wasm-unsafe-eval' 'nonce-${nonce}' https://us-assets.i.posthog.com 'strict-dynamic'; connect-src https://openrouter.ai https://api.requesty.ai https://us.i.posthog.com https://us-assets.i.posthog.com">
706707
<link rel="stylesheet" type="text/css" href="${stylesUri}">
707708
<link href="${codiconsUri}" rel="stylesheet" />
708709
<script nonce="${nonce}">
709710
window.IMAGES_BASE_URI = "${imagesUri}"
711+
window.AUDIO_BASE_URI = "${audioUri}"
710712
window.MATERIAL_ICONS_BASE_URI = "${materialIconsUri}"
711713
</script>
712714
<title>Roo Code</title>

src/core/webview/__tests__/ClineProvider.test.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import axios from "axios"
66

77
import { ClineProvider } from "../ClineProvider"
88
import { ProviderSettingsEntry, ClineMessage, ExtensionMessage, ExtensionState } from "../../../shared/ExtensionMessage"
9-
import { setSoundEnabled } from "../../../utils/sound"
109
import { setTtsEnabled } from "../../../utils/tts"
1110
import { defaultModeSlug } from "../../../shared/modes"
1211
import { experimentDefault } from "../../../shared/experiments"
@@ -173,10 +172,6 @@ jest.mock("vscode", () => ({
173172
},
174173
}))
175174

176-
jest.mock("../../../utils/sound", () => ({
177-
setSoundEnabled: jest.fn(),
178-
}))
179-
180175
jest.mock("../../../utils/tts", () => ({
181176
setTtsEnabled: jest.fn(),
182177
setTtsSpeed: jest.fn(),
@@ -365,7 +360,7 @@ describe("ClineProvider", () => {
365360

366361
// Verify Content Security Policy contains the necessary PostHog domains
367362
expect(mockWebviewView.webview.html).toContain(
368-
"connect-src https://openrouter.ai https://api.requesty.ai https://us.i.posthog.com https://us-assets.i.posthog.com;",
363+
"connect-src https://openrouter.ai https://api.requesty.ai https://us.i.posthog.com https://us-assets.i.posthog.com",
369364
)
370365

371366
// Extract the script-src directive section and verify required security elements
@@ -545,14 +540,12 @@ describe("ClineProvider", () => {
545540

546541
// Simulate setting sound to enabled
547542
await messageHandler({ type: "soundEnabled", bool: true })
548-
expect(setSoundEnabled).toHaveBeenCalledWith(true)
549543
expect(updateGlobalStateSpy).toHaveBeenCalledWith("soundEnabled", true)
550544
expect(mockContext.globalState.update).toHaveBeenCalledWith("soundEnabled", true)
551545
expect(mockPostMessage).toHaveBeenCalled()
552546

553547
// Simulate setting sound to disabled
554548
await messageHandler({ type: "soundEnabled", bool: false })
555-
expect(setSoundEnabled).toHaveBeenCalledWith(false)
556549
expect(mockContext.globalState.update).toHaveBeenCalledWith("soundEnabled", false)
557550
expect(mockPostMessage).toHaveBeenCalled()
558551

src/core/webview/webviewMessageHandler.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import { getTheme } from "../../integrations/theme/getTheme"
1919
import { discoverChromeHostUrl, tryChromeHostUrl } from "../../services/browser/browserDiscovery"
2020
import { searchWorkspaceFiles } from "../../services/search/file-search"
2121
import { fileExistsAtPath } from "../../utils/fs"
22-
import { playSound, setSoundEnabled, setSoundVolume } from "../../utils/sound"
2322
import { playTts, setTtsEnabled, setTtsSpeed, stopTts } from "../../utils/tts"
2423
import { singleCompletionHandler } from "../../utils/single-completion-handler"
2524
import { searchCommits } from "../../utils/git"
@@ -486,22 +485,15 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
486485
await updateGlobalState("enableMcpServerCreation", message.bool ?? true)
487486
await provider.postStateToWebview()
488487
break
489-
case "playSound":
490-
if (message.audioType) {
491-
const soundPath = path.join(provider.context.extensionPath, "audio", `${message.audioType}.wav`)
492-
playSound(soundPath)
493-
}
494-
break
488+
// playSound handler removed - now handled directly in the webview
495489
case "soundEnabled":
496490
const soundEnabled = message.bool ?? true
497491
await updateGlobalState("soundEnabled", soundEnabled)
498-
setSoundEnabled(soundEnabled) // Add this line to update the sound utility
499492
await provider.postStateToWebview()
500493
break
501494
case "soundVolume":
502495
const soundVolume = message.value ?? 0.5
503496
await updateGlobalState("soundVolume", soundVolume)
504-
setSoundVolume(soundVolume)
505497
await provider.postStateToWebview()
506498
break
507499
case "ttsEnabled":

src/utils/sound.ts

Lines changed: 0 additions & 75 deletions
This file was deleted.
File renamed without changes.
File renamed without changes.
File renamed without changes.

webview-ui/package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)