Selaa lähdekoodia

Added Sound Notification 🎵 (#2203)

* Added Sound Notification

* prettify

* linted

* disabled by default

* Add dev config for frontend

* add volume icon

* fix typo

* lint

* lint

* Apply suggestions from code review

Co-authored-by: Graham Neubig <neubig@gmail.com>

* Move volume icon to bottom

---------

Co-authored-by: Graham Neubig <neubig@gmail.com>
மனோஜ்குமார் பழனிச்சாமி 1 vuosi sitten
vanhempi
sitoutus
877d9ae794

BIN
frontend/public/beep.wav


+ 12 - 5
frontend/src/App.tsx

@@ -11,6 +11,7 @@ import SettingsModal from "#/components/modals/settings/SettingsModal";
 import "./App.css";
 import AgentControlBar from "./components/AgentControlBar";
 import AgentStatusBar from "./components/AgentStatusBar";
+import VolumeIcon from "./components/VolumeIcon";
 import Terminal from "./components/terminal/Terminal";
 import Session from "#/services/session";
 import { getToken } from "#/services/auth";
@@ -27,11 +28,17 @@ function Controls({ setSettingOpen }: Props): JSX.Element {
         <AgentControlBar />
       </div>
       <AgentStatusBar />
-      <div
-        className="cursor-pointer hover:opacity-80 transition-all"
-        onClick={() => setSettingOpen(true)}
-      >
-        <CogTooth />
+
+      <div style={{ display: "flex", alignItems: "center" }}>
+        <div style={{ marginRight: "8px" }}>
+          <VolumeIcon />
+        </div>
+        <div
+          className="cursor-pointer hover:opacity-80 transition-all"
+          onClick={() => setSettingOpen(true)}
+        >
+          <CogTooth />
+        </div>
       </div>
     </div>
   );

+ 12 - 1
frontend/src/components/AgentStatusBar.tsx

@@ -1,9 +1,10 @@
-import React from "react";
+import React, { useEffect } from "react";
 import { useTranslation } from "react-i18next";
 import { useSelector } from "react-redux";
 import { I18nKey } from "#/i18n/declaration";
 import { RootState } from "#/store";
 import AgentState from "#/types/AgentState";
+import beep from "#/utils/beep";
 
 enum IndicatorColor {
   BLUE = "bg-blue-500",
@@ -65,6 +66,16 @@ function AgentStatusBar() {
   // - Agent is thinking
   // - Agent is ready
   // - Agent is not available
+  useEffect(() => {
+    if (
+      curAgentState === AgentState.AWAITING_USER_INPUT ||
+      curAgentState === AgentState.ERROR ||
+      curAgentState === AgentState.INIT
+    ) {
+      if (document.cookie.indexOf("audio") !== -1) beep();
+    }
+  }, [curAgentState]);
+
   return (
     <div className="flex items-center">
       <div

+ 29 - 0
frontend/src/components/VolumeIcon.tsx

@@ -0,0 +1,29 @@
+import React, { useState } from "react";
+import { IoMdVolumeHigh, IoMdVolumeOff } from "react-icons/io";
+import beep from "#/utils/beep";
+
+function VolumeIcon(): JSX.Element {
+  const [isMuted, setIsMuted] = useState(true);
+
+  const toggleMute = () => {
+    const cookieName = "audio";
+    setIsMuted(!isMuted);
+    if (!isMuted) {
+      document.cookie = `${cookieName}=;`;
+    } else {
+      document.cookie = `${cookieName}=on;`;
+      beep();
+    }
+  };
+
+  return (
+    <div
+      className="cursor-pointer hover:opacity-80 transition-all"
+      onClick={toggleMute}
+    >
+      {isMuted ? <IoMdVolumeOff size={23} /> : <IoMdVolumeHigh size={23} />}
+    </div>
+  );
+}
+
+export default VolumeIcon;

+ 9 - 0
frontend/src/utils/beep.tsx

@@ -0,0 +1,9 @@
+const beep = () => {
+  const snd = new Audio("/beep.wav");
+  snd.addEventListener("canplaythrough", () => snd.play());
+  snd.addEventListener("error", (e) =>
+    console.error("Audio file could not be loaded", e),
+  );
+};
+
+export default beep;