analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
187 lines (178 loc) • 7.17 kB
JavaScript
;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