Files
rm-circle-team-router/public/translate.js
T
martbost faf397f681 Add on-site translation for multilingual members
Floating translate button (bottom-left) on every member-facing page
lazy-loads the Google Translate element; language choice persists
across pages via the googtrans cookie. CSP extended for Google's
translate hosts only. Chatbot now replies in the member's language
and a canned answer points at the button.
2026-08-21 07:23:55 -05:00

48 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Floating language picker — lazy-loads the Google Translate element on first
// tap so pages pay zero cost until someone actually wants a translation. The
// googtrans cookie carries the chosen language across every page after that.
(function(){
var STYLE = ''+
'#rmcTrBtn{position:fixed;bottom:18px;left:18px;z-index:9998;display:flex;align-items:center;gap:7px;'+
'background:#0d2236;border:1px solid #24425d;color:#f7f9fc;border-radius:999px;padding:9px 14px;'+
'font:700 13px/1 Inter,system-ui,sans-serif;cursor:pointer;box-shadow:0 6px 24px rgba(0,0,0,.35)}'+
'#rmcTrBtn:hover{border-color:#4ed6cb}'+
'#rmcTrPanel{position:fixed;bottom:64px;left:18px;z-index:9999;background:#0d2236;border:1px solid #24425d;'+
'border-radius:14px;padding:14px;display:none;box-shadow:0 10px 34px rgba(0,0,0,.45)}'+
'#rmcTrPanel.on{display:block}'+
'#rmcTrPanel .t{color:#aebdca;font:600 12px/1.4 Inter,system-ui,sans-serif;margin:0 0 8px}'+
/* suppress Google's top banner + body shift */
'.goog-te-banner-frame,.skiptranslate iframe{display:none!important}'+
'body{top:0!important}'+
'#google_translate_element select{background:#071726;color:#f7f9fc;border:1px solid #24425d;border-radius:8px;padding:8px;font-size:14px;max-width:230px}'+
'#google_translate_element .goog-te-gadget{color:#aebdca;font-size:11px}'+
'#google_translate_element .goog-logo-link{color:#aebdca!important}';
var loaded=false;
function mount(){
var st=document.createElement('style');st.textContent=STYLE;document.head.appendChild(st);
var btn=document.createElement('button');btn.id='rmcTrBtn';btn.type='button';
btn.innerHTML='🌐 <span>Translate</span>';
btn.setAttribute('aria-label','Translate this page');
var panel=document.createElement('div');panel.id='rmcTrPanel';
panel.innerHTML='<p class="t">Choose your language — it sticks on every page.</p><div id="google_translate_element"></div>';
document.body.appendChild(btn);document.body.appendChild(panel);
btn.addEventListener('click',function(){
panel.classList.toggle('on');
if(!loaded){
loaded=true;
window.googleTranslateElementInit=function(){
new google.translate.TranslateElement({pageLanguage:'en',autoDisplay:false},'google_translate_element');
};
var s=document.createElement('script');
s.src='https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
s.onerror=function(){document.getElementById('google_translate_element').innerHTML='<p class="t">Translation is unavailable right now — your browser’s own “Translate page” option also works on this site.</p>';};
document.head.appendChild(s);
}
});
document.addEventListener('click',function(e){
if(panel.classList.contains('on')&&!panel.contains(e.target)&&e.target!==btn&&!btn.contains(e.target))panel.classList.remove('on');
});
}
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',mount);else mount();
})();