/**
* @module managers/language-manager
* @description This module manages language handling
* @requires jHammer
*/
define([
"common/view",
"jHammer"
],
function (View)
{
// ---------------------------------------------------------------
//
// Language
//
// ---------------------------------------------------------------
var Language = function ()
{
console.log(" * <language>");
this.oView = View;
window.tEvent.eventStr.EVENT_LANGUAGE_SET = "EVENT_LANGUAGE_SET";
window.tEvent.eventStr.EVENT_LANGUAGE_RESET = "EVENT_LANGUAGE_RESET";
window.tEvent.eventStr.EVENT_SET_LANGUAGE = "EVENT_SET_LANGUAGE";
window.tEvent.eventStr.EVENT_APPLY_LANGUAGE = "EVENT_APPLY_LANGUAGE";
window.tEvent.eventStr.EVENT_LANGUAGE_CONFIG_LOADED = "EVENT_LANGUAGE_CONFIG_LOADED";
this.ui = {
body : "body",
autoText : "[data-auto-lang-source-id]",
dynamicText : "[data-lang-copy-id]",
dynamicImg : "[data-lang-img-id]",
langRotationItem : ".js-lang-rotation-item",
langIcon : ".js-complex-lang-icon",
langBtn : ".js-complex-lang-btn",
micToggle : ".js-complex-mic",
persistentLangContainer : ".js-complex-persistent-lang",
persistentLangRotationItem : ".js-complex-persistent-lang-btn",
autoTranslate : ".js-auto-translate"
};
this.def = -1;
// project.json
this.jConfig = -1;
this.jLangConfig = -1;
// enable first load events
this.firstLoad = true;
this.currentLang = -1;
this.langAnimDelayedCall = -1;
this.langPersistentAnimDelayedCall = -1;
this.init();
};
Language.prototype =
{
// ______________________________________________________________
// init
/**
* init
* @description Initializes class. Sets data-lang attribute of <body>
* @fires loadLanguageFile()
* @memberOf module:managers/language-manager
* @instance
*/
init: function() {
var self = this;
// in case there no unit connection so there is no "GAP"
$(this.ui.body).attr(this.def.DATA_LANGUAGE, "_English");
// is model ready?
if (typeof window.oModel === "undefined" || window.oModel.modelReady === false){
window.tEvent.addListener("EVENT_MODEL_READY", function(evt, data) {
self.loadLanguageFile();
});
} else {
self.loadLanguageFile();
}
},
// ______________________________________________________________
// assignListeners
/**
* assignListeners
* @description Assigns listeners to events used in this class.
* @listens EVENT_ADMIN_GOT_MANIFEST
* @listens EVENT_LANGUAGE_RESET
* @listens EVENT_PRSONAS_MESSAGE_STATUS
* @listens EVENT_APPLY_LANGUAGE
* @listens EVENT_TEMPLATE_LOADED
* @listens langBtn
* @memberOf module:managers/language-manager
* @instance
*/
assignListeners: function() {
var self = this;
// got manifest with language options
window.tEvent.addListener("EVENT_ADMIN_GOT_MANIFEST", function(evt, manifest) {
self.onReceivedManifest(manifest);
});
// got language status - make sure we are synced
window.tEvent.addListener("EVENT_PRSONAS_MESSAGE_STATUS", function(evt, data) {
if (data.property === "language"){
self.onLanguageStatus(data);
}
});
// set a language
window.tEvent.addListener(window.tEvent.eventStr.EVENT_APPLY_LANGUAGE, function(evt, languageData) {
languageData.fromUnit = false;
self.onSetLanguage(languageData);
});
// lang btn
$("body").hammer().on("click", this.ui.langBtn, function(e){
var lang = $(this).attr("data-id");
self.onSetLanguage({
language: lang
}, "button");
});
// choose a lang btn
$("body").hammer().on("click", this.ui.persistentLangContainer, function(e){
window.tEvent.fire(window.tEvent.eventStr.EVENT_PAGE_LANGUAGES);
});
window.tEvent.addListener(window.tEvent.eventStr.EVENT_TEMPLATE_LOADED_DETAILS, function(evt, eventData){
self.onPageLoad(eventData);
});
window.tEvent.addListener("EVENT_ADMIN_GOT_MANIFEST", function(evt, data){
self.resetLanguage();
});
window.tEvent.addListener(window.tEvent.eventStr.EVENT_LANGUAGE_RESET, function(evt, data){
self.resetLanguage();
});
},
// --------------------------------------------------------------
// HELPERS
// --------------------------------------------------------------
// ______________________________________________________________
// getProjectId
/**
* getProjectId
* @description Returns the project ID. First trying the commandline then falling back to project JSON prsonas.projectId
* @return {String} Returns the project ID
* @memberOf module:managers/language-manager
* @instance
*/
getProjectId: function() {
var projectId = this.jConfig.prsonas.projectId;
if (typeof this.oPrsonas !== "undefined" &&
typeof this.oPrsonas.app !== "undefined" &&
this.oPrsonas.app.getCommandLineParameters() !== null){
if (typeof this.oPrsonas.app.getCommandLineParameters().experience !== "undefined"){
projectId = this.oPrsonas.app.getCommandLineParameters().experience;
}
}
return (projectId);
},
// ______________________________________________________________
// initLanguages
/**
* initLanguages
* @description Initializes languages
* @fires resetLanguage()
* @memberOf module:managers/language-manager
* @instance
*/
initLanguages: function() {
this.resetLanguage();
},
// ______________________________________________________________
// resetLanguage
/**
* resetLanguage
* @description Resets the language to defaults.
* @fires onSetLanguage()
* jConfig.document.language
* @memberOf module:managers/language-manager
* @instance
*/
resetLanguage: function() {
var defaultLang = this.jConfig.document.language;
this.onSetLanguage({
language: defaultLang
}, "reset");
},
// ______________________________________________________________
// loadLanguageFile
/**
* loadLanguageFile
* @description Loads language file content/json/langCopy.json
* @fires jConfig.document.startEvent
* @memberOf module:managers/language-manager
* @instance
*/
loadLanguageFile: function() {
var self = this;
this.oView.oServices.loadProjectJson("langCopy.json", function(evt){
self.jLangConfig = evt.data;
self.onModelReady();
window.tEvent.fire(window.tEvent.eventStr.EVENT_LANGUAGE_CONFIG_LOADED, self.jLangConfig);
// hack to resolve race condition with onPageLoad being called before the language file is ready.
self.firstLoad = true;
// start program
window.tEvent.fire(self.jConfig.document.startEvent);
});
},
// ______________________________________________________________
// initLanguageUX
/**
* initLanguageUX
* @description Loads language file content/json/langCopy.json
* @fires jConfig.document.startEvent
* @memberOf module:managers/language-manager
* @instance
*/
initLanguageUX: function() {
// populate persistent languages
if (typeof this.jConfig.modules["m-persistent-languages"] !== "undefined"){
var module = this.jConfig.modules["m-persistent-languages"];
var templateObj = window.oDxpTemplates["complex-template-persistent-languages"](module);
$(this.ui.persistentLangContainer).html(templateObj);
this.doPersistentLangAnim();
}
},
// ______________________________________________________________
// doPersistentLangAnim
/**
* doPersistentLangAnim
* @description Animates the rotation of the persistent language panel
* @memberOf module:managers/language-manager
* @instance
*/
doPersistentLangAnim: function() {
if (typeof this.jConfig.modules["m-persistent-languages"] === "undefined"){
return;
}
var self = this;
var config = this.jConfig.modules["m-persistent-languages"].config;
var itemHeight = $(this.ui.persistentLangRotationItem)[0].getBoundingClientRect().height + this.jConfig.language.languageRotation.persistentRotationElementHeightOffset;
var imgs = window.gsap.utils.toArray(this.ui.persistentLangRotationItem);
var itemCount = $(this.ui.persistentLangRotationItem).length;
var delay = config.delay; // time to change
var rotationList = [];
var activeIndex = 0;
function crossfade(){
action = window.gsap.timeline()
.to(imgs, {y: '-=' + itemHeight, duration: config.duration, ease: "expo"})
.to(imgs[0], {y: '+=' + itemHeight*itemCount, duration: 0});
imgs.push( imgs.shift() ); // the first (shift) to the end (push) from the array
// start endless run
self.langPersistentAnimDelayedCall = window.gsap.delayedCall(delay, crossfade);
}
// kill delay if it exists to resume properly
if (typeof this.langPersistentAnimDelayedCall.kill !== "undefined"){
this.langPersistentAnimDelayedCall.kill();
}
// start the crossfade after delay = 3 sec
this.langPersistentAnimDelayedCall = window.gsap.delayedCall(delay, crossfade);
},
// ______________________________________________________________
// doLangPageAnim
/**
* doLangPageAnim
* @description Animates the rotation of the language page
* @memberOf module:managers/language-manager
* @instance
*/
doLangPageAnim: function() {
//return;
var self = this;
var config = this.jConfig.modules["m-page-languages"].config;
var itemHeight = $(this.ui.langRotationItem)[0].getBoundingClientRect().height + this.jConfig.language.languageRotation.pageRotationElementHeightOffset;
var imgs = window.gsap.utils.toArray(this.ui.langRotationItem)
var itemCount = $(this.ui.langRotationItem).length;
var delay = config.delay; // time to change
var rotationList = [];
var activeIndex = 0;
// get rotation list
$(this.ui.langRotationItem).each(function(){
rotationList.push($(this).attr("data-id"));
});
function crossfade(){
if ($("body").attr("data-module-id") !== "m-page-languages"){
self.langAnimDelayedCall.kill();
return;
}
action = window.gsap.timeline()
.to(imgs, {y: '-=' + itemHeight, duration: config.duration, ease: "expo"})
.to(imgs[0], {y: '+=' + itemHeight*itemCount, duration: 0});
imgs.push( imgs.shift() ); // the first (shift) to the end (push) from the array
// start endless run
self.langAnimDelayedCall = window.gsap.delayedCall(delay, crossfade);
// get active index and trigger other anim
activeIndex++;
if (activeIndex > rotationList.length-1){
activeIndex = 0;
}
TweenLite.to($(self.ui.langIcon + "[data-id='" + rotationList[activeIndex] + "'"), 0.4, {scale: 1.2})
TweenLite.to($(self.ui.langIcon + "[data-id='" + rotationList[activeIndex] + "'"), 1, {scale: 1, delay: 0.4, ease: "elastic"});
}
// kill delay if it exists to resume properly
if (typeof this.langAnimDelayedCall.kill !== "undefined"){
this.langAnimDelayedCall.kill();
}
// start the crossfade after delay = 3 sec
this.langAnimDelayedCall = window.gsap.delayedCall(delay, crossfade);
},
// ______________________________________________________________
// applyCurrentLanguage
/**
* applyCurrentLanguage
* @description Applies the current language based on $("body").attr("data-lang");
* @memberOf module:managers/language-manager
* @instance
*/
applyCurrentLanguage: function() {
var self = this;
var config = this.jLangConfig.languageCopy;
var lang = $("body").attr("data-lang");
var id,
copy,
path;
$(this.ui.langBtn).removeClass(this.def.CLASS_IS_ACTIVE);
$(this.ui.langBtn + "[data-id='" + lang + "']").addClass(this.def.CLASS_IS_ACTIVE);
// translate text
$(this.ui.dynamicText).each(function(){
id = $(this).attr("data-lang-copy-id");
if (id !== "" && typeof id !== "undefined"){
copy = config[id][lang];
$(this).html(copy);
}
});
// translate images
path = "content/images/" + lang + "/";
$(this.ui.dynamicImg).each(function(){
id = $(this).attr("data-lang-img-id");
if (id !== "" && typeof id !== "undefined"){
$(this).attr("src", path + id);
}
});
// auto translate text
$(this.ui.autoText).each(function(){
if (!window.oPrsonas.avatar.isConnected()) {
return;
}
var textArray = $(this).attr("data-copy");
var srcLangId = $(this).attr("data-auto-lang-source-id");
var destLangId = window.oModel.jConfig.language.nuBrowserIds[lang];
var translation = window.oPrsonas.avatar.translateText(destLangId, textArray, srcLangId);
if (translation.success){
$(this).html(translation.data[0]);
} else {
console.warn(" ! <language.applyCurrentLanguage> Error in " + self.ui.autoText, translation.message);
}
});
},
// --------------------------------------------------------------
// EVENTS
// --------------------------------------------------------------
// ______________________________________________________________
// onModelReady
/**
* onModelReady
* @description Called when project.json is loaded
* @fires initIha()
* @fires assignListeners()
* @fires initMappedIn()
* @memberOf module:managers/language-manager
* @instance
*/
onModelReady: function() {
// set defines
this.def = window.helpers.clone(window.oModel.def);
this.def.CLASS_HIDE_ME = "hide-me";
this.def.DATA_LANGUAGE = "data-lang";
// set jConfig data
this.jConfig = window.oModel.jConfig;
this.initLanguageUX();
this.assignListeners();
},
// ______________________________________________________________
// onReceivedManifest
/**
* onReceivedManifest
* @description Process manifest data from Prsonas manifest
* @param {Object} manifest
* @memberOf module:managers/language-manager
* @instance
*/
onReceivedManifest: function(manifest) {
},
// ______________________________________________________________
// onLanguageStatus
/**
* onLanguageStatus
* @description Applies current language from Prsonas message event EVENT_PRSONAS_MESSAGE_STATUS
* @memberOf module:managers/language-manager
* @instance
*/
onLanguageStatus: function() {
this.currentLang = $("body").attr("data-lang");
console.log(" * <language.onLanguageStatus> this.currentLang:", this.currentLang);
this.onSetLanguage({
fromUnit: true,
language: this.currentLang
});
},
// ______________________________________________________________
// onLanguageStatus
/**
* onSetLanguage
* @description Applies current language from user event EVENT_SET_LANGUAGE
* @param {Object} langObj - Language data
* @fires EVENT_LANGUAGE_SET
* @memberOf module:managers/language-manager
* @instance
*/
onSetLanguage: function(langObj, fromSource){
var lang = langObj.language;
var projectId = this.getProjectId();
if (typeof lang === "undefined"){
lang = $("body").attr("data-lang");
} else {
$("body").attr("data-lang", lang);
}
switch(fromSource){
case "reset":
break;
}
// set unit, Q&A services, and mappedin language
window.tEvent.fire(window.tEvent.eventStr.EVENT_SET_LANGUAGE, {
language: lang
});
switch(fromSource){
case "reset":
break;
case "button":
// tagging
window.oPrsonas.sdk.logStat("", projectId, "LanguageSelected", lang, "touch");
if (typeof window.oIha !== "undefined" && window.oIha.isIha) {
window.tEvent.fire("EVENT_PAGE_HOME_BTN");
}
break;
}
},
// ______________________________________________________________
// onPageLoad
/**
* onPageLoad
* @description Called when a page is loaded
* @param {String} eventId - Event ID
* @param {Object} data - Event data
* @memberOf module:managers/language-manager
* @instance
*/
onPageLoad: function(eventData, data) {
var self = this;
if (this.firstLoad){
this.firstLoad = false;
// set language
this.initLanguages();
}
switch(eventData.event){
case "EVENT_PAGE_LANGUAGES":
if (typeof window.oIha !== "undefined" && window.oIha.isIha) {
// hide interactive
$(this.ui.micToggle).css("display", "none");
// disable speech recognition
window.oSpeech.toggleSpeech("disable");
// hide map
window.oIha.onShowMap(false);
}
if (typeof eventData._proxyEvtStr !== "undefined" && eventData._proxyEvtStr !== "" && typeof this.jConfig.sendKeyEvents[eventData._proxyEvtStr] !== "undefined" && this.jConfig.sendKeyEvents[eventData._proxyEvtStr].toLowerCase() === "walkaway"){
} else {
// reset language
this.onSetLanguage({
language: this.jConfig.document.language
}, "reset");
}
this.doLangPageAnim();
break;
default:
if (this.jConfig.speech.showMicToggle){
$(this.ui.micToggle).css("display", "block");
}
}
// set language
this.applyCurrentLanguage();
}
};
/**
* @global
*/
window.oLang = new Language();
return (window.oLang);
});