UNPKG

@broadreachalliance/q-assistant

Version:

A React-based chat window supporting both voice and text communication modes.

92 lines 3.9 kB
import { useSpeech } from "../contexts"; import speakericon from "./icons/speaker.svg"; import React, { useState } from "react"; const VoiceSettings = () => { const { speechStatus, setUtterence } = useSpeech(); const [selectedVoice, setSelectedVoice] = useState(localStorage.getItem("selectedVoice")); const [saved, setSaved] = useState(false); const saveVoiceToLocalStorage = () => { localStorage.setItem("selectedVoice", selectedVoice); setSaved(true); setTimeout(() => setSaved(false), 1000); }; const speaksampleText = () => { if (!selectedVoice) return; const utterance = new SpeechSynthesisUtterance("Hello ! This is your selected voice."); setUtterence(utterance); const voice = speechStatus?.voices.find(v => v.name === selectedVoice); if (voice) { utterance.voice = voice; } window.speechSynthesis.speak(utterance); }; return /*#__PURE__*/React.createElement("div", { className: "flex flex-col p-6 max-w-lg mx-auto bg-white rounded-lg border border-gray-200" }, /*#__PURE__*/React.createElement("h2", { className: "text-xl font-bold mb-4" }, "Assistant voice settings"), /*#__PURE__*/React.createElement("div", { className: "mb-4" }, /*#__PURE__*/React.createElement("label", { htmlFor: "voiceSelect", className: "block text-sm font-medium text-gray-700 mb-1" }, "Select Voice"), /*#__PURE__*/React.createElement("div", { className: "relative flex flex-row justify-between items-center" }, /*#__PURE__*/React.createElement("div", { className: "relative w-[88%]" }, /*#__PURE__*/React.createElement("select", { id: "voiceSelect", value: selectedVoice, onChange: event => setSelectedVoice(event.target.value), className: "w-full p-3 pl-4 pr-10 border border-gray-300 rounded-lg text-sm shadow-sm focus:ring-0 focus:outline-none text-gray-700 appearance-none" }, /*#__PURE__*/React.createElement("option", { value: "", disabled: true }, "Select a voice"), speechStatus?.voices.map((voice, index) => /*#__PURE__*/React.createElement("option", { key: index, value: voice.name }, voice.name, " (", voice.lang, ")"))), /*#__PURE__*/React.createElement("div", { className: "absolute inset-y-0 right-3 flex items-center pointer-events-none text-gray-400" }, /*#__PURE__*/React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "w-6 h-6" }, /*#__PURE__*/React.createElement("path", { d: "M6 9l6 6 6-6" })))), selectedVoice && /*#__PURE__*/React.createElement("button", { onClick: speaksampleText, className: "flex items-center justify-center w-[10%] h-full bg-gray-100 text-gray-700 rounded-lg py-2 shadow-md hover:bg-gray-200 transition" }, /*#__PURE__*/React.createElement("img", { src: speakericon, alt: "speak", className: "w-6 h-6" })))), /*#__PURE__*/React.createElement("button", { onClick: saveVoiceToLocalStorage, className: "w-[20%] bg-[#1f4745] ml-auto text-white text-sm py-2 rounded-md shadow-md hover:bg-[#2ba49e]" }, saved ? /*#__PURE__*/React.createElement("div", { className: "flex flex-row items-center justify-center gap-2" }, /*#__PURE__*/React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", class: "lucide lucide-circle-check-big-icon lucide-circle-check-big" }, /*#__PURE__*/React.createElement("path", { d: "M21.801 10A10 10 0 1 1 17 3.335" }), /*#__PURE__*/React.createElement("path", { d: "m9 11 3 3L22 4" })), "Saved") : "Save")); }; export default VoiceSettings;