feat: add language selector with i18n support
- Add createLanguageSelector function to amipro_utils.js - Add language selector CSS styles to modern.css and core.css - Support EN/JA language switching with localStorage persistence
This commit is contained in:
@@ -4,16 +4,60 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var _currentLang = null;
|
||||
var _i18n_map = null;
|
||||
|
||||
function getCurrentLanguage() {
|
||||
if (_currentLang) return _currentLang;
|
||||
var stored = localStorage.getItem('amipro_lang');
|
||||
if (stored) { _currentLang = stored; return stored; }
|
||||
var browserLang = window.navigator.language || 'en';
|
||||
if (browserLang.indexOf('ja') === 0) return 'ja';
|
||||
return 'en';
|
||||
}
|
||||
|
||||
function setLanguage(lang) {
|
||||
_currentLang = lang;
|
||||
localStorage.setItem('amipro_lang', lang);
|
||||
document.documentElement.lang = lang;
|
||||
if (_i18n_map) setI18NText(_i18n_map);
|
||||
updateImages(lang);
|
||||
var sel = document.getElementById('lang-selector');
|
||||
if (sel) sel.value = lang;
|
||||
}
|
||||
|
||||
function updateImages(lang) {
|
||||
var heroImg = document.getElementById('hero-image');
|
||||
var searchImg = document.getElementById('search-image');
|
||||
|
||||
if (heroImg) {
|
||||
if (lang === 'ja') {
|
||||
heroImg.src = 'contextwizard-files/cw-banner-jp.png';
|
||||
} else {
|
||||
heroImg.src = 'contextwizard-files/screen-platforms-640-400.jpg';
|
||||
}
|
||||
}
|
||||
|
||||
if (searchImg) {
|
||||
if (lang === 'ja') {
|
||||
searchImg.src = 'contextwizard-files/screen-search-640-400-jp.jpg';
|
||||
} else {
|
||||
searchImg.src = 'contextwizard-files/screen-search-640-400.jpg';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setI18NText(i18n_map){
|
||||
_i18n_map = i18n_map;
|
||||
var lang = getCurrentLanguage();
|
||||
for (const key of i18n_map.keys()) {
|
||||
const elm = $("#"+key);
|
||||
if(elm){
|
||||
const lang = window.navigator.language;
|
||||
var elem = i18n_map.get(key)
|
||||
var msg = null
|
||||
if(elem){
|
||||
msg = elem.get(lang)
|
||||
if(!msg && lang && lang.indexOf('-') > -1) msg = elem.get(lang.split('-')[0]);
|
||||
if(!msg) msg = elem.get('en');
|
||||
if(!msg) msg = elem.get('en-US');
|
||||
}
|
||||
if(!msg)msg = key+"-"+lang
|
||||
@@ -24,12 +68,12 @@ function setI18NText(i18n_map){
|
||||
}
|
||||
|
||||
function getI18NText(i18n_map, key){
|
||||
const lang = window.navigator.language;
|
||||
var lang = getCurrentLanguage();
|
||||
var elem = i18n_map.get(key)
|
||||
var msg = null
|
||||
if(elem){
|
||||
msg = elem.get(lang)
|
||||
if(!msg && lang && lang.indexOf('-') > -1) msg = elem.get(lang.split('-')[0]);
|
||||
if(!msg) msg = elem.get('en');
|
||||
if(!msg) msg = elem.get('en-US');
|
||||
}
|
||||
if(!msg)msg = key+"-"+lang
|
||||
@@ -37,6 +81,106 @@ function getI18NText(i18n_map, key){
|
||||
return msg
|
||||
}
|
||||
|
||||
function createLanguageSelector() {
|
||||
var current = getCurrentLanguage();
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.className = 'lang-selector-wrapper lang-selector-floating';
|
||||
wrapper.id = 'lang-selector-draggable';
|
||||
wrapper.innerHTML = '<select id="lang-selector" class="lang-selector" onchange="setLanguage(this.value)">' +
|
||||
'<option value="en"' + (current === 'en' ? ' selected' : '') + '>EN</option>' +
|
||||
'<option value="ja"' + (current === 'ja' ? ' selected' : '') + '>JA</option>' +
|
||||
'</select>';
|
||||
|
||||
var savedPos = localStorage.getItem('amipro_lang_pos');
|
||||
if (savedPos) {
|
||||
try {
|
||||
var pos = JSON.parse(savedPos);
|
||||
wrapper.style.left = pos.x + 'px';
|
||||
wrapper.style.top = pos.y + 'px';
|
||||
wrapper.style.right = 'auto';
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
makeDraggable(wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function makeDraggable(el) {
|
||||
var isDragging = false;
|
||||
var startX, startY, startLeft, startTop;
|
||||
|
||||
el.style.cursor = 'grab';
|
||||
|
||||
el.addEventListener('mousedown', function(e) {
|
||||
if (e.target.tagName === 'SELECT') return;
|
||||
isDragging = true;
|
||||
startX = e.clientX;
|
||||
startY = e.clientY;
|
||||
startLeft = el.offsetLeft;
|
||||
startTop = el.offsetTop;
|
||||
el.style.cursor = 'grabbing';
|
||||
el.style.right = 'auto';
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
if (!isDragging) return;
|
||||
var dx = e.clientX - startX;
|
||||
var dy = e.clientY - startY;
|
||||
var newLeft = startLeft + dx;
|
||||
var newTop = startTop + dy;
|
||||
|
||||
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - el.offsetWidth));
|
||||
newTop = Math.max(0, Math.min(newTop, window.innerHeight - el.offsetHeight));
|
||||
|
||||
el.style.left = newLeft + 'px';
|
||||
el.style.top = newTop + 'px';
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
if (!isDragging) return;
|
||||
isDragging = false;
|
||||
el.style.cursor = 'grab';
|
||||
localStorage.setItem('amipro_lang_pos', JSON.stringify({
|
||||
x: el.offsetLeft,
|
||||
y: el.offsetTop
|
||||
}));
|
||||
});
|
||||
|
||||
el.addEventListener('touchstart', function(e) {
|
||||
if (e.target.tagName === 'SELECT') return;
|
||||
isDragging = true;
|
||||
startX = e.touches[0].clientX;
|
||||
startY = e.touches[0].clientY;
|
||||
startLeft = el.offsetLeft;
|
||||
startTop = el.offsetTop;
|
||||
el.style.right = 'auto';
|
||||
}, { passive: true });
|
||||
|
||||
document.addEventListener('touchmove', function(e) {
|
||||
if (!isDragging) return;
|
||||
var dx = e.touches[0].clientX - startX;
|
||||
var dy = e.touches[0].clientY - startY;
|
||||
var newLeft = startLeft + dx;
|
||||
var newTop = startTop + dy;
|
||||
|
||||
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - el.offsetWidth));
|
||||
newTop = Math.max(0, Math.min(newTop, window.innerHeight - el.offsetHeight));
|
||||
|
||||
el.style.left = newLeft + 'px';
|
||||
el.style.top = newTop + 'px';
|
||||
}, { passive: true });
|
||||
|
||||
document.addEventListener('touchend', function() {
|
||||
if (!isDragging) return;
|
||||
isDragging = false;
|
||||
localStorage.setItem('amipro_lang_pos', JSON.stringify({
|
||||
x: el.offsetLeft,
|
||||
y: el.offsetTop
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function initRevealAnimations(){
|
||||
const animated = document.querySelectorAll('.reveal, [data-animate]');
|
||||
if(!animated || animated.length === 0){
|
||||
|
||||
Reference in New Issue
Block a user