UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

187 lines (178 loc) 7.17 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _chunkALPGURNKjs = require('./chunk-ALPGURNK.js'); // src/hooks/useTTS.ts var _react = require('react'); // src/components/AccessibilityWidget/tts/WebSpeechProvider.ts var WebSpeechProvider = (_class = class { __init() {this.currentUtterance = null} constructor(synth = getSynth()) {;_class.prototype.__init.call(this); this.synth = synth; } isSupported() { return this.synth !== null; } async getVoices() { if (!this.synth) return []; const synth = this.synth; const collect = () => synth.getVoices().map((v) => ({ id: v.voiceURI, name: v.name, lang: v.lang, isLocal: v.localService })); const initial = collect(); if (initial.length > 0) return initial; return new Promise((resolve) => { const onChange = () => { synth.removeEventListener("voiceschanged", onChange); resolve(collect()); }; synth.addEventListener("voiceschanged", onChange); setTimeout(() => { synth.removeEventListener("voiceschanged", onChange); resolve(collect()); }, 1500); }); } speak(text, options = {}, events = {}) { if (!this.synth) { _optionalChain([events, 'access', _ => _.onError, 'optionalCall', _2 => _2("S\xEDntese de voz n\xE3o dispon\xEDvel neste navegador.")]); return; } const trimmed = text.trim(); if (!trimmed) return; this.synth.cancel(); const utterance = new SpeechSynthesisUtterance(trimmed); utterance.rate = _nullishCoalesce(options.rate, () => ( 1)); utterance.pitch = _nullishCoalesce(options.pitch, () => ( 1)); const allVoices = this.synth.getVoices(); let chosenVoice; if (options.voiceId) { chosenVoice = allVoices.find((v) => v.voiceURI === options.voiceId); } else if (options.lang) { chosenVoice = allVoices.find( (v) => v.lang.toLowerCase().startsWith(options.lang.toLowerCase()) ); } if (chosenVoice) { utterance.voice = chosenVoice; utterance.lang = chosenVoice.lang; } utterance.onstart = () => _optionalChain([events, 'access', _3 => _3.onStart, 'optionalCall', _4 => _4()]); utterance.onend = () => { this.currentUtterance = null; _optionalChain([events, 'access', _5 => _5.onEnd, 'optionalCall', _6 => _6()]); }; utterance.onpause = () => _optionalChain([events, 'access', _7 => _7.onPause, 'optionalCall', _8 => _8()]); utterance.onresume = () => _optionalChain([events, 'access', _9 => _9.onResume, 'optionalCall', _10 => _10()]); utterance.onerror = (event) => { this.currentUtterance = null; _optionalChain([events, 'access', _11 => _11.onError, 'optionalCall', _12 => _12(event.error || "Erro desconhecido na s\xEDntese.")]); }; this.currentUtterance = utterance; this.synth.speak(utterance); } pause() { _optionalChain([this, 'access', _13 => _13.synth, 'optionalAccess', _14 => _14.pause, 'call', _15 => _15()]); } resume() { _optionalChain([this, 'access', _16 => _16.synth, 'optionalAccess', _17 => _17.resume, 'call', _18 => _18()]); } stop() { _optionalChain([this, 'access', _19 => _19.synth, 'optionalAccess', _20 => _20.cancel, 'call', _21 => _21()]); this.currentUtterance = null; } }, _class); var getSynth = () => { if (typeof globalThis === "undefined") return null; const synth = globalThis.speechSynthesis; return _nullishCoalesce(synth, () => ( null)); }; // src/hooks/useTTS.ts var useTTS = (providerOverride) => { const setTTSStatus = _chunkALPGURNKjs.useAccessibilityStore.call(void 0, (s) => s.setTTSStatus); const ttsRate = _chunkALPGURNKjs.useAccessibilityStore.call(void 0, (s) => s.ttsRate); const ttsVoiceId = _chunkALPGURNKjs.useAccessibilityStore.call(void 0, (s) => s.ttsVoiceId); const provider = _react.useMemo.call(void 0, () => _nullishCoalesce(providerOverride, () => ( new WebSpeechProvider())), [providerOverride] ); const [voices, setVoices] = _react.useState.call(void 0, []); const rateRef = _react.useRef.call(void 0, ttsRate); const voiceIdRef = _react.useRef.call(void 0, ttsVoiceId); rateRef.current = ttsRate; voiceIdRef.current = ttsVoiceId; const isActiveSpeakerRef = _react.useRef.call(void 0, false); _react.useEffect.call(void 0, () => { let mounted = true; if (provider.isSupported()) { provider.getVoices().then((list) => { if (mounted) setVoices(list); }).catch(() => void 0); } return () => { mounted = false; if (isActiveSpeakerRef.current) { provider.stop(); setTTSStatus("idle"); isActiveSpeakerRef.current = false; } }; }, [provider, setTTSStatus]); const hasPortugueseVoice = voices.some( (v) => v.lang.toLowerCase().startsWith("pt") ); const speak = _react.useCallback.call(void 0, (text) => { isActiveSpeakerRef.current = true; provider.speak( text, { rate: rateRef.current, voiceId: _nullishCoalesce(voiceIdRef.current, () => ( void 0)) // Não fixamos `lang: 'pt-BR'` aqui — em sistemas sem voz pt-BR // instalada, o browser fica tentando achar uma e nunca emite // áudio. O provider usa o `voice.lang` quando há voz escolhida. }, { onStart: () => setTTSStatus("speaking"), onEnd: () => { isActiveSpeakerRef.current = false; setTTSStatus("idle"); }, onPause: () => setTTSStatus("paused"), onResume: () => setTTSStatus("speaking"), onError: () => { isActiveSpeakerRef.current = false; setTTSStatus("idle"); } } ); }, [provider, setTTSStatus] ); const pause = _react.useCallback.call(void 0, () => { provider.pause(); setTTSStatus("paused"); }, [provider, setTTSStatus]); const resume = _react.useCallback.call(void 0, () => { provider.resume(); setTTSStatus("speaking"); }, [provider, setTTSStatus]); const stop = _react.useCallback.call(void 0, () => { isActiveSpeakerRef.current = false; provider.stop(); setTTSStatus("idle"); }, [provider, setTTSStatus]); return { isSupported: provider.isSupported(), voices, hasPortugueseVoice, speak, pause, resume, stop }; }; exports.WebSpeechProvider = WebSpeechProvider; exports.useTTS = useTTS; //# sourceMappingURL=chunk-Q3SVOFHA.js.map