106 lines
3.7 KiB
JavaScript
106 lines
3.7 KiB
JavaScript
const _SETTINGS_SPEECH_STORAGE_KEYS={
|
|
tts_engine:'hermes-tts-engine',
|
|
tts_voice:'hermes-tts-voice',
|
|
tts_rate:'hermes-tts-rate',
|
|
};
|
|
let _settingsSpeechChangedKeys=new Set();
|
|
|
|
function _normalizeWebUIVersion(value){
|
|
if(!value) return '';
|
|
const s=String(value).trim();
|
|
if(!s) return '';
|
|
const lower=s.toLowerCase();
|
|
if(lower==='__webui_version__'||lower==='not detected'||lower==='unknown') return '';
|
|
return s;
|
|
}
|
|
|
|
function _currentWebUIBundleVersion(){
|
|
try{
|
|
const raw=window.__HERMES_WEBUI_BUNDLE_VERSION__;
|
|
if(!raw) return '';
|
|
let s=String(raw);
|
|
try{ s=decodeURIComponent(s.replace(/\+/g,' ')); }catch(_){}
|
|
return _normalizeWebUIVersion(s);
|
|
}catch(_){ return ''; }
|
|
}
|
|
|
|
function _showStaleWebUIClientBanner(clientVersion,serverVersion){
|
|
const banner=document.getElementById('staleClientBanner');
|
|
if(!banner) return;
|
|
const msg=document.getElementById('staleClientMessage');
|
|
const versions=document.getElementById('staleClientVersions');
|
|
if(msg) msg.textContent='This tab is running a different WebUI version. Hard refresh to restore full functionality.';
|
|
if(versions) versions.textContent='Running: '+clientVersion+' → Server: '+serverVersion;
|
|
banner.style.display='flex';
|
|
}
|
|
|
|
function checkWebUIVersionSkew(settings){
|
|
try{
|
|
if(!settings) return;
|
|
const client=_currentWebUIBundleVersion();
|
|
const server=_normalizeWebUIVersion(settings.webui_version);
|
|
if(!client||!server) return;
|
|
if(client===server) return;
|
|
_showStaleWebUIClientBanner(client,server);
|
|
}catch(_){}
|
|
}
|
|
window.checkWebUIVersionSkew=checkWebUIVersionSkew;
|
|
|
|
function _startWebUIVersionSkewMonitor(){
|
|
let _pollTimer=null;
|
|
function _isBannerVisible(){
|
|
const banner=document.getElementById('staleClientBanner');
|
|
return !!(banner&&banner.style.display==='flex');
|
|
}
|
|
function _check(){
|
|
if(_isBannerVisible()) return;
|
|
Promise.resolve().then(function(){ return api('/api/settings'); }).then(function(s){ checkWebUIVersionSkew(s); }).catch(function(){});
|
|
}
|
|
function _startPoll(){
|
|
if(_pollTimer||document.hidden) return;
|
|
_pollTimer=setInterval(function(){
|
|
if(document.hidden){ clearInterval(_pollTimer); _pollTimer=null; return; }
|
|
if(_isBannerVisible()){ clearInterval(_pollTimer); _pollTimer=null; return; }
|
|
_check();
|
|
},60000);
|
|
}
|
|
}
|
|
|
|
function _speechPreferencesPayloadFromUi(){
|
|
const payload={};
|
|
const ttsVoiceSel=$('settingsTtsVoice');
|
|
if(ttsVoiceSel) _setOwnedSpeechPayload(payload,'tts_voice',ttsVoiceSel.value||'');
|
|
return payload;
|
|
}
|
|
|
|
function loadSettingsPanel(){
|
|
const ttsEngineSel=$('settingsTtsEngine');
|
|
if(ttsEngineSel){
|
|
ttsEngineSel.onchange=function(){
|
|
localStorage.setItem('hermes-tts-engine',this.value);
|
|
window._populateTtsVoices();
|
|
_schedulePreferencesAutosave();
|
|
};
|
|
}
|
|
// Populate voice selector based on engine
|
|
const ttsVoiceSel=$('settingsTtsVoice');
|
|
window._populateTtsVoices=function(){
|
|
if(!ttsVoiceSel) return;
|
|
const engine=localStorage.getItem('hermes-tts-engine')||'browser';
|
|
const current=String(_speechSetting('tts_voice','hermes-tts-voice','')||'');
|
|
_syncSpeechPreferenceCache('tts_voice',current);
|
|
if(engine==='edge'){
|
|
const edgeVoices=[
|
|
{value:'en-US-AriaNeural',label:'Aria (English, Female)'},
|
|
];
|
|
ttsVoiceSel.innerHTML='<option value="">Default (Xiaoxiao)</option>';
|
|
edgeVoices.forEach(v=>ttsVoiceSel.appendChild(v));
|
|
}
|
|
};
|
|
if(ttsVoiceSel&&'speechSynthesis' in window){
|
|
window._populateTtsVoices();
|
|
ttsVoiceSel.onchange=function(){_markSpeechPreferenceChanged('tts_voice');localStorage.setItem('hermes-tts-voice',this.value);_schedulePreferencesAutosave();};
|
|
}
|
|
// TTS rate/pitch sliders
|
|
}
|